Compare commits

...

1 commit

Author SHA1 Message Date
Jeff Epler
84472921c1 Don't open part 21 files as text files
On Windows, when a file is opened in "text" mode, but it actually
contains Unix-style line endings, the behavior of tellg() is
unexpected.

Consider this program which puts the (binary) contents "a\nb\n" in a
file, then opens it in text mode for reading.  It prints each
character read, along with the value returned by tellg():

    #include <iostream>
    #include <fstream>

    int main()
    {
        {
            std::ofstream f("myfile.txt", std::ios::binary);
            f << "a\nb\n";
        }

        std::ifstream f("myfile.txt");

        for (char c=0; f.get(c);)
            std::cout << f.tellg() << ' ' << int(c) << '\n';
    }

On a UNIX platform which does not have a distinction between "text"
and "binary" files, the output will read
    1 97
    2 10
    3 98
    4 10
because the file position simply advances one position after each
byte is read.

On Windows with the Visual Studio C and C++ runtime, the result is
instead
    -1 97
    1 10
    2 98
    4 10
While it is impossible to say exactly what the Windows runtime is
doing here, it appears that it is trying to adjust for the mismatch
between "number of bytes read in byte oriented mode and "number of
bytes read in text mode".

Since "part21" files don't necessarily contain CRLF line endings
when viewed in binary mode, open the file in binary mode.  This
fixes the test failure seen on appveyor ci running the
"test_inverse_attr3" test.
2017-08-21 17:11:50 -05:00

View file

@ -50,7 +50,7 @@ instancesLoaded_t * lazyFileReader::getHeaderInstances() {
} }
lazyFileReader::lazyFileReader( std::string fname, lazyInstMgr * i, fileID fid ): _fileName( fname ), _parent( i ), _fileID( fid ) { lazyFileReader::lazyFileReader( std::string fname, lazyInstMgr * i, fileID fid ): _fileName( fname ), _parent( i ), _fileID( fid ) {
_file.open( _fileName.c_str() ); _file.open( _fileName.c_str(), std::ios::binary );
_file.imbue( std::locale::classic() ); _file.imbue( std::locale::classic() );
_file.unsetf( std::ios_base::skipws ); _file.unsetf( std::ios_base::skipws );
assert( _file.is_open() && _file.good() ); assert( _file.is_open() && _file.good() );