How do I use basic_filebuf with element type other than char?
Question
Say I want to read the contents of a file using basic_filebuf
. I have a type called boost::uintmax_t
which has a size of 8 bytes
. I am trying to write the following:
typedef basic_filebuf<uintmax_t> file;
typedef istreambuf_iterator<uintmax_t> ifile;
file f;
vector<uintmax_t> data, buf(2);
f.open("test.txt", std::ios::in | std::ios::binary);
f.pubsetbuf(&buf[0], 1024);
ifile start(&f), end;
while(start != end)
{
data.push_back(*start);
start++;
}
The problem is that some of the bytes
get read, others don't. For example, lets say there are 9 bytes
in the file numbered 1-9
:
|1|2|3|4|5|6|7|8|9|
When I run the above code, only one element is pushed back into data
, which contains 4 bytes
only from the original data in f
:
[0|0|0|0|4|3|2|1] --> only element in [data]
What am I doing wrong? This is my first time to use basic_filebuf
directly, though I know how to use filebuf
.
Solution
A basic_filebuf deals with an "internal" char type and an "external" one. The "external" one is the contents of the file, and is always bytes. The "internal" one is the template parameter, and is the one used in its interface with the program. To convert between the two, basic_filebuf uses the codecvt facet of its locale.
So if you want it to write directly the bytes you give it, you have two options:
- use a "degenerate" codecvt that only casts between the "internal" and "external" encodings instead of trying to perform a conversion.
- use a basic_filebuf, make sure to use the "classic" locale, and do the cast to char yourself
OTHER TIPS
Objects of type basic_filebuf are created with an internal buffer of type char * regardless of the char_type specified by the type parameter Elem. This means that a Unicode string (containing wchar_t characters) will be converted to an ANSI string (containing char characters) before it is written to the internal buffer. To store Unicode strings in the buffer, create a new buffer of type wchar_t and set it using the basic_streambuf::pubsetbuf() method.
from http://msdn.microsoft.com/en-us/library/tzf8k3z8(VS.80).aspx