Trevor Robinson
Trevor Robinson

Reputation: 16564

Recommendations for a C++ polymorphic, seekable, binary I/O interface

I've been using std::istream and ostream as a polymorphic interface for random-access binary I/O in C++, but it seems suboptimal in numerous ways:

I like the simplified interface provided by the Boost.Iostreams Device concept, but it's provided as function templates rather than a polymorphic class. (There is a device class, but it's not polymorphic and is just an implementation helper class not necessarily used by the supplied device implementations.) I'm primarily using large disk files, but I really want polymorphism so I can easily substitute alternate implementations (e.g. use stringstream instead of fstream for unit tests) without all the complexity and compile-time coupling of deep template instantiation.

Does anyone have any recommendations of a standard approach to this? It seems like a common situation, so I don't want to invent my own interfaces unnecessarily. As an example, something like java.nio.FileChannel seems ideal.

My best solution so far is to put a thin polymorphic layer on top of Boost.Iostreams devices. For example:

class my_istream
{
public:
    virtual std::streampos seek(stream_offset off, std::ios_base::seekdir way) = 0;
    virtual std::streamsize read(char* s, std::streamsize n) = 0;
    virtual void close() = 0;
};

template <class T>
class boost_istream : public my_istream
{
public:
    boost_istream(const T& device) : m_device(device)
    {
    }

    virtual std::streampos seek(stream_offset off, std::ios_base::seekdir way)
    {
        return boost::iostreams::seek(m_device, off, way);
    }

    virtual std::streamsize read(char* s, std::streamsize n)
    {
        return boost::iostreams::read(m_device, s, n);
    }

    virtual void close()
    {
        boost::iostreams::close(m_device);
    }

private:
    T m_device;
};

Upvotes: 5

Views: 753

Answers (2)

Trevor Robinson
Trevor Robinson

Reputation: 16564

I just ended up going with a set of abstract interfaces similar to what I outlined in the question. There don't seem to be any lightweight, polymorphic standards for this...

Upvotes: 0

Elrohir
Elrohir

Reputation: 1486

Did you have a look an Qt's QIODevice class and subclasses? I'm not quite sure if it fits your needs, but maybe its worth a try: QIODevice.

Upvotes: 1

Related Questions