Enhance 'r' command to lookup values in the huffman tree
This commit is contained in:
parent
8d59720195
commit
3262f44afb
4 changed files with 70 additions and 28 deletions
|
@ -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`
|
||||||
|
|
49
huffman.c
49
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);
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
44
unpack.c
44
unpack.c
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue