diff --git a/src/ecma119.c b/src/ecma119.c index 7bd5579..c1f672b 100644 --- a/src/ecma119.c +++ b/src/ecma119.c @@ -136,10 +136,12 @@ int ecma119_writer_compute_data_blocks(IsoImageWriter *writer) target = writer->target; /* compute position of directories */ + iso_msg_debug(target->image, "Computing position of dir structure"); target->ndirs = 0; calc_dir_pos(target, target->root); /* compute length of pathlist */ + iso_msg_debug(target->image, "Computing length of pathlist"); path_table_size = calc_path_table_size(target->root); /* compute location for path tables */ @@ -529,6 +531,7 @@ int ecma119_writer_create(Ecma119Image *target) /* add this writer to image */ target->writers[target->nwriters++] = writer; + iso_msg_debug(target->image, "Creating low level ECMA-119 tree..."); ret = ecma119_tree_create(target); if (ret < 0) { return ret; diff --git a/src/ecma119_tree.c b/src/ecma119_tree.c index ea479e5..bab27ee 100644 --- a/src/ecma119_tree.c +++ b/src/ecma119_tree.c @@ -25,6 +25,7 @@ int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name) { int ret; char *ascii_name; + char *isoname = NULL; if (iso->name == NULL) { /* it is not necessarily an error, it can be the root */ @@ -41,19 +42,28 @@ int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name) // TODO add support for relaxed constraints if (iso->type == LIBISO_DIR) { if (img->iso_level == 1) { - iso_dirid(ascii_name, 8); + isoname = iso_1_dirid(ascii_name); } else { - iso_dirid(ascii_name, 31); + isoname = iso_2_dirid(ascii_name); } } else { if (img->iso_level == 1) { - iso_1_fileid(ascii_name); + isoname = iso_1_fileid(ascii_name); } else { - iso_2_fileid(ascii_name); + isoname = iso_2_fileid(ascii_name); } } - *name = ascii_name; - return ISO_SUCCESS; + free(ascii_name); + if (isoname != NULL) { + *name = isoname; + return ISO_SUCCESS; + } else { + /* + * only possible if mem error, as check for empty names is done + * in public tree + */ + return ISO_MEM_ERROR; + } } static diff --git a/src/util.c b/src/util.c index 1d8b96c..e850388 100644 --- a/src/util.c +++ b/src/util.c @@ -202,62 +202,87 @@ static int valid_a_char(char c) || (c >= 'A' && c <= 'Z') || (c == '_'); } -void iso_dirid(char *src, int maxlen) +static +char *iso_dirid(const char *src, int size) { size_t len, i; - + char name[32]; + len = strlen(src); - if (len > maxlen) { - src[maxlen] = '\0'; - len = maxlen; + if (len > size) { + len = size; } for (i = 0; i < len; i++) { char c = toupper(src[i]); - src[i] = valid_d_char(c) ? c : '_'; + name[i] = valid_d_char(c) ? c : '_'; } + + name[len] = '\0'; + return strdup(name); } -void iso_1_fileid(char *src) +char *iso_1_dirid(const char *src) { - char *dot; /* Position of the last dot in the filename, will be used to - calculate lname and lext. */ - int lname, lext, pos, i; + return iso_dirid(src, 8); +} +char *iso_2_dirid(const char *src) +{ + return iso_dirid(src, 31); +} + +char *iso_1_fileid(const char *src) +{ + char *dot; /* Position of the last dot in the filename, will be used + to calculate lname and lext. */ + int lname, lext, pos, i; + char dest[13]; /* 13 = 8 (name) + 1 (.) + 3 (ext) + 1 (\0) */ + + if (src == NULL) { + return NULL; + } dot = strrchr(src, '.'); lext = dot ? strlen(dot + 1) : 0; lname = strlen(src) - lext - (dot ? 1 : 0); - /* If we can't build a filename, return. */ + /* If we can't build a filename, return NULL. */ if (lname == 0 && lext == 0) { - return; + return NULL; } pos = 0; + /* Convert up to 8 characters of the filename. */ for (i = 0; i < lname && i < 8; i++) { char c = toupper(src[i]); - src[pos++] = valid_d_char(c) ? c : '_'; + + dest[pos++] = valid_d_char(c) ? c : '_'; } /* This dot is mandatory, even if there is no extension. */ - src[pos++] = '.'; + dest[pos++] = '.'; /* Convert up to 3 characters of the extension, if any. */ for (i = 0; i < lext && i < 3; i++) { char c = toupper(src[lname + 1 + i]); - src[pos++] = valid_d_char(c) ? c : '_'; + + dest[pos++] = valid_d_char(c) ? c : '_'; } - src[pos] = '\0'; + + dest[pos] = '\0'; + return strdup(dest); } -void iso_2_fileid(char *src) +char *iso_2_fileid(const char *src) { char *dot; int lname, lext, lnname, lnext, pos, i; + char dest[32]; /* 32 = 30 (name + ext) + 1 (.) + 1 (\0) */ - if (!src) - return; + if (src == NULL) { + return NULL; + } dot = strrchr(src, '.'); @@ -280,23 +305,124 @@ void iso_2_fileid(char *src) } if (lnname == 0 && lnext == 0) { - return; + return NULL; } pos = 0; + /* Convert up to lnname characters of the filename. */ for (i = 0; i < lnname; i++) { char c = toupper(src[i]); - src[pos++] = valid_d_char(c) ? c : '_'; + + dest[pos++] = valid_d_char(c) ? c : '_'; } - src[pos++] = '.'; + dest[pos++] = '.'; + /* Convert up to lnext characters of the extension, if any. */ for (i = 0; i < lnext; i++) { char c = toupper(src[lname + 1 + i]); - src[pos++] = valid_d_char(c) ? c : '_'; + + dest[pos++] = valid_d_char(c) ? c : '_'; } - src[pos] = '\0'; + dest[pos] = '\0'; + return strdup(dest); } + +//void iso_dirid(char *src, int maxlen) +//{ +// size_t len, i; +// +// len = strlen(src); +// if (len > maxlen) { +// src[maxlen] = '\0'; +// len = maxlen; +// } +// for (i = 0; i < len; i++) { +// char c = toupper(src[i]); +// src[i] = valid_d_char(c) ? c : '_'; +// } +//} + +//void iso_1_fileid(char *src) +//{ +// char *dot; /* Position of the last dot in the filename, will be used to +// calculate lname and lext. */ +// int lname, lext, pos, i; +// +// dot = strrchr(src, '.'); +// +// lext = dot ? strlen(dot + 1) : 0; +// lname = strlen(src) - lext - (dot ? 1 : 0); +// +// /* If we can't build a filename, return. */ +// if (lname == 0 && lext == 0) { +// return; +// } +// +// pos = 0; +// /* Convert up to 8 characters of the filename. */ +// for (i = 0; i < lname && i < 8; i++) { +// char c = toupper(src[i]); +// src[pos++] = valid_d_char(c) ? c : '_'; +// } +// +// /* This dot is mandatory, even if there is no extension. */ +// src[pos++] = '.'; +// +// /* Convert up to 3 characters of the extension, if any. */ +// for (i = 0; i < lext && i < 3; i++) { +// char c = toupper(src[lname + 1 + i]); +// src[pos++] = valid_d_char(c) ? c : '_'; +// } +// src[pos] = '\0'; +//} +// +//void iso_2_fileid(char *src) +//{ +// char *dot; +// int lname, lext, lnname, lnext, pos, i; +// +// if (!src) +// return; +// +// dot = strrchr(src, '.'); +// +// /* +// * Since the maximum length can be divided freely over the name and +// * extension, we need to calculate their new lengths (lnname and +// * lnext). If the original filename is too long, we start by trimming +// * the extension, but keep a minimum extension length of 3. +// */ +// if (dot == NULL || *(dot + 1) == '\0') { +// lname = strlen(src); +// lnname = (lname > 30) ? 30 : lname; +// lext = lnext = 0; +// } else { +// lext = strlen(dot + 1); +// lname = strlen(src) - lext - 1; +// lnext = (strlen(src) > 31 && lext > 3) +// ? (lname < 27 ? 30 - lname : 3) : lext; +// lnname = (strlen(src) > 31) ? 30 - lnext : lname; +// } +// +// if (lnname == 0 && lnext == 0) { +// return; +// } +// +// pos = 0; +// /* Convert up to lnname characters of the filename. */ +// for (i = 0; i < lnname; i++) { +// char c = toupper(src[i]); +// src[pos++] = valid_d_char(c) ? c : '_'; +// } +// src[pos++] = '.'; +// /* Convert up to lnext characters of the extension, if any. */ +// for (i = 0; i < lnext; i++) { +// char c = toupper(src[lname + 1 + i]); +// src[pos++] = valid_d_char(c) ? c : '_'; +// } +// src[pos] = '\0'; +//} int str2d_char(const char *icharset, const char *input, char **output) { diff --git a/src/util.h b/src/util.h index 700ce9a..a766f9b 100644 --- a/src/util.h +++ b/src/util.h @@ -47,35 +47,39 @@ int int_pow(int base, int power); int str2ascii(const char *icharset, const char *input, char **output); /** - * Ensure a given string is a valid ISO directory identifier, modifying - * it if needed. + * Create a level 1 directory identifier. * * @param src - * The identifier, in ASCII encoding. It may be modified by the function. - * @param maxlen - * Maximum length supported by current iso level. + * The identifier, in ASCII encoding. */ -void iso_dirid(char *src, int maxlen); +char *iso_1_dirid(const char *src); /** - * Ensure a given string is a valid ISO level 1 file identifier, in 8.3 - * format, modifying it if needed. + * Create a level 2 directory identifier. + * + * @param src + * The identifier, in ASCII encoding. + */ +char *iso_2_dirid(const char *src); + +/** + * Create a level 1 file identifier that consists of a name, in 8.3 + * format. * Note that version number is not added to the file name * * @param src - * The identifier, in ASCII encoding. It may be modified by the function. + * The identifier, in ASCII encoding. */ -void iso_1_fileid(char *src); +char *iso_1_fileid(const char *src); /** - * Ensure a given string is a valid ISO level 2 file identifier, modifying it - * if needed. + * Create a level 2 file identifier. * Note that version number is not added to the file name * * @param src - * The identifier, in ASCII encoding. It may be modified by the function. + * The identifier, in ASCII encoding. */ -void iso_2_fileid(char *src); +char *iso_2_fileid(const char *src); /** * Convert a given input string to d-chars. diff --git a/test/test_util.c b/test/test_util.c index 1e68c10..3d10f0d 100644 --- a/test/test_util.c +++ b/test/test_util.c @@ -29,6 +29,105 @@ static void test_round_up() CU_ASSERT_EQUAL( round_up(14, 7), 14 ); } +static void test_iso_bb() +{ + uint8_t buf[8]; + uint32_t num; + + num = 0x01020304; + iso_bb(buf, num, 4); + CU_ASSERT_EQUAL( buf[0], 0x04 ); + CU_ASSERT_EQUAL( buf[1], 0x03 ); + CU_ASSERT_EQUAL( buf[2], 0x02 ); + CU_ASSERT_EQUAL( buf[3], 0x01 ); + CU_ASSERT_EQUAL( buf[4], 0x01 ); + CU_ASSERT_EQUAL( buf[5], 0x02 ); + CU_ASSERT_EQUAL( buf[6], 0x03 ); + CU_ASSERT_EQUAL( buf[7], 0x04 ); + + iso_bb(buf, num, 2); + CU_ASSERT_EQUAL( buf[0], 0x04 ); + CU_ASSERT_EQUAL( buf[1], 0x03 ); + CU_ASSERT_EQUAL( buf[2], 0x03 ); + CU_ASSERT_EQUAL( buf[3], 0x04 ); +} + +static void test_iso_1_dirid() +{ + CU_ASSERT_STRING_EQUAL( iso_1_dirid("dir1"), "DIR1" ); + CU_ASSERT_STRING_EQUAL( iso_1_dirid("dIR1"), "DIR1" ); + CU_ASSERT_STRING_EQUAL( iso_1_dirid("DIR1"), "DIR1" ); + CU_ASSERT_STRING_EQUAL( iso_1_dirid("dirwithbigname"), "DIRWITHB"); + CU_ASSERT_STRING_EQUAL( iso_1_dirid("dirwith8"), "DIRWITH8"); + CU_ASSERT_STRING_EQUAL( iso_1_dirid("dir.1"), "DIR_1"); + CU_ASSERT_STRING_EQUAL( iso_1_dirid("4f<0KmM::xcvf"), "4F_0KMM_"); +} + +static void test_iso_2_dirid() +{ + CU_ASSERT_STRING_EQUAL( iso_2_dirid("dir1"), "DIR1" ); + CU_ASSERT_STRING_EQUAL( iso_2_dirid("dIR1"), "DIR1" ); + CU_ASSERT_STRING_EQUAL( iso_2_dirid("DIR1"), "DIR1" ); + CU_ASSERT_STRING_EQUAL( iso_2_dirid("dirwithbigname"), "DIRWITHBIGNAME"); + CU_ASSERT_STRING_EQUAL( iso_2_dirid("dirwith8"), "DIRWITH8"); + CU_ASSERT_STRING_EQUAL( iso_2_dirid("dir.1"), "DIR_1"); + CU_ASSERT_STRING_EQUAL( iso_2_dirid("4f<0KmM::xcvf"), "4F_0KMM__XCVF"); + CU_ASSERT_STRING_EQUAL( iso_2_dirid("directory with 31 characters ok"), "DIRECTORY_WITH_31_CHARACTERS_OK"); + CU_ASSERT_STRING_EQUAL( iso_2_dirid("directory with more than 31 characters"), "DIRECTORY_WITH_MORE_THAN_31_CHA"); +} + +static void test_iso_1_fileid() +{ + CU_ASSERT_STRING_EQUAL( iso_1_fileid("file1"), "FILE1."); + CU_ASSERT_STRING_EQUAL( iso_1_fileid("fILe1"), "FILE1."); + CU_ASSERT_STRING_EQUAL( iso_1_fileid("FILE1"), "FILE1."); + CU_ASSERT_STRING_EQUAL( iso_1_fileid(".EXT"), ".EXT"); + CU_ASSERT_STRING_EQUAL( iso_1_fileid("file.ext"), "FILE.EXT"); + CU_ASSERT_STRING_EQUAL( iso_1_fileid("fiLE.ext"), "FILE.EXT"); + CU_ASSERT_STRING_EQUAL( iso_1_fileid("file.EXt"), "FILE.EXT"); + CU_ASSERT_STRING_EQUAL( iso_1_fileid("FILE.EXT"), "FILE.EXT"); + CU_ASSERT_STRING_EQUAL( iso_1_fileid("bigfilename"), "BIGFILEN."); + CU_ASSERT_STRING_EQUAL( iso_1_fileid("bigfilename.ext"), "BIGFILEN.EXT"); + CU_ASSERT_STRING_EQUAL( iso_1_fileid("bigfilename.e"), "BIGFILEN.E"); + CU_ASSERT_STRING_EQUAL( iso_1_fileid("file.bigext"), "FILE.BIG"); + CU_ASSERT_STRING_EQUAL( iso_1_fileid(".bigext"), ".BIG"); + CU_ASSERT_STRING_EQUAL( iso_1_fileid("bigfilename.bigext"), "BIGFILEN.BIG"); + CU_ASSERT_STRING_EQUAL( iso_1_fileid("file<:a.ext"), "FILE__A.EXT"); + CU_ASSERT_STRING_EQUAL( iso_1_fileid("file.<:a"), "FILE.__A"); + CU_ASSERT_STRING_EQUAL( iso_1_fileid("file<:a.--a"), "FILE__A.__A"); + CU_ASSERT_STRING_EQUAL( iso_1_fileid("file.ex1.ex2"), "FILE_EX1.EX2"); + CU_ASSERT_STRING_EQUAL( iso_1_fileid("file.ex1.ex2.ex3"), "FILE_EX1.EX3"); + CU_ASSERT_STRING_EQUAL( iso_1_fileid("fil.ex1.ex2.ex3"), "FIL_EX1_.EX3"); +} + +static void test_iso_2_fileid() +{ + CU_ASSERT_STRING_EQUAL( iso_2_fileid("file1"), "FILE1."); + CU_ASSERT_STRING_EQUAL( iso_2_fileid("fILe1"), "FILE1."); + CU_ASSERT_STRING_EQUAL( iso_2_fileid("FILE1"), "FILE1."); + CU_ASSERT_STRING_EQUAL( iso_2_fileid(".EXT"), ".EXT"); + CU_ASSERT_STRING_EQUAL( iso_2_fileid("file.ext"), "FILE.EXT"); + CU_ASSERT_STRING_EQUAL( iso_2_fileid("fiLE.ext"), "FILE.EXT"); + CU_ASSERT_STRING_EQUAL( iso_2_fileid("file.EXt"), "FILE.EXT"); + CU_ASSERT_STRING_EQUAL( iso_2_fileid("FILE.EXT"), "FILE.EXT"); + CU_ASSERT_STRING_EQUAL( iso_2_fileid("bigfilename"), "BIGFILENAME."); + CU_ASSERT_STRING_EQUAL( iso_2_fileid("bigfilename.ext"), "BIGFILENAME.EXT"); + CU_ASSERT_STRING_EQUAL( iso_2_fileid("bigfilename.e"), "BIGFILENAME.E"); + CU_ASSERT_STRING_EQUAL( iso_2_fileid("31 characters filename.extensio"), "31_CHARACTERS_FILENAME.EXTENSIO"); + CU_ASSERT_STRING_EQUAL( iso_2_fileid("32 characters filename.extension"), "32_CHARACTERS_FILENAME.EXTENSIO"); + CU_ASSERT_STRING_EQUAL( iso_2_fileid("more than 30 characters filename.extension"), "MORE_THAN_30_CHARACTERS_FIL.EXT"); + CU_ASSERT_STRING_EQUAL( iso_2_fileid("file.bigext"), "FILE.BIGEXT"); + CU_ASSERT_STRING_EQUAL( iso_2_fileid(".bigext"), ".BIGEXT"); + CU_ASSERT_STRING_EQUAL( iso_2_fileid("bigfilename.bigext"), "BIGFILENAME.BIGEXT"); + CU_ASSERT_STRING_EQUAL( iso_2_fileid("file<:a.ext"), "FILE__A.EXT"); + CU_ASSERT_STRING_EQUAL( iso_2_fileid("file.<:a"), "FILE.__A"); + CU_ASSERT_STRING_EQUAL( iso_2_fileid("file<:a.--a"), "FILE__A.__A"); + CU_ASSERT_STRING_EQUAL( iso_2_fileid("file.ex1.ex2"), "FILE_EX1.EX2"); + CU_ASSERT_STRING_EQUAL( iso_2_fileid("file.ex1.ex2.ex3"), "FILE_EX1_EX2.EX3"); + CU_ASSERT_STRING_EQUAL( iso_2_fileid("fil.ex1.ex2.ex3"), "FIL_EX1_EX2.EX3"); + CU_ASSERT_STRING_EQUAL( iso_2_fileid(".file.bigext"), "_FILE.BIGEXT"); +} + static void test_iso_rbtree_insert() { int res; @@ -86,5 +185,10 @@ void add_util_suite() CU_add_test(pSuite, "div_up()", test_div_up); CU_add_test(pSuite, "round_up()", test_round_up); + CU_add_test(pSuite, "iso_bb()", test_iso_bb); + CU_add_test(pSuite, "iso_1_dirid()", test_iso_1_dirid); + CU_add_test(pSuite, "iso_2_dirid()", test_iso_2_dirid); + CU_add_test(pSuite, "iso_1_fileid()", test_iso_1_fileid); + CU_add_test(pSuite, "iso_2_fileid()", test_iso_2_fileid); CU_add_test(pSuite, "iso_rbtree_insert()", test_iso_rbtree_insert); }