paquete x
Inglés
- Se utiliza para convertir entre estructuras C++ y json/xml/yaml/bson/mysql/sqlite.
- Solo hay archivos de encabezado, no es necesario compilar archivos de biblioteca, por lo que no hay Makefile.
- Admite bson, depende de
libbson-1.0
y debe instalarlo usted mismo. No probado completamente , consulte README para obtener más detalles. - Admite MySQL y depende de
libmysqlclient-dev
, que debe instalar usted mismo. No completamente probado - Admite Sqlite y depende de libsqlite3, que debe instalar usted mismo. No completamente probado
- Admite yaml, depende de yaml-cpp y debe instalarlo usted mismo. No completamente probado
- Para más detalles, consulte el ejemplo.
- Uso básico
- Soporte de contenedores
- BANDERA
- Alias
- campo de bits
- heredar
- enumerar
- Códec personalizado
- unión
- tipo indefinido
- formación
- Clases y estructuras de terceros.
- Formato de sangría
- matriz XML
- CDATA
- soporte qt
- mysql
- Nota importante
Uso básico
- La macro XPACK se utiliza después de la estructura para contener cada variable. XPACK también requiere una letra. Consulte FLAG para conocer los significados de las diferentes letras.
- Utilice xpack::json::encode para convertir la estructura a json
- Utilice xpack::json::decode para convertir json en estructura
# include < iostream >
# include " xpack/json.h " // Json包含这个头文件,xml则包含xpack/xml.h
using namespace std ;
struct User {
int id;
string name;
XPACK (O(id, name)); // 添加宏定义XPACK在结构体定义结尾
};
int main ( int argc, char *argv[]) {
User u;
string data = " { " id " :12345, " name " : " xpack " } " ;
xpack::json::decode (data, u); // json转结构体
cout<<u. id << ' ; ' <<u. name <<endl;
string json = xpack::json::encode (u); // 结构体转json
cout<<json<<endl;
return 0 ;
}
Soporte de contenedores
Actualmente se admiten los siguientes contenedores (std)
- vector
- colocar
- lista
- mapa<cadena, T>
- map<integer, T> // Sólo JSON, XML no es compatible
- unordered_map<cadena, T> (requiere compatibilidad con C++11)
- share_ptr (requiere compatibilidad con C++11)
BANDERA
En la macro XPACK, las variables deben incluirse con letras, como XPACK (O (a, b)). XPACK puede contener varias letras y cada letra puede contener varias variables. Las letras admitidas actualmente son:
- INCÓGNITA. El formato es X(F(flag1, flag2...), miembro1, miembro2,...) F contiene varios FLAG, actualmente admitidos son:
- 0 sin BANDERA
- OE omitido, al codificar, si la variable es 0 o una cadena vacía o falsa, no se generará la información clave correspondiente.
- EN vacío como nulo, utilizado para codificar json OE es un campo que no genera un vacío directamente, mientras que EN genera un nulo.
- M obligatorio, al decodificar, si este campo no existe, se generará una excepción, que se utiliza para algunos campos de identificación.
- Atributo ATTR, al codificar xml, coloque el valor en el atributo.
- SL de una sola línea, cuando codifica json, para matrices, colóquelas en una línea
- DO. El formato es C(customcodec, F(flag1,flags...), member1, member2,...) para funciones de codificación y decodificación personalizadas. Para obtener más información, consulte Códec personalizado.
- o. Equivalente a X(F(0), ...) sin ningún BANDERA.
- METRO. Equivale a X(F(M),...) indicando que estos campos deben existir.
- A. Alias, A(miembro1, alias1, miembro2, alias2...), utilizado cuando los nombres de la variable y la clave son diferentes
- AF. Alias con BANDERA, AF(F(bandera1, bandera2,...), miembro1, alias1, miembro2, alias2...)
- B. Bitfield, B(F(flag1, flag2, ...), miembro1, miembro2, ...) bitfield no admite alias
- I. Herencia, yo (baseclass1, baseclass2....), pongo la clase padre en ella
- MI. enumerar:
- Si el compilador admite C++ 11, no es necesario utilizar E y la enumeración se puede colocar en X/O/M/A.
- De lo contrario, la enumeración solo se puede colocar en E y no se admiten alias.
Alias
- Se utiliza para escenarios donde el nombre de la variable y el nombre de la clave son inconsistentes
- El formato es A(variable, alias....) o AF(F(flags), variable, alias....), y el formato del alias es el formato "xt:n".
- x representa el alias global, t representa el tipo (actualmente admite json, xml y bson) y n representa el alias del tipo.
- No es necesario un alias global. Por ejemplo
json:_id
es legal. - No es necesario utilizar alias de tipo. Por ejemplo,
_id
es legal. - Si hay un alias de tipo, use primero el alias de tipo. De lo contrario, use el alias global. Si no hay un alias de tipo, use el nombre de la variable.
# include < iostream >
# include " xpack/json.h "
using namespace std ;
struct Test {
long uid;
string name;
XPACK (A(uid, " id " ), O(name)); // "uid"的别名是"id"
};
int main ( int argc, char *argv[]) {
Test t;
string json= " { " id " :123, " name " : " Pony " } " ;
xpack::json::decode (json, t);
cout<<t. uid <<endl;
return 0 ;
}
campo de bits
- Utilice "B" para incluir variables de campo de bits. Los campos de bits no admiten alias.
# include < iostream >
# 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<<t. ver <<endl;
cout<<t. len <<endl;
return 0 ;
}
heredar
- Utilice "I" para incluir la clase principal. Si necesita utilizar las variables de la clase principal, inclúyalas. Si no las necesita, no es necesario que las incluya.
- También es necesario incluir la clase principal de la clase principal, como clase Base1: base pública clase Base2: base1 pública, entonces se necesita I (Base1, Base) en Base2;
- La clase principal también necesita definir la macro XPACK/XPACK_OUT.
# include < iostream >
# 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 " : " [email protected] " , " version " :2019, " id " :123, " name " : " Pony " } " ;
xpack::json::decode (json, t);
cout<<t. mail <<endl;
cout<<t. version <<endl;
return 0 ;
}
enumerar
- Si el compilador admite C++ 11, la enumeración tiene el mismo nombre que una variable ordinaria y se puede colocar en X/O/M/A.
- De lo contrario, debe colocarse en E, el formato es E(F(...), miembro1, miembro2,...)
# include < iostream >
# 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<<t. name <<endl;
cout<<t. e <<endl;
return 0 ;
}
Códec personalizado
Escenarios de aplicación
- Algunos tipos básicos quieren codificarse de forma personalizada, como el uso de cadenas para codificar números enteros/punto flotante.
- Es posible que algunos tipos no quieran codificarse uno por uno según las variables de estructura. Por ejemplo, si se define una estructura de tiempo:
struct Time {
long ts; // unix timestamp
};
No queremos codificarlo en el formato {"ts":1218196800}, pero queremos codificarlo en el formato "2008-08-08 20:00:00".
Hay dos formas aquí:
- Usando xtype, puedes consultar el ejemplo.
- Utilice C para incluir variables que requieren codificación y decodificación personalizadas (en lo sucesivo, el método C). Puede consultar el ejemplo.
Básicamente, ambos métodos implementan la codificación/decodificación por sí mismos, pero existen las siguientes diferencias:
- xtype está en el nivel de tipo, es decir, una vez que un tipo se encapsula con xtype, la codificación/decodificación personalizada tendrá efecto en este tipo. xtype no se puede utilizar en tipos básicos (int/string, etc.)
- El método C puede admitir tipos básicos (int/string, etc.) y tipos no básicos, pero solo funciona con variables contenidas en C, como int a; int O(a), C(custome_int, F(0; ), b) ;Entonces a todavía usa el códec predeterminado y b usa el códec personalizado.
- xtype tiene prioridad sobre la macro XPACK, es decir, si se define xtype, la codificación/decodificación de xtype se utilizará primero.
- El método C tiene prioridad sobre xtype, es decir, las variables contenidas en C definitivamente utilizarán los métodos de codificación y decodificación especificados en C.
Con estas dos funciones, puede lograr algunos controles de codificación y __x_pack_decode
más flexibles. Por ejemplo, este ejemplo implementa una función de codificación basada en condiciones variables. Si Sub.type == 1, codifique __x_pack_encode
; de lo contrario, codifique seq2. XPACK Las funciones de decodificación / codificación agregadas por la macro a la estructura, las funciones de codificación y decodificación personalizadas pueden llamar a las funciones de codificación y decodificación predeterminadas de xpack a través de estas funciones.
unión
Puede utilizar códecs personalizados para procesar uniones; consulte el ejemplo
formación
- Al decodificar, si el número de elementos excede la longitud de la matriz, se truncará.
- Las matrices de caracteres se procesan como si tuvieran un terminador
# include < iostream >
# 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 " : " [email protected] " } " ;
xpack::json::decode (json, t);
cout<<t. name <<endl;
cout<<t. email <<endl;
return 0 ;
}
tipo indefinido
- Escenarios en los que el esquema de json es incierto
- Utilice xpack::JsonData para recibir esta información
- Puedes consultar ejemplos.
- Los principales métodos de xpack::JsonData son:
- Tipo. solía obtener tipo
- Serie de funciones IsXXX. Se utiliza para determinar si es de un determinado tipo, básicamente equivalente a devolver Type()==xxxx;
- Funciones de la serie GetXXX. Se utiliza para extraer valores.
- Sobrecarga bool. Se utiliza para determinar si es un JsonData legal.
- Tamaño. Se utiliza para determinar la cantidad de elementos en un tipo de matriz.
-
operator [](size_t index)
se utiliza para obtener el elemento de índice de la matriz (comenzando desde 0) -
operator [](const char *key)
se usa para obtener elementos de tipo Objeto según la clave - Comenzar. Se utiliza para recorrer los elementos de Object, tomando el primero.
- Próximo. Úselo con Begin para obtener el siguiente elemento.
- Llave. Configure Begin y Next para usar y obtenga la clave al atravesar
Clases y estructuras de terceros.
- Utilice XPACK_OUT en lugar de XPACK para incluir variables
- XPACK_OUT debe definirse en el espacio de nombres global
# include < sys/time.h >
# include < iostream >
# 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<<s<<endl;
xpack::json::decode (s, r);
cout<<r. a << ' , ' <<r. b << ' , ' <<r. t . tv_sec << ' , ' <<r. t . tv_usec <<endl;
return 0 ;
}
Formato de sangría
- El json/xml generado por codificación no tiene sangría de forma predeterminada y es adecuado para el uso del programa. Si lo leen personas, se le puede sangrar.
- Los dos últimos parámetros del control de codificación.
- indentCount representa el número de caracteres para sangría, <0 representa sin sangría, 0 representa una nueva línea pero sin sangría.
- indentChar representa el carácter sangrado, usando espacios o tabulaciones
matriz XML
- Las matrices utilizan nombres de variables como etiquetas de elementos de forma predeterminada, como "ids": [1,2,3], y el xml correspondiente es:
< ids >
< ids >1</ ids >
< ids >2</ ids >
< ids >3</ ids >
</ ids >
- Puede utilizar alias para controlar las etiquetas de los elementos de la matriz, como A(ids,"xml:ids,vl@id"), vl va seguido de @xx, xx es la etiqueta de la matriz y el generado resultado es:
< ids >
< id >1</ id >
< id >2</ id >
< id >3</ id >
</ ids >
- Si desea que la matriz se expanda directamente en lugar de envolverla con una capa exterior, puede usar el alias más el indicador "sbs" para lograrlo, como A ( ids, "xml:ids,sbs"). La etiqueta sbs solo se puede usar para matrices. Otros El uso local puede fallar.
< ids >1</ ids >
< ids >2</ ids >
< ids >3</ ids >
CDATA
- Para el tipo CDATA, debe utilizar el indicador "cdata" para implementarlo, como A(data, "xml:data,cdata")
- cdata solo se puede recibir usando std::string
- Si el xml correspondiente a la variable no es una estructura CDATA, se procesará como una cadena normal. Por ejemplo,
<data>hello</data>
también se puede analizar correctamente.
soporte qt
- Modifique config.h y habilite la macro XPACK_SUPPORT_QT (o habilítela en la opción de compilación)
- Actualmente es compatible con QString/QMap/QList/QVector
mysql
- Actualmente solo se admite la decodificación y aún no se admite la codificación.
- No probado completamente, úselo con precaución
- Los tipos admitidos actualmente son:
- cadena. Prueba sencilla.
- Tipo entero. Prueba sencilla.
- Tipo de coma flotante. No probado.
- Utilice un tipo entero (como time_t) para recibir HORA/DATETIME/TIMESTAMP. No probado.
- Conversión de tipo personalizada, is_xpack_mysql_xtype, similar a xtype. No probado.
- Hay dos API (xpack::mysql::):
-
static void decode(MYSQL_RES *result, T &val)
- Se utiliza para convertir MYSQL_RES en una estructura o vector <>. Si no es un vector, solo se convertirá la primera fila.
-
static void decode(MYSQL_RES *result, const std::string&field, T &val)
- Se usa para analizar un campo determinado, se usa en escenarios en los que solo desea obtener el contenido de un campo determinado, como seleccionar ID de mytable donde nombre = lilei, y solo desea obtener la información de identificación. vector de soportes de val
Nota importante
- Intente no comenzar el nombre de la variable con __x_pack, de lo contrario puede entrar en conflicto con la biblioteca.
- vc6 no es compatible.
- msvc no ha realizado muchas pruebas, solo pruebas simples en 2019.
- La serialización y deserialización de json utiliza rapidjson.
- La deserialización de xml utiliza rapidxml
- La serialización de xml la escribí yo mismo sin hacer referencia a RFC, por lo que puede ser diferente del estándar.
- Si tienes alguna duda puedes unirte al grupo QQ 878041110