/* * Normally enums are required to be ascending in the schema and * therefore there is no need to sort enums. If not, we export them in * the order defined anyway becuase there is no well-defined ordering * and blindly sorting the content would just loose more information. * * In conclusion: find by enum value is only support when enums are * defined in consequtive order. * * refers to: `opts->ascending_enum` * * `size` must hold the maximum buffer size. * Returns intput buffer if successful and updates size argument. */ void *fb_codegen_bfbs_to_buffer(fb_options_t *opts, fb_schema_t *S, void *buffer, size_t *size) { flatcc_builder_t builder, *B; B = &builder; flatcc_builder_init(B); export_schema(B, opts, S); if (!flatcc_builder_copy_buffer(B, buffer, *size)) { goto done; } sort_fields(buffer); done: *size = flatcc_builder_get_buffer_size(B); flatcc_builder_clear(B); return buffer; }
/* * Like to_buffer, but returns allocated buffer. * Updates size argument with buffer size if not null. * Returned buffer must be deallocatd with `free`. * The buffer is malloc aligned which should suffice for reflection buffers. */ void *fb_codegen_bfbs_alloc_buffer(fb_options_t *opts, fb_schema_t *S, size_t *size) { flatcc_builder_t builder, *B; void *buffer = 0; B = &builder; flatcc_builder_init(B); if (export_schema(B, opts, S)) { goto done; } if (!(buffer = flatcc_builder_finalize_buffer(B, size))) { goto done; } sort_fields(buffer); done: flatcc_builder_clear(B); return buffer; }
// TODO: // when running benchmark with the wrong size argument (output size // instead of input size), the warmup loop iterates indefinitely in the // first iteration. This suggests there is an end check missing somwhere // and this needs to be debugged. The input size as of this writing is 701 // bytes, and the output size is 288 bytes. int test_parse() { #if FLATCC_BENCHMARK double t1, t2; int i; int rep = 1000000; int warmup_rep = 1000000; #endif const char *buf; void *flatbuffer = 0; size_t in_size, out_size; flatcc_json_parser_t ctx; flatcc_builder_t builder; flatcc_builder_t *B = &builder; int ret = -1; int flags = 0; const char *filename = "monsterdata_test.golden"; flatcc_builder_init(B); buf = readfile(filename, FILE_SIZE_MAX, &in_size); if (!buf) { fprintf(stderr, "%s: could not read input json file\n", filename); return -1; } if (monster_test_parse_json(B, &ctx, buf, in_size, flags)) { goto failed; } fprintf(stderr, "%s: successfully parsed %d lines\n", filename, ctx.line); flatbuffer = flatcc_builder_finalize_buffer(B, &out_size); hexdump("parsed monsterdata_test.golden", flatbuffer, out_size, stdout); fprintf(stderr, "input size: %lu, output size: %lu\n", (unsigned long)in_size, (unsigned long)out_size); verify_parse(flatbuffer); flatcc_builder_reset(B); #if FLATCC_BENCHMARK fprintf(stderr, "Now warming up\n"); for (i = 0; i < warmup_rep; ++i) { if (monster_test_parse_json(B, &ctx, buf, in_size, flags)) { goto failed; } flatcc_builder_reset(B); } fprintf(stderr, "Now benchmarking\n"); t1 = elapsed_realtime(); for (i = 0; i < rep; ++i) { if (monster_test_parse_json(B, &ctx, buf, in_size, flags)) { goto failed; } flatcc_builder_reset(B); } t2 = elapsed_realtime(); printf("----\n"); show_benchmark(BENCH_TITLE " C generated JSON parse " COMPILE_TYPE, t1, t2, in_size, rep, "1M"); #endif ret = 0; done: if (flatbuffer) { free(flatbuffer); } if (buf) { free((void *)buf); } flatcc_builder_clear(B); return ret; failed: fprintf(stderr, "%s:%d:%d: %s\n", filename, (int)ctx.line, (int)(ctx.error_loc - ctx.line_start + 1), flatcc_json_parser_error_string(ctx.error)); goto done; }