+void
+ods_unref (struct spreadsheet *s)
+{
+ struct ods_reader *r = (struct ods_reader *) s;
+
+ if (--s->ref_cnt == 0)
+ {
+ int i;
+
+ state_data_destroy (&r->msd);
+ for (i = 0; i < r->n_allocated_sheets; ++i)
+ {
+ xmlFree (r->sheets[i].name);
+ }
+
+ zip_reader_destroy (r->zreader);
+ free (r->sheets);
+ free (s->file_name);
+ free (r);
+ }
+}
+
+
+
+static bool
+reading_target_sheet (const struct ods_reader *r, const struct state_data *msd)
+{
+ if (r->target_sheet_name != NULL)
+ {
+ if ( 0 == xmlStrcmp (r->target_sheet_name, msd->current_sheet_name))
+ return true;
+ }
+
+ if (r->target_sheet_index == msd->current_sheet + 1)
+ return true;
+
+ return false;
+}
+
+
+static void process_node (struct ods_reader *or, struct state_data *r);
+
+
+const char *
+ods_get_sheet_name (struct spreadsheet *s, int n)
+{
+ struct ods_reader *r = (struct ods_reader *) s;
+ struct state_data *or = &r->msd;
+
+ assert (n < s->n_sheets);
+
+ while (
+ (r->n_allocated_sheets <= n)
+ || or->state != STATE_SPREADSHEET
+ )
+ {
+ int ret = xmlTextReaderRead (or->xtr);
+ if ( ret != 1)
+ break;
+
+ process_node (r, or);
+ }
+
+ return r->sheets[n].name;
+}
+
+char *
+ods_get_sheet_range (struct spreadsheet *s, int n)
+{
+ struct ods_reader *r = (struct ods_reader *) s;
+ struct state_data *or = &r->msd;
+
+ assert (n < s->n_sheets);
+
+ while (
+ (r->n_allocated_sheets <= n)
+ || (r->sheets[n].stop_row == -1)
+ || or->state != STATE_SPREADSHEET
+ )
+ {
+ int ret = xmlTextReaderRead (or->xtr);
+ if ( ret != 1)
+ break;
+
+ process_node (r, or);
+ }
+
+ return create_cell_range (
+ r->sheets[n].start_col,
+ r->sheets[n].start_row,
+ r->sheets[n].stop_col,
+ r->sheets[n].stop_row);
+}
+