Add 'r' raw command to unpack.
r dumps the raw format as seen in the file to stdout as readable text.
This commit is contained in:
parent
e0245db498
commit
8d59720195
3 changed files with 82 additions and 10 deletions
|
@ -73,7 +73,8 @@ huffman_build_tree(void **values, int count)
|
|||
}
|
||||
|
||||
void *
|
||||
huffman_lookup (struct huffman_node *tree, unsigned char *bits, int *bits_read)
|
||||
huffman_lookup (struct huffman_node *tree, unsigned char *bits, int *bits_read,
|
||||
bool print)
|
||||
{
|
||||
|
||||
struct huffman_node *node = tree;
|
||||
|
@ -88,8 +89,14 @@ huffman_lookup (struct huffman_node *tree, unsigned char *bits, int *bits_read)
|
|||
|
||||
if ((bits[0] << *bits_read % 8 & 0x80) == 0) {
|
||||
node = node->left;
|
||||
if (print) {
|
||||
putchar ('0');
|
||||
}
|
||||
} else {
|
||||
node = node->right;
|
||||
if (print) {
|
||||
putchar ('1');
|
||||
}
|
||||
}
|
||||
|
||||
(*bits_read)++;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include <stdbool.h>
|
||||
|
||||
struct huffman_node {
|
||||
int weight;
|
||||
|
@ -9,4 +10,4 @@ struct huffman_node {
|
|||
struct huffman_node *huffman_build_tree(void **values, int count);
|
||||
|
||||
void *huffman_lookup (struct huffman_node *tree, unsigned char *bits,
|
||||
int *bits_read);
|
||||
int *bits_read, bool print);
|
||||
|
|
80
unpack.c
80
unpack.c
|
@ -129,9 +129,9 @@ load_dictionary(FILE *source, char ***dictionary, int *dictionary_size,
|
|||
}
|
||||
|
||||
static int
|
||||
load_content_sets(FILE *stream, struct node **list,
|
||||
struct huffman_node *dictionary_tree, bool stats) {
|
||||
|
||||
load_content_sets(FILE *stream, struct node **list, int *node_count,
|
||||
struct huffman_node *dictionary_tree, bool stats, bool raw)
|
||||
{
|
||||
unsigned char *buf = malloc (sizeof (char *) * CHUNK);
|
||||
size_t read;
|
||||
struct node **nodes;
|
||||
|
@ -141,8 +141,10 @@ load_content_sets(FILE *stream, struct node **list,
|
|||
fread(&count, sizeof (unsigned char), 1, stream);
|
||||
|
||||
if (stats) {
|
||||
printf("node stats:\n");
|
||||
printf("\tnumber of nodes: %hd\n", count);
|
||||
printf ("node stats:\n");
|
||||
printf ("\tnumber of nodes: %hd\n", count);
|
||||
} else if (raw) {
|
||||
printf ("Nodes (%d entries):\n", count);
|
||||
}
|
||||
|
||||
|
||||
|
@ -173,19 +175,40 @@ load_content_sets(FILE *stream, struct node **list,
|
|||
node->paths = malloc (sizeof (char *) * 64);
|
||||
node->children = malloc (sizeof (struct node *) * 64);
|
||||
|
||||
if (raw) {
|
||||
printf ("\tNode:\n");
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (raw) {
|
||||
printf("\t\t");
|
||||
}
|
||||
|
||||
char *path = (char *) huffman_lookup (dictionary_tree,
|
||||
buf, &bits_read);
|
||||
buf, &bits_read,
|
||||
raw);
|
||||
buf = buf + bits_read / 8;
|
||||
bits_read = bits_read % 8;
|
||||
|
||||
if (path[0] == '\0') {
|
||||
if (raw) {
|
||||
printf("\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (raw) {
|
||||
printf (" :: ");
|
||||
}
|
||||
|
||||
struct node *child =
|
||||
(struct node *) huffman_lookup (tree, buf,
|
||||
&bits_read);
|
||||
&bits_read,
|
||||
raw);
|
||||
if (raw) {
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
buf = buf + bits_read / 8;
|
||||
bits_read = bits_read % 8;
|
||||
|
||||
|
@ -330,14 +353,46 @@ check_content_set (struct node *content_sets, const char *path)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_dictionary (char **dictionary, int dictionary_size)
|
||||
{
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv) {
|
||||
FILE *fp;
|
||||
char **dictionary;
|
||||
int dictionary_size;
|
||||
struct node *content_sets;
|
||||
int content_set_size;
|
||||
|
||||
bool stats = false;
|
||||
bool raw = false;
|
||||
bool dump = false;
|
||||
bool check = false;
|
||||
|
||||
|
@ -345,6 +400,7 @@ main(int argc, char **argv) {
|
|||
printf("usage: unpack [mode] [bin file]\n");
|
||||
printf("mode is one of:\n");
|
||||
printf("s - print stats for the binary content set blob\n");
|
||||
printf("r - display the raw binary as text\n");
|
||||
printf("d - dump the blob contents to stdout\n");
|
||||
printf("c - check if a path is allowed by the blob\n");
|
||||
printf("\n");
|
||||
|
@ -361,6 +417,9 @@ main(int argc, char **argv) {
|
|||
case 'd':
|
||||
dump = true;
|
||||
break;
|
||||
case 'r':
|
||||
raw = true;
|
||||
break;
|
||||
case 'c':
|
||||
check = true;
|
||||
if (argc != 4) {
|
||||
|
@ -385,7 +444,12 @@ main(int argc, char **argv) {
|
|||
struct huffman_node *dictionary_tree =
|
||||
huffman_build_tree ((void **) dictionary, dictionary_size);
|
||||
|
||||
if (load_content_sets(fp, &content_sets, dictionary_tree, stats)) {
|
||||
if (raw) {
|
||||
print_dictionary (dictionary, dictionary_size);
|
||||
}
|
||||
|
||||
if (load_content_sets(fp, &content_sets, &content_set_size,
|
||||
dictionary_tree, stats, raw)) {
|
||||
printf("node list parsing failed. exiting\n");
|
||||
return -1;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue