Implemented complete iso PVM and workaround charset problems

master
Mario Danic 16 years ago
parent d54045fb42
commit a97e96c604
  1. 30
      libisofs/ecma119.c
  2. 33
      libisofs/libisofs.h
  3. 78
      libisofs/util.c
  4. 30
      libisofs/volume.c
  5. 6
      libisofs/volume.h
  6. 4
      test/iso.c

@ -442,11 +442,21 @@ write_pri_vol_desc(struct ecma119_write_target *t, uint8_t *buf)
char *pub_id = str2ascii(volume->publisher_id);
char *data_id = str2ascii(volume->data_preparer_id);
char *volset_id = str2ascii(t->volset->volset_id);
char *system_id = str2ascii(volume->system_id);
char *application_id = str2ascii(volume->application_id);
char *copyright_file_id = str2ascii(volume->copyright_file_id);
char *abstract_file_id = str2ascii(volume->abstract_file_id);
char *biblio_file_id = str2ascii(volume->biblio_file_id);
vol->vol_desc_type[0] = 1;
memcpy(vol->std_identifier, "CD001", 5);
vol->vol_desc_version[0] = 1;
memcpy(vol->system_id, "SYSID", 5);
if (system_id)
strncpy((char*)vol->system_id, system_id, 32);
else
/* put linux by default? */
memcpy(vol->system_id, "LINUX", 5);
if (vol_id)
strncpy((char*)vol->volume_id, vol_id, 32);
iso_bb(vol->vol_space_size, t->vol_space_size, 4);
@ -459,10 +469,19 @@ write_pri_vol_desc(struct ecma119_write_target *t, uint8_t *buf)
write_one_dir_record(t, t->root, 3, vol->root_dir_record);
/* mmm, why not check for null? */
strncpy((char*)vol->vol_set_id, volset_id, 128);
strncpy((char*)vol->publisher_id, pub_id, 128);
strncpy((char*)vol->data_prep_id, data_id, 128);
strncpy((char*)vol->application_id, "APPID", 128);
if (application_id)
strncpy((char*)vol->application_id, application_id, 128);
if (copyright_file_id)
strncpy((char*)vol->copyright_file_id, copyright_file_id, 37);
if (abstract_file_id)
strncpy((char*)vol->abstract_file_id, abstract_file_id, 37);
if (biblio_file_id)
strncpy((char*)vol->bibliographic_file_id, biblio_file_id, 37);
iso_datetime_17(vol->vol_creation_time, t->now);
iso_datetime_17(vol->vol_modification_time, t->now);
@ -473,6 +492,11 @@ write_pri_vol_desc(struct ecma119_write_target *t, uint8_t *buf)
free(volset_id);
free(pub_id);
free(data_id);
free(system_id);
free(application_id);
free(copyright_file_id);
free(abstract_file_id);
free(biblio_file_id);
}
static void

@ -84,6 +84,39 @@ void iso_volume_set_publisher_id(struct iso_volume *volume,
void iso_volume_set_data_preparer_id(struct iso_volume *volume,
const char *data_preparer_id);
/**
* Fill in the system id for a volume. Up to 32 characters.
*/
void iso_volume_set_system_id(struct iso_volume *volume,
const char *system_id);
/**
* Fill in the application id for a volume. Up to 128 chars.
*/
void iso_volume_set_application_id(struct iso_volume *volume,
const char *application_id);
/**
* Fill copyright information for the volume. Usually this refers
* to a file on disc. Up to 37 characters.
*/
void iso_volume_set_copyright_file_id(struct iso_volume *volume,
const char *copyright_file_id);
/**
* Fill abstract information for the volume. Usually this refers
* to a file on disc. Up to 37 characters.
*/
void iso_volume_set_abstract_file_id(struct iso_volume *volume,
const char *abstract_file_id);
/**
* Fill biblio information for the volume. Usually this refers
* to a file on disc. Up to 37 characters.
*/
void iso_volume_set_biblio_file_id(struct iso_volume *volume,
const char *biblio_file_id);
/**
* Locate a node by its path on disc.
*

@ -35,16 +35,63 @@ int round_up(int n, int mul)
return div_up(n, mul) * mul;
}
/**
* Convert a str in a specified codeset to WCHAR_T.
* The result must be free() when no more needed
*/
static wchar_t *str2wchar(const char *str, const char *codeset)
{
iconv_t conv;
size_t inbytes;
size_t outbytes;
char *ret;
char *src;
wchar_t *wstr;
size_t n;
conv = iconv_open("WCHAR_T", codeset);
if (conv == (iconv_t)-1) {
perror("Invalid encodings\n");
return NULL;
}
inbytes = strlen(str);
outbytes = (inbytes + 1) * sizeof(wchar_t);
/* we are sure that numchars <= inbytes */
wstr = malloc(outbytes);
ret = (char *)wstr;
src = (char *)str;
n = iconv(conv, &src, &inbytes, &ret, &outbytes);
if (n == -1) {
/* error, should never occur */
/*
* FIXME
* The above assumption is not always true, because the str could
* actually not be encoded in specified codeset. This can lead to
* problems if, for example, a file is not in UTF-8. You should
* take care about this in a way like str2ascii
*/
perror("Convert error\n");
return NULL;
}
iconv_close(conv);
//TODO is needed this??
*( (wchar_t *)ret )='\0';
return wstr;
}
/* this function must always return a name
* since the caller never checks if a NULL
* is returned. It also avoids some warnings. */
char *str2ascii(const char *src_arg)
{
wchar_t wsrc_[NAME_BUFFER_SIZE];
char *src = (char*)wsrc_;
char *ret_;
wchar_t *wsrc_;
char *ret;
mbstate_t state;
char *ret_;
char *src;
iconv_t conv;
size_t numchars;
size_t outbytes;
@ -56,11 +103,20 @@ char *str2ascii(const char *src_arg)
/* convert the string to a wide character string. Note: outbytes
* is in fact the number of characters in the string and doesn't
* include the last NULL character. */
memset(&state, 0, sizeof(state));
numchars = mbsrtowcs(wsrc_, &src_arg, NAME_BUFFER_SIZE-1, &state);
if (numchars < 0)
* include the last NULL character.
*
* For now, just assume input to be in UTF-8, we can change
* this later.
*/
wsrc_ = str2wchar(src_arg, "UTF-8");
if (!wsrc_)
return NULL;
src = (char *)wsrc_;
numchars = wcslen(wsrc_);
inbytes = numchars * sizeof(wchar_t);
@ -70,8 +126,10 @@ char *str2ascii(const char *src_arg)
/* initialize iconv */
conv = iconv_open("ASCII", "WCHAR_T");
if (conv == (iconv_t)-1)
if (conv == (iconv_t)-1) {
free(wsrc_);
return NULL;
}
n = iconv(conv, &src, &inbytes, &ret, &outbytes);
while(n == -1) {
@ -109,6 +167,8 @@ char *str2ascii(const char *src_arg)
iconv_close(conv);
*ret='\0';
free(wsrc_);
return ret_;
}

@ -109,6 +109,36 @@ void iso_volume_set_data_preparer_id(struct iso_volume *volume,
volume->data_preparer_id = strdup(data_preparer_id);
}
void iso_volume_set_system_id(struct iso_volume *volume,
const char *system_id)
{
volume->system_id = strdup(system_id);
}
void iso_volume_set_application_id(struct iso_volume *volume,
const char *application_id)
{
volume->application_id = strdup(application_id);
}
void iso_volume_set_copyright_file_id(struct iso_volume *volume,
const char *copyright_file_id)
{
volume->copyright_file_id = strdup(copyright_file_id);
}
void iso_volume_set_abstract_file_id(struct iso_volume *volume,
const char *abstract_file_id)
{
volume->abstract_file_id = strdup(abstract_file_id);
}
void iso_volume_set_biblio_file_id(struct iso_volume *volume,
const char *biblio_file_id)
{
volume->biblio_file_id = strdup(biblio_file_id);
}
struct iso_tree_node *
iso_tree_volume_path_to_node(struct iso_volume *volume, const char *path)
{

@ -24,6 +24,12 @@ struct iso_volume
char *volume_id; /**< Volume identifier. */
char *publisher_id; /**< Volume publisher. */
char *data_preparer_id; /**< Volume data preparer. */
char *system_id; /**< Volume system identifier. */
char *application_id; /**< Volume application id */
char *copyright_file_id;
char *abstract_file_id;
char *biblio_file_id;
};
/**

@ -95,6 +95,10 @@ int main(int argc, char **argv)
}
volume = iso_volume_new_with_root( "VOLID", "PUBID", "PREPID", root );
volset = iso_volset_new( volume, "VOLSETID" );
//some tests
iso_volume_set_application_id(volume, "Libburnia");
iso_volume_set_copyright_file_id(volume, "LICENSE");
src = iso_source_new_ecma119(volset, 0, level, flags);

Loading…
Cancel
Save