246 lines
5.9 KiB
C++
246 lines
5.9 KiB
C++
// 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;
|
|
}
|