changeset 4332:e41906608e0f

[project @ 2003-02-19 01:15:59 by jwe]
author jwe
date Wed, 19 Feb 2003 01:15:59 +0000
parents d3278845f764
children c17f6d87da97
files src/ChangeLog src/load-save.cc
diffstat 2 files changed, 157 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Wed Feb 19 00:13:50 2003 +0000
+++ b/src/ChangeLog	Wed Feb 19 01:15:59 2003 +0000
@@ -1,3 +1,10 @@
+2003-02-18  Roger Banks <rbanks@colsa.com>
+
+	* load-save.cc (read_ascii_data, read_ascii_data,
+	read_mat5_binary_element, save_mat5_binary_element,
+	save_ascii_data): Handle cell arrays.
+	(write_mat5_cell_array): New function.
+
 2003-02-18  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
 	* Makefile.in (DLD_XSRC): Delete log.cc from the list.
--- a/src/load-save.cc	Wed Feb 19 00:13:50 2003 +0000
+++ b/src/load-save.cc	Wed Feb 19 01:15:59 2003 +0000
@@ -54,12 +54,14 @@
 #include "quit.h"
 #include "str-vec.h"
 
+#include "Cell.h"
 #include "defun.h"
 #include "error.h"
 #include "gripes.h"
 #include "load-save.h"
 #include "oct-obj.h"
 #include "oct-map.h"
+#include "ov-cell.h"
 #include "pager.h"
 #include "pt-exp.h"
 #include "symtab.h"
@@ -94,6 +96,8 @@
 #define OCT_RBV DBL_MAX / 100.0
 #endif
 
+#define CELL_ELT_TAG "<cell-element>"
+
 enum arrayclasstype
   {
     mxCELL_CLASS=1,		// cell array
@@ -129,6 +133,11 @@
     miMATRIX			// MATLAB array
   };
 
+static bool
+save_mat5_binary_element (std::ostream& os,
+			  const octave_value& tc, const std::string& name,
+			  bool mark_as_global, bool save_as_floats);
+
 #ifdef HAVE_HDF5
 // this is only used for HDF5 import
 // try to convert s into a valid identifier, replacing invalid chars with "_":
@@ -542,7 +551,11 @@
       return std::string ();
     }
 
-  if (! valid_identifier (name))
+  if (name == CELL_ELT_TAG)
+    {
+      // This is OK -- name won't be used.
+    }
+  else if (! valid_identifier (name))
     {
       error ("load: bogus identifier `%s' found in file `%s'",
 	     name.c_str (), filename.c_str ());
@@ -600,6 +613,56 @@
 	  else
 	    error ("load: failed to extract number of rows and columns");
 	}
+      else if (SUBSTRING_COMPARE_EQ (typ, 0, 4, "cell"))
+	{
+	  int nr = 0;
+	  int nc = 0;
+
+	  if (extract_keyword (is, "rows",    nr) && nr >= 0
+	      && extract_keyword (is, "columns", nc) && nc >= 0)
+	    {
+	      if (nr > 0 && nc > 0)
+		{
+		  Cell tmp (nr, nc);
+
+		  for (int j = 0; j < nc; j++)
+		    {
+		      for (int i = 0; i < nr; i++)
+			{
+			  octave_value t2;
+
+			  // recurse to read cell elements
+			  std::string nm
+			    = read_ascii_data (is, filename, global, t2, count);
+
+			  if (nm == CELL_ELT_TAG)
+			    {
+			      if (is)
+				tmp.elem (i, j) = t2;
+			    }
+			  else
+			    {
+			      error ("load: cell array element had unexpected name");
+			      goto cell_read_error;
+			    }
+			}
+		    }
+
+		cell_read_error:
+
+		  if (is)
+		    tc = tmp;
+		  else
+		    error ("load: failed to load cell element");
+		}
+	      else if (nr == 0 || nc == 0)
+		tc = Cell (nr, nc);
+	      else
+		panic_impossible ();
+	    }
+	  else
+	    error ("load: failed to extract number of rows and columns for cell array");
+	}
       else if (SUBSTRING_COMPARE_EQ (typ, 0, 14, "complex scalar"))
 	{
 	  Complex tmp = octave_read_complex (is);
@@ -2625,8 +2688,31 @@
   switch (arrayclass)
     {
     case mxCELL_CLASS:
-      warning ("load: cell arrays are not implemented");
-      goto skip_ahead;
+      {
+	Cell cell_array (nr, nc);
+
+	for (int j = 0; j < nc; j++)
+	  {
+	    for (int i = 0; i < nr; i++)
+	      {
+		octave_value tc2;
+
+		std::string nm
+		  = read_mat5_binary_element (is, filename, swap, global, tc2);
+
+		if (! is || error_state)
+		  {
+		    error ("load: reading cell data for `%s'", nm.c_str ());
+		    goto data_read_error;
+		  }
+
+		cell_array.elem (i, j) = tc2;
+	      }
+	  }
+
+	tc = cell_array;
+      }
+      break;
 
     case mxOBJECT_CLASS:
       warning ("load: objects are not implemented");
@@ -4085,6 +4171,31 @@
     }
 }
 
+// Write out cell element values in the cell array to OS, preceded by
+// the appropriate tag.
+
+static bool 
+write_mat5_cell_array (std::ostream& os, Cell& cell, bool mark_as_global,
+		       const int save_as_floats)
+{
+  int nr = cell.rows ();
+  int nc = cell.columns ();
+
+  for (int j = 0; j < nc; j++)
+    {
+      for (int i = 0; i < nr; i++)
+	{
+	  octave_value ov = cell.elem (i, j);
+
+	  if (! save_mat5_binary_element (os, ov, "", mark_as_global,
+					  save_as_floats))
+	    return false;
+	}
+    }
+
+  return true;
+}
+
 // save the data from TC along with the corresponding NAME on stream
 // OS in the MatLab version 5 binary format.  Return true on success.
 
@@ -4124,6 +4235,8 @@
     flags |= mxDOUBLE_CLASS;
   else if (tc.is_map ()) 
     flags |= mxSTRUCT_CLASS;
+  else if (tc.is_cell ())
+    flags |= mxCELL_CLASS;
   else
     {
       gripe_wrong_type_arg ("save", tc, false);
@@ -4194,6 +4307,13 @@
 
       write_mat5_array (os, m, save_as_floats);
     }
+  else if (tc.is_cell ())
+    {
+      Cell cell = tc.cell_value ();
+
+      if (! write_mat5_cell_array (os, cell, mark_as_global, save_as_floats))
+	goto error_cleanup;
+    }
   else if (tc.is_complex_scalar () || tc.is_complex_matrix ()) 
     {
       ComplexMatrix m_cmplx = tc.complex_matrix_value ();
@@ -4545,6 +4665,33 @@
 
       os << tmp;
     }
+  else if (tc.is_cell ())
+    {
+      ascii_save_type (os, "cell", mark_as_global);
+
+      os << "# rows: " << tc.rows () << "\n"
+	 << "# columns: " << tc.columns () << "\n";
+
+      Cell tmp = tc.cell_value ();
+      
+      for (int j = 0; j < tmp.cols (); j++)
+	{
+	  for (int i = 0; i < tmp.rows (); i++)
+	    {
+	      octave_value o_val = tmp.elem (i, j);
+
+	      // Recurse to print sub-value.
+	      bool b = save_ascii_data (os, o_val, CELL_ELT_TAG,
+					infnan_warned, strip_nan_and_inf,
+					mark_as_global, 0);
+
+	      if (! b)
+		return os;
+	    }
+
+	  os << "\n";
+	}
+    }
   else if (tc.is_complex_scalar ())
     {
       ascii_save_type (os, "complex scalar", mark_as_global);