iphone - 是否有关于如何使用基于 C 的 YAJL 库解析简单 JSON 文件的简单示例?

标签 iphone ios json ipad yajl

我知道 YAJL 周围有一个 Objective-C 包装器,但这确实是一个的东西,它将整个 JASON 解析器炸成可笑的巨大数量的 21 个文件,其中许多文件都很小滚动条。

因此,为了保持我的应用程序二进制文件较小,我想坚持使用该解析器的 C 版本。但我很难找到任何有用的文档而不是包装器。

也许使用过 C 库的人可以指出这样的教程或文档?

最佳答案

带有 C 示例的文档可以在这里找到:http://lloyd.github.com/yajl/
包含示例的 github 存储库可以在这里找到:https://github.com/lloyd/yajl

下面是一个从标准输入重新格式化 JSON 的 C 示例:

#include <yajl/yajl_parse.h>
#include <yajl/yajl_gen.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static int reformat_null(void * ctx)
{
    yajl_gen g = (yajl_gen) ctx;
    return yajl_gen_status_ok == yajl_gen_null(g);
}

static int reformat_boolean(void * ctx, int boolean)
{
    yajl_gen g = (yajl_gen) ctx;
    return yajl_gen_status_ok == yajl_gen_bool(g, boolean);
}

static int reformat_number(void * ctx, const char * s, size_t l)
{
    yajl_gen g = (yajl_gen) ctx;
    return yajl_gen_status_ok == yajl_gen_number(g, s, l);
}

static int reformat_string(void * ctx, const unsigned char * stringVal,
                           size_t stringLen)
{
    yajl_gen g = (yajl_gen) ctx;
    return yajl_gen_status_ok == yajl_gen_string(g, stringVal, stringLen);
}

static int reformat_map_key(void * ctx, const unsigned char * stringVal,
                            size_t stringLen)
{
    yajl_gen g = (yajl_gen) ctx;
    return yajl_gen_status_ok == yajl_gen_string(g, stringVal, stringLen);
}

static int reformat_start_map(void * ctx)
{
    yajl_gen g = (yajl_gen) ctx;
    return yajl_gen_status_ok == yajl_gen_map_open(g);
}


static int reformat_end_map(void * ctx)
{
    yajl_gen g = (yajl_gen) ctx;
    return yajl_gen_status_ok == yajl_gen_map_close(g);
}

static int reformat_start_array(void * ctx)
{
    yajl_gen g = (yajl_gen) ctx;
    return yajl_gen_status_ok == yajl_gen_array_open(g);
}

static int reformat_end_array(void * ctx)
{
    yajl_gen g = (yajl_gen) ctx;
    return yajl_gen_status_ok == yajl_gen_array_close(g);
}

static yajl_callbacks callbacks = {
    reformat_null,
    reformat_boolean,
    NULL,
    NULL,
    reformat_number,
    reformat_string,
    reformat_start_map,
    reformat_map_key,
    reformat_end_map,
    reformat_start_array,
    reformat_end_array
};

static void
usage(const char * progname)
{
    fprintf(stderr, "%s: reformat json from stdin\n"
            "usage:  json_reformat [options]\n"
            "    -m minimize json rather than beautify (default)\n"
            "    -u allow invalid UTF8 inside strings during parsing\n",
            progname);
    exit(1);

}

int 
main(int argc, char ** argv)
{
    yajl_handle hand;
    static unsigned char fileData[65536];
    /* generator config */
    yajl_gen g;
    yajl_status stat;
    size_t rd;
    int retval = 0;
    int a = 1;

    g = yajl_gen_alloc(NULL);
    yajl_gen_config(g, yajl_gen_beautify, 1);
    yajl_gen_config(g, yajl_gen_validate_utf8, 1);

    /* ok.  open file.  let's read and parse */
    hand = yajl_alloc(&callbacks, NULL, (void *) g);
    /* and let's allow comments by default */
    yajl_config(hand, yajl_allow_comments, 1);

    /* check arguments.*/
    while ((a < argc) && (argv[a][0] == '-') && (strlen(argv[a]) > 1)) {
        unsigned int i;
        for ( i=1; i < strlen(argv[a]); i++) {
            switch (argv[a][i]) {
                case 'm':
                    yajl_gen_config(g, yajl_gen_beautify, 0);
                    break;
                case 'u':
                    yajl_config(hand, yajl_dont_validate_strings, 1);
                    break;
                default:
                    fprintf(stderr, "unrecognized option: '%c'\n\n",
                            argv[a][i]);
                    usage(argv[0]);
            }
        }
        ++a;
    }
    if (a < argc) {
        usage(argv[0]);
    }


    for (;;) {
        rd = fread((void *) fileData, 1, sizeof(fileData) - 1, stdin);

        if (rd == 0) {
            if (!feof(stdin)) {
                fprintf(stderr, "error on file read.\n");
                retval = 1;
            }
            break;
        }
        fileData[rd] = 0;

        stat = yajl_parse(hand, fileData, rd);

        if (stat != yajl_status_ok) break;

        {
            const unsigned char * buf;
            size_t len;
            yajl_gen_get_buf(g, &buf, &len);
            fwrite(buf, 1, len, stdout);
            yajl_gen_clear(g);
        }
    }

    stat = yajl_complete_parse(hand);

    if (stat != yajl_status_ok) {
        unsigned char * str = yajl_get_error(hand, 1, fileData, rd);
        fprintf(stderr, "%s", (const char *) str);
        yajl_free_error(hand, str);
        retval = 1;
    }

    yajl_gen_free(g);
    yajl_free(hand);

    return retval;
}

关于iphone - 是否有关于如何使用基于 C 的 YAJL 库解析简单 JSON 文件的简单示例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7050966/

相关文章:

ios - 如何在 swift 中定义自定义本地化常量

javascript - 如何通过 AJAX 显示 Rails 中的验证错误?

iphone - Xcode编译为较低版本的iOS

iphone - 免费桥接问题

ios - 如何同时使用水平和垂直 ScrollView (快速)

JSON指定 "any UNICODE character"吗?

python - 在 Flask 中获取数据 JSON

iphone - 我可以在 iOS 上使用 MongoDB 作为 CoreData 的替代品吗?

iphone - Objective-C for循环问题

iphone - 将 UITextField 添加到 UITableViewCell 仅在最后一个单元格中显示一个 textField