//
//  Title:  Output Byte Stream Class
//
//  Copyright 1999, Colosseum Builders, Inc.
//  All rights reserved.
//
//  Colosseum Builders, Inc. makes no warranty, expressed or implied
//  with regards to this software. It is provided as is.
//
//  Author:  John M. Miano (miano@colosseumbuilders.com)
//
//  Date:    March 15, 1999
//
//  Version: 1
//
//  Description:
//
//

#include "outputbytestream.h"
#include "checks.h"

namespace Colosseum
{

//
//  Description:
//
//    Default Constructor
//
OutputByteStream::OutputByteStream ()
: bit_position (-1)
{
  return ;
}

//
//  Description:
//
//    Function to write a block of bytes.
//
//  Parameters:
//
//    buffer : The output buffer
//    count : The number of bytes to write
//
void OutputByteStream::write (const char *buffer, int count)
{
  ASSERT (bit_position == -1) ;

  while (count > 0)
  {
    if (count <= buffer_limit - current_byte)
    {
      memcpy (current_byte, buffer, count) ;
      current_byte += count ;
      count = 0 ;
    }
    else
    {
      int outputcount = buffer_limit - current_byte ;
      memcpy (current_byte, buffer, outputcount) ;
      buffer_limit += outputcount ;
      buffer += outputcount ;
      count -= outputcount ;
      flushBuffer () ;
    }
  }
  return ;
}

//
//  Description:
//
//    This function writes a single byte to the output stream.
//
//  Parameters:
//
//    value : The byte to write
//
void OutputByteStream::writeByte (UBYTE1 value)
{
  ASSERT (bit_position == -1) ;
  if (current_byte >= buffer_limit)
    flushBuffer () ;
  *current_byte = value ;
  ++ current_byte ;
  return ;
}
//
//  Description:
//
//    This function writes a 2-byte integer to the output stream
//    in big endian format.
//
//  Parameters:
//
//    value : The value to output
//
void OutputByteStream::writeBigEndianWord (UBYTE2 value)
{
  ASSERT (bit_position == -1) ;
  if (current_byte + sizeof (value) >= buffer_limit)
    flushBuffer () ;

  *reinterpret_cast<UBYTE2*>(current_byte) = SystemToBigEndian (value) ;
  current_byte += sizeof (value) ;
  if (current_byte >= buffer_limit)
    flushBuffer () ;
  return ;
}
//
//  Description:
//
//    This function writes a 4-byte integer to the output stream
//    in big endian format.
//
//  Parameters:
//
//    value : THe value to output
//
void OutputByteStream::writeBigEndianLong (UBYTE4 value)
{
  ASSERT (bit_position == -1) ;
  if (current_byte + sizeof (value) >= buffer_limit)
    flushBuffer () ;

  *reinterpret_cast<UBYTE4*>(current_byte) = SystemToBigEndian (value) ;
  current_byte += sizeof (value) ;
  if (current_byte >= buffer_limit)
    flushBuffer () ;
  return ;
}
//
//  Description:
//
//    This function puts the output stream in bit mode.
//
//  Parameters:
//
//    initialposition : The first bit position (usually 8 or 0)
//
void OutputByteStream::enterBitMode (int initialposition)
{
  ASSERT (bit_position == -1) ;
  if (current_byte >= buffer_limit)
    flushBuffer () ;
  bit_position = initialposition ;
  *current_byte = 0 ;
  return ;
}
//
//  Description:
//
//    This function returns the number of bytes remaining in the 
//    output buffer
//
//  Return Value:
//
//    The number of bytes remaining in the output buffer.
//
unsigned int OutputByteStream::remainingBufferSpace () const
{
  unsigned int result = buffer_limit - current_byte ;
  return result ;
}


} // End Namespace Colosseum
