使用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