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

#include "DeviceIOStream.h"

#include <fcntl.h>
#include <unistd.h>

#include "data/StrValue.h"
#include "data/Slate.h"

/// Constructor 1
/// argument filename: device filename
DeviceIOStream::DeviceIOStream( const char* filename, bool useHardware )
    : file_( -1 ),
      useHardware_( useHardware ),
      name_( filename )
{
    if( useHardware_ && name_ != "/dev/null" )
    {
        file_ = ::open( name_.cStr(), O_RDWR );
    }
}

/// Constructor 2
/// argument configUri: device name in vehicle.cfg file
/// argument logger
DeviceIOStream::DeviceIOStream( const ConfigURI& configUri, bool useHardware, Logger& logger )
    : file_( -1 ),
      useHardware_( useHardware ),
      name_( GetFilename( configUri, logger ).cStr() )
{
    if( useHardware_ && name_ != "/dev/null" )
    {
        file_ = ::open( name_.cStr(), O_RDWR );
        if( file_ == - 1 )
        {
            logger.syslog( "Could not open device '" + name_ + "' at " + configUri, Syslog::ERROR );
        }
    }
}

DeviceIOStream::~DeviceIOStream()
{
    if( -1 != file_ )
    {
        ::close( file_ );
    }
}

/// reads num bytes from the stream to the buffer
IOStream& DeviceIOStream::read( char* buffer, size_t num )
{
    if( -1 != file_ )
    {
        ssize_t bytesRead = ::read( file_, ( void * )buffer, num );
        if( bytesRead > 0 )
        {
            setBytesRead( bytesRead );
        }
    }
    return *this;
}

/// Writes num bytes from buffer to the output buffer/stream
OutStream& DeviceIOStream::write( const char* buffer, size_t num )
{
    if( -1 != file_ )
    {
        lastWritten_ = ::write( file_, ( const void * )buffer, num );
    }
    return *this;
}

Str DeviceIOStream::GetFilename( const ConfigURI& configUri, Logger& logger )
{
    StrValue filename( "/dev/invalid" );
    Slate::ReadOnce( configUri, filename, logger );
    return filename.asString();
}

