Pre-computing size of data file content area and publishing it to

writers as Ecma119Image.filesrc_blocks.
This commit is contained in:
Thomas Schmitt 2012-06-05 21:29:52 +02:00
parent a3285f6e5d
commit cb3a6f8bb0
4 changed files with 80 additions and 16 deletions

View File

@ -1894,6 +1894,8 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
target->gpt_backup_end = 0; target->gpt_backup_end = 0;
target->gpt_max_entries = 0; target->gpt_max_entries = 0;
target->filesrc_blocks = 0;
/* /*
* 2. Based on those options, create needed writers: iso, joliet... * 2. Based on those options, create needed writers: iso, joliet...
* Each writer inits its structures and stores needed info into * 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 */ /* create writer for ISO 9660:1999 structure */
if (target->iso1999) { if (target->iso1999) {
ret = iso1999_writer_create(target); ret = iso1999_writer_create(target);
@ -2008,6 +2002,16 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
goto target_cleanup; 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 */ /* create writer for file contents */
ret = iso_file_src_writer_create(target); ret = iso_file_src_writer_create(target);
if (ret < 0) { 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. * 3.
* Call compute_data_blocks() in each Writer. * Call compute_data_blocks() in each Writer.

View File

@ -835,6 +835,12 @@ struct ecma119_image
*/ */
uint8_t sys_area_as_written[16 * BLOCK_SIZE]; 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] #define BP(a,b) [(b) - (a) + 1]

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2007 Vreixo Formoso * 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 * 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 * 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; return f->prev_img ? 0 : 1;
} }
static int filesrc_writer_pre_compute(IsoImageWriter *writer)
int filesrc_writer_compute_data_blocks(IsoImageWriter *writer)
{ {
size_t i, size; size_t i, size;
Ecma119Image *t; Ecma119Image *t;
@ -233,12 +232,13 @@ int filesrc_writer_compute_data_blocks(IsoImageWriter *writer)
} }
t = writer->target; t = writer->target;
t->filesrc_blocks = 0;
/* Normally reserve a single zeroed block for all files which have /* Normally reserve a single zeroed block for all files which have
no block address: symbolic links, device files, empty data files. no block address: symbolic links, device files, empty data files.
*/ */
if (! t->old_empty) if (! t->old_empty)
t->curblock++; t->filesrc_blocks++;
/* on appendable images, ms files shouldn't be included */ /* on appendable images, ms files shouldn't be included */
if (t->appendable) { 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); off_t section_size = iso_stream_get_size(file->stream);
for (extent = 0; extent < file->nsections - 1; ++extent) { 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); (ISO_EXTENT_SIZE / BLOCK_SIZE);
file->sections[extent].size = ISO_EXTENT_SIZE; file->sections[extent].size = ISO_EXTENT_SIZE;
section_size -= (off_t) ISO_EXTENT_SIZE; section_size -= (off_t) ISO_EXTENT_SIZE;
@ -275,14 +275,20 @@ int filesrc_writer_compute_data_blocks(IsoImageWriter *writer)
* final section * final section
*/ */
if (section_size <= 0) { 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 { } else {
file->sections[extent].block = 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; 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 */ /* 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; 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 static
int filesrc_writer_write_vol_desc(IsoImageWriter *writer) int filesrc_writer_write_vol_desc(IsoImageWriter *writer)
{ {

View File

@ -1,5 +1,6 @@
/* /*
* Copyright (c) 2007 Vreixo Formoso * Copyright (c) 2007 Vreixo Formoso
* 2012 Thomas Schmitt
* *
* This file is part of the libisofs project; you can redistribute it and/or * 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 * 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); 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_*/ #endif /*LIBISO_FILESRC_H_*/