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

#ifndef FILEIOSTREAM_H_
#define FILEIOSTREAM_H_

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

#include <cstdio>
#include <sys/stat.h>

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

    /// Constructor
    FileIOStream( FILE* file = NULL, bool autoClose = false );

    /// Constructor
    FileIOStream( const char* filename, bool clobber );

    virtual ~FileIOStream();

    void close();

    /// reads num bytes from buffer to the output buffer/stream
    virtual IOStream& read( char* buffer, size_t num );

    /// Change the assoicated file
    void setFile( FILE* file, const char* filename )
    {
        file_ = file;
        filename_ = filename;
    }

    bool seek( unsigned int location );

    virtual bool eof();

    virtual void clearErr();

    bool isReadable()
    {
        return NULL != file_;
    }

    const char* getName()
    {
        return filename_.cStr();
    }

    const Str& getFilename()
    {
        return filename_;
    }

    const struct stat getStat();

    /// writes num bytes from buffer to the output buffer/stream
    IOStream& write( const char* buffer, size_t num );

    /// writes zero-terminated buffer to the output buffer/stream
    virtual IOStream& write( const char* buffer )
    {
        return write( buffer, strlen( buffer ) );
    }

    /// Change the assoicated file
    void setFile( FILE* file )
    {
        file_ = file;
    }

    int tell();

    void flush();

    bool open( const char* filename, bool clobber );

    bool isWritable()
    {
        return NULL != file_;
    }

protected:
    FILE* file_;
    bool autoClose_;
    Mutex fileMutex_;

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

#endif /*FILEIOSTREAM_H_*/
