r23502 - gnucash/branches/2.4/src/backend/xml - [23412]Decompress zipped XML files ourself instead of letting libxml2 do it.

Geert Janssens gjanssens at code.gnucash.org
Sat Dec 7 11:07:58 EST 2013


Author: gjanssens
Date: 2013-12-07 11:07:58 -0500 (Sat, 07 Dec 2013)
New Revision: 23502
Trac: http://svn.gnucash.org/trac/changeset/23502

Modified:
   gnucash/branches/2.4/src/backend/xml/io-gncxml-gen.c
   gnucash/branches/2.4/src/backend/xml/io-gncxml-gen.h
   gnucash/branches/2.4/src/backend/xml/io-gncxml-v2.c
   gnucash/branches/2.4/src/backend/xml/sixtp.c
   gnucash/branches/2.4/src/backend/xml/sixtp.h
Log:
[23412]Decompress zipped XML files ourself instead of letting libxml2 do it.
As of version 2.9.1 it has a bug that causes it to fail to decompress certain files.
See https://bugzilla.gnome.org/show_bug.cgi?id=712528 for more info.

Modified: gnucash/branches/2.4/src/backend/xml/io-gncxml-gen.c
===================================================================
--- gnucash/branches/2.4/src/backend/xml/io-gncxml-gen.c	2013-12-07 15:57:46 UTC (rev 23501)
+++ gnucash/branches/2.4/src/backend/xml/io-gncxml-gen.c	2013-12-07 16:07:58 UTC (rev 23502)
@@ -41,3 +41,19 @@
     return sixtp_parse_file(top_parser, filename,
                             NULL, &gpdata, &parse_result);
 }
+
+gboolean
+gnc_xml_parse_fd(sixtp *top_parser, FILE *fd,
+                 gxpf_callback callback, gpointer parsedata,
+                 gpointer bookdata)
+{
+    gpointer parse_result = NULL;
+    gxpf_data gpdata;
+
+    gpdata.cb = callback;
+    gpdata.parsedata = parsedata;
+    gpdata.bookdata = bookdata;
+
+    return sixtp_parse_fd(top_parser, fd,
+                          NULL, &gpdata, &parse_result);
+}

Modified: gnucash/branches/2.4/src/backend/xml/io-gncxml-gen.h
===================================================================
--- gnucash/branches/2.4/src/backend/xml/io-gncxml-gen.h	2013-12-07 15:57:46 UTC (rev 23501)
+++ gnucash/branches/2.4/src/backend/xml/io-gncxml-gen.h	2013-12-07 16:07:58 UTC (rev 23502)
@@ -45,4 +45,9 @@
                    gxpf_callback callback, gpointer parsedata,
                    gpointer bookdata);
 
+gboolean
+gnc_xml_parse_fd(sixtp *top_parser, FILE *fd,
+                 gxpf_callback callback, gpointer parsedata,
+                 gpointer bookdata);
+
 #endif /* IO_GNCXML_GEN_H */

Modified: gnucash/branches/2.4/src/backend/xml/io-gncxml-v2.c
===================================================================
--- gnucash/branches/2.4/src/backend/xml/io-gncxml-v2.c	2013-12-07 15:57:46 UTC (rev 23501)
+++ gnucash/branches/2.4/src/backend/xml/io-gncxml-v2.c	2013-12-07 16:07:58 UTC (rev 23502)
@@ -99,6 +99,12 @@
 const gchar *gnc_v2_xml_version_string = GNC_V2_STRING;
 extern const gchar *gnc_v2_book_version_string;        /* see gnc-book-xml-v2 */
 
+/* Forward declarations */
+static FILE *try_gz_open (const char *filename, const char *perms, gboolean use_gzip,
+                          gboolean compress);
+static gboolean is_gzipped_file(const gchar *name);
+static gboolean wait_for_gzip(FILE *file);
+
 void
 run_callback(sixtp_gdv2 *data, const char *type)
 {
@@ -774,8 +780,38 @@
     }
     else
     {
-        retval = gnc_xml_parse_file(top_parser, fbe->fullpath,
-                                    generic_callback, gd, book);
+        /* Even though libxml2 knows how to decompress zipped files, we do it 
+           ourself since as of version 2.9.1 it has a bug that causes it to fail
+           to decompress certain files.  
+           See https://bugzilla.gnome.org/show_bug.cgi?id=712528 for more info */
+        gchar *filename = fbe->fullpath;
+#ifdef G_OS_WIN32
+        filename = g_win32_locale_filename_from_utf8(fbe->fulpath);
+        if (filename)
+        {
+#endif
+            FILE *file;
+            gboolean is_compressed = is_gzipped_file(filename);
+            file = try_gz_open(filename, "r", is_compressed, FALSE);
+            if (file == NULL)
+            {
+                PWARN("Unable to open file %s", filename);
+                retval = FALSE;
+            }
+            else
+            {
+                retval = gnc_xml_parse_fd(top_parser, file,
+                                          generic_callback, gd, book);
+                fclose(file);
+                if (is_compressed)
+                    wait_for_gzip(file);
+            }
+#ifdef G_OS_WIN32
+            g_free(filename);
+        else
+            retval = FALSE;
+        }
+#endif
     }
 
     if (!retval)

Modified: gnucash/branches/2.4/src/backend/xml/sixtp.c
===================================================================
--- gnucash/branches/2.4/src/backend/xml/sixtp.c	2013-12-07 15:57:46 UTC (rev 23501)
+++ gnucash/branches/2.4/src/backend/xml/sixtp.c	2013-12-07 16:07:58 UTC (rev 23502)
@@ -28,6 +28,7 @@
 #include <string.h>
 #include <ctype.h>
 #include <stdarg.h>
+#include <stdio.h>
 #include <sys/types.h>
 #ifdef _MSC_VER
 typedef int ssize_t;
@@ -759,7 +760,35 @@
     return ret;
 }
 
+/* Call back function for libxml2 to read from compressed or uncompressed stream */
+static int
+sixtp_parser_read(void *context, char *buffer, int len)
+{
+    int ret;
+    
+    ret = fread(&buffer[0], sizeof(char), len, (FILE *) context);
+    if (ret < 0)
+        g_warning("Error reading XML file");
+    return ret;
+}
+
 gboolean
+sixtp_parse_fd(sixtp *sixtp,
+               FILE *fd,
+               gpointer data_for_top_level,
+               gpointer global_data,
+               gpointer *parse_result)
+{
+    gboolean ret;
+    xmlParserCtxtPtr context = xmlCreateIOParserCtxt( NULL, NULL, 
+                                                     sixtp_parser_read, NULL /*no close */, fd, 
+                                                     XML_CHAR_ENCODING_NONE);
+    ret = sixtp_parse_file_common(sixtp, context, data_for_top_level,
+                                  global_data, parse_result);
+    return ret;
+}
+
+gboolean
 sixtp_parse_buffer(sixtp *sixtp,
                    char *bufp,
                    int bufsz,

Modified: gnucash/branches/2.4/src/backend/xml/sixtp.h
===================================================================
--- gnucash/branches/2.4/src/backend/xml/sixtp.h	2013-12-07 15:57:46 UTC (rev 23501)
+++ gnucash/branches/2.4/src/backend/xml/sixtp.h	2013-12-07 16:07:58 UTC (rev 23502)
@@ -185,6 +185,9 @@
 gboolean sixtp_parse_file(sixtp *sixtp, const char *filename,
                           gpointer data_for_top_level, gpointer global_data,
                           gpointer *parse_result);
+gboolean sixtp_parse_fd(sixtp *sixtp, FILE *fd,
+                        gpointer data_for_top_level, gpointer global_data,
+                        gpointer *parse_result);
 gboolean sixtp_parse_buffer(sixtp *sixtp, char *bufp, int bufsz,
                             gpointer data_for_top_level, gpointer global_data,
                             gpointer *parse_result);



More information about the gnucash-changes mailing list