in source/huffman_generator/generator.c [217:353]
int main(int argc, char *argv[]) {
if (argc != 4) {
fprintf(
stderr,
"generator expects 3 arguments: [input file] [output file] "
"[encoding name]\n"
"A function of the following signature will be exported:\n"
"struct aws_huffman_symbol_coder *[encoding name]_get_coder()\n");
return 1;
}
const char *input_file = argv[1];
const char *output_file = argv[2];
const char *decoder_name = argv[3];
if (read_code_points(input_file)) {
return 1;
}
struct huffman_node tree_root;
memset(&tree_root, 0, sizeof(struct huffman_node));
/* Populate the tree */
for (size_t i = 0; i < num_code_points; ++i) {
struct huffman_code_point *value = &code_points[i];
if (value->code.num_bits == 0) {
continue;
}
struct huffman_node *current = &tree_root;
uint8_t bit_idx = value->code.num_bits - 1;
while (1) {
struct huffman_code code = value->code;
code.bits >>= bit_idx;
code.num_bits = value->code.num_bits - bit_idx;
uint8_t encoded_bit = code.bits & 0x01;
assert(encoded_bit == 0 || encoded_bit == 1);
if (bit_idx == 0) {
/* Done traversing, add value as leaf */
assert(!current->children[encoded_bit]);
current->children[encoded_bit] = huffman_node_new_value(value);
break;
}
if (current->children[encoded_bit]) {
/* Not at the end yet, keep traversing */
current = current->children[encoded_bit];
} else {
/* Not at the end yet, but this is the first time down this
* path. */
struct huffman_node *new_node = huffman_node_new(code);
current->children[encoded_bit] = new_node;
current = new_node;
}
--bit_idx;
}
}
/* Open the file */
FILE *file = aws_fopen(output_file, "w");
if (!file) {
printf("Failed to open file '%s' for write.", output_file);
return 1;
}
/* Write the file/function header */
fprintf(
file,
"/**\n"
" * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n"
" * SPDX-License-Identifier: Apache-2.0.\n"
" */\n"
"\n"
"/* WARNING: THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. */\n"
"/* clang-format off */\n"
"\n"
"#include <aws/compression/huffman.h>\n"
"\n"
"static struct aws_huffman_code code_points[] = {\n");
for (size_t i = 0; i < num_code_points; ++i) {
struct huffman_code_point *cp = &code_points[i];
fprintf(
file,
" { .pattern = 0x%x, .num_bits = %u }, /* '%c' %u */\n",
cp->code.bits,
cp->code.num_bits,
isprint(cp->symbol) ? cp->symbol : ' ',
cp->symbol);
}
fprintf(
file,
"};\n"
"\n"
"static struct aws_huffman_code encode_symbol(uint8_t symbol, void "
"*userdata) {\n"
" (void)userdata;\n\n"
" return code_points[symbol];\n"
"}\n"
"\n"
"/* NOLINTNEXTLINE(readability-function-size) */\n"
"static uint8_t decode_symbol(uint32_t bits, uint8_t *symbol, void "
"*userdata) {\n"
" (void)userdata;\n\n");
/* Traverse the tree */
huffman_node_write_decode(&tree_root, file, 0);
/* Write the function footer & encode header */
fprintf(
file,
"}\n"
"\n"
"struct aws_huffman_symbol_coder *%s_get_coder(void) {\n"
"\n"
" static struct aws_huffman_symbol_coder coder = {\n"
" .encode = encode_symbol,\n"
" .decode = decode_symbol,\n"
" .userdata = NULL,\n"
" };\n"
" return &coder;\n"
"}\n",
decoder_name);
fclose(file);
huffman_node_clean_up(&tree_root);
return 0;
}