#include "stdinc.h" #include #include #include #include #include #include #include #include "xmlhelper.hxx" bool isCharAlphaW(WCHAR wChar) { FN_TRACE(); WORD ctype1info; if (!GetStringTypeW(CT_CTYPE1, &wChar, 1, &ctype1info)) { // // GetStringTypeW returned an error! IsCharAlphaW has no // provision for returning an error... The best we can do // is to return FALSE // //UserAssert(FALSE); ASSERT(FALSE); return FALSE; } if (ctype1info & C1_ALPHA) { return TRUE; } else { return FALSE; } } ////////////////////////////////////////////////////////////////////////////// bool isDigit(WCHAR ch) { return (ch >= 0x30 && ch <= 0x39); } ////////////////////////////////////////////////////////////////////////////// bool isHexDigit(WCHAR ch) { return (ch >= '0' && ch <= '9' ) || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F'); } ////////////////////////////////////////////////////////////////////////////// bool isLetter(WCHAR ch) { return (ch >= 'a') && ::isCharAlphaW(ch); } ////////////////////////////////////////////////////////////////////////////// int isStartNameChar(WCHAR ch) { return (ch < TABLE_SIZE) ? (g_anCharType[ch] & (FLETTER | FSTARTNAME)) : (isLetter(ch) || (ch == '_' || ch == ':')); } ////////////////////////////////////////////////////////////////////////////// bool isCombiningChar(WCHAR ch) { UNUSED(ch); return false; } ////////////////////////////////////////////////////////////////////////////// bool isExtender(WCHAR ch) { return (ch == 0xb7); } ////////////////////////////////////////////////////////////////////////////// bool isAlphaNumeric(WCHAR ch) { return (ch >= '0' && ch <= '9') || ((ch >= 'a') && isCharAlphaW(ch)); } ////////////////////////////////////////////////////////////////////////////// int isNameChar(WCHAR ch) { return (ch < TABLE_SIZE ? (g_anCharType[ch] & (FLETTER | FDIGIT | FMISCNAME | FSTARTNAME)) : ( isAlphaNumeric(ch) || ch == '-' || ch == '_' || ch == '.' || ch == ':' || isCombiningChar(ch) || isExtender(ch))); } ////////////////////////////////////////////////////////////////////////////// int isCharData(WCHAR ch) { // it is in the valid range if it is greater than or equal to // 0x20, or it is white space. return (ch < TABLE_SIZE) ? (g_anCharType[ch] & FCHARDATA) : ((ch < 0xD800 && ch >= 0x20) || // Section 2.2 of spec. (ch >= 0xE000 && ch < 0xfffe)); } //============================================================================== WCHAR BuiltinEntity(const WCHAR* text, ULONG len) { ULONG ulength = len * sizeof(WCHAR); // Length in chars switch (len) { case 4: if (::memcmp(L"quot", text, ulength) == 0) { return '\"'; } else if (::memcmp(L"apos", text, ulength) == 0) { return '\''; } break; case 3: if (::memcmp(L"amp", text, ulength) == 0) { return '&'; } break; case 2: if (::memcmp(L"lt", text, ulength) == 0) { return '<'; } else if (::memcmp(L"gt", text, ulength) == 0) { return '>'; } break; } return 0; } // Since we cannot use the SHLWAPI wnsprintfA function... int DecimalToBuffer(long value, char* buffer, int j, long maxdigits) { long max = 1; for (int k = 0; k < maxdigits; k++) max = max * 10; if (value > (max*10)-1) value = (max*10)-1; max = max/10; for (int i = 0; i < maxdigits; i++) { long digit = (value / max); value -= (digit * max); max /= 10; buffer[i+j] = char('0' + (char)digit); } buffer[i+j]=0; return i+j; } ///////////////////////////////////////////////////////////////////// int StrToBuffer(const WCHAR* str, WCHAR* buffer, int j) { while (*str != UNICODE_NULL) { buffer[j++] = *str++; } return j; } //============================================================================== const ULONG MAXWCHAR = 0xFFFF; HRESULT DecimalToUnicode(const WCHAR* text, ULONG len, WCHAR& ch) { ULONG result = 0; for (ULONG i = 0; i < len; i++) { ULONG digit = 0; if (text[i] >= L'0' && text[i] <= L'9') { digit = (text[i] - L'0'); } else return XML_E_INVALID_DECIMAL; // Last unicode value (MAXWCHAR) is reserved as "invalid value" if (result >= (MAXWCHAR - digit) /10) // result is about to overflow return XML_E_INVALID_UNICODE; // the maximum 4 byte value. result = (result*10) + digit; } if (result == 0) // zero is also invalid. return XML_E_INVALID_UNICODE; ch = (WCHAR)result; return S_OK; } //============================================================================== HRESULT HexToUnicode(const WCHAR* text, ULONG len, WCHAR& ch) { ULONG result = 0; for (ULONG i = 0; i < len; i++) { ULONG digit = 0; if (text[i] >= L'a' && text[i] <= L'f') { digit = 10 + (text[i] - L'a'); } else if (text[i] >= L'A' && text[i] <= L'F') { digit = 10 + (text[i] - L'A'); } else if (text[i] >= L'0' && text[i] <= L'9') { digit = (text[i] - L'0'); } else return XML_E_INVALID_HEXIDECIMAL; // Last unicode value (MAXWCHAR) is reserved as "invalid value" if (result >= (MAXWCHAR - digit)/16) // result is about to overflow return XML_E_INVALID_UNICODE; // the maximum 4 byte value. result = (result*16) + digit; } if (result == 0) // zero is also invalid. return XML_E_INVALID_UNICODE; ch = (WCHAR)result; return S_OK; }