这个写的有些复杂,包含太多方法了。其实我真正在项目里用的是自己简化的版本,不过都是基于这个版本修改的。
.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_