INPSTRM.CXX
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:6k
源码类别:

Windows编程

开发平台:

Visual C++

  1. //+---------------------------------------------------------------------------
  2. //
  3. //  Copyright (C) 1992 - 1997 Microsoft Corporation.
  4. //
  5. //  File:       inpstrm.cxx
  6. //
  7. //  Contents:   Memory mapped input stream
  8. //
  9. //  Classes:    CMemoryMappedSerialStream
  10. //
  11. //----------------------------------------------------------------------------
  12. #include <pch.cxx>
  13. #pragma hdrstop
  14. #include <htmlfilt.hxx>
  15. #include <codepage.hxx>
  16. //+-------------------------------------------------------------------------
  17. //
  18. //  Method:     CMemoryMappedInputStream::CMemoryMappedInputStream
  19. //
  20. //  Synopsis:   Constructor
  21. //
  22. //--------------------------------------------------------------------------
  23. CMemoryMappedInputStream::CMemoryMappedInputStream()
  24.     : _bytesReadFromMMBuffer(0),
  25.       _charsReadFromTranslatedBuffer(0),
  26.       _cwcTranslatedBuffer(0),
  27.       _ulCodePage(LocaleToCodepage(GetSystemDefaultLCID())),
  28.       _fUnGotChar(FALSE),
  29.       _wch(0)
  30. {
  31. }
  32. //+-------------------------------------------------------------------------
  33. //
  34. //  Method:     CMemoryMappedInputStream::~CMemoryMappedInputStream
  35. //
  36. //  Synopsis:   Destructor
  37. //
  38. //--------------------------------------------------------------------------
  39. CMemoryMappedInputStream::~CMemoryMappedInputStream()
  40. {
  41.     if ( _mmStream.Ok() && _mmStreamBuf.Get() != 0 )
  42.         _mmStream.Unmap( _mmStreamBuf );
  43. }
  44. //+-------------------------------------------------------------------------
  45. //
  46. //  Method:     CMemoryMappedInputStream::Init
  47. //
  48. //  Synopsis:   Initialize the memory mapped stream
  49. //
  50. //  Arguments:  [pwszFileName] -- File to be mapped
  51. //
  52. //--------------------------------------------------------------------------
  53. void CMemoryMappedInputStream::Init( WCHAR *pwszFileName )
  54. {
  55.     Win4Assert( pwszFileName );
  56.     _bytesReadFromMMBuffer = 0;
  57.     if ( _mmStream.Ok() )
  58.     {
  59.         _mmStreamBuf.Rewind();
  60.         _mmStream.Close();
  61.     }
  62.     _mmStream.Open( pwszFileName,
  63.                     GENERIC_READ,
  64.                     FILE_SHARE_READ,
  65.                     OPEN_EXISTING );
  66.     if ( _mmStream.Ok() )
  67.     {
  68.         _mmStreamBuf.Init( &_mmStream );
  69.         if ( !_mmStream.isEmpty() )
  70.             _mmStreamBuf.Map( HTML_FILTER_CHUNK_SIZE );
  71.     }
  72.     else
  73.     {
  74.         htmlDebugOut(( DEB_ERROR, "Throwing FILTER_E_ACCESS in CMemoryMappedInputStream::Initn" ));
  75.         throw( CException( FILTER_E_ACCESS ) );
  76.     }
  77. }
  78. //+-------------------------------------------------------------------------
  79. //
  80. //  Method:     CMemoryMappedInputStream::GetChar
  81. //
  82. //  Synopsis:   Read the next consecutive character from the input file
  83. //
  84. //--------------------------------------------------------------------------
  85. WCHAR CMemoryMappedInputStream::GetChar()
  86. {
  87.     if ( !_mmStream.Ok() || !_mmStreamBuf.Get() )
  88.         throw( CException( FILTER_E_ACCESS ) );
  89.     if ( _fUnGotChar )
  90.     {
  91.         _fUnGotChar = FALSE;
  92.         return _wch;
  93.     }
  94.     if ( _charsReadFromTranslatedBuffer == _cwcTranslatedBuffer )
  95.     {
  96.         if ( _bytesReadFromMMBuffer == _mmStreamBuf.Size() )
  97.         {
  98.             if ( _mmStreamBuf.Eof() )
  99.                 return WEOF;
  100.     
  101.             //
  102.             // Try to map in next chunk of file
  103.             //
  104.             _mmStreamBuf.Map( HTML_FILTER_CHUNK_SIZE );
  105.             _bytesReadFromMMBuffer = 0;
  106.     
  107.             Win4Assert( _mmStreamBuf.Size() > _bytesReadFromMMBuffer );
  108.         }
  109.         ULONG cChUnread = _mmStreamBuf.Size() - _bytesReadFromMMBuffer;
  110.         //
  111.         // Since, the wide chars are precomposed, assume 1:1 translation mapping
  112.         //
  113.         ULONG cChIn = TRANSLATED_CHAR_BUFFER_LENGTH;
  114.         if ( cChIn > cChUnread )
  115.         {
  116.             //
  117.             // Not enough chars in input
  118.             //
  119.             cChIn = cChUnread;
  120.         }
  121.         ULONG cwcActual = 0;
  122.         do
  123.         {
  124.             cwcActual = MultiByteToWideChar( _ulCodePage,
  125.                                              MB_PRECOMPOSED,
  126.                                              (char *) _mmStreamBuf.Get() + _bytesReadFromMMBuffer,
  127.                                              cChIn,
  128.                                              _awcTranslatedBuffer,
  129.                                              TRANSLATED_CHAR_BUFFER_LENGTH );
  130.             if ( cwcActual == 0 )
  131.             {
  132.                 if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER && cChIn >= 2 )
  133.                     cChIn /= 2;
  134.                 else
  135.                 {
  136.                     Win4Assert( !"CMemoryMappedInputStream::GetChar, cannot translate single char" );
  137.                     throw( CException( GetLastError() ) );
  138.                 }
  139.             }
  140.         } while( cwcActual == 0 );
  141.         Win4Assert( _bytesReadFromMMBuffer + cChIn <= _mmStreamBuf.Size() );
  142.         Win4Assert( cwcActual <= TRANSLATED_CHAR_BUFFER_LENGTH );
  143.         _bytesReadFromMMBuffer += cChIn;
  144.         _charsReadFromTranslatedBuffer = 0;
  145.         _cwcTranslatedBuffer = cwcActual;
  146.     }
  147.     return _awcTranslatedBuffer[_charsReadFromTranslatedBuffer++];
  148. }
  149. //+-------------------------------------------------------------------------
  150. //
  151. //  Method:     CMemoryMappedInputStream::UnGetChar
  152. //
  153. //  Synopsis:   Pushes(logically) a character back into the input stream
  154. //
  155. //  Arguments:  [wch] -- Char to be pushed back
  156. //
  157. //--------------------------------------------------------------------------
  158. void CMemoryMappedInputStream::UnGetChar( WCHAR wch )
  159. {
  160.     //
  161.     // We can unget only one char at a time
  162.     //
  163.     Win4Assert( !_fUnGotChar );
  164.     _fUnGotChar = TRUE;
  165.     _wch = wch;
  166. }
  167. //+-------------------------------------------------------------------------
  168. //
  169. //  Method:     CMemoryMappedInputStream::Eof
  170. //
  171. //  Synopsis:   Is this the end of input file ?
  172. //
  173. //--------------------------------------------------------------------------
  174. BOOL CMemoryMappedInputStream::Eof()
  175. {
  176.     if ( !_mmStream.Ok() )
  177.         throw( CException( FILTER_E_ACCESS ) );
  178.     if ( _fUnGotChar )
  179.         return FALSE;
  180.     if ( _charsReadFromTranslatedBuffer < _cwcTranslatedBuffer )
  181.         return FALSE;
  182.     if ( _bytesReadFromMMBuffer == _mmStreamBuf.Size() )
  183.         return _mmStreamBuf.Eof();
  184.     else
  185.         return FALSE;
  186. }