rapidjson读写方法总结

原创 2015年11月20日 16:46:50

这个写的有些复杂,包含太多方法了。其实我真正在项目里用的是自己简化的版本,不过都是基于这个版本修改的。
.h 文件

//*******************************
// Json Parse
// Created by Simon on 10/29/2015
//*******************************

#ifndef _JSON_UTILS_H_
#define  _JSON_UTILS_H_

#include <iostream>
#include <string>
#include "json/rapidjson.h"
#include "json/document.h"
#include "json/writer.h"
#include "json/stringbuffer.h"
#include "json/prettywriter.h"
#include "cocos2d.h"

using namespace std;
using namespace rapidjson;
USING_NS_CC;

// Basic Check;
#define json_check_is_bool(value, strKey) (value.HasMember(strKey) && value[strKey].IsBool())
#define json_check_is_string(value, strKey) (value.HasMember(strKey) && value[strKey].IsString())
#define json_check_is_int32(value, strKey) (value.HasMember(strKey) && value[strKey].IsInt())
#define json_check_is_uint32(value, strKey) (value.HasMember(strKey) && value[strKey].IsUint())
#define json_check_is_int64(value, strKey) (value.HasMember(strKey) && value[strKey].IsInt64())
#define json_check_is_uint64(value, strKey) (value.HasMember(strKey) && value[strKey].IsUint64())
#define json_check_is_double(value, strKey) (value.HasMember(strKey) && value[strKey].IsDouble())
#define json_check_is_number(value, strKey) (value.HasMember(strKey) && value[strKey].IsNumber())
#define json_check_is_array(value, strKey) (value.HasMember(strKey) && value[strKey].IsArray())
#define json_check_is_object(value, strKey) (value.HasMember(strKey) && value[strKey].IsObject())

// Utils Method;
#if (0)    // 1 Myself Debug Mode
inline void String_Check_Null(string _String_, string _Method_) { if (_String_ == "") MessageBox(StringUtils::format("Has null string In %s", _Method_).c_str(), "HasParseError"); }
inline void File_Not_Exist(const char* _File_, const char* _Method_) {MessageBox(StringUtils::format("CODE-ERROR %s Does Not Exist, then create this, Method = %s", _File_, _Method_).c_str(), "File does not exist");}
#else
inline void String_Check_Null(string _String_, const char* _Method_) { if (_String_ == "") CCLOG(StringUtils::format("Has null string In %s, HasParseError", _Method_).c_str()); }
inline void File_Not_Exist(const char* _File_, const char* _Method_) { CCLOG(StringUtils::format("CODE-ERROR %s Does Not Exist, then create this, Method = %s ", _File_, _Method_).c_str()); }
inline void DefaultFile(string _File_) { CCLOG("Platform Default Path = %s", _File_.c_str()); }

#endif

// File Path;
const string _USER_ = "user.json";
const string _TEST_ = "test.json";

const string REF_PATH = "data/";

const int ENCRYPTION = 0;

class JsonUtils : public Ref
{
private:
	JsonUtils();
	~JsonUtils();

	static JsonUtils* _self;

	map<std::string, rapidjson::Document*> _docBuffer;

public:
	static JsonUtils* getInstance();
	void deleteInstance();

	//-----------UserData-Method-Begin-----------;

	// Type 1 : writable path, Type : 0 resource path;
	void loadJson(string filename, bool isWritable = true);
	void parseJson(string filename, string jsonBuffer);
	void writeJson(string filename);
    void setValue(string filename, string key, rapidjson::Value& value, bool save = false);
	void saveJson(rapidjson::Document* doc, const std::string &fileName, bool prettyFlag = true, bool Asynchronous = false);
    void saveJson(const std::string& filename, bool prettyFlag = true, bool Asynchronous = false);
    void unloadJson(string filename);

	void setIntegerForKey(string key, int value, string filename, bool save = false);
	int getIntegerForKey(string key, string filename);
    void setBooleanForKey(string key, bool value, string filename, bool save = false);
	bool getBooleanForKey(string key, string filename);
    void setDoubleForKey(string key, float value, string filename, bool save = false);
	float getDoubleForKey(string key, string filename);
    void setStringForKey(string key, string value, string filename, bool save = false);
	string getStringForKey(string key, string filename);
	rapidjson::Document* getDoc(string filename);
    rapidjson::Value& getValue(string filename, string key);
    void testCode();

	//--------------UserData-Method-End-------------

};

#endif  //_JSON_UTILS_H_
//_EOF_/.--- ... --- -. ..- - .. .-.. ... .-.-.- ..../


.cpp文件

//*******************************
// Json Parse
// Created on 10/29/2015
//*******************************

#include "JsonUtils.h"

JsonUtils* JsonUtils::_self = nullptr;

JsonUtils::JsonUtils()
{
	_docBuffer.clear();
}

JsonUtils::~JsonUtils()
{
}

JsonUtils* JsonUtils::getInstance()
{
	if (!_self)
	{
		_self = new JsonUtils();
	}
	return _self;
}

void JsonUtils::deleteInstance()
{
	if (_self)
	{
		delete(_self);
	}
	_self = nullptr;
}

void JsonUtils::loadJson(string filename, bool isWritable)
{
    string path = "";
    if (isWritable)
	{
        path = FileUtils::getInstance()->getWritablePath().append(filename);
		assert(path!="");
	}
	else
	{
        path = REF_PATH + filename;
	}

	if (!FileUtils::getInstance()->isFileExist(path))
	{
        File_Not_Exist(filename.c_str(), "JsonUtils::loadJson");
		writeJson(filename);
	}

	string jsonBuffer = FileUtils::getInstance()->getStringFromFile(path);
	assert(jsonBuffer != "");
	parseJson(filename, jsonBuffer);
}

void JsonUtils::parseJson(string filename, string jsonBuffer)
{
	rapidjson::Document* doc = new rapidjson::Document();
	doc->Parse<rapidjson::kParseDefaultFlags>(jsonBuffer.c_str());
	assert(doc->IsObject());
	_docBuffer[filename] = doc;
}

void JsonUtils::writeJson(string filename)
{
	string value = filename + " data";
	rapidjson::Document* doc = new rapidjson::Document();
	rapidjson::Document::AllocatorType& allocator = doc->GetAllocator();
	doc->SetObject();
	doc->AddMember("description", StringRef(value.c_str()), allocator);
	saveJson(doc, filename);
}

void JsonUtils::setValue(string filename, string key, rapidjson::Value& value, bool save)
{
	rapidjson::Document* doc = _docBuffer[filename];
	rapidjson::Document::AllocatorType& allocator = doc->GetAllocator();
	assert(doc->IsObject());
	rapidjson::Value& var = *doc;
	if (doc->HasMember(key.c_str()))
	{
		var[key.c_str()] = value;
        if (save)
            saveJson(doc, filename);
	}
	else
	{
		doc->AddMember(StringRef(key.c_str()), value, allocator);

        saveJson(doc, filename);
        string name = filename + ".json";
        string jsonBuffer = FileUtils::getInstance()->getStringFromFile(FileUtils::getInstance()->getWritablePath().append(name));
        assert(jsonBuffer != "");
        parseJson(filename, jsonBuffer);
	}
}

void JsonUtils::saveJson(rapidjson::Document* doc, const std::string &fileName, bool prettyFlag, bool Asynchronous)
{
	StringBuffer buffer;
	buffer.Clear();
	if (prettyFlag)
	{
		rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);
		//writer.SetIndent(' ', 2);
        doc->Accept(writer);
	}
	else
	{
		rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
		doc->Accept(writer);
	}

	std::function<void(std::string, std::string)> saveHandler = [](std::string str, std::string fName)
	{
#if ENCRYPTION
		std::string tag = fName;
		for (int i = 0; i < str.size(); i++)
			str[i] ^= tag[i % tag.size()];
#endif
        std::string filepath = FileUtils::getInstance()->getWritablePath().append(fName);
		FILE *fp = fopen(filepath.c_str(), "wb");
		//fputs(str.c_str(), fp);
		fwrite(str.c_str(), 1, str.size(), fp);

#if ENCRYPTION
		string tagStr = tag;
		for (int i = 0; i < tag.size(); i++)
			tagStr[i] ^= tag[tag.size() - 1 - i];
		fwrite(tagStr.c_str(), 1, tagStr.size(), fp);
#endif
		fclose(fp);
	};

	if (Asynchronous)
	{
		std::thread save(saveHandler, std::string(buffer.GetString(), buffer.GetSize()), fileName);
		save.detach();
	}
	else
	{
		saveHandler(std::string(buffer.GetString(), buffer.GetSize()), fileName);
	}
}

void JsonUtils::saveJson(const std::string& filename, bool prettyFlag /*= true*/, bool Asynchronous /*= false*/)
{
    saveJson(_docBuffer[filename], filename, prettyFlag, Asynchronous);
}

void JsonUtils::unloadJson(string filename)
{
	map<string, rapidjson::Document*>::iterator iter;
    iter = _docBuffer.find(filename);
	if (iter != _docBuffer.end())
	{
		_docBuffer.erase(iter);
	}
}

void JsonUtils::setIntegerForKey(string key, int value, string filename, bool save)
{
	rapidjson::Document* doc = _docBuffer[filename];
	rapidjson::Document::AllocatorType& allocator = doc->GetAllocator();
	if (json_check_is_int32((*doc), key.c_str()))
	{
		(*doc)[key.c_str()].SetInt(value);
        if (save)
            saveJson(doc, filename);
	}
	else
	{
		doc->AddMember(StringRef(key.c_str()), value, allocator);

        saveJson(doc, filename);
        string name = filename + ".json";
        string jsonBuffer = FileUtils::getInstance()->getStringFromFile(FileUtils::getInstance()->getWritablePath().append(name));
        assert(jsonBuffer != "");
        parseJson(filename, jsonBuffer);
	}
}

int JsonUtils::getIntegerForKey(string key, string filename)
{
	rapidjson::Document* doc = _docBuffer[filename];
	assert(doc);
    if (json_check_is_int32((*doc), key.c_str()))
	{
		return (*doc)[key.c_str()].GetInt();
	}
	return 0;
}

void JsonUtils::setBooleanForKey(string key, bool value, string filename, bool save)
{
	rapidjson::Document* doc = _docBuffer[filename];
	rapidjson::Document::AllocatorType& allocator = doc->GetAllocator();
	rapidjson::Value& var = *doc;
	if (json_check_is_bool(var, key.c_str()))
	{
		var[key.c_str()].SetBool(value);
        if (save)
            saveJson(doc, filename);
	}
	else
	{
		doc->AddMember(StringRef(key.c_str()), value, allocator);

        saveJson(doc, filename);
        string name = filename + ".json";
        string jsonBuffer = FileUtils::getInstance()->getStringFromFile(FileUtils::getInstance()->getWritablePath().append(name));
        assert(jsonBuffer != "");
        parseJson(filename, jsonBuffer);
	}
}

bool JsonUtils::getBooleanForKey(string key, string filename)
{
	if (_docBuffer[filename] && _docBuffer[filename]->HasMember(key.c_str()))
	{
		return (*_docBuffer[filename])[key.c_str()].GetBool();
	}
	return false;
}

void JsonUtils::setDoubleForKey(string key, float value, string filename, bool save)
{
	rapidjson::Document* doc = _docBuffer[filename];
	rapidjson::Document::AllocatorType& allocator = doc->GetAllocator();
	rapidjson::Value& var = *doc;
    string floatStr = __String::createWithFormat("%.2f", value)->getCString();
    if (json_check_is_string(var, key.c_str()))
	{
        var[key.c_str()].SetString(StringRef(floatStr.c_str()), allocator);
        if (save)
            saveJson(doc, filename);
	}
	else
	{
        doc->AddMember(StringRef(key.c_str()), StringRef(floatStr.c_str()), allocator);
        saveJson(doc, filename);
        string name = filename + ".json";
        string jsonBuffer = FileUtils::getInstance()->getStringFromFile(FileUtils::getInstance()->getWritablePath().append(name));
        assert(jsonBuffer != "");
        parseJson(filename, jsonBuffer);
	}
}

float JsonUtils::getDoubleForKey(string key, string filename)
{
	if (_docBuffer[filename] && _docBuffer[filename]->HasMember(key.c_str()))
	{
		return atof(((*_docBuffer[filename])[key.c_str()].GetString()));
	}
	return 0.0f;
}

void JsonUtils::setStringForKey(string key, string value, string filename, bool save)
{
	rapidjson::Document* doc = _docBuffer[filename];
	rapidjson::Document::AllocatorType& allocator = doc->GetAllocator();
	rapidjson::Value& var = *doc;
	if (json_check_is_string(var, key.c_str()))
	{
        var[key.c_str()].SetString(StringRef(value.c_str()), allocator);
        if (save)
            saveJson(doc, filename);
	}
	else
	{
		doc->AddMember(StringRef(key.c_str()), StringRef(value.c_str()), allocator);

        saveJson(doc, filename);
        string name = filename + ".json";
        string jsonBuffer = FileUtils::getInstance()->getStringFromFile(FileUtils::getInstance()->getWritablePath().append(name));
        assert(jsonBuffer != "");
        parseJson(filename, jsonBuffer);
	}
}

std::string JsonUtils::getStringForKey(string key, string filename)
{
	if (_docBuffer[filename] && _docBuffer[filename]->HasMember(key.c_str()))
	{
		return (*_docBuffer[filename])[key.c_str()].GetString();
	}
	return "";
}

rapidjson::Document* JsonUtils::getDoc(string filename)
{
	if (_docBuffer[filename])
	{
		return _docBuffer[filename];
	}
    return nullptr;
}

rapidjson::Value& JsonUtils::getValue(string filename, string key)
{
    if (_docBuffer[filename] && _docBuffer[filename]->HasMember(key.c_str()))
    {
        return (*_docBuffer[filename])[key.c_str()];
    }
}

void JsonUtils::testCode()
{
    JsonUtils::getInstance()->loadJson(_USER_);
    JsonUtils::getInstance()->loadJson(_TEST_);

    int num = 100;
    string key1 = "aaa";
    string key2 = "bb";
    string key3 = "c";
    string key4 = "d";
    JsonUtils::getInstance()->setIntegerForKey(key1, num, _USER_);
    JsonUtils::getInstance()->setIntegerForKey(key1, num, _TEST_);
    int temp = JsonUtils::getInstance()->getIntegerForKey(key1, _USER_);
    int temp2 = JsonUtils::getInstance()->getIntegerForKey(key1, _TEST_);
    CCLOG("%d  %d ", temp, temp2);

    JsonUtils::getInstance()->setStringForKey(key4, "dddddddd", _USER_);
    string temp9 = JsonUtils::getInstance()->getStringForKey(key4, _USER_);
    CCLOG("%s", temp9.c_str());

    JsonUtils::getInstance()->setStringForKey(key4, "ffffffff", _USER_);
    string temo0 = JsonUtils::getInstance()->getStringForKey(key4, _USER_);
    CCLOG("%s", temo0.c_str());

    JsonUtils::getInstance()->setBooleanForKey(key2, true, _USER_);
    JsonUtils::getInstance()->setBooleanForKey(key2, true, _TEST_);
    bool temp32 = JsonUtils::getInstance()->getBooleanForKey(key2, _USER_);
    bool temp3 = JsonUtils::getInstance()->getBooleanForKey(key2, _TEST_);
    
    JsonUtils::getInstance()->setDoubleForKey(key3, 1.56f, _USER_);
    double temp6 = JsonUtils::getInstance()->getDoubleForKey(key3, _USER_);
    CCLOG("%f     ", temp6);

    JsonUtils::getInstance()->saveJson(_USER_);

    // Value Methods;
    rapidjson::Value cache;
    cache.SetInt(12220);
    JsonUtils::getInstance()->setValue(_USER_, "qwer", cache);

    cache.SetBool(false);
    JsonUtils::getInstance()->setValue(_USER_, "bool", cache);

    cache.SetDouble(1.9966f);
    JsonUtils::getInstance()->setValue(_USER_, "float", cache);

    cache.SetString("gggg");
    JsonUtils::getInstance()->setValue(_USER_, "ConstString", cache);

    string hello = "dd";
    cache.SetString(StringRef(hello.c_str()));
    JsonUtils::getInstance()->setValue(_USER_, "CopyString", cache);

    rapidjson::Document* please = JsonUtils::getInstance()->getDoc(_USER_);
    CCLOG("%s", (*please)["d"].GetString());

    // Other Path Files;
    JsonUtils::getInstance()->loadJson("data.json", false);
    string data = JsonUtils::getInstance()->getStringForKey(key4, "data");
    CCLOG("data from ref/data %s", data.c_str());
}

//_EOF_


rapidjson使用总结

rapidjson是腾讯的开源json解析框架,用c++实现。由于全部代码仅用header file实现,所以很容易集成到项目中。 rapidjson的性能是很出色的,其作者[Milo Yipz](...
  • elloop
  • elloop
  • 2015年11月18日 16:13
  • 37778

rapidjson官方教程

教程 目录 Value 及 Document 查询Value 查询Array 查询Object 查询Number 查询String 创建/修改值 改变Value类型 转移语意(...

如何使用rapidjson库进行json格式的封装及解析

一,字符串json封装及及解析的实例 #include "rapidjson/document.h" #include "rapidjson/prettywriter.h"   #inclu...

RapidJson简单实例

一、RapidJson的详细介绍网站:http://miloyip.github.io/rapidjson/zh-cn/  二、 1、RapidJson的实践一:解析一个字符串。 std::st...
  • Cvito
  • Cvito
  • 2015年06月24日 13:22
  • 2438

rapidjson的使用例子

最近在使用json, 由以前的jsoncpp转为rapidjson, 听说这个效率高一点; 不过我觉得比较好的就是rapidjson不需要库,只要头文件就可以了 记录下来方便自己以后使用 #incl...

Rapidjson的简单使用示例

很早就想用用Markdown了,一直没机会。今天就来试一下 先放个目录: Rapidjson的简单使用示例 rapidjson官方教程 本示例所用环境 示...

c++中rapidjson库下载安装及使用

rapidjson库官网地址:http://www.oschina.net/news/61812/rapidjson-1-0-final rapidjson库下载网地址:https://github...

[rapidjson]_[C/C++]_[rapidjson库使用简单介绍]

场景: 1.cpp的json有很多,其中哟jsoncpp等,rapidjson是一个比较好的选择,特别是开发跨平台应用时,因为它只有头文件. 2.再用cpp生成html网页时,通过json数据和j...

rapidjson常见使用示例

// 需要#include的头文件: #include #include #include // 需要#include的头文件: #include #include #include //...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:rapidjson读写方法总结
举报原因:
原因补充:

(最多只允许输入30个字)