aboutsummaryrefslogtreecommitdiff
path: root/flatcc/test/emit_test/emit_test.c
blob: ddb973dde3e34a94ac2bdffc443f8971f1ca41d5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include <stdio.h>
#include <assert.h>
#include "emit_test_builder.h"
#include "flatcc/support/hexdump.h"
#include "flatcc/portable/pparsefp.h"

#define test_assert(x) do { if (!(x)) { assert(0); return -1; }} while(0)
/* Direct floating point comparisons are not always directly comparable,
 * especially not for GCC 32-bit compilers. */
#define test_assert_floateq(x, y) test_assert(parse_float_is_equal((x), (y)))
#define test_assert_doubleeq(x, y) test_assert(parse_double_is_equal((x), (y)))

int dbg_emitter(void *emit_context,
        const flatcc_iovec_t *iov, int iov_count,
        flatbuffers_soffset_t offset, size_t len)
{
    int i;

    (void)emit_context;

    printf("dbg: emit: iov_count: %d, offset: %ld, len: %ld\n",
            (int)iov_count, (long)offset, (long)len);

    for (i = 0; i < iov_count; ++i) {
        if (iov[i].iov_base == flatcc_builder_padding_base) {
            printf("dbg:  padding at: %ld, len: %ld\n",
                    (long)offset, (long)iov[i].iov_len);
        }
        if (iov[i].iov_base == 0) {
            printf("dbg:  null vector reserved at: %ld, len: %ld\n",
                    (long)offset, (long)iov[i].iov_len);
        }
        offset += (flatbuffers_soffset_t)iov[i].iov_len;
    }
    return 0;
}

int debug_test(void)
{
    flatcc_builder_t builder, *B;
    float x[10] = { 0 };

    B = &builder;
    printf("dbg: output is generated by a custom emitter that doesn't actually build a buffer\n");
    flatcc_builder_custom_init(B, dbg_emitter, 0, 0, 0);
    /* We can create a null vector because we have a custom emitter. */
    main_create_as_root(B, 42, 1, flatbuffers_float_vec_create(B, x, 10));
    flatcc_builder_clear(B);
    return 0;
}

/*
 * this assumes a very simple schema:
 * "table { time: long; device: ubyte; samples: [float]; }"
 */
int emit_test(void)
{
    /*
     * Note that there is some apparently unnecessary padding after 0x01
     * which is caused by the end of the buffer content excluding
     * vtables is forced to buffer alignment due to clustering and
     * because alignment happens before the buffer is fully generated.
     */
    unsigned char expect[] =
#if FLATBUFFERS_PROTOCOL_IS_LE
        "\x04\x00\x00\x00\xd4\xff\xff\xff\x2a\x00\x00\x00\x00\x00\x00\x00"
        "\x0c\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00"
        "\x00\x00\x80\x3f\xcd\xcc\x8c\x3f\x9a\x99\x99\x3f\x66\x66\xa6\x3f"
        "\x0a\x00\x11\x00\x04\x00\x10\x00\x0c\x00";
#else

        "\x00\x00\x00\x04\xff\xff\xff\xd4\x00\x00\x00\x00\x00\x00\x00\x2a"
        "\x00\x00\x00\x0c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04"
        "\x3f\x80\x00\x00\x3f\x8c\xcc\xcd\x3f\x99\x99\x9a\x3f\xa6\x66\x66"
        "\x00\x0a\x00\x11\x00\x04\x00\x10\x00\x0c";
#endif

    size_t size;
    uint8_t *buf;
    flatcc_emitter_t *E;
    flatcc_builder_t builder, *B;
    flatbuffers_float_vec_ref_t vref;
    float data[4] = { 1.0f, 1.1f, 1.2f, 1.3f };

    main_table_t mt;
    int64_t time;

    (void)expect;
    B = &builder;

    flatcc_builder_init(B);

    /* Get the default emitter. */
    E = flatcc_builder_get_emit_context(B);

    vref = flatbuffers_float_vec_create(B, data, 4);
    //vref = 0;
    main_create_as_root(B, 42, 1, vref);

    /* We could also have used flatcc_builder API wrapper for this. */
    buf = flatcc_emitter_get_direct_buffer(E, &size);
    if (!buf) {
        return -1;
    }
    test_assert(size == flatcc_emitter_get_buffer_size(E));
    test_assert(size == flatcc_builder_get_buffer_size(B));

    fprintf(stderr, "buffer size: %d\n", (int)size);
    hexdump("emit_test", buf, size, stderr);

    test_assert(size == 58);
    test_assert(sizeof(expect) - 1 == size);
    test_assert(0 == memcmp(buf, expect, size));

    mt = main_as_root(buf);
    time = main_time(mt);
    test_assert(time == 42);
    test_assert(main_device(mt) == 1);
    test_assert(flatbuffers_float_vec_len(main_samples(mt)) == 4);
    test_assert_floateq(flatbuffers_float_vec_at(main_samples(mt), 2), 1.2f);

    /* We use get_direct_buffer, so we can't clear the builder until last. */
    flatcc_builder_clear(B);
    return 0;
}

int main(int argc, char *argv[])
{
    int ret = 0;

    (void)argc;
    (void)argv;

    ret |= debug_test();
    ret |= emit_test();
    return ret;
}