//+--------------------------------------------------------------------------- // // Copyright (C) 1996, Microsoft Corporation. // // File: fmapio.cxx // // Contents: A class to read lines from a unicode or an ascii file. // // History: 96/Jan/3 DwightKr Created // Aug 20 1996 SrikantS Moved from web // //---------------------------------------------------------------------------- #include #pragma hdrstop //+--------------------------------------------------------------------------- // // Member: CFileMapView::CFileMapView - public // // Synopsis: Maps a file in its entirety // // Arguments: [wcsFileName] - full path of file to map // // History: 96/Jan/03 DwightKr created // //---------------------------------------------------------------------------- CFileMapView::CFileMapView( WCHAR const * wcsFileName ) : _hFile(INVALID_HANDLE_VALUE), _hMap(0), _pbBuffer(0), _cbBuffer(0), _IsUnicode(FALSE) { // // Open the file // _hFile = CreateFile( wcsFileName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0 ); if ( INVALID_HANDLE_VALUE == _hFile ) { qutilDebugOut(( DEB_IWARN, "Unable to open %ws for mapping\n", wcsFileName )); THROW( CException() ); } _cbBuffer = GetFileSize( _hFile, 0 ); END_CONSTRUCTION(CFileMapView); } //+--------------------------------------------------------------------------- // // Member: CFileMapView::~CFileMapView - public // // Synopsis: Release handles & unmap file // // History: 96/Jan/03 DwightKr created // //---------------------------------------------------------------------------- CFileMapView::~CFileMapView() { if ( 0 != _pbBuffer ) { UnmapViewOfFile( _pbBuffer ); } if ( 0 != _hMap ) { CloseHandle( _hMap ); } if ( INVALID_HANDLE_VALUE != _hFile ) { CloseHandle( _hFile ); } } //+--------------------------------------------------------------------------- // // Member: CFileMapView::Init - public // // Synopsis: Maps the file // // History: 96/Jan/03 DwightKr created // //---------------------------------------------------------------------------- void CFileMapView::Init() { // // Create a map of the file // _hMap = CreateFileMapping( _hFile, 0, PAGE_READONLY, 0, _cbBuffer, 0 ); if ( 0 == _hMap ) { qutilDebugOut(( DEB_IWARN, "CreateFileMapping failed\n" )); THROW( CException() ); } _pbBuffer = (BYTE *) MapViewOfFile( _hMap, FILE_MAP_READ, 0, 0, _cbBuffer ); if ( 0 == _pbBuffer ) { qutilDebugOut(( DEB_IWARN, "MapViewOfFile failed\n" )); THROW( CException() ); } _IsUnicode = (GetBufferSize() > 3) && // At least one unicode character (_pbBuffer[0] == 0xFF) && // Begins with OxFF 0xFE (_pbBuffer[1] == 0xFE) && ((GetBufferSize() & 1) == 0); // Must be an even # of bytes } //+--------------------------------------------------------------------------- // // Member: CFileBuffer::CFileBuffer - public // // Synopsis: Constructor // // Arguments: [fileMap] - a mapped file // // History: 96/May/06 DwightKr created // //---------------------------------------------------------------------------- CFileBuffer::CFileBuffer( CFileMapView & fileMap, UINT codePage ) { // // We need to return unicode data from methods of this class. If the file // contains ASCII data, convert it to unicode here. // if ( !fileMap.IsUnicode() ) { _cwcFileBuffer = MultiByteToXArrayWideChar( fileMap.GetBuffer(), fileMap.GetBufferSize(), codePage, _pwBuffer ); _wcsNextLine = _pwBuffer.Get(); } else { // // We have a unicode file. Skip past the leading 0xFF - 0xFE bytes // _wcsNextLine = (WCHAR *) (fileMap.GetBuffer() + 2); _cwcFileBuffer = (fileMap.GetBufferSize() - 2) / sizeof(WCHAR); } END_CONSTRUCTION(CFileBuffer); } //+--------------------------------------------------------------------------- // // Member: CFileBuffer::fgetsw - public // // Synopsis: Gets the next line from the file // // Arguments: [wcsLine] - buffer to return next line into // [cwcLine] - size of the buffer in characters // // History: 96/May/06 DwightKr created // //---------------------------------------------------------------------------- ULONG CFileBuffer::fgetsw( XGrowable & xLine ) { ULONG cwcCopied = 0; // // Copy characters upto either cwcLine, a CR, or the end of // the string. // while ( (_cwcFileBuffer > 0) ) { xLine.SetSize( cwcCopied + 1 ); xLine[ cwcCopied] = *_wcsNextLine; cwcCopied++; _wcsNextLine++; _cwcFileBuffer--; // // If we just copied over a CR, then break out of the // loop; we've found the end of a line. // if ( L'\n' == xLine[ cwcCopied - 1] ) { break; } } xLine.SetSize( cwcCopied + 1 ); xLine[ cwcCopied ] = 0; // Null terminate return cwcCopied; }