Hadoopのサブプロジェクト(だった)のavroシリアライザを使ってみる

schema.jsonを作成

{
    "type": "record",
    "name": "Test",
    "fields": [
        {
            "name": "ID",
            "type": "long"
        },
        {
            "name": "Name",
            "type": "string"
        }
    ]
}

テストプログラムを作成

#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <unistd.h>
#include <avro.h>

// schema.jsonからavroスキーマを構築する
avro_schema_t init_schema(void) {
    FILE *fp;
    char schema_text[8192];
    size_t schema_text_len;

    avro_schema_t schema;
    avro_schema_error_t schema_error;

    if(!(fp = fopen("schema.json", "r"))) {
        fprintf(stderr, "cannot open schema");
        exit(1);
    }

    schema_text_len = fread(schema_text, sizeof(schema_text), fp);
    schema_text_len = avro_schema_from_json(schema_text, sizeof(schema_text), schema, schema_error)

    return schema;
}

int test_write(avro_schema_t schema, int64_t _id, const char* _name) {
    size_t writer_len;

    avro_file_writer_t writer;
    avro_datum_t data_test;
    avro_datum_t data_test_id;
    avro_datum_t data_test_name;

    unlink("test.db");

    writer_len = avro_file_writer_create("test.db", schema, writer)

    if(writer_len) {
        fprintf(stderr, "writer open error");
        exit(1);
    }

    data_test = avro_record("Test", NULL);
    data_test_id = avro_int64(_id);
    data_test_name = avro_string(_name);

    if(avro_record_set(data_test, "ID", data_test_id) || avro_record_set(data_test, "Name", data_test_name)) {
        fprintf(stderr, "record set error");
        exit(1);
    }
    if(avro_file_writer_append(writer, data_test)) {
        fprintf(stderr, "record write error");
        exit(1);
    }

    avro_file_writer_close(writer);

    avro_datum_decref(data_test_name);
    avro_datum_decref(data_test_id);
    avro_datum_decref(data_test);

    return 0;
}
void test_read(avro_schema_t schema) {
    size_t reader_len;
    avro_file_reader_t reader;

    avro_datum_t data_test;
    avro_datum_t data_test_id;
    avro_datum_t data_test_name;
    avro_file_reader("test.db", reader)

    if((reader_len = avro_file_reader_read(reader, schema, data_test))) {
        fprintf(stderr, "cannnot read schema");
        exit(1);
    }

    if(avro_record_get(data_test, "ID", data_test_id) == 0) {
        int64_t id;
        avro_int64_get(data_test_id, id)

        fprintf(stdout, "%"PRId64"\r\n", id);
    }
    if(avro_record_get(data_test, "Name", data_test_name) == 0) {
        char *name;
        avro_string_get(data_test_name, name)

        fprintf(stdout, "%s\r\n", name);
    }

    avro_datum_decref(data_test_name);
    avro_datum_decref(data_test_id);
    avro_datum_decref(data_test);

    avro_file_reader_close(reader);
}

int main(int argc, char* argv[]) {
    avro_schema_t schema;
    schema = init_schema();

    int id = atoi(argv[1]);
    char* name = argv[2];

    test_write(schema, (int64_t)id, (const char*)name);
    test_read(schema);

    return 0;
}

作成後

gcc -lavro avro.c -o test_client

でコンパイルして

./test_client 1 hoge

と実行するとtest.dbにavroシリアライズされたデータが作成される