[easytag/wip/gerror: 3/8] Use GError in ID3 tagging code



commit 3c7014b234d1896061bf8f373d1ffe34dc1196ed
Author: David King <amigadave amigadave com>
Date:   Wed Sep 24 00:17:05 2014 +0100

    Use GError in ID3 tagging code
    
    Avoid several uses of Log_Print(), and convert some more into warnings
    or debugging messages.

 src/et_core.c          |   22 +++++-
 src/et_core.h          |    2 +-
 src/tags/flac_tag.c    |    4 +-
 src/tags/id3_tag.c     |  177 +++++++++++++++++++++++------------------------
 src/tags/id3_tag.h     |    8 +-
 src/tags/id3v24_tag.c  |  139 +++++++++++++++++++------------------
 src/tags/mpeg_header.c |   43 +++++++-----
 src/tags/mpeg_header.h |    2 +-
 8 files changed, 208 insertions(+), 189 deletions(-)
---
diff --git a/src/et_core.c b/src/et_core.c
index 6a3a524..c1f095a 100644
--- a/src/et_core.c
+++ b/src/et_core.c
@@ -530,7 +530,13 @@ GList *ET_Add_File_To_File_List (gchar *filename)
     {
 #ifdef ENABLE_MP3
         case ID3_TAG:
-            Id3tag_Read_File_Tag(filename,FileTag);
+            if (!id3tag_read_file_tag (filename, FileTag, &error))
+            {
+                Log_Print (LOG_ERROR,
+                           "Error reading ID3 tag from file ‘%s’: %s",
+                           filename_utf8, error->message);
+                g_clear_error (&error);
+            }
             break;
 #endif
 #ifdef ENABLE_OGG
@@ -600,7 +606,13 @@ GList *ET_Add_File_To_File_List (gchar *filename)
 #if defined ENABLE_MP3 && defined ENABLE_ID3LIB
         case MP3_FILE:
         case MP2_FILE:
-            Mpeg_Header_Read_File_Info(filename,ETFileInfo);
+            if (!mpeg_header_read_file_info (filename, ETFileInfo, &error))
+            {
+                Log_Print (LOG_ERROR,
+                           _("Error while querying information for file ‘%s’: %s"),
+                           filename_utf8, error->message);
+                g_error_free (error);
+            }
             break;
 #endif
 #ifdef ENABLE_OGG
@@ -3455,7 +3467,7 @@ ET_Save_File_Tag_To_HD (ET_File *ETFile, GError **error)
     {
 #ifdef ENABLE_MP3
         case ID3_TAG:
-            state = Id3tag_Write_File_Tag(ETFile);
+            state = id3tag_write_file_tag (ETFile, error);
             break;
 #endif
 #ifdef ENABLE_OGG
@@ -3716,7 +3728,9 @@ ET_Detect_Changes_Of_File_Name (File_Name *FileName1, File_Name *FileName2)
  * Notes:
  *  - if field is '' or NULL => will be removed
  */
-gboolean ET_Detect_Changes_Of_File_Tag (File_Tag *FileTag1, File_Tag *FileTag2)
+gboolean
+ET_Detect_Changes_Of_File_Tag (const File_Tag *FileTag1,
+                               const File_Tag *FileTag2)
 {
     Picture *pic1;
     Picture *pic2;
diff --git a/src/et_core.h b/src/et_core.h
index 35f82c7..5338091 100644
--- a/src/et_core.h
+++ b/src/et_core.h
@@ -332,7 +332,7 @@ gboolean ET_File_Name_Convert_Character          (gchar *filename_utf8);
 gchar   *ET_File_Name_Generate                   (ET_File *ETFile, gchar *new_file_name);
 guint ET_Get_Number_Of_Files_In_Directory (const gchar *path_utf8);
 
-gboolean ET_Detect_Changes_Of_File_Tag          (File_Tag  *FileTag1,  File_Tag  *FileTag2);
+gboolean ET_Detect_Changes_Of_File_Tag (const File_Tag *FileTag1, const File_Tag  *FileTag2);
 
 GList *ET_Sort_File_List (GList *ETFileList, EtSortMode Sorting_Type);
 void ET_Sort_Displayed_File_List_And_Update_UI (EtSortMode Sorting_Type);
diff --git a/src/tags/flac_tag.c b/src/tags/flac_tag.c
index 54c35fc..965688a 100644
--- a/src/tags/flac_tag.c
+++ b/src/tags/flac_tag.c
@@ -734,7 +734,7 @@ flac_tag_read_file_tag (const gchar *filename,
       && FileTag->encoded_by  == NULL
       && FileTag->picture     == NULL)
     {
-        gint rc = Id3tag_Read_File_Tag(filename,FileTag);
+        gboolean rc = id3tag_read_file_tag (filename, FileTag, NULL);
 
         // If an ID3 tag has been found (and no FLAC tag), we mark the file as
         // unsaved to rewrite a flac tag.
@@ -1155,7 +1155,7 @@ flac_tag_write_file_tag (ET_File *ETFile, GError **error)
         // With empty tag...
         ETFile_tmp->FileTagList  = g_list_append(NULL,FileTag_tmp);
         ETFile_tmp->FileTag      = ETFile_tmp->FileTagList;
-        Id3tag_Write_File_Tag(ETFile_tmp);
+        id3tag_write_file_tag (ETFile_tmp, NULL);
         ET_Free_File_List_Item(ETFile_tmp);
     }
 #endif
diff --git a/src/tags/id3_tag.c b/src/tags/id3_tag.c
index 756b5dd..a11e57c 100644
--- a/src/tags/id3_tag.c
+++ b/src/tags/id3_tag.c
@@ -76,7 +76,7 @@ ID3_C_EXPORT size_t ID3Field_GetUNICODE_1 (const ID3Field *field, unicode_t *buf
 static gboolean et_id3tag_check_if_file_is_corrupted (GFile *file,
                                                       GError **error);
 
-static gboolean Id3tag_Check_If_Id3lib_Is_Bugged (void);
+static gboolean id3tag_check_if_id3lib_is_buggy (GError **error);
 
 
 
@@ -92,7 +92,7 @@ static gboolean Id3tag_Check_If_Id3lib_Is_Bugged (void);
  * Returns: a newly allocated string, should be freed using g_free.
  */
 gchar *
-et_id3tag_get_tpos_from_file_tag (File_Tag *FileTag)
+et_id3tag_get_tpos_from_file_tag (const File_Tag *FileTag)
 {
     GString *gstring;
     gchar *p;
@@ -135,20 +135,19 @@ et_id3tag_get_tpos_from_file_tag (File_Tag *FileTag)
  * Write the ID3 tags to the file. Returns TRUE on success, else 0.
  */
 static gboolean
-Id3tag_Write_File_v23Tag (ET_File *ETFile)
+id3tag_write_file_v23tag (ET_File *ETFile, GError **error)
 {
-    File_Tag *FileTag;
-    gchar    *filename;
-    gchar    *filename_utf8;
+    const File_Tag *FileTag;
+    const gchar *filename;
+    const gchar *filename_utf8;
     gchar    *basename_utf8;
     GFile *file;
-    GError *gerror = NULL;
     ID3Tag   *id3_tag = NULL;
     ID3_Err   error_strip_id3v1  = ID3E_NoError;
     ID3_Err   error_strip_id3v2  = ID3E_NoError;
     ID3_Err   error_update_id3v1 = ID3E_NoError;
     ID3_Err   error_update_id3v2 = ID3E_NoError;
-    gint error = 0;
+    gboolean success = TRUE;
     gint number_of_frames;
     gboolean has_title       = FALSE;
     gboolean has_artist      = FALSE;
@@ -176,6 +175,7 @@ Id3tag_Write_File_v23Tag (ET_File *ETFile)
     Picture *pic;
 
     g_return_val_if_fail (ETFile != NULL && ETFile->FileTag != NULL, FALSE);
+    g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
     // When writing the first MP3 file, we check if the version of id3lib of the
     // system doesn't contain a bug when writting Unicode tags
@@ -183,7 +183,7 @@ Id3tag_Write_File_v23Tag (ET_File *ETFile)
         && g_settings_get_boolean (MainSettings, "id3v2-enable-unicode"))
     {
         flag_first_check = FALSE;
-        flag_id3lib_bugged = Id3tag_Check_If_Id3lib_Is_Bugged ();
+        flag_id3lib_bugged = id3tag_check_if_id3lib_is_buggy (NULL);
     }
 
     FileTag  = (File_Tag *)ETFile->FileTag->data;
@@ -192,21 +192,15 @@ Id3tag_Write_File_v23Tag (ET_File *ETFile)
 
     file = g_file_new_for_path (filename);
 
+    /* FIXME: Handle this in the caller instead. */
     /* This is a protection against a bug in id3lib that enters an infinite
      * loop with corrupted MP3 files (files containing only zeroes) */
-    if (et_id3tag_check_if_file_is_corrupted (file, &gerror))
+    if (et_id3tag_check_if_file_is_corrupted (file, error))
     {
         GtkWidget *msgdialog;
         gchar *basename;
         gchar *basename_utf8;
 
-        if (gerror)
-        {
-            Log_Print (LOG_ERROR, _("Error while reading file ‘%s’: %s"),
-                       filename_utf8, gerror->message);
-            g_error_free (gerror);
-        }
-
         basename = g_file_get_basename (file);
         basename_utf8 = filename_to_display (basename);
 
@@ -229,8 +223,12 @@ Id3tag_Write_File_v23Tag (ET_File *ETFile)
 
     /* We get again the tag from the file to keep also unused data (by EasyTAG), then
      * we replace the changed data */
-    if ( (id3_tag = ID3Tag_New()) == NULL )
+    if ((id3_tag = ID3Tag_New ()) == NULL)
+    {
+        g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOMEM,
+                     g_strerror (ENOMEM));
         return FALSE;
+    }
 
     basename_utf8 = g_path_get_basename(filename_utf8);
 
@@ -600,24 +598,26 @@ Id3tag_Write_File_v23Tag (ET_File *ETFile)
         {
             if (error_strip_id3v1 != ID3E_NoError)
             {
-                Log_Print (LOG_ERROR,
-                           _("Error while removing ID3v1 tag of ‘%s’: %s"),
-                           basename_utf8,
-                           Id3tag_Get_Error_Message (error_strip_id3v1));
+                g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                             _("Error while removing ID3v1 tag of ‘%s’: %s"),
+                             basename_utf8,
+                             Id3tag_Get_Error_Message (error_strip_id3v1));
             }
 
             if (error_strip_id3v2 != ID3E_NoError)
             {
-                Log_Print (LOG_ERROR,
-                           _("Error while removing ID3v2 tag of ‘%s’: %s"),
-                           basename_utf8,
-                           Id3tag_Get_Error_Message (error_strip_id3v2));
+                g_clear_error (error);
+                g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                             _("Error while removing ID3v2 tag of ‘%s’: %s"),
+                             basename_utf8,
+                             Id3tag_Get_Error_Message (error_strip_id3v2));
             }
 
-            error++;
+            success = FALSE;
         }
 
-    }else
+    }
+    else
     {
         /* It's better to remove the id3v1 tag before, to synchronize it with the
          * id3v2 tag (else id3lib doesn't do it correctly)
@@ -633,12 +633,13 @@ Id3tag_Write_File_v23Tag (ET_File *ETFile)
             error_update_id3v2 = ID3Tag_UpdateByTagType(id3_tag,ID3TT_ID3V2);
             if (error_update_id3v2 != ID3E_NoError)
             {
-                Log_Print (LOG_ERROR,
-                           _("Error while updating ID3v2 tag of ‘%s’: %s"),
-                           basename_utf8,
-                           Id3tag_Get_Error_Message (error_update_id3v2));
-                error++;
-            }else
+                g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                             _("Error while updating ID3v2 tag of ‘%s’: %s"),
+                             basename_utf8,
+                             Id3tag_Get_Error_Message (error_update_id3v2));
+                success = FALSE;
+            }
+            else
             {
                 /* See known problem on the top : [ 1016290 ] Unicode16 writing bug.
                  * When we write the tag in Unicode, we try to check if it was correctly
@@ -646,20 +647,18 @@ Id3tag_Write_File_v23Tag (ET_File *ETFile)
                  * with the previous one. We check up to find an error (as only some
                  * characters are affected).
                  * If the patch to id3lib was applied to fix the problem (tested
-                 * by Id3tag_Check_If_Id3lib_Is_Bugged) we didn't make the following
+                 * by id3tag_check_if_id3lib_is_buggy) we didn't make the following
                  * test => OK */
                 if (flag_id3lib_bugged
                     && g_settings_get_boolean (MainSettings,
                                                "id3v2-enable-unicode"))
                 {
                     File_Tag  *FileTag_tmp = ET_File_Tag_Item_New();
-                    if (Id3tag_Read_File_Tag(filename,FileTag_tmp) == TRUE
+                    if (id3tag_read_file_tag (filename, FileTag_tmp, NULL) == TRUE
                     &&  ET_Detect_Changes_Of_File_Tag(FileTag,FileTag_tmp) == TRUE)
                     {
                         GtkWidget *msgdialog;
 
-                        //Log_Print(LOG_ERROR,msg);
-
                         msgdialog = gtk_message_dialog_new(GTK_WINDOW(MainWindow),
                                                            GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
                                                            GTK_MESSAGE_ERROR,
@@ -683,16 +682,17 @@ Id3tag_Write_File_v23Tag (ET_File *ETFile)
                 }
 
             }
-        }else
+        }
+        else
         {
             error_strip_id3v2 = ID3Tag_Strip(id3_tag,ID3TT_ID3V2);
             if (error_strip_id3v2 != ID3E_NoError)
             {
-                Log_Print (LOG_ERROR,
-                           _("Error while removing ID3v2 tag of ‘%s’: %s"),
-                           basename_utf8,
-                           Id3tag_Get_Error_Message (error_strip_id3v2));
-                error++;
+                g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                             _("Error while removing ID3v2 tag of ‘%s’: %s"),
+                             basename_utf8,
+                             Id3tag_Get_Error_Message (error_strip_id3v2));
+                success = FALSE;
             }
         }
 
@@ -712,26 +712,28 @@ Id3tag_Write_File_v23Tag (ET_File *ETFile)
             error_update_id3v1 = ID3Tag_UpdateByTagType(id3_tag,ID3TT_ID3V1);
             if (error_update_id3v1 != ID3E_NoError)
             {
-                Log_Print (LOG_ERROR,
-                           _("Error while updating ID3v1 tag of ‘%s’: %s"),
-                           basename_utf8,
-                           Id3tag_Get_Error_Message (error_update_id3v1));
-                error++;
+                g_clear_error (error);
+                g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                             _("Error while updating ID3v1 tag of ‘%s’: %s"),
+                             basename_utf8,
+                             Id3tag_Get_Error_Message (error_update_id3v1));
+                success = FALSE;
             }
         }else
         {
             error_strip_id3v1 = ID3Tag_Strip(id3_tag,ID3TT_ID3V1);
             if (error_strip_id3v1 != ID3E_NoError)
             {
-                Log_Print (LOG_ERROR,
-                           _("Error while removing ID3v1 tag of ‘%s’: %s"),
-                           basename_utf8,
-                           Id3tag_Get_Error_Message (error_strip_id3v1));
-                error++;
+                g_clear_error (error);
+                g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                             _("Error while removing ID3v1 tag of ‘%s’: %s"),
+                             basename_utf8,
+                             Id3tag_Get_Error_Message (error_strip_id3v1));
+                success = FALSE;
             }
         }
 
-        if (error == 0)
+        if (success)
         {
             Log_Print (LOG_OK, _("Updated tag of ‘%s’"), basename_utf8);
         }
@@ -742,9 +744,7 @@ Id3tag_Write_File_v23Tag (ET_File *ETFile)
     ID3Tag_Delete(id3_tag);
     g_free(basename_utf8);
 
-    if (error) return FALSE;
-    else       return TRUE;
-
+    return success;
 }
 
 
@@ -940,7 +940,8 @@ gchar *Id3tag_Get_Field (const ID3Frame *id3_frame, ID3_FieldID id3_fieldid)
         // Data of the field must be a TEXT (ID3FTY_TEXTSTRING)
         if (ID3Field_GetType(id3_field) != ID3FTY_TEXTSTRING)
         {
-            Log_Print(LOG_ERROR,"Id3tag_Get_Field() must be used only for fields containing text.\n");
+            g_critical ("%s",
+                        "Id3tag_Get_Field() must be used only for fields containing text");
             return NULL;
         }
 
@@ -1045,7 +1046,7 @@ out:
     if (num_chars && !string1)
     {
         gchar *escaped_str = g_strescape(string, NULL);
-        Log_Print(LOG_OK,"Id3tag_Get_Field: Trying to fix string '%s'…",escaped_str);
+        g_debug ("Id3tag_Get_Field: Trying to fix string '%s'…", escaped_str);
         g_free(escaped_str);
 
         string1 = filename_to_display(string);
@@ -1098,7 +1099,8 @@ Id3tag_Set_Field (const ID3Frame *id3_frame,
         // Data of the field must be a TEXT (ID3FTY_TEXTSTRING)
         if (ID3Field_GetType(id3_field) != ID3FTY_TEXTSTRING)
         {
-            Log_Print(LOG_ERROR,"Id3tag_Set_Field() must be used only for fields containing text.");
+            g_critical ("%s",
+                        "Id3tag_Set_Field() must be used only for fields containing text");
             return ID3TE_NONE;
         }
 
@@ -1428,12 +1430,12 @@ et_id3tag_check_if_file_is_corrupted (GFile *file, GError **error)
  * Function to detect if id3lib isn't bugged when writting to Unicode
  * Returns TRUE if bugged, else FALSE
  */
-gboolean Id3tag_Check_If_Id3lib_Is_Bugged (void)
+static gboolean
+id3tag_check_if_id3lib_is_buggy (GError **error)
 {
     GFile *file;
     GFileIOStream *iostream = NULL;
     GOutputStream *ostream = NULL;
-    GError *error = NULL;
     guchar tmp[16] = {0xFF, 0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
     ID3Tag *id3_tag = NULL;
@@ -1444,21 +1446,18 @@ gboolean Id3tag_Check_If_Id3lib_Is_Bugged (void)
     gsize bytes_written;
     const gchar test_str[] = "\xe5\x92\xbb";
 
+    g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
     /* Create a temporary file. */
-    file = g_file_new_tmp ("easytagXXXXXX.mp3", &iostream, &error);
+    file = g_file_new_tmp ("easytagXXXXXX.mp3", &iostream, error);
+
     if (!file)
     {
-        if (error)
+        /* TODO: Investigate whether error can be unset in this case. */
+        if (!error)
         {
-            Log_Print (LOG_ERROR,
-                       _("Error while creating temporary file ‘%s’"),
-                       error->message);
-            g_clear_error (&error);
-        }
-        else
-        {
-            Log_Print (LOG_ERROR, "%s",
-                       _("Error while creating temporary file"));
+            g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT, "%s",
+                         _("Error while creating temporary file"));
         }
 
         return FALSE;
@@ -1466,24 +1465,14 @@ gboolean Id3tag_Check_If_Id3lib_Is_Bugged (void)
 
     /* Set data in the file. */
     ostream = g_io_stream_get_output_stream (G_IO_STREAM (iostream));
+
     if (!g_output_stream_write_all (G_OUTPUT_STREAM (ostream), tmp,
                                     sizeof (tmp), &bytes_written, NULL,
-                                    &error))
+                                    error))
     {
-        gchar *filename;
-        gchar *filename_utf8;
-
         g_debug ("Only %" G_GSIZE_FORMAT " bytes out of %" G_GSIZE_FORMAT
                  " bytes of data were written", bytes_written, sizeof (tmp));
 
-        filename = g_file_get_path (file);
-        filename_utf8 = filename_to_display (filename);
-        Log_Print (LOG_ERROR, _("Error while writing to file ‘%s’: %s"),
-                   filename_utf8, error->message);
-
-        g_free (filename);
-        g_free (filename_utf8);
-        g_clear_error (&error);
         g_object_unref (file);
         g_output_stream_close (G_OUTPUT_STREAM (ostream), NULL, NULL);
 
@@ -1540,6 +1529,8 @@ gboolean Id3tag_Check_If_Id3lib_Is_Bugged (void)
     }
 
     g_free (result);
+    g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "%s",
+                 "Buggy id3lib detected");
     return FALSE;
 }
 
@@ -1549,15 +1540,21 @@ gboolean Id3tag_Check_If_Id3lib_Is_Bugged (void)
 /*
  * Write tag according the version selected by the user
  */
-gboolean Id3tag_Write_File_Tag (ET_File *ETFile)
+gboolean
+id3tag_write_file_tag (ET_File *ETFile,
+                       GError **error)
 {
 #ifdef ENABLE_ID3LIB
     if (g_settings_get_boolean (MainSettings, "id3v2-version-4"))
-        return Id3tag_Write_File_v24Tag(ETFile);
+    {
+        return id3tag_write_file_v24tag (ETFile, error);
+    }
     else
-        return Id3tag_Write_File_v23Tag(ETFile);
+    {
+        return id3tag_write_file_v23tag (ETFile, error);
+    }
 #else
-    return Id3tag_Write_File_v24Tag(ETFile);
+    return id3tag_write_file_v24tag (ETFile, error);
 #endif /* !ENABLE_ID3LIB */
 }
 
diff --git a/src/tags/id3_tag.h b/src/tags/id3_tag.h
index a167ca5..e8ec743 100644
--- a/src/tags/id3_tag.h
+++ b/src/tags/id3_tag.h
@@ -27,14 +27,14 @@ G_BEGIN_DECLS
 
 #define ID3_INVALID_GENRE 255
 
-gboolean Id3tag_Read_File_Tag (const gchar *filename, File_Tag *FileTag);
-gboolean Id3tag_Write_File_v24Tag (ET_File *ETFile);
-gboolean Id3tag_Write_File_Tag    (ET_File *ETFile);
+gboolean id3tag_read_file_tag (const gchar *filename, File_Tag *FileTag, GError **error);
+gboolean id3tag_write_file_v24tag (ET_File *ETFile, GError **error);
+gboolean id3tag_write_file_tag (ET_File *ETFile, GError **error);
 
 const gchar * Id3tag_Genre_To_String (unsigned char genre_code);
 guchar Id3tag_String_To_Genre (const gchar *genre);
 
-gchar *et_id3tag_get_tpos_from_file_tag (File_Tag *file_tag);
+gchar *et_id3tag_get_tpos_from_file_tag (const File_Tag *file_tag);
 
 G_END_DECLS
 
diff --git a/src/tags/id3v24_tag.c b/src/tags/id3v24_tag.c
index 1c59ff9..d334af7 100644
--- a/src/tags/id3v24_tag.c
+++ b/src/tags/id3v24_tag.c
@@ -78,8 +78,8 @@ static void   Id3tag_delete_txxframes   (struct id3_tag *tag, const gchar *param
 static struct id3_frame *Id3tag_find_and_create_frame    (struct id3_tag *tag, const gchar *name);
 static int    id3taglib_set_field       (struct id3_frame *frame, const gchar *str, enum id3_field_type 
type, int num, int clear, int id3v1);
 static int    etag_set_tags             (const gchar *str, const char *frame_name, enum id3_field_type 
field_type, struct id3_tag *v1tag, struct id3_tag *v2tag, gboolean *strip_tags);
-static int etag_write_tags (const gchar *filename, struct id3_tag const *v1tag,
-                            struct id3_tag const *v2tag, gboolean strip_tags);
+static gboolean etag_write_tags (const gchar *filename, struct id3_tag const *v1tag,
+                            struct id3_tag const *v2tag, gboolean strip_tags, GError **error);
 
 /*************
  * Functions *
@@ -91,8 +91,9 @@ static int etag_write_tags (const gchar *filename, struct id3_tag const *v1tag,
  * If a tag entry exists (ex: title), we allocate memory, else value stays to NULL
  */
 gboolean
-Id3tag_Read_File_Tag (const gchar *filename,
-                      File_Tag *FileTag)
+id3tag_read_file_tag (const gchar *filename,
+                      File_Tag *FileTag,
+                      GError **error)
 {
     int tmpfile;
     struct id3_file *file;
@@ -105,15 +106,13 @@ Id3tag_Read_File_Tag (const gchar *filename,
     unsigned tmpupdate, update = 0;
     long tagsize;
 
-
     g_return_val_if_fail (filename != NULL && FileTag != NULL, FALSE);
+    g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
-    if ( (tmpfile=open(filename,O_RDONLY)) < 0 )
+    if ((tmpfile = open (filename, O_RDONLY)) < 0)
     {
-        gchar *filename_utf8 = filename_to_display(filename);
-        Log_Print (LOG_ERROR, _("Error while opening file ‘%s’: %s"),
-                   filename_utf8, g_strerror (errno));
-        g_free(filename_utf8);
+        g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+                     _("Error while opening file: %s"), g_strerror (errno));
         return FALSE;
     }
 
@@ -872,21 +871,24 @@ libid3tag_Get_Frame_Str (const struct id3_frame *frame,
 /*
  * Write the ID3 tags to the file. Returns TRUE on success, else 0.
  */
-gboolean Id3tag_Write_File_v24Tag (ET_File *ETFile)
+gboolean
+id3tag_write_file_v24tag (ET_File *ETFile, GError **error)
 {
-    File_Tag         *FileTag;
-    gchar            *filename, *filename_utf8;
-    gchar            *basename_utf8;
+    const File_Tag *FileTag;
+    const gchar *filename;
+    const gchar *filename_utf8;
+    gchar *basename_utf8;
     struct id3_tag   *v1tag, *v2tag;
     struct id3_frame *frame;
     union id3_field  *field;
     gchar            *string1;
     Picture          *pic;
-    gint error = 0;
     gboolean strip_tags = TRUE;
     guchar genre_value = ID3_INVALID_GENRE;
+    gboolean success;
 
     g_return_val_if_fail (ETFile != NULL && ETFile->FileTag != NULL, FALSE);
+    g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
     FileTag       = (File_Tag *)ETFile->FileTag->data;
     filename      = ((File_Name *)ETFile->FileNameCur->data)->value;
@@ -1138,7 +1140,7 @@ gboolean Id3tag_Write_File_v24Tag (ET_File *ETFile)
     /*********************************
      * Update id3v1.x and id3v2 tags *
      *********************************/
-    error |= etag_write_tags(filename, v1tag, v2tag, strip_tags);
+    success = etag_write_tags (filename, v1tag, v2tag, strip_tags, error);
 
     // Free data
     if (v1tag)
@@ -1146,16 +1148,14 @@ gboolean Id3tag_Write_File_v24Tag (ET_File *ETFile)
     if (v2tag)
         id3_tag_delete(v2tag);
 
-    if (error == 0)
+    if (success)
     {
         basename_utf8 = g_path_get_basename(filename_utf8);
         Log_Print (LOG_OK, _("Updated tag of ‘%s’"), basename_utf8);
         g_free(basename_utf8);
     }
 
-    if (error) return FALSE;
-    else       return TRUE;
-
+    return success;
 }
 
 /* Dele all frames with 'name'
@@ -1463,11 +1463,12 @@ etag_set_tags (const gchar *str,
     return 0;
 }
 
-static int
+static gboolean
 etag_write_tags (const gchar *filename, 
                  struct id3_tag const *v1tag,
                  struct id3_tag const *v2tag,
-                 gboolean strip_tags)
+                 gboolean strip_tags,
+                 GError **error)
 {
     id3_byte_t *v1buf, *v2buf;
     id3_length_t v1size = 0, v2size = 0;
@@ -1477,7 +1478,7 @@ etag_write_tags (const gchar *filename,
     long filev2size;
     gsize ctxsize;
     char *ctx = NULL;
-    int err = 0;
+    gboolean success = TRUE;
     gssize size_read = 0;
 
     v1buf = v2buf = NULL;
@@ -1521,20 +1522,21 @@ etag_write_tags (const gchar *filename,
     if (v2buf == NULL)
         v2size = 0;
 
-    if ((fd = open(filename, O_RDWR)) < 0)
+    if ((fd = open (filename, O_RDWR)) < 0)
     {
-        err = errno;
-        g_free(v1buf);
-        g_free(v2buf);
-        return (err);
+        g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+                     "%s", g_strerror (errno));
+        g_free (v1buf);
+        g_free (v2buf);
+        return FALSE;
     }
 
-    err = 1;
+    success = FALSE;
 
     /* Handle Id3v1 tag */
-    if ((curpos = lseek(fd, -128, SEEK_END)) < 0)
+    if ((curpos = lseek (fd, -128, SEEK_END)) < 0)
         goto out;
-    if ( (size_read = read(fd, tmp, ID3_TAG_QUERYSIZE)) != ID3_TAG_QUERYSIZE)
+    if ((size_read = read (fd, tmp, ID3_TAG_QUERYSIZE)) != ID3_TAG_QUERYSIZE)
     {
         goto out;
     }
@@ -1558,36 +1560,35 @@ etag_write_tags (const gchar *filename,
 
     /* Search id3v2 tags at the end of the file (before any ID3v1 tag) */
     /* XXX: Unsafe */
-    if ((curpos = lseek(fd, -ID3_TAG_QUERYSIZE, SEEK_CUR)) >= 0)
+    if ((curpos = lseek (fd, -ID3_TAG_QUERYSIZE, SEEK_CUR)) >= 0)
     {
-        if (read(fd, tmp, ID3_TAG_QUERYSIZE) != ID3_TAG_QUERYSIZE)
+        if (read (fd, tmp, ID3_TAG_QUERYSIZE) != ID3_TAG_QUERYSIZE)
             goto out;
         filev2size = id3_tag_query((id3_byte_t const *)tmp, ID3_TAG_QUERYSIZE);
-        if ( (filev2size > 10)
-        &&   (curpos = lseek(fd, -filev2size, SEEK_CUR)) )
+        if ((filev2size > 10) && (curpos = lseek (fd, -filev2size, SEEK_CUR)))
         {
-            if ( (size_read = read(fd, tmp, ID3_TAG_QUERYSIZE)) != ID3_TAG_QUERYSIZE)
+            if ((size_read = read (fd, tmp, ID3_TAG_QUERYSIZE)) != ID3_TAG_QUERYSIZE)
             {
                 goto out;
             }
             if (id3_tag_query((id3_byte_t const *)tmp, ID3_TAG_QUERYSIZE) != filev2size)
-                curpos = lseek(fd, -ID3_TAG_QUERYSIZE - filev2size, SEEK_CUR);
+                curpos = lseek (fd, -ID3_TAG_QUERYSIZE - filev2size, SEEK_CUR);
             else
-                curpos = lseek(fd, -ID3_TAG_QUERYSIZE, SEEK_CUR);
+                curpos = lseek (fd, -ID3_TAG_QUERYSIZE, SEEK_CUR);
         }
     }
 
     /* Write id3v1 tag */
     if (v1buf)
     {
-        if ( write(fd, v1buf, v1size) != v1size)
+        if (write (fd, v1buf, v1size) != v1size)
             goto out;
     }
 
     /* Truncate file (strip tags at the end of file) */
-    if ((curpos = lseek(fd, 0, SEEK_CUR)) <= 0 )
+    if ((curpos = lseek (fd, 0, SEEK_CUR)) <= 0)
         goto out;
-    if ((err = ftruncate(fd, curpos)))
+    if (ftruncate (fd, curpos) == -1)
         goto out;
 
     /* Handle Id3v2 tag */
@@ -1616,13 +1617,13 @@ etag_write_tags (const gchar *filename,
     {
         /* XXX */
         // Size of audio data (tags at the end were already removed)
-        ctxsize = lseek(fd, 0, SEEK_END) - filev2size;
+        ctxsize = lseek (fd, 0, SEEK_END) - filev2size;
 
         if ((ctx = g_try_malloc(ctxsize)) == NULL)
             goto out;
-        if ((curpos = lseek(fd, filev2size, SEEK_SET)) < 0)
+        if ((curpos = lseek (fd, filev2size, SEEK_SET)) < 0)
             goto out;
-        if ((size_read = /*err = */read(fd, ctx, ctxsize)) != ctxsize)
+        if ((size_read = read (fd, ctx, ctxsize)) != ctxsize)
         {
             gchar *filename_utf8 = filename_to_display(filename);
             gchar *basename_utf8 = g_path_get_basename(filename_utf8);
@@ -1633,24 +1634,24 @@ etag_write_tags (const gchar *filename,
              * support macros in extracted strings.
              * https://bugzilla.gnome.org/show_bug.cgi?id=705952
              */
-            Log_Print (LOG_ERROR,
-                       /* Translators: The first string is a filename, the
-                        * second string is the number of bytes that were
-                        * missing (not read for some reason) while reading from
-                        * the file.
-                        */
-                       ngettext ("Cannot write tag of file ‘%s’ (a byte was missing)",
-                                 "Cannot write tag of file ‘%s’ (%s bytes were missing)",
-                                 ctxsize - size_read),
-                       basename_utf8, bytes_missing);
-            g_free(filename_utf8);
-            g_free(basename_utf8);
+            g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+                         /* Translators: The first string is a filename, the
+                          * second string is the number of bytes that were
+                          * missing (not read for some reason) while reading
+                          * from the file.
+                          */
+                         ngettext ("Cannot write tag of file ‘%s’ (a byte was missing)",
+                                   "Cannot write tag of file ‘%s’ (%s bytes were missing)",
+                                   ctxsize - size_read),
+                         basename_utf8, bytes_missing);
+            g_free (filename_utf8);
+            g_free (basename_utf8);
             g_free (bytes_missing);
             goto out;
         }
         
         // Return to the beginning of the file
-        if (lseek(fd, 0, SEEK_SET) < 0)
+        if (lseek (fd, 0, SEEK_SET) < 0)
             goto out;
             
         // Write the ID3v2 tag
@@ -1660,8 +1661,9 @@ etag_write_tags (const gchar *filename,
             {
                 gchar *filename_utf8 = filename_to_display (filename);
                 gchar *basename_utf8 = g_path_get_basename (filename_utf8);
-                Log_Print (LOG_ERROR, _("Cannot save tag of file ‘%s’"),
-                           basename_utf8);
+                g_set_error (error, G_FILE_ERROR,
+                             g_file_error_from_errno (errno),
+                             _("Cannot save tag of file ‘%s’"), basename_utf8);
                 g_free (basename_utf8);
                 goto out;
             }
@@ -1671,29 +1673,30 @@ etag_write_tags (const gchar *filename,
         {
             gchar *filename_utf8 = filename_to_display(filename);
             gchar *basename_utf8 = g_path_get_basename(filename_utf8);
-            Log_Print (LOG_ERROR,
-                       _("Size error while saving tag of ‘%s’"),
-                       basename_utf8);
-            g_free(filename_utf8);
-            g_free(basename_utf8);
+            g_set_error (error, G_FILE_ERROR,
+                         g_file_error_from_errno (errno),
+                         _("Size error while saving tag of ‘%s’"),
+                         basename_utf8);
+            g_free (filename_utf8);
+            g_free (basename_utf8);
             goto out;
         }
 
-        if ((curpos = lseek(fd, 0, SEEK_CUR)) <= 0 )
+        if ((curpos = lseek (fd, 0, SEEK_CUR)) <= 0)
             goto out;
 
-        if ((err = ftruncate(fd, curpos)))
+        if (ftruncate (fd, curpos) < 0)
             goto out;
     }
 
-    err = 0;
+    success = TRUE;
 out:
     g_free(ctx);
     lseek(fd, 0, SEEK_SET);
     close(fd);
     g_free(v1buf);
     g_free(v2buf);
-    return err;
+    return success;
 }
 
 #endif /* ENABLE_MP3 */
diff --git a/src/tags/mpeg_header.c b/src/tags/mpeg_header.c
index ea60154..c88cef2 100644
--- a/src/tags/mpeg_header.c
+++ b/src/tags/mpeg_header.c
@@ -1,21 +1,20 @@
-/* mpeg_header.c - 2000/05/12 */
-/*
- *  EasyTAG - Tag editor for MP3 and Ogg Vorbis files
- *  Copyright (C) 2000-2003  Jerome Couderc <easytag gmail com>
+/* EasyTAG - Tag editor for MP3 and Ogg Vorbis files
+ * Copyright (C) 2014  David King <amigadave amigadave com>
+ * Copyright (C) 2000-2003  Jerome Couderc <easytag gmail com>
  *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
  *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
 #include "config.h"
@@ -24,6 +23,7 @@
 
 #include <gtk/gtk.h>
 #include <glib/gi18n.h>
+#include <errno.h>
 
 #include "mpeg_header.h"
 #include "easytag.h"
@@ -63,13 +63,13 @@ channel_mode_name (int mode)
     return _(channel_mode[mode]);
 }
 
-
-
 /*
  * Read infos into header of first frame
  */
 gboolean
-Mpeg_Header_Read_File_Info (const gchar *filename, ET_File_Info *ETFileInfo)
+mpeg_header_read_file_info (const gchar *filename,
+                            ET_File_Info *ETFileInfo,
+                            GError **error)
 {
     /*
      * With id3lib, the header frame couldn't be read if the file contains an ID3v2 tag with an APIC frame
@@ -78,13 +78,18 @@ Mpeg_Header_Read_File_Info (const gchar *filename, ET_File_Info *ETFileInfo)
     const Mp3_Headerinfo* headerInfo = NULL;
 
     g_return_val_if_fail (filename != NULL || ETFileInfo != NULL, FALSE);
+    g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
     /* Get size of file */
     ETFileInfo->size = et_get_file_size (filename);
 
     /* Get data from tag */
-    if ( (id3_tag = ID3Tag_New()) == NULL )
+    if ((id3_tag = ID3Tag_New()) == NULL)
+    {
+        g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOMEM, "%s",
+                     g_strerror (ENOMEM));
         return FALSE;
+    }
 
     /* Link the file to the tag (uses ID3TT_ID3V2 to get header if APIC is present in Tag) */
     ID3Tag_LinkWithFlags(id3_tag,filename,ID3TT_ID3V2);
diff --git a/src/tags/mpeg_header.h b/src/tags/mpeg_header.h
index f73abf3..e726a8e 100644
--- a/src/tags/mpeg_header.h
+++ b/src/tags/mpeg_header.h
@@ -24,7 +24,7 @@
 
 G_BEGIN_DECLS
 
-gboolean Mpeg_Header_Read_File_Info (const gchar *filename, ET_File_Info *ETFileInfo);
+gboolean mpeg_header_read_file_info (const gchar *filename, ET_File_Info *ETFileInfo, GError **error);
 EtFileHeaderFields * Mpeg_Header_Display_File_Info_To_UI (const gchar *filename, ET_File *ETFile);
 void et_mpeg_file_header_fields_free (EtFileHeaderFields *fields);
 


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