上一节介绍了jsoncpp库的下载及编译方式,中Value类中最基础的一部分功能的源码,包括Value的构造形式、重载"="、">"、"<"、"<="、">="、"!="、"[]"符号、一部分功能函数,以及对它们各自举了示例进行了展示。本节将继续对Value类的剩余常用源码进行介绍并做示例分析。

Value类中有一部分用于从JSON对象中提取值时对结果进行类型转换的功能函数,这些函数声明如下:

//声明
const char* asCString() const;    //转换为const char*类型
String asString() const;          //转换为string类型
Int asInt() const;                //转换为int类型
UInt asUInt() const;              //转换为unsigned int类型
Int64 asInt64() const;            //转换为int64_t类型
UInt64 asUInt64() const;          //转换为uint64_t类型
LargestInt asLargestInt() const;  //转换为int64_t类型
LargestUInt asLargestUInt() const;//转换为uint64_t类型
float asFloat() const;            //转换为float类型
double asDouble() const;          //转换为double类型
bool asBool() const;              //转换为bool类型
unsigned getCStringLength() const;                            //获取字符串长度
bool getString(char const** begin, char const** end) const;   //获取原始字符串

实现源码如下:

//decodePrefixedString的实现,后面用到,主要就是用来对提前分配内存做保护,并把JSON对象中的值以字符串形式提取出来
inline static void decodePrefixedString(bool isPrefixed,char const* prefixed,unsigned* length,char const** value) {if (!isPrefixed) {*length = static_cast<unsigned>(strlen(prefixed));*value = prefixed;} else {*length = *reinterpret_cast<unsigned const*>(prefixed);*value = prefixed + sizeof(unsigned);}
}//asCString实现,只需调用上面的decodePrefixedString提取字符串,把字符串拿出来返回,它只能对JSON里的string类型转换,其他类型不能。
const char* Value::asCString() const {JSON_ASSERT_MESSAGE(type() == stringValue,"in Json::Value::asCString(): requires stringValue");if (value_.string_ == nullptr)return nullptr;unsigned this_len;char const* this_str;decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len,&this_str);return this_str;
}//asString的实现,以JSON后面值的不同的类型处理,反正最后的结果就是全部转成string表示。字符串类型的话,处理同asCString,只是最后将char*类型转换成string即可。如果是布尔,true就是"true",false就是"false",其余数字类型的,直接转成对应的字符表示即可。
String Value::asString() const {switch (type()) {case nullValue:return "";case stringValue: {if (value_.string_ == nullptr)return "";unsigned this_len;char const* this_str;decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len,&this_str);return String(this_str, this_len);}case booleanValue:return value_.bool_ ? "true" : "false";case intValue:return valueToString(value_.int_);case uintValue:return valueToString(value_.uint_);case realValue:return valueToString(value_.real_);default:JSON_FAIL_MESSAGE("Type is not convertible to string");}
}//asInt的实现,只要JSON对象的值不是不能转的字符串类型,就可以转成int,处理过程很简单。
Value::Int Value::asInt() const {switch (type()) {case intValue:JSON_ASSERT_MESSAGE(isInt(), "LargestInt out of Int range");return Int(value_.int_);case uintValue:JSON_ASSERT_MESSAGE(isInt(), "LargestUInt out of Int range");return Int(value_.uint_);case realValue:JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt, maxInt),"double out of Int range");return Int(value_.real_);case nullValue:return 0;case booleanValue:return value_.bool_ ? 1 : 0;default:break;}JSON_FAIL_MESSAGE("Value is not convertible to Int.");
}//asUInt的实现,与asInt相似。
Value::UInt Value::asUInt() const {switch (type()) {case intValue:JSON_ASSERT_MESSAGE(isUInt(), "LargestInt out of UInt range");return UInt(value_.int_);case uintValue:JSON_ASSERT_MESSAGE(isUInt(), "LargestUInt out of UInt range");return UInt(value_.uint_);case realValue:JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt),"double out of UInt range");return UInt(value_.real_);case nullValue:return 0;case booleanValue:return value_.bool_ ? 1 : 0;default:break;}JSON_FAIL_MESSAGE("Value is not convertible to UInt.");
}//asInt64的实现,与asInt相似。
#if defined(JSON_HAS_INT64)Value::Int64 Value::asInt64() const {switch (type()) {case intValue:return Int64(value_.int_);case uintValue:JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range");return Int64(value_.uint_);case realValue:JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt64, maxInt64),"double out of Int64 range");return Int64(value_.real_);case nullValue:return 0;case booleanValue:return value_.bool_ ? 1 : 0;default:break;}JSON_FAIL_MESSAGE("Value is not convertible to Int64.");
}//asUInt64的实现,与asInt相似。
Value::UInt64 Value::asUInt64() const {switch (type()) {case intValue:JSON_ASSERT_MESSAGE(isUInt64(), "LargestInt out of UInt64 range");return UInt64(value_.int_);case uintValue:return UInt64(value_.uint_);case realValue:JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt64),"double out of UInt64 range");return UInt64(value_.real_);case nullValue:return 0;case booleanValue:return value_.bool_ ? 1 : 0;default:break;}JSON_FAIL_MESSAGE("Value is not convertible to UInt64.");
}
#endif // if defined(JSON_HAS_INT64)//同asInt
LargestInt Value::asLargestInt() const {
#if defined(JSON_NO_INT64)return asInt();
#elsereturn asInt64();
#endif
}//同asUInt
LargestUInt Value::asLargestUInt() const {
#if defined(JSON_NO_INT64)return asUInt();
#elsereturn asUInt64();
#endif
}//asDouble的实现,与asInt相似,只是强转成double。
double Value::asDouble() const {switch (type()) {case intValue:return static_cast<double>(value_.int_);case uintValue:
#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)return static_cast<double>(value_.uint_);
#else  // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)return integerToDouble(value_.uint_);
#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)case realValue:return value_.real_;case nullValue:return 0.0;case booleanValue:return value_.bool_ ? 1.0 : 0.0;default:break;}JSON_FAIL_MESSAGE("Value is not convertible to double.");
}//asFloat的实现,与asDouble一样方法。
float Value::asFloat() const {switch (type()) {case intValue:return static_cast<float>(value_.int_);case uintValue:
#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)return static_cast<float>(value_.uint_);
#else  // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)// This can fail (silently?) if the value is bigger than MAX_FLOAT.return static_cast<float>(integerToDouble(value_.uint_));
#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)case realValue:return static_cast<float>(value_.real_);case nullValue:return 0.0;case booleanValue:return value_.bool_ ? 1.0f : 0.0f;default:break;}JSON_FAIL_MESSAGE("Value is not convertible to float.");
}//asBool的实现,对于数字型的,非0即是true,0即是false。
bool Value::asBool() const {switch (type()) {case booleanValue:return value_.bool_;case nullValue:return false;case intValue:return value_.int_ ? true : false;case uintValue:return value_.uint_ ? true : false;case realValue:// This is kind of strange. Not recommended.return (value_.real_ != 0.0) ? true : false;default:break;}JSON_FAIL_MESSAGE("Value is not convertible to bool.");
}//getCStringLength的实现,与asCString相同的处理方式,只是最后返回的是转换成的char*类型字符串长度
#if JSONCPP_USING_SECURE_MEMORY
unsigned Value::getCStringLength() const {JSON_ASSERT_MESSAGE(type() == stringValue,"in Json::Value::asCString(): requires stringValue");if (value_.string_ == 0)return 0;unsigned this_len;char const* this_str;decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len,&this_str);return this_len;
}
#endif//getString的实现,处理方式也与asCString相同,只是使用场景与asCString不同,最终也得到char*类型的字符串。
bool Value::getString(char const** begin, char const** end) const {if (type() != stringValue)return false;if (value_.string_ == nullptr)return false;unsigned length;decodePrefixedString(this->isAllocated(), this->value_.string_, &length,begin);*end = *begin + length;return true;
}

这几个JSON转换函数的示例如下:

int main()
{Json::Value jsonMess = Json::Value::null;jsonMess[0u]["Computer"] = "ASUS";jsonMess[0u]["MemorySize"] = 500 * 1024 * 1024 * 1.0;jsonMess[0u]["USB"][0u] = "SanDisk";jsonMess[0u]["USB"][1] = "Kingston";jsonMess[0u]["isEnable"] = true;jsonMess[1]["Computer"] = "Apple";jsonMess[1]["MemorySize"] = 256 * 1024 * 1024 * 1.0;jsonMess[1]["USB"][0u] = "Toshiba";jsonMess[1]["USB"][1] = "WestData";jsonMess[1]["isEnable"] = false;printf("jsonMess = %s\n", jsonMess.toStyledString().c_str());//asCString测试char* computer0;computer0 = (char*)((jsonMess[0u]["Computer"]).asCString());std::cout << "computer0 = " << computer0 << std::endl;//asCString只支持字符串类型的提取,不能提取其他类型的//computer0 = (char*)((jsonMess[0u]["isEnable"]).asCString());//std::cout << "computer0 = " << computer0 << std::endl;//asString测试,它可以提取包括字符类型外的其他的类型,都转成字符串表示出来std::string computer1;computer1 = (jsonMess[0u]["Computer"]).asString();std::string isEnables;isEnables = (jsonMess[0u]["isEnable"].asString());std::string mems;mems = (jsonMess[0u]["MemorySize"]).asString();printf("computer1 = %s\n", computer1.c_str());std::cout << "computer1 = " << computer1 << std::endl;std::cout << "isEnables = " << isEnables << std::endl;std::cout << "mems = " << mems << std::endl;//asInt测试int mem = (jsonMess[0u]["MemorySize"]).asInt();std::cout << "mem = " << mem << std::endl;//asInt64测试long long meml = (jsonMess[0u]["MemorySize"]).asInt64();std::cout << "meml = " << meml << std::endl;//asDouble测试double memd = (jsonMess[0u]["MemorySize"]).asDouble();std::cout << "memd = " << memd << std::endl;//asFloat测试float memf = (jsonMess[0u]["MemorySize"]).asFloat();std::cout << "memf = " << memf << std::endl;//asBool测试bool isEnbale = (jsonMess[0u]["isEnable"]).asBool();std::cout << "isEnable = " << isEnbale << std::endl;//getString测试char const* computerNameBegin;char const* computerNameEnd;bool res = (jsonMess[1]["Computer"]).getString(&computerNameBegin, &computerNameEnd);std::cout << "-----" <<std::endl;if(res){std::cout << "computerNameBegin = " << computerNameBegin << " ,computerNameEnd = " << computerNameEnd << std::endl;}return 0;
}//测试结果
jsonMess = [{"Computer" : "ASUS","MemorySize" : 524288000.0,"USB" : ["SanDisk","Kingston"],"isEnable" : true},{"Computer" : "Apple","MemorySize" : 268435456.0,"USB" : ["Toshiba","WestData"],"isEnable" : false}
]computer0 = ASUS
computer1 = ASUS
computer1 = ASUS
isEnables = true
mems = 524288000.0
mem = 524288000
meml = 524288000
memd = 5.24288e+08
memf = 5.24288e+08
isEnable = 1
-----
computerNameBegin = Apple ,computerNameEnd = 

接下来是一些用于判断JSON对象某些性质的函数,声明如下:

bool isNull() const;              //判断JSON某一项是否为空
bool isBool() const;              //判断JSON某一项是否是bool类型
bool isInt() const;               //判断JSON某一项是否是int类型
bool isInt64() const;             //判断JSON某一项是否是int64类型
bool isUInt() const;              //判断JSON某一项是否是unsigned int类型
bool isUInt64() const;            //判断JSON某一项是否是unsigned int64类型
bool isIntegral() const;          //判断JSON某一项是否是整数
bool isDouble() const;            //判断JSON某一项是否是double类型
bool isNumeric() const;           //判断JSON某一项是否是数值类型
bool isString() const;            //判断JSON某一项是否是string类型
bool isArray() const;             //判断JSON某一项是否是数组类型
bool isObject() const;            //判断JSON某一项是否是对象类型
bool isConvertibleTo(ValueType other) const; //判断JSON某一项是否能转换成other类型

它们的实现如下,注意点都写在注释中:

//内部private函数,调用了modf,用以判断是不是整数,modf结果是0就是整数。
static bool IsIntegral(double d) {double integral_part;return modf(d, &integral_part) == 0.0;
}//判断是否为空,JSON值是nullValue,例如刚初始化时或未赋值时。
bool Value::isNull() const { return type() == nullValue; }//判断是否是bool类型,JSON值是true或false。
bool Value::isBool() const { return type() == booleanValue; }//判断是否是int类型,有符号整型、无符号整型时,只要不超过最大的有符号、无符号表示范围时为true、实点型时,不超过表示范围的情况下,小数部分为0则也为true。
bool Value::isInt() const {switch (type()) {case intValue:
#if defined(JSON_HAS_INT64)return value_.int_ >= minInt && value_.int_ <= maxInt;
#elsereturn true;
#endifcase uintValue:return value_.uint_ <= UInt(maxInt);case realValue:return value_.real_ >= minInt && value_.real_ <= maxInt &&IsIntegral(value_.real_);default:break;}return false;
}//判断是否是uint类型,有符号整型时,只要值大于0且不超过最大无符号表示范围、无符号整型时,只要不超过最大无符号表示范围时为true、实点型时,值大于0且不超过表示范围的情况下,小数部分为0则也为true。
bool Value::isUInt() const {switch (type()) {case intValue:
#if defined(JSON_HAS_INT64)return value_.int_ >= 0 && LargestUInt(value_.int_) <= LargestUInt(maxUInt);
#elsereturn value_.int_ >= 0;
#endifcase uintValue:
#if defined(JSON_HAS_INT64)return value_.uint_ <= maxUInt;
#elsereturn true;
#endifcase realValue:return value_.real_ >= 0 && value_.real_ <= maxUInt &&IsIntegral(value_.real_);default:break;}return false;
}//判断是否是int64类型,有符号整型为true、无符号整型时,只要不超过最大的64位无符号表示范围时为true、实点型时,不超过64位有符号整数表示范围的情况下,小数部分为0则也为true。
bool Value::isInt64() const {
#if defined(JSON_HAS_INT64)switch (type()) {case intValue:return true;case uintValue:return value_.uint_ <= UInt64(maxInt64);case realValue:// Note that maxInt64 (= 2^63 - 1) is not exactly representable as a// double, so double(maxInt64) will be rounded up to 2^63. Therefore we// require the value to be strictly less than the limit.return value_.real_ >= double(minInt64) &&value_.real_ < double(maxInt64) && IsIntegral(value_.real_);default:break;}
#endif // JSON_HAS_INT64return false;
}//判断是否是uint64类型,有符号整型时,只要值大于0则为true、无符号整型时,也为true、实点型时,值大于0且不超过64位无符号整数最大表示范围的情况下,小数部分为0则也为true。
bool Value::isUInt64() const {
#if defined(JSON_HAS_INT64)switch (type()) {case intValue:return value_.int_ >= 0;case uintValue:return true;case realValue:// Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a// double, so double(maxUInt64) will be rounded up to 2^64. Therefore we// require the value to be strictly less than the limit.return value_.real_ >= 0 && value_.real_ < maxUInt64AsDouble &&IsIntegral(value_.real_);default:break;}
#endif // JSON_HAS_INT64return false;
}//判断是否是整数类型,有符号整型、无符号整型都为true,实点型时,值在整型(64为整型)表示范围内且小数部分为0时为true。
bool Value::isIntegral() const {switch (type()) {case intValue:case uintValue:return true;case realValue:
#if defined(JSON_HAS_INT64)// Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a// double, so double(maxUInt64) will be rounded up to 2^64. Therefore we// require the value to be strictly less than the limit.return value_.real_ >= double(minInt64) &&value_.real_ < maxUInt64AsDouble && IsIntegral(value_.real_);
#elsereturn value_.real_ >= minInt && value_.real_ <= maxUInt &&IsIntegral(value_.real_);
#endif // JSON_HAS_INT64default:break;}return false;
}//判断是否是double类型,只要是有符号、无符号、实点型的都是true。
bool Value::isDouble() const {return type() == intValue || type() == uintValue || type() == realValue;
}//判断是否是数字,同isDouble,只要是有符号、无符号、实点型的都是true。
bool Value::isNumeric() const { return isDouble(); }//判断是否是string型,JSON值为字符串的情况下,就是true。
bool Value::isString() const { return type() == stringValue; }//判断是否是array型,JSON值含数组的情况下为true。
bool Value::isArray() const { return type() == arrayValue; }//判断是否是object型,对象类型。
bool Value::isObject() const { return type() == objectValue; }//判断类型能否转换的实现。从这里很容易可以看得出每种类型转换的条件。
bool Value::isConvertibleTo(ValueType other) const {switch (other) {case nullValue:return (isNumeric() && asDouble() == 0.0) ||(type() == booleanValue && value_.bool_ == false) ||(type() == stringValue && asString().empty()) ||(type() == arrayValue && value_.map_->empty()) ||(type() == objectValue && value_.map_->empty()) ||type() == nullValue;case intValue:return isInt() ||(type() == realValue && InRange(value_.real_, minInt, maxInt)) ||type() == booleanValue || type() == nullValue;case uintValue:return isUInt() ||(type() == realValue && InRange(value_.real_, 0, maxUInt)) ||type() == booleanValue || type() == nullValue;case realValue:return isNumeric() || type() == booleanValue || type() == nullValue;case booleanValue:return isNumeric() || type() == booleanValue || type() == nullValue;case stringValue:return isNumeric() || type() == booleanValue || type() == stringValue ||type() == nullValue;case arrayValue:return type() == arrayValue || type() == nullValue;case objectValue:return type() == objectValue || type() == nullValue;}JSON_ASSERT_UNREACHABLE;return false;
}

当我们在使用JSON时,需要用JSON的值做判断条件或当我们不知道值是什么类型时,使用上面的isXXX函数很容易得到答案,部分示例如下:

 Json::Value jsonMess1 = Json::Value::null;jsonMess1[0u]["Computer"] = "ASUS";jsonMess1[0u]["MemorySize"] = 500 * 1024 * 1024 * 1.0;jsonMess1[0u]["USB"][0u] = "SanDisk";jsonMess1[0u]["USB"][1] = "Kingston";jsonMess1[0u]["isEnable"] = true;jsonMess1[0u]["Memo"];bool valueType0 = (jsonMess1[0u]["Memo"]).isNull();std::cout << "valueType0 = " << valueType0 << std::endl;bool valueType1 = (jsonMess1[0u]["isEnable"]).isBool();std::cout << "valueType1 = " << valueType1 << std::endl;bool valueType2 = (jsonMess1[0u]["MemorySize"]).isIntegral();std::cout << "valueType2 = " << valueType2 << std::endl;bool valueType3 = (jsonMess1[0u]["MemorySize"]).isNumeric();std::cout << "valueType3 = " << valueType3 << std::endl;bool valueType4 = (jsonMess1[0u]["MemorySize"]).isDouble();std::cout << "valueType4 = " << valueType4 << std::endl;bool valueType5 = (jsonMess1[0u]["USB"]).isArray();std::cout << "valueType5 = " << valueType5 << std::endl;bool valueType6 = (jsonMess1[0u]["Computer"]).isObject();std::cout << "valueType6 = " << valueType6 << std::endl;bool valueType7 = (jsonMess1[0u]["Computer"]).isArray();std::cout << "valueType7 = " << valueType7 << std::endl;std::cout << "----" << std::endl;bool valueType8 = (jsonMess1[0u]["Computer"]).isConvertibleTo(Json::objectValue);std::cout << "valueType8 = " << valueType8 << std::endl;bool valueType9 = (jsonMess1[0u]["isEnable"]).isConvertibleTo(Json::uintValue);std::cout << "valueType9 = " << valueType9 << std::endl;//结果
valueType0 = 1
valueType1 = 1
valueType2 = 1
valueType3 = 1
valueType4 = 1
valueType5 = 1
valueType6 = 0
valueType7 = 0
----
valueType8 = 0
valueType9 = 1

另外,Value中还有一些非常常用的功能性函数,如下:

ArrayIndex size() const; //用来确定JSON数组、对象的长度//实现:所有的非数组、非对象类型的JSON中,size()均为0,数组和对象类型事,用了个迭代器指向最后一个元素,取最后元素-1的角标就是size的大小。
ArrayIndex Value::size() const {switch (type()) {case nullValue:case intValue:case uintValue:case realValue:case booleanValue:case stringValue:return 0;case arrayValue: // size of the array is highest index + 1if (!value_.map_->empty()) {ObjectValues::const_iterator itLast = value_.map_->end();--itLast;return (*itLast).first.index() + 1;}return 0;case objectValue:return ArrayIndex(value_.map_->size());}JSON_ASSERT_UNREACHABLE;return 0; // unreachable;
}bool empty() const;    //用来判断JSON是否为null、空数组或空对象。//实现:空类型、数组类型、对象类型时,size为0则为empty。
bool Value::empty() const {if (isNull() || isArray() || isObject())return size() == 0u;elsereturn false;
}void clear();          //用来清空数组或对象类型JSON的内容,其他类型的没有作用。//实现:数组和对象类型下,直接调用map中的clear清空。
void Value::clear() {JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue ||type() == objectValue,"in Json::Value::clear(): requires complex value");start_ = 0;limit_ = 0;switch (type()) {case arrayValue:case objectValue:value_.map_->clear();break;default:break;}
}void resize(ArrayIndex newSize);   //用来更改JSON的大小//实现:如果传入0,则意味着清空JSON,如果传入的数大于原来的大小,则意味着扩大空间,若传入的数小于原来的大小,则删除多余的一部分空间。
void Value::resize(ArrayIndex newSize) {JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue,"in Json::Value::resize(): requires arrayValue");if (type() == nullValue)*this = Value(arrayValue);ArrayIndex oldSize = size();if (newSize == 0)clear();else if (newSize > oldSize)this->operator[](newSize - 1);else {for (ArrayIndex index = newSize; index < oldSize; ++index) {value_.map_->erase(index);}JSON_ASSERT(size() == newSize);}
}Value get(ArrayIndex index, const Value& defaultValue) const; //获取序号index的值,若不存在,返回默认值//实现:判断index处的value是否为null,若不为null,则直接返回index处的值,若为null,则返回传入的defaultValue。这可以用在提取JSON值时,不确定值是否存在时的情况,不存在就赋值我们想要的默认值。
Value Value::get(ArrayIndex index, const Value& defaultValue) const {const Value* value = &((*this)[index]);return value == &nullSingleton() ? defaultValue : *value;
}bool isValidIndex(ArrayIndex index) const; //判断index是否有效,也就是是否超出了最大的大小//实现,很简单。
bool Value::isValidIndex(ArrayIndex index) const { return index < size(); }Value& append(const Value& value);  //向JSON数组最后继续添加值//实现,直接在数组的最后一位元素处赋值。
Value& Value::append(const Value& value) { return (*this)[size()] = value; }Value get(const char* begin, const char* end, const Value& defaultValue) const; //主要供下面两个get调用,直接使用的情况不多
Value get(const char* key, const Value& defaultValue) const; //与前面的get相似,只是这里获取的是key对应的值。
Value get(const String& key, const Value& defaultValue) const;//同上,string类型的key//实现:查找begin和end字符(key值)在JSON中的位置,找到则返回这个值,找不到返回传入的defaultValue。后面两个get调用了这个get。
Value Value::get(char const* begin,char const* end,Value const& defaultValue) const {Value const* found = find(begin, end);return !found ? defaultValue : *found;
}Value Value::get(char const* key, Value const& defaultValue) const {return get(key, key + strlen(key), defaultValue);
}
Value Value::get(String const& key, Value const& defaultValue) const {return get(key.data(), key.data() + key.length(), defaultValue);
}Value const* find(char const* begin, char const* end) const; //在JSON中查找begin~end字符的键,找到返回其对应的值。//实现:就是使用了map中的find方法,找到则返回对应的值,找不到返回null。
Value const* Value::find(char const* begin, char const* end) const {JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue,"in Json::Value::find(key, end, found): requires ""objectValue or nullValue");if (type() == nullValue)return nullptr;CZString actualKey(begin, static_cast<unsigned>(end - begin),CZString::noDuplication);ObjectValues::const_iterator it = value_.map_->find(actualKey);if (it == value_.map_->end())return nullptr;return &(*it).second;
}//下面这几个是用来删除JSON元素的,根据key删除,删除后得到所删除的值。
void removeMember(const char* key);
void removeMember(const String& key);
bool removeMember(const char* key, Value* removed);
bool removeMember(String const& key, Value* removed);
bool removeMember(const char* begin, const char* end, Value* removed);//实现:其实就是find函数的基础上,多了一步erase,find到相应的key后,把key对应的value给removed,然后将这个key删除掉。这几个remove都是一样,兼容const char*和string类型。但,只能操作objectValue类型,其他类型不可以。
bool Value::removeMember(const char* begin, const char* end, Value* removed) {if (type() != objectValue) {return false;}CZString actualKey(begin, static_cast<unsigned>(end - begin),CZString::noDuplication);auto it = value_.map_->find(actualKey);if (it == value_.map_->end())return false;if (removed)
#if JSON_HAS_RVALUE_REFERENCES*removed = std::move(it->second);
#else*removed = it->second;
#endifvalue_.map_->erase(it);return true;
}
bool Value::removeMember(const char* key, Value* removed) {return removeMember(key, key + strlen(key), removed);
}
bool Value::removeMember(String const& key, Value* removed) {return removeMember(key.data(), key.data() + key.length(), removed);
}
void Value::removeMember(const char* key) {JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue,"in Json::Value::removeMember(): requires objectValue");if (type() == nullValue)return;CZString actualKey(key, unsigned(strlen(key)), CZString::noDuplication);value_.map_->erase(actualKey);
}
void Value::removeMember(const String& key) { removeMember(key.c_str()); }//也是删除元素,但是是以index序号删除,删除后返回被删除的值,只能适用于数组。
bool removeIndex(ArrayIndex index, Value* removed);//实现:在内部的map中寻找index,找到后,将对应的value值赋给removed传出,然后将数组全部向前推移一个,并删除最后一个留空的位置
bool Value::removeIndex(ArrayIndex index, Value* removed) {if (type() != arrayValue) {return false;}CZString key(index);auto it = value_.map_->find(key);if (it == value_.map_->end()) {return false;}if (removed)*removed = it->second;ArrayIndex oldSize = size();// shift left all items left, into the place of the "removed"for (ArrayIndex i = index; i < (oldSize - 1); ++i) {CZString keey(i);(*value_.map_)[keey] = (*this)[i + 1];}// erase the last one ("leftover")CZString keyLast(oldSize - 1);auto itLast = value_.map_->find(keyLast);value_.map_->erase(itLast);return true;
}//判断JSON中是否有key这个成员
bool isMember(const char* key) const;
bool isMember(const String& key) const;
bool isMember(const char* begin, const char* end) const;//实现:实现很简单,只是调用find找key,找到就是true,找不到就是false。
bool Value::isMember(char const* begin, char const* end) const {Value const* value = find(begin, end);return nullptr != value;
}
bool Value::isMember(char const* key) const {return isMember(key, key + strlen(key));
}
bool Value::isMember(String const& key) const {return isMember(key.data(), key.data() + key.length());
}//返回JSON中所有的key,Json::Members定义为typedef std::vector<String> Json::Value::Members
Members getMemberNames() const;//实现:非空时使用了迭代器遍历整个JSON内部的map,将key全部加入到Members这个vector中,返回。
Value::Members Value::getMemberNames() const {JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue,"in Json::Value::getMemberNames(), value must be objectValue");if (type() == nullValue)return Value::Members();Members members;members.reserve(value_.map_->size());ObjectValues::const_iterator it = value_.map_->begin();ObjectValues::const_iterator itEnd = value_.map_->end();for (; it != itEnd; ++it) {members.push_back(String((*it).first.data(), (*it).first.length()));}return members;
}//用于格式化JSON字符串,加换行符,常用在打印JSON时,把整个JSON转成string型。
String toStyledString() const;//实现
String Value::toStyledString() const {StreamWriterBuilder builder;String out = this->hasComment(commentBefore) ? "\n" : "";out += Json::writeString(builder, *this);out += '\n';return out;
}

常用的功能函数示例如下:

Json::Value jsonMess1 = Json::Value::null;jsonMess1[0u]["Computer"] = "ASUS";jsonMess1[0u]["MemorySize"] = 500 * 1024 * 1024 * 1.0;jsonMess1[0u]["USB"][0u] = "SanDisk";jsonMess1[0u]["USB"][1] = "Kingston";jsonMess1[0u]["isEnable"] = true;jsonMess1[0u]["Memo"];std::cout << "jsonMess1 = " << jsonMess1.toStyledString() << std::endl;int size1 = (jsonMess1[0u]["USB"]).size();int size2 = (jsonMess1[0u]["Computer"]).size();std::cout << "size1 = " << size1 << std::endl;std::cout << "size2 = " << size2 << std::endl;bool isEmpty1 = (jsonMess1[0u]["Memo"]).empty();bool isEmpty2 = (jsonMess1[0u]["Computer"]).empty();std::cout << "isEmpty1 = " << isEmpty1 << std::endl;std::cout << "isEmpty2 = " << isEmpty2 << std::endl;//(jsonMess1[0u]["Computer"]).clear();   //会报错,只能clear数组类型.(jsonMess1[0u]["USB"]).clear(); std::cout << "jsonMess1 = " << jsonMess1.toStyledString() << std::endl;(jsonMess1[0u]["USB"]).resize(3);int size = (jsonMess1[0u]["USB"]).size();std::cout << "size = " << size << std::endl;jsonMess1[0u]["USB"][0u] = "Kingston";jsonMess1[0u]["USB"][1] = "SanDisk";jsonMess1[0u]["USB"][2] = "Toshiba";Json::Value jsonMess2 = (jsonMess1[0u]).get("USB", "WestData");Json::Value jsonMess3 = (jsonMess1[0u]).get("XXXX", "default");std::cout << "jsonMess2 = " << jsonMess2.toStyledString() << std::endl;std::cout << "jsonMess3 = " << jsonMess3.toStyledString() << std::endl;Json::Value jsonMess4 = jsonMess2.get(0u, "default");Json::Value jsonMess5 = jsonMess2.get(5, "default");std::cout << "jsonMess4 = " << jsonMess4.toStyledString() << std::endl;std::cout << "jsonMess5 = " << jsonMess5.toStyledString() << std::endl;bool isValidIndex = jsonMess2.isValidIndex(2);std::cout << "isValidIndex = " << isValidIndex << std::endl;jsonMess2.append("WestData");std::cout << "jsonMess2 = " << jsonMess2.toStyledString() << std::endl;Json::Value jsonMess6 = Json::nullValue;Json::Value json = Json::nullValue;json["key1"] = "value1";json["key2"] = "vaule2";json["key3"] = "value3";json["key4"] = "value4";jsonMess6 = json;std::cout << "jsonMess6 = " << jsonMess6.toStyledString() << std::endl;jsonMess6.removeMember("key1");std::cout << "jsonMess6 = " << jsonMess6.toStyledString() << std::endl;Json::Value removeValue = Json::nullValue;jsonMess6.removeMember("key3", &removeValue);std::cout << "jsonMess6 = " << jsonMess6.toStyledString() << std::endl;std::cout << "removeValue = " << removeValue.toStyledString() << std::endl;//结果
jsonMess1 = [{"Computer" : "ASUS","Memo" : null,"MemorySize" : 524288000.0,"USB" : ["SanDisk","Kingston"],"isEnable" : true}
]size1 = 2
size2 = 0
isEmpty1 = 1
isEmpty2 = 0
jsonMess1 = [{"Computer" : "ASUS","Memo" : null,"MemorySize" : 524288000.0,"USB" : [],"isEnable" : true}
]size = 3
jsonMess2 = ["Kingston","SanDisk","Toshiba"
]jsonMess3 = "default"jsonMess4 = "Kingston"jsonMess5 = "default"isValidIndex = 1
jsonMess2 = ["Kingston","SanDisk","Toshiba","WestData"
]jsonMess6 = {"key1" : "value1","key2" : "vaule2","key3" : "value3","key4" : "value4"
}jsonMess6 = {"key2" : "vaule2","key3" : "value3","key4" : "value4"
}jsonMess6 = {"key2" : "vaule2","key4" : "value4"
}removeValue = "value3"

以上就是Value类中最常用的一些函数和功能的源码介绍。

jsoncpp库常用源码解析及使用介绍(二)相关推荐

  1. TiKV 源码解析系列文章(二)raft-rs proposal 示例情景分析

    作者:屈鹏 本文为 TiKV 源码解析系列的第二篇,按照计划首先将为大家介绍 TiKV 依赖的周边库 raft-rs .raft-rs 是 Raft 算法的 Rust 语言实现.Raft 是分布式领域 ...

  2. vue源码解析之选项合并(二)

    选项 data 的合并策略 我们跳过mergeData 以及 mergeDataOrFn,我们暂且不关注这两个函数的作用.暂且跳过继续看下面的代码: strats.data = function (p ...

  3. 日志 note_深入源码解析日志框架Log4j2(二)

    异步 AsyncAppender ​ log4j2突出于其他日志的优势,异步日志实现.我们先从日志打印看进去.找到Logger,随便找一个log日志的方法. public void debug(fin ...

  4. angular select2源码解析_Angular 组件库 NG-NEST 源码解析:Form 表单组件

    前言 NG-NEST介绍 今天我们来看一下 Form 表单组件是如何实现的: 功能分析 由不同的表单控件组成(输入框.选择器.单选框.多选框等) 控件的禁用.必填.正则验证等状态 标题和控件位置,局部 ...

  5. RocketMQ源码解析-事务消息的二阶段提交

    在生产者producer当中,通过sendMessageInTransaction()方法来发送事务消息,但是在一开始向Broker发送的事务消息的时候,具体的事务操作还并没有进行处理,而是相当于向B ...

  6. java源码解析之反射(二)

    依赖的结构图: 查看全文 http://www.taodudu.cc/news/show-2970933.html 相关文章: js基础 宿主环境 [笔记]实战mpvue2.0多端小程序框架--原生小 ...

  7. 【移动开发】Checkout开源库源码解析

    Checkout开源库的源码解析 1.功能介绍 1.1Checkout是什么 Checkout是Android In-App Billing API(v3 +)的一个封装库.In-App Billin ...

  8. BAT高级架构师合力熬夜15天,肝出了这份PDF版《Android百大框架源码解析》,还不快快码住。。。

    前言 为什么要阅读源码? 现在中高级Android岗位面试中,对于各种框架的源码都会刨根问底,从而来判断应试者的业务能力边际所在.但是很多开发者习惯直接搬运,对各种框架的源码都没有过深入研究,在面试时 ...

  9. semver 源码解析(Npm library)

    semver 源码解析(Npm library) 文章目录 semver 源码解析(Npm library) 正文 0. 基本信息 1. 源码解析 1.1 核心类型 1.2 SemVer 类型实现核心 ...

最新文章

  1. 2018.2.11-12 写作业
  2. 第12章 存储器的保护
  3. wget在线扒站网站程序源码
  4. golang 代理地址
  5. select 存储过程 mysql_MySQL存储过程无法使用SELECT(基本问题)
  6. 【论文写作】课程指导平台的开发中界面设计如何写
  7. mysql结构改写为hbase表_根据mysql表中字段创建hbase表
  8. spring boot介绍及使用详解
  9. 【mediasoup 带宽估计】aimd算法2 : AimdRateControl
  10. ubuntu文件夹加密_安装Ubuntu后如何加密您的主文件夹
  11. 来自百度,为什么要重构(Refactoring)
  12. 如何通过织云 Lite 愉快地玩转 TSW
  13. 汇编指令 BCC/BLO
  14. protobuf根据有关联的.proto文件进行编译
  15. beanshell断言_jmeter之beanshell断言实例
  16. 中国网络教育行业市场需求及十四五发展新挑战研究报告2021-2027年
  17. 坐标变换的艺术—PMSM(两相)静止轴系的扩展反电势公式推导
  18. Git之多人协同开发
  19. 关于 CentOS系统编译Qt项目报错:error: cannot find -lGL 的解决方法
  20. 微信公众号缓存严重的问题

热门文章

  1. python画管柱图_汽车电动控制调整转向管柱的制作方法
  2. 色彩构成与搭配内涵教程
  3. 仙人掌之歌——系统设计(1)
  4. NCL的示例1:常见符号的用法
  5. C# 读写自定义的Config文件
  6. 概率密度变换公式 雅可比矩阵_的联合概率密度函数f(x,y).ppt
  7. ModuleNotFoundError: No module named 'exceptions'什么意思
  8. SOLD格雷母线的简介和运用
  9. 360前端星计划—技术翻译:进阶的直梯(李松峰)
  10. Could not find messages which '/home/../msg/Lane.msg' depends on.Did you forget to specify...