Linux下编译安装Jsoncpp及应用实例

前言:json是一种很简洁的协议。可惜的是他只能传递基本的数据类型(例如int/long/string)这种,本身不支持二进制数据(不能传递byte类型)。

换句话说json本身是不支持二进制数据传输的。

举个例子。你可能会遇到用json传递protobuf对象的情况;一个看起来可行的方案是 对pb对象序列化后把序列化后的二进制流直接赋给json的某个字段;传输到对端后对端取到二进制流再反序列换成pb对象。但实际操作后你就会发现这样是行不通的。同理传输图片等二进制文件也是行不通的。

解决办法:一个可行的方案就是将二进制数据进行转换,只要转换后的数据能用json的字符串表示即可。显然base64就是一种基于64个可见字符来表示二进制数据的方法。所以一个可行的解决方案就是对byte[]进行base64编码转换成字符串,接收端再decode得到原byte[]即可。

缺点:缺点也是很明显的。①性能方面。Base64有着较高的处理开销。 ②空间方面。base64将3个字节扩展为4个字符,导致数据大小膨胀约33%。

安装JsonCpp需要下载JsonCpp和Scon还需要机器上有python

scons又是一个牛叉的工具,功能和GNU make一样,又比make简单多了。scons是python工具,需要先安装好python。

验证python是否安装以及安装版本的指令为:python --version

0、scons简介:

Scons是一个开放源码、以Python语言编码的自动化构建工具,可用来替代make编写复杂的makefile。并且scons是跨平台的,只要scons脚本写的好,可以在Linux和Windows下随意编译。

scons 的设计目标就是让开发人员更容易、更可靠和更快速的建造软件。

与传统的 make 工具比较,scons 具有以下优点:

(1)使用 Python 脚本做为配置文件
(2)对于 C,C++ 和 Fortran, 内建支持可靠自动依赖分析 . 不用像 make 工具那样需要 执行"make depends"和"make clean"就可以获得所有的依赖关系。
(3)内建支持 C, C++, D, Java, Fortran, Yacc, Lex, Qt,SWIG 以及 Tex/Latex。 用户还可以根据自己的需要进行扩展以获得对需要编程语言的支持。
(4)支持 make -j 风格的并行建造。相比 make -j, scons可以同时运行 N 个工作,而不用担心代码的层次结构。
(5)使用 Autoconf 风格查找头文件,函数库,函数和类型定义。
(6)良好的夸平台性。scons 可以运行在 Linux, AIX, BSD, HP/UX, IRIX, Solaris, Windows, Mac OS X 和 OS/2 上。

一句话:scons是make的同类产品,也可以看做升级产品。它做的事情跟make一样,但更简单,更容易。

1、下载地址:

Jsoncpp下载:https://sourceforge.net/projects/jsoncpp/
Scons下载:https://sourceforge.net/projects/scons/

注意:对于jsoncpp最好安装高版本,如0.10.6这种。对于0.5.0这种低版本不支持UInt64、Int64这种数据。

2.解压并配置SCons

将下载的 Scons压缩包,进行解压:

$tar -zxvf scons-3.1.1.tar.gz

配置环境变量:

export SCONS_PATH=/jsoncpp/scons-3.1.1
export SCONS_LIB_DIR=$SCONS_PATH/engine

3.解压配置Jsoncpp

将下载的 jsoncpp压缩包,进行解压:

$tar zxvf jsoncpp-src-0.5.0.tar.gz

配置环境变量:

export JSONCPP_PATH=/jsoncpp/jsoncpp-src-0.5.0

注:配置环境变量的几种方法这里在说一下。

1、用export命令,直接执行 export JSONCPP_PATH=/jsoncpp/jsoncpp-src-0.5.0 指令。

2、修改profile文件,vim /etc/profile,输入export语句。

source /etc/profile  #注意执行本指令来生效
echo $SCONS_PATH  #来验证SCONS_PATH这个环境变量在当前终端是否生效。

3、修改.bashrc文件,输入vim /root/.bashrc,输入export语句。

注意:对于jsoncpp最好安装高版本,如0.10.6这种。对于0.5.0这种低版本不支持UInt64、Int64这种数据。

jsoncpp-0.10.6版本安装:

//获取安装包
wget https://github.com/open-source-parsers/jsoncpp/archive/0.10.6.zip
unzip jsoncpp-0.10.1.zip

//进入路径
cd jsoncpp-0.10.1
mkdir -p ./build/debug
cd ./build/debug

//cmake
//以下gcc 或者 g++ 的路径最好which确认下再填上去
cmake \
-D CMAKE_BUILD_TYPE=debug \
-D BUILD_STATIC_LIBS=ON \
-D BUILD_SHARED_LIBS=OFF \
-D CMAKE_INSTALL_PREFIX=/usr/local/jsoncpp \
-D CMAKE_C_COMPILER=/usr/bin/gcc \
-D CMAKE_CXX_COMPILER=/usr/bin/g++ \
-G "Unix Makefiles" ../..

//编译和安装
make && make install

4.编译Jsoncpp

 我的jsoncpp目录在/jsoncpp/jsoncpp-src-0.5.0

cd jsoncpp-src-0.5.0

python $SCONS_PATH/script/scons platform=linux-gcc

注释:网上有一些错误的 也可能是早期的版本 ,如下:
经过测试 发现报错 查看路径下 没有scons.py文件 故改为scons

python $SCONS_PATH/src/script/scons.py platform=linux-gcc #这个会出错

 编译 完成后就会在jsoncpp-src-0.5.0/libs/linux-gcc-4.8.5目录下生成静态和动态库文件。如下:

5.举例

 创建jsoncpptest.cpp文件,内容如下:

#include "json/json.h"
#include 
#include 
using namespace std;
int main()
{
 string test ="{\"id\":1,\"name\":\"kurama\"}";
 //string test = "{\"id\": 1, \"name\": \"张三\", \"age\": 18, \"sister\": [{\"name\": \"张大姐\", \"age\": 30}, {\"name\": \"张二姐\", \"age\": 20}]}";
 Json::Reader reader;
 Json::Value value;
 if(reader.parse(test,value))
 {
  if(!value["id"].isNull())
  {
  cout<

我的jsoncpp目录在/jsoncpp/jsoncpp-src-0.5.0,故编译指令如下:

g++ jsoncpptest.cpp -I /jsoncpp/jsoncpp-src-0.5.0/include -L /jsoncpp/jsoncpp-src-0.5.0/libs/linux-gcc-4.8.5/ -ljson_linux-gcc-4.8.5_libmt

./a.out时错误,说是找不到.so文件,报错如下:

如下解决方法均可:
1.将jsoncpp编译后的.so文件拷贝到当前项目目录中;
2.编辑/etc/ld.so.conf文件,将.so文件所在的路径加进去,同时加入/usr/local/lib

/jsoncpp/jsoncpp-src-0.5.0/libs/linux-gcc-4.8.5

/usr/local/lib

然后用如下命令对.so的配置进行更新

/sbin/ldconfig -v

编译业务程序:

编译业务程序其实很简单。跳转到jsoncpp编译路径下的/pkg-config(即/jsoncpp/jsoncpp-0.10.6/build/debug/pkg-config)。

我们编译业务方程序需要的无非是  -L${libdir} 、-ljsoncpp  和-I${includedir};而这些 jsoncpp.pc 文件中全有。于是就可以得到:

g++ jsontest.cpp -o jsontest -I /usr/local/jsoncpp/include/jsoncpp -L /usr/local/jsoncpp/lib -ljsoncpp

举例二

创建如下jsontest.cpp文件。这个实例包含了json的诸多用法。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "json/json.h"
 
using namespace std;
 
int main(int argc, char **argv) {  
    Json::Value root; 
    Json::Value header;     
    Json::Value arrayObj;  
    Json::Value item; 
 
    //Json头信息
    header["pro"] = "17";
    header["service_type"] = "GPS11";
 
    cout << "*************读取普通文件生成json************" << endl;
    //open文件
    char buffer[256];  
    ifstream in("test.txt");  
    int i = 0;
    if (! in.is_open())  
    {
        cout << "Error opening file";
        exit (1); 
    }  
    while (!in.eof() )  
    {  
        in.getline (buffer,100);  
        item[buffer] = i;  
        i++;
        arrayObj.append(item);
        item.clear();
 
    } 
    root["HEADER"] = header;
    root["BODYLIST"] = arrayObj;  
 
    std::string out = root.toStyledString();  
    std::cout << out << std::endl;   
    in.close(); 



    cout << "*****************Writer的用法******************" << endl;
    Json::Value person;
    person["name"]="shuozhuo";
    person["sex"]="male";
    person["age"]=26;

    Json::Value family;
    family["address"]="anhui";
    family["number"]=4;

    Json::Value occupation;
    occupation["occupation"]="engineer";
    occupation["company_name"]="tencent";
    occupation["company_address"]="shanghai";

    Json::Value other_info;
    //other_info.append(family);
    //other_info.append(occupation);
    other_info["occupation"]= occupation;
    other_info["family"]=family;

    person["other_info"]=other_info;

    cout << "***********无style格式的输出*************" << endl;
    //json转换成json字符串,无格式化输出。所谓无格式输出就是没有缩进当成一个字符串的输出。
    Json::FastWriter fast_writer;
    string str1=fast_writer.write(person);
    cout << "str1=" << str1 << endl;

    cout << "********style格式的输出(方法一)*********" << endl;
    //json转换成json字符串,有格式化输出。所谓有格式输出就是错落有致的输出。
    Json::StyledWriter style_writer;
    string str2=style_writer.write(person);
    cout << "str2" << str2 << endl;

    cout << "********style格式的输出(方法二)*********" << endl;
    cout << person.toStyledString() << endl;

    cout << "*************生成json文件***************" << endl;
    Json::StyledStreamWriter stream_writer;
    ofstream ofs("stream_writer.json");
    stream_writer.write(ofs,person);
    ofs.close();


    cout << "**********Reader的用法(Reader)**********" << endl;
    ifstream jsonfile("stream_writer.json");
    Json::Value value_read;
    Json::Reader reader;
    if(!reader.parse(jsonfile,value_read)){
        cout << "parse error!!" << endl;
    }else{
        cout << "parse success!!" << endl;
        cout << value_read["name"].asString() << endl;
        cout << value_read["age"].asInt() << endl;
        cout << value_read["other_info"]["family"]["number"].asInt() << endl;
    }

    cout << "********判断key是否存在(isMember)********" << endl;
    if(value_read.isMember("sex")){
    	cout << "sex is member" << endl;
    }else
    {
    	cout << "sex is not member" << endl;
    }
    if(value_read.isMember("high")){
    	cout << "high is member" << endl;
    }else
    {
    	cout << "high is not member" << endl;
    }

    cout << "********删除成员(removeMember)**********" << endl;
    value_read.removeMember("sex");
    string str3=style_writer.write(value_read);
    cout << "str3" << str3 << endl;

    return 0;  
}

编译语句如下:

g++ jsontest.cpp -I /jsoncpp/jsoncpp-src-0.5.0/include -L /jsoncpp/jsoncpp-src-0.5.0/libs/linux-gcc-4.8.5/ -ljson_linux-gcc-4.8.5_libmt

随便创建一个test.txt文件放在当前目录。例如:

1111
2222
3333

编译完成后,执行./a.out 即可看到运行效果。

(1)如下图所示即为无格式输出和有格式输出的区别:

Linux下编译安装Jsoncpp及应用实例_第1张图片

举例三——json的数组读写

#include 
#include 
#include 
using namespace std;

int main()
{
    //std::string strValue = "{\"name\":\"json\",\"array\":[{\"cpp\":\"jsoncpp\"},{\"java\":\"jsoninjava\"},{\"php\":\"support\"}]}";    
    // 构建json数组
    Json::Value root;
    Json::Value group;
    Json::Value person;
    Json::FastWriter writer;

    person["name"] = "allen";
    person["age"] = 10; 
    person["sex"] = "male";
    group.append(person);
 
    person["name"] = "keiv";
    person["age"] = 20; 
    person["sex"] = "female";
    group.append(person);
    
    person["name"] = "lihua";
    person["age"] = 10; 
    person["sex"] = "female";
    group.append(person);
 
    string strValue0 = group.toStyledString();
    cout << "group Styled output is:" << endl;
    cout << strValue0 << endl;

    string data = writer.write(group);
    cout << "group unStyled output is:" << endl;
    cout << data << endl;

    //给数组的第一个元素对应的json追加一个字段
    if (group.size() > 0){
        group[0]["unique_id"] = "unique_id";
    }

    //子节点挂到根节点上
    root["array"] = Json::Value(group);
    //cout<

6.json原始字串书写形式

        json的规则其实很简单,我们完全可以按照规则书写出这些json串(看我们部门的代码其实也有很多生拼json的写法),而且书写出来的这些json字符串实际上也可以使用Json::Reader reader的parse方法解析成Json::Value对象被正常的按照json形式来引用操作的。一下给出几个例子:

#json对象包含在字符‘{’和‘}’中每个键值对由逗号分隔(最简单的例子):
{"age":26,"high":181,"name":"shuozhuo"}
#包含嵌套的例子
{"age":26,"high":181,"name":"shuozhuo","other_info":{"family":{"address":"anhui","number":4},"occupation":{"company_address":"shanghai","company_name":"tencent","occupation":"engineer"}}}
#array数组,JSON数据包含在字符‘[’和‘]’中,为一个由逗号分隔的值列表:
["apple","banana","orange","watermelon"]
{"id": 1, "age": 18, "name": "张三", "sister": [{"age": 30, "name": "张大姐"}, {"age": 20, "name": "张二姐"}]}
#数组嵌套的例子
{"id": 3, "age": 18, "name": "小明", "sister": [{"age": 25, "name": "小明大姐", "friend": [{"age": 25, "name": "大姐朋友一"}, {"age": 25, "name": "大姐朋友二"}]}, {"age": 20, "name": "小明二姐", "friend": [{"age": 22, "name": "二姐朋友一"}, {"age": 21, "name": "二姐朋友二"}]}]}

7.关于生拼json

很简单,一句话:除了最外层的双引号里面的每个双引号都加一个转义反斜线就好了。

如果出现变量的话也差不多就是对着上面生拼的字符串照搬过来然后用stringstream黏在一起就好了。实例如下:

#看看几个生拼json的实例,很简单。
"{\"id\":1,\"name\":\"kurama\"}"
"{\"menuid\":\"")+ m_msg.m_content+"\",\"menuname\":\""+m_msg.m_menuname+"\"}")
"{\"id\": 1, \"name\": \"张三\", \"age\": 18, \"sister\": [{\"name\": \"张大姐\", \"age\": 30}, {\"name\": \"张二姐\", \"age\": 20}]}"
"{ \"weatherinfo\":{\"city\":\"北京\", \"cityid\" : \"101010100\", \"temp\" : \"18\", \"WD\" : \"东南风\", \"WS\" : \"1级\", \"SD\" : \"17 % \", \"WSE\" : \"1\", \"time\" : \"17:05\", \"isRadar\" : \"1\", \"Radar\" : \"JC_RADAR_AZ9010_JB\", \"njd\" : \"这是什么\", \"qy\" : \"1011\", \"rain\" : \"0\"} }"


#include "json/json.h"
#include 
#include 
#include 
using namespace std;
int main()
{
	/*
	这种生拼json没有任何问题。方法也说过了就是除了最外层引号外,其他所有的引号都加一个转义字符
	*/
	string test = "{\"alg\":\"HS256\",\"typ\":\"JWT\"}";
	string raw_payload = "{\"appId\":1255566655,\"fileId\":\"4564972818519602447\",\"currentTimeStamp\":1546340400,\"expireTimeStamp\":1546344000,\"urlAccessInfo\":{\"t\":\"5c2b5640\",\"rlimit\":3,\"us\":\"72d4cd1101\"}}";

	cout << "test:" << test << endl;
	cout << "raw_payload:" << raw_payload << endl;

	Json::Reader reader;
	Json::Value value;

	/*
	如果json中的value为变量该怎么办呢?——显然也是可以的。实例如下:
	其实就是对着上面test的生拼字符串照搬过来用stringstream黏在一起就好了。
	*/
	string alg = "HS256";
	string type = "JWT";
	std::stringstream ss0;
	ss0 << "{\"alg\":\"" << alg << "\",\"typ\":\"" << type << "\"}";
	cout << "ssss:"<< ss0.str() << endl;

	unsigned long long appid = 1255566655;
	string fileid = "4564972818519602447";
	unsigned long long currentStamp = 1546340400;
	unsigned long long expireTimeStamp = 1546344000;
	string t = "5c2b5640";
	int rlimit = 3;
	string us = "72d4cd1101";
	std::stringstream ss;
	ss << "{\"appId\":" << appid << ",\"fileId\":\"" << fileid << "\",\"currentTimeStamp\":" << currentStamp << ",\"expireTimeStamp\":" << expireTimeStamp << ",\"urlAccessInfo\":{\"t\":\"" << t << "\",\"rlimit\":" << rlimit << ",\"us\":\"" << us << "\"}}";
	cout << "raw_payload:" << ss.str() << endl;

	if(reader.parse(ss.str(),value))
	{
		cout << "value:" << value.toStyledString()<< endl;
	}
	return 0;
}




8.Json系统类型及常用成员函数

 注:如下的好多方法必须要高版本jsoncpp才支持,例如“(Json::Value::UInt64)”、“(Json::Value::Int64)”这种; jsoncpp-src-0.5.0 不支持,jsoncpp-0.10.6支持。

 Linux下编译安装Jsoncpp及应用实例_第2张图片

 注:“Int64 asInt64() const”的意思是我们取json某字段数值的时候可以使用 asInt64();同时也意味着“Int64”是jsoncpp认可的数据类型,即在给json赋值的时候可以用(Json::Value::Int64)来强制转换成jsoncpp认可的int64数据。如下:

下面这些方法,尤其是isXXX方法的实际效果见 这里

//类型转换
string asString() const; //是string才可以用asString来取(不可以对子json用asString)
Int asInt() const;   //是数字才可以用asXXIntXX来取(返回类型Json::Value::Int)(当实际转换数据超过Int表示范畴就会core)
UInt asUInt() const; //是数字才可以用asXXIntXX来取(返回类型Json::Value::UInt)
Int64 asInt64() const; //是数字才可以用asXXIntXX来取;也可以强制转换为Int64类型(返回类型Json::Value::Int64)
UInt64 asUInt64() const; //是数字才可以用asXXIntXX来取;也可以强制转换为UInt64类型(返回类型Json::Value::UInt64)
LargestInt asLargestInt() const;
LargestUInt asLargestUInt() const;
float asFloat() const;
double asDouble() const;
bool asBool() const;

// 检测类型的几个方法
bool isNull() const;
bool isBool() const;
bool isInt() const;
bool isInt64() const;
bool isUInt() const;
bool isUInt64() const;
bool isIntegral() const;    
bool isDouble() const;
bool isNumeric() const;     //浮点数、数字为true
bool isString() const;		//字符串
bool isArray() const;		//是否是数组
bool isObject() const;		//是否对象(子结构为true)


//json的value.type()方法取值枚举(注释是源码摘出来的)
//Type of the value held by a Value object.
Json::nullValue  //'null' value
Json::intValue   //signed integer value
Json::uintValue  //unsigned integer value
Json::realValue  //double value
Json::stringValue  //UTF-8 string value
Json::booleanValue //bool value
Json::arrayValue   //array value (ordered list)
Json::objectValue  //object value (collection of name/value pairs).
判断方法如下:
if (jsondata.type() == Json::objectValue)
{
   cout << endl;
   print_json(jsondata);
}

注:asInt、asUInt当待转换数据超过int、uint的标识范畴时就会core!!!

另外(注:其实这些就是上面列出来的检测类型的若干方法)。

(1)判断某个key(or子结构)是否存在使用isMember(判断key是否存在不能用empty);

(2)判断value是否为null:isNull成员函数;

(3)判断value是否为空:empty() 和 size()成员函数;

(4)判断value是否为数组:isArray();

(5)判断value是否为一个子结构:isObject()。

上面的isXxx方法都是可以用的这里就不继续列出来了…………

另外还可以通过type()方法取其类型做判断。

#如下,判断type是否为Json::objectValue也是可以的
if (person.type() == Json::objectValue)
{
    cout << endl;
    print_json(person);
}

9.上下文中出现的诸多方法都可以在源码中找到

/jsoncpp-0.10.6/include/json/value.h

10、jsoncpp遍历json数据

#include "json/json.h"
#include 
#include 
typedef Json::Writer JsonWriter;
typedef Json::Reader JsonReader;
typedef Json::Value  JsonValue;

using namespace std;
void print_json(JsonValue data);

int main()
{
  //string testJson = "{\"id\":1,\"name\":\"kurama\"}";
  /*------------------------------------------
  这里面涉及到json数组和json对象的区别(json数组是不可以调用getMemberNames方法的):
  json数组:是由[]括起来的,中间可以包括json对象或者键值对;
  json对象是由{}括起来的,中间可以报错接送对象或者键值对;
  ------------------------------------------*/
  //string testJson = "{[{\"age\":10,\"name\":\"allen\",\"sex\":\"male\"},{\"age\":20,\"name\":\"keiv\",\"sex\":\"female\"},{\"age\":10,\"name\":\"lihua\",\"sex\":\"female\"}]}";
  string testJson = "{ \"weatherinfo\":{\"city\":\"北京\", \"cityid\" : \"101010100\", \"temp\" : \"18\", \"WD\" : \"东南风\", \"WS\" : \"1级\", \"SD\" : \"17 % \", \"WSE\" : \"1\", \"time\" : \"17:05\", \"isRadar\" : \"1\", \"Radar\" : \"JC_RADAR_AZ9010_JB\", \"njd\" : \"这是什么\", \"qy\" : \"1011\", \"rain\" : \"0\"} }";

  //解析json数据
  JsonReader reader;
  JsonValue value;
  if (!reader.parse(testJson, value))
  {
    cout << value.toStyledString() << endl;
    return 0;
  }
  //遍历键值
  print_json(value);
  system("pause");

  return 0;
}

void print_json(JsonValue data)
{
  /*---------Return a list of the member names--------*/
  //getMemberNames仅对type为objectValue(json对象)或者nullValue(null)可用.
  JsonValue::Members mem = data.getMemberNames();
  for (auto iter = mem.begin(); iter != mem.end(); iter++)
  {
    cout << *iter << "\t: ";
    if (data[*iter].type() == Json::objectValue)
    {
      cout << endl;
      print_json(data[*iter]);
    }
    else if (data[*iter].type() == Json::arrayValue)
    {
      cout << endl;
      auto cnt = data[*iter].size();
      for (auto i = 0; i < cnt; i++)
      {
        print_json(data[*iter][i]);
      }
    }
    else if (data[*iter].type() == Json::stringValue)
    {
      cout << data[*iter].asString() << endl;
    }
    else if (data[*iter].type() == Json::realValue)
    {
      cout << data[*iter].asDouble() << endl;
    }
    else if (data[*iter].type() == Json::uintValue)
    {
      cout << data[*iter].asUInt() << endl;
    }
    else
    {
      cout << data[*iter].asInt() << endl;
    }
  }
  return;
}

注意:给属性字段赋值的时候可以赋字符串string、数字、布尔值、数组都是可以的。

低版本的jsoncpp不支持uint64(例如0.5.0就不支持C++中的long long)类型的数据!!!

(1)对于常值和非uint64(C++中的long long)的数值变量是可以直接赋值的,例如:

person["age"] = 26;

int high=181;
person["high"] = high;

(2)但是将int64/uint64用来赋值的时候就会报错,如下。

long long high = 181;
person["high"] = high;//这句在编译的时候会报错


/*----高版本的jsoncpp是支持int64/uint64;使用(Json::Value::UInt64)强制转换即可------*/
//(Json::Value::UInt64)转换后json就支持int64和uint64了(注意UInt64、Int64需要高版本的jsoncpp)。
jsonS2cContext["kfext"] = (Json::Value::UInt64)recep_record_qq_kfuin.uint64_bqquin();
jsonS2cContext["cqq"] = (Json::Value::UInt64)recep_record_qq_kfuin.uint64_cqquin();

//直接赋值的话会报错
jsonS2cContext["kfext"] = recep_record_qq_kfuin.uint64_bqquin();
jsonS2cContext["cqq"] = recep_record_qq_kfuin.uint64_cqquin();

赋uint64(long long)后对应的报错如下:

(3)注意左右两者的区别,他们的设置方式和取值方式都是不一样的。

Linux下编译安装Jsoncpp及应用实例_第3张图片 Linux下编译安装Jsoncpp及应用实例_第4张图片

//(1)前者是这样赋出来的:
jsonS2cContext["kfext"] = to_string(recep_record_qq_kfuin.uint64_bqquin());
jsonS2cContext["cqq"] = to_string(recep_record_qq_kfuin.uint64_cqquin());
//(2)后者是这样赋出来的:
//此处的(Json::Value::UInt64)仅仅是为了让json支持uint64的一种实现。
jsonS2cContext["kfext"] = (Json::Value::UInt64)recep_record_qq_kfuin.uint64_bqquin();
jsonS2cContext["cqq"] = (Json::Value::UInt64)recep_record_qq_kfuin.uint64_cqquin();

//(3)下面这种不是uint64的数据用来直接赋值是没有任何问题的。
int age=26,weight=125;
person["age"] = age;
person["weight"] = weight;

//(4)对于前者取值方式如下:
//值得注意的是如果按照下方的asUInt或者asUInt64的方式来取值是会出错的。这个在编译的时候并没有报错,是那种执行到这条语句后直接戛然而止看不到任何报错信息的出错。
uint32_t channel = jsonS2cContext["channel"].asString();
uint64_t kfext = jsonS2cContext["kfext"].asString();

//(5)对于后者取值方式为:
uint32_t channel = jsonS2cContext["channel"].asUInt();
uint64_t kfext = jsonS2cContext["kfext"].asUInt64();

参见:

linux下jsoncpp的编译安装使用_elainedou_新浪博客

Linux下编译安装Jsoncpp及简单应用_Linux教程_Linux公社-Linux系统门户网站

11、json对二进制数据的支持情况。

背景:想用json的"msg_body"字段传输pb对象,显然pb对象是序列化之后的。

json+二进制(流/文件/数据)就往base64这块想想!!!!!

  //如下是可以成功反解出pb对象的
  data["msg_body"] = msg_info.SerializeAsString();
  string str_msg_info = data["msg_body"].asString();
  LOGSYS_WATER(_LC_DEBUG_, "size=%d, str_msg_info=%s", str_msg_info.size(), str_msg_info.c_str());
  if (msg_info1.ParseFromString(str_msg_info)) {
     LOGSYS_WATER(_LC_DEBUG_, "msg_info1=\n%s\n", msg_info1.DebugString().c_str());
  }
  else{
     LOGSYS_WATER(_LC_ERROR_, "parse msg_info1 error!");
  }


  //即使json经过了序列化操作也还依然可以解出其中的pb对象
  row["document"] = data;
  str_row = writer.write(row);
  Json::Reader reader;
  Json::Value doc;
  if (!str_row.empty() && reader.parse(str_row, doc)){
      LOGSYS_WATER(_LC_DEBUG_, "doc is: \n%s", doc.toStyledString().c_str());
  }
  else{
      LOGSYS_WATER(_LC_ERROR_, "parse str_row fail:\n%s", str_row.c_str());
  }
  string str_msg_info = doc["document"]["msg_body"].asString();
  LOGSYS_WATER(_LC_DEBUG_, "str_msg_info=%s", str_msg_info.c_str());
  com::tencent::qidian::cloudim::MsgInfo msg_info00;
  if (msg_info00.ParseFromString(str_msg_info)) {
     LOGSYS_WATER(_LC_DEBUG_, "msg_info00=\n%s\n", msg_info00.DebugString().c_str());
  }
  else{
     LOGSYS_WATER(_LC_ERROR_, "parse msg_info00 error!");
  }

  //但是直接这样把数据存储到db中,然后在取出来又确实不行。!!

  //究竟是哪个环节不行的呢?难道经过网络传输后就不行了吗???

   

附录——源码之value.h:

// Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE

#ifndef CPPTL_JSON_H_INCLUDED
#define CPPTL_JSON_H_INCLUDED

#if !defined(JSON_IS_AMALGAMATION)
#include "forwards.h"
#endif // if !defined(JSON_IS_AMALGAMATION)
#include 
#include 
#include 

#ifndef JSON_USE_CPPTL_SMALLMAP
#include 
#else
#include 
#endif
#ifdef JSON_USE_CPPTL
#include 
#endif

// Disable warning C4251: :  needs to have dll-interface to
// be used by...
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#pragma warning(push)
#pragma warning(disable : 4251)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)

//Conditional NORETURN attribute on the throw functions would:
// a) suppress false positives from static code analysis 
// b) possibly improve optimization opportunities.
#if !defined(JSONCPP_NORETURN)
#  if defined(_MSC_VER)
#    define JSONCPP_NORETURN __declspec(noreturn)
#  elif defined(__GNUC__)
#    define JSONCPP_NORETURN __attribute__ ((__noreturn__))
#  else
#    define JSONCPP_NORETURN
#  endif
#endif

/** \brief JSON (JavaScript Object Notation).
 */
namespace Json {

/** Base class for all exceptions we throw.
 *
 * We use nothing but these internally. Of course, STL can throw others.
 */
class JSON_API Exception : public std::exception {
public:
  Exception(std::string const& msg);
  virtual ~Exception() throw();
  virtual char const* what() const throw();
protected:
  std::string const msg_;
};

/** Exceptions which the user cannot easily avoid.
 *
 * E.g. out-of-memory (when we use malloc), stack-overflow, malicious input
 * 
 * \remark derived from Json::Exception
 */
class JSON_API RuntimeError : public Exception {
public:
  RuntimeError(std::string const& msg);
};

/** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros.
 *
 * These are precondition-violations (user bugs) and internal errors (our bugs).
 * 
 * \remark derived from Json::Exception
 */
class JSON_API LogicError : public Exception {
public:
  LogicError(std::string const& msg);
};

/// used internally
JSONCPP_NORETURN void throwRuntimeError(std::string const& msg);
/// used internally
JSONCPP_NORETURN void throwLogicError(std::string const& msg);

/** \brief Type of the value held by a Value object.
 */
enum ValueType {
  nullValue = 0, ///< 'null' value
  intValue,      ///< signed integer value
  uintValue,     ///< unsigned integer value
  realValue,     ///< double value
  stringValue,   ///< UTF-8 string value
  booleanValue,  ///< bool value
  arrayValue,    ///< array value (ordered list)
  objectValue    ///< object value (collection of name/value pairs).
};

enum CommentPlacement {
  commentBefore = 0,      ///< a comment placed on the line before a value
  commentAfterOnSameLine, ///< a comment just after a value on the same line
  commentAfter, ///< a comment on the line after a value (only make sense for
  /// root value)
  numberOfCommentPlacement
};

//# ifdef JSON_USE_CPPTL
//   typedef CppTL::AnyEnumerator EnumMemberNames;
//   typedef CppTL::AnyEnumerator EnumValues;
//# endif

/** \brief Lightweight wrapper to tag static string.
 *
 * Value constructor and objectValue member assignement takes advantage of the
 * StaticString and avoid the cost of string duplication when storing the
 * string or the member name.
 *
 * Example of usage:
 * \code
 * Json::Value aValue( StaticString("some text") );
 * Json::Value object;
 * static const StaticString code("code");
 * object[code] = 1234;
 * \endcode
 */
class JSON_API StaticString {
public:
  explicit StaticString(const char* czstring) : c_str_(czstring) {}

  operator const char*() const { return c_str_; }

  const char* c_str() const { return c_str_; }

private:
  const char* c_str_;
};

/** \brief Represents a JSON value.
 *
 * This class is a discriminated union wrapper that can represents a:
 * - signed integer [range: Value::minInt - Value::maxInt]
 * - unsigned integer (range: 0 - Value::maxUInt)
 * - double
 * - UTF-8 string
 * - boolean
 * - 'null'
 * - an ordered list of Value
 * - collection of name/value pairs (javascript object)
 *
 * The type of the held value is represented by a #ValueType and
 * can be obtained using type().
 *
 * Values of an #objectValue or #arrayValue can be accessed using operator[]()
 * methods.
 * Non-const methods will automatically create the a #nullValue element
 * if it does not exist.
 * The sequence of an #arrayValue will be automatically resized and initialized
 * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue.
 *
 * The get() methods can be used to obtain default value in the case the
 * required element does not exist.
 *
 * It is possible to iterate over the list of a #objectValue values using
 * the getMemberNames() method.
 *
 * \note #Value string-length fit in size_t, but keys must be < 2^30.
 * (The reason is an implementation detail.) A #CharReader will raise an
 * exception if a bound is exceeded to avoid security holes in your app,
 * but the Value API does *not* check bounds. That is the responsibility
 * of the caller.
 */
class JSON_API Value {
  friend class ValueIteratorBase;
public:
  typedef std::vector Members;
  typedef ValueIterator iterator;
  typedef ValueConstIterator const_iterator;
  typedef Json::UInt UInt;
  typedef Json::Int Int;
#if defined(JSON_HAS_INT64)
  typedef Json::UInt64 UInt64;
  typedef Json::Int64 Int64;
#endif // defined(JSON_HAS_INT64)
  typedef Json::LargestInt LargestInt;
  typedef Json::LargestUInt LargestUInt;
  typedef Json::ArrayIndex ArrayIndex;

  static const Value& nullRef;
#if !defined(__ARMEL__)
  /// \deprecated This exists for binary compatibility only. Use nullRef.
  static const Value null;
#endif
  /// Minimum signed integer value that can be stored in a Json::Value.
  static const LargestInt minLargestInt;
  /// Maximum signed integer value that can be stored in a Json::Value.
  static const LargestInt maxLargestInt;
  /// Maximum unsigned integer value that can be stored in a Json::Value.
  static const LargestUInt maxLargestUInt;

  /// Minimum signed int value that can be stored in a Json::Value.
  static const Int minInt;
  /// Maximum signed int value that can be stored in a Json::Value.
  static const Int maxInt;
  /// Maximum unsigned int value that can be stored in a Json::Value.
  static const UInt maxUInt;

#if defined(JSON_HAS_INT64)
  /// Minimum signed 64 bits int value that can be stored in a Json::Value.
  static const Int64 minInt64;
  /// Maximum signed 64 bits int value that can be stored in a Json::Value.
  static const Int64 maxInt64;
  /// Maximum unsigned 64 bits int value that can be stored in a Json::Value.
  static const UInt64 maxUInt64;
#endif // defined(JSON_HAS_INT64)

private:
#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
  class CZString {
  public:
    enum DuplicationPolicy {
      noDuplication = 0,
      duplicate,
      duplicateOnCopy
    };
    CZString(ArrayIndex index);
    CZString(char const* str, unsigned length, DuplicationPolicy allocate);
    CZString(CZString const& other);
    ~CZString();
    CZString& operator=(CZString other);
    bool operator<(CZString const& other) const;
    bool operator==(CZString const& other) const;
    ArrayIndex index() const;
    //const char* c_str() const; ///< \deprecated
    char const* data() const;
    unsigned length() const;
    bool isStaticString() const;

  private:
    void swap(CZString& other);

    struct StringStorage {
      unsigned policy_: 2;
      unsigned length_: 30; // 1GB max
    };

    char const* cstr_;  // actually, a prefixed string, unless policy is noDup
    union {
      ArrayIndex index_;
      StringStorage storage_;
    };
  };

public:
#ifndef JSON_USE_CPPTL_SMALLMAP
  typedef std::map ObjectValues;
#else
  typedef CppTL::SmallMap ObjectValues;
#endif // ifndef JSON_USE_CPPTL_SMALLMAP
#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION

public:
  /** \brief Create a default Value of the given type.

    This is a very useful constructor.
    To create an empty array, pass arrayValue.
    To create an empty object, pass objectValue.
    Another Value can then be set to this one by assignment.
This is useful since clear() and resize() will not alter types.

    Examples:
\code
Json::Value null_value; // null
Json::Value arr_value(Json::arrayValue); // []
Json::Value obj_value(Json::objectValue); // {}
\endcode
  */
  Value(ValueType type = nullValue);
  Value(Int value);
  Value(UInt value);
#if defined(JSON_HAS_INT64)
  Value(Int64 value);
  Value(UInt64 value);
#endif // if defined(JSON_HAS_INT64)
  Value(double value);
  Value(const char* value); ///< Copy til first 0. (NULL causes to seg-fault.)
  Value(const char* begin, const char* end); ///< Copy all, incl zeroes.
  /** \brief Constructs a value from a static string.

   * Like other value string constructor but do not duplicate the string for
   * internal storage. The given string must remain alive after the call to this
   * constructor.
   * \note This works only for null-terminated strings. (We cannot change the
   *   size of this class, so we have nowhere to store the length,
   *   which might be computed later for various operations.)
   *
   * Example of usage:
   * \code
   * static StaticString foo("some text");
   * Json::Value aValue(foo);
   * \endcode
   */
  Value(const StaticString& value);
  Value(const std::string& value); ///< Copy data() til size(). Embedded zeroes too.
#ifdef JSON_USE_CPPTL
  Value(const CppTL::ConstString& value);
#endif
  Value(bool value);
  /// Deep copy.
  Value(const Value& other);
  ~Value();

  /// Deep copy, then swap(other).
  /// \note Over-write existing comments. To preserve comments, use #swapPayload().
  Value &operator=(const Value &other);
  /// Swap everything.
  void swap(Value& other);
  /// Swap values but leave comments and source offsets in place.
  void swapPayload(Value& other);

  ValueType type() const;

  /// Compare payload only, not comments etc.
  bool operator<(const Value& other) const;
  bool operator<=(const Value& other) const;
  bool operator>=(const Value& other) const;
  bool operator>(const Value& other) const;
  bool operator==(const Value& other) const;
  bool operator!=(const Value& other) const;
  int compare(const Value& other) const;

  const char* asCString() const; ///< Embedded zeroes could cause you trouble!
  std::string asString() const; ///< Embedded zeroes are possible.
  /** Get raw char* of string-value.
   *  \return false if !string. (Seg-fault if str or end are NULL.)
   */
  bool getString(
      char const** begin, char const** end) const;
#ifdef JSON_USE_CPPTL
  CppTL::ConstString asConstString() const;
#endif
  Int asInt() const;
  UInt asUInt() const;
#if defined(JSON_HAS_INT64)
  Int64 asInt64() const;
  UInt64 asUInt64() const;
#endif // if defined(JSON_HAS_INT64)
  LargestInt asLargestInt() const;
  LargestUInt asLargestUInt() const;
  float asFloat() const;
  double asDouble() const;
  bool asBool() const;

  bool isNull() const;
  bool isBool() const;
  bool isInt() const;
  bool isInt64() const;
  bool isUInt() const;
  bool isUInt64() const;
  bool isIntegral() const;
  bool isDouble() const;
  bool isNumeric() const;
  bool isString() const;
  bool isArray() const;
  bool isObject() const;

  bool isConvertibleTo(ValueType other) const;

  /// Number of values in array or object
  ArrayIndex size() const;

  /// \brief Return true if empty array, empty object, or null;
  /// otherwise, false.
  bool empty() const;

  /// Return isNull()
  bool operator!() const;

  /// Remove all object members and array elements.
  /// \pre type() is arrayValue, objectValue, or nullValue
  /// \post type() is unchanged
  void clear();

  /// Resize the array to size elements.
  /// New elements are initialized to null.
  /// May only be called on nullValue or arrayValue.
  /// \pre type() is arrayValue or nullValue
  /// \post type() is arrayValue
  void resize(ArrayIndex size);

  /// Access an array element (zero based index ).
  /// If the array contains less than index element, then null value are
  /// inserted
  /// in the array so that its size is index+1.
  /// (You may need to say 'value[0u]' to get your compiler to distinguish
  ///  this from the operator[] which takes a string.)
  Value& operator[](ArrayIndex index);

  /// Access an array element (zero based index ).
  /// If the array contains less than index element, then null value are
  /// inserted
  /// in the array so that its size is index+1.
  /// (You may need to say 'value[0u]' to get your compiler to distinguish
  ///  this from the operator[] which takes a string.)
  Value& operator[](int index);

  /// Access an array element (zero based index )
  /// (You may need to say 'value[0u]' to get your compiler to distinguish
  ///  this from the operator[] which takes a string.)
  const Value& operator[](ArrayIndex index) const;

  /// Access an array element (zero based index )
  /// (You may need to say 'value[0u]' to get your compiler to distinguish
  ///  this from the operator[] which takes a string.)
  const Value& operator[](int index) const;

  /// If the array contains at least index+1 elements, returns the element
  /// value,
  /// otherwise returns defaultValue.
  Value get(ArrayIndex index, const Value& defaultValue) const;
  /// Return true if index < size().
  bool isValidIndex(ArrayIndex index) const;
  /// \brief Append value to array at the end.
  ///
  /// Equivalent to jsonvalue[jsonvalue.size()] = value;
  Value& append(const Value& value);

  /// Access an object value by name, create a null member if it does not exist.
  /// \note Because of our implementation, keys are limited to 2^30 -1 chars.
  ///  Exceeding that will cause an exception.
  Value& operator[](const char* key);
  /// Access an object value by name, returns null if there is no member with
  /// that name.
  const Value& operator[](const char* key) const;
  /// Access an object value by name, create a null member if it does not exist.
  /// \param key may contain embedded nulls.
  Value& operator[](const std::string& key);
  /// Access an object value by name, returns null if there is no member with
  /// that name.
  /// \param key may contain embedded nulls.
  const Value& operator[](const std::string& key) const;
  /** \brief Access an object value by name, create a null member if it does not
   exist.

   * If the object has no entry for that name, then the member name used to store
   * the new entry is not duplicated.
   * Example of use:
   * \code
   * Json::Value object;
   * static const StaticString code("code");
   * object[code] = 1234;
   * \endcode
   */
  Value& operator[](const StaticString& key);
#ifdef JSON_USE_CPPTL
  /// Access an object value by name, create a null member if it does not exist.
  Value& operator[](const CppTL::ConstString& key);
  /// Access an object value by name, returns null if there is no member with
  /// that name.
  const Value& operator[](const CppTL::ConstString& key) const;
#endif
  /// Return the member named key if it exist, defaultValue otherwise.
  /// \note deep copy
  Value get(const char* key, const Value& defaultValue) const;
  /// Return the member named key if it exist, defaultValue otherwise.
  /// \note deep copy
  /// \note key may contain embedded nulls.
  Value get(const char* begin, const char* end, const Value& defaultValue) const;
  /// Return the member named key if it exist, defaultValue otherwise.
  /// \note deep copy
  /// \param key may contain embedded nulls.
  Value get(const std::string& key, const Value& defaultValue) const;
#ifdef JSON_USE_CPPTL
  /// Return the member named key if it exist, defaultValue otherwise.
  /// \note deep copy
  Value get(const CppTL::ConstString& key, const Value& defaultValue) const;
#endif
  /// Most general and efficient version of isMember()const, get()const,
  /// and operator[]const
  /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30
  Value const* find(char const* begin, char const* end) const;
  /// Most general and efficient version of object-mutators.
  /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30
  /// \return non-zero, but JSON_ASSERT if this is neither object nor nullValue.
  Value const* demand(char const* begin, char const* end);
  /// \brief Remove and return the named member.
  ///
  /// Do nothing if it did not exist.
  /// \return the removed Value, or null.
  /// \pre type() is objectValue or nullValue
  /// \post type() is unchanged
  /// \deprecated
  Value removeMember(const char* key);
  /// Same as removeMember(const char*)
  /// \param key may contain embedded nulls.
  /// \deprecated
  Value removeMember(const std::string& key);
  /// Same as removeMember(const char* begin, const char* end, Value* removed),
  /// but 'key' is null-terminated.
  bool removeMember(const char* key, Value* removed);
  /** \brief Remove the named map member.

      Update 'removed' iff removed.
      \param key may contain embedded nulls.
      \return true iff removed (no exceptions)
  */
  bool removeMember(std::string const& key, Value* removed);
  /// Same as removeMember(std::string const& key, Value* removed)
  bool removeMember(const char* begin, const char* end, Value* removed);
  /** \brief Remove the indexed array element.

      O(n) expensive operations.
      Update 'removed' iff removed.
      \return true iff removed (no exceptions)
  */
  bool removeIndex(ArrayIndex i, Value* removed);

  /// Return true if the object has a member named key.
  /// \note 'key' must be null-terminated.
  bool isMember(const char* key) const;
  /// Return true if the object has a member named key.
  /// \param key may contain embedded nulls.
  bool isMember(const std::string& key) const;
  /// Same as isMember(std::string const& key)const
  bool isMember(const char* begin, const char* end) const;
#ifdef JSON_USE_CPPTL
  /// Return true if the object has a member named key.
  bool isMember(const CppTL::ConstString& key) const;
#endif

  /// \brief Return a list of the member names.
  ///
  /// If null, return an empty list.
  /// \pre type() is objectValue or nullValue
  /// \post if type() was nullValue, it remains nullValue
  Members getMemberNames() const;

  //# ifdef JSON_USE_CPPTL
  //      EnumMemberNames enumMemberNames() const;
  //      EnumValues enumValues() const;
  //# endif

  /// \deprecated Always pass len.
  JSONCPP_DEPRECATED("Use setComment(std::string const&) instead.")
  void setComment(const char* comment, CommentPlacement placement);
  /// Comments must be //... or /* ... */
  void setComment(const char* comment, size_t len, CommentPlacement placement);
  /// Comments must be //... or /* ... */
  void setComment(const std::string& comment, CommentPlacement placement);
  bool hasComment(CommentPlacement placement) const;
  /// Include delimiters and embedded newlines.
  std::string getComment(CommentPlacement placement) const;

  std::string toStyledString() const;

  const_iterator begin() const;
  const_iterator end() const;

  iterator begin();
  iterator end();

private:
  void initBasic(ValueType type, bool allocated = false);

  Value& resolveReference(const char* key);
  Value& resolveReference(const char* key, const char* end);

  struct CommentInfo {
    CommentInfo();
    ~CommentInfo();

    void setComment(const char* text, size_t len);

    char* comment_;
  };

  // struct MemberNamesTransform
  //{
  //   typedef const char *result_type;
  //   const char *operator()( const CZString &name ) const
  //   {
  //      return name.c_str();
  //   }
  //};

  union ValueHolder {
    LargestInt int_;
    LargestUInt uint_;
    double real_;
    bool bool_;
    char* string_;  // actually ptr to unsigned, followed by str, unless !allocated_
    ObjectValues* map_;
  } value_;
  ValueType type_ : 8;
  unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.
                               // If not allocated_, string_ must be null-terminated.
  CommentInfo* comments_;
};

/** \brief Experimental and untested: represents an element of the "path" to
 * access a node.
 */
class JSON_API PathArgument {
public:
  friend class Path;

  PathArgument();
  PathArgument(ArrayIndex index);
  PathArgument(const char* key);
  PathArgument(const std::string& key);

private:
  enum Kind {
    kindNone = 0,
    kindIndex,
    kindKey
  };
  std::string key_;
  ArrayIndex index_;
  Kind kind_;
};

/** \brief Experimental and untested: represents a "path" to access a node.
 *
 * Syntax:
 * - "." => root node
 * - ".[n]" => elements at index 'n' of root node (an array value)
 * - ".name" => member named 'name' of root node (an object value)
 * - ".name1.name2.name3"
 * - ".[0][1][2].name1[3]"
 * - ".%" => member name is provided as parameter
 * - ".[%]" => index is provied as parameter
 */
class JSON_API Path {
public:
  Path(const std::string& path,
       const PathArgument& a1 = PathArgument(),
       const PathArgument& a2 = PathArgument(),
       const PathArgument& a3 = PathArgument(),
       const PathArgument& a4 = PathArgument(),
       const PathArgument& a5 = PathArgument());

  const Value& resolve(const Value& root) const;
  Value resolve(const Value& root, const Value& defaultValue) const;
  /// Creates the "path" to access the specified node and returns a reference on
  /// the node.
  Value& make(Value& root) const;

private:
  typedef std::vector InArgs;
  typedef std::vector Args;

  void makePath(const std::string& path, const InArgs& in);
  void addPathInArg(const std::string& path,
                    const InArgs& in,
                    InArgs::const_iterator& itInArg,
                    PathArgument::Kind kind);
  void invalidPath(const std::string& path, int location);

  Args args_;
};

/** \brief base class for Value iterators.
 *
 */
class JSON_API ValueIteratorBase {
public:
  typedef std::bidirectional_iterator_tag iterator_category;
  typedef unsigned int size_t;
  typedef int difference_type;
  typedef ValueIteratorBase SelfType;

  bool operator==(const SelfType& other) const { return isEqual(other); }

  bool operator!=(const SelfType& other) const { return !isEqual(other); }

  difference_type operator-(const SelfType& other) const {
    return other.computeDistance(*this);
  }

  /// Return either the index or the member name of the referenced value as a
  /// Value.
  Value key() const;

  /// Return the index of the referenced Value, or -1 if it is not an arrayValue.
  UInt index() const;

  /// Return the member name of the referenced Value, or "" if it is not an
  /// objectValue.
  /// \note Avoid `c_str()` on result, as embedded zeroes are possible.
  std::string name() const;

  /// Return the member name of the referenced Value. "" if it is not an
  /// objectValue.
  /// \deprecated This cannot be used for UTF-8 strings, since there can be embedded nulls.
  JSONCPP_DEPRECATED("Use `key = name();` instead.")
  char const* memberName() const;
  /// Return the member name of the referenced Value, or NULL if it is not an
  /// objectValue.
  /// \note Better version than memberName(). Allows embedded nulls.
  char const* memberName(char const** end) const;

protected:
  Value& deref() const;

  void increment();

  void decrement();

  difference_type computeDistance(const SelfType& other) const;

  bool isEqual(const SelfType& other) const;

  void copy(const SelfType& other);

private:
  Value::ObjectValues::iterator current_;
  // Indicates that iterator is for a null value.
  bool isNull_;

public:
  // For some reason, BORLAND needs these at the end, rather
  // than earlier. No idea why.
  ValueIteratorBase();
  explicit ValueIteratorBase(const Value::ObjectValues::iterator& current);
};

/** \brief const iterator for object and array value.
 *
 */
class JSON_API ValueConstIterator : public ValueIteratorBase {
  friend class Value;

public:
  typedef const Value value_type;
  //typedef unsigned int size_t;
  //typedef int difference_type;
  typedef const Value& reference;
  typedef const Value* pointer;
  typedef ValueConstIterator SelfType;

  ValueConstIterator();

private:
/*! \internal Use by Value to create an iterator.
 */
  explicit ValueConstIterator(const Value::ObjectValues::iterator& current);
public:
  SelfType& operator=(const ValueIteratorBase& other);

  SelfType operator++(int) {
    SelfType temp(*this);
    ++*this;
    return temp;
  }

  SelfType operator--(int) {
    SelfType temp(*this);
    --*this;
    return temp;
  }

  SelfType& operator--() {
    decrement();
    return *this;
  }

  SelfType& operator++() {
    increment();
    return *this;
  }

  reference operator*() const { return deref(); }

  pointer operator->() const { return &deref(); }
};

/** \brief Iterator for object and array value.
 */
class JSON_API ValueIterator : public ValueIteratorBase {
  friend class Value;

public:
  typedef Value value_type;
  typedef unsigned int size_t;
  typedef int difference_type;
  typedef Value& reference;
  typedef Value* pointer;
  typedef ValueIterator SelfType;

  ValueIterator();
  ValueIterator(const ValueConstIterator& other);
  ValueIterator(const ValueIterator& other);

private:
/*! \internal Use by Value to create an iterator.
 */
  explicit ValueIterator(const Value::ObjectValues::iterator& current);
public:
  SelfType& operator=(const SelfType& other);

  SelfType operator++(int) {
    SelfType temp(*this);
    ++*this;
    return temp;
  }

  SelfType operator--(int) {
    SelfType temp(*this);
    --*this;
    return temp;
  }

  SelfType& operator--() {
    decrement();
    return *this;
  }

  SelfType& operator++() {
    increment();
    return *this;
  }

  reference operator*() const { return deref(); }

  pointer operator->() const { return &deref(); }
};

} // namespace Json


namespace std {
/// Specialize std::swap() for Json::Value.
template<>
inline void swap(Json::Value& a, Json::Value& b) { a.swap(b); }
}


#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#pragma warning(pop)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)

#endif // CPPTL_JSON_H_INCLUDED

你可能感兴趣的:(协议,jsoncpp)