• 使用rapidjson实现了TouchVG的序列化适配器类


    外部接口类隐藏JSON细节:

    #ifndef __GEOMETRY_JSONSTORAGE_H_
    #define __GEOMETRY_JSONSTORAGE_H_
    
    struct MgStorage;
    
    //! JSON序列化适配器类
    /*! \ingroup GEOM_SHAPE
    */
    class MgJsonStorage
    {
    public:
        MgJsonStorage();
        ~MgJsonStorage();
    
        //! 给定JSON内容,返回存取接口对象以便开始读取
        MgStorage* storageForRead(const char* content);
    
        //! 返回存取接口对象以便开始写数据,写完可调用 getContentWriten()
        MgStorage* storageForWrite();
    
        //! 返回写完后的JSON内容
        const char* getContentWriten() const;
    
    private:
        class Impl;
        Impl* _impl;
    };
    
    #endif // __GEOMETRY_JSONSTORAGE_H_

    内部实现文件使用rapidjson框架,代码少、运行速度比iOS和Android的Json框架快。

    #include "mgjsonstorage.h"
    #include <mgstorage.h>
    #include <vector>
    #include "rapidjson/document.h"     // rapidjson's DOM-style API
    #include "rapidjson/prettywriter.h" // for stringify JSON
    #include "rapidjson/filestream.h"   // wrapper of C stream for prettywriter as output
    #include "rapidjson/stringbuffer.h"
    
    using namespace rapidjson;
    
    //! JSON序列化适配器类,内部实现类
    class MgJsonStorage::Impl : public MgStorage
    {
    public:
        Impl() {}
    
        void clear();
        const char* getContent() const;
        void setContent(const char* content);
    
    private:
        bool readNode(const char* name, int index, bool ended);
        bool writeNode(const char* name, int index, bool ended);
    
        int readInt(const char* name, int defvalue);
        bool readBool(const char* name, bool defvalue);
        float readFloat(const char* name, float defvalue);
        int readFloatArray(const char* name, float* values, int count);
        int readString(const char* name, char* value, int count);
    
        void writeInt(const char* name, int value);
        void writeBool(const char* name, bool value);
        void writeFloat(const char* name, float value);
        void writeFloatArray(const char* name, const float* values, int count);
        void writeString(const char* name, const char* value);
    
    private:
        Document _doc;
        std::vector<Value*> _stack;
        StringBuffer _strbuf;
    };
    
    MgJsonStorage::MgJsonStorage()
    {
        _impl = new Impl();
    }
    
    MgJsonStorage::~MgJsonStorage()
    {
        delete _impl;
    }
    
    const char* MgJsonStorage::getContentWriten() const
    {
        return _impl->getContent();
    }
    
    MgStorage* MgJsonStorage::storageForRead(const char* content)
    {
        _impl->clear();
        _impl->setContent(content);
    
        return _impl;
    }
    
    MgStorage* MgJsonStorage::storageForWrite()
    {
        _impl->clear();
    
        return _impl;
    }
    
    void MgJsonStorage::Impl::clear()
    {
        _doc.SetNull();
        _stack.clear();
        _strbuf.Clear();
    }
    
    const char* MgJsonStorage::Impl::getContent() const
    {
        return _strbuf.GetString();
    }
    
    void MgJsonStorage::Impl::setContent(const char* content)
    {
        if (content && *content) {
            _doc.Parse<0>(content);         // DOM解析
            if (_doc.HasParseError()) {
                const char* err = _doc.GetParseError();
                err = err;
            }
        }
    }
    
    bool MgJsonStorage::Impl::readNode(const char* name, int index, bool ended)
    {
        if (!ended) {                       // 开始一个新节点
            char tmpname[32];
            if (index >= 0) {               // 形成实际节点名称
                sprintf(tmpname, "%s%d", name, index + 1);
                name = tmpname;
            }
    
            Value &parent = _stack.empty() ? _doc : *_stack.back();
    
            if (!parent.IsObject() || !parent.HasMember(name)) {    // 没有节点则返回
                return false;
            }
    
            _stack.push_back(&parent[name]);    // 当前JSON对象压栈
        }
        else {                              // 当前节点读取完成
            if (!_stack.empty()) {
                _stack.pop_back();          // 出栈
            }
            if (_stack.empty()) {           // 根节点已出栈
                clear();
            }
        }
    
        return true;
    }
    
    int MgJsonStorage::Impl::readInt(const char* name, int defvalue)
    {
        int ret = defvalue;
        Value *node = _stack.empty() ? NULL : _stack.back();
    
        if (node && node->HasMember(name)) {
            const Value &item = (*node)[name];
    
            if (item.IsInt()) {
                ret = item.GetInt();
            }
            else if (item.IsUint()) {
                ret = item.GetUint();
            }
            else {
                ret = ret;
            }
        }
    
        return ret;
    }
    
    bool MgJsonStorage::Impl::readBool(const char* name, bool defvalue)
    {
        bool ret = defvalue;
        Value *node = _stack.empty() ? NULL : _stack.back();
    
        if (node && node->HasMember(name)) {
            const Value &item = node->GetMember(name);
    
            if (item.IsBool()) {
                ret = item.GetBool();
            }
            else {
                ret = ret;
            }
        }
    
        return ret;
    }
    
    float MgJsonStorage::Impl::readFloat(const char* name, float defvalue)
    {
        float ret = defvalue;
        Value *node = _stack.empty() ? NULL : _stack.back();
    
        if (node && node->HasMember(name)) {
            const Value &item = node->GetMember(name);
    
            if (item.IsDouble()) {
                ret = (float)item.GetDouble();
            }
            else if (item.IsInt()) {    // 浮点数串可能没有小数点,需要判断整数
                ret = (float)item.GetInt();
            }
            else {
                ret = ret;
            }
        }
    
        return ret;
    }
    
    int MgJsonStorage::Impl::readFloatArray(const char* name, float* values, int count)
    {
        int ret = 0;
        Value *node = _stack.empty() ? NULL : _stack.back();
    
        if (node && node->HasMember(name)) {
            const Value &item = node->GetMember(name);
    
            if (item.IsArray()) {
                ret = item.Size();
                if (values) {
                    count = ret < count ? ret : count;
                    ret = 0;
                    for (int i = 0; i < count; i++) {
                        const Value &v = item[i];
    
                        if (v.IsDouble()) {
                            values[ret++] = (float)v.GetDouble();
                        }
                        else if (v.IsInt()) {
                            values[ret++] = (float)v.GetInt();
                        }
                        else {
                            ret = ret;
                        }
                    }
                }
            }
            else {
                ret = ret;
            }
        }
    
        return ret;
    }
    
    int MgJsonStorage::Impl::readString(const char* name, char* value, int count)
    {
        int ret = 0;
        Value *node = _stack.empty() ? NULL : _stack.back();
    
        if (node && node->HasMember(name)) {
            const Value &item = node->GetMember(name);
    
            if (item.IsString()) {
                ret = item.GetStringLength();
                if (value) {
                    ret = ret < count ? ret : count;
                    strncpy(value, item.GetString(), ret);
                }
            }
            else {
                ret = ret;
            }
        }
    
        return ret;
    }
    
    bool MgJsonStorage::Impl::writeNode(const char* name, int index, bool ended)
    {
        if (!ended) {                       // 开始一个新节点
            char tmpname[32];
            if (index >= 0) {               // 形成实际节点名称
                sprintf(tmpname, "%s%d", name, index + 1);
                name = tmpname;
            }
    
            if (_stack.empty()) {
                _doc.SetObject();
            }
    
            Value &parent = _stack.empty() ? _doc : *_stack.back();
            Value tmpnode(kObjectType);
            Value namenode(name, _doc.GetAllocator());  // 节点名是临时串,要复制
            
            parent.AddMember(namenode, tmpnode, _doc.GetAllocator());
            _stack.push_back(&(parent.MemberEnd() - 1)->value); // 新节点压栈
        }
        else {                              // 当前节点写完
            if (!_stack.empty()) {
                _stack.pop_back();          // 出栈
            }
            if (_stack.empty()) {           // 根节点已出栈
                Document::AllocatorType allocator;
                Writer<StringBuffer> writer(_strbuf, &allocator);
                _doc.Accept(writer);        // DOM树转换到文本流
    
                _doc.SetNull();
                _stack.clear();
            }
        }
    
        return true;
    }
    
    void MgJsonStorage::Impl::writeInt(const char* name, int value)
    {
        _stack.back()->AddMember(name, value, _doc.GetAllocator());
    }
    
    void MgJsonStorage::Impl::writeBool(const char* name, bool value)
    {
        _stack.back()->AddMember(name, value, _doc.GetAllocator());
    }
    
    void MgJsonStorage::Impl::writeFloat(const char* name, float value)
    {
        _stack.back()->AddMember(name, (double)value, _doc.GetAllocator());
    }
    
    void MgJsonStorage::Impl::writeFloatArray(const char* name, const float* values, int count)
    {
        Value node(kArrayType);
    
        for (int i = 0; i < count; i++) {
            node.PushBack((double)values[i], _doc.GetAllocator());
        }
        _stack.back()->AddMember(name, node, _doc.GetAllocator());
    }
    
    void MgJsonStorage::Impl::writeString(const char* name, const char* value)
    {
        _stack.back()->AddMember(name, value, _doc.GetAllocator());
    }
  • 相关阅读:
    java模拟多线程
    zookeeper的搭建方法
    虚拟机无法ping通物理机的解决方案
    虚拟机桥接模式下多台Ubuntu16.04系统互相连接
    Ubuntu下安装libpcap+测试安装
    在Ubuntu下安装gcc编译器+测试
    在Ubuntu下配置jdk+maven
    使用Xshell对虚拟机上的Ubuntu系统进行远程连接
    javaWeb开发中常见的问题
    如何用eclipse运行导入的maven项目
  • 原文地址:https://www.cnblogs.com/rhcad/p/2850331.html
Copyright © 2020-2023  润新知