vho
vho

Reputation: 1141

How to return streambuf pointer

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

Answers (1)

Some programmer dude
Some programmer dude

Reputation: 409356

You have two major problems with the getStreamBuffer function, even though both are really the same and both leading to undefined behavior:

  1. 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.

  2. 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

Related Questions