From 257b08bfcf3da76bb3cbd292272b3e41bda0f3a4 Mon Sep 17 00:00:00 2001 From: Vreixo Formoso Date: Tue, 18 Dec 2007 00:20:03 +0100 Subject: [PATCH] Code to compute position of directory records and path tables. --- src/ecma119.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++- src/ecma119.h | 12 ++++++ src/libisofs.h | 2 +- 3 files changed, 115 insertions(+), 3 deletions(-) diff --git a/src/ecma119.c b/src/ecma119.c index 45c0a0a..60c7dbf 100644 --- a/src/ecma119.c +++ b/src/ecma119.c @@ -13,11 +13,13 @@ #include "filesrc.h" #include "image.h" #include "writer.h" +#include "util.h" #include "libburn/libburn.h" #include #include +#include static void ecma119_image_free(Ecma119Image *t) @@ -37,11 +39,108 @@ void ecma119_image_free(Ecma119Image *t) free(t); } +/** + * Compute the size of a directory entry for a single node + */ +static +size_t calc_dirent_len(Ecma119Node *n) +{ + int ret = n->iso_name ? strlen(n->iso_name) + 33 : 34; + if (ret % 2) ret++; + return ret; +} + +/** + * Computes the total size of all directory entries of a single dir, + * acording to ECMA-119 6.8.1.1 + */ +static +size_t calc_dir_size(Ecma119Image *t, Ecma119Node *dir) +{ + size_t i, len; + + t->ndirs++; + + /* size of "." and ".." entries */ + len = 34 + 34; + for (i = 0; i < dir->info.dir.nchildren; ++i) { + Ecma119Node *child = dir->info.dir.children[i]; + size_t dirent_len = calc_dirent_len(child); + size_t remaining = BLOCK_SIZE - (len % BLOCK_SIZE); + if (dirent_len > remaining) { + /* child directory entry doesn't fit on block */ + len += remaining + dirent_len; + } else { + len += dirent_len; + } + } + return len; +} + +static +void calc_dir_pos(Ecma119Image *t, Ecma119Node *dir) +{ + size_t i, len; + + dir->info.dir.block = t->curblock; + len = calc_dir_size(t, dir); + t->curblock += div_up(len, BLOCK_SIZE); + for (i = 0; i < dir->info.dir.nchildren; i++) { + Ecma119Node *child = dir->info.dir.children[i]; + if (child->type == ECMA119_DIR) { + calc_dir_pos(t, child); + } + } +} + static int ecma119_writer_compute_data_blocks(IsoImageWriter *writer) { - //TODO to implement - return -1; + Ecma119Image *target; + Ecma119Node **pathlist; + uint32_t path_table_size; + size_t i, j, cur; + + if (writer == NULL) { + return ISO_MEM_ERROR; + } + + target = writer->target; + + /* compute position of directories */ + target->ndirs = 0; + calc_dir_pos(target, target->root); + + /* compute length of pathlist */ + pathlist = calloc(1, sizeof(void*) * target->ndirs); + if (pathlist == NULL) { + return ISO_MEM_ERROR; + } + pathlist[0] = target->root; + path_table_size = 10; /* root directory record */ + cur = 1; + for (i = 0; i < target->ndirs; i++) { + Ecma119Node *dir = pathlist[i]; + for (j = 0; j < dir->info.dir.nchildren; j++) { + Ecma119Node *child = dir->info.dir.children[j]; + if (child->type == ECMA119_DIR) { + size_t len = 8 + strlen(child->iso_name); + pathlist[cur++] = child; + path_table_size += len + len % 2; + } + } + } + + /* compute location for path tables */ + target->l_path_table_pos = target->curblock; + target->curblock += div_up(path_table_size, BLOCK_SIZE); + target->m_path_table_pos = target->curblock; + target->curblock += div_up(path_table_size, BLOCK_SIZE); + + /* ...and free path table cache, as we do not need it at all */ + free(pathlist); + + return ISO_SUCCESS; } static @@ -112,6 +211,7 @@ int ecma119_image_new(IsoImage *src, Ecma119WriteOpts *opts, iso_image_ref(src); target->iso_level = opts->level; + target->sort_files = opts->sort_files; target->now = time(NULL); diff --git a/src/ecma119.h b/src/ecma119.h index 76c8ccb..3a4571b 100644 --- a/src/ecma119.h +++ b/src/ecma119.h @@ -13,6 +13,8 @@ #include +#define BLOCK_SIZE 2048 + typedef struct ecma119_image Ecma119Image; typedef struct ecma119_node Ecma119Node; typedef struct Iso_File_Src IsoFileSrc; @@ -40,6 +42,8 @@ struct ecma119_image { // mode_t file_mode; // gid_t gid; // uid_t uid; + int sort_files; /**< if sort files or not. Sorting is based of + * the weight of each file */ time_t now; /**< Time at which writing began. */ @@ -52,6 +56,14 @@ struct ecma119_image { * size calculation. */ uint32_t curblock; + + /* + * number of dirs in ECMA-119 tree, computed together with dir position, + * and needed for path table computation in a efficient way + */ + size_t ndirs; + uint32_t l_path_table_pos; + uint32_t m_path_table_pos; size_t nwriters; IsoImageWriter **writers; diff --git a/src/libisofs.h b/src/libisofs.h index 99a830d..f5a3236 100644 --- a/src/libisofs.h +++ b/src/libisofs.h @@ -71,7 +71,7 @@ typedef struct { * its size. In those cases, we only copy 1 block of data. */ - //unsigned int sort_files:1; + unsigned int sort_files:1; /**< If files should be sorted based on their weight. */ // unsigned int default_mode:1; // /**<