/** \file
 *
 *  Contains the StrIOStream class declaration.
 *
 *  Copyright (c) 2007,2008,2009 MBARI
 *  MBARI Proprietary Information.  All Rights Reserved
 *
 */

#ifndef STRIOSTREAM_H_
#define STRIOSTREAM_H_

#include "IOStream.h"
#include "utils/Str.h"

/**
 *  Wraps a Str with an IOStream class.
 *
 *  Part of an attempt to avoid the
 *  standard template library
 *
 *  \ingroup io
 */
class StrIOStream : public IOStream
{
public:

    /// Constructor
    StrIOStream( Str& str )
        : str_( str ),
          readPos_( 0 )
    {}

    virtual ~StrIOStream()
    {}

    /// reads num bytes from stream to the buffer
    virtual InStream& read( char* buffer, size_t num )
    {
        if( readPos_ >= str_.length() )
        {
            num = 0;
        }
        if( str_.length() - readPos_ < num )
        {
            num = str_.length() - readPos_;
        }
        memcpy( buffer, str_.cStr() + readPos_, num );
        //buffer[num] = 0;  // Can cause buffer overflow!
        readPos_ += num;
        setBytesRead( num );
        return *this;
    }

    const char* getName()
    {
        return "String";
    }

    void clear()
    {
        rewind();
        str_ = Str::EMPTY_STR;
    }

    void rewind()
    {
        readPos_ = 0;
    }

    /// indicates whether the stream can actually be read from.
    virtual bool isReadable()
    {
        return !eof();
    }

    /// Indicates if the end of file has been reached
    virtual bool eof()
    {
        return str_.length() <= readPos_;
    }

    /// writes num bytes from buffer to the output buffer/stream
    virtual OutStream& write( const char* buffer, size_t num )
    {
        lastWritten_ = str_.size();
        str_ += Str( buffer, num );
        lastWritten_ = str_.length() - lastWritten_;
        return *this;
    }

    bool isWritable()
    {
        return true;
    }

protected:
    Str& str_;
    size_t readPos_;

private:
    // Note that the copy constructor below is private and not given a body.
    // Any attempt to call it will return a compiler error.
    StrIOStream( const StrIOStream& old ); // disallow copy constructor

};

#endif /*STRIOSTREAM_H_*/
