引言

  scjson是一个小巧的纯c跨平台小巧引擎. 适用于替换老的cJSON引擎的场景.

数据结构和代码布局做了大量改进.优势体现在以下几个方面:

  1) 跨平台 (window 10 + VS2017 / ubuntu 16.10 + gcc 6.2 测试通过)

  2) 数据结构重构(内存结构缩减了小一半)

  3) 代码思路精简(全部加起来抛掉注释也许800行不到)

  4) 支持json文本注释特性 // or /* */

  5) 接口更少,更容易掌握全部

本文用到的资源

  上一篇博文 c json实战引擎四 , 最后❤跳跃

  内嵌到simplec框架的源码地址 https://github.com/wangzhione/simplec

  其中需要用到的文件

    scjson.h  -> 解析json的接口文件

    scjson.c  -> 解析json的具体实现

    tstr.h    -> 和文件打交道用到的c字符串结构接口文件

    tstr.c    -> 和文件打交道用到的c字符串结构具体实现

扯个蛋, 写了无数的代码, 还是觉得写代码还是挺有意思的O(∩_∩)O哈哈~.

  流浪记 http://music.163.com/#/song?id=26075648

前言

  在说这里之前来点有意思点心, 不知道有木有人对malloc接口使用起来感觉很别扭.

详细一点可以了解 C基础 内存统一入口 .这里我们加深一下对malloc内部机制的理解,

首先看以前找的资料, 主要是linux上用户态申请内存最大大小是多少等.

  malloc 一些解释 : https://www.zhihu.com/question/20836462

后面自己做了一些测试

#include <stdio.h>
#include <stdlib.h>
#include <limits.h> /*
* test calloc 返回结果信息
*/
int main(void) {
void * node; printf("UINT_MAX = %ld.\n", UINT_MAX); node = malloc(UINT_MAX);
printf("malloc UINT_MAX node = %p.\n", node);
if (node) {
puts("神奇!");
free(node);
} // 测试calloc 结果
node = calloc(UINT_MAX, sizeof(char));
printf("calloc UINT_MAX node = %p.\n", node);
if (node) {
puts("无语");
free(node);
} return ;
} //
// 测试结果 -> 系统蓝屏
// 结论 -> calloc 和 malloc 的行为是系统决定, assert也许是最好的选择

上面代码 run 之后, window 10系统直接蓝屏. 说明malloc/calloc 这类用户向系统要内存的函数, 都是不透明的.

都存在未定义行为. 因此得到的结论是

  1. 需要分系统来处理malloc, windows申请大内存存在崩溃行为

  2. 推荐以后关于 malloc / calloc 推荐用 assert 处理

上面是对malloc的解惑. 扯淡一点发现Microsoft 的 Visual Studio 2017 真厉害 , 黑科技太猛了, 强烈推荐尝试!!

到这里开始逐渐开始介绍scjson的设计思路了, 这里用到一个数据结构tstr . 设计结构图如下

完整代码可以在github上找, 还是挺不错的200行左右的代码, 加深对C字符串的理解.

这里再扯一点, str指向内存常变, tstr指向内存不怎么变. 所以采用两块内存保存,

方便后期优化, 例如加上字符串引用, 字符串枚举呀.

具体可以尝试了解对cloudwu字符串的解析博文 对云风 cstring 第二次解析

正文

  这里主要讲解scjson 解析的思路. 开篇继续扯淡, 发现C11的匿名结构体或联合体挺爽的.

(好像C99就有).例如设计的c保存json节点结构

struct cjson {
struct cjson * next;   // 采用链表结构处理, 放弃二叉树结构, 优化内存
struct cjson * child;   // type == ( _CJSON_ARRAY or _CJSON_OBJECT ) 那么 child 就不为空 unsigned char type; // 数据类型和方式定义, 一个美好的意愿
char * key; // json内容那块的 key名称
union {
char * vs; // type == _CJSON_STRING, 是一个字符串
double vd; // type == _CJSON_NUMBER, 是一个num值, ((int)c->vd) 转成int 或 bool
};
};

其中 union 中 vs 和 vd. 其实在老的C89也可以实现这种效果, 具体在linux内核中有过一个小技巧.

    union {
char * vs;
double vd;
};

伪造实现如下, 这种方式缺点是宏污染, 搞起来麻烦, 不好看.

union {
char * vs;
double vd;
} __v;
#define vs __v.vs
#define vd __v.vd

我们这里scjson 解析引擎内存结构如下:

详细一点代码类型就是

// json中几种数据结构和方式定义, 对于程序开发而言最难的还是理解思路(思想 or 业务)
#define _CJSON_FALSE (0u)
#define _CJSON_TRUE (1u)
#define _CJSON_NULL (1u << 1)
#define _CJSON_NUMBER (1u << 2)
#define _CJSON_STRING (1u << 3)
#define _CJSON_ARRAY (1u << 4)
#define _CJSON_OBJECT (1u << 5) #define _CJSON_ISREF (1u << 6) //set 时候用如果是引用就不释放了
#define _CJSON_ISCONST (1u << 7) //set 时候用, 如果是const char * 就不释放了

上面就是解析之后的具体结构类型. 下面简单分析一下文本解析规则.

主要思路就是递归下降分析. 到这里基本关于scjson详细设计图介绍完毕了.

去掉注释一共也许800行代码都不到, 愿这只麻雀 ヽ(✿゚▽゚)ノ

后记

   On s'en va (Shy'm) http://music.163.com/m/song?id=29814206&userid=16529894

相濡以沫,不如相忘于江湖   --  《庄子·大宗师·天运》

c json实战引擎五 , 优化重构的更多相关文章

  1. C json实战引擎 三 , 最后实现部分辅助函数

    引言 大学读的是一个很时髦的专业, 学了四年的游戏竞技. 可惜没学好. 但认真过, 比做什么都认真. 见证了  ...... 打的所有游戏人物中 分享一位最喜爱 的 “I've been alone ...

  2. c json实战引擎四 , 最后❤跳跃

    引言  - 以前那些系列 长活短说, 写的最终 scjson 纯c跨平台引擎, 希望在合适场景中替代老的csjon引擎, 速度更快, 更轻巧. 下面也是算一个系列吧. 从cjson 中得到灵感, 外加 ...

  3. C json实战引擎 二 , 实现构造部分

    引言 这篇博文和前一篇 C json实战引擎一,实现解析部分设计是相同的,都是采用递归下降分析. 这里扯一点 假如你是学生 推荐一本书 给 大家 自制编程语言 http://baike.baidu.c ...

  4. C json实战引擎 一 , 实现解析部分

    引言 以前可能是去年的去年,写了一个 c json 解析引擎用于一个统计实验数据项目开发中. 基本上能用. 去年在网上 看见了好多开源的c json引擎 .对其中一个比较标准的 cJSON 引擎 深入 ...

  5. c json实战引擎六 , 感觉还行

    前言 看到六, 自然有 一二三四五 ... 为什么还要写呢.  可能是它还需要活着 : ) 挣扎升级中 . c json 上面代码也存在于下面项目中(维护的最及时) structc json 这次版本 ...

  6. .NET-架构优化实战-底层服务优化

    原文:.NET-架构优化实战-底层服务优化 前言 问题分析 在本系列第一篇文章我们提到,底层问题主要存在以下两点: 代码冗余 时效低 代码冗余 例如: 领奖方法不统一,一次性的写一套,可循环的又写一套 ...

  7. [原创].NET 业务框架开发实战之六 DAL的重构

    原文:[原创].NET 业务框架开发实战之六 DAL的重构 .NET 业务框架开发实战之六 DAL的重构 前言:其实这个系列还是之前的".NET 分布式架构开发实战 ",之所以改了 ...

  8. 第一章-Flink介绍-《Fink原理、实战与性能优化》读书笔记

    Flink介绍-<Fink原理.实战与性能优化>读书笔记 1.1 Apache Flink是什么? 在当代数据量激增的时代,各种业务场景都有大量的业务数据产生,对于这些不断产生的数据应该如 ...

  9. Javascript多线程引擎(五)

    Javascript多线程引擎(五)之异常处理 C语言没有提供一个像Java一样的异常处理机制, 这就带来了一个问题, 对于一个子函数中发生异常后, 需要在父函数调用子函数的位置进行Check, 如果 ...

随机推荐

  1. 【bzoj1231】[Usaco2008 Nov]mixup2 混乱的奶牛 状态压缩dp

    题目描述 混乱的奶牛[Don Piele, 2007]Farmer John的N(4 <= N <= 16)头奶牛中的每一头都有一个唯一的编号S_i (1 <= S_i <= ...

  2. (二)MySQL学习笔记

    1.视图 视图是一系列select语句返回的可视化结果集,是一张虚拟表.更多介绍请查看http://tool.oschina.net/apidocs/apidoc?api=mysql-5.1-zh 视 ...

  3. Signal函数

    Signal函数: 这个函数是一种系统调用,就是告诉系统发生中断的时候用该干嘛.第一个参数就是信号的编号,第二个参数就是信号的指针. 原型: #include <signal.h> voi ...

  4. 【bzoj】3477: [Usaco2014 Mar]Sabotage 01分数规划

    这题算是01分数规划吧2333 sum-a[i]*x[i]=c*(n-x[i]) 化简一下就是sum-(a[i]-c)*x[i]-nc=0,每次找最大的(a[i]-c)*x[i](子段和),如果结果& ...

  5. [HAOI2007]分割矩阵 DP+推式子

    发现最近好少写博客啊(其实是各种摆去了) 更一点吧 这道题要求最小化均方差,其实凭直觉来说就是要使每个块分的比较均匀一点,但是单单想到想到这些还是不够的, 首先f[i][j][k][l][t]表示以( ...

  6. BZOJ4755: [JSOI2016]扭动的回文串——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4755 JYY有两个长度均为N的字符串A和B. 一个“扭动字符串S(i,j,k)由A中的第i个字符到 ...

  7. HDOJ(HDU).1025 Constructing Roads In JGShining's Kingdom (DP)

    HDOJ(HDU).1025 Constructing Roads In JGShining's Kingdom (DP) 点我挑战题目 题目分析 题目大意就是给出两两配对的poor city和ric ...

  8. Mac添加锁屏快捷键

    Mac要想添加锁屏快捷键,必须使用Automator. 1. 打开Automator,创建一个新的服务. 2. 在左侧栏中找到 启动屏幕保护 ,将其拖曳到右侧窗口内,并且修改 服务收到改为" ...

  9. Problem B. Harvest of Apples 莫队求组合数前缀和

    Problem Description There are n apples on a tree, numbered from 1 to n.Count the number of ways to p ...

  10. Generating Sets 贪心

    H - Generating Sets Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64 ...