diff --git a/libisofs/trunk/CONTRIBUTORS b/libisofs/trunk/CONTRIBUTORS index c774a038..7c150504 100644 --- a/libisofs/trunk/CONTRIBUTORS +++ b/libisofs/trunk/CONTRIBUTORS @@ -1,2 +1,3 @@ Joe Neeman Philippe Rouquier +David Mohr diff --git a/libisofs/trunk/libisofs/ecma119.c b/libisofs/trunk/libisofs/ecma119.c index a1ac6810..f0f85484 100755 --- a/libisofs/trunk/libisofs/ecma119.c +++ b/libisofs/trunk/libisofs/ecma119.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "ecma119.h" #include "ecma119_tree.h" @@ -27,8 +28,6 @@ bs_get_size(struct burn_source *bs); static void bs_free_data(struct burn_source *bs); -typedef void (*write_fn)(struct ecma119_write_target*, uint8_t*); - /* return true if the given state is only required for Joliet volumes */ static int is_joliet_state(enum ecma119_write_state); @@ -42,15 +41,15 @@ write_data_chunk(struct ecma119_write_target *t, uint8_t *buf); /* writing functions. All these functions assume the buf is large enough */ static void -write_pri_vol_desc(struct ecma119_write_target *t, uint8_t *buf); +write_pri_vol_desc(struct ecma119_write_target *t, uint8_t *buf, va_list params); static void -write_vol_desc_terminator(struct ecma119_write_target *t, uint8_t *buf); +write_vol_desc_terminator(struct ecma119_write_target *t, uint8_t *buf, va_list params); static void write_path_table(struct ecma119_write_target *t, int l_type, uint8_t *buf); static void -write_l_path_table(struct ecma119_write_target *t, uint8_t *buf); +write_l_path_table(struct ecma119_write_target *t, uint8_t *buf, va_list params); static void -write_m_path_table(struct ecma119_write_target *t, uint8_t *buf); +write_m_path_table(struct ecma119_write_target *t, uint8_t *buf, va_list params); static void write_one_dir_record(struct ecma119_write_target *t, struct ecma119_tree_node *dir, @@ -61,7 +60,7 @@ write_one_dir(struct ecma119_write_target *t, struct ecma119_tree_node *dir, uint8_t *buf); static void -write_dirs(struct ecma119_write_target *t, uint8_t *buf); +write_dirs(struct ecma119_write_target *t, uint8_t *buf, va_list params); /* wrapper functions for writing */ static void wr_system_area(struct ecma119_write_target*, uint8_t*); @@ -72,7 +71,7 @@ static void wr_m_path_table(struct ecma119_write_target*, uint8_t*); static void wr_dir_records(struct ecma119_write_target*, uint8_t*); static void wr_files(struct ecma119_write_target*, uint8_t*); -static const write_fn writers[] = +static const write_fn_wrap writers[] = { NULL, wr_system_area, @@ -391,7 +390,23 @@ wr_m_path_table(struct ecma119_write_target *t, uint8_t *buf) static void wr_dir_records(struct ecma119_write_target *t, uint8_t *buf) { - ecma119_start_chunking(t, write_dirs, t->total_dir_size, buf); + int i; + int j; + size_t size = 0; + size_t dir_size; + struct ecma119_tree_node *dir; + for (i = j = 0; j < t->dirlist_len; j++) { + dir = t->dirlist[j]; + dir_size = dir->dir.len + dir->dir.CE_len; + if (size + dir_size > t->block_size) { + /* we are exceeding a logical block now, + * so write all the directory records so far */ + ecma119_start_chunking(t, write_dirs, size, buf, i, j-1); + i = j; + size = 0; + } + size += dir_size; + } } static void @@ -427,7 +442,7 @@ wr_files(struct ecma119_write_target *t, uint8_t *buf) } static void -write_pri_vol_desc(struct ecma119_write_target *t, uint8_t *buf) +write_pri_vol_desc(struct ecma119_write_target *t, uint8_t *buf, va_list params) { struct ecma119_pri_vol_desc *vol = (struct ecma119_pri_vol_desc*)buf; struct iso_volume *volume = t->volset->volume[t->volnum]; @@ -469,7 +484,7 @@ write_pri_vol_desc(struct ecma119_write_target *t, uint8_t *buf) } static void -write_vol_desc_terminator(struct ecma119_write_target *t, uint8_t *buf) +write_vol_desc_terminator(struct ecma119_write_target *t, uint8_t *buf, va_list params) { struct ecma119_vol_desc_terminator *vol = (struct ecma119_vol_desc_terminator*) buf; @@ -507,13 +522,13 @@ write_path_table(struct ecma119_write_target *t, int l_type, uint8_t *buf) } static void -write_l_path_table(struct ecma119_write_target *t, uint8_t *buf) +write_l_path_table(struct ecma119_write_target *t, uint8_t *buf, va_list params) { write_path_table(t, 1, buf); } static void -write_m_path_table(struct ecma119_write_target *t, uint8_t *buf) +write_m_path_table(struct ecma119_write_target *t, uint8_t *buf, va_list params) { write_path_table(t, 0, buf); } @@ -597,14 +612,19 @@ write_one_dir(struct ecma119_write_target *t, } static void -write_dirs(struct ecma119_write_target *t, uint8_t *buf) +write_dirs(struct ecma119_write_target *t, uint8_t *buf, va_list params) { - size_t i; + int i,start,end; struct ecma119_tree_node *dir; - for (i = 0; i < t->dirlist_len; i++) { + start = va_arg(params, int); + end = va_arg(params, int); + assert(start >= 0); + assert(end < t->dirlist_len); + + for (i = start; i < end; i++) { dir = t->dirlist[i]; write_one_dir(t, dir, buf); - buf += round_up(dir->dir.len + dir->dir.CE_len, t->block_size); + buf += dir->dir.len + dir->dir.CE_len; } } @@ -612,9 +632,13 @@ void ecma119_start_chunking(struct ecma119_write_target *t, write_fn writer, off_t data_size, - uint8_t *buf) + uint8_t *buf, + ...) { + va_list params; + va_start(params, buf); if (data_size != t->state_data_size) { + /* FIXME: are we sure that roundup works as expected? */ data_size = round_up(data_size, t->block_size); t->state_data = realloc(t->state_data, data_size); t->state_data_size = data_size; @@ -622,8 +646,9 @@ ecma119_start_chunking(struct ecma119_write_target *t, memset(t->state_data, 0, t->state_data_size); t->state_data_off = 0; t->state_data_valid = 1; - writer(t, t->state_data); + writer(t, t->state_data, params); write_data_chunk(t, buf); + va_end(params); } static void diff --git a/libisofs/trunk/libisofs/ecma119.h b/libisofs/trunk/libisofs/ecma119.h index 79505509..0ff5eede 100755 --- a/libisofs/trunk/libisofs/ecma119.h +++ b/libisofs/trunk/libisofs/ecma119.h @@ -258,10 +258,14 @@ struct ecma119_path_table_record * rather than block-by-block. This creates a buffer of size \p size, passes * it to the given writer, then hands out block-sized chunks. */ +typedef void (*write_fn)(struct ecma119_write_target*, uint8_t*, va_list); +typedef void (*write_fn_wrap)(struct ecma119_write_target*, uint8_t*); + void ecma119_start_chunking(struct ecma119_write_target *t, - void (*)(struct ecma119_write_target*, uint8_t*), + write_fn writer, off_t size, - uint8_t *buf); + uint8_t *buf, + ...); #endif /* LIBISO_ECMA119_H */