From cb3a6f8bb073629a9c0a58d62c374f1330e88ddb Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Tue, 5 Jun 2012 21:29:52 +0200 Subject: [PATCH] Pre-computing size of data file content area and publishing it to writers as Ecma119Image.filesrc_blocks. --- libisofs/ecma119.c | 29 +++++++++++++++++++------- libisofs/ecma119.h | 6 ++++++ libisofs/filesrc.c | 52 +++++++++++++++++++++++++++++++++++++++------- libisofs/filesrc.h | 9 ++++++++ 4 files changed, 80 insertions(+), 16 deletions(-) diff --git a/libisofs/ecma119.c b/libisofs/ecma119.c index 977c304..ac58eb3 100644 --- a/libisofs/ecma119.c +++ b/libisofs/ecma119.c @@ -1894,6 +1894,8 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img) target->gpt_backup_end = 0; target->gpt_max_entries = 0; + target->filesrc_blocks = 0; + /* * 2. Based on those options, create needed writers: iso, joliet... * Each writer inits its structures and stores needed info into @@ -1973,14 +1975,6 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img) } } - /* create writer for HFS+ structure */ - if (target->hfsplus) { - ret = hfsplus_writer_create(target); - if (ret < 0) { - goto target_cleanup; - } - } - /* create writer for ISO 9660:1999 structure */ if (target->iso1999) { ret = iso1999_writer_create(target); @@ -2008,6 +2002,16 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img) goto target_cleanup; } + /* create writer for HFS+/FAT structure */ + /* Impotant: It must be created directly before iso_file_src_writer_create. + */ + if (target->hfsplus) { + ret = hfsplus_writer_create(target); + if (ret < 0) { + goto target_cleanup; + } + } + /* create writer for file contents */ ret = iso_file_src_writer_create(target); if (ret < 0) { @@ -2077,6 +2081,15 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img) } + /* At least the FAT computation needs to know the size of filesrc data + in advance. So this call produces target->filesrc_blocks and + relative extent addresses, which get absolute in + filesrc_writer_compute_data_blocks(). + */ + ret = filesrc_writer_pre_compute(target->writers[file_src_writer_index]); + if (ret < 0) + goto target_cleanup; + /* * 3. * Call compute_data_blocks() in each Writer. diff --git a/libisofs/ecma119.h b/libisofs/ecma119.h index 9b2dc47..c4bdd30 100644 --- a/libisofs/ecma119.h +++ b/libisofs/ecma119.h @@ -835,6 +835,12 @@ struct ecma119_image */ uint8_t sys_area_as_written[16 * BLOCK_SIZE]; + /* Size of the filesrc_writer area (data file content). + This is available before any IsoImageWriter.compute_data_blocks() + is called. + */ + uint32_t filesrc_blocks; + }; #define BP(a,b) [(b) - (a) + 1] diff --git a/libisofs/filesrc.c b/libisofs/filesrc.c index 37683f5..42d87ee 100644 --- a/libisofs/filesrc.c +++ b/libisofs/filesrc.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2007 Vreixo Formoso - * 2010 - 2011 Thomas Schmitt + * 2010 - 2012 Thomas Schmitt * * This file is part of the libisofs project; you can redistribute it and/or * modify it under the terms of the GNU General Public License version 2 @@ -220,8 +220,7 @@ int is_ms_file(void *arg) return f->prev_img ? 0 : 1; } -static -int filesrc_writer_compute_data_blocks(IsoImageWriter *writer) +int filesrc_writer_pre_compute(IsoImageWriter *writer) { size_t i, size; Ecma119Image *t; @@ -233,12 +232,13 @@ int filesrc_writer_compute_data_blocks(IsoImageWriter *writer) } t = writer->target; + t->filesrc_blocks = 0; /* Normally reserve a single zeroed block for all files which have no block address: symbolic links, device files, empty data files. */ if (! t->old_empty) - t->curblock++; + t->filesrc_blocks++; /* on appendable images, ms files shouldn't be included */ if (t->appendable) { @@ -265,7 +265,7 @@ int filesrc_writer_compute_data_blocks(IsoImageWriter *writer) off_t section_size = iso_stream_get_size(file->stream); for (extent = 0; extent < file->nsections - 1; ++extent) { - file->sections[extent].block = t->curblock + extent * + file->sections[extent].block = t->filesrc_blocks + extent * (ISO_EXTENT_SIZE / BLOCK_SIZE); file->sections[extent].size = ISO_EXTENT_SIZE; section_size -= (off_t) ISO_EXTENT_SIZE; @@ -275,14 +275,20 @@ int filesrc_writer_compute_data_blocks(IsoImageWriter *writer) * final section */ if (section_size <= 0) { - file->sections[extent].block = t->empty_file_block; + /* Will become t->empty_file_block + in filesrc_writer_compute_data_blocks() + Special use of 0xffffffe0 to 0xffffffff is covered by + mspad_writer which enforces a minimum start of filesrc at + block 0x00000020. + */ + file->sections[extent].block = 0xffffffff; } else { file->sections[extent].block = - t->curblock + extent * (ISO_EXTENT_SIZE / BLOCK_SIZE); + t->filesrc_blocks + extent * (ISO_EXTENT_SIZE / BLOCK_SIZE); } file->sections[extent].size = (uint32_t)section_size; - t->curblock += DIV_UP(iso_file_src_get_size(file), BLOCK_SIZE); + t->filesrc_blocks += DIV_UP(iso_file_src_get_size(file), BLOCK_SIZE); } /* the list is only needed by this writer, store locally */ @@ -290,6 +296,36 @@ int filesrc_writer_compute_data_blocks(IsoImageWriter *writer) return ISO_SUCCESS; } +static +int filesrc_writer_compute_data_blocks(IsoImageWriter *writer) +{ + Ecma119Image *t; + int extent = 0; + size_t i; + IsoFileSrc *file; + IsoFileSrc **filelist; + + if (writer == NULL) { + return ISO_ASSERT_FAILURE; + } + t = writer->target; + filelist = (IsoFileSrc **) writer->data; + + /* Give all extent addresses their final absolute value */ + i = 0; + while ((file = filelist[i++]) != NULL) { + for (extent = 0; extent < file->nsections; ++extent) { + if (file->sections[extent].block == 0xffffffff) + file->sections[extent].block = t->empty_file_block; + else + file->sections[extent].block += t->curblock; + } + } + + t->curblock += t->filesrc_blocks; + return ISO_SUCCESS; +} + static int filesrc_writer_write_vol_desc(IsoImageWriter *writer) { diff --git a/libisofs/filesrc.h b/libisofs/filesrc.h index f0c8cdd..ee4c22a 100644 --- a/libisofs/filesrc.h +++ b/libisofs/filesrc.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2007 Vreixo Formoso + * 2012 Thomas Schmitt * * This file is part of the libisofs project; you can redistribute it and/or * modify it under the terms of the GNU General Public License version 2 @@ -93,4 +94,12 @@ off_t iso_file_src_get_size(IsoFileSrc *file); */ int iso_file_src_writer_create(Ecma119Image *target); +/** + * Determine number of filesrc blocks in the image and compute extent addresses + * relative to start of the file source writer area. + * filesrc_writer_compute_data_blocks() later makes them absolute. + */ +int filesrc_writer_pre_compute(IsoImageWriter *writer); + + #endif /*LIBISO_FILESRC_H_*/