0

我正在尝试组合一个函数来将 PSTR 转换为 PWSTR,同时转义某些字符。我无法控制 PSTR 包含的输入。它可以是任何网页上的内容。

我已经有以下代码,但我想知道是否有更好/更有效的方法,或者我所拥有的是否可以工作。

__inline PCWSTR ToEscape(CHAR c)
{
    switch (c)
    {
    case '"':  return L"\"";
    case '\\': return L"\\";
    case '\b': return L"\b";
    case '\f': return L"\f";
    case '\n': return L"\n";
    case '\r': return L"\r";
    case '\t': return L"\t";
    default:   return NULL;
    }
}

// Helper for mbstowcs_s that does not return NULL terminator included in size
__inline DWORD CharToWChar(__out_ecount_opt(cchBuffer) WCHAR* pszBuffer, __in DWORD cchBuffer, __in_ecount(valueLen) PCSTR value, __in DWORD valueLen)
{
    if (valueLen == 0) return 0;

    size_t dwSize = 0;
    mbstowcs_s(&dwSize, pszBuffer, cchBuffer, value, valueLen);
    return dwSize - 1;
}

// Writes the input value to pszBuffer, or if pszBuffer is NULL, returns the length necessary to write value
__inline DWORD WriteJsonValue(__out_ecount_opt(cchBuffer) WCHAR* pszBuffer, __in DWORD cchBuffer, __in PCSTR value)
{
    if (pszBuffer == NULL)
    {
        DWORD offset = 2;

        PCSTR start = value;
        DWORD index = 0;
        while (value[index] != '\0')
        {
            PCWSTR Escape = ToEscape(value[index]);
            if (Escape)
            {
                offset += CharToWChar(NULL, 0, start, (value + index) - start);
                start = value + index + 1;
                offset += 2;
            }
            index++;
        }

        // Any more left to write?
        offset += CharToWChar(NULL, 0, start, (value + index) - start);

        return offset;
    }
    else
    {
        DWORD offset = 0;
        if (cchBuffer < 1) return 0;
        pszBuffer[offset++] = L'"';

        PCSTR start = value;
        DWORD index = 0;
        while (value[index] != '\0')
        {
            PCWSTR Escape = ToEscape(value[index]);
            if (Escape)
            {
                DWORD dwLen = (value + index) - start;
                offset += CharToWChar(pszBuffer+offset, cchBuffer-offset, start, dwLen);
                start = value + index + 1;

                if (cchBuffer < offset + 2) return offset;
                pszBuffer[offset++] = Escape[0];
                pszBuffer[offset++] = Escape[1];
            }
            index++;
        }

        // Any more left to write?
        DWORD dwLen = (value + index) - start;
        offset += CharToWChar(pszBuffer+offset, cchBuffer-offset, start, dwLen);

        if (cchBuffer < offset + 1) return offset;
        pszBuffer[offset++] = L'"';

        return offset;
    }
}
4

1 回答 1

0
__inline PCWSTR ToEscape(WCHAR c)
{
    switch (c)
    {
    case L'"':  return L"\"";
    case L'\\': return L"\\";
    case L'\b': return L"\b";
    case L'\f': return L"\f";
    case L'\n': return L"\n";
    case L'\r': return L"\r";
    case L'\t': return L"\t";
    default:   return NULL;
    }
}

__inline DWORD WriteEscapedCharacter(__out_ecount(cchBuffer) WCHAR* pszBuffer, __in DWORD cchBuffer, __in WCHAR value)
{
    PCWSTR Escape = ToEscape(value);
    if (Escape)
    {
        if (cchBuffer < 2) return 0;
        pszBuffer[0] = Escape[0];
        pszBuffer[1] = Escape[1];
        return 2;
    }
    else
    {
        if (cchBuffer < 1) return 0;
        pszBuffer[0] = value;
        return 1;
    }
}

// Writes the input value to pszBuffer, or if pszBuffer is NULL, returns the length necessary to write value
__inline DWORD WriteJsonValue(__out_ecount_opt(cchBuffer) WCHAR* pszBuffer, __in DWORD cchBuffer, __in PCSTR value)
{
    size_t valueLen = _mbstrlen(value);

    if (pszBuffer == NULL)
    {
        DWORD offset = 2;

        WCHAR ch = 0;
        DWORD index = 0;
        while (index < valueLen)
        {
            DWORD chLen = mblen(value + index, valueLen - index);
            if (chLen < 1) break;
            mbtowc(&ch, value + index, chLen);
            offset += ToEscape(ch) ? 2 : 1;
            index += chLen;
        }

        return offset;
    }
    else
    {
        DWORD offset = 0;
        if (cchBuffer < 1) return 0;
        pszBuffer[offset++] = L'"';

        WCHAR ch = 0;
        DWORD index = 0;
        while (value[index] != '\0')
        {
            DWORD chLen = mblen(value + index, valueLen - index);
            if (chLen < 1) break;
            mbtowc(&ch, value + index, chLen);
            offset += WriteEscapedCharacter(pszBuffer + offset, cchBuffer - offset, value[index]);
            index += chLen;
        }

        if (cchBuffer < offset + 1) return offset;
        pszBuffer[offset++] = L'"';

        return offset;
    }
}
于 2013-02-22T19:43:09.020 回答