RapidJson在MFC多字节应用程序中的编码问题

GBK与Utf-8编码在rapidjson的转换。

        字符串为GBK编码的程序与utf-8编码的程序通过json交互时,由于rapidjson使用Utf-8编码,GBK和utf-8对某些中文字符的编码不同导致rapidjson解析时出错。例如“玕”在utf-8编码第一位对应多字节的转义符'\',导致后面解析为其它符号意义全乱套,rapidjson解析json串时就会失败。

解决方案

        通过修改rapidjson接口,自动处理GBK与Utf8互转,调用方不需要考虑编码问题。调用方通过CJsonHelper接口实现json生成与解析。

rapidjson源代码修改:

document.h 修改前

        template <unsigned parseFlags>
    GenericDocument& Parse(const Ch* str) {
        return Parse<parseFlags, Encoding>(str);
    }

修改后

#include <stringapiset.h>

    template <unsigned parseFlags>
    GenericDocument& Parse(const Ch* str) {
        CString s(str);
        jsonConvertGBKToUtf8(s);
        return Parse<parseFlags, Encoding>(s);
    }

    void jsonConvertGBKToUtf8(CString& strGBK)
    {
        int len = MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)strGBK, -1, NULL, 0);
        wchar_t* wszUtf8 = new wchar_t[len];
        memset(wszUtf8, 0, len);
        MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)strGBK, -1, wszUtf8, len);
        len = WideCharToMultiByte(CP_UTF8, 0, wszUtf8, -1, NULL, 0, NULL, NULL);
        char* szUtf8 = new char[len + 1];
        memset(szUtf8, 0, len + 1);
        WideCharToMultiByte(CP_UTF8, 0, wszUtf8, -1, szUtf8, len, NULL, NULL);
        strGBK = szUtf8;
        delete[] szUtf8;
        delete[] wszUtf8;
    }

stringbuffer.h 修改前:

    const Ch* GetString() const {
        // Push and pop a null terminator. This is safe.
        *stack_.template Push<Ch>() = '\0';
        stack_.template Pop<Ch>(1);

        return stack_.template Bottom<Ch>();
    }

修改后:

#include <afxstr.h>

    CString GetString() const {
        // Push and pop a null terminator. This is safe.
        *stack_.template Push<Ch>() = '\0';
        stack_.template Pop<Ch>(1);

        CString sRet(stack_.template Bottom<Ch>());
        ConvertUtf8ToGBK(sRet);
        return sRet;
    }

   
    void ConvertUtf8ToGBK(CString& strUtf8) const
    {
        int len = MultiByteToWideChar(CP_UTF8, 0, (LPCTSTR)strUtf8, -1, NULL, 0);
        wchar_t* wszGBK = new wchar_t[len];
        memset(wszGBK, 0, len);
        MultiByteToWideChar(CP_UTF8, 0, (LPCTSTR)strUtf8, -1, wszGBK, len);
        len = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL);
        char* szGBK = new char[len + 1];
        memset(szGBK, 0, len + 1);
        WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, szGBK, len, NULL, NULL);
        strUtf8 = szGBK;
        delete[] szGBK;
        delete[] wszGBK;
    }

接口封装类的修改:

对rapidJson调用做了封装,调用时原则上通过CJsonHelper实现。为了防止调用GenericValue类AddMember方法将其删除:(document.h)——GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator)。

对rapidjson的接口封装

  • 24
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值