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

#include "FileOutStream.h"

FileOutStream::FileOutStream( FILE* file, bool autoClose )
    : file_( file ),
      autoClose_( autoClose ),
      filename_( "unknown" )
{}

/// Constructor
FileOutStream::FileOutStream( const char* filename, bool append, bool rewrite )
    : file_( NULL ),
      autoClose_( true ),
      filename_( filename )
{
    open( filename, append, rewrite );
}

FileOutStream::~FileOutStream()
{
    if( autoClose_ )
    {
        close();
    }
}

/// writes num bytes from buffer to the output buffer/stream
OutStream& FileOutStream::write( const char* buffer, size_t num )
{
    MutexLocker locker( fileMutex_ );
    if( NULL != file_ )
    {
        lastWritten_ = fwrite( ( const void * ) buffer, 1, num, file_ );
    }
    return *this;
}

bool FileOutStream::seek( unsigned int location )
{
    MutexLocker locker( fileMutex_ );
    if( NULL != file_ )
    {
        return fseek( file_, location, SEEK_SET ) == 0;
    }
    return false;
}

int FileOutStream::tell()
{
    MutexLocker locker( fileMutex_ );
    if( NULL != file_ )
    {
        return ftell( file_ );
    }
    return 0;
}

void FileOutStream::close()
{
    MutexLocker locker( fileMutex_ );
    if( NULL != file_ && stdout != file_ && stderr != file_ )
    {
        fclose( file_ );
        file_ = NULL;
    }
}

void FileOutStream::flush()
{
    MutexLocker locker( fileMutex_ );
    if( NULL != file_ )
    {
        fflush( file_ );
    }
}

bool FileOutStream::open( const char* filename, bool append, bool rewrite )
{
    close();
    MutexLocker locker( fileMutex_ );
    if( append )
    {
        file_ = fopen( filename, "ab" );
    }
    else if( rewrite )
    {
        file_ = fopen( filename, "r+b" );
    }
    else
    {
        file_ = fopen( filename, "wb" );
    }
    return NULL != file_;
}
