Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
/ json2cpp Public
forked from nasacj/json2cpp

A tool for JSON & C++ Mapping. Convert json string to c++ class, and convert c++ class to json string in reverse.

License

Notifications You must be signed in to change notification settings

icson/json2cpp

Open more actions menu
 
 

Repository files navigation

json2cpp

Join the chat at https://gitter.im/nasacj/json2cpp

A tool for JSON & C++ Mapping

Copyright (C) 2016, ICSON company, ZhengFeng Rao, NASaCJ. All rights reserved.

Build Status

Platfrom Linux
Status Build Status

Introduction

JSON is a kind of Object notation. When programmers deal with the json strings by C++ json APIs (eg, RapidJSON, jsoncpp) they have to write codes for parsing each different Class, which there may be a lot of similar repeated API calling codes. So json2cpp can help programmer to auto-generate the C++ codes for transferring form JSON to C++ and conversely. json2cpp is a script tool written in python language. It uses pyparsing to parse a Modeling file to C++ files and RapidJSON, jsoncpp for C++ to parse the JSON.

Installation before use

  • json2cpp depends on Python and pyparsing, so make sure that Python has been installed on your System
  • For installing pyparsing, use "easy_install" to install it through command line:
user@localhost $ sudo easy_install pyparsing

Download & Run Sample

Thie simple instruction shows a common running command of json2cpp

git clone https://github.com/nasacj/json2cpp
cd json2cpp
./json2cpp.py rapidjson sample.jsf test
cd test/test
make
./test

License

See the LICENSE file for details. In summary, json2cpp is licensed under the MIT license, or public domain if desired and recognized in your jurisdiction. json2cpp uses RapidJSON & jsoncpp, which 2 are both under MIT license.

Usage

Before use json2cpp, a definition file is required:

Define the class

As sample.jsf file shows, user can define the class structure as C++ sytle. The classes are according to the JSON objects:

Sample JSON Object for Request

{
    "sourceId": 1,
    "orgId": 10,
    "ivcType": 100,
    "reqNo": "asd",
    "payerNo": "10032-11",
    "businessIds": [
        "saddd",
        "xxxx"
    ],
    "invoiceTicket": {
        "invoiceType": "Normal",
        "invoiceCode": "200001",
        "invoiceAddress": {
            "provinceNo": 10001,
            "provinceStr": "New York",
        },
        "optionalAddress": [
            {
                "provinceNo": 10002,
                "provinceStr": "Shanghi",
            },
            {
                "provinceNo": 10003,
                "provinceStr": "Beijing",
            }
        ]
    }
}

Sample JSON Object for Response:

{
    "code": "200",
    "msg": "This is msg",
    "reqNo": "100200012",
    "businessIds": [
        "111asd",
        "2cde2"
    ],
    "invoiceTicket": {
        "invoiceType": "Normal",
        "invoiceCode": "200001",
        "invoiceAddress": {
            "provinceNo": 10001,
            "provinceStr": "Shanghai",
        },
        "optionalAddress": [
            {
                "provinceNo": 10002,
                "provinceStr": "Beijing",
            },
            {
                "provinceNo": 10003,
                "provinceStr": "Hong Kong",
            }
        ]
    }
}

Definitation of Class, Request and Response:

//namespace Definition
namespace jsf;

//Class Definition
@description="Address Structure"  //@descpription is optional
class Address
{
    @jsonname="provinceNo", description="Province ID" //@descpription is optional
    int provinceNo;	
	
    @jsonname="provinceStr", description="Province"
    string province;
};

//@descpription is optional
class InvoiceTicket
{
    @jsonname="invoiceType" //@descpription is optional
    string invoiceType;
	
    @jsonname="invoiceCode", description="Invoice Code"
    string invoiceCode;

    @jsonname="invoiceAddress", description="Inoice Address"
    Address address;

    @jsonname="optionalAddress"
    vector<Address> optionalAddress; //Only use vector for list handling
};

//The Interface which handles the serialization of JSON
@description="Add Invoice Interface"
Interface AddInvoice {
    Request {
        @jsonname="sourceId", description="Source"
        int source;

        @jsonname="orgId", description="Organization"
        int organizationId;

        @jsonname="ivcType",description="Type"
        int invoiceType;

        @jsonname="reqNo", description="Rquest Number"
        string requestNo;

        @jsonname="payerNo", description="Payer No"
        string payNo;

        @jsonname="receiverNo", description="ReceiverNo", optional="true" //Optional member
        string receiverNo ;

        @jsonname="businessIds", description="Business ID List"
        vector<string> bussinessIds;
		
        @jsonname="invoiceTicket", description="Invoice Ticket"
        InvoiceTicket invoiceTicket;
	};

	Response {
        @jsonname="code", description="Return Code"
        string code;

        @jsonname="msg", description="Message"
        string message;

        @jsonname="reqNo", description="Require Number"
        string requestNo;

        @jsonname="businessIds", description="BusinessID", optional="true"
        vector<string> bussinessIds ;
		
        @jsonname="invoiceTicket", description="Invoice Ticket"
        InvoiceTicket invoiceTicket;
	};
};

Generate the C++ Class files

./json2cpp.py rapidjson sample.jsf dir_test

Command json2cpp takes 3 arguements: {rapidjson/jsoncpp} {Class definitation File} {Directory} Outputs in dir_test path is organized by the namespace defined in sample.jsf:

dir_test
├── jsf
     ├── AddInvoice.h
     ├── Address.h
     ├── InvoiceTicket.h
     ├── json2cpp.h
     ├── base.h
     ├── macro.h
     └── rapidjson
            ├── ......
          ......

Class Usage

base.h: defines the basic object access:

  • Field<>: Every json object in interface class are all Field type. It has Get/SetVaule()
  • IRequest: ToJson() serialize C++ Object to JSON string
  • IResponse: FromJson() unserialize JSON string to C++ Object macro.h: defines some marcos for internel use. json2cpp.h: include all header files, provide for other to use.

json2cpp will generate a hpp file each user defined class and interface. AddInvoice.h: interface AddInvoice implemention. AddWare.h: interface AddWare implemention. Address.h: user define class Address implemention. InvoiceTicket.h: user define class InvoiceTicket implemetion.

all you have to do is include header file "json2cpp.h", and use the classes generated.

C++ Sample Code:

#include "json2cpp.h"

/**** Request Sample ****/
AddInvoiceRequest request;
Address address;
Address address1;
InvoiceTicket invoTic;

address.m_provinceNo.SetValue(10001);
... //set address and address1 members
invoTic.m_invoiceType.SetValue("Normal");
... //set invoTic members

vector<Address> v_addr;
v_addr.push_back(address1);
invoTic.m_optionalAddress.SetValue(v_addr);

//Set the Request values:
request.m_source.SetValue(1);
request.m_organizationId.SetValue(10);
request.m_invoiceType.SetValue(100);
request.m_requestNo.SetValue("asd");
request.m_payNo.SetValue("10032-11");
std::vector<std::string> bid;
bid.push_back("saddd");
bid.push_back("xxxx");
request.m_bussinessIds.SetValue(bid);
request.m_invoiceTicket.SetValue(invoTic);

std::string str;
std::string error;
uint32_t ret = request.ToJson(str, error);
if (json2cpp::ERR_OK != ret)
{
    std::cout<<"error:"<<ret<<", "<<error<<std::endl;
    return;
}

/**** Response Sample ****/
ifstream fin("json.txt");
getline(fin,str);
uint32_t status = 200;
AddInvoiceResponse response;
uint32_t ret = response.FromJson(str, status);
if(ret != json2cpp::ERR_OK)
{
    std::cout<<"error:"<<ret<<", "<<response.m_JSFMessage.GetValue()<<std::endl;
    return;
}

Grammar

//namespace, allow 0 or more
(namespace {name_space};)

//user define class, allow 0 or more
(
(@description="{description_str}")
class {class_name}{
	@jsonname={json_filed_name}(,description="{description_str}", optional=["true","false"], default="{default_value_str}")
	[field_type] {field_name}; 
};
)
 
 //interface, allow 1 or more
(@description="{description_str}")
Interface {interface_name}{
	//request, must have only 1 for every interface
	Request{
		@jsonname={json_filed_name}(,description="{description_str}", optional=["true","false"], default="{default_value_str}")
		[field_type] {field_name} (optional); 
	};
	
	//response, must have only 1 for every interface
	Response{
		@jsonname={json_filed_name}(,description="{description_str}", optional=["true","false"], default="{default_value_str}")
		[field_type] {field_name} (optional); 
	};
};

Conventions:

  1. () means the grammar token is optional, it can be defined 0 or 1
  2. {} means variable name
  3. @ means comments
  4. [] means specified value of the set

Details:

  1. {name_space} means C++ style namespace

  2. {class_name}, {interface_name}, {field_name}, {json_filed_name} means self-defined struct/class, Interface, Field Name, JSON Field name. They can be any valid string

  3. User can define 1 or more class, the definitation sequence should follow the C++ style

  4. User can define 1 or more Interface,each Interface MUST have a pair of request/response objects

  5. @ means comments,now it supports jsonname, description, optional, default key-words:

    Key-Word Description
    jsonname JSON Field Name [It MUST be specified]
    description It will be generated into C++ code for comments [Optional]
    optional Specifies the JSON field is optional,value should be "true" or "false",default is"false" [Optional]
    default Specifies the default value of C++ member feild [Optional]
  6. [field_type] Filed Type. Now supporting short, int, bool, uint32_t, uint64_t, int64_t, double, self-define class T and vector<T>.

  7. Supports C++ sytle comments like //comments and /*comments*/ , the commots will be ignored when being parsing.

Anonymous Array

json2cpp supports anonymous array Request/Response, like the following JSON string:

[
    {
        "provinceNo": 10002,
        "provinceStr": "Beijing",
    },
    {
        "provinceNo": 10003,
        "provinceStr": "Hong Kong",
    }
]

This JSON string only contains an anonymous array of "Address", so the grammar is defined as following style:

@description="AddWare"
Interface AddWare{
	Request {
		@jsonname="", description="Request Addresses"
		vector<Address> addresses;
	};
	
	Response {
		.......
	};

When Request/Respons is an anonymous array JSON string, the @jsonname MUST be defined as "" (null), and the Field should ONLY contains ONE AND ONLY ONE vector type class or normal type (e.g. vector<Address>, vector<int>).

Inheritance

User can use defined Class to be inherited to Request/Response, which means user can reuse the definitation of a Class, put the fields of that class into Request/Response. For instance, Address has 2 fields: {int, string}. If the Request and Response are both required as a single Address Object (NOT an Object contains an Address). So the definitation file can be written as following:

// Tedious definitation:
@description="AddWare"
Interface AddWare{
	Request {
		@jsonname="provinceNo", description="Province ID" //@descpription is optional
		int provinceNo;	
	
		@jsonname="provinceStr", description="Province"
		string province;
	};

	Response {
		@jsonname="provinceNo", description="Province ID" //@descpription is optional
		int provinceNo;	
	
		@jsonname="provinceStr", description="Province"
		string province;
	};
};

// Can be simplified as following --->
@description="AddWare"
Interface AddWare{
	Request(Address) {};
	Response(Address){};
};
Inheritance Grammar Explanation
  • If (class_type) follows Request/Response, the Fields in Request/Response is optional (ZeroOrMore).
  • If Inheritance is not used, Fields in Request/Response is OneOrMore

About

A tool for JSON & C++ Mapping. Convert json string to c++ class, and convert c++ class to json string in reverse.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • C++ 80.9%
  • Python 13.9%
  • C 5.1%
  • Shell 0.1%
Morty Proxy This is a proxified and sanitized view of the page, visit original site.