JSON处理C函数库-YAJL
2024-10-14 21:57:01 阿炯

本站赞助商链接,请多关照。 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