|
|
/******************************************************************************
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;
m_lpstr = NULL;
_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); } }
|