diff sidlib.c @ 319:6d0143e43edf

Add functionality and API changes for doing on-the-fly character set conversion of STIL data and PSID header string fields while reading them.
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 11 Jan 2020 20:12:00 +0200
parents ee56f1f2b528
children e35e15f07c66
line wrap: on
line diff
--- 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'.",