Implemented complete iso PVM and workaround charset problems

This commit is contained in:
Mario Danic 2007-05-12 00:30:04 +00:00
parent d54045fb42
commit a97e96c604
6 changed files with 169 additions and 12 deletions

View File

@ -443,10 +443,20 @@ write_pri_vol_desc(struct ecma119_write_target *t, uint8_t *buf)
char *data_id = str2ascii(volume->data_preparer_id); char *data_id = str2ascii(volume->data_preparer_id);
char *volset_id = str2ascii(t->volset->volset_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; vol->vol_desc_type[0] = 1;
memcpy(vol->std_identifier, "CD001", 5); memcpy(vol->std_identifier, "CD001", 5);
vol->vol_desc_version[0] = 1; 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) if (vol_id)
strncpy((char*)vol->volume_id, vol_id, 32); strncpy((char*)vol->volume_id, vol_id, 32);
iso_bb(vol->vol_space_size, t->vol_space_size, 4); 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); 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->vol_set_id, volset_id, 128);
strncpy((char*)vol->publisher_id, pub_id, 128); strncpy((char*)vol->publisher_id, pub_id, 128);
strncpy((char*)vol->data_prep_id, data_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_creation_time, t->now);
iso_datetime_17(vol->vol_modification_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(volset_id);
free(pub_id); free(pub_id);
free(data_id); free(data_id);
free(system_id);
free(application_id);
free(copyright_file_id);
free(abstract_file_id);
free(biblio_file_id);
} }
static void static void

View File

@ -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, void iso_volume_set_data_preparer_id(struct iso_volume *volume,
const char *data_preparer_id); 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. * Locate a node by its path on disc.
* *

View File

@ -35,16 +35,63 @@ int round_up(int n, int mul)
return div_up(n, mul) * 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 /* this function must always return a name
* since the caller never checks if a NULL * since the caller never checks if a NULL
* is returned. It also avoids some warnings. */ * is returned. It also avoids some warnings. */
char *str2ascii(const char *src_arg) char *str2ascii(const char *src_arg)
{ {
wchar_t wsrc_[NAME_BUFFER_SIZE]; wchar_t *wsrc_;
char *src = (char*)wsrc_;
char *ret_;
char *ret; char *ret;
mbstate_t state; char *ret_;
char *src;
iconv_t conv; iconv_t conv;
size_t numchars; size_t numchars;
size_t outbytes; size_t outbytes;
@ -56,12 +103,21 @@ char *str2ascii(const char *src_arg)
/* convert the string to a wide character string. Note: outbytes /* convert the string to a wide character string. Note: outbytes
* is in fact the number of characters in the string and doesn't * is in fact the number of characters in the string and doesn't
* include the last NULL character. */ * include the last NULL character.
memset(&state, 0, sizeof(state)); *
numchars = mbsrtowcs(wsrc_, &src_arg, NAME_BUFFER_SIZE-1, &state); * For now, just assume input to be in UTF-8, we can change
if (numchars < 0) * this later.
*/
wsrc_ = str2wchar(src_arg, "UTF-8");
if (!wsrc_)
return NULL; return NULL;
src = (char *)wsrc_;
numchars = wcslen(wsrc_);
inbytes = numchars * sizeof(wchar_t); inbytes = numchars * sizeof(wchar_t);
ret_ = malloc(numchars+1); ret_ = malloc(numchars+1);
@ -70,8 +126,10 @@ char *str2ascii(const char *src_arg)
/* initialize iconv */ /* initialize iconv */
conv = iconv_open("ASCII", "WCHAR_T"); conv = iconv_open("ASCII", "WCHAR_T");
if (conv == (iconv_t)-1) if (conv == (iconv_t)-1) {
free(wsrc_);
return NULL; return NULL;
}
n = iconv(conv, &src, &inbytes, &ret, &outbytes); n = iconv(conv, &src, &inbytes, &ret, &outbytes);
while(n == -1) { while(n == -1) {
@ -109,6 +167,8 @@ char *str2ascii(const char *src_arg)
iconv_close(conv); iconv_close(conv);
*ret='\0'; *ret='\0';
free(wsrc_);
return ret_; return ret_;
} }

View File

@ -109,6 +109,36 @@ void iso_volume_set_data_preparer_id(struct iso_volume *volume,
volume->data_preparer_id = strdup(data_preparer_id); 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 * struct iso_tree_node *
iso_tree_volume_path_to_node(struct iso_volume *volume, const char *path) iso_tree_volume_path_to_node(struct iso_volume *volume, const char *path)
{ {

View File

@ -24,6 +24,12 @@ struct iso_volume
char *volume_id; /**< Volume identifier. */ char *volume_id; /**< Volume identifier. */
char *publisher_id; /**< Volume publisher. */ char *publisher_id; /**< Volume publisher. */
char *data_preparer_id; /**< Volume data preparer. */ 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;
}; };
/** /**

View File

@ -96,6 +96,10 @@ int main(int argc, char **argv)
volume = iso_volume_new_with_root( "VOLID", "PUBID", "PREPID", root ); volume = iso_volume_new_with_root( "VOLID", "PUBID", "PREPID", root );
volset = iso_volset_new( volume, "VOLSETID" ); 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); src = iso_source_new_ecma119(volset, 0, level, flags);
while (src->read(src, buf, 2048) == 2048) { while (src->read(src, buf, 2048) == 2048) {