Another test works
[pspp] / src / data / ods-reader.c
index c48fbfc1efbacce3f25b1f55f81ddc6c0fda68a6..7c12af221562a00749738e05341b1f6dec366eed 100644 (file)
@@ -106,11 +106,11 @@ struct ods_reader
   xmlTextReaderPtr xtr;
 
   enum reader_state state;
-  bool sheet_found;
   int row;
   int col;
   int node_type;
   int current_sheet;
+  xmlChar *current_sheet_name;
 
   const xmlChar *target_sheet_name;
   int target_sheet_index;
@@ -141,6 +141,22 @@ struct ods_reader
 };
 
 
+static bool
+reading_target_sheet (const struct ods_reader *r)
+{
+  if (r->target_sheet_name != NULL)
+    {
+      if ( 0 == xmlStrcmp (r->target_sheet_name, r->current_sheet_name))
+       return true;
+    }
+  
+  if (r->target_sheet_index == r->current_sheet + 1)
+    return true;
+
+  return false;
+}
+
+
 static void process_node (struct ods_reader *r);
 
 
@@ -234,6 +250,7 @@ process_node (struct ods_reader *r)
        {
          r->state = STATE_SPREADSHEET;
          r->current_sheet = -1;
+         r->current_sheet_name = NULL;
        }
       break;
     case STATE_SPREADSHEET:
@@ -241,7 +258,8 @@ process_node (struct ods_reader *r)
          && 
          (XML_READER_TYPE_ELEMENT == r->node_type))
        {
-         xmlChar *value = xmlTextReaderGetAttribute (r->xtr, _xml ("table:name"));
+         xmlFree (r->current_sheet_name);
+         r->current_sheet_name = xmlTextReaderGetAttribute (r->xtr, _xml ("table:name"));
 
          ++r->current_sheet;
 
@@ -252,31 +270,18 @@ process_node (struct ods_reader *r)
              r->sheets[r->n_allocated_sheets - 1].stop_col = -1;
              r->sheets[r->n_allocated_sheets - 1].start_row = -1;
              r->sheets[r->n_allocated_sheets - 1].stop_row = -1;
-             r->sheets[r->n_allocated_sheets - 1].name = value;
+             r->sheets[r->n_allocated_sheets - 1].name = xmlStrdup (r->current_sheet_name);
            }
 
          r->col = 0;
          r->row = 0;
 
-         if ( r->target_sheet_name != NULL)
-           {
-             if ( 0 == xmlStrcmp (value, r->target_sheet_name))
-               {
-                 r->sheet_found = true;
-               }
-           }
-         else if (r->target_sheet_index == r->current_sheet)
-           {
-             r->sheet_found = true;
-           }
          r->state = STATE_TABLE;
        }
       else if (0 == xmlStrcasecmp (name, _xml("office:spreadsheet")) &&
               XML_READER_TYPE_ELEMENT  == r->node_type)
        {
          r->state = STATE_INIT;
-         printf ("%s:%d End of Workbook %d: Rows %d Cols %d\n", __FILE__, __LINE__,
-                 r->current_sheet,  r->row, r->col);
        }
       break;
     case STATE_TABLE:
@@ -302,6 +307,7 @@ process_node (struct ods_reader *r)
        }
       break;
     case STATE_ROW:
+      //      printf ("%s:%d Name is %s\n", __FILE__, __LINE__, name);
       if ( (0 == xmlStrcasecmp (name, _xml ("table:table-cell")))
           && 
           (XML_READER_TYPE_ELEMENT  == r->node_type))
@@ -313,6 +319,8 @@ process_node (struct ods_reader *r)
          r->col_span = value ? _xmlchar_to_int (value) : 1;
          r->col += r->col_span;
 
+         //      printf ("%s:%d %s\n", __FILE__, __LINE__, value);
+
          if (! xmlTextReaderIsEmptyElement (r->xtr))
            r->state = STATE_CELL;
        }
@@ -620,9 +628,7 @@ ods_make_reader (struct spreadsheet *spreadsheet,
 #endif
 
   /* Advance to the start of the cells for the target sheet */
-  while ( r->current_sheet < r->target_sheet_index - 1 ||
-         r->state != STATE_TABLE
-         )
+  while ( ! reading_target_sheet (r)  || r->state != STATE_ROW  )
     {
       if (1 != (ret = xmlTextReaderRead (r->xtr)))
           break;
@@ -716,6 +722,7 @@ ods_make_reader (struct spreadsheet *spreadsheet,
        }
     }
 
+
   /* Create the dictionary and populate it */
   r->spreadsheet.dict = r->dict = dict_create (
     CHAR_CAST (const char *, xmlTextReaderConstEncoding (r->xtr)));
@@ -826,41 +833,44 @@ ods_file_casereader_read (struct casereader *reader UNUSED, void *r_)
   struct ods_reader *r = r_;
   int current_row = r->row;
 
-  if ( !r->used_first_case )
+  if (!r->used_first_case)
     {
       r->used_first_case = true;
       return r->first_case;
     }
 
-  if ( r->state > STATE_INIT)
+
+  /* Advance to the start of a row. (If there is one) */
+  while (r->state != STATE_ROW && 1 == xmlTextReaderRead (r->xtr))
     {
-      c = case_create (r->proto);
-      case_set_missing (c);
+      process_node (r);
     }
 
-  if (r->state == STATE_SPREADSHEET 
-      && 
-      r->current_sheet == r->target_sheet_index - 1
-      )
+
+  if ( ! reading_target_sheet (r)  ||  r->state < STATE_TABLE)
     {
       return NULL;
     }
 
+  c = case_create (r->proto);
+  case_set_missing (c);
+  
   while (1 == xmlTextReaderRead (r->xtr))
     {
       process_node (r);
-
+#if 0
       if (r->row > current_row && r->state == STATE_ROW)
        break;
-
-      if ( r->state == STATE_CELL &&
-          r->node_type == XML_READER_TYPE_ELEMENT )
+#endif
+      //      printf ("%s:%d\n", __FILE__, __LINE__);
+      if (r->state == STATE_CELL &&
+          r->node_type == XML_READER_TYPE_ELEMENT)
        {
          val_string = xmlTextReaderGetAttribute (r->xtr, _xml ("office:value"));
        }
 
-      if ( r->state == STATE_CELL_CONTENT && 
-          r->node_type == XML_READER_TYPE_TEXT )
+      if (r->state == STATE_CELL_CONTENT && 
+          r->node_type == XML_READER_TYPE_TEXT)
        {
          int col;
          struct xml_value *xmv = xzalloc (sizeof *xmv);
@@ -879,19 +889,10 @@ ods_file_casereader_read (struct casereader *reader UNUSED, void *r_)
          free (xmv->value);
          free (xmv);
        }
-
-      if ( r->state < STATE_TABLE)
+      if ( r->state <= STATE_TABLE)
        break;
     }
 
-  if (NULL == c)
-    {
-      case_unref (c);
-      return NULL;
-    }
-  else
-    {
-      return c;
-    }
+  return c;
 }
 #endif