From 3262f44afbd8aab05eaca32134c44ef51656b223 Mon Sep 17 00:00:00 2001 From: James Bowes Date: Thu, 6 Sep 2012 11:51:37 -0300 Subject: [PATCH] Enhance 'r' command to lookup values in the huffman tree --- README.md | 3 +++ huffman.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ huffman.h | 2 ++ unpack.c | 44 ++++++++++++++++---------------------------- 4 files changed, 70 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index e8dac5b..ffbda9d 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,9 @@ etc): `./unpack s this-cert.bin` +To dump the raw packed file as text: + `./unpack r this-cert.bin` + To reconstruct the content sets and dump them to stdout: `./unpack d this-cert.bin` diff --git a/huffman.c b/huffman.c index edbbfd5..b8417b2 100644 --- a/huffman.c +++ b/huffman.c @@ -105,3 +105,52 @@ huffman_lookup (struct huffman_node *tree, unsigned char *bits, int *bits_read, } } } + +struct stack { + struct stack *next; + bool val; +}; + +static void +huffman_lookup_driver (struct huffman_node *tree, void *value, + struct stack *head, struct stack *cur) +{ + if (tree->value == value) { + struct stack *x = head->next; + while (x != NULL) { + if (x->val) { + putchar ('1'); + } else { + putchar ('0'); + } + x = x->next; + } + + return; + } + + struct stack *next = malloc (sizeof (struct stack)); + next->next = NULL; + cur->next = next; + + if (tree->left != NULL) { + next->val = false; + huffman_lookup_driver (tree->left, value, head, next); + } + if (tree->right != NULL) { + next->val = true; + huffman_lookup_driver (tree->right, value, head, next); + } + + cur->next = NULL; + free (next); +} + +// given a value, print its code to stdout. +void +huffman_reverse_lookup (struct huffman_node *tree, void *value) +{ + struct stack head; + head.next = NULL; + huffman_lookup_driver (tree, value, &head, &head); +} diff --git a/huffman.h b/huffman.h index c4b499d..1f5cc25 100644 --- a/huffman.h +++ b/huffman.h @@ -11,3 +11,5 @@ struct huffman_node *huffman_build_tree(void **values, int count); void *huffman_lookup (struct huffman_node *tree, unsigned char *bits, int *bits_read, bool print); + +void huffman_reverse_lookup (struct huffman_node *tree, void *value); diff --git a/unpack.c b/unpack.c index 77ccbfd..979c521 100644 --- a/unpack.c +++ b/unpack.c @@ -176,12 +176,14 @@ load_content_sets(FILE *stream, struct node **list, int *node_count, node->children = malloc (sizeof (struct node *) * 64); if (raw) { - printf ("\tNode:\n"); + printf (" Node - "); + huffman_reverse_lookup (tree, node); + printf (":\n"); } while (true) { if (raw) { - printf("\t\t"); + printf(" "); } char *path = (char *) huffman_lookup (dictionary_tree, @@ -192,13 +194,13 @@ load_content_sets(FILE *stream, struct node **list, int *node_count, if (path[0] == '\0') { if (raw) { - printf("\n"); + printf(" ()\n"); } break; } if (raw) { - printf (" :: "); + printf (" (%s) :: ", path); } struct node *child = @@ -354,33 +356,19 @@ check_content_set (struct node *content_sets, const char *path) } static void -print_dictionary (char **dictionary, int dictionary_size) +print_dictionary (char **dictionary, int dictionary_size, + struct huffman_node *dictionary_tree) { int i; printf ("Path Dictionary (%d entries):\n", dictionary_size); - for (i = 0; i < dictionary_size; i++) { - printf ("\t%s\n", dictionary[i]); - } -} - -static void -print_node (struct node *content_set) -{ - int i; - printf ("\tNode:\n"); - for (i = 0; i < content_set->count; i++) { - printf ("\t\t%s\n", content_set->paths[i]); - } -} - -static void -print_nodes (struct node **content_sets, int content_set_size) -{ - int i; - printf ("Node Dictionary (%d entries):\n", content_set_size); - for (i = 0; i < content_set_size; i++) { - print_node (content_sets[i]); + for (i = 0; i < dictionary_size - 1; i++) { + printf (" %s - ", dictionary[i]); + huffman_reverse_lookup (dictionary_tree, dictionary[i]); + printf("\n"); } + printf (" - "); + huffman_reverse_lookup (dictionary_tree, dictionary[i]); + printf ("\n"); } int @@ -445,7 +433,7 @@ main(int argc, char **argv) { huffman_build_tree ((void **) dictionary, dictionary_size); if (raw) { - print_dictionary (dictionary, dictionary_size); + print_dictionary (dictionary, dictionary_size, dictionary_tree); } if (load_content_sets(fp, &content_sets, &content_set_size,