windows-nt/Source/XPSP1/NT/printscan/wia/setup/clsinst/string.cpp
2020-09-26 16:20:57 +08:00

562 lines
12 KiB
C++

/******************************************************************************
Source File: String.CPP
String Handling class implementation, v 98.6 1/2
Copyright (c) 1997 by Microsoft Corporation. All Rights Reserved.
Change History:
01-08-97 Bob Kjelgaard
01-03-97 Bob Kjelgaard Added special functions to aid port extraction
for plug-and-play.
07-05-97 Tim Wells Ported to NT.
******************************************************************************/
//
// Precompiled header
//
#include "precomp.h"
#pragma hdrstop
//
// Include
//
#include "sti_ci.h"
//
// Extern
//
extern HINSTANCE g_hDllInstance;
//
// Function
//
CString::CString(const CString& csRef) {
m_lpstr = (csRef.m_lpstr && *csRef.m_lpstr) ?
new TCHAR[1 + lstrlen(csRef.m_lpstr)] : NULL;
if (m_lpstr)
lstrcpy(m_lpstr, csRef.m_lpstr);
}
CString::CString(LPCTSTR lpstrRef){
DWORD dwLength;
_try {
dwLength = lstrlen(lpstrRef);
} // _try {
_except(EXCEPTION_EXECUTE_HANDLER) {
dwLength = 0;
} // _except(EXCEPTION_EXECUTE_HANDLER)
if( (NULL != lpstrRef)
&& (NULL != *lpstrRef)
&& (0 != dwLength) )
{
m_lpstr = new TCHAR[dwLength+1];
lstrcpy(m_lpstr, lpstrRef);
}
} // CString::CString(LPCTSTR lpstrRef)
const CString& CString::operator =(const CString& csRef) {
Empty();
m_lpstr = (csRef.m_lpstr && *csRef.m_lpstr) ?
new TCHAR[1 + lstrlen(csRef.m_lpstr)] : NULL;
if (m_lpstr)
lstrcpy(m_lpstr, csRef.m_lpstr);
return *this;
}
const
CString&
CString::operator =(
LPCTSTR lpstrRef
)
{
DWORD dwLength;
Empty();
_try {
dwLength = lstrlen(lpstrRef);
} // _try {
_except(EXCEPTION_EXECUTE_HANDLER) {
dwLength = 0;
} // _except(EXCEPTION_EXECUTE_HANDLER)
if( (NULL != lpstrRef)
&& (NULL != *lpstrRef)
&& (0 != dwLength) )
{
m_lpstr = new TCHAR[dwLength+1];
lstrcpy(m_lpstr, lpstrRef);
}
return *this;
} // CString::operator =(LPCTSTR lpstrRef)
void CString::GetContents(HWND hwnd) {
Empty();
if (!IsWindow(hwnd))
return;
unsigned u = (unsigned) SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0);
if (!u)
return;
m_lpstr = new TCHAR[++u];
if(NULL != m_lpstr){
SendMessage(hwnd, WM_GETTEXT, u, (LPARAM) m_lpstr);
}
}
void CString::FromTable(unsigned uid) {
TCHAR acTemp[MAX_PATH+1];
memset(acTemp, 0, sizeof(acTemp));
LoadString(g_hDllInstance, uid, acTemp, ARRAYSIZE(acTemp)-1);
*this = acTemp;
}
void CString::Load(ATOM at, BOOL bGlobal) {
TCHAR acTemp[MAX_PATH+1];
memset(acTemp, 0, sizeof(acTemp));
if(bGlobal){
GlobalGetAtomName(at,
acTemp,
ARRAYSIZE(acTemp)-1);
} else {
GetAtomName(at,
acTemp,
sizeof(acTemp)/sizeof(TCHAR));
}
*this = acTemp;
}
void
CString::Load(
HINF hInf,
LPCTSTR lpstrSection,
LPCTSTR lpstrKeyword,
DWORD dwFieldIndex,
LPCTSTR lpstrDefault
)
{
INFCONTEXT InfContext;
TCHAR szKeyBuffer[MAX_PATH+1];
TCHAR szValueBuffer[MAX_PATH+1];
//
// Initialize local.
//
memset(&InfContext, 0, sizeof(InfContext));
memset(szKeyBuffer, 0, sizeof(szKeyBuffer));
memset(szValueBuffer, 0, sizeof(szValueBuffer));
//
// Cleanup contents;
//
Empty();
//
// Check all parameters.
//
if( (NULL == lpstrSection)
|| (NULL == lpstrKeyword)
|| (!IS_VALID_HANDLE(hInf)) )
{
//
// Invalid parameter.
//
goto Load_return;
}
//
// Get matching line.
//
while(SetupFindFirstLine(hInf, lpstrSection, lpstrKeyword, &InfContext)){
//
// Get a field of a line.
//
if(SetupGetStringField(&InfContext, dwFieldIndex, szValueBuffer, ARRAYSIZE(szValueBuffer)-1, NULL)){
*this = szValueBuffer;
break;
}// if(SetupGetStringField(&InfContext, dwFieldIndex, szValueBuffer, ARRAYSIZE(szValueBuffer)-1))
} // while(SetupFindFirstLine(hInf, lpstrSection, lpstrKeyword, &InfContext))
Load_return:
return;
} // CString::Load() Load from INF
void CString::Load(HKEY hk, LPCTSTR lpstrKeyword) {
TCHAR abTemp[MAX_PATH+1];
ULONG lcbNeeded = sizeof(abTemp)-sizeof(TCHAR);
memset(abTemp, 0, sizeof(abTemp));
RegQueryValueEx(hk, lpstrKeyword, NULL, NULL, (PBYTE)abTemp, &lcbNeeded);
*this = (LPCTSTR) abTemp;
}
void CString::MakeSystemPath(LPCTSTR lpstrFileName) {
DWORD dwLength;
if (m_lpstr)
delete m_lpstr;
_try {
dwLength = lstrlen(lpstrFileName);
} // _try {
_except(EXCEPTION_EXECUTE_HANDLER) {
dwLength = 0;
} // _except(EXCEPTION_EXECUTE_HANDLER)
m_lpstr = new TCHAR[MAX_PATH * 2];
if( (NULL != m_lpstr)
&& (0 != dwLength)
&& (MAX_PATH >= dwLength) )
{
memset(m_lpstr, 0, MAX_PATH*2*sizeof(TCHAR));
UINT uiLength = GetSystemDirectory (m_lpstr, MAX_PATH);
if ( *(m_lpstr + uiLength) != TEXT('\\'))
lstrcat (m_lpstr, TEXT("\\"));
lstrcat (m_lpstr, lpstrFileName);
}
}
void CString::Store(HKEY hk, LPCTSTR lpstrKey, LPCTSTR lpstrType) {
DWORD dwLength;
if (IsEmpty())
return;
_try {
dwLength = lstrlen(lpstrKey);
} // _try {
_except(EXCEPTION_EXECUTE_HANDLER) {
return;
} // _except(EXCEPTION_EXECUTE_HANDLER)
if (lpstrType && *lpstrType == TEXT('1')) {
DWORD dwValue = Decode();
RegSetValueEx(hk, lpstrKey, NULL, REG_DWORD, (LPBYTE) &dwValue,
sizeof (DWORD));
} else {
RegSetValueEx(hk, lpstrKey, NULL, REG_SZ, (LPBYTE) m_lpstr,
(1 + lstrlen(m_lpstr)) * sizeof(TCHAR) );
}
}
// This one is a bit lame, but it does the job.
DWORD CString::Decode() {
if (IsEmpty())
return 0;
for (LPTSTR lpstrThis = m_lpstr;
*lpstrThis && *lpstrThis == TEXT(' ');
lpstrThis++)
;
if (!*lpstrThis)
return 0;
// BIUGBUG
if (lpstrThis[0] == TEXT('0') && (lpstrThis[1] | TEXT('\x20') ) == TEXT('x')) {
// Hex string
lpstrThis += 2;
DWORD dwReturn = 0;
while (*lpstrThis) {
switch (*lpstrThis) {
case TEXT('0'):
case TEXT('1'):
case TEXT('2'):
case TEXT('3'):
case TEXT('4'):
case TEXT('5'):
case TEXT('6'):
case TEXT('7'):
case TEXT('8'):
case TEXT('9'):
dwReturn <<= 4;
dwReturn += ((*lpstrThis) - TEXT('0'));
break;
case TEXT('a'):
case TEXT('A'):
case TEXT('b'):
case TEXT('c'):
case TEXT('d'):
case TEXT('e'):
case TEXT('f'):
case TEXT('B'):
case TEXT('C'):
case TEXT('D'):
case TEXT('E'):
case TEXT('F'):
dwReturn <<= 4;
dwReturn += 10 + ((*lpstrThis | TEXT('\x20')) - TEXT('a'));
break;
default:
return dwReturn;
}
lpstrThis++;
}
return dwReturn;
}
for (DWORD dwReturn = 0;
*lpstrThis && *lpstrThis >= TEXT('0') && *lpstrThis <= TEXT('9');
lpstrThis++) {
dwReturn *= 10;
dwReturn += *lpstrThis - TEXT('0');
}
return dwReturn;
}
CString operator + (const CString& cs1, const CString& cs2) {
if (cs1.IsEmpty())
return cs2;
if (cs2.IsEmpty())
return cs1;
CString csReturn;
csReturn.m_lpstr = new TCHAR[ 1 + lstrlen(cs1) +lstrlen(cs2)];
if(NULL != csReturn.m_lpstr){
lstrcat(lstrcpy(csReturn.m_lpstr, cs1.m_lpstr), cs2.m_lpstr);
}
return csReturn;
}
CString operator + (const CString& cs1, LPCTSTR lpstr2) {
DWORD dwLength;
_try {
dwLength = lstrlen(lpstr2);
} // _try {
_except(EXCEPTION_EXECUTE_HANDLER) {
dwLength = 0;
} // _except(EXCEPTION_EXECUTE_HANDLER)
if(0 == dwLength)
return cs1;
if(cs1.IsEmpty())
return lpstr2;
CString csReturn;
csReturn.m_lpstr = new TCHAR[ 1 + lstrlen(cs1) + dwLength];
if(NULL != csReturn.m_lpstr){
lstrcat(lstrcpy(csReturn.m_lpstr, cs1.m_lpstr), lpstr2);
}
return csReturn;
}
CString operator + (LPCTSTR lpstr1,const CString& cs2) {
DWORD dwLength;
_try {
dwLength = lstrlen(lpstr1);
} // _try {
_except(EXCEPTION_EXECUTE_HANDLER) {
dwLength = 0;
} // _except(EXCEPTION_EXECUTE_HANDLER)
if(0 == dwLength)
return cs2;
if (cs2.IsEmpty())
return lpstr1;
CString csReturn;
csReturn.m_lpstr = new TCHAR[ 1 + dwLength +lstrlen(cs2)];
if(NULL != csReturn.m_lpstr){
lstrcat(lstrcpy(csReturn.m_lpstr, lpstr1), cs2.m_lpstr);
}
return csReturn;
}
// CStringArray class- the implementation is a bit lame, but it isn't
// really necessary to not be lame, at this point...
CStringArray::CStringArray(unsigned uGrowBy) {
m_ucItems = m_ucMax = 0;
m_pcsContents = NULL;
m_uGrowBy = uGrowBy ? uGrowBy : 10;
}
CStringArray::~CStringArray() {
if (m_pcsContents)
delete[] m_pcsContents;
}
VOID
CStringArray::Cleanup() {
if (m_pcsContents){
delete[] m_pcsContents;
}
m_pcsContents = NULL;
m_ucItems = m_ucMax = 0;
}
void CStringArray::Add(LPCTSTR lpstr) {
if (m_ucItems >= m_ucMax) {
CString *pcsNew = new CString[m_ucMax += m_uGrowBy];
if (!pcsNew) {
m_ucMax -= m_uGrowBy;
return;
}
for (unsigned u = 0; u < m_ucItems; u++)
pcsNew[u] = m_pcsContents[u];
delete[] m_pcsContents;
m_pcsContents = pcsNew;
}
m_pcsContents[m_ucItems++] = lpstr;
}
CString& CStringArray::operator [](unsigned u) {
return (u < m_ucItems) ? m_pcsContents[u] : m_csEmpty;
}
// Split a string into tokens, and make an array of it
void CStringArray::Tokenize(LPTSTR lpstr, TCHAR cSeparator) {
BOOL fInsideQuotes = FALSE;
TCHAR cPreviousChar = TEXT('\0');
if (m_pcsContents) {
delete[] m_pcsContents;
m_pcsContents = NULL;
m_ucItems = m_ucMax = 0;
}
if (!lpstr)
return;
for (LPTSTR lpstrThis = lpstr; *lpstr; lpstr = lpstrThis) {
/*
for (; *lpstrThis && *lpstrThis != cSeparator; lpstrThis++) {
}
*/
//
// Skip for next separator , counting quotes
//
cPreviousChar = '\0';
for (;*lpstrThis; lpstrThis++) {
if (fInsideQuotes) {
if (*lpstrThis == TEXT('"')) {
if (cPreviousChar != TEXT('"')) {
// Previous was not a quote - going out of quotation
fInsideQuotes = FALSE;
}
else {
// Previous char was tab too - continue BUGBUG should coalesce
}
cPreviousChar = TEXT('\0');
}
else {
cPreviousChar = *lpstrThis;
}
continue;
}
else {
if (*lpstrThis == TEXT('"')) {
// Starting quote
fInsideQuotes = TRUE;
cPreviousChar = TEXT('\0');
continue;
}
if (*lpstrThis == cSeparator) {
// Got to separator outside of quote - break the loop
break;
}
}
}
if (*lpstrThis) {
*lpstrThis = '\0';
Add(lpstr);
*lpstrThis++ = cSeparator;
}
else
Add(lpstr);
}
}