+static struct gnumeric_reader *
+gnumeric_reopen (struct gnumeric_reader *r, const char *filename, bool show_errors)
+{
+ int ret = -1;
+ struct state_data *sd;
+
+ xmlTextReaderPtr xtr;
+ gzFile gz;
+
+ assert (r == NULL || filename == NULL);
+
+ if (filename)
+ {
+ gz = gzopen (filename, "r");
+ }
+ else
+ {
+ gz = gzopen (r->spreadsheet.file_name, "r");
+ }
+
+ if (NULL == gz)
+ return NULL;
+
+ if (r == NULL)
+ {
+ r = xzalloc (sizeof *r);
+ r->n_sheets = -1;
+ r->spreadsheet.file_name = strdup (filename);
+ struct spreadsheet *s = SPREADSHEET_CAST (r);
+ strcpy (s->type, "GNM");
+ s->destroy = gnumeric_destroy;
+ s->make_reader = gnumeric_make_reader;
+ s->get_sheet_name = gnumeric_get_sheet_name;
+ s->get_sheet_range = gnumeric_get_sheet_range;
+ s->get_sheet_n_sheets = gnumeric_get_sheet_n_sheets;
+ s->get_sheet_n_rows = gnumeric_get_sheet_n_rows;
+ s->get_sheet_n_columns = gnumeric_get_sheet_n_columns;
+ s->get_sheet_cell = gnumeric_get_sheet_cell;
+
+ sd = &r->msd;
+ hmap_init (&r->cache);
+ }
+ else
+ {
+ sd = &r->rsd;
+ }
+ sd->gz = gz;
+
+ r = (struct gnumeric_reader *) spreadsheet_ref (SPREADSHEET_CAST (r));
+
+ {
+ xtr = xmlReaderForIO ((xmlInputReadCallback) gzread,
+ (xmlInputCloseCallback) gzclose, gz,
+ NULL, NULL,
+ show_errors ? 0 : (XML_PARSE_NOERROR | XML_PARSE_NOWARNING));
+
+ if (xtr == NULL)
+ {
+ gzclose (gz);
+ free (r);
+ return NULL;
+ }
+
+ if (show_errors)
+ xmlTextReaderSetErrorHandler (xtr, gnumeric_error_handler, r);
+
+ sd->row = sd->col = -1;
+ sd->state = STATE_PRE_INIT;
+ sd->xtr = xtr;
+ }
+
+ r->target_sheet_name = NULL;
+ r->target_sheet_index = -1;
+
+
+ /* Advance to the start of the workbook.
+ This gives us some confidence that we are actually dealing with a gnumeric
+ spreadsheet.
+ */
+ while ((sd->state != STATE_INIT)
+ && 1 == (ret = xmlTextReaderRead (sd->xtr)))
+ {
+ process_node (r, sd);
+ }
+
+ if (ret != 1)
+ {
+ /* Does not seem to be a gnumeric file */
+ spreadsheet_unref (&r->spreadsheet);
+ return NULL;
+ }
+
+ if (show_errors)
+ {
+ const xmlChar *enc = xmlTextReaderConstEncoding (sd->xtr);
+ xmlCharEncoding xce = xmlParseCharEncoding (CHAR_CAST (const char *, enc));
+
+ if (XML_CHAR_ENCODING_UTF8 != xce)
+ {
+ /* I have been told that ALL gnumeric files are UTF8 encoded. If that is correct, this
+ can never happen. */
+ msg (MW, _("The gnumeric file `%s' is encoded as %s instead of the usual UTF-8 encoding. "
+ "Any non-ascii characters will be incorrectly imported."),
+ r->spreadsheet.file_name,
+ enc);
+ }
+ }
+
+ return r;
+}
+