gnumeric r17301 - in trunk: . plugins/excel src



Author: jody
Date: Sun Apr  5 01:37:25 2009
New Revision: 17301
URL: http://svn.gnome.org/viewvc/gnumeric?rev=17301&view=rev

Log:
2008-12-10  Jody Goldberg <jody gnome org>

	* excel-xml-read.c (xl_xml_probe_start_element) : new.
	(excel_xml_file_probe) : use the new gsf_xml_probe.

	* plugin.xml.in : SpreadsheetML has a probe function now.

2008-12-10  Jody Goldberg <jody gnome org>

	* src/xml-io.c (xml_probe) : split out the content test into ...
	(gsf_xml_probe) : here.  Then generalize it a bit and use the SAX2
			  startElement routine to handle name spaces.
	(gnm_xml_probe_element) : handle the .gnumeric specific checks here.
	    1) root element == Workbook
	    2) Workbook is in a namespace that contains 'gnumeric'

Modified:
   trunk/ChangeLog
   trunk/NEWS
   trunk/plugins/excel/ChangeLog
   trunk/plugins/excel/excel-xml-read.c
   trunk/plugins/excel/plugin.xml.in
   trunk/src/xml-io.c
   trunk/src/xml-io.h

Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS	(original)
+++ trunk/NEWS	Sun Apr  5 01:37:25 2009
@@ -109,6 +109,8 @@
 Jody:
 	* Display top-left when selecting a rel ref to a merged region.
 	* Win32 fixed.
+	* Make .gnumeric xml probe smarter.
+	* Add probe routine for MS Excel (tm) 2003 SpreadsheetML.
 
 Jon KÃre:
         * Work around vulnerability in Python.  [#569648]

Modified: trunk/plugins/excel/excel-xml-read.c
==============================================================================
--- trunk/plugins/excel/excel-xml-read.c	(original)
+++ trunk/plugins/excel/excel-xml-read.c	Sun Apr  5 01:37:25 2009
@@ -1,9 +1,9 @@
 /* vim: set sw=8: */
 
 /*
- * excel-xml-read.c : Read MS Excel's xml
+ * excel-xml-read.c : Read MS Excel 2003 SpreadsheetML 
  *
- * Copyright (C) 2003-2005 Jody Goldberg (jody gnome org)
+ * Copyright (C) 2003-2008 Jody Goldberg (jody gnome org)
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of version 2 of the GNU General Public
@@ -41,6 +41,7 @@
 #include "command-context.h"
 #include "workbook-view.h"
 #include "workbook.h"
+#include "xml-io.h"
 #include <goffice/app/error-info.h>
 #include <goffice/app/io-context.h>
 #include <goffice/app/go-plugin.h>
@@ -48,6 +49,7 @@
 
 #include <gsf/gsf-libxml.h>
 #include <gsf/gsf-input.h>
+#include <gsf/gsf-utils.h>
 #include <gmodule.h>
 #include <glib/gi18n-lib.h>
 #include <stdlib.h>
@@ -703,10 +705,34 @@
 static void
 xl_xml_num_fmt (GsfXMLIn *xin, xmlChar const **attrs)
 {
+#if 0
+	static EnumVal const named_format [] = {
+		{ "General"		},
+		{ "General Number"		},
+		{ "General Date"		},
+		{ "Long Date"		},
+		{ "Medium Date"		},
+		{ "Short Date"		},
+		{ "Long Time"		},
+		{ "Medium Time"		},
+		{ "Short Time"		},
+		{ "Currency"		},
+		{ "Euro Currency"		},
+		{ "Fixed"		},
+		{ "Standard"		},
+		{ "Percent"		},
+		{ "Scientific"		},
+		{ "Yes/No"		},
+		{ "True/False"		},
+		{ "On/Off"		},
+		{ NULL, 0 }
+	};
+#endif
 	ExcelXMLReadState *state = (ExcelXMLReadState *)xin->user_state;
 	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
 		if (gsf_xml_in_namecmp (xin, attrs[0], XL_NS_SS, "Format")) {
 			GOFormat *fmt = NULL;
+
 			if (!strcmp (attrs[1], "Percent"))
 				fmt = go_format_default_percentage ();
 			else if (!strcmp (attrs[1], "Short Time"))
@@ -718,6 +744,8 @@
 				fmt = go_format_new_from_XL ("0.00");
 			else
 				fmt = go_format_new_from_XL (attrs[1]);
+
+
 			gnm_style_set_format (state->style, fmt);
 			go_format_unref (fmt);
 		} else
@@ -981,6 +1009,39 @@
 excel_xml_file_open (GOFileOpener const *fo, IOContext *context,
 		     WorkbookView *wbv, GsfInput *input);
 
+G_MODULE_EXPORT gboolean
+excel_xml_file_probe (GOFileOpener const *fo, GsfInput *input, FileProbeLevel pl);
+
+static gboolean
+xl_xml_probe_start_element (const xmlChar *name,
+			    G_GNUC_UNUSED const xmlChar *prefix,
+			    const xmlChar *URI,
+			    G_GNUC_UNUSED int nb_namespaces,
+			    G_GNUC_UNUSED const xmlChar **namespaces,
+			    G_GNUC_UNUSED int nb_attributes,
+			    G_GNUC_UNUSED int nb_defaulted,
+			    G_GNUC_UNUSED const xmlChar **attributes)
+{
+	/* starts with <Workbook> in namespace "schemas-microsoft-com:office:spreadsheet" */
+	return 0 == strcmp (name, "Workbook") &&
+		NULL != URI &&
+		NULL != strstr (URI, "schemas-microsoft-com:office:spreadsheet");
+}
+
+gboolean
+excel_xml_file_probe (GOFileOpener const *fo, GsfInput *input, FileProbeLevel pl)
+{
+	if (pl == FILE_PROBE_FILE_NAME) {
+		char const *ext;
+		char const *name = gsf_input_name (input);
+		return  NULL != name &&
+			NULL != (ext = gsf_extension_pointer (name)) &&
+			0 == g_ascii_strcasecmp (ext, "xml");
+	}
+
+	return gsf_xml_probe (input, &xl_xml_probe_start_element);
+}
+
 void
 excel_xml_file_open (GOFileOpener const *fo, IOContext *io_context,
 		     WorkbookView *wb_view, GsfInput *input)

Modified: trunk/plugins/excel/plugin.xml.in
==============================================================================
--- trunk/plugins/excel/plugin.xml.in	(original)
+++ trunk/plugins/excel/plugin.xml.in	Sun Apr  5 01:37:25 2009
@@ -57,7 +57,7 @@
 		</service>
 
 		<!-- IMPORT partial format spreadsheetml from 2003  -->
-		<service type="file_opener" id="excel_xml" priority="1" probe="FALSE">
+		<service type="file_opener" id="excel_xml" priority="1" probe="TRUE">
 			<information>
 				<_description>MS Excel (tm) 2003 SpreadsheetML</_description>
 			</information>

Modified: trunk/src/xml-io.c
==============================================================================
--- trunk/src/xml-io.c	(original)
+++ trunk/src/xml-io.c	Sun Apr  5 01:37:25 2009
@@ -2567,35 +2567,7 @@
 	}
 }
 
-/* We parse and do some limited validation of the XML file, if this passes,
- * then we return TRUE
- */
-
-typedef enum {
-	XML_PROBE_STATE_PROBING,
-	XML_PROBE_STATE_ERR,
-	XML_PROBE_STATE_SUCCESS
-} GnmXMLProbeState;
-
-static void
-xml_probe_start_element (GnmXMLProbeState *state, xmlChar const *name, xmlChar const **atts)
-{
-	int len = strlen (name);
-
-	*state = XML_PROBE_STATE_ERR;
-	if (len < 8)
-		return;
-	if (strcmp (name+len-8, "Workbook"))
-		return;
-	/* Do we want to get fancy and check namespace ? */
-	*state = XML_PROBE_STATE_SUCCESS;
-}
-
-static void
-xml_probe_problem (GnmXMLProbeState *state, char const *msg, ...)
-{
-	*state = XML_PROBE_STATE_ERR;
-}
+/**************************************************************************/
 
 static IOContext *io_context = NULL;
 static void
@@ -2626,15 +2598,120 @@
 		gnumeric_io_error_info_set (io_context, ei);
 }
 
+/**************************************************************************/
+/* We parse and do some limited validation of the XML file, if this passes,
+ * then we return TRUE
+ */
+typedef struct {
+	GsfXMLProbeFunc	func;
+	gboolean success;
+} GsfXMLProbeState;
+
+static void
+gsf_xml_probe_error (GsfXMLProbeState *state, char const *msg, ...)
+{
+	state->func = NULL;
+	state->success = FALSE;
+}
+static void
+gsf_xml_probe_element (GsfXMLProbeState *state,
+		       const xmlChar *name,
+		       const xmlChar *prefix,
+		       const xmlChar *URI,
+		       int nb_namespaces,
+		       const xmlChar **namespaces,
+		       int nb_attributes,
+		       int nb_defaulted,
+		       const xmlChar **attributes)
+{
+	state->success = (state->func) (name, prefix, URI, nb_namespaces, namespaces,
+					nb_attributes, nb_defaulted, attributes);
+	state->func = NULL;
+}
 
-static xmlSAXHandler xml_sax_prober;
-static gboolean
-xml_probe (GOFileOpener const *fo, GsfInput *input, FileProbeLevel pl)
+gboolean
+gsf_xml_probe (GsfInput *input, GsfXMLProbeFunc func)
 {
+	static xmlSAXHandler gsf_xml_prober = {
+		NULL, /* internalSubset */
+		NULL, /* isStandalone */
+		NULL, /* hasInternalSubset */
+		NULL, /* hasExternalSubset */
+		NULL, /* resolveEntity */
+		NULL, /* getEntity */
+		NULL, /* entityDecl */
+		NULL, /* notationDecl */
+		NULL, /* attributeDecl */
+		NULL, /* elementDecl */
+		NULL, /* unparsedEntityDecl */
+		NULL, /* setDocumentLocator */
+		NULL, /* startDocument */
+		NULL, /* endDocument */
+		NULL, /* startElement */
+		NULL, /* endElement */
+		NULL, /* reference */
+		NULL, /* characters */
+		NULL, /* ignorableWhitespace */
+		NULL, /* processingInstruction */
+		NULL, /* comment */
+		NULL, /* xmlParserWarning */
+		(errorSAXFunc) &gsf_xml_probe_error, /* error */
+		(errorSAXFunc) &gsf_xml_probe_error, /* fatalError */
+		NULL, /* getParameterEntity */
+		NULL, /* cdataBlock; */
+		NULL, /* externalSubset; */
+		XML_SAX2_MAGIC,
+		NULL,
+		(startElementNsSAX2Func) &gsf_xml_probe_element, /* startElementNs */
+		NULL, /* endElementNs */
+		NULL  /* xmlStructuredErrorFunc */
+	};
+	GsfXMLProbeState probe_state = { func, FALSE };
 	xmlParserCtxt *parse_context;
-	GnmXMLProbeState is_gnumeric_xml = XML_PROBE_STATE_PROBING;
 	char const *buf;
 
+	if (gsf_input_seek (input, 0, G_SEEK_SET))
+		return FALSE;
+
+	g_object_ref (input);
+	input = maybe_gunzip (input);
+	input = maybe_convert (input, TRUE);
+	gsf_input_seek (input, 0, G_SEEK_SET);
+
+	buf = gsf_input_read (input, 4, NULL);
+	if (NULL != buf ) {
+		parse_context = xmlCreatePushParserCtxt (&gsf_xml_prober, &probe_state,
+			(char *)buf, 4, gsf_input_name (input));
+		if (NULL != parse_context) {
+			while (NULL != probe_state.func &&
+			       NULL != (buf = gsf_input_read (input, 1, NULL)))
+				xmlParseChunk (parse_context, (char *)buf, 1, 0);
+		}
+		xmlFreeParserCtxt (parse_context);
+	}
+	g_object_unref (input);
+
+	return probe_state.success;
+}
+
+/**************************************************************************/
+
+static gboolean
+gnm_xml_probe_element (const xmlChar *name,
+		       G_GNUC_UNUSED const xmlChar *prefix,
+		       const xmlChar *URI,
+		       G_GNUC_UNUSED int nb_namespaces,
+		       G_GNUC_UNUSED const xmlChar **namespaces,
+		       G_GNUC_UNUSED int nb_attributes,
+		       G_GNUC_UNUSED int nb_defaulted,
+		       G_GNUC_UNUSED const xmlChar **attributes)
+{
+	return 0 == strcmp (name, "Workbook") &&
+		NULL != URI && NULL != strstr (URI, "gnumeric");
+}
+static gboolean
+xml_probe (GOFileOpener const *fo, GsfInput *input, FileProbeLevel pl)
+{
 	if (pl == FILE_PROBE_FILE_NAME) {
 		char const *name = gsf_input_name (input);
 		int len;
@@ -2652,39 +2729,10 @@
 			(g_ascii_strcasecmp (name, "gnumeric") == 0 ||
 			 g_ascii_strcasecmp (name, "xml") == 0));
 	}
-
-/* probe by content */
-	if (gsf_input_seek (input, 0, G_SEEK_SET))
-		return FALSE;
-
-	g_object_ref (input);
-	input = maybe_gunzip (input);
-	input = maybe_convert (input, TRUE);
-	gsf_input_seek (input, 0, G_SEEK_SET);
-
-	buf = gsf_input_read (input, 4, NULL);
-	if (buf == NULL)
-		goto unref_input;
-	parse_context = xmlCreatePushParserCtxt (&xml_sax_prober, &is_gnumeric_xml,
-		(char *)buf, 4, gsf_input_name (input));
-	if (parse_context == NULL)
-		goto unref_input;
-
-	do {
-		buf = gsf_input_read (input, 1, NULL);
-		if (buf != NULL)
-			xmlParseChunk (parse_context, (char *)buf, 1, 0);
-		else
-			is_gnumeric_xml = XML_PROBE_STATE_ERR;
-	} while (is_gnumeric_xml == XML_PROBE_STATE_PROBING);
-
-	xmlFreeParserCtxt (parse_context);
-
-unref_input:
-	g_object_unref (input);
-
-	return is_gnumeric_xml == XML_PROBE_STATE_SUCCESS;
+	/* probe by content */
+	return gsf_xml_probe (input, &gnm_xml_probe_element);
 }
+/**************************************************************************/
 
 /*
  * Open an XML file and read a Workbook
@@ -2780,11 +2828,6 @@
 	GOFileSaver *saver;
 	GSList *suffixes = go_slist_create (g_strdup ("gnumeric"), g_strdup ("xml"), NULL);
 	GSList *mimes = go_slist_create (g_strdup ("application/x-gnumeric"), NULL);
-	xml_sax_prober.comment    = NULL;
-	xml_sax_prober.warning    = NULL;
-	xml_sax_prober.error      = (errorSAXFunc) xml_probe_problem;
-	xml_sax_prober.fatalError = (fatalErrorSAXFunc) xml_probe_problem;
-	xml_sax_prober.startElement = (startElementSAXFunc) xml_probe_start_element;
 #warning REMOVE for 2.0
 	go_file_opener_register (go_file_opener_new (
 		"Gnumeric_XmlIO:dom",

Modified: trunk/src/xml-io.h
==============================================================================
--- trunk/src/xml-io.h	(original)
+++ trunk/src/xml-io.h	Sun Apr  5 01:37:25 2009
@@ -68,6 +68,19 @@
 
 GnmConventions *gnm_xml_io_conventions (void);
 
+/********************************************************/
+
+typedef gboolean (*GsfXMLProbeFunc) (const xmlChar *name,
+				     const xmlChar *prefix,
+				     const xmlChar *URI,
+				     int nb_namespaces,
+				     const xmlChar **namespaces,
+				     int nb_attributes,
+				     int nb_defaulted,
+				     const xmlChar **attributes);
+gboolean gsf_xml_probe (GsfInput *input,
+			GsfXMLProbeFunc startElement);
+
 G_END_DECLS
 
 #endif /* _GNM_XML_IO_H_ */



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