# xpack **Repository Path**: maitianlu/xpack ## Basic Information - **Project Name**: xpack - **Description**: 用于C++结构体和json/xml/bson/mysql的互相转换 - **Primary Language**: C++ - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 23 - **Created**: 2024-09-20 - **Last Updated**: 2024-09-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README xpack ==== * Used to convert between C++ structure and json/xml, bson is supported in [xbson](https://github.com/xyz347/xbson). * Only header files, no need to compile library files, so there is no Makefile. * Support MySQL, depends on `libmysqlclient-dev`, need to install by yourself. **not fully tested** * Support Sqlite, depends on [libsqlite3](https://cppget.org/libsqlite3), need to install it yourself. **not fully tested** * Support yaml, depend on [yaml-cpp](https://github.com/jbeder/yaml-cpp), need to install it yourself. **not fully tested** * For details, please refer to the example ------ * [Quick start](#quick-start) * [Container Support](#container-support) * [FLAG](#flag) * [Alias](#alias) * [Bitfield](#bitfield) * [Inherit](#inherit) * [enum](#enum) * [Custom codec](#custom-codec) * [union](#union) * [Schema indeterminate type](#schema-indeterminate-type) * [Define macro outside the structure](#define-macro-outside-the-structure) * [Array](#array) * [Format indentation](#format-indentation) * [XML array](#xml-array) * [CDATA](#cdata) * [Qt support](#qt-support) * [Important note](#important-note) Quick start ---- - Use macro `XPACK`(or `XPACK_OUT` if you don't want to change the structure) include structure members - Use xpack::json::encode to convert structure to json - Use xpack::json::decode to convert json to structure ```C++ #include #include "xpack/json.h" // include this header file for json or "xpack/xml.h" for xml using namespace std; struct User { int id; string name; XPACK(O(id, name)); // Add XPACK at the end of structure, up to 99 'O' can be added, and each 'O' can contain up to 99 members }; int main(int argc, char *argv[]) { User u; string data = "{\"id\":12345, \"name\":\"xpack\"}"; xpack::json::decode(data, u); // json to structure cout< - map // only for json - unordered_map (need C++11) - shared_ptr (need C++11) FLAG ---- In the macro `XPACK`, variables need to be enclosed with letters, such as `XPACK(O(a,b))`, `XPACK` can contain multiple letters, and each letter can contain multiple variables. Currently supported letters are: - X Usage: X(F(flag1, flag2...), member1, member2,...) Multiple flags can be written in 'F', currently supported flags are: - 0 no flag - OE omitempty. When encoding, if the variable is 0 or an empty string or false, the variable is ignored - EN empty as null. When json encoding, encode empty variable as null(OE is ignore the variable) - M mandatory. When decoding, if the key corresponding to the variable does not exist, an exception is thrown - ATTR attribute. When xml encode, put the value in attribute - SL single line, When json encoding, put vector in single line - C Usage: C(customcodec, F(flag1,flags...), member1, member2,...) For custom codec function, please refer to [Custom codec](#custom-codec) for details - O Usage: O(member1, member2, ...) Same as X(F(0), member1, member2, ...) no flags - M Usage: M(member1, member2, ...) Same as X(F(M), member1, member2, ...) mandatory - A Usage: A(member1, alias1, member2, alias2...) Used when the key and the variable name are different, please refer to [Alias](#alias) for details - AF Usage: AF(F(flag1, flag2,...), member1, alias1, member2, alias2...) Alias with flags - B Usage: B(F(flag1, flag2, ...), member1, member2, ...) For bitfield, please refer to [Bitfield](#bitfield) for details. **bitfield not support alias** - I Usage: I(baseclass1, baseclass2....), baseclassx is parent class, please refer to [Inherit](#inherit) for details - E Usage: E(member1, member2) For enumeration variables that do not support C++11. **E not support alias** Alias ---- - Used when the key and the variable name are different - Usage: A(member1, alias1, member2, alias2...) or AF(F(flag1, flag2,...), member1, alias1, member2, alias2...), alias's format is "x t:n" - x stands for global alias, not required - t stands for type(currently support json/xml/bson), n stands for type alias, type alias is not required - The order of precedence is: type alias, global alias, variable name - For example, `id bson:_id`, in bson will use `_id` and json/xml will use `id` - Type alias can take some type flags, format is "t:n,flag1,flag2,...", currently supported flags are: - cdata. For xml, indicates that it is cdata - sbs. For xml vector, In normal, `vector nums` will be encoded into `12`, in sbs is `12` ``` C++ #include #include "xpack/json.h" using namespace std; struct Test { long uid; string name; XPACK(A(uid, "id"), O(name)); // "uid" use alias "id" }; int main(int argc, char *argv[]) { Test t; string json="{\"id\":123, \"name\":\"Pony\"}"; xpack::json::decode(json, t); cout< #include "xpack/json.h" using namespace std; struct Test { short ver:8; short len:8; string name; XPACK(B(F(0), ver, len), O(name)); }; int main(int argc, char *argv[]) { Test t; string json="{\"ver\":4, \"len\":20, \"name\":\"IPv4\"}"; xpack::json::decode(json, t); cout< #include "xpack/json.h" using namespace std; struct P1 { string mail; XPACK(O(mail)); }; struct P2 { long version; XPACK(O(version)); }; struct Test:public P1, public P2 { long uid; string name; XPACK(I(P1, P2), O(uid, name)); }; int main(int argc, char *argv[]) { Test t; string json="{\"mail\":\"pony@xpack.com\", \"version\":2019, \"id\":123, \"name\":\"Pony\"}"; xpack::json::decode(json, t); cout< #include "xpack/json.h" using namespace std; enum Enum { X = 0, Y = 1, Z = 2, }; struct Test { string name; Enum e; XPACK(O(name), E(F(0), e)); }; int main(int argc, char *argv[]) { Test t; string json="{\"name\":\"IPv4\", \"e\":1}"; xpack::json::decode(json, t); cout< #include "xpack/json.h" using namespace std; struct Test { char name[64]; char email[64]; XPACK(O(name, email)); }; int main(int argc, char *argv[]) { Test t; string json="{\"name\":\"Pony\", \"email\":\"pony@xpack.com\"}"; xpack::json::decode(json, t); cout< #include #include "xpack/json.h" using namespace std; /* struct timeval { time_t tv_sec; suseconds_t tv_usec; }; */ // timeval is thirdparty struct XPACK_OUT(timeval, O(tv_sec, tv_usec)); struct T { int a; string b; timeval t; XPACK(O(a, b, t)); }; int main(int argc, char *argv[]) { T t; T r; t.a = 123; t.b = "xpack"; t.t.tv_sec = 888; t.t.tv_usec = 999; string s = xpack::json::encode(t); cout< 1 2 3 ``` - You can use alias to change the label name. For example: A(ids,"xml:ids,vl@id"), vl@id means to use id as label: ``` xml 1 2 3 ``` - If want to encode array element side by side, can use `sbs` flag. For example: `A(ids, "xml:ids,sbs")`. **Note that the sbs tag can only be used for arrays(vector), and it may crash if used elsewhere** ``` xml 1 2 3 ``` CDATA ---- - For xml CDATA, need to use `cdata` flag. For example: A(data, "xml:data,cdata") - variable type must be std::string - Non-cdata types can also add cdata flag, which will be processed as ordinary strings Qt support ---- - Modify [config.h](config.h) to enable XPACK_SUPPORT_QT(or enable it in compile flags) - Currently supports: QString/QMap/QList/QVector Important note ---- - Try not to start the variable name with __x_pack, otherwise it may conflict with the library. - vc6 is not supported - msvc has only been tested on vs2019 - The serialization and deserialization of json uses [rapidjson](https://github.com/Tencent/rapidjson) (November 2018 edition) - The deserialization of xml uses [rapidxml](http://rapidxml.sourceforge.net) - The serialization of xml is written by myself, without reference to RFC, there may be some differences from the standard.