Reputation: 1141
I have wrote my own input streambuf, which should work with gzipped files. Here is its interface:
class gzstreambuf : public std::streambuf
{
static const int bufferSize = 8192;
public:
gzstreambuf();
~gzstreambuf();
int is_open() { return opened_; }
gzstreambuf* open(const std::string& name, int mode);
std::streampos pubseekpos(std::streampos offset, std::ios_base::openmode which = std::ios_base::in);
int underflow();
private:
void close();
private:
gzFile file;
char opened;
char buffer[bufferSize];
int mode;
std::string fileName;
};
I am trying to write function which will take the file name and return ordinary streambuf in case if file is non gzipped ,and gzstreambuf otherwise:
boost::shared_ptr<std::streambuf>
getStreamBuffer(const std::string& fileName)
{
const bool isGzippedFile = ( fileName.size() >= 3 && ".gz" == fileName.substr(fileName.size() -3));
std::ifstream is(fileName.c_str());
boost::shared_ptr<std::streambuf> strBuf;
if(! isGzippedFile)
{
strBuf.reset(is.rdbuf());
}
else
{
boost::shared_ptr<gzstreambuf> gz(new gzstreambuf);
gz->open(fileName, std::ios_base::in);
strBuf = gz;
}
return strBuf;
}
But this implementation will not work in case of non gzipped files, because is
object will be destroyed after call of this function.
How can I resolve this?
Upvotes: 0
Views: 853
Reputation: 409356
You have two major problems with the getStreamBuffer
function, even though both are really the same and both leading to undefined behavior:
Your use of std::auto_ptr
. You then use this smart pointer to get the raw pointer contained in the smart pointer, just to put in another smart pointer. However, the problem is that once the std::auto_ptr
object goes out of scope, the contained pointer will be deleted, so the other smart pointer will now point to a deleted object.
The second problem is the same as the previous, but with the returned smart pointer. You get the raw pointer from strBuf
and return that. However, since strBuf
is not really shared and its reference counter is one, the pointer will be deleted once strBuf
goes out of scope, making the returned pointer be a pointer to a now deleted object.
The first problem can be solved by not using std::auto_ptr
at all, or using e.g. std::shared_ptr
and use simple assignment to strBuf
.
The second problem can be solved by simply returning strBuf
.
Upvotes: 3