# HG changeset patch # User jwe # Date 1045617359 0 # Node ID e41906608e0fcc7fc1074a64ff51e47a18b7203f # Parent d3278845f764a90bc1f19a5ace521ec67ac2937e [project @ 2003-02-19 01:15:59 by jwe] diff -r d3278845f764 -r e41906608e0f src/ChangeLog --- 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 + + * 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 * Makefile.in (DLD_XSRC): Delete log.cc from the list. diff -r d3278845f764 -r e41906608e0f src/load-save.cc --- 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 "" + 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);