xpack
Englisch
- Wird zum Konvertieren zwischen C++-Strukturen und json/xml/yaml/bson/mysql/sqlite verwendet
- Es gibt nur Header-Dateien, es müssen keine Bibliotheksdateien kompiliert werden, daher gibt es kein Makefile.
- Unterstützt BSON, hängt von
libbson-1.0
ab und muss selbst installiert werden. Nicht vollständig getestet . Weitere Informationen finden Sie in der README-Datei - Unterstützt MySQL und hängt von
libmysqlclient-dev
ab, das Sie selbst installieren müssen. Nicht vollständig getestet - Unterstützt SQLite und hängt von libsqlite3 ab, das Sie selbst installieren müssen. Nicht vollständig getestet
- Unterstützt Yaml, hängt von Yaml-CPP ab und muss selbst installiert werden. Nicht vollständig getestet
- Einzelheiten entnehmen Sie bitte dem Beispiel
- Grundlegende Verwendung
- Containerunterstützung
- FLAGGE
- Alias
- Bitfeld
- erben
- aufzählen
- Benutzerdefinierter Codec
- Union
- unbestimmter Typ
- Array
- Klassen und Strukturen von Drittanbietern
- Einzug formatieren
- XML-Array
- CDATA
- Qt-Unterstützung
- MySQL
- Wichtiger Hinweis
Grundlegende Verwendung
- Das XPACK-Makro wird nach der Struktur verwendet, um jede Variable zu enthalten. Die Bedeutung der verschiedenen Buchstaben finden Sie auch in FLAG.
- Verwenden Sie xpack::json::encode, um die Struktur in JSON zu konvertieren
- Verwenden Sie xpack::json::decode, um JSON in eine Struktur zu konvertieren
# 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 ;
}
Containerunterstützung
Derzeit werden die folgenden Container (std) unterstützt
- Vektor
- Satz
- Liste
- map<string, T>
- map<integer, T> // Nur JSON, XML wird nicht unterstützt
- unordered_map<string, T> (erfordert C++11-Unterstützung)
- shared_ptr (erfordert C++11-Unterstützung)
FLAGGE
Im Makro XPACK müssen Variablen mit Buchstaben eingeschlossen werden, z. B. kann XPACK(O(a,b)) mehrere Buchstaben enthalten, und jeder Buchstabe kann mehrere Variablen enthalten. Derzeit unterstützte Briefe sind:
- X. Das Format ist X(F(flag1, flag2...), member1, member2,...) F enthält verschiedene FLAGs, derzeit unterstützt werden:
- 0 keine FLAGGE
- OE omitempty: Wenn die Variable beim Codieren 0 oder eine leere Zeichenfolge oder false ist, werden die entsprechenden Schlüsselinformationen nicht generiert.
- EN leer als Null, wird für die Codierung von JSON verwendet. OE ist ein Feld, das nicht direkt leer generiert, während EN eine Null generiert.
- M obligatorisch. Wenn dieses Feld beim Dekodieren nicht vorhanden ist, wird eine Ausnahme ausgelöst, die für einige ID-Felder verwendet wird.
- ATTR-Attribut: Geben Sie beim Codieren von XML den Wert in das Attribut ein.
- SL-Einzelzeile: Wenn JSON codiert, fügen Sie Arrays in einer Zeile ein
- C. Das Format ist C(customcodec, F(flag1,flags...), member1, member2,...) für benutzerdefinierte Codierungs- und Decodierungsfunktionen. Weitere Informationen finden Sie unter Benutzerdefinierter Codec
- O. Entspricht X(F(0), ...) ohne FLAG.
- M. Entspricht X(F(M),...) und gibt an, dass diese Felder vorhanden sein müssen.
- A. Alias, A(Mitglied1, Alias1, Mitglied2, Alias2...), wird verwendet, wenn die Variablen- und Schlüsselnamen unterschiedlich sind
- AF. Alias mit FLAG, AF(F(flag1, flag2,...), member1, alias1, member2, alias2...)
- B. Bitfield, B(F(flag1, flag2, ...), member1, member2, ...) Bitfield unterstützt keine Aliase
- ICH. Vererbung, ich (Basisklasse1, Basisklasse2 ...), füge die übergeordnete Klasse darin ein
- E. aufzählen:
- Wenn der Compiler C++11 unterstützt, muss E nicht verwendet werden und die Aufzählung kann in X/O/M/A platziert werden.
- Andernfalls kann die Aufzählung nur in E platziert werden und Aliase werden nicht unterstützt.
Alias
- Wird für Szenarien verwendet, in denen der Variablenname und der Schlüsselname inkonsistent sind
- Das Format ist A(Variable, Alias...) oder AF(F(Flags), Variable, Alias...) und das Alias-Format ist das Format "xt:n".
- x repräsentiert den globalen Alias, t repräsentiert den Typ (unterstützt derzeit JSON, XML und BSON) und n repräsentiert den Alias unter dem Typ.
- Es ist kein globaler Alias erforderlich. Beispielsweise ist
json:_id
zulässig. - Es sind keine Typaliase erforderlich. Beispielsweise ist
_id
zulässig. - Wenn ein Typalias vorhanden ist, verwenden Sie zuerst den Typalias. Andernfalls verwenden Sie den globalen Alias. Wenn kein Typalias vorhanden ist, verwenden Sie den Variablennamen.
# 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 ;
}
Bitfeld
- Verwenden Sie „B“, um Bitfeldvariablen einzuschließen. Bitfelder unterstützen keine Aliase.
# 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 ;
}
erben
- Verwenden Sie „I“, um die übergeordnete Klasse einzuschließen. Wenn Sie die Variablen der übergeordneten Klasse verwenden müssen, schließen Sie sie ein. Wenn Sie sie nicht benötigen, müssen Sie sie nicht einschließen.
- Die übergeordnete Klasse der übergeordneten Klasse muss ebenfalls enthalten sein, z. B. die Klasse Base1:public Base1, dann wird I(Base1, Base) in Base2 benötigt
- Die übergeordnete Klasse muss außerdem das XPACK/XPACK_OUT-Makro definieren.
# 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 ;
}
aufzählen
- Wenn der Compiler C++11 unterstützt, hat die Aufzählung denselben Namen wie eine gewöhnliche Variable und kann in X/O/M/A platziert werden.
- Andernfalls muss es in E platziert werden, das Format ist E(F(...), Mitglied1, Mitglied2, ...)
# 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 ;
}
Benutzerdefinierter Codec
Anwendungsszenarien
- Einige Grundtypen möchten auf benutzerdefinierte Weise codiert werden, z. B. die Verwendung von Zeichenfolgen zum Codieren von Ganzzahlen/Gleitkommazahlen.
- Einige Typen möchten möglicherweise nicht einzeln gemäß den Strukturvariablen codiert werden. Wenn beispielsweise eine Zeitstruktur definiert ist:
struct Time {
long ts; // unix timestamp
};
Wir wollen es nicht in das Format {"ts":1218196800} kodieren, sondern in das Format „2008-08-08 20:00:00“.
Hier gibt es zwei Möglichkeiten:
- Mit xtype können Sie auf das Beispiel verweisen
- Verwenden Sie C, um Variablen einzuschließen, die eine benutzerdefinierte Kodierung und Dekodierung erfordern (im Folgenden als C-Methode bezeichnet). Sie können sich auf das Beispiel beziehen
Beide Methoden implementieren die Kodierung/Dekodierung im Wesentlichen selbst, es gibt jedoch folgende Unterschiede:
- xtype befindet sich auf Typebene. Das heißt, sobald ein Typ mit xtype gekapselt ist, wird die benutzerdefinierte Codierung/Decodierung auf diesen Typ wirksam. xtype kann nicht für Basistypen (int/string usw.) verwendet werden.
- Die C-Methode kann Basistypen (int/string usw.) und Nicht-Basistypen unterstützen, funktioniert aber nur mit in C enthaltenen Variablen, wie z. B. int a, C(custome_int, F(0). ), b) ;Dann verwendet a immer noch den Standardcodec und b verwendet den benutzerdefinierten Codec.
- xtype hat Vorrang vor dem XPACK-Makro, d. h. wenn xtype definiert ist, wird die Kodierung/Dekodierung von xtype zuerst verwendet.
- Die C-Methode hat Vorrang vor xtype, d. h. in C enthaltene Variablen verwenden definitiv die in C angegebenen Codierungs- und Decodierungsmethoden.
Mit diesen beiden Funktionen können Sie einige flexiblere __x_pack_encode
und Decodierungssteuerungen erreichen. In diesem Beispiel wird __x_pack_decode
eine Codierungsfunktion basierend auf variablen Bedingungen implementiert XPACK Die vom Makro zur Struktur hinzugefügten Dekodier-/Kodierungsfunktionen sowie benutzerdefinierte Kodierungs- und Dekodierungsfunktionen können über diese Funktionen die Standardkodierungs- und Dekodierungsfunktionen von xpack aufrufen.
Union
Sie können benutzerdefinierte Codecs verwenden, um Gewerkschaften zu verarbeiten. Weitere Informationen finden Sie im Beispiel
Array
- Wenn beim Dekodieren die Anzahl der Elemente die Länge des Arrays überschreitet, wird es abgeschnitten.
- Char-Arrays werden so verarbeitet, als ob sie ein -Terminator hätten
# 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 ;
}
unbestimmter Typ
- Szenarien, in denen das Schema für JSON unsicher ist
- Verwenden Sie xpack::JsonData, um diese Informationen zu erhalten
- Sie können sich auf Beispiele beziehen
- Die Hauptmethoden von xpack::JsonData sind:
- Typ. Wird verwendet, um Typ zu erhalten
- IsXXX-Reihe von Funktionen. Wird verwendet, um zu bestimmen, ob es sich um einen bestimmten Typ handelt. Dies entspricht im Grunde der Rückgabe von Type()==xxxx;
- Funktionen der GetXXX-Serie. Wird zum Extrahieren von Werten verwendet.
- Bool überladen. Wird verwendet, um zu bestimmen, ob es sich um ein legales JsonData handelt.
- Größe. Wird verwendet, um die Anzahl der Elemente in einem Array-Typ zu bestimmen
-
operator [](size_t index)
wird verwendet, um das Indexelement des Arrays abzurufen (beginnend bei 0) -
operator [](const char *key)
wird verwendet, um Elemente vom Typ Object basierend auf dem Schlüssel abzurufen - Beginnen. Wird verwendet, um die Elemente von Object zu durchlaufen und dabei das erste zu übernehmen.
- Nächste. Verwenden Sie es mit Begin, um das nächste Element abzurufen.
- Schlüssel. Konfigurieren Sie „Begin“ und „Next“ für die Verwendung und erhalten Sie beim Durchlaufen den Schlüssel
Klassen und Strukturen von Drittanbietern
- Verwenden Sie XPACK_OUT anstelle von XPACK, um Variablen einzuschließen
- XPACK_OUT muss im globalen Namensraum definiert sein
# 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 ;
}
Einzug formatieren
- Das von encode generierte JSON/XML ist standardmäßig nicht eingerückt und für die Programmverwendung geeignet. Wenn es von Personen gelesen wird, kann es eingerückt werden.
- Die letzten beiden Parameter der Codierungssteuerung
- indentCount stellt die Anzahl der Zeichen für die Einrückung dar, <0 steht für keine Einrückung, 0 steht für eine neue Zeile, aber keine Einrückung.
- indentChar repräsentiert das eingerückte Zeichen unter Verwendung von Leerzeichen oder Tabulatoren
XML-Array
- Arrays verwenden standardmäßig Variablennamen als Elementbezeichnungen, z. B. „ids“:[1,2,3], und die entsprechende XML lautet:
< ids >
< ids >1</ ids >
< ids >2</ ids >
< ids >3</ ids >
</ ids >
- Sie können Aliase verwenden, um die Beschriftungen der Elemente des Arrays zu steuern, z. B. A(ids,"xml:ids,vl@id"), auf vl folgt @xx, xx ist die Beschriftung des Arrays und generiert Ergebnis ist:
< ids >
< id >1</ id >
< id >2</ id >
< id >3</ id >
</ ids >
- Wenn Sie möchten , dass das Array direkt erweitert wird, anstatt es mit einer Ebene außerhalb zu umschließen, können Sie dazu das Alias-Plus-Flag „sbs“ verwenden, z. B. A(ids, „xml:ids,sbs“) Das sbs-Tag kann nur für Arrays verwendet werden. Bei der lokalen Verwendung kann es zu Abstürzen kommen
< ids >1</ ids >
< ids >2</ ids >
< ids >3</ ids >
CDATA
- Für den CDATA-Typ müssen Sie zum Implementieren das Flag „cdata“ verwenden, z. B. A(data, „xml:data,cdata“)
- cdata kann nur mit std::string empfangen werden
- Wenn die der Variablen entsprechende XML-Datei keine CDATA-Struktur ist, wird sie als normale Zeichenfolge verarbeitet. Beispielsweise kann auch
<data>hello</data>
erfolgreich analysiert werden.
Qt-Unterstützung
- Ändern Sie config.h und aktivieren Sie das XPACK_SUPPORT_QT-Makro (oder aktivieren Sie es in der Kompilierungsoption).
- Unterstützt derzeit QString/QMap/QList/QVector
MySQL
- Derzeit wird nur die Dekodierung unterstützt, die Kodierung wird noch nicht unterstützt.
- Nicht vollständig getestet, mit Vorsicht verwenden
- Derzeit unterstützte Typen sind:
- Zeichenfolge. Einfacher Test.
- Integer-Typ. Einfacher Test.
- Gleitkommatyp. Nicht getestet.
- Verwenden Sie einen Ganzzahltyp (z. B. time_t), um TIME/DATETIME/TIMESTAMP zu empfangen. Nicht getestet.
- Benutzerdefinierte Typkonvertierung, is_xpack_mysql_xtype, ähnlich wie xtype. Nicht getestet.
- Es gibt zwei APIs (xpack::mysql::):
-
static void decode(MYSQL_RES *result, T &val)
- Wird zum Konvertieren von MYSQL_RES in eine Struktur oder einen Vektor verwendet<>. Wenn es kein Vektor ist, wird nur die erste Zeile konvertiert.
-
static void decode(MYSQL_RES *result, const std::string&field, T &val)
- Wird zum Parsen eines bestimmten Felds verwendet und in Szenarien verwendet, in denen Sie nur den Inhalt eines bestimmten Felds abrufen möchten, z. B. wenn Sie eine ID aus Mytable auswählen, wobei Name = Lilei ist, und nur die ID-Informationen abrufen möchten. val unterstützt Vektor
Wichtiger Hinweis
- Versuchen Sie, den Variablennamen nicht mit __x_pack zu beginnen, da es sonst zu Konflikten mit der Bibliothek kommen kann.
- vc6 wird nicht unterstützt.
- msvc hat im Jahr 2019 nicht viele Tests durchgeführt, sondern nur einfache Tests.
- Die Serialisierung und Deserialisierung von JSON verwendet RapidJSON.
- Die Deserialisierung von XML verwendet Rapidxml
- Die XML-Serialisierung wurde von mir selbst geschrieben, ohne auf RFC zu verweisen, daher kann sie vom Standard abweichen.
- Wenn Sie Fragen haben, können Sie der QQ-Gruppe 878041110 beitreten