JSON处理C函数库-YAJL
Yet Another JSON Library (YAJL) 作为一个快速的流式 JSON 解析库,为开发者提供了高效的 JSON 处理解决方案。采用 ISC 许可协议授权。YAJL is a small event-driven (SAX-style) JSON parser written in ANSI C, and a small validating JSON generator.
YAJL 的主要优势在于其快速的流式处理能力。与传统的一次性解析整个 JSON 文档的方式不同,YAJL 可以在数据逐步到达时进行解析,这对于处理大型 JSON 文档或来自网络流的 JSON 数据非常有用。它能够在不占用大量内存的情况下,高效地处理 JSON 数据,提高了系统的性能和可扩展性。
Features
Stream (incremental) parsing and generation of JSON
ANSI C & tiny & portable
Human readable error messages with context
event driven
support for generating "beautified" JSON
includes It also includes a small simplified tree interface for simplified parsing and extraction of data from smallish JSON documents.
例如,在网络应用中,YAJL 可以实时解析来自服务器的 JSON 数据流,无需等待整个文档下载完成。在数据处理管道中,它可以与其他工具和库无缝集成,实现高效的数据转换和处理。
示例代码
#include <stdio.h>
#include <yajl/yajl_parse.h>
#define BUFFER_SIZE 4096
typedef struct {
int depth;
} ParseContext;
static int yajl_null(void *ctx) {
ParseContext *context = (ParseContext *)ctx;
printf("%*sNULL\n", context->depth * 2, "");
return 1;
}
static int yajl_boolean(void *ctx, int boolean) {
ParseContext *context = (ParseContext *)ctx;
printf("%*sBOOLEAN: %s\n", context->depth * 2, "", boolean? "true" : "false");
return 1;
}
static int yajl_integer(void *ctx, long long integerVal) {
ParseContext *context = (ParseContext *)ctx;
printf("%*sINTEGER: %lld\n", context->depth * 2, "", integerVal);
return 1;
}
static int yajl_double(void *ctx, double doubleVal) {
ParseContext *context = (ParseContext *)ctx;
printf("%*sDOUBLE: %f\n", context->depth * 2, "", doubleVal);
return 1;
}
static int yajl_string(void *ctx, const unsigned char *stringVal, size_t stringLen) {
ParseContext *context = (ParseContext *)ctx;
char *str = (char *)malloc(stringLen + 1);
memcpy(str, stringVal, stringLen);
str[stringLen] = '\0';
printf("%*sSTRING: %s\n", context->depth * 2, "", str);
free(str);
return 1;
}
static int yajl_start_map(void *ctx) {
ParseContext *context = (ParseContext *)ctx;
context->depth++;
printf("%*sSTART MAP\n", context->depth * 2, "");
return 1;
}
static int yajl_map_key(void *ctx, const unsigned char *key, size_t keyLen) {
ParseContext *context = (ParseContext *)ctx;
char *str = (char *)malloc(keyLen + 1);
memcpy(str, key, keyLen);
str[keyLen] = '\0';
printf("%*sMAP KEY: %s\n", context->depth * 2, "", str);
free(str);
return 1;
}
static int yajl_end_map(void *ctx) {
ParseContext *context = (ParseContext *)ctx;
context->depth--;
printf("%*sEND MAP\n", context->depth * 2, "");
return 1;
}
static int yajl_start_array(void *ctx) {
ParseContext *context = (ParseContext *)ctx;
context->depth++;
printf("%*sSTART ARRAY\n", context->depth * 2, "");
return 1;
}
static int yajl_end_array(void *ctx) {
ParseContext *context = (ParseContext *)ctx;
context->depth--;
printf("%*sEND ARRAY\n", context->depth * 2, "");
return 1;
}
int main() {
const char *json = "{\"key1\":true,\"key2\":123,\"key3\":{\"nestedKey\":\"value\"},\"key4\":[1,2,3]}";
yajl_callbacks callbacks = {
.yajl_null = yajl_null,
.yajl_boolean = yajl_boolean,
.yajl_integer = yajl_integer,
.yajl_double = yajl_double,
.yajl_string = yajl_string,
.yajl_start_map = yajl_start_map,
.yajl_map_key = yajl_map_key,
.yajl_end_map = yajl_end_map,
.yajl_start_array = yajl_start_array,
.yajl_end_array = yajl_end_array
};
ParseContext context = {0};
yajl_handle parser = yajl_alloc(&callbacks, NULL, (void *)&context);
yajl_status status;
status = yajl_parse(parser, (const unsigned char *)json, strlen(json));
if (status!= yajl_status_ok) {
unsigned char *errorMsg = yajl_get_error(parser, 1, (const unsigned char *)json, strlen(json));
fprintf(stderr, "JSON parsing error: %s\n", errorMsg);
yajl_free_error(parser, errorMsg);
}
yajl_free(parser);
return 0;
}
为了满足特定项目的更复杂需求,可以适当增加代码来扩展 YAJL 的功能。比如可添加对特定 JSON 数据格式的特殊处理,或者实现自定义的事件处理逻辑。在实际应用中,YAJL 已经被广泛应用于各种软件项目中。它的快速和高效使得开发者能够轻松地处理 JSON 数据,提高开发效率和软件性能。
最新版本:2.1
项目主页:
https://lloyd.github.io/yajl/
https://github.com/lloyd/yajl