/* This file is part of Nekopack.
Copyright (C) 2017 Jakob Tsar-Fox, All Rights Reserved.
Nekopack is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at
your option) any later version.
Nekopack is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with Nekopack. If not, see . */
#include
#include
#include
#include
#include
#include "decompress.h"
#include "extract.h"
#include "file.h"
#include "write.h"
/* Finds an eliF entry with the given key in a linked list and returns
the associated filename, removing it from the linked list. */
char *pop_file_name(uint32_t key, elif_node *root) {
char *file_name = NULL;
elif_node *current = root->next, *last = root;
for (;;) {
if (current->key == key) {
file_name = current->file_name;
last->next = current->next;
free(current);
break;
} else if (current->next == NULL) {
break;
} else {
last = current;
current = current->next;
}
}
return file_name;
}
/* Iterates through the linked list of file entries and writes every
entry to disk, according to information specified by the node. */
void write_files(file_node *file_root, elif_node *elif_root, Bytef *start) {
FILE *output;
file_node *current;
Bytef *compressed_buffer, *decompressed_buffer;
for (current = file_root->next; current != NULL; current = current->next) {
char *file_name = pop_file_name(current->key, elif_root);
if (file_name == NULL) {
fprintf(stderr, "File found without matching eliF entry.\n");
continue;
}
compressed_buffer = malloc(current->compressed_size);
for (int i = 0; i < current->segment_count; i++)
free(current->segments[i]);
free(current->segments);
/* memcpy(compressed_buffer, start + current->offset, */
/* current->decompressed_size); */
/* if (current->compressed) { */
/* fprintf(stderr, "Not implemented :^)\n"); // don't leave this in lol */
/* continue; */
/* } else { */
/* output = fopen(file_name, "wb+"); */
/* fwrite(compressed_buffer, current->compressed_size, 1, output); */
/* fclose(output); */
/* } */
free(compressed_buffer);
break;
}
}
/* Inserts an eliF entry at the end of a linked list. */
void defer_elif_node(elif_node *new, elif_node *root) {
elif_node *current = root;
for (;;) {
if (current->next == NULL) {
current->next = new;
break;
} else {
current = current->next;
}
}
}
/* Inserts a File entry node at the end of a linked list. */
void defer_file_node(file_node *new, file_node *root) {
file_node *current = root;
for (;;) {
if (current->next == NULL) {
current->next = new;
break;
} else {
current = current->next;
}
}
}
/* Iterates through the linked list and frees all entries. */
void free_elif_nodes(elif_node *base) {
if (base->next != NULL)
free_elif_nodes(base->next);
free(base->file_name);
free(base);
}
/* Iterates through the linked list and frees all entries. */
void free_file_nodes(file_node *base) {
if (base->next != NULL)
free_file_nodes(base->next);
free(base);
}
void test_elif_linked_list(elif_node *root) {
for (elif_node *current = root; current != NULL; current = current->next) {
printf("ELIF NODE\n---------\n");
printf("KEY: %" PRIx32 "\n", current->key);
printf("FILE_NAME: %s\n\n", current->file_name);
}
}
void test_file_linked_list(file_node *root) {
for (file_node *current = root; current != NULL; current = current->next) {
printf("FILE NODE\n---------\n");
printf("KEY: %" PRIx32 "\n\n", current->key);
}
}