// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. // // Copyright (c) Microsoft Corporation. All rights reserved #include "Private.h" #include "File.h" #include "SampleIMEBaseStructure.h" //--------------------------------------------------------------------- // // ctor // //--------------------------------------------------------------------- CFile::CFile(UINT codePage) { _codePage = codePage; _fileHandle = nullptr; _pReadBuffer = nullptr; _fileSize = 0; _filePosPointer = 0; _pFileName = nullptr; } //--------------------------------------------------------------------- // // dtor // //--------------------------------------------------------------------- CFile::~CFile() { if (_pReadBuffer) { delete [] _pReadBuffer; _pReadBuffer = nullptr; } if (_fileHandle) { CloseHandle(_fileHandle); _fileHandle = nullptr; } if (_pFileName) { delete [] _pFileName; _pFileName = nullptr; } } //--------------------------------------------------------------------- // // CreateFile // //--------------------------------------------------------------------- BOOL CFile::CreateFile(_In_ PCWSTR pFileName, DWORD desiredAccess, DWORD creationDisposition, DWORD sharedMode, _Inout_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD flagsAndAttributes, _Inout_opt_ HANDLE templateFileHandle) { size_t fullPathLen = wcslen(pFileName); if (!_pFileName) { _pFileName = new (std::nothrow) WCHAR[ fullPathLen + 1 ]; } if (!_pFileName) { return FALSE; } StringCchCopyN(_pFileName, fullPathLen + 1, pFileName, fullPathLen); _fileHandle = ::CreateFile(pFileName, desiredAccess, sharedMode, lpSecurityAttributes, creationDisposition, flagsAndAttributes, templateFileHandle); if (_fileHandle == INVALID_HANDLE_VALUE) { return FALSE; } _fileSize = ::GetFileSize(_fileHandle, NULL); return TRUE; } //--------------------------------------------------------------------- // // SetupReadBuffer // //--------------------------------------------------------------------- BOOL CFile::SetupReadBuffer() { const WCHAR* pWideBuffer = nullptr; _pReadBuffer = (const WCHAR *) new (std::nothrow) BYTE[ _fileSize ]; if (!_pReadBuffer) { return FALSE; } DWORD dwNumberOfByteRead = 0; if (!ReadFile(_fileHandle, (LPVOID)_pReadBuffer, (DWORD)_fileSize, &dwNumberOfByteRead, NULL)) { delete [] _pReadBuffer; _pReadBuffer = nullptr; return FALSE; } if (!IsTextUnicode(_pReadBuffer, dwNumberOfByteRead, NULL)) { // This is ASCII file. // Read file with Unicode conversion. int wideLength = 0; wideLength = MultiByteToWideChar(_codePage, 0, (LPCSTR)_pReadBuffer, dwNumberOfByteRead, NULL, 0); if (wideLength <= 0) { delete [] _pReadBuffer; _pReadBuffer = nullptr; return FALSE; } pWideBuffer = new (std::nothrow) WCHAR[ wideLength ]; if (!pWideBuffer) { delete [] _pReadBuffer; _pReadBuffer = nullptr; return FALSE; } wideLength = MultiByteToWideChar(_codePage, 0, (LPCSTR)_pReadBuffer, (DWORD)_fileSize, (LPWSTR)pWideBuffer, wideLength); if (wideLength <= 0) { delete [] pWideBuffer; delete [] _pReadBuffer; _pReadBuffer = nullptr; return FALSE; } _fileSize = wideLength * sizeof(WCHAR); delete [] _pReadBuffer; _pReadBuffer = pWideBuffer; } else if (_fileSize > sizeof(WCHAR)) { // Read file in allocated buffer pWideBuffer = new (std::nothrow) WCHAR[ _fileSize/sizeof(WCHAR) - 1 ]; if (!pWideBuffer) { delete [] _pReadBuffer; _pReadBuffer = nullptr; return FALSE; } // skip unicode byte-order signature SetFilePointer(_fileHandle, sizeof(WCHAR), NULL, FILE_BEGIN); if (!ReadFile(_fileHandle, (LPVOID)pWideBuffer, (DWORD)(_fileSize - sizeof(WCHAR)), &dwNumberOfByteRead, NULL)) { delete [] pWideBuffer; delete [] _pReadBuffer; _pReadBuffer = nullptr; return FALSE; } _fileSize -= sizeof(WCHAR); delete [] _pReadBuffer; _pReadBuffer = pWideBuffer; } else { return FALSE; } return TRUE; } //+--------------------------------------------------------------------------- // // IsEndOfFile // //---------------------------------------------------------------------------- BOOL CFile::IsEndOfFile() { return _fileSize == _filePosPointer ? TRUE : FALSE; } //+--------------------------------------------------------------------------- // // NextLine // //---------------------------------------------------------------------------- VOID CFile::NextLine() { DWORD_PTR totalBufLen = GetBufferInWCharLength(); if (totalBufLen == 0) { goto SetEOF; } const WCHAR *pwch = GetBufferInWChar(); DWORD_PTR indexTrace = 0; // in char if (FindChar(L'\r', pwch, totalBufLen, &indexTrace) != S_OK) { goto SetEOF; } if (indexTrace >= DWORD_MAX -1) { goto SetEOF; } indexTrace++; // skip CR totalBufLen -= indexTrace; if (totalBufLen == 0) { goto SetEOF; } if (pwch[indexTrace] != L'\n') { _filePosPointer += (indexTrace * sizeof(WCHAR)); return; } indexTrace++; totalBufLen--; if (totalBufLen == 0) { goto SetEOF; } _filePosPointer += (indexTrace * sizeof(WCHAR)); return; SetEOF: _filePosPointer = _fileSize; return; }