[easytag/wip/win32: 1/6] Convert Windows filename encoding for id3lib



commit cf1f383088a8faeaa98de010f16435fce11bf405
Author: David King <amigadave amigadave com>
Date:   Tue Jan 19 16:52:21 2016 +0000

    Convert Windows filename encoding for id3lib
    
    As id3lib does not use the wide character API on Windows, it expects
    filenames to be in the system codepage. Convert the GLib encoding to the
    system codepage before passing it to id3lib.

 src/tags/id3_tag.c              |   76 +++++++++++++++++++++++++++++++++++---
 src/tags/libapetag/id3v2_read.c |   26 +++++++++++++-
 src/tags/mpeg_header.c          |   24 ++++++++++++-
 src/tags/opus_header.c          |    2 +
 4 files changed, 120 insertions(+), 8 deletions(-)
---
diff --git a/src/tags/id3_tag.c b/src/tags/id3_tag.c
index 7b568e4..70cb809 100644
--- a/src/tags/id3_tag.c
+++ b/src/tags/id3_tag.c
@@ -229,13 +229,34 @@ id3tag_write_file_v23tag (const ET_File *ETFile,
         return FALSE;
     }
 
-    basename_utf8 = g_path_get_basename(filename_utf8);
+#ifdef G_OS_WIN32
+    /* On Windows, id3lib expects filenames to be in system codepage
+     * encoding. */
+    {
+        gchar *locale_filename;
+
+        locale_filename = g_locale_from_utf8 (filename, -1, NULL, NULL,
+                                              error);
 
-    ID3Tag_Link(id3_tag,filename);
+        if (!locale_filename)
+        {
+            ID3Tag_Delete (id3_tag);
+            g_object_unref (file);
+            return FALSE;
+        }
+
+        ID3Tag_Link (id3_tag, locale_filename);
+
+        g_free (locale_filename);
+    }
+#else
+    ID3Tag_Link (id3_tag, filename);
+#endif
 
     /* Set padding when tag was changed, for faster writing */
     ID3Tag_SetPadding(id3_tag,TRUE);
 
+    basename_utf8 = g_path_get_basename (filename_utf8);
 
     /*********
      * Title *
@@ -803,27 +824,70 @@ ID3_C_EXPORT size_t ID3Tag_Link_1 (ID3Tag *id3tag, const char *filename)
 {
     size_t offset;
 
+#ifdef G_OS_WIN32
+    /* On Windows, id3lib expects filenames to be in system codepage
+     * encoding. */
+    GError *error = NULL;
+    gchar *locale_filename;
+
+    locale_filename = g_locale_from_utf8 (filename, -1, NULL, NULL,
+                                          &error);
+
+    if (!locale_filename)
+    {
+        g_debug ("Error converting filename to system codepage: %s",
+                 error->message);
+        g_clear_error (&error);
+        return 0;
+    }
+#endif
+
 #   if (0) // Link the file with the both tags may cause damage to unicode strings
 //#   if ( (ID3LIB_MAJOR >= 3) && (ID3LIB_MINOR >= 8) && (ID3LIB_PATCH >= 1) ) // Same test used in 
Id3tag_Read_File_Tag to use ID3Tag_HasTagType
         /* No problem of priority, so we link the file with the both tags
          * to manage => ID3Tag_HasTagType works correctly */
-        offset = ID3Tag_LinkWithFlags(id3tag,filename,ID3TT_ID3V1 | ID3TT_ID3V2);
+#ifdef G_OS_WIN32
+        offset = ID3Tag_LinkWithFlags (id3tag, locale_filename,
+                                       ID3TT_ID3V1 | ID3TT_ID3V2);
+#else
+        offset = ID3Tag_LinkWithFlags (id3tag, filename,
+                                       ID3TT_ID3V1 | ID3TT_ID3V2);
+#endif
 #   elif ( (ID3LIB_MAJOR >= 3) && (ID3LIB_MINOR >= 8) )
         /* Version 3.8.0pre2 gives priority to tag id3v1 instead of id3v2, so we
          * try to fix it by linking the file with the id3v2 tag first. This bug
          * was fixed in the final version of 3.8.0 but we can't know it... */
         /* First, try to get the ID3v2 tags */
-        offset = ID3Tag_LinkWithFlags(id3tag,filename,ID3TT_ID3V2);
+#ifdef G_OS_WIN32
+        offset = ID3Tag_LinkWithFlags (id3tag, locale_filename, ID3TT_ID3V2);
+#else
+        offset = ID3Tag_LinkWithFlags (id3tag, filename, ID3TT_ID3V2);
+#endif
+
         if (offset == 0)
         {
             /* No ID3v2 tags available => try to get the ID3v1 tags */
-            offset = ID3Tag_LinkWithFlags(id3tag,filename,ID3TT_ID3V1);
+#ifdef G_OS_WIN32
+            offset = ID3Tag_LinkWithFlags (id3tag, locale_filename,
+                                           ID3TT_ID3V1);
+#else
+            offset = ID3Tag_LinkWithFlags (id3tag, filename, ID3TT_ID3V1);
+#endif
         }
 #   else
         /* Function 'ID3Tag_LinkWithFlags' is not defined up to id3lib-.3.7.13 */
-        offset = ID3Tag_Link(id3tag,filename);
+#ifdef G_OS_WIN32
+        offset = ID3Tag_Link (id3tag, locale_filename);
+#else
+        offset = ID3Tag_Link (id3tag, filename);
+#endif
 #   endif
     //g_print("ID3 TAG SIZE: %d\t%s\n",offset,g_path_get_basename(filename));
+
+#ifdef G_OS_WIN32
+    g_free (locale_filename);
+#endif
+
     return offset;
 }
 
diff --git a/src/tags/libapetag/id3v2_read.c b/src/tags/libapetag/id3v2_read.c
index ec1fd0f..ab49c00 100644
--- a/src/tags/libapetag/id3v2_read.c
+++ b/src/tags/libapetag/id3v2_read.c
@@ -310,7 +310,31 @@ int readtag_id3v2 ( apetag *mem_cnt, char* fileName )
     if ( (tag = ID3Tag_New ()) == NULL )
     return 1;
     // on some casses its weerrryyy slooowwwwlyyy 65k file take 2-5 sec 
-    ID3Tag_LinkWithFlags ( tag, fileName, ID3TT_ID3V2 );
+#ifdef G_OS_WIN32
+    /* On Windows, id3lib expects filenames to be in system codepage
+     * encoding. */
+    {
+        GError *error = NULL;
+        gchar *locale_filename;
+
+        locale_filename = g_locale_from_utf8 (filename, -1, NULL, NULL,
+                                              &error);
+
+        if (!locale_filename)
+        {
+            g_debug ("Error converting filename to system codepage: %s",
+                     error->message);
+            g_clear_error (&error);
+            return 0;
+        }
+
+        ID3Tag_LinkWithFlags (id3_tag, locale_filename, ID3TT_ID3V2);
+
+        g_free (locale_filename);
+    }
+#else
+    ID3Tag_LinkWithFlags (tag, filename, ID3TT_ID3V2);
+#endif
     
     if ( tag == NULL ) {
     ID3Tag_Delete (tag);
diff --git a/src/tags/mpeg_header.c b/src/tags/mpeg_header.c
index dfccbbf..6de9c79 100644
--- a/src/tags/mpeg_header.c
+++ b/src/tags/mpeg_header.c
@@ -110,7 +110,29 @@ et_mpeg_header_read_file_info (GFile *file,
 
     /* Link the file to the tag (uses ID3TT_ID3V2 to get header if APIC is present in Tag) */
     filename = g_file_get_path (file);
-    ID3Tag_LinkWithFlags(id3_tag,filename,ID3TT_ID3V2);
+#ifdef G_OS_WIN32
+    /* On Windows, id3lib expects filenames to be in system codepage
+     * encoding. */
+    {
+        gchar *locale_filename;
+
+        locale_filename = g_locale_from_utf8 (filename, -1, NULL, NULL,
+                                              error);
+
+        if (!locale_filename)
+        {
+            g_free (filename);
+            return FALSE;
+        }
+
+        ID3Tag_LinkWithFlags (id3_tag, locale_filename, ID3TT_ID3V2);
+
+        g_free (locale_filename);
+    }
+#else
+    ID3Tag_LinkWithFlags (id3_tag, filename, ID3TT_ID3V2);
+#endif
+
     g_free (filename);
 
     if ( (headerInfo = ID3Tag_GetMp3HeaderInfo(id3_tag)) )
diff --git a/src/tags/opus_header.c b/src/tags/opus_header.c
index 17f5907..77cd3d6 100644
--- a/src/tags/opus_header.c
+++ b/src/tags/opus_header.c
@@ -60,6 +60,8 @@ et_opus_open_file (GFile *gfile, GError **error)
     g_return_val_if_fail (gfile != NULL, NULL);
 
     path = g_file_get_path (gfile);
+    /* Opusfile does the UTF-8 to UTF-16 translation on Windows
+     * automatically. */
     file = op_open_file (path, &error_val);
     g_free (path);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]