
On 29.04.2011 11:52, Mathias Gaunard wrote:
int main() { fstream f("binary_stream_example.dat", std::ios_base::trunc | std::ios_base::in | std::ios_base::out | std::ios_base::binary);
int32_t x = 0x01020304; int32_t y = 0;
f<< bin(x); // write 4 bytes f.seekg(0); f>> bin(y); // read 4 bytes
I think it's a bad idea.
If you want to do that kind of thing, you should use the streambuf abstraction directly, along with its sgetn and sputn member functions. It will be much more efficient.
I am not agree. (If you *want* to use the streambuf directly, you should :) But don't force everyone to use this low-level tool.) I think binary stream IO shouldn't be implemented on the manipulator-like basis, an independent raw_stream class with minimal and full functionality is better. Then below I don't tied to proposed syntax (on the manipulator-like basis). A stream provide automatic "type deduction" / type safety, therefore an user shouldn't specify the type by hand: double d; char c; raw_stream raw; raw << d << c; raw >> d >> c; but with streambuf it should: std::streambuf* buf = . . . ; double d = . . . ; buf->sputn(reinterpret_cast<char const*>(&d), sizeof( double )); int i = . . . ; buf->sputn(reinterpret_cast<char const*>(&i), sizeof( int )); It's error-prone; and the user to simplify its job should write template wrapper like: template<typename T> void put(std::streambuf* buf, T value) { buf->sputn(reinterpret_cast<char const*>(&value), sizeof( T )); } template<typename T> T get(std::streambuf* buf) { T value; buf->sgetn(reinterpret_cast<char*>(&value), sizeof( T )); return value; } ..but a similar "type deduced" / type-safe code already written for stream (in more convenient manner) and placed in library for general use. sgetn() / sputn() functions doesn't support endianess directly, the user should use something like reverse_iterator<char*> explicitly. In stream's environment endianess can be implemented on the manipulator basis: raw_stream raw; raw << ordering::little_endian << 1.0 << 'X' << 127; double d; char c; int i; raw >> d >> c >> ordering::big_endian >> i; std::cout << d << " - " << c << " - " << std::hex << std::showbase << i << std::endl; // out: 1 - X - 0x7f000000 // on a little-endian machine Streams are highly extensible with a well-known to every C++ programmer interface; library can provide shift operators overloaded for std::vector<>, std::basic_string<>, std::deque<> and std::list<> in a separate library's header: std::vector<int> v; raw << v; // trivial implementation raw >> v; raw << some_user_type(); // if operator << (raw_stream&, some_user_type) exists and found via ADL With streambuf it's not so convenient. -- - thank you for your indulgence about my poor english :)