I want to be able to write logging data out to a network device with the same ease as using std::cout
, so I implemented an ostream
wrapper. The wrapper uses the C file IO functions to simulate writing to the device. I am looking for feedback on whether or not I have implemented the ostream
API correctly.
device_ostream.hpp:
#ifndef DEVICE_OSTREAM_HPP__
#define DEVICE_OSTREAM_HPP__
#include <ostream>
#define BUF_SIZE 100
class device_buffer : public std::streambuf
{
public:
device_buffer();
~device_buffer();
int overflow(int ch = EOF);
int sync();
private:
char buffer_[BUF_SIZE];
FILE* fp_;
};
class device_ostream : public std::ostream {
public:
device_ostream() : std::ostream(new device_buffer) {}
~device_ostream() {
delete rdbuf();
}
};
#endif // DEVICE_OSTREAM_HPP__
device_ostream.cpp:
#include "device_ostream.hpp"
device_buffer::device_buffer() : fp_(0) {
memset(buffer_, 0, sizeof(buffer_));
setp(buffer_, buffer_+BUF_SIZE-1);
fp_=fopen("test.bin","wb"); // simulate our device
}
device_buffer::~device_buffer() {
if(fp_)
fclose(fp_); // simulate disconnection from device
}
// ostream fwk notification that buffer is now full
// so write out data now
int device_buffer::overflow(int ch) {
if(ch != EOF) {
*pptr() = ch;
pbump(1);
}
return sync();
}
// function to sync up with hardware device. ie we actually write out data here
int device_buffer::sync() {
if(fp_) {
fwrite(buffer_, 1, size_t(pptr() - pbase()), fp_);
// reset put ptr
setp(pbase(), epptr());
return 0; // success
}
else
return EOF; // return EOF on device failure
}
Code to exercise:
#include "device_ostream.hpp"
int main () {
device_ostream os;
os.write("WRITE", 5);
os << "Hi there, how are you today???" << "\n";
os << "Number: " << 33 << std::endl; // std::endl causes sync to be called even if buffer not full yet
os << "ABCDEFGHIJKLMNOPQRSTUVWXYZ" << std::endl;
os << "abcdefghijklmnopqrstuvwxyz" << std::endl;
os << "ABCDEFGHIJKLMNOPQRSTUVWXYZ" << std::endl;
if(os)
os << "abcdefghijklmnopqrstuvwxyz" << std::endl;
return 0;
}
BUF_SIZE
should definitely be a member constant ofdevice_buffer
. \$\endgroup\$