{"id":15629727,"url":"https://github.com/xyz347/x2struct","last_synced_at":"2025-08-22T00:41:21.781Z","repository":{"id":104151176,"uuid":"102450127","full_name":"xyz347/x2struct","owner":"xyz347","description":"Convert between json string and c++ object.  json字符串和c++结构体之间互相转换","archived":false,"fork":false,"pushed_at":"2020-12-21T05:30:09.000Z","size":2793,"stargazers_count":264,"open_issues_count":1,"forks_count":107,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-03-31T16:19:17.306Z","etag":null,"topics":["bson","convert","cpp","json","object","struct","xml"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xyz347.png","metadata":{"files":{"readme":"README.en.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2017-09-05T07:41:53.000Z","updated_at":"2025-01-10T20:42:11.000Z","dependencies_parsed_at":null,"dependency_job_id":"1fa0f93e-1762-4e8d-9748-5477aef493a4","html_url":"https://github.com/xyz347/x2struct","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xyz347%2Fx2struct","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xyz347%2Fx2struct/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xyz347%2Fx2struct/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xyz347%2Fx2struct/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xyz347","download_url":"https://codeload.github.com/xyz347/x2struct/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247713258,"owners_count":20983683,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bson","convert","cpp","json","object","struct","xml"],"created_at":"2024-10-03T10:28:21.783Z","updated_at":"2025-04-07T19:16:19.748Z","avatar_url":"https://github.com/xyz347.png","language":"C++","readme":"x2struct\n====\n*Read this in other languages: [简体中文](README.zh-cn.md).*\n\n\n* Used to convert between C++ objects and json/xml/json/libconfig\n* json/xml is header file only, no need to compile librarys\n* json is enabled by default, others need to modify [config.h](config.h)\n* The following example uses json as an example. Others can refer to api of x2struct::X in [x2struct.hpp](x2struct.hpp)\n------\n* [Basic usage](#basic-usage)\n* [Mandatory](#mandatory)\n* [Alias](#alias)\n* [Inherit](#inherit)\n* [Bit field](#bit-field)\n* [Load conditional](#load-conditional)\n* [char array](#char-array)\n* [check exist](#check-exist)\n* [local class](#local-class)\n* [customize type](#customize-type)\n* [thirdparty class](#thirdparty-class)\n* [Format indent](#format-indent)\n* [Qt support](#qt-support)\n* [xml bson libconfig](#xml-bson-libconfig)\n* [Generate Golang struct](#generate-golang-struct)\n* [IMPORTANT](#important)\n\nBasic usage\n----\n```C++\n#include \u003ciostream\u003e\n#include \"x2struct/x2struct.hpp\" // include this header file\n\nusing namespace std;\n\nstruct User {\n    int64_t id;\n    string  name;\n    string  mail;\n    User(int64_t i=0, const string\u0026 n=\"\", const string\u0026 m=\"\"):id(i),name(n),mail(m){}\n    XTOSTRUCT(O(id, name, mail)); // add XTOSTRUCT at the end of struct/class\n};\n\nstruct Group {\n    string  name;\n    int64_t master;\n    vector\u003cUser\u003e members;\n    XTOSTRUCT(O(name, master, members)); //  add XTOSTRUCT at the end of struct/class\n};\n\nint main(int argc, char *argv[]) {\n    Group g;\n    g.name = \"C++\";\n    g.master = 2019;\n    g.members.resize(2);\n    g.members[0] = User(1, \"Jack\", \"jack@x2struct.com\");\n    g.members[1] = User(2, \"Pony\", \"pony@x2struct.com\");\n\n    string json = x2struct::X::tojson(g);  // C++ object to json\n    cout\u003c\u003cjson\u003c\u003cendl;\n\n    Group n;\n    x2struct::X::loadjson(json, n, false); // json to C++ object\n    cout\u003c\u003cn.name\u003c\u003cendl;\n\n    vector\u003cint\u003e vi;\n    x2struct::X::loadjson(\"[1,2,3]\", vi, false); // load vector directory\n    cout\u003c\u003cvi.size()\u003c\u003c','\u003c\u003cvi[1]\u003c\u003cendl;\n\n    map\u003cint, int\u003e m;\n    x2struct::X::loadjson(\"{\\\"1\\\":10, \\\"2\\\":20}\", m, false); // load map directory\n    cout\u003c\u003cm.size()\u003c\u003c','\u003c\u003cm[2]\u003c\u003cendl;\n\n    return 0;\n}\n```\n- include \"x2struct.hpp\"\n- add XTOSTRUCT at the end of struct, put all the variables inside \"O\"\n- use x2struct::X::tojson to convert C++ object to json\n- use x2struct::X::loadjson to load json to C++ object\n\nMandatory\n----\n- for json to C++ object\n- use M to include those mandatory variables\n- if mandatory field miss in json, an exception will throw\n\n```C++\n#include \u003ciostream\u003e\n#include \"x2struct/x2struct.hpp\"\n\nusing namespace std;\n\nstruct Test {\n    int64_t id;\n    string  name;\n    XTOSTRUCT(M(id), O(name)); // \"id\" is mandatory and \"name\" is optional\n};\n\nint main(int argc, char *argv[]) {\n    Test t;\n    string json=\"{\\\"name\\\":\\\"Pony\\\"}\";\n\n    x2struct::X::loadjson(json, t, false); // will throw exception(id is mandatory and no \"id\" in json)\n    return 0;\n}\n```\n\nAlias\n----\n- used for scenes where the variable name and json key name are inconsistent\n- use A to include alias variable. \"A\" take two parameters, 1st is variable, 2nd is tag-field\n- tag format is \"[type:]alias[,extension]\", Tag-field can contain multiple tags, separated by spaces\n- type is one of \"json\"/\"xml\"/\"bson\"/\"config\", no type field in tag  means this tag is applied to all type\n    - for example, \"tid\" means use tid as alias for all type\n    - \"tid json:xid\" means json use \"xid\" as alias and other types use \"tid\"\n- extension only support \"m\" now, means mandatory(A like O, optional)\n- if no alias in json, loadjson will also try variable name\n- tojson use alias\n\n``` C++\n#include \u003ciostream\u003e\n#include \"x2struct/x2struct.hpp\"\n\nusing namespace std;\n\nstruct Test {\n    int64_t uid;\n    string  name;\n    XTOSTRUCT(A(uid, \"id\"), O(name)); // \"uid\" use alias \"id\"\n};\n\nint main(int argc, char *argv[]) {\n    Test t;\n    string json=\"{\\\"id\\\":123, \\\"name\\\":\\\"Pony\\\"}\";\n\n    x2struct::X::loadjson(json, t, false); \n    cout\u003c\u003ct.uid\u003c\u003cendl;\n    return 0;\n}\n\n```\n\nInherit\n----\n- use I to include parents classs\n\n```C++\n#include \u003ciostream\u003e\n#include \"x2struct/x2struct.hpp\"\n\nusing namespace std;\n\nstruct P1 {\n    string mail;\n    XTOSTRUCT(O(mail));\n};\n\nstruct P2 {\n    int64_t version;\n    XTOSTRUCT(O(version));\n};\n\nstruct Test:public P1, public P2 {\n    int64_t uid;\n    string  name;\n    XTOSTRUCT(I(P1, P2), O(uid, name)); \n};\n\nint main(int argc, char *argv[]) {\n    Test t;\n    string json=\"{\\\"mail\\\":\\\"pony@x2struct.com\\\", \\\"version\\\":2019, \\\"id\\\":123, \\\"name\\\":\\\"Pony\\\"}\";\n\n    x2struct::X::loadjson(json, t, false);\n    cout\u003c\u003ct.mail\u003c\u003cendl;\n    cout\u003c\u003ct.version\u003c\u003cendl;\n    return 0;\n}\n\n```\n\nBit field\n----\n- use B to include those bit field variables\n\n``` C++\n#include \u003ciostream\u003e\n#include \"x2struct/x2struct.hpp\"\n\nusing namespace std;\n\nstruct Test {\n    int16_t ver:8;\n    int16_t len:8;\n    string  name;\n    XTOSTRUCT(B(ver, len), O(name)); \n};\n\nint main(int argc, char *argv[]) {\n    Test t;\n    string json=\"{\\\"ver\\\":4, \\\"len\\\":20, \\\"name\\\":\\\"IPv4\\\"}\";\n\n    x2struct::X::loadjson(json, t, false);\n    cout\u003c\u003ct.ver\u003c\u003cendl;\n    cout\u003c\u003ct.len\u003c\u003cendl;\n    return 0;\n}\n```\n\nLoad conditional\n----\n- load at most one object from an array of objects\n- use C to include those conditional variables at the beginning of XTOSTRUCT\n- conditional variables still need included in one of O,A or M\n\n```C++\n#include \u003ciostream\u003e\n#include \"x2struct/x2struct.hpp\"\n\nusing namespace std;\n\nstruct Task {\n    int id;\n    string name;\n    XTOSTRUCT(O(id, name));\n};\n\nstruct Test {\n    int  tid;\n    Task task;\n    XTOSTRUCT(C(task), O(tid, task)); // task included in C and O, C must at beginning of XTOSTRUCT\n    /*\n     XTOSTRUCT_CONDITION take two parameters, 1st is class name, 2nd is variable name\n     XTOSTRUCT_CONDITION defined a function take one parameter named \"obj\", pointer to xdoc of variable\n     \"task\" in json is array, load conditional only load the one that this functin return true\n    */\n    XTOSTRUCT_CONDITION(Test, task) {\n        int id;\n        // only load the one that Task.id is equal to Test.tid\n        return obj.convert(\"id\", id)\u0026\u0026id==this-\u003etid;\n    }\n};\n\n\n\nint main(int argc, char *argv[]) {\n    string s = \"{\\\"tid\\\":2019,\\\"task\\\":[{\\\"id\\\":2018,\\\"name\\\":\\\"hello\\\"},{\\\"id\\\":2019,\\\"name\\\":\\\"world\\\"}]}\";\n    Test t;\n    x2struct::X::loadjson(s, t, false);\n    cout\u003c\u003ct.task.name\u003c\u003cendl;\n}\n```\n\nchar array\n----\nmodify [config.h](config.h) to enable XTOSTRUCT_SUPPORT_CHAR_ARRAY\n\n\ncheck exist\n----\n- to check if field exist after load json to C++ object\n- use xhas to check if field exist\n\n```C++\n#include \u003ciostream\u003e\n#include \"x2struct/x2struct.hpp\"\n\nusing namespace std;\n\nstruct Test {\n    int64_t id;\n    string  name;\n    XTOSTRUCT(O(id, name));\n};\n\nint main(int argc, char *argv[]) {\n    Test t;\n    string json=\"{\\\"name\\\":\\\"Pony\\\"}\";\n\n    x2struct::X::loadjson(json, t, false, true); // 4th parameter apply true\n    cout\u003c\u003ct.xhas(\"id\")\u003c\u003cendl;       // use xhas to check exist\n    cout\u003c\u003ct.xhas(\"name\")\u003c\u003cendl;\n    return 0;\n}\n```\n\nlocal class\n----\n- XTOSTRUCT will add some template function, and local class could not define template function\n- use XTOSTRUCT_NT(types) instead of XTOSTRUCT, types support Json/Xml/Bson/Config\n- need C++11 support\n- not support load conditional now\n\n```C++\n// nt.cpp\n// g++ -o t nt.cpp -std=c++11\n#include \u003ciostream\u003e\n#include \"x2struct/x2struct.hpp\"\n\nusing namespace std;\n\nint main(int argc, char *argv[]) {\n    struct Test {\n        int64_t id;\n        string  name;\n        XTOSTRUCT_NT(Json)(O(id, name));\n    };\n\n    Test t;\n    string json=\"{\\\"id\\\":123, \\\"name\\\":\\\"Pony\\\"}\";\n\n    x2struct::X::loadjson(json, t, false);\n    cout\u003c\u003ct.name\u003c\u003cendl;\n    return 0;\n}\n```\n\ncustomize type\n----\n- customize type is string\n- need implement:\n\t- std::string format() const; use to format data to string\n\t- void parse(const std::string\u0026); use to load string to data\n- typedef XType\u003cxxx\u003e to define customize type\n- following is an IPv4 example\n\n```C++\n#include \u003ciostream\u003e\n#include \"x2struct/x2struct.hpp\"\n\nusing namespace std;\n\n// just example, no error handle\nstruct _XIPv4 {\n    uint32_t ip;\n    std::string format() const {\n        char buf[64];\n        int  len = sprintf(buf, \"%u.%u.%u.%u\", ip\u003e\u003e24, 0xff\u0026(ip\u003e\u003e16), 0xff\u0026(ip\u003e\u003e8), 0xff\u0026ip);\n        return string(buf, len);\n    }\n    void parse(const std::string\u0026 d) {\n        uint32_t u[4];\n        sscanf(d.c_str(), \"%u.%u.%u.%u\", \u0026u[0], \u0026u[1], \u0026u[2], \u0026u[3]);\n        ip = (u[0]\u003c\u003c24)+(u[1]\u003c\u003c16)+(u[2]\u003c\u003c8)+u[3];\n    }\n};\n\ntypedef x2struct::XType\u003c_XIPv4\u003e XIPv4;\n\nstruct Test {\n    XIPv4 ip;\n    XIPv4 mask;\n    XTOSTRUCT(O(ip, mask));\n};\n\nint main(int argc, char *argv[]) {\n    Test t;\n    string json=\"{\\\"ip\\\":\\\"192.168.1.2\\\", \\\"mask\\\":\\\"255.255.255.0\\\"}\";\n\n    x2struct::X::loadjson(json, t, false);\n    cout\u003c\u003ct.ip.ip\u003c\u003c','\u003c\u003ct.mask.ip\u003c\u003cendl;\n    cout\u003c\u003cx2struct::X::tojson(t)\u003c\u003cendl;\n    return 0;\n}\n```\n\nFormat indent\n----\n- last two parameters of tojson control format indent\n\nQt support\n----\n- modify config.h to enable macro XTOSTRUCT_QT\n- support QString/QList/QMap/QVector now\n\nthirdparty class\n----\n- need c++11 support\n- use XTOSTRUCT_OUT instead of XTOSTRUCT\n\n```c++\n#include \u003csys/time.h\u003e\n#include \u003ciostream\u003e\n#include \"x2struct/x2struct.hpp\"\n\nusing namespace std;\n\n/*\nstruct timeval {\n    time_t      tv_sec;\n    suseconds_t tv_usec;\n};\n*/\n\n// timeval is thirdparty struct\nXTOSTRUCT_OUT(timeval, O(tv_sec, tv_usec));\n\nstruct T {\n    int  a;\n    string b;\n    timeval t;\n    XTOSTRUCT(O(a, b, t));\n};\n\n\nint main(int argc, char *argv[]) {\n    T t;\n    T r;\n    t.a = 123;\n    t.b = \"x2struct\";\n    t.t.tv_sec = 888;\n    t.t.tv_usec = 999;\n    string s = x2struct::X::tojson(t);\n    cout\u003c\u003cs\u003c\u003cendl;\n    x2struct::X::loadjson(s, r, false);\n    cout\u003c\u003cr.a\u003c\u003c','\u003c\u003cr.b\u003c\u003c','\u003c\u003cr.t.tv_sec\u003c\u003c','\u003c\u003cr.t.tv_usec\u003c\u003cendl;\n    return 0;\n}\n```\n\nxml bson libconfig\n----\n- need to modify [config.h](config.h) to enable\n- not support load vector map directory\n- xml/libconfig not permit use digit as key, so if want to use map\u003cint, xxx\u003e, key need add 'x', e.g. x100\n- mongoxclient(https://github.com/xyz347/mongoxclient) is a wrapper of mongo-cxx-driver use bson\n\n\nGenerate Golang struct\n----\n- use to generate Golang struct define by C++ struct\n- need to define macro XTOSTRUCT_GOCODE\n```C++\n// go.cpp\n// g++ -o t go.cpp -DXTOSTRUCT_GOCODE\n#include \u003ciostream\u003e\n#include \"x2struct/x2struct.hpp\"\n\nusing namespace std;\n\nstruct Test {\n    int64_t id;\n    vector\u003cstring\u003e  names;\n    XTOSTRUCT(O(id, names));\n};\n\nint main(int argc, char *argv[]) {\n    Test t;\n\n    cout\u003c\u003cx2struct::X::togocode(t, true, true, true)\u003c\u003cendl; // last 3 parameter to generate (json/bson/xml) tags\n    return 0;\n}\n\n```\n\noutput is:\n```go\ntype Test struct {\n        Id      int64       `json:\"id\" bson:\"id\" xml:\"id\"`\n        Names   []string    `json:\"names\" bson:\"names\" xml:\"names\"`\n}\n```\n\nIMPORTANT\n----\n- Encode/decode json is use [rapidjson](https://github.com/Tencent/rapidjson)\n- Decode xml is use [rapidxml](http://rapidxml.sourceforge.net)\n- Decode bson is use [libbson](https://github.com/mongodb/libbson/tree/1.0.0)\n- Decode libconfig is use [libconfig](https://github.com/hyperrealm/libconfig)\n- Encode of xml/bson is written by myself. Without reference to the RFC, there may be cases where the standard is not met.\n- The library of bson/libconfig is precompiled. The environment is: Ubuntu12.04 g++4.9.2. Other environments may need to download the code and recompile if you need to use these two libraries.\n\n","funding_links":[],"categories":["C++"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxyz347%2Fx2struct","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxyz347%2Fx2struct","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxyz347%2Fx2struct/lists"}