#include "stdafx.h" #include "Unicode.h" #define _PARAMLIST_EXPORT #include "ParamList.h"
#define INVALID_NAME(name) ((name) == NULL || *(name) == '\0')
ParamListW::ParamListW(void) { pParams = pRear = NULL; }
ParamListW::ParamListW(LPCWSTR lpSource) { pParams = pRear = NULL; SetResult(lpSource); }
ParamListW::ParamListW(const ParamListW &pl) { pParams = pRear = NULL; operator = (pl); }
ParamListW::~ParamListW(void) { RemoveAll(); }
ParamListW &ParamListW::operator = (const ParamListW &pl) { LPPARAMW p = pl.pParams; LPPARAMW p2 = NULL; RemoveAll(); while (p != NULL) { if (p2 == NULL) pParams = p2 = (LPPARAMW)malloc(sizeof(PARAMW)); else { p2->pNext = (LPPARAMW)malloc(sizeof(PARAMW)); p2 = p2->pNext; } CopyParam(p2, p); p = p->pNext; } if (p2 != NULL) { p2->pNext = NULL; pRear = p2; } return *this; }
// Warning: A + B != B + A ParamListW operator + (const LPWSTR &a, const ParamListW &pl) { ParamListW obj(a); obj.Combine(pl); return obj; }
ParamListW ParamListW::operator + (const ParamListW &pl) { ParamListW obj(*this); obj.Combine(pl); return obj; }
ParamListW &ParamListW::operator += (const ParamListW &pl) { Combine(pl); return *this; }
UINT ParamListW::Combine(const ParamListW &pl, bool bMerge) { UINT uCount = 0; LPPARAMW p; for (p = pl.pParams; p != NULL; p = p->pNext) { if (!bMerge && HasParam(p->lpszName)) continue;
CopyParam(p); uCount++; } return uCount; }
void ParamListW::CopyParam(LPPARAMW lpDest, LPPARAMW lpSource) { CopyParam(lpSource, &lpDest->lpszName, &lpDest->lpszValue); lpDest->uFree = lpSource->uFree; }
void ParamListW::CopyParam(LPPARAMW lpSource) { LPWSTR pName, pValue; CopyParam(lpSource, &pName, &pValue); SetParam(pName, pValue, lpSource->uFree); }
void ParamListW::CopyParam(LPPARAMW lpSource, LPWSTR *ppName, LPWSTR *ppValue) { if (lpSource->uFree & PL_FREENAME) *ppName = DuplicateStringW(lpSource->lpszName); else *ppName = lpSource->lpszName; if (lpSource->uFree & PL_FREEVALUE) *ppValue = DuplicateStringW(lpSource->lpszValue); else *ppValue = lpSource->lpszValue; }
UINT ParamListW::Count(void) const { UINT n = 0; LPPARAMW p = pParams; while (p != NULL) { n++; p = p->pNext; } return n; }
void ParamListW::FreeParam(LPPARAMW lpParam) { if (lpParam->uFree & PL_FREENAME) { free(lpParam->lpszName); lpParam->lpszName = NULL; } if (lpParam->uFree & PL_FREEVALUE) { free(lpParam->lpszValue); lpParam->lpszValue = NULL; } }
LPWSTR ParamListW::GetResult(void) const { LPPARAMW p = pParams; LPWSTR lpResult = NULL; size_t cchTotal = 0; bool bFirst = true; while (p != NULL) { LPWSTR p1 = URLEncodeW(p->lpszName); LPWSTR p2 = URLEncodeW(p->lpszValue); size_t cch1 = wcslen(p1); size_t cch2 = (p->lpszValue == NULL) ? 0 : wcslen(p2); size_t cchExtend = cch1 + cch2 + 3; // 3 more bytes for '&', '=' and '\0' lpResult = (LPWSTR)realloc(lpResult, (cchTotal + cchExtend) * sizeof(WCHAR));
LPWCH pStr = lpResult + cchTotal; if (!bFirst) *pStr++ = L'&'; memcpy(pStr, p1, cch1 * sizeof(WCHAR)); pStr += cch1; if (p2 != NULL) { *pStr++ = L'='; memcpy(pStr, p2, cch2 * sizeof(WCHAR)); pStr += cch2; }
cchTotal = pStr - lpResult; free(p1); free(p2); p = p->pNext; bFirst = false; } if (lpResult != NULL) *(lpResult + cchTotal) = L'\0'; return lpResult; }
bool ParamListW::HasParam(LPCWSTR szName, LPPARAMW *ppParam) const { LPPARAMW p = pParams; while (p != NULL) { if (wcscmp(p->lpszName, szName) == 0) { if (ppParam != NULL) *ppParam = p; return true; } p = p->pNext; } if (ppParam != NULL) *ppParam = NULL; return false; }
bool ParamListW::IsEmpty(void) const { return pParams == NULL; }
void ParamListW::RemoveAll(void) { if (pParams == NULL) return;
LPPARAMW p = pParams; LPPARAMW temp; while (p != NULL) { temp = p->pNext; FreeParam(p); free(p); p = temp; }
pParams = pRear = NULL; }
bool ParamListW::RemoveParam(LPCWSTR szName) { LPPARAMW p = pParams; LPPARAMW pPrev = NULL; while (p != NULL) { if (wcscmp(p->lpszName, szName) == 0) { if (pPrev != NULL) pPrev->pNext = p->pNext; else pParams = p->pNext; // change head if (p->pNext == NULL) pRear = pPrev; // change rear FreeParam(p); free(p); return true; }
pPrev = p; p = p->pNext; } return false; }
void ParamListW::SetParam(LPWSTR szName, int nValue) { if (INVALID_NAME(szName)) return;
LPWSTR buf = (LPWSTR)malloc(30 * sizeof(WCHAR)); _itow_s(nValue, buf, 30, 10); SetParam(szName, buf, PL_FREEVALUE); }
void ParamListW::SetParam(LPWSTR szName, LPWSTR szValue, UINT uFree) { if (INVALID_NAME(szName)) return;
LPPARAMW p; if (!HasParam(szName, &p)) { /* Create a param at the end of pParams */ p = (LPPARAMW)malloc(sizeof(PARAMW)); p->pNext = NULL; if (pRear != NULL) { // Update pRear pRear->pNext = p; pRear = p; } else pParams = pRear = p; // first-created param } else { /* Change the param */ FreeParam(p); // free old data } p->lpszName = szName; // force to use the new lpszName pointer p->lpszValue = szValue; p->uFree = uFree; }
void ParamListW::SetParam(LPWSTR szName, WCHAR ch) { if (INVALID_NAME(szName)) return;
LPWSTR buf = (LPWSTR)malloc(2 * sizeof(WCHAR)); buf[0] = ch; buf[1] = L'\0'; SetParam(szName, buf, PL_FREEVALUE); }
void ParamListW::SetResult(LPCWSTR lpSource) { LPWSTR lpszName = NULL; LPWSTR lpszValue = NULL; bool bFlag = false; RemoveAll(); while (true) { if (*lpSource == L'?' || *lpSource == L'&' || *lpSource == L'\0') { if (bFlag) SetParam(lpszName, NULL, PL_FREENAME); // Pending ?param or ¶m (without value) if (*lpSource == L'\0') break;
bFlag = false; lpSource++; } else if (*lpSource == L'=') { bFlag = true; lpSource++; } LPWSTR pPart, pDecodedPart; LPCWSTR pPartStart = lpSource; while (*lpSource != '\0' && *lpSource != '=' && *lpSource != '&') lpSource++; size_t cbPartSize = (lpSource - pPartStart) * sizeof(WCHAR); pPart = (LPWSTR)malloc(cbPartSize + sizeof(WCHAR)); memcpy(pPart, pPartStart, cbPartSize); *(LPWCH)((LPBYTE)pPart + cbPartSize) = L'\0'; pDecodedPart = URLDecodeW(pPart); free(pPart);
if (!bFlag) lpszName = pDecodedPart; else { lpszValue = pDecodedPart; SetParam(lpszName, lpszValue, PL_FREENAME | PL_FREEVALUE); lpszName = lpszValue = NULL; } bFlag = !bFlag; } }
|