Thread overview
Strange behavior with BufferedFile
May 16, 2005
Vathix
May 16, 2005
Ben Hinkle
May 16, 2005
Ben Hinkle
May 18, 2005
Ben Hinkle
May 16, 2005
import std.stream, std.stdio;

int main(char[][] args)
{
   if(args.length < 2)
      throw new Exception("Expected text file!");

   Stream _f;
   EndianStream f;
   int ibom;

   _f = new BufferedFile(args[1]); // Problem.
   //_f = new File(args[1]); // Use this instead and it works.
   f = new EndianStream(_f);

   writef("File size is %d, file position is %d\n", f.size(), f.position());

   ibom = f.readBOM();
   if(ibom != -1 && ibom != BOM.UTF8)
      throw new Exception("File not UTF-8!");

   writef("File size is %d, file position is %d\n", f.size(), f.position());
   writef("Expecting to read %d characters.\n", f.size() - f.position());

   size_t iw = 0;
   while(!f.eof())
   {
      f.getc();
      iw++;
   }

   writef("Read %d characters.\n", iw);

   return 0;
}


Output of the above:

File size is 10, file position is 0
File size is 10, file position is 3
Expecting to read 18446744069414584327 characters.
Read 0 characters.


Output when I switch to File instead of BufferedFile:

File size is 10, file position is 0
File size is 10, file position is 3
Expecting to read 7 characters.
Read 7 characters.
May 16, 2005
Looks like BufferedStream/File has a bug with ungetc and size(). The following simpler example reproduces the bug:

import std.stream, std.stdio;
int main(char[][] args)
{
    Stream f;
    f = new BufferedFile(args[1]);
    char c = f.getc();
    f.ungetc(c);
    f.size(); // comment out to get working
    size_t iw = 0;
    while(!f.eof())
    {
       f.getc();
       iw++;
    }
    writef("Read %d characters.\n", iw);
    return 0;
}

If you comment out the f.size() call everything works. I'll figure out what the fix is and send something to Walter. Thanks for the bug report!

"Vathix" <vathix@dprogramming.com> wrote in message news:op.squshjl3kcck4r@esi...
> import std.stream, std.stdio;
>
> int main(char[][] args)
> {
>    if(args.length < 2)
>       throw new Exception("Expected text file!");
>
>    Stream _f;
>    EndianStream f;
>    int ibom;
>
>    _f = new BufferedFile(args[1]); // Problem.
>    //_f = new File(args[1]); // Use this instead and it works.
>    f = new EndianStream(_f);
>
>    writef("File size is %d, file position is %d\n", f.size(),
> f.position());
>
>    ibom = f.readBOM();
>    if(ibom != -1 && ibom != BOM.UTF8)
>       throw new Exception("File not UTF-8!");
>
>    writef("File size is %d, file position is %d\n", f.size(),
> f.position());
>    writef("Expecting to read %d characters.\n", f.size() - f.position());
>
>    size_t iw = 0;
>    while(!f.eof())
>    {
>       f.getc();
>       iw++;
>    }
>
>    writef("Read %d characters.\n", iw);
>
>    return 0;
> }
>
>
> Output of the above:
>
> File size is 10, file position is 0
> File size is 10, file position is 3
> Expecting to read 18446744069414584327 characters.
> Read 0 characters.
>
>
> Output when I switch to File instead of BufferedFile:
>
> File size is 10, file position is 0
> File size is 10, file position is 3
> Expecting to read 7 characters.
> Read 7 characters.


May 16, 2005
I should add a workaround is to reset the file position manually after
calling size():
    f.position(0);


May 18, 2005
fixed the problem. If you want to rebuild phobos change the std.stream line
    long diff = bufferCurPos-bufferSourcePos;
to
    long diff = cast(long)bufferCurPos-bufferSourcePos;
The problem was that the two variables being subtracted were uints and the
result was a long and in your example code diff should have been negative
but it wasn't. By the way, the output I get from running the posted code
looks something like

File size is 851, file position is 0
File size is 851, file position is 1
Expecting to read 850 characters.
Read 851 characters.

I noticed the mismatch between the expected amount (850) and the read amount
(851) and that is the correct output because data pushed back using ungetc
does not effect the position.
Anyway, I'll add a test and send the result to Walter.

"Vathix" <vathix@dprogramming.com> wrote in message news:op.squshjl3kcck4r@esi...
> import std.stream, std.stdio;
>
> int main(char[][] args)
> {
>    if(args.length < 2)
>       throw new Exception("Expected text file!");
>
>    Stream _f;
>    EndianStream f;
>    int ibom;
>
>    _f = new BufferedFile(args[1]); // Problem.
>    //_f = new File(args[1]); // Use this instead and it works.
>    f = new EndianStream(_f);
>
>    writef("File size is %d, file position is %d\n", f.size(),
> f.position());
>
>    ibom = f.readBOM();
>    if(ibom != -1 && ibom != BOM.UTF8)
>       throw new Exception("File not UTF-8!");
>
>    writef("File size is %d, file position is %d\n", f.size(),
> f.position());
>    writef("Expecting to read %d characters.\n", f.size() - f.position());
>
>    size_t iw = 0;
>    while(!f.eof())
>    {
>       f.getc();
>       iw++;
>    }
>
>    writef("Read %d characters.\n", iw);
>
>    return 0;
> }
>
>
> Output of the above:
>
> File size is 10, file position is 0
> File size is 10, file position is 3
> Expecting to read 18446744069414584327 characters.
> Read 0 characters.
>
>
> Output when I switch to File instead of BufferedFile:
>
> File size is 10, file position is 0
> File size is 10, file position is 3
> Expecting to read 7 characters.
> Read 7 characters.