-
February 8th, 2009, 09:47 AM
#1
Writing my own standard-compatible file buffer
Hi,
I am trying to implement a new type similar to std::ifstream which works in an MPI-parallel environment. My approach is to write a dedicated buffer which inherits from std::streambuf; then, I write a dedicated file-stream class which inherits from from std::istream and uses the dedicated buffer.
My implementation works with the gcc compiler, it works with the Intel compiler, but it doesn't work with the Portland compiler (it always reads zeros when reading an input file). I suspect that my implementation is not fully standard compatible, and I wonder if somebody can help me with this issue. Here is a minimal version of my code, which does NOT work with Portland. This minimal version doesn't do any parallelism. It basically encapsulates a std::streambuf object by fowarding all function calls to the original std::streambuf. This is kind of trivial, and I find myself unable to figure out what's wrong here.
Thank you in advance for your help.
Code:
class ParBuf : public std::streambuf {
public:
ParBuf(std::streambuf* originalBuf_);
protected:
virtual int_type overflow (int_type c);
virtual std::streamsize xsputn(const char* s, std::streamsize num);
virtual int_type uflow();
virtual int_type underflow();
virtual std::streamsize xsgetn (char* s, std::streamsize num);
private:
std::streambuf* originalBuf;
};
class my_ifstream : public std::istream {
public:
my_ifstream();
explicit my_ifstream(const char * filename,
openmode mode = in );
~my_ifstream();
std::streambuf* rdbuf() const;
bool is_open();
void open(const char* filename, openmode mode = in);
void close();
private:
std::filebuf fbuf;
mutable ParBuf mybuf;
};
ParBuf::ParBuf(std::streambuf* originalBuf_)
: originalBuf(originalBuf_)
{ }
std::streambuf::int_type
ParBuf::overflow (std::streambuf::int_type c) {
int_type returnVal = c;
if (c != EOF) {
returnVal = originalBuf->sputc((char)c);
}
return returnVal;
}
std::streamsize
ParBuf::xsputn(const char* s, std::streamsize num) {
return originalBuf->sputn(s,num);
}
std::streambuf::int_type
ParBuf::uflow() {
int_type = originalBuf->sbumpc();
return value;
}
std::streambuf::int_type
ParBuf::underflow() {
int_type value = originalBuf->sgetc();
return value;
}
std::streamsize
ParBuf::xsgetn (char* s, std::streamsize num) {
std::streamsize sizeRead = originalBuf->sgetn(s, num);
return sizeRead;
}
my_ifstream::my_ifstream() : std::istream(NULL), fbuf(), mybuf(&fbuf) {
init(&mybuf);
}
my_ifstream::my_ifstream(const char * filename, openmode mode)
: std::istream(NULL), fbuf(), mybuf(&fbuf)
{
init(&mybuf);
open(filename, mode);
}
my_ifstream::~my_ifstream()
{ }
std::streambuf*
my_ifstream::rdbuf() const {
return &mybuf;
}
bool my_ifstream::is_open() {
return fbuf.is_open();
}
void my_ifstream::open(const char* filename, openmode mode)
{
int ok = (bool) fbuf.open(filename, mode | ios_base::in);
if (!ok) {
this->setstate(ios_base::failbit);
}
}
void my_ifstream::close() {
int ok = (bool) fbuf.close();
if (!ok) {
setstate(ios_base::failbit);
}
}
Last edited by signalingNaN; February 8th, 2009 at 12:09 PM.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|