/* (C) 2005 The Measurement Factory Licensed under the Apache License, Version 2.0 */ #ifndef TMF_BASE_XSTD__FXSTREAM_H #define TMF_BASE_XSTD__FXSTREAM_H #if defined(XSTD_HAVE_STREAMBUF) # include #elsif defined(XSTD_HAVE_STREAMBUF_H) # include #endif // XXX: Keep in sync with the same classes in Polygraph's src/xstd/h/sstream.h // A streambuf with a fixed-size user-owned storage area. // The implementation is incomplete and too forgiving, // but hopefully sufficient. class FixedStreamBuf: public std::streambuf { public: // based on http://www.dbforums.com/showthread.php?t=776452 FixedStreamBuf(char_type *buffer, std::streamsize size) { setp(buffer, buffer + size); setg(buffer, buffer, buffer + size); } // set position relative to dir virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) { pos_type result = pos_type(-1); if (mode & std::ios_base::out) { // convert to absolute offset if needed if (dir == std::ios_base::cur) off = pptr() - pbase() + off; else if (dir == std::ios_base::end) off = epptr() - pbase() - off; result = seekpos(off); } // XXX: support std::ios_base::in mode return result; } // set absolute position (i.e., relative to the base) virtual pos_type seekpos(pos_type off, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) { pos_type result = pos_type(-1); if (mode & std::ios_base::out) { if (0 <= off && off <= (epptr() - pbase())) { pbump(off - pos_type(pptr() - pbase())); result = off; } } // XXX: support std::ios_base::in mode return result; } }; // an output stream that uses our FixedStreamBuf class OFixedStream: public std::ostream { public: OFixedStream(char_type *buffer, std::streamsize size): theBuffer(buffer, size) { this->init(&theBuffer); // set our custom buffer } private: FixedStreamBuf theBuffer; }; // More "fixed size stream buffer" ideas at // http://www.inf.uni-konstanz.de/~kuehl/c++/iostream/ // http://www.velocityreviews.com/forums/showpost.php?p=1532770 #endif