SuperJson-超级Json解析和生成器

一款强大简单高性能的Json解析和生成器

设计的初衷有两个。希望能设计最佳性能而又强大的Json解析器。类似芯片一样,追求更高性能的芯片。
第二个初衷是,希望Json源文件数量少,容易导入项目。希望有更丰富的错误提示,让开发简单一点。更重要的是,希望有更高效的解析效率,甚至可以轻松解析几百MB大小的Json文件。根据多年的经验,设计出这款超级Json解析和生成器

介绍

SuperJson是一个Json解析器和生成器,它的设计遵循着无语言特性,可以用任何编程语言实现,目前暂时实现C++版本。

  • SuperJson很迷你,代码行数不超过2000,但功能相对完善。
  • SuperJson解析是非常快速,直接复制一份json数据,在此基础上,不会进行任何字符串切割,只是标记每个值的位置pos和len, 用node-tree的方式管理这些节点node。因此,它解析大json文件非常快速。只有取值的时候,才根据标记去获得相应的值。
    如果是字符串,直接返回json数据的内存所在地址,该内存片段末尾被置为0,确保是c语言字符串,当然也有字段记录数据片段的大小,以防数据缺失。如果获取的值是数值,会生成segment片段,记录此数值。
  • SuperJson使用节点node管理的,节点管理通过c语言数组实现,保证迭代json节点的高效。有四种节点node,这四种节点继承jsonnode。父类jsonnode是root节点,否则其子类就是子节点。子节点有NumberNode,StringNode,ObjectNode,ArrayNode四个,对应记录的json类型。root节点不记录任何值,只保存了树根节点。
  • SuperJson的内存管理很高效,当然还有进一步优化的空间。
    注意:不能释放SuperJson返回都内存,即使是write操作返回json字符串,也不能进行释放。因为它已经绑定到root节上。root节点释放,它就会自动被释放。

配置

只有源文件SuperJson.h和SuperJson.cpp,无其他依赖。跑测试例子,可以使用cmake快速构建编译执行

运行测试

在superjson根目录下,建一个build文件节。

mkdir build

cd到build文件文件夹,执行cmake。

cmake ../

再执行make命令,就可以生成可执行程序
也可以用cmake可视化工具进行生成工程。非常简单,不在此介绍。

demo

1.解析json字符串

#include 
#include 
#include 
#include "SuperJson.h"
using namespace SuperJson;
int main(int argc, char* argv[])
{
    const char* test = "{\
        \"bool1\":    true,\
        \"bool2\" :     false,\
        \"int\" :  323,\
        \"long\" :    2147483648,\
        \"double\" :    234.23\
        \"string\" : \"txt\"\
    }";
    printf("start:%s", test);

    //创建root对象,基类JsonNode实例对象都是root对象
    JsonNode root = JsonNode();
    //输入json格式数据
    root.read(test, strlen(test));

    //root对象,只包含了一个子节点,这个子节点就是json的数据结构
    JsonNode* node = root.array(0);
    //由于json数据,是一个object,所以它必定是ObjectNode
    assert(node->isObject());

    //取出字段bool1的节点,此节点保存了数值,同时还保存了key节点
    JsonNode* bool1node = node->object("bool1");
    printf("key=%s value=%d\n", bool1node->getKey(), (int)bool1node->getBool());

    //同上
    JsonNode* bool2node = node->object("bool2");
    printf("key=%s value=%d\n", bool2node->getKey(), (int)bool2node->getBool());

    JsonNode* intnode = node->object("int");
    printf("key=%s value=%d\n", intnode->getKey(), intnode->getInteger());

    JsonNode* longnode = node->object("long");
    printf("key=%s value=%ld\n", longnode->getKey(), longnode->getLong());

    JsonNode* doublenode = node->object("double");
    printf("key=%s value=%lf\n", doublenode->getKey(), doublenode->getDouble());
    printf("for==>>\n");
    JsonNode* child;
    //Object和Array都是通过c语言数组保存,通过接口count()获得子节点的数量
    for (size_t i=0; icount(); ++i)
    {
        //JsonNode& child = (*node)[i];
        child = node->array(i);
        //子节点的key节点丢弃,一般在Array节点存在
        if (child->getKey() == JsonNode::none) 
            printf("JsonNode type=%s, number=%lf\n", child->getTypeName(), child->getNumber());
        else 
            printf("JsonNode type=%s, key=%s, number=%lf\n", child->getTypeName(),child->getKey(), child->getNumber());
    }

    size_t len;
    //把解析出的json,再生成会json字符串数据
    const char* buffer = root.write(&len);
    printf("finish:%s", buffer);
    return 0;
}

2.解析json文件

#include 
#include 
#include 
#include "SuperJson.h"
using namespace SuperJson;
int main(int argc, char* argv[])
{
    JsonNode* root = new JsonNode();
    //原json文件
    const char* src_file = "./TestCtrl.json";
    root->readFile(src_file);
    //再把它生成回去,用另一个文件保存
    const char* dst_file = "./TestCtrl123.json";
    root->writeFile(dst_file);
    return 0;
}

3.生成json数据

#include 
#include 
#include 
#include "SuperJson.h"
using namespace SuperJson;
int main(int argc, char* argv[])
{
    //root节点
    JsonNode root = JsonNode();

    //创建一个ObjectNode节点  obj = {}
    JsonNode* object = root.newObjectNode();
    //放入到root节点,注意,root节点只能有一个节点
    root.addNode(object);

    //创建一个NumberNode节点  obj['bool'] = true
    JsonNode* numberb = root.newNumberNode();
    numberb->setBool(true);
    object->addNode("bool", numberb);

    //创建一个NumberNode节点  obj['int'] = 323
    JsonNode* numberi = root.newNumberNode();
    numberi->setInteger(323);
    object->addNode("int", numberi);

    //创建一个NumberNode节点  obj['double'] = 234.23
    JsonNode* numberd = root.newNumberNode();
    numberd->setDouble(234.23);
    object->addNode("double", numberd);
    {
        size_t len;
        //把此节点序列化成出来,打印
        const char* buffer = numberd->write(&len);
        printf("stringd:%s \n", buffer);
    }

    //创建一个NumberNode节点  obj['string'] = "test txt"
    JsonNode* stringd = root.newStringNode();
    const char* txt = "test txt";
    stringd->setString(txt, strlen(txt));
    object->addNode("string", stringd);

    //可以把每个节点序列化出来
    {
        size_t len;
        const char* buffer = stringd->write(&len);
        printf("stringd:%s\n", buffer);
    }
    {
        size_t len;
        const char* buffer = object->write(&len);
        printf("object:%s\n", buffer);
    }

    //最后生成整个json字符串
    size_t len;
    const char* buffer = root.write(&len);
    printf("finish:%s\n", buffer);
}

输出日志

stringd:"double":234.23 
stringd:"string":"test txt"
object:{"bool":1,"int":323,"double":234.23,"string":"test txt"}
finish:{"bool":1,"int":323,"double":234.23,"string":"test txt"}

4.迭代整个json结构

#include 
#include 
#include 
#include "SuperJson.h"
using namespace SuperJson;

void iterFunc(JsonNode& node, int depth);
int main(int argc, char* argv[])
{
    const char* test = "{\
        \"bool1\":    true,\
        \"bool2\" :     false,\
        \"int\" :  323,\
        \"long\" :    2147483648,\
        \"double\" :    234.23\
        \"string\" : \"txt\"\
    }";
    JsonNode root = JsonNode();
    root.read(test, strlen(test));
    JsonNode* node = root.array(0);

    iterFunc(*node, 5);
}

void iterFunc(JsonNode& node, int depth)
{
    if (depth >= 7) return;
    switch (node.getType())
    {
    case JsonNode::STRING:
    case JsonNode::NUMBER:
        if (node.getKey() == JsonNode::none)
        {
            if (node.isNumber())
                printf("JsonNode index=%d,type=%s, number=%lf\n", node.getIndex(), node.getTypeName(), node.getNumber());
            else
                printf("JsonNode index=%d,type=%s, string=%s\n", node.getIndex(), node.getTypeName(), node.getString());
        }
        else
        {
            if (node.isNumber())
                printf("JsonNode index=%d, type=%s, key=%s, number=%lf\n", node.getIndex(), node.getTypeName(), node.getKey(), node.getNumber());
            else
                printf("JsonNode index=%d, type=%s, key=%s, string=%s\n", node.getIndex(), node.getTypeName(), node.getKey(), node.getString());
        }
        break;
    case JsonNode::ARRAY:
    case JsonNode::OBJECT:
        if (node.getKey() == JsonNode::none)
            printf("JsonNode:%d:%s\n", node.getIndex(), node.getTypeName());
        else
            printf("JsonNode:%d:%s:%s\n", node.getIndex(), node.getTypeName(), node.getKey());

        for (size_t i = 0; i < node.count(); ++i)
        {
            JsonNode& child = node[i];
            iterFunc(child, depth + 1);
        }
        break;
    case JsonNode::ROOT:
        for (size_t i = 0; i < node.count(); ++i)
        {
            JsonNode& child = node[i];
            iterFunc(child, depth + 1);
        }
        break;
    default:
        break;
    }
}

你可能感兴趣的:(SuperJson-超级Json解析和生成器)