www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - Strange behavior with BufferedFile

reply Vathix <vathix dprogramming.com> writes:
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 15 2005
next sibling parent "Ben Hinkle" <ben.hinkle gmail.com> writes:
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
prev sibling next sibling parent "Ben Hinkle" <ben.hinkle gmail.com> writes:
I should add a workaround is to reset the file position manually after 
calling size():
    f.position(0); 
May 16 2005
prev sibling parent "Ben Hinkle" <ben.hinkle gmail.com> writes:
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. 
May 17 2005