r23412 - gnucash/trunk/src/backend/xml - Decompress zipped XML files ourself instead of letting libxml2 do it.
Mike Alexander
mta at code.gnucash.org
Mon Nov 18 22:47:08 EST 2013
Author: mta
Date: 2013-11-18 22:47:07 -0500 (Mon, 18 Nov 2013)
New Revision: 23412
Trac: http://svn.gnucash.org/trac/changeset/23412
Modified:
gnucash/trunk/src/backend/xml/io-gncxml-gen.c
gnucash/trunk/src/backend/xml/io-gncxml-gen.h
gnucash/trunk/src/backend/xml/io-gncxml-v2.c
gnucash/trunk/src/backend/xml/sixtp.c
gnucash/trunk/src/backend/xml/sixtp.h
Log:
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/trunk/src/backend/xml/io-gncxml-gen.c
===================================================================
--- gnucash/trunk/src/backend/xml/io-gncxml-gen.c 2013-11-18 08:00:44 UTC (rev 23411)
+++ gnucash/trunk/src/backend/xml/io-gncxml-gen.c 2013-11-19 03:47:07 UTC (rev 23412)
@@ -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/trunk/src/backend/xml/io-gncxml-gen.h
===================================================================
--- gnucash/trunk/src/backend/xml/io-gncxml-gen.h 2013-11-18 08:00:44 UTC (rev 23411)
+++ gnucash/trunk/src/backend/xml/io-gncxml-gen.h 2013-11-19 03:47:07 UTC (rev 23412)
@@ -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/trunk/src/backend/xml/io-gncxml-v2.c
===================================================================
--- gnucash/trunk/src/backend/xml/io-gncxml-v2.c 2013-11-18 08:00:44 UTC (rev 23411)
+++ gnucash/trunk/src/backend/xml/io-gncxml-v2.c 2013-11-19 03:47:07 UTC (rev 23412)
@@ -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/trunk/src/backend/xml/sixtp.c
===================================================================
--- gnucash/trunk/src/backend/xml/sixtp.c 2013-11-18 08:00:44 UTC (rev 23411)
+++ gnucash/trunk/src/backend/xml/sixtp.c 2013-11-19 03:47:07 UTC (rev 23412)
@@ -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/trunk/src/backend/xml/sixtp.h
===================================================================
--- gnucash/trunk/src/backend/xml/sixtp.h 2013-11-18 08:00:44 UTC (rev 23411)
+++ gnucash/trunk/src/backend/xml/sixtp.h 2013-11-19 03:47:07 UTC (rev 23412)
@@ -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