Enhance 'r' command to lookup values in the huffman tree

This commit is contained in:
James Bowes 2012-09-06 11:51:37 -03:00
parent 8d59720195
commit 3262f44afb
4 changed files with 70 additions and 28 deletions

View file

@ -56,6 +56,9 @@ etc):
`./unpack s this-cert.bin` `./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: To reconstruct the content sets and dump them to stdout:
`./unpack d this-cert.bin` `./unpack d this-cert.bin`

View file

@ -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);
}

View file

@ -11,3 +11,5 @@ struct huffman_node *huffman_build_tree(void **values, int count);
void *huffman_lookup (struct huffman_node *tree, unsigned char *bits, void *huffman_lookup (struct huffman_node *tree, unsigned char *bits,
int *bits_read, bool print); int *bits_read, bool print);
void huffman_reverse_lookup (struct huffman_node *tree, void *value);

View file

@ -176,12 +176,14 @@ load_content_sets(FILE *stream, struct node **list, int *node_count,
node->children = malloc (sizeof (struct node *) * 64); node->children = malloc (sizeof (struct node *) * 64);
if (raw) { if (raw) {
printf ("\tNode:\n"); printf (" Node - ");
huffman_reverse_lookup (tree, node);
printf (":\n");
} }
while (true) { while (true) {
if (raw) { if (raw) {
printf("\t\t"); printf(" ");
} }
char *path = (char *) huffman_lookup (dictionary_tree, 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 (path[0] == '\0') {
if (raw) { if (raw) {
printf("\n"); printf(" (<end>)\n");
} }
break; break;
} }
if (raw) { if (raw) {
printf (" :: "); printf (" (%s) :: ", path);
} }
struct node *child = struct node *child =
@ -354,33 +356,19 @@ check_content_set (struct node *content_sets, const char *path)
} }
static void static void
print_dictionary (char **dictionary, int dictionary_size) print_dictionary (char **dictionary, int dictionary_size,
struct huffman_node *dictionary_tree)
{ {
int i; int i;
printf ("Path Dictionary (%d entries):\n", dictionary_size); printf ("Path Dictionary (%d entries):\n", dictionary_size);
for (i = 0; i < dictionary_size; i++) { for (i = 0; i < dictionary_size - 1; i++) {
printf ("\t%s\n", dictionary[i]); printf (" %s - ", dictionary[i]);
} huffman_reverse_lookup (dictionary_tree, dictionary[i]);
} printf("\n");
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]);
} }
printf (" <end of node indicator> - ");
huffman_reverse_lookup (dictionary_tree, dictionary[i]);
printf ("\n");
} }
int int
@ -445,7 +433,7 @@ main(int argc, char **argv) {
huffman_build_tree ((void **) dictionary, dictionary_size); huffman_build_tree ((void **) dictionary, dictionary_size);
if (raw) { if (raw) {
print_dictionary (dictionary, dictionary_size); print_dictionary (dictionary, dictionary_size, dictionary_tree);
} }
if (load_content_sets(fp, &content_sets, &content_set_size, if (load_content_sets(fp, &content_sets, &content_set_size,