
//
//  Title:  JpegInputMapStream Implementation
//
//  Copyright 1997-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:
//
//    JpegInputMapStream implements JPEG input through a Windows file mapping.
//
//  Revision History:
//
//

#include "jpginputmapstream.h"
using namespace std ;

namespace Colosseum
{
//
//  Description:
//
//    Default Constructor
//
JpegInputMapStream::JpegInputMapStream ()
: is_open (false),
  file_mapping (0),
  file_handle (0)
{
  return;
}
//
//  Description:
//    
//    Class Destructor
//
JpegInputMapStream::~JpegInputMapStream ()
{
  close () ;
  return ;
}


//
//  Description:
//
//    This function tells the caller if the input stream is open.
//
//  Return Value:
//
//    true => The mapping is open
//    false => The mapping is not open
//
JpegInputMapStream::operator bool () 
{
  return is_open ;
}
//
//  Description:
//
//    This function creates (opens) a file mapping for reading.
//
//  Parameters:
//
//    filename : The name of the file top open.
//
void JpegInputMapStream::open (const std::string &filename) 
{
  OFSTRUCT ofstruct = { sizeof (OFSTRUCT) } ;

  try
  {
    file_handle = OpenFile (filename.c_str (), &ofstruct, OF_READ) ;
    if (file_handle == HFILE_ERROR)
      throw StreamError ("Can't open input file") ;

    file_mapping = CreateFileMapping (reinterpret_cast<HANDLE>(file_handle),
                                            0, // Security
                                            PAGE_READONLY, // Attributes
                                            0,  // Mapping High
                                            0,  // Mapping Low
                                            0) ; // Name
    if (file_mapping == 0)
      throw StreamError ("Can't create file mapping") ;

    map_location = MapViewOfFile(
                    file_mapping, 
                    FILE_MAP_READ, // Access
                    0, // Offset High
                    0, // Offset Low
                    0) ; // Byte Count
    if (map_location == 0)
      throw StreamError ("Can't map input file") ;
  }
  catch (...)
  {
    close () ;
    throw ;
  }

  current_byte = reinterpret_cast<UBYTE1*>(map_location) ;
  long filesize = GetFileSize (reinterpret_cast<HANDLE>(file_handle), 0) ;
  buffer_limit = &current_byte [filesize] ;

  is_open = true ;
  return ;
}
//
//  Description:
//
//    This function closes the input stream and deletes the mapping.
//
void JpegInputMapStream::close () 
{
  is_open = false ;
  UnmapViewOfFile (map_location) ;
  CloseHandle (file_mapping) ;
  CloseHandle (reinterpret_cast<HANDLE>(file_handle)) ;
  map_location = 0 ;
  return ;
}

//
//  Description:
//
//    This function tells the call if the end of teh stream has been reached.
//
//  Return Value:
//
//    true => The end of the stream has been reached.
//    false => The end of the stream has not been reached.
//
bool JpegInputMapStream::endReached ()
{
  bool result = current_byte >= buffer_limit ;
  return result ;
}

//
//  Description:
//
//    This virtual function is supposed to read the input stream and fill
//    fill the input buffer. Since a map "reads" the entire file this is
//    a NoOp.
//
void JpegInputMapStream::fillBuffer ()
{
  return ;
}
//
//  Description:
//
//    This function returns the current position in the input stream.
//
//  Return Value:
//
//    The current input position
//
InputByteStream::POSITIONTYPE JpegInputMapStream::tellg () 
{
  POSITIONTYPE result = reinterpret_cast<UBYTE1*>(map_location) - current_byte ;
  return result ;
}
//
//  Description:
//
//    This function moves the input position to a specific location.
//
//  Parameters:
//
//    position : The absolution position in the input stream to move to.
//
void JpegInputMapStream::seekg (InputByteStream::POSITIONTYPE position)
{
  current_byte = reinterpret_cast<UBYTE1*>(map_location)
               + static_cast<unsigned long>(position) ;
  return ;
}


}  // End Namespace Colosseum
