rapidjson效率高,所以之前cocostudio里面解析用的jsoncpp也换成了rapidjson。
引擎又带有rapidjson库,所以不用单独去下载,直接就可以用。
这里主要写一下关于解析和存储的代码笔记。
1. 解析
#include "json/rapidjson.h" #include "json/document.h" #include "json/writer.h" #include "json/stringbuffer.h" #define FILE_Name "EmailInfo.txt" #define KEY_Root "EmailList" #define KEY_Id "id" #define KEY_Type "type" #define KEY_Content "content" #define KEY_BonusId "bonus_unitID" #define KEY_BonusCount "bonusCount" #define KEY_IsRead "isAlreadyRead" #define KEY_RecvTime "recvTime" //将要解析的json格式 // { // "EmailList":[ // { // "id":1, // "type":1, // "content":"string", // "bonus_unitID":99, // "bonusCount":10, // "isAlreadyRead":false, // "recvTime":11111 // } // ] // } //解析函数 bool EmailHelper::initData() { string filePath = FileUtils::getInstance()->getWritablePath(); filePath += FILE_Name; Data dat = FileUtils::getInstance()->getDataFromFile(filePath); if (dat.getSize() <= 0) { // no file CCLOG("%s ---> no file [%s]", __FUNCTION__, filePath.c_str()); return false; } char *buf = new char[dat.getSize()+1]; strncpy(buf, (char*)dat.getBytes(), dat.getSize()); buf[dat.getSize()] = 0; //重新分配内存就是为了这一步,否则直接用Data来解析会解析错误。 CCLOG("%s ---> %s\n", __FUNCTION__, buf); rapidjson::Document d; d.Parse<0>(buf); delete [] buf; if (d.HasParseError()) //解析错误 { CCLOG("%s ---> GetParseError %s\n", __FUNCTION__, d.GetParseError()); return false; } else if (d.IsObject()) { if (d.HasMember(KEY_Root) && d[KEY_Root].IsArray()/* && d[KEY_Root].Size() > 0*/) { const rapidjson::Value& arr = d[KEY_Root]; for (int i=0,count=arr.Size(); i<count; ++i) { Email temp; if (arr[i].HasMember(KEY_Id)) temp.id = arr[i][KEY_Id].GetUint(); if (arr[i].HasMember(KEY_Type)) temp.type = (Email::EmailType)arr[i][KEY_Type].GetUint(); if (arr[i].HasMember(KEY_Content)) temp.content = arr[i][KEY_Content].GetString(); if (arr[i].HasMember(KEY_BonusId)) temp.bonus_unitID = arr[i][KEY_BonusId].GetUint(); if (arr[i].HasMember(KEY_BonusCount)) temp.bonusCount = arr[i][KEY_BonusCount].GetUint(); if (arr[i].HasMember(KEY_IsRead)) temp.isAlreadyRead = arr[i][KEY_IsRead].GetBool(); if (arr[i].HasMember(KEY_RecvTime)) temp.recvTime = arr[i][KEY_RecvTime].GetInt(); m_vecEmailList.push_back(temp); } return true; } } return false; }
2. 存储
bool EmailHelper::saveData() { rapidjson::Document document; document.SetObject(); //Set this value as an empty object. rapidjson::Document::AllocatorType& allocator = document.GetAllocator(); //value rapidjson::Value emailArr(rapidjson::kArrayType); for (int i=0,count=m_vecEmailList.size(); i<count; ++i) { rapidjson::Value object(rapidjson::kObjectType); object.AddMember<unsigned int>(KEY_Id, m_vecEmailList[i].id, allocator); object.AddMember<unsigned int>(KEY_Type, m_vecEmailList[i].type, allocator); object.AddMember<const char*>(KEY_Content, m_vecEmailList[i].content.c_str(), allocator); object.AddMember<unsigned int>(KEY_BonusId, m_vecEmailList[i].bonus_unitID, allocator); object.AddMember<unsigned int>(KEY_BonusCount, m_vecEmailList[i].bonusCount, allocator); object.AddMember<bool>(KEY_IsRead, m_vecEmailList[i].isAlreadyRead, allocator); object.AddMember<int>(KEY_RecvTime, m_vecEmailList[i].recvTime, allocator); emailArr.PushBack(object, allocator); } document.AddMember(KEY_Root, emailArr, allocator); rapidjson::StringBuffer buffer; rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); document.Accept(writer); string filePath = FileUtils::getInstance()->getWritablePath(); filePath += FILE_Name; FILE* fp = fopen(FileUtils::getInstance()->fullPathForFilename(filePath).c_str(),"w+");//具有读写属性,写的时候如果文件存在,会被清空,从头开始写。 if (!fp) { CCASSERT(fp,"file open faild!"); return false; } fwrite(buffer.GetString(),sizeof(char),buffer.Size(),fp); fclose(fp); CCLOG("%s %s ---> %s", __FUNCTION__, filePath.c_str(), buffer.GetString()); return true; }