使用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()); }