jsoncpp按寫入順序讀取
在不修改jsoncpp原始碼的基礎上,按照寫入順序讀取,編寫JsonValue類派生自Json::Value。
jsonvalue.h
#ifndef JSONVALUE_H
#define JSONVALUE_H
#include <jsoncpp/json/json.h>
class JsonValue : public Json::Value
{
public:
static inline Json::Value &toValue(JsonValue &value)
{
return *reinterpret_cast<Json::Value*>(&value);
}
static inline JsonValue &fromValue(Json::Value &value)
{
return *reinterpret_cast<JsonValue*>(&value);
}
static inline const Json::Value &toConstValue(const JsonValue &value)
{
return *reinterpret_cast<const Json::Value*>(&value);
}
static inline const JsonValue &fromConstValue(const Json::Value &value)
{
return *reinterpret_cast<const JsonValue*>(&value);
}
public:
JsonValue(Json::ValueType type = Json::ValueType::nullValue):Json::Value(type){}
JsonValue(Int value):Json::Value(value){}
JsonValue(UInt value):Json::Value(value){}
#if defined(JSON_HAS_INT64)
JsonValue(Int64 value):Json::Value(value){}
JsonValue(UInt64 value):Json::Value(value){}
#endif // if defined(JSON_HAS_INT64)
JsonValue(double value):Json::Value(value){}
JsonValue(const char* value):Json::Value(value){}
JsonValue(const char* begin, const char* end):Json::Value(begin, end){}
JsonValue(const Json::StaticString& value):Json::Value(value){}
JsonValue(const JSONCPP_STRING& value):Json::Value(value){}///< Copy data() til size(). Embedded zeroes too.
#ifdef JSON_USE_CPPTL
JsonValue(const CppTL::ConstString& value):Json::Value(value){}
#endif
JsonValue(bool value):Json::Value(value){}
JsonValue(const Json::Value& other):Json::Value(other){}
JsonValue(const JsonValue& other):Json::Value(toConstValue(other)){}
#if JSON_HAS_RVALUE_REFERENCES
JsonValue(JsonValue&& other):Json::Value(other){}
#endif
JsonValue& operator=(JsonValue other) {return fromValue(Json::Value::operator=(toValue(other)));}
void swap(Value& other){Json::Value::swap(other);}
void swapPayload(Value& other){Json::Value::swapPayload(other);}
Json::ValueType type() const{return Json::Value::type();}
/// Compare payload only, not comments etc.
bool operator<(const JsonValue& other) const{return Json::Value::operator<(other);}
bool operator<=(const JsonValue& other) const{return Json::Value::operator<=(other);}
bool operator>=(const JsonValue& other) const{return Json::Value::operator>=(other);}
bool operator>(const JsonValue& other) const{return Json::Value::operator>(other);}
bool operator==(const JsonValue& other) const{return Json::Value::operator==(other);}
bool operator!=(const JsonValue& other) const{return Json::Value::operator!=(other);}
int compare(const JsonValue& other) const{return Json::Value::compare(other);}
public:
JsonValue& operator[](ArrayIndex index){return fromValue(Json::Value::operator[](index));}
JsonValue& operator[](int index){return fromValue(Json::Value::operator[](index));}
const JsonValue& operator[](ArrayIndex index) const{return fromConstValue(Json::Value::operator[](index));}
const JsonValue& operator[](int index) const {return fromConstValue(Json::Value::operator[](index));}
JsonValue get(ArrayIndex index, const JsonValue& defaultValue) const{return Json::Value::get(index, defaultValue);}
JsonValue& append(const JsonValue& value){return fromValue(Json::Value::append(value));}
const JsonValue& operator[](const char* key) const{return fromConstValue(Json::Value::operator[](key));}
const JsonValue& operator[](const JSONCPP_STRING& key) const{return fromConstValue(Json::Value::operator[](key));}
JsonValue get(const char* key, const JsonValue& defaultValue) const{return Json::Value::get(key, defaultValue);}
JsonValue get(const char* begin, const char* end, const JsonValue& defaultValue) const{return Json::Value::get(begin, end, defaultValue);}
JsonValue get(const JSONCPP_STRING& key, const JsonValue& defaultValue) const{return Json::Value::get(key, defaultValue);}
#ifdef JSON_USE_CPPTL
JsonValue get(const CppTL::ConstString& key, const JsonValue& defaultValue) const{return Json::Value::get(key, defaultValue);}
#endif
JsonValue const* find(char const* begin, char const* end) const {return reinterpret_cast<JsonValue const*>(Json::Value::find(begin, end));}
JsonValue const* demand(char const* begin, char const* end){return reinterpret_cast<JsonValue const*>(Json::Value::demand(begin, end));}
inline JsonValue& operator[](const JSONCPP_STRING& key){return JsonValue::operator[](key.c_str());}
inline JsonValue& operator[](const Json::StaticString& key) {return JsonValue::operator[](key.c_str());}
#ifdef JSON_USE_CPPTL
JsonValue& operator[](const CppTL::ConstString& key){return fromValue(Json::Value::operator[](key));};
const JsonValue& operator[](const CppTL::ConstString& key) const{return fromValue(Json::Value::operator[](key));};
#endif
JsonValue removeMember(const JSONCPP_STRING& key){return removeMember(key.c_str());}
bool removeMember(JSONCPP_STRING const& key, JsonValue* removed){return removeMember(key.c_str(), removed);}
bool removeMember(const char* begin, const char* end, JsonValue* removed) {return Json::Value::removeMember(std::string(begin, end - begin).c_str(), removed);}
bool removeIndex(ArrayIndex i, JsonValue* removed) {return Json::Value::removeIndex(i, reinterpret_cast<Json::Value*>(removed));}
public:
JsonValue& operator[](const char* key);
Members getMemberNames() const;
JsonValue removeMember(const char* key);
bool removeMember(const char* key, JsonValue* removed);
public:
static std::string m_KeyWordQueueName;
};
#endif // JSONVALUE_H
jsonvalue.cpp
#include "jsonvalue.h"
std::string JsonValue::m_KeyWordQueueName = "#JsonValue#Members";
JsonValue& JsonValue::operator[](const char* key) {
if(m_KeyWordQueueName != key)
{
if(isMember(m_KeyWordQueueName)) {
Json::Value& object = Json::Value::operator[](m_KeyWordQueueName.c_str());
if(object.isArray()) {
int32_t bufPos = object.size();
for(int32_t i = 0; i < bufPos; ++i) {
if(object[i] == key) {
return fromValue(Json::Value::operator[](key));
}
}
object[bufPos] = key;
}
else {
if(!object.isArray()) Json::Value::operator[](0) = key;
}
} else {
Json::Value::operator[](m_KeyWordQueueName)[0] = key;
}
}
return fromValue(Json::Value::operator[](key));
}
JsonValue::Members JsonValue::getMemberNames() const
{
JsonValue::Members cache;
if(isMember(m_KeyWordQueueName)) {
for(int i = 0; i < static_cast<int>(operator[](m_KeyWordQueueName).size()); ++i) {
cache.push_back(operator[](m_KeyWordQueueName)[i].asString());
}
}
return cache;
}
JsonValue JsonValue::removeMember(const char* key)
{
if(m_KeyWordQueueName != key) {
JsonValue::Members cache;
bool flag = false;
if(isMember(m_KeyWordQueueName)) {
for(int i = 0; i < static_cast<int>(operator[](m_KeyWordQueueName).size()); ++i) {
const auto &name = operator[](m_KeyWordQueueName)[i].asString();
if(name == key) {
flag = true;
} else {
cache.push_back(name);
}
}
}
if(flag) {
Json::Value::removeMember(m_KeyWordQueueName, this);
for(int i = 0; i < static_cast<int>(cache.size()); ++i) {
Json::Value::operator[](m_KeyWordQueueName)[i] = cache[i];
}
}
}
return JsonValue(Json::Value::removeMember(key));
}
bool JsonValue::removeMember(const char* key, JsonValue* removed)
{
if(m_KeyWordQueueName != key) {
JsonValue::Members cache;
bool flag = false;
if(isMember(m_KeyWordQueueName)) {
for(int i = 0; i < static_cast<int>(operator[](m_KeyWordQueueName).size()); ++i) {
const auto &name = operator[](m_KeyWordQueueName)[i].asString();
if(name == key) {
flag = true;
} else {
cache.push_back(name);
}
}
}
if(flag) {
Json::Value::removeMember(m_KeyWordQueueName, this);
for(int i = 0; i < static_cast<int>(cache.size()); ++i) {
Json::Value::operator[](m_KeyWordQueueName)[i] = cache[i];
}
}
}
return Json::Value::removeMember(key, reinterpret_cast<Json::Value*>(removed));
}
main.cpp
#include <QCoreApplication>
#include <QDebug>
#include "jsonvalue.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
JsonValue root;
constexpr bool shouldUseOldWay = false;
int count = 0;
root["className"] = "高一(3)班";
root["teacher"]["name"] = "小王";
root["teacher"]["age"] = 28;
//陣列
root["student"][count]["name"] = "張三";
root["student"][count]["age"] = 15;
root["student"][count]["friend"]["name"] = "大黃";
root["student"][count]["friend"]["age"] = 3;
++count;
root["student"][count]["name"] = "李四";
root["student"][count]["age"] = 14;
root["student"][count]["friend"]["name"] = "小黑";
root["student"][count]["friend"]["age"] = 3;
++count;
root["student"][count]["name"] = "王五";
root["student"][count]["age"] = 13;
root["student"][count]["friend"]["name"] = "大花";
root["student"][count]["friend"]["age"] = 3;
++count;
if (shouldUseOldWay) {
Json::FastWriter writer;
const std::string json_file = writer.write(root);
qInfo() << json_file.c_str();
} else {
Json::StreamWriterBuilder builder;
const std::string json_file = Json::writeString(builder, root);
qInfo() << json_file.c_str();
}
return a.exec();
}
以派生類JsonValue代替基類Json::Value即可自動實現key值順序記錄,讀取時使用getMemberNames獲取到的key值陣列中的key值順序與寫入時相同。