mirror of
https://github.com/rizonesoft/Notepad3.git
synced 2026-06-14 21:09:05 +08:00
283 lines
7.6 KiB
C++
283 lines
7.6 KiB
C++
// sktoolslib - common files for SK tools
|
|
|
|
// Copyright (C) 2012, 2020 - Stefan Kueng
|
|
|
|
// This program is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License
|
|
// as published by the Free Software Foundation; either version 2
|
|
// of the License, or (at your option) any later version.
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, write to the Free Software Foundation,
|
|
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <malloc.h>
|
|
#include <crtdbg.h>
|
|
#include "ResourceTextFile.h"
|
|
|
|
CResourceTextFile::CResourceTextFile()
|
|
: m_pszText(NULL)
|
|
, m_eBomAction(NoBomAction)
|
|
, m_eConvertAction(NoConvertAction)
|
|
{
|
|
}
|
|
|
|
CResourceTextFile::CResourceTextFile(const CResourceTextFile &rf)
|
|
{
|
|
if (rf.m_bDoNotDeleteBuffer)
|
|
{
|
|
// buffer is allocated externally or has been detached
|
|
m_pszText = rf.m_pszText;
|
|
}
|
|
else
|
|
{
|
|
m_pszText = new wchar_t[rf.m_nBufLen + 2];
|
|
memset(m_pszText, 0, (rf.m_nBufLen + 2) * sizeof(wchar_t));
|
|
wcsncpy_s(m_pszText, rf.m_nBufLen + 2, rf.m_pszText, rf.m_nBufLen);
|
|
}
|
|
|
|
m_nBufLen = rf.m_nBufLen;
|
|
m_nPosition = 0;
|
|
m_bIsOpen = rf.m_bIsOpen;
|
|
m_bText = rf.m_bText;
|
|
m_bDoNotDeleteBuffer = rf.m_bDoNotDeleteBuffer;
|
|
m_eConvertAction = rf.m_eConvertAction;
|
|
m_eBomAction = rf.m_eBomAction;
|
|
}
|
|
|
|
CResourceTextFile::~CResourceTextFile()
|
|
{
|
|
Close();
|
|
}
|
|
|
|
BOOL CResourceTextFile::Open(HINSTANCE hInstance,
|
|
LPCWSTR lpszResId,
|
|
LPCWSTR lpszResType /*= L"TEXT"*/,
|
|
ConvertAction eConvertAction /*= NoConvertAction*/,
|
|
BomAction eBomAction /*= NoBomAction*/)
|
|
{
|
|
BOOL rc = FALSE;
|
|
|
|
Close();
|
|
|
|
_ASSERTE(lpszResId);
|
|
_ASSERTE(lpszResType);
|
|
|
|
m_eConvertAction = eConvertAction;
|
|
m_eBomAction = eBomAction;
|
|
|
|
if (lpszResId && lpszResType)
|
|
{
|
|
rc = CResourceFile::Open(hInstance, lpszResId, lpszResType);
|
|
|
|
if (rc)
|
|
{
|
|
wchar_t *cp = (wchar_t *)GetByteBuffer();
|
|
DWORD dwSize = (DWORD)GetLength();
|
|
|
|
rc = SetTextBuffer(cp, dwSize,
|
|
eConvertAction, eBomAction);
|
|
|
|
if (rc)
|
|
{
|
|
m_bText = TRUE;
|
|
}
|
|
else
|
|
{
|
|
Close();
|
|
}
|
|
}
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
void CResourceTextFile::Close()
|
|
{
|
|
CResourceFile::Close();
|
|
|
|
if (m_pszText && !m_bDoNotDeleteBuffer)
|
|
delete[] m_pszText;
|
|
m_pszText = NULL;
|
|
}
|
|
|
|
wchar_t *CResourceTextFile::DetachTextBuffer()
|
|
{
|
|
wchar_t *cp = NULL;
|
|
|
|
if (m_bIsOpen && m_bText)
|
|
{
|
|
m_bDoNotDeleteBuffer = TRUE;
|
|
cp = m_pszText;
|
|
}
|
|
|
|
return cp;
|
|
}
|
|
|
|
wchar_t *CResourceTextFile::DuplicateTextBuffer()
|
|
{
|
|
wchar_t *dup = NULL;
|
|
|
|
if (IsOpen() && m_bText)
|
|
dup = _wcsdup(m_pszText);
|
|
|
|
return dup;
|
|
}
|
|
|
|
BOOL CResourceTextFile::SetTextBuffer(wchar_t * inbuf,
|
|
DWORD len,
|
|
ConvertAction eConvertAction /*= NoConvertAction*/,
|
|
BomAction eBomAction /*= NoBomAction*/)
|
|
{
|
|
BOOL rc = FALSE;
|
|
|
|
_ASSERTE(inbuf);
|
|
_ASSERTE(len != 0);
|
|
_ASSERTE(m_pszText == NULL);
|
|
|
|
if (inbuf && (len != 0))
|
|
{
|
|
m_bText = TRUE;
|
|
|
|
m_eConvertAction = eConvertAction;
|
|
m_eBomAction = eBomAction;
|
|
|
|
DWORD dwSize = len; // bytes
|
|
|
|
// copy buffer to ensure it's null terminated
|
|
BYTE *buf = new BYTE[dwSize + 16];
|
|
memset(buf, 0, dwSize + 16);
|
|
memcpy(buf, inbuf, dwSize);
|
|
|
|
BOOL bFoundBom = (buf[0] == 0xFF) && (buf[1] == 0xFE);
|
|
|
|
if (m_eConvertAction == ConvertToUnicode)
|
|
{
|
|
int wlen = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)buf, -1, NULL, 0);
|
|
#ifndef _UNICODE
|
|
wlen = wlen * sizeof(WCHAR);
|
|
#endif
|
|
m_pszText = new wchar_t[wlen + 16];
|
|
memset(m_pszText, 0, (wlen + 16) * sizeof(wchar_t));
|
|
LPWSTR wp = (LPWSTR)m_pszText;
|
|
if ((m_eBomAction == AddBom) && !bFoundBom)
|
|
{
|
|
// caller wants a BOM
|
|
BYTE *p = (BYTE *)m_pszText;
|
|
p[0] = 0xFF;
|
|
p[1] = 0xFE;
|
|
wp += 1;
|
|
}
|
|
MultiByteToWideChar(CP_ACP, 0, (LPCSTR)buf, -1, wp, wlen + 2);
|
|
m_nBufLen = wcslen((WCHAR *)m_pszText);
|
|
}
|
|
else if (m_eConvertAction == ConvertToAnsi)
|
|
{
|
|
LPCWSTR wp = (LPCWSTR)buf;
|
|
if (bFoundBom && (m_eBomAction == RemoveBom))
|
|
wp++; // skip over BOM
|
|
int alen = WideCharToMultiByte(CP_ACP, 0, wp, -1,
|
|
NULL, 0, NULL, NULL);
|
|
m_pszText = new wchar_t[alen + 4];
|
|
memset(m_pszText, 0, (alen + 4) * sizeof(wchar_t));
|
|
WideCharToMultiByte(CP_ACP, 0, wp, -1,
|
|
(LPSTR)m_pszText, alen + 1, NULL, NULL);
|
|
m_nBufLen = strlen((LPCSTR)m_pszText);
|
|
}
|
|
else
|
|
{
|
|
// no conversion
|
|
m_pszText = new wchar_t[(dwSize + 16) / sizeof(wchar_t)];
|
|
wchar_t *cp = m_pszText;
|
|
memset(m_pszText, 0, dwSize + 8);
|
|
int index = 0;
|
|
if ((m_eBomAction == AddBom) && !bFoundBom)
|
|
{
|
|
BYTE bom[2] = {0xFF, 0xFE};
|
|
memcpy(cp, bom, 2);
|
|
cp += 2;
|
|
}
|
|
else if ((m_eBomAction == RemoveBom) && bFoundBom)
|
|
{
|
|
index = 2;
|
|
}
|
|
memcpy(cp, &buf[index], dwSize);
|
|
m_nBufLen = wcslen(m_pszText);
|
|
}
|
|
|
|
m_nPosition = 0;
|
|
m_bIsOpen = TRUE;
|
|
m_bDoNotDeleteBuffer = FALSE; // ok to delete the buffer
|
|
delete[] buf;
|
|
rc = TRUE;
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
size_t CResourceTextFile::ReadLine(wchar_t *buf, size_t nBufLen)
|
|
{
|
|
size_t nOldPosition = m_nPosition;
|
|
size_t nIndex = 0;
|
|
if (buf)
|
|
*buf = L'\0';
|
|
|
|
if (m_bIsOpen && m_pszText && m_bText)
|
|
{
|
|
while (!IsAtEOF())
|
|
{
|
|
wchar_t c = m_pszText[m_nPosition++];
|
|
|
|
if ((c == L'\r') || (c == L'\n'))
|
|
{
|
|
if (!IsAtEOF())
|
|
{
|
|
// check for \r\n pair
|
|
wchar_t prevc = c;
|
|
c = m_pszText[m_nPosition];
|
|
if (((prevc == L'\r') && (c == L'\n')) ||
|
|
((prevc == L'\n') && (c == L'\r')))
|
|
{
|
|
m_nPosition++;
|
|
}
|
|
}
|
|
break; // end of line
|
|
}
|
|
|
|
if (buf && (nIndex < nBufLen))
|
|
buf[nIndex] = c;
|
|
nIndex++;
|
|
}
|
|
}
|
|
|
|
// add terminating nul always
|
|
if (buf)
|
|
{
|
|
if (nIndex >= nBufLen)
|
|
{
|
|
// there is not enough room, so replace last char
|
|
nIndex = nBufLen - 1;
|
|
if (nBufLen == 0)
|
|
nIndex = 0;
|
|
}
|
|
buf[nIndex] = L'\0';
|
|
}
|
|
|
|
// if we were just getting buffer size, restore position
|
|
if (!buf)
|
|
{
|
|
m_nPosition = nOldPosition;
|
|
}
|
|
|
|
return nIndex;
|
|
}
|