mirror of
https://github.com/rizonesoft/Notepad3.git
synced 2026-06-14 21:09:05 +08:00
284 lines
7.4 KiB
C++
284 lines
7.4 KiB
C++
// sktoolslib - common files for SK tools
|
|
|
|
// Copyright (C) 2012 - 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 <tchar.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 TCHAR [rf.m_nBufLen + 2];
|
|
memset(m_pszText, 0, (rf.m_nBufLen+2)*sizeof(TCHAR));
|
|
_tcsncpy_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,
|
|
LPCTSTR lpszResId,
|
|
LPCTSTR lpszResType /*= _T("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)
|
|
{
|
|
TCHAR *cp = (TCHAR *) 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;
|
|
}
|
|
|
|
TCHAR * CResourceTextFile::DetachTextBuffer()
|
|
{
|
|
TCHAR *cp = NULL;
|
|
|
|
if (m_bIsOpen && m_bText)
|
|
{
|
|
m_bDoNotDeleteBuffer = TRUE;
|
|
cp = m_pszText;
|
|
}
|
|
|
|
return cp;
|
|
}
|
|
|
|
TCHAR * CResourceTextFile::DuplicateTextBuffer()
|
|
{
|
|
TCHAR *dup = NULL;
|
|
|
|
if (IsOpen() && m_bText)
|
|
dup = _tcsdup(m_pszText);
|
|
|
|
return dup;
|
|
}
|
|
|
|
BOOL CResourceTextFile::SetTextBuffer(TCHAR * 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 TCHAR [wlen+16];
|
|
memset(m_pszText, 0, (wlen+16)*sizeof(TCHAR));
|
|
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 TCHAR [alen+4];
|
|
memset(m_pszText, 0, (alen+4)*sizeof(TCHAR));
|
|
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 TCHAR [(dwSize + 16)/sizeof(TCHAR)];
|
|
TCHAR *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 = _tcslen(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(TCHAR *buf, size_t nBufLen)
|
|
{
|
|
size_t nOldPosition = m_nPosition;
|
|
size_t nIndex = 0;
|
|
if (buf)
|
|
*buf = _T('\0');
|
|
|
|
if (m_bIsOpen && m_pszText && m_bText)
|
|
{
|
|
while (!IsAtEOF())
|
|
{
|
|
TCHAR c = m_pszText[m_nPosition++];
|
|
|
|
if ((c == _T('\r')) || (c == _T('\n')))
|
|
{
|
|
if (!IsAtEOF())
|
|
{
|
|
// check for \r\n pair
|
|
TCHAR prevc = c;
|
|
c = m_pszText[m_nPosition];
|
|
if (((prevc == _T('\r')) && (c == _T('\n'))) ||
|
|
((prevc == _T('\n')) && (c == _T('\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] = _T('\0');
|
|
}
|
|
|
|
// if we were just getting buffer size, restore position
|
|
if (!buf)
|
|
{
|
|
m_nPosition = nOldPosition;
|
|
}
|
|
|
|
return nIndex;
|
|
}
|