使用C++来编写json生成器的使用来熟悉C++区别于C的使用方法和语法。
头文件
/* json-writer.cpp */ #ifndef _JSONWRITER_H_ #define _JSONWRITER_H_ #include<iostream> #include<string> #include<stack> #include<cstdint> using namespace std; class JsonWriter { public: enum ContainerType { CONTAINER_TYPE_ARRAY, CONTAINER_TYPE_OBJECT }; enum ContainerLayout { CONTAINER_LAYOUT_INHERIT, CONTAINER_LAYOUT_MULTI_LINE, CONTAINER_LAYOUT_SINGLE_LINE }; explicit JsonWriter(): writer(NULL), initialIndentDepth(0), indent(" "), containerPadding(" "), keyPaddingLeft(""), keyPaddingRight(" "), defaultContainerLayout(CONTAINER_LAYOUT_MULTI_LINE), forceDefaultContainerLayout(false) { } void ConfigureCompressedOutput() { SetIndent (""); SetContainerPadding(""); SetKeyPaddingLeft(""); SetKeyPaddingRight(""); SetDefaultContainerLayout(CONTAINER_LAYOUT_MULTI_LINE); SetForceDefaultContainerLayout(true); } ostream *GetWriter() {return writer; } void SetWriter (ostream *writer) { this->writer = writer; } int GetInitialIndentDepth() { return initialIndentDepth; } void SetInitialIndentDepth(int depth) { initialIndentDepth = depth; } const char *GetIndent() { return indent; } void SetIndent(const char *indent) { this->indent = indent; } const char *GetContainerPadding() { return containerPadding; } void SetContainerPadding(const char *padding) { keyPaddingRight = padding; } const char *GetKeyPaddingLeft() { return keyPaddingLeft; } void SetKeyPaddingLeft(const char *padding) { keyPaddingLeft = padding; } const char *GetKeyPaddingRight() { return keyPaddingRight; } void SetKeyPaddingRight(const char *padding) { keyPaddingRight = padding; } ContainerLayout GetDefaultContainerLayout() { return defaultContainerLayout; } void SetDefaultContainerLayout(ContainerLayout layout) { defaultContainerLayout = layout; } bool GetForceDeafultContainerLayout() { return forceDefaultContainerLayout; } void SetForceDefaultContainerLayout(bool force) { forceDefaultContainerLayout = force; } std::ostream& Write() { if (writer == NULL) { return std::cout; } return *writer; } void WriteEscapedChar (char c); void WriteString(const char *str); void StartChild (bool isKey); void StartChild() { StartChild (false); } void StartContainer(ContainerType type, ContainerLayout layout); void EndContainer(); void StartArray() { StartContainer(CONTAINER_TYPE_ARRAY, CONTAINER_LAYOUT_INHERIT); } void StartArray(ContainerLayout layout) { StartContainer(CONTAINER_TYPE_ARRAY, layout); } void StartShortArray() { StartContainer(CONTAINER_TYPE_ARRAY, CONTAINER_LAYOUT_SINGLE_LINE); } void EndArray() { EndContainer(); } void StartObject() { StartContainer(CONTAINER_TYPE_OBJECT, CONTAINER_LAYOUT_INHERIT); } void StartObject(ContainerLayout layout) { StartContainer(CONTAINER_TYPE_OBJECT, layout); } void StartShortObject() { StartContainer (CONTAINER_TYPE_OBJECT, CONTAINER_LAYOUT_SINGLE_LINE); } void EndObjct() { EndContainer(); } void Key(const char *key); void NullValue(); void Value(const char *value); void Value(std::string value); void Value(bool value); #define VALUE_DEF(t) void Value (t value) {StartChild(); Write() << value; } #define KEYVALUE_DEF(t) void KeyValue (const char *key, t value) { Key (key); Value (value); } VALUE_DEF(int8_t) VALUE_DEF(uint8_t) VALUE_DEF(int16_t) VALUE_DEF(uint16_t) VALUE_DEF(int32_t) VALUE_DEF(uint32_t) VALUE_DEF(int64_t) VALUE_DEF(uint64_t) VALUE_DEF(float) VALUE_DEF(double) void KeyNullValue( const char *key) { Key (key); NullValue(); } KEYVALUE_DEF(const char *) KEYVALUE_DEF(std::string) KEYVALUE_DEF(bool) KEYVALUE_DEF(int8_t) KEYVALUE_DEF(uint8_t) KEYVALUE_DEF(int16_t) KEYVALUE_DEF(uint16_t) KEYVALUE_DEF(int32_t) KEYVALUE_DEF(uint32_t) KEYVALUE_DEF(int64_t) KEYVALUE_DEF(uint64_t) KEYVALUE_DEF(float) KEYVALUE_DEF(double) private: ostream *writer; int initialIndentDepth; const char *indent; const char *containerPadding; const char *keyPaddingLeft; const char *keyPaddingRight; ContainerLayout defaultContainerLayout; bool forceDefaultContainerLayout; struct Container { ContainerType type; ContainerLayout layout; bool isKey; int childCount; Container (ContainerType type , ContainerLayout layout): type (type), layout(layout), isKey(false), childCount(0) { } }; std::stack<Container *> depth; void Indent(); }; #endif
.cpp文件
/* json-writer.cpp */ #include"json-writer.h" using namespace std; void JsonWriter::Indent() { for (int i = 0, s = initialIndentDepth + depth.size(); i < s; i++) { Write() << indent; } } void JsonWriter::StartChild(bool isKey) { if (0 == depth.size()) { if (initialIndentDepth > 0) { Indent(); } return; } Container *container = depth.top(); if (container->childCount > 0 && (container->type == CONTAINER_TYPE_ARRAY || (container->type == CONTAINER_TYPE_OBJECT && !container->isKey))) { Write() << ","; if (container->layout == CONTAINER_LAYOUT_SINGLE_LINE) { Write() << containerPadding; } else { Write() << endl; Indent(); } } else if (container->childCount == 0) { Write() << containerPadding; if (container->layout == CONTAINER_LAYOUT_MULTI_LINE) { Write() << endl; Indent(); } } container->isKey = isKey; container->childCount++; } void JsonWriter::Key (const char *key) { StartChild (true); WriteString(key); Write() << keyPaddingLeft << ":" << keyPaddingRight; } void JsonWriter::NullValue() { StartChild(); Write() << "null"; } void JsonWriter::Value(const char * value) { StartChild(); WriteString(value); } void JsonWriter::Value(string value) { StartChild(); WriteString(value.c_str()); } void JsonWriter::Value (bool value) { StartChild(); Write() << (value ? "true" : "false"); } void JsonWriter::StartContainer(ContainerType type, ContainerLayout layout) { if (forceDefaultContainerLayout) { layout = defaultContainerLayout; } else if (layout == CONTAINER_LAYOUT_INHERIT) { if (depth.size() > 0) { layout = depth.top()->layout; } else { layout = defaultContainerLayout; } } StartChild(); depth.push(new Container(type, layout)); Write() << (type == CONTAINER_TYPE_OBJECT ? '{' : '['); } void JsonWriter::EndContainer() { Container *container = depth.top(); depth.pop(); if (container->childCount > 0) { if (container->layout == CONTAINER_LAYOUT_MULTI_LINE) { Write() << endl; Indent(); } else { Write() << containerPadding; } } Write() << (container->type == CONTAINER_TYPE_OBJECT ? '}' : ']'); delete container; } void JsonWriter::WriteEscapedChar(char c) { switch(c) { case '"': Write() << "\\\""; break; case '\\': Write() << "\\\\"; break; case '\b': Write() << "\\b"; break; case '\f': Write() << "\\f"; break; case '\n': Write() << "\\n"; break; case '\r': Write() << "\\r"; break; case '\t': Write() << "\\t"; break; default: Write() << c; break; } } void JsonWriter::WriteString(const char *str) { Write() << "\""; for (int i = 0; str[i] != 0; i++) { WriteEscapedChar(str[i]); } Write() << "\""; }
简单测试代码:
#include<iostream> #include<cmath> #include"json-writer.h" int main() { auto writer = new JsonWriter; writer->StartArray(); writer->StartShortObject(); writer->KeyValue("name", "shiyanlou"); writer->KeyValue("age", "3"); writer->EndObjct(); writer->StartObject(); writer->KeyValue("skills", "c++"); writer->KeyValue("skills", "python"); writer->KeyValue("skills", "php"); writer->KeyValue("skills", "java"); writer->KeyValue("uri", "http://shiyanlou.com"); writer->Key("path"); writer->StartArray(); writer->Value("web"); writer->Value("algorithm"); writer->Value("linux"); writer->EndArray(); writer->Key("short-array"); writer->StartShortArray(); writer->Value(1); writer->Value((uint64_t)0xabcdef123456); writer->Value(M_PI); writer->EndContainer(); writer->EndObjct(); writer->Value(false); writer->EndArray(); }
多种格式测试代码:
#include "json-writer.h" #define BEGIN_TEST(name) \ { \ JsonWriter *w = new JsonWriter; \ w->SetInitialIndentDepth(2); \ if (compress) \ { \ w->ConfigureCompressedOutput(); \ } \ cout << #name << ":" << endl << endl; #define END_TEST \ delete w; \ cout << endl << endl; \ } int main() { bool compress; for (int i = 0; i < 2; compress = i == 0, i++) { BEGIN_TEST(null) w->NullValue(); END_TEST BEGIN_TEST(bool-false) w->Value(false); END_TEST BEGIN_TEST(bool-true) w->Value(true); END_TEST BEGIN_TEST(int) w->Value(30000); END_TEST BEGIN_TEST(double) w->Value(0.131415926); END_TEST BEGIN_TEST(empty-string) w->Value(""); END_TEST BEGIN_TEST(simple-string) w->Value("Hello"); END_TEST BEGIN_TEST(escaped-string) w->Value("\"newline\ntab\t\""); END_TEST BEGIN_TEST(empty-object) w->StartObject(); w->EndObjct(); END_TEST BEGIN_TEST(empty-array) w->StartArray(); w->EndArray(); END_TEST BEGIN_TEST(short-object) w->StartShortObject(); w->KeyValue("name", "Aaron"); w->EndObjct(); END_TEST BEGIN_TEST(short-array) w->StartShortArray(); for(int i = 0; i < 10; i++) { w->Value(i); } w->EndArray(); END_TEST BEGIN_TEST(array-with-object) w->StartArray(); w->StartShortObject(); w->KeyValue("name", "Aaron"); w->KeyValue("age", 7); w->EndObjct(); w->StartObject(); w->KeyValue("animal", "cat"); w->KeyValue("life-expectancy", "forever"); w->KeyValue("url", "http://catoverflow.com"); w->Key("catch-phrases"); w->StartArray(); w->Value("meow"); w->Value("hiss"); w->Value("purr"); w->EndArray(); w->EndObjct(); w->Value(false); w->EndArray(); END_TEST BEGIN_TEST(nested-objects) w->StartObject(); w->Key("a"); w->StartObject(); w->Key("b"); w->StartObject(); w->Key("c"); w->StartObject(); w->EndObjct(); w->EndObjct(); w->EndObjct(); w->EndArray(); END_TEST BEGIN_TEST(nested-arrays) w->StartArray(); w->StartArray(); w->StartArray(); w->StartArray(); w->EndArray(); w->EndArray(); w->EndArray(); w->EndArray(); END_TEST } return 0; }
makefile文件:
CXXFLAGS = -Wall -g -std=c++11 all: test json-writer-test clean: rm -rf *.o test json-writer-test test: json-writer.h json-writer.cpp test.cpp $(CXX) $(CXXFLAGS) json-writer.h json-writer.cpp test.cpp -o test json-writer-test: json-writer-test.cpp json-writer.h json-writer.cpp $(CXX) $(CXXFLAGS) json-writer.h json-writer.cpp json-writer-test.cpp -o json-writer-test
运行结果就不放了。
版权归于实验楼
来源:https://www.cnblogs.com/wanghao-boke/p/12238600.html