I'm working on a couple classes that, when finished, will allow binary I/O to files, strings, etc. Basic usage is:
So far, it's working wonderfully for strings. I plugged in the bit of code needed for file I/O, and everything crashed. I've boiled it down to the following small example:Code:mystream << binaryio::little_endian << binaryio::set_size(2) << my_integer;
The program says that the file is open, and will get to the "Attempting read of 8 bytes" part, call basic_filebuf::sgetn(), and a "St8bad_cast" exception gets thrown. On my system, the backtrace at the time of the exception looks something like this:Code:#include <fstream> #include <iostream> int main() { unsigned char data[8]; std::basic_filebuf<unsigned char, std::char_traits<unsigned char> > bfs; std::cerr << "About to open file..." << std::endl; bfs.open("filetest", std::ios::in | std::ios::binary); std::cerr << "Is file open? " << (bfs.is_open() ? "yes" : "no") << std::endl; std::cerr << "Attempting read of 8 bytes." << std::endl; try { std::streamsize ret; ret = bfs.sgetn(data, 8); std::cerr << "Got " << ret << " bytes." << std::endl; } catch(std::exception &e) { std::cerr << "Exception: " << e.what() << std::endl; return 1; } return 0; }
Looking at the __check_facet function, all it does is check if it's parameter is NULL, and if so, throws the bad cast exception. The passed NULL is the value of std::basic_filebuf<...>::_M_codecvt.Code:std::__check_facet(NULL) in bits/localefwd.h:187 std::basic_filebuf<unsigned char, std::char_traits<unsigned char> >::underflow() std::basic_filebuf<unsigned char, std::char_traits<unsigned char> >::uflow() std::basic_filebuf<unsigned char, std::char_traits<unsigned char> >::xsgetn() std::basic_filebuf<unsigned char, std::char_traits<unsigned char> >::xsgetn() std::basic_filebuf<unsigned char, std::char_traits<unsigned char> >::sgetn() main()
Why is this (private) member NULL? Interestingly, if I change all occurrences of "unsigned char" to just "char", it works. However, I'm reading binary data, which to mean should be stored as unsigned char. Is there any way I can make this work? Do I need to modify/specialize std::traits? Also, why is locale even playing an issue here?
I see now that streambufs have a "pubimbue" and a "getloc" (getlocale and imbue locale) functions. Why? I thought streambufs handled reading/writing data to a stream, and that locale-dependant issues were the job of higher classes, such as istream/ostream/iostream?



LinkBack URL
About LinkBacks


