C++ 的 JSON 解析器及生成器

http://rapidjson.org/zh-cn/

RapidJSON 是只有头文件的 C++ 库。只需把 include/rapidjson 目录复制至系统或项目的 include 目录中。

 

速成参考http://www.bubuko.com/infodetail-2961998.html

 

void  OnBnClickedCmdSave()
{
    rapidjson::StringBuffer strBuf;
    //rapidjson::Writer<rapidjson::StringBuffer> writer(strBuf);
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(strBuf);//PrettyWriter带\n换行符
 
    writer.StartObject();
  
#if 0
    //1. 整数类型
    writer.Key("Int");
    writer.Int(1);
  
    //2. 浮点类型
    writer.Key("Double");
    writer.Double(12.0000001);
  
    //3. 字符串类型
    writer.Key("String");
    writer.String("This is a string");

    //4. 结构体类型
    writer.Key("Object");
    writer.StartObject();
    writer.Key("name");
    writer.String("qq849635649");
    writer.Key("age");
    writer.Int(25);
    writer.EndObject();
  
    //5. 数组类型
    //5.1 整型数组
    writer.Key("IntArray");
    writer.StartArray();
    //顺序写入即可
    writer.Int(10);
    writer.Int(20);
    writer.Int(30);
    writer.EndArray();
  
    //5.2 浮点型数组
    writer.Key("DoubleArray");
    writer.StartArray();
    for(int i = 1; i < 4; i++)
    {
        writer.Double(i * 1.0);
    }
    writer.EndArray();
  
    //5.3 字符串数组
    writer.Key("StringArray");
    writer.StartArray();
    writer.String("one");
    writer.String("two");
    writer.String("three");
    writer.EndArray();
  
    //5.4 混合型数组
    //这说明了,一个json数组内容是不限制类型的
    writer.Key("MixedArray");
    writer.StartArray();
    writer.String("one");
    writer.Int(50);
    writer.Bool(false);
    writer.Double(12.005);
    writer.EndArray();
  #endif
    
    //5.5 结构体数组
    writer.Key("Commands");
    writer.StartArray();
    HTREEITEM root = m_DeviceTree.GetRootItem();
    HTREEITEM hCurCategoryItem = m_DeviceTree.GetChildItem(root);
    while(hCurCategoryItem)
    {
        HTREEITEM hTempCategoryItem = hCurCategoryItem;
        hCurCategoryItem = m_DeviceTree.GetNextSiblingItem(hCurCategoryItem);

        //
        HTREEITEM hCurCmdItem = m_DeviceTree.GetChildItem(hTempCategoryItem);
        while(hCurCmdItem){
             HTREEITEM hTempCmdItem = hCurCmdItem;
             hCurCmdItem = m_DeviceTree.GetNextSiblingItem(hCurCmdItem);
             //
             NODE_INFO* pNode = (NODE_INFO*)m_DeviceTree.GetItemData(hTempCmdItem);
             writer.StartObject();
             writer.Key("uuid"); 
             writer.String(pNode->operationCmdInfo->cmdGUID?pNode->operationCmdInfo->cmdGUID: "");
             writer.Key("alias"); 
             writer.String(pNode->operationCmdInfo->cmdDesc?pNode->operationCmdInfo->cmdDesc: "");
             writer.Key("categoryCode"); 
             writer.String(pNode->categoryCode?pNode->categoryCode: "");
             writer.Key("categoryName"); 
             writer.String(pNode->categoryName?pNode->categoryName: "");
             writer.Key("model"); 
             writer.String(pNode->operationCmdInfo->deviceModel? pNode->operationCmdInfo->deviceModel: "");
             writer.Key("brand"); 
             writer.String(pNode->operationCmdInfo->deviceBrand?pNode->operationCmdInfo->deviceBrand:"");
             writer.Key("timeout"); 
             writer.Int(pNode->operationCmdInfo->ackRecvOverTimeSec);
             writer.Key("protocol"); 
             writer.String((pNode->operationCmdInfo->protocol == CDeviceMapTree::cmd_interface_modbus_tcp)?"modbus":"raw");
             //
             writer.Key("connectType"); 
             writer.String("tcp"); 
             writer.Key("connectParam"); 
             char tmp[512];
             sprintf_s(tmp, "%s:%d", pNode->operationCmdInfo->defaultTcpParam.IpAddr,pNode->operationCmdInfo->defaultTcpParam.IpPort);
             writer.String(tmp);
             //
             if(pNode->operationCmdInfo->protocol== CDeviceMapTree::cmd_interface_modbus_tcp)
             {
                 writer.Key("modbusCommand"); 
            
                MODBUS_PROTOCOL_INFO*    pModbusCmdInfo = &(pNode->operationCmdInfo->modbusCmdInfo);

                 writer.StartObject();
                  writer.Key("slaveAddr");         writer.Int(pModbusCmdInfo->slaveAddr);
                  writer.Key("opCode");         writer.Int(pModbusCmdInfo->opCode);
                  writer.Key("regAddrStart");     writer.Int(pModbusCmdInfo->regAddrStart);
                  writer.Key("regNumbers");        writer.Int(pModbusCmdInfo->regNumbers);
                  writer.Key("regValue");        writer.Int(pModbusCmdInfo->regValue);
                  writer.Key("regValueString");    writer.String(pModbusCmdInfo->szHexVals?pModbusCmdInfo->szHexVals:"");
                  //writer.Key("X");    writer.String(NULL); //NULL导致异常
                 writer.EndObject();
             }
             //
             else
             {
                 RAW_CMD_INFO *   pRawCmdInfo = &(pNode->operationCmdInfo->rawCmdInfo);   //tcp-raw     uart-raw     gateway-raw有效
                 writer.Key("rawCommand"); 
                
                 writer.StartObject();
                  writer.Key("cmd");             writer.String(pRawCmdInfo->szCmdHexData?pRawCmdInfo->szCmdHexData:"");
                  writer.Key("ackTemplate");     writer.String(pRawCmdInfo->szAckHexDataTemplate?pRawCmdInfo->szAckHexDataTemplate: "");
                  writer.Key("ackMask");         writer.String(pRawCmdInfo->szAckHexDataMask?pRawCmdInfo->szAckHexDataMask: "");
                  writer.Key("ackLenExpected"); writer.Int(pRawCmdInfo->ackLenExpected);
                writer.EndObject();
             }

             writer.EndObject();
        }
    }
    writer.EndArray();

    //
 #if 0
   writer.Key("UartCommands");
    writer.StartArray();
    for(int i = 0; i < 3; i++)
    {
        writer.StartObject();
        writer.Key("name");
        writer.String("qq849635649");
        writer.Key("age");
        writer.Int(i * 10);
        writer.Key("sex");
        writer.Bool((i % 2) == 0);
        writer.EndObject();
    }
    writer.EndArray();
#endif
    //
#if 0
    writer.Key("GatewayCommands");
    writer.StartArray();
    for(int i = 0; i < 3; i++)
    {
        writer.StartObject();
        writer.Key("name");
        writer.String("qq849635649");
        writer.Key("age");
        writer.Int(i * 10);
        writer.Key("sex");
        writer.Bool((i % 2) == 0);
        writer.EndObject();
    }
    writer.EndArray();
#endif
    // 
    writer.EndObject();
  
    std::string data = strBuf.GetString();

    {
        //rapidjson::Document doc;  
        //char* tmp = _strdup(data.c_str());
        //int len = strlen(tmp);
        //        if (doc.ParseInsitu(tmp).HasParseError()){
        //            NetPrintf("%s", "配置文件解析失败!");    
        //        }
    }

    NetPrintf("%s", data.c_str());    
    FILE* f ;
    fopen_s(&f, "TcpCommands.conf", "w");
    if(f)
    {
        fwrite( data.c_str(), 1, data.length()+1, f);
        fclose(f);
    }
}

==========================================================================

》》》解析参考

 

void  LoadFromConfFile(const char* filename, const char* connectType)
{
    FILE* f;
    char* buf = NULL;
    fopen_s(&f, filename, "r");
    do{
        if(!f)  break;

        fseek(f,  0, SEEK_END);
        long fileLen = ftell(f);
        fseek(f,  0, SEEK_SET);

        buf = new char[fileLen+1];
        int n = fread(buf, 1, fileLen, f);
        if(f) fclose(f);
        buf[n] = '\0';
        TRACE("%s\n", buf);
        

        //解析json配置文件数据
        try{
                rapidjson::Document doc;  
                if (doc.ParseInsitu(buf).HasParseError()){
                    NetPrintf("%s", "配置文件解析失败!");    
                    break;
                }

                if (!doc.HasMember("Commands"))  break;

                rapidjson::Value &commands = doc["Commands"];
                if(!commands.IsArray()) break;
                if(commands.Empty())    break;

                rapidjson::Value command;
                NODE_INFO* pNode= NULL;
                for (rapidjson::SizeType i = 0; i < commands.Size(); i++)
                {
                        command = commands[i]; //Array中每个元素又是一个Object                            
                        //
                        if(!command.HasMember("connectType"))     continue;
                        if(!command.HasMember("protocol"))     continue;
                        char* curConnectType = _strdup(command["connectType"].GetString());
                        if(0 != _stricmp(curConnectType, connectType)) {
                            free(curConnectType);
                            break;
                        }
                        free(curConnectType);

                        pNode= new NODE_INFO;
                        pNode->nodeType = enum_node_cmd;
                        pNode->bModifyEnabled = TRUE;
                        pNode->hTreeItem = NULL;
                        pNode->categoryCode = command.HasMember("categoryCode")?_strdup(command["categoryCode"].GetString())  :_strdup("");
                        pNode->categoryName = command.HasMember("categoryName")?_strdup(command["categoryName"].GetString())  :_strdup("");
                    
                        //查找节点所在的树节点-- 没找到则创建
                        HTREEITEM root = this->GetRootItem();
                        ASSERT(root);
                        HTREEITEM hCurCategoryItem = GetChildItem(root);
                        while(hCurCategoryItem)
                        {
                            CString  strCategoryName = GetItemText(hCurCategoryItem);
                            USES_CONVERSION;
                            int n = strCategoryName.Find(A2T(pNode->categoryCode));
                            if(n != -1)
                                break;

                            hCurCategoryItem = GetNextSiblingItem(hCurCategoryItem);
                        }

                        if(!hCurCategoryItem){
                            char temp[128];
                            sprintf_s(temp, sizeof(temp),"%s%s", pNode->categoryCode, pNode->categoryName );
                            USES_CONVERSION;
                            hCurCategoryItem = InsertItem(A2T(temp), root);    
                            SetItemDataExt(hCurCategoryItem, pNode->categoryCode, pNode->categoryName);

                            NODE_INFO *categoryNode = new NODE_INFO;
                            categoryNode->nodeType = enum_node_category;
                            categoryNode->bModifyEnabled = FALSE;
                            categoryNode->hTreeItem = hCurCategoryItem;
                            categoryNode->categoryCode = _strdup(pNode->categoryCode);
                            categoryNode->categoryName = _strdup(pNode->categoryName);
                            SetItemData(hCurCategoryItem, (DWORD_PTR)categoryNode);
                        }


                        OPERATION_CMD_INFO*   pOperationCmdInfo = new OPERATION_CMD_INFO;
                        ASSERT(pOperationCmdInfo);
                        pNode->operationCmdInfo = pOperationCmdInfo;
                    
                        pOperationCmdInfo->cmdDesc = command.HasMember("alias")?_strdup(command["alias"].GetString())  :_strdup("");
                        pOperationCmdInfo->cmdGUID = command.HasMember("uuid")?_strdup(command["uuid"].GetString())  :_strdup("");
                        pOperationCmdInfo->deviceBrand = command.HasMember("brand")?_strdup(command["brand"].GetString())  :_strdup("");
                        pOperationCmdInfo->deviceModel = command.HasMember("model")?_strdup(command["model"].GetString())  :_strdup("");
                        pOperationCmdInfo->ackRecvOverTimeSec = command["timeout"].GetInt();

                        USES_CONVERSION;
                        pNode->hTreeItem = InsertItem(A2T(pOperationCmdInfo->cmdDesc), hCurCategoryItem);
                        SetItemData(pNode->hTreeItem, (DWORD_PTR)pNode);


                        char*  protocol = _strdup(command["protocol"].GetString());
                        if(0 == _stricmp(connectType, "tcp")) 
                        {
                            pOperationCmdInfo->protocol = (0 == _stricmp(protocol, "modbus"))? CDeviceMapTree::cmd_interface_modbus_tcp : CDeviceMapTree::cmd_interface_raw_tcp;
                            
                            char* tcpConnectParam = command.HasMember("connectParam") ? _strdup(command["connectParam"].GetString()) : _strdup("192.168.0.140:502");
                            char* ip = tcpConnectParam; 
                            char* p = ip;
                            while (p&& *p != ':') p++;
                            if (*p == ':'){
                                *p++ = '\0';
                                pOperationCmdInfo->defaultTcpParam.IpAddr = _strdup(ip);
                                pOperationCmdInfo->defaultTcpParam.IpPort = atoi(p);
                            }
                            else{
                                pOperationCmdInfo->defaultTcpParam.IpAddr = _strdup(ip);
                                pOperationCmdInfo->defaultTcpParam.IpPort = 502;//default tcp-modbus port
                            }
                            free(tcpConnectParam);
                        }
                        else if(0 == _stricmp(connectType, "uart")) 
                        {
                            pOperationCmdInfo->protocol = (0 == _stricmp(protocol, "modbus"))? CDeviceMapTree::cmd_interface_modbus_uart : CDeviceMapTree::cmd_interface_raw_uart;
                        
                            char* uartConnectParam = command.HasMember("connectParam") ? _strdup(command["connectParam"].GetString()) : _strdup("COM4:9600,8,N,1");

                            char* commfile = uartConnectParam; 
                            char* p = commfile;
                            while (p&& *p != ':') p++;
                            if (*p == ':'){
                                *p++ = '\0';
                                pOperationCmdInfo->defaultyUartParam.uartPort = atoi(&commfile[3]) - 1; //commfile=COM5跳过字符COM
                                pOperationCmdInfo->defaultyUartParam.conn_param =  _strdup(p);
                            }
                            else{
                                pOperationCmdInfo->defaultyUartParam.uartPort = 4;
                                pOperationCmdInfo->defaultyUartParam.conn_param =  _strdup("9600,8,N,1");
                            }
                            free(uartConnectParam);

                        }
                        else if(0 == _stricmp(connectType, "gateway")) 
                        {
                            pOperationCmdInfo->protocol = (0 == _stricmp(protocol, "gw_WR"))? CDeviceMapTree::cmd_interface_gateway_wr : 
                                                          (0 == _stricmp(protocol, "gw_W"))? CDeviceMapTree::cmd_interface_gateway_w:
                                                           CDeviceMapTree::cmd_interface_gateway_r ;
                            
                            char* tcpConnectParam  = command.HasMember("connectParam") ? _strdup(command["connectParam"].GetString()) : _strdup("192.168.0.140:502");
                            char* ip = tcpConnectParam;
                            char* p = ip;
                            while (p&& *p != ':') p++;
                            if (*p == ':'){
                                *p++ = '\0';
                                pOperationCmdInfo->defaultTcpParam.IpAddr = _strdup(ip);
                                pOperationCmdInfo->defaultTcpParam.IpPort = atoi(p);
                            }
                            else{
                                pOperationCmdInfo->defaultTcpParam.IpAddr = _strdup(ip);
                                pOperationCmdInfo->defaultTcpParam.IpPort = 502;//default tcp-modbus port
                            }
                            free(tcpConnectParam);

                            //提取gateway命令参数
                            if(command.HasMember("gatewayCommand"))
                            {
                                rapidjson::Value &gatewayCommand = command["gatewayCommand"];
                                pOperationCmdInfo->gatewayCmdInfo.incomingDataLenExpected = gatewayCommand.HasMember("IncomingDataLen")?gatewayCommand["IncomingDataLen"].GetInt(): 65535;
                                pOperationCmdInfo->gatewayCmdInfo.szHexPassThrouhVals     = gatewayCommand.HasMember("PassthroughDataHex")?_strdup(gatewayCommand["PassthroughDataHex"].GetString()): _strdup("");
                                if(gatewayCommand.HasMember("UartParam"))
                                {
                                    rapidjson::Value &UartParam = gatewayCommand["UartParam"];
                                    pOperationCmdInfo->gatewayCmdInfo.uartParam.uartPort   = UartParam.HasMember("UartPort")?UartParam["UartPort"].GetInt(): 0;
                                    pOperationCmdInfo->gatewayCmdInfo.uartParam.conn_param = UartParam.HasMember("ConnParam")?_strdup(UartParam["ConnParam"].GetString()): _strdup("9600,8,N,1");
                                }
                            }    
                    }
                    else
                    {
                        free(protocol);
                        delete pNode;
                        pNode = NULL;
                        continue;
                    }
                    free(protocol);


                    switch(pOperationCmdInfo->protocol)
                    {
                        case CDeviceMapTree::cmd_interface_modbus_tcp:
                        case CDeviceMapTree::cmd_interface_modbus_uart:
                            if (command.HasMember("modbusCommand"))
                             {//modbus初始参数
                                MODBUS_PROTOCOL_INFO*    pModbusCmdInfo = &(pOperationCmdInfo->modbusCmdInfo);

                                rapidjson::Value &modbusCmdInfo = command["modbusCommand"];
                                
                                pModbusCmdInfo->slaveAddr = modbusCmdInfo.HasMember("slaveAddr") ? modbusCmdInfo["slaveAddr"].GetInt() : 0xFF;
                                pModbusCmdInfo->opCode = modbusCmdInfo.HasMember("opCode") ? modbusCmdInfo["opCode"].GetInt() : 0x01;
                                pModbusCmdInfo->regAddrStart = modbusCmdInfo.HasMember("regAddrStart") ? modbusCmdInfo["regAddrStart"].GetInt() : 0xFFFF;
                                pModbusCmdInfo->regNumbers = modbusCmdInfo.HasMember("regNumbers") ? modbusCmdInfo["regNumbers"].GetInt() : 1;
                                pModbusCmdInfo->regValue = modbusCmdInfo.HasMember("regValue") ? modbusCmdInfo["regValue"].GetInt() : 0x1234;
                                pModbusCmdInfo->szHexVals = modbusCmdInfo.HasMember("regValueString") ? _strdup(modbusCmdInfo["regValueString"].GetString()) : _strdup("");                                                     
                             }    
                            break;

                        case CDeviceMapTree::cmd_interface_raw_tcp:
                        case CDeviceMapTree::cmd_interface_raw_uart:
                        case CDeviceMapTree::cmd_interface_gateway_wr :
                        case CDeviceMapTree::cmd_interface_gateway_w :
                        case CDeviceMapTree::cmd_interface_gateway_r :
                            if (command.HasMember("rawCommand"))
                            {
                                RAW_CMD_INFO *   pRawCmdInfo = &(pNode->operationCmdInfo->rawCmdInfo);   //tcp-raw     uart-raw     gateway-raw有效
                                rapidjson::Value &rawCmdInfo = command["rawCommand"];

                                pRawCmdInfo->szCmdHexData = rawCmdInfo.HasMember("cmd") ? _strdup(rawCmdInfo["cmd"].GetString()) : _strdup("");
                                pRawCmdInfo->szAckHexDataTemplate = rawCmdInfo.HasMember("ackTemplate") ? _strdup(rawCmdInfo["ackTemplate"].GetString()) : _strdup("");
                                pRawCmdInfo->szAckHexDataMask = rawCmdInfo.HasMember("ackMask") ? _strdup(rawCmdInfo["ackMask"].GetString()) : _strdup("");
                                pRawCmdInfo->ackLenExpected = rawCmdInfo.HasMember("ackLenExpected") ? rawCmdInfo["ackLenExpected"].GetInt() : 0;
                            }
                            break;
                }

                        
            }//end for                    
        }
        catch(...){
            NetPrintf("%s", "配置文件解析异常!");    
        }
        
    }while(0);
    if(buf)    delete buf;
    if(f) fclose(f);
}


 

 

 

 


 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值