# HG changeset patch # User Matti Hamalainen # Date 1578766320 -7200 # Node ID 6d0143e43edf4b9bf6ff0d560133996c97cf2a17 # Parent f3ba2ba894b13eb0ab854c143e214c543b67d56b Add functionality and API changes for doing on-the-fly character set conversion of STIL data and PSID header string fields while reading them. diff -r f3ba2ba894b1 -r 6d0143e43edf sidinfo.c --- a/sidinfo.c Sat Jan 11 19:11:34 2020 +0200 +++ b/sidinfo.c Sat Jan 11 20:12:00 2020 +0200 @@ -991,7 +991,7 @@ th_io_set_handlers(inFile, siPSIDError, NULL); // Read PSID data - if ((res = sidlib_read_sid_file_alloc(inFile, &psid, setSLDBNewFormat)) != THERR_OK) + if ((res = sidlib_read_sid_file_alloc(inFile, &psid, setSLDBNewFormat, NULL)) != THERR_OK) goto error; // Get songlength information, if any @@ -1287,7 +1287,7 @@ goto err2; } - if ((ret = sidlib_stildb_read(inFile, sidSTILDB)) != THERR_OK) + if ((ret = sidlib_stildb_read(inFile, sidSTILDB, NULL)) != THERR_OK) { THERR("Error parsing STIL: %s\n", th_error_str(ret)); diff -r f3ba2ba894b1 -r 6d0143e43edf sidlib.c --- a/sidlib.c Sat Jan 11 19:11:34 2020 +0200 +++ b/sidlib.c Sat Jan 11 20:12:00 2020 +0200 @@ -8,7 +8,16 @@ #include "th_string.h" -BOOL sidlib_fread_str(th_ioctx *ctx, char **str, const size_t len) +static char *sidlib_strdup_convert(SIDLibChConvCtx *chconv, const char *str) +{ + if (chconv != NULL) + return chconv->convert(chconv, str); + else + return th_strdup(str); +} + + +static BOOL sidlib_fread_str(th_ioctx *ctx, SIDLibChConvCtx *chconv, char **str, const size_t len) { char *tmp; @@ -29,6 +38,12 @@ } tmp[len] = 0; + + if (chconv != NULL) + { + *str = chconv->convert(chconv, tmp); + th_free(tmp); + } return TRUE; err: @@ -94,7 +109,8 @@ } -int sidlib_read_sid_file(th_ioctx *ctx, SIDLibPSIDHeader *psid, const BOOL newSLDB) +int sidlib_read_sid_file(th_ioctx *ctx, SIDLibPSIDHeader *psid, + const BOOL newSLDB, SIDLibChConvCtx *chconv) { int ret = THERR_OK; th_md5state_t state; @@ -131,9 +147,9 @@ psid->isRSID = psid->magic[0] == 'R'; - if (!sidlib_fread_str(ctx, &psid->sidName, SIDLIB_PSID_STR_LEN) || - !sidlib_fread_str(ctx, &psid->sidAuthor, SIDLIB_PSID_STR_LEN) || - !sidlib_fread_str(ctx, &psid->sidCopyright, SIDLIB_PSID_STR_LEN)) + if (!sidlib_fread_str(ctx, chconv, &psid->sidName, SIDLIB_PSID_STR_LEN) || + !sidlib_fread_str(ctx, chconv, &psid->sidAuthor, SIDLIB_PSID_STR_LEN) || + !sidlib_fread_str(ctx, chconv, &psid->sidCopyright, SIDLIB_PSID_STR_LEN)) { ret = th_io_error(ctx, ctx->status, "Error reading SID file header data."); @@ -218,14 +234,15 @@ } -int sidlib_read_sid_file_alloc(th_ioctx *ctx, SIDLibPSIDHeader **ppsid, const BOOL newSLDB) +int sidlib_read_sid_file_alloc(th_ioctx *ctx, SIDLibPSIDHeader **ppsid, + const BOOL newSLDB, SIDLibChConvCtx *chconv) { if ((*ppsid = th_malloc0(sizeof(SIDLibPSIDHeader))) == NULL) return THERR_MALLOC; (*ppsid)->allocated = TRUE; - return sidlib_read_sid_file(ctx, *ppsid, newSLDB); + return sidlib_read_sid_file(ctx, *ppsid, newSLDB, chconv); } @@ -602,7 +619,8 @@ static int sidlib_stildb_entry_realloc( SIDLibSTILNode *node, const int nsubtune, const BOOL alloc, - const int nfield, const char *fdata) + const int nfield, const char *fdata, + SIDLibChConvCtx *chconv) { SIDLibSTILSubTune *subtune; @@ -632,7 +650,7 @@ if ((field->data = th_realloc(field->data, (field->ndata + 1) * sizeof(char *))) == NULL) return THERR_MALLOC; - field->data[field->ndata] = th_strdup(fdata); + field->data[field->ndata] = sidlib_strdup_convert(chconv, fdata); field->ndata++; } @@ -664,7 +682,8 @@ } -static int sidlib_stildb_node_new(SIDLibSTILNode **pnode, const char *filename) +static int sidlib_stildb_node_new(SIDLibSTILNode **pnode, const char *filename, + SIDLibChConvCtx *chconv) { // Allocate memory for new node SIDLibSTILNode *node; @@ -674,10 +693,11 @@ return THERR_MALLOC; // Allocate filename and initial space for one subtune + // NOTE! Filename is not converted even if chconv != NULL if ((node->filename = th_strdup(filename)) == NULL) return THERR_MALLOC; - if ((res = sidlib_stildb_entry_realloc(node, 1, FALSE, -1, NULL)) != THERR_OK) + if ((res = sidlib_stildb_entry_realloc(node, 1, FALSE, -1, NULL, chconv)) != THERR_OK) { sidlib_stildb_node_free(node); return res; @@ -774,7 +794,7 @@ #define VADDCH(ch) if (strPos < SIDLIB_BUFFER_SIZE) { tmpStr[strPos++] = ch; } -int sidlib_stildb_read(th_ioctx *fh, SIDLibSTILDB *dbh) +int sidlib_stildb_read(th_ioctx *fh, SIDLibSTILDB *dbh, SIDLibChConvCtx *chconv) { int ret = THERR_OK, field = -1; SIDLibSTILParserCtx ctx; @@ -893,7 +913,7 @@ // A new file / entry, allocate and append tmpStr[strPos] = 0; - if ((ret = sidlib_stildb_node_new(&entry, tmpStr)) != THERR_OK) + if ((ret = sidlib_stildb_node_new(&entry, tmpStr, chconv)) != THERR_OK) goto out; th_llist_append_node((th_llist_t **) &dbh->nodes, (th_llist_t *) entry); @@ -1026,7 +1046,7 @@ { // Supported field, add it if ((ret = sidlib_stildb_entry_realloc( - entry, subtune, TRUE, field, tmpStr)) != THERR_OK) + entry, subtune, TRUE, field, tmpStr, chconv)) != THERR_OK) { ret = th_io_error(fh, THERR_MALLOC, "Could not allocate memory for field '%s'.", diff -r f3ba2ba894b1 -r 6d0143e43edf sidlib.h --- a/sidlib.h Sat Jan 11 19:11:34 2020 +0200 +++ b/sidlib.h Sat Jan 11 20:12:00 2020 +0200 @@ -84,7 +84,7 @@ typedef struct { int ndata; - char **data; + char **data; // Converted through SIDLibChConvCtx if conversion is used } SIDLibSTILField; @@ -99,9 +99,11 @@ { th_llist_t node; - char *filename; // HVSC path/filename + char *filename; // HVSC path/filename (NOT converted through SIDLibChConvCtx) size_t nsubtunes; // Number of subtune information structures - SIDLibSTILSubTune *subtunes; + SIDLibSTILSubTune *subtunes; // NOTE! Subtunes are in undefined order here + // (through with correct SIDLibSTILSubTune::tune number, of course) + // unless sidlib_stildb_build_index() has been run on the SIDLibSTILDB // Internal use only SIDLibSLDBNode *lengths; @@ -127,8 +129,9 @@ nSongs, // Number of subsongs startSong; // Default starting song uint32_t speed; // Speed + char *sidName; // Descriptive text-fields, ASCIIZ - char *sidAuthor; + char *sidAuthor; // Converted through SIDLibChConvCtx if conversion is used char *sidCopyright; // PSIDv2+ data @@ -148,16 +151,24 @@ } SIDLibPSIDHeader; +typedef struct SIDLibChConvCtx +{ + void *data; + char* (*convert)(struct SIDLibChConvCtx *ctx, const char *str); +} SIDLibChConvCtx; + + // // Globals // -const char *sidlib_stil_fields[STF_LAST]; +const char * sidlib_stil_fields[STF_LAST]; + // // Functions // -int sidlib_read_sid_file(th_ioctx *ctx, SIDLibPSIDHeader *psid, const BOOL newSLDB); -int sidlib_read_sid_file_alloc(th_ioctx *ctx, SIDLibPSIDHeader **ppsid, const BOOL newSLDB); +int sidlib_read_sid_file(th_ioctx *ctx, SIDLibPSIDHeader *psid, const BOOL newSLDB, SIDLibChConvCtx *chconv); +int sidlib_read_sid_file_alloc(th_ioctx *ctx, SIDLibPSIDHeader **ppsid, const BOOL newSLDB, SIDLibChConvCtx *chconv); void sidlib_free_sid_file(SIDLibPSIDHeader *psid); const char * sidlib_get_sid_clock_str(const int flags); @@ -170,7 +181,7 @@ SIDLibSLDBNode * sidlib_sldb_get_by_hash(SIDLibSLDB *dbh, th_md5hash_t hash); int sidlib_stildb_new(SIDLibSTILDB **pdbh); -int sidlib_stildb_read(th_ioctx *ctx, SIDLibSTILDB *dbh); +int sidlib_stildb_read(th_ioctx *ctx, SIDLibSTILDB *dbh, SIDLibChConvCtx *chconv); int sidlib_stildb_build_index(SIDLibSTILDB *dbh); void sidlib_stildb_free(SIDLibSTILDB *dbh); SIDLibSTILNode * sidlib_stildb_get_node(SIDLibSTILDB *dbh, const char *filename);