changeset 4805:b0d6da24caeb

[project @ 2004-03-02 03:43:15 by jwe]
author jwe
date Tue, 02 Mar 2004 03:43:15 +0000
parents 6202d9b75f83
children d3bd9c04147f
files src/ChangeLog src/ls-hdf5.cc src/ls-hdf5.h src/ov-bool-mat.cc src/ov-cx-mat.cc src/ov-re-mat.cc src/ov-str-mat.cc
diffstat 7 files changed, 485 insertions(+), 215 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Fri Feb 27 16:40:59 2004 +0000
+++ b/src/ChangeLog	Tue Mar 02 03:43:15 2004 +0000
@@ -1,3 +1,17 @@
+2004-03-01  David Bateman  <dbateman@free.fr>
+ 
+	* ls-hdf5.cc (save_hdf5_empty, load_hdf5_empty): New functions
+	to save/load empty matrices keeping their dimensions.
+	* ls-hdf5.h (save_hdf5_empty, load_hdf5_empty): Provide decls.
+
+	* ov-re-mat.cc (save_hdf5, load_hdf5): Cleanup, check empty matrix.
+	* ov-cx-mat.cc (save_hdf5, load_hdf5): Ditto.
+	* ov-bool-mat.cc (save_hdf5, load_hdf5): Ditto.
+
+	* ov-str-mat.cc (save_ascoo, load_ascii, save_binary,
+	load_binary, save_hdf5, load_hdf5): Cleanup, check empty matrix,
+	and save/load N-d arrays.
+ 
 2004-02-27  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
 	* octave.cc (execute_startup_files): Don't find current directory
--- a/src/ls-hdf5.cc	Fri Feb 27 16:40:59 2004 +0000
+++ b/src/ls-hdf5.cc	Tue Mar 02 03:43:15 2004 +0000
@@ -514,6 +514,83 @@
   return retval;
 }
 
+// Save an empty matrix, if needed. Returns
+//    > 0  Saved empty matrix
+//    = 0  Not an empty matrix; did nothing
+//    < 0  Error condition
+int
+save_hdf5_empty (hid_t loc_id, const char *name, const dim_vector d)
+{
+  hsize_t sz = d.length ();
+  int dims[sz];
+  bool empty = false;
+  hid_t space_hid = -1, data_hid = -1;
+  int retval;
+  for (hsize_t i = 0; i < sz; i++)
+    {
+      dims[i] = d(i);
+      if (dims[i] < 1)
+	empty = true;
+    }
+
+  if (!empty)
+    return 0;
+
+  space_hid = H5Screate_simple (1, &sz, (hsize_t *) 0);
+  if (space_hid < 0) return space_hid;
+
+  data_hid = H5Dcreate (loc_id, name, H5T_NATIVE_INT, space_hid, 
+			H5P_DEFAULT);
+  if (data_hid < 0)
+    {
+      H5Sclose (space_hid);
+      return data_hid;
+    }
+  
+  retval = H5Dwrite (data_hid, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
+		     H5P_DEFAULT, (void*) dims) >= 0;
+
+  H5Dclose (data_hid);
+  H5Sclose (space_hid);
+
+  if (retval >= 0)
+    retval = hdf5_add_attr (loc_id, "OCTAVE_EMPTY_MATRIX");
+  
+  return (retval == 0 ? 1 : retval);
+}
+
+// Load an empty matrix, if needed. Returns
+//    > 0  loaded empty matrix, dimensions returned
+//    = 0  Not an empty matrix; did nothing
+//    < 0  Error condition
+int
+load_hdf5_empty (hid_t loc_id, const char *name, dim_vector &d)
+{
+  if (!hdf5_check_attr(loc_id, "OCTAVE_EMPTY_MATRIX"))
+    return 0;
+
+  hsize_t hdims, maxdims;
+  hid_t data_hid = H5Dopen (loc_id, name);
+  hid_t space_id = H5Dget_space (data_hid);
+  H5Sget_simple_extent_dims (space_id, &hdims, &maxdims);
+  int dims[hdims];
+  int retval;
+
+  retval = H5Dread (data_hid, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, 
+		    H5P_DEFAULT, (void *) dims);
+  if (retval >= 0)
+    {
+      d.resize (hdims);
+      for (hsize_t i = 0; i < hdims; i++)
+	d(i) = dims[i];
+    }
+
+  H5Sclose (space_id);
+  H5Dclose (data_hid);
+
+  return (retval == 0 ? hdims : retval);
+}
+
 // save_type_to_hdf5 is not currently used, since hdf5 doesn't yet support
 // automatic float<->integer conversions:
 
--- a/src/ls-hdf5.h	Fri Feb 27 16:40:59 2004 +0000
+++ b/src/ls-hdf5.h	Tue Mar 02 03:43:15 2004 +0000
@@ -153,6 +153,12 @@
 	       const std::string& name, const std::string& doc,
 	       bool mark_as_global, bool save_as_floats);
 
+extern int
+save_hdf5_empty (hid_t loc_id, const char *name, const dim_vector d);
+
+extern int
+load_hdf5_empty (hid_t loc_id, const char *name, dim_vector &d);
+
 extern std::string
 read_hdf5_data (std::istream& is,  const std::string& filename, bool& global,
 		octave_value& tc, std::string& doc);
--- a/src/ov-bool-mat.cc	Fri Feb 27 16:40:59 2004 +0000
+++ b/src/ov-bool-mat.cc	Tue Mar 02 03:43:15 2004 +0000
@@ -344,16 +344,20 @@
 			       bool /* save_as_floats */)
 {
   dim_vector d = dims ();
-  hsize_t hdims[d.length () > 2 ? d.length () : 3];
+  int empty = save_hdf5_empty (loc_id, name, d);
+  if (empty != 0)
+    return (empty > 0);
+
+  int rank = d.length ();
   hid_t space_hid = -1, data_hid = -1;
-  int rank = ( (d (0) == 1) && (d.length () == 2) ? 1 : d.length ());
   bool retval = true;
-
   boolNDArray m = bool_array_value ();
 
+  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
+
   // Octave uses column-major, while HDF5 uses row-major ordering
-  for (int i = 0, j = d.length() - 1; i < d.length (); i++, j--)
-    hdims[i] = d (j);
+  for (int i = 0; i < rank; i++)
+    hdims[i] = d (rank-i-1);
 
   space_hid = H5Screate_simple (rank, hdims, (hsize_t*) 0);
   if (space_hid < 0) return false;
@@ -385,6 +389,13 @@
 octave_bool_matrix::load_hdf5 (hid_t loc_id, const char *name,
 			       bool /* have_h5giterate_bug */)
 {
+  dim_vector dv;
+  int empty = load_hdf5_empty (loc_id, name, dv);
+  if (empty > 0)
+    matrix.resize(dv);
+  if (empty != 0)
+      return (empty > 0);
+
   bool retval = false;
   hid_t data_hid = H5Dopen (loc_id, name);
   hid_t space_id = H5Dget_space (data_hid);
@@ -402,8 +413,6 @@
 
   H5Sget_simple_extent_dims (space_id, hdims, maxdims);
 
-  dim_vector dv;
-
   // Octave uses column-major, while HDF5 uses row-major ordering
   if (rank == 1)
     {
--- a/src/ov-cx-mat.cc	Fri Feb 27 16:40:59 2004 +0000
+++ b/src/ov-cx-mat.cc	Tue Mar 02 03:43:15 2004 +0000
@@ -446,16 +446,21 @@
 				  bool save_as_floats)
 {
   dim_vector d = dims ();
-  hsize_t hdims[d.length () > 2 ? d.length () : 3];
-  hid_t space_hid = -1, type_hid = -1, data_hid = -1;
-  int rank = ( (d (0) == 1) && (d.length () == 2) ? 1 : d.length ());
+  int empty = save_hdf5_empty (loc_id, name, d);
+  if (empty != 0)
+    return (empty > 0);
+
+  int rank = d.length ();
+  hid_t space_hid = -1, data_hid = -1, type_hid = -1;
   bool retval = true;
   ComplexNDArray m = complex_array_value ();
 
+  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
+
   // Octave uses column-major, while HDF5 uses row-major ordering
-  for (int i = 0, j = d.length() - 1; i < d.length (); i++, j--)
-    hdims[i] = d (j);
-
+  for (int i = 0; i < rank; i++)
+    hdims[i] = d (rank-i-1);
+ 
   space_hid = H5Screate_simple (rank, hdims, (hsize_t*) 0);
   if (space_hid < 0) return false;
 
@@ -523,6 +528,13 @@
 octave_complex_matrix::load_hdf5 (hid_t loc_id, const char *name,
 				  bool /* have_h5giterate_bug */)
 {
+  dim_vector dv;
+  int empty = load_hdf5_empty (loc_id, name, dv);
+  if (empty > 0)
+    matrix.resize(dv);
+  if (empty != 0)
+      return (empty > 0);
+
   bool retval = false;
   hid_t data_hid = H5Dopen (loc_id, name);
   hid_t type_hid = H5Dget_type (data_hid);
@@ -553,8 +565,6 @@
 
   H5Sget_simple_extent_dims (space_id, hdims, maxdims);
 
-  dim_vector dv;
-
   // Octave uses column-major, while HDF5 uses row-major ordering
   if (rank == 1)
     {
--- a/src/ov-re-mat.cc	Fri Feb 27 16:40:59 2004 +0000
+++ b/src/ov-re-mat.cc	Tue Mar 02 03:43:15 2004 +0000
@@ -53,6 +53,7 @@
 #include "byte-swap.h"
 #include "ls-oct-ascii.h"
 #include "ls-utils.h"
+#include "ls-hdf5.h"
 
 #if ! defined (UCHAR_MAX)
 #define UCHAR_MAX 255
@@ -508,17 +509,23 @@
 octave_matrix::save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats)
 {
   dim_vector d = dims ();
-  hsize_t hdims[d.length () > 2 ? d.length () : 3];
+  int empty = save_hdf5_empty (loc_id, name, d);
+  if (empty != 0)
+    return (empty > 0);
+
+  int rank = d.length ();
   hid_t space_hid = -1, data_hid = -1;
-  int rank = ( (d (0) == 1) && (d.length () == 2) ? 1 : d.length ());
   bool retval = true;
   NDArray m = array_value ();
 
+  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
+
   // Octave uses column-major, while HDF5 uses row-major ordering
-  for (int i = 0, j = d.length() - 1; i < d.length (); i++, j--)
-    hdims[i] = d (j);
+  for (int i = 0; i < rank; i++)
+    hdims[i] = d (rank-i-1);
+ 
+  space_hid = H5Screate_simple (rank, hdims, (hsize_t *)0);
 
-  space_hid = H5Screate_simple (rank, hdims, (hsize_t*) 0);
   if (space_hid < 0) return false;
 
   hid_t save_type_hid = H5T_NATIVE_DOUBLE;
@@ -566,6 +573,13 @@
 octave_matrix::load_hdf5 (hid_t loc_id, const char *name,
 			  bool /* have_h5giterate_bug */)
 {
+  dim_vector dv;
+  int empty = load_hdf5_empty (loc_id, name, dv);
+  if (empty > 0)
+    matrix.resize(dv);
+  if (empty != 0)
+      return (empty > 0);
+
   bool retval = false;
   hid_t data_hid = H5Dopen (loc_id, name);
   hid_t space_id = H5Dget_space (data_hid);
@@ -584,8 +598,6 @@
 
   H5Sget_simple_extent_dims (space_id, hdims, maxdims);
 
-  dim_vector dv;
-
   // Octave uses column-major, while HDF5 uses row-major ordering
   if (rank == 1)
     {
--- a/src/ov-str-mat.cc	Fri Feb 27 16:40:59 2004 +0000
+++ b/src/ov-str-mat.cc	Tue Mar 02 03:43:15 2004 +0000
@@ -240,19 +240,35 @@
 				    bool& /* infnan_warned */, 
 				    bool /* strip_nan_and_inf */)
 {
-  charMatrix chm = char_matrix_value ();
-  int elements = chm.rows ();
-  os << "# elements: " << elements << "\n";
-  for (int i = 0; i < elements; i++)
+  dim_vector d = dims ();
+  if (d.length () > 2)
+    {
+      charNDArray tmp = char_array_value ();
+      os << "# ndims: " << d.length () << "\n";
+      for (int i=0; i < d.length (); i++)
+	os << " " << d (i);
+      os << "\n";
+      os.write (X_CAST (char *, tmp.fortran_vec ()), d.numel ());
+      os << "\n";
+    }
+  else
     {
-      unsigned len = chm.cols ();
-      os << "# length: " << len << "\n";
-      std::string tstr = chm.row_as_string (i, false, true);
-      const char *tmp = tstr.data ();
-      if (tstr.length () > len)
-	panic_impossible ();
-      os.write (X_CAST (char *, tmp), len);
-      os << "\n";
+      // Keep this case, rather than use generic code above for
+      // backward compatiability. Makes load_ascii much more complex!!
+      charMatrix chm = char_matrix_value ();
+      int elements = chm.rows ();
+      os << "# elements: " << elements << "\n";
+      for (int i = 0; i < elements; i++)
+	{
+	  unsigned len = chm.cols ();
+	  os << "# length: " << len << "\n";
+	  std::string tstr = chm.row_as_string (i, false, true);
+	  const char *tmp = tstr.data ();
+	  if (tstr.length () > len)
+	    panic_impossible ();
+	  os.write (X_CAST (char *, tmp), len);
+	  os << "\n";
+	}
     }
 
   return true;
@@ -261,88 +277,130 @@
 bool 
 octave_char_matrix_str::load_ascii (std::istream& is)
 {
-  int elements;
+  int mdims = 0;
   bool success = true;
   std::streampos pos = is.tellg ();
 
-  if (extract_keyword (is, "elements", elements, true))
+  if (extract_keyword (is, "ndims", mdims, true))
     {
-
-      if (elements >= 0)
+      if (mdims >= 0)
 	{
-	  // XXX FIXME XXX -- need to be able to get max length
-	  // before doing anything.
+	  dim_vector dv;
+	  dv.resize (mdims);
+
+	  for (int i = 0; i < mdims; i++)
+	    is >> dv(i);
 
-	  charMatrix chm (elements, 0);
-	  int max_len = 0;
-	  for (int i = 0; i < elements; i++)
+	  charNDArray tmp(dv);
+	  char *ftmp = tmp.fortran_vec ();
+
+	  // Skip the return line
+	  if (! is.read (ftmp, 1))
+	    return false;
+
+	  if (! is.read (ftmp, dv.numel ()) || !is)
 	    {
-	      int len;
-	      if (extract_keyword (is, "length", len) && len >= 0)
-		{
-		  OCTAVE_LOCAL_BUFFER (char, tmp, len+1);
-		  
-		  if (len > 0 && ! is.read (X_CAST (char *, tmp), len))
-		    {
-		      error ("load: failed to load string constant");
-		      success = false;
-		      break;
-		    }
-		  else
-		    {
-		      tmp [len] = '\0';
-		      if (len > max_len)
-			{
-			  max_len = len;
-			  chm.resize (elements, max_len, 0);
-			}
-		      chm.insert (tmp, i, 0);
-		    }
-		}
-	      else
-		{
-		  error ("load: failed to extract string length for element %d", 
-			 i+1);
-		  success = false;
-		}
+	      error ("load: failed to load string constant");
+	      success = false;
 	    }
-	  
-	  if (! error_state)
-	    matrix = chm;
-	  
+	  else
+	    matrix = tmp;
 	}
       else
 	{
-	  error ("load: failed to extract number of string elements");
+	  error ("load: failed to extract matrix size");
 	  success = false;
 	}
     }
   else
     {
+      int elements;
+
       // re-read the same line again
       is.clear ();
       is.seekg (pos);
 
-      int len;
-      
-      if (extract_keyword (is, "length", len) && len >= 0)
+      if (extract_keyword (is, "elements", elements, true))
 	{
-	  // This is cruft for backward compatiability, but relatively harmless.
+
+	  if (elements >= 0)
+	    {
+	      // XXX FIXME XXX -- need to be able to get max length
+	      // before doing anything.
 
-	  OCTAVE_LOCAL_BUFFER (char, tmp, len+1);
-
-	  if (len > 0 && ! is.read (X_CAST (char *, tmp), len))
-	    {
-	      error ("load: failed to load string constant");
+	      charMatrix chm (elements, 0);
+	      int max_len = 0;
+	      for (int i = 0; i < elements; i++)
+		{
+		  int len;
+		  if (extract_keyword (is, "length", len) && len >= 0)
+		    {
+		      OCTAVE_LOCAL_BUFFER (char, tmp, len+1);
+		  
+		      if (len > 0 && ! 
+			  is.read (X_CAST (char *, tmp), len))
+			{
+			  error ("load: failed to load string constant");
+			  success = false;
+			  break;
+			}
+		      else
+			{
+			  tmp [len] = '\0';
+			  if (len > max_len)
+			    {
+			      max_len = len;
+			      chm.resize (elements, max_len, 0);
+			    }
+			  chm.insert (tmp, i, 0);
+			}
+		    }
+		  else
+		    {
+		      error ("load: failed to extract string length for element %d", 
+			     i+1);
+		      success = false;
+		    }
+		}
+	  
+	      if (! error_state)
+		matrix = chm;
+	  
 	    }
 	  else
 	    {
-	      tmp [len] = '\0';
+	      error ("load: failed to extract number of string elements");
+	      success = false;
+	    }
+	}
+      else
+	{
+	  // re-read the same line again
+	  is.clear ();
+	  is.seekg (pos);
 
-	      if (is)
-		matrix = charMatrix (tmp);
+	  int len;
+      
+	  if (extract_keyword (is, "length", len) && len >= 0)
+	    {
+	      // This is cruft for backward compatiability, 
+	      // but relatively harmless.
+
+	      OCTAVE_LOCAL_BUFFER (char, tmp, len+1);
+
+	      if (len > 0 && ! is.read (X_CAST (char *, tmp), len))
+		{
+		  error ("load: failed to load string constant");
+		}
 	      else
-		error ("load: failed to load string constant");
+		{
+		  tmp [len] = '\0';
+		  
+		  if (is)
+		    matrix = charMatrix (tmp);
+		  else
+		    error ("load: failed to load string constant");
+		}
 	    }
 	}
     }
@@ -354,17 +412,21 @@
 octave_char_matrix_str::save_binary (std::ostream& os,
 				     bool& /* save_as_floats */)
 {
-  FOUR_BYTE_INT nr = rows ();
-  os.write (X_CAST (char *, &nr), 4);
-  charMatrix chm = char_matrix_value ();
-  for (int i = 0; i < nr; i++)
+  dim_vector d = dims ();
+  if (d.length() < 1)
+    return false;
+
+  // Use negative value for ndims to differentiate with old format!!
+  FOUR_BYTE_INT tmp = - d.length();
+  os.write (X_CAST (char *, &tmp), 4);
+  for (int i=0; i < d.length (); i++)
     {
-      FOUR_BYTE_INT len = chm.cols ();
-      os.write (X_CAST (char *, &len), 4);
-      std::string tstr = chm.row_as_string (i);
-      const char *btmp = tstr.data ();
-      os.write (X_CAST (char *, btmp), len);
+      tmp = d(i);
+      os.write (X_CAST (char *, &tmp), 4);
     }
+
+  charNDArray m = char_array_value ();
+  os.write (m.fortran_vec (), d.numel ());
   return true;
 }
 
@@ -377,28 +439,55 @@
     return false;
   if (swap)
     swap_4_bytes (X_CAST (char *, &elements));
-  charMatrix chm (elements, 0);
-  int max_len = 0;
-  for (int i = 0; i < elements; i++)
+
+  if (elements < 0)
     {
-      FOUR_BYTE_INT len;
-      if (! is.read (X_CAST (char *, &len), 4))
+      FOUR_BYTE_INT mdims = - elements;
+      FOUR_BYTE_INT di;
+      dim_vector dv;
+      dv.resize (mdims);
+
+      for (int i = 0; i < mdims; i++)
+	{
+	  if (! is.read (X_CAST (char *, &di), 4))
+	    return false;
+	  if (swap)
+	    swap_4_bytes (X_CAST (char *, &di));
+	  dv(i) = di;
+	}
+      
+      charNDArray m(dv);
+      char *tmp = m.fortran_vec ();
+      is.read (tmp, dv.numel ());
+      
+      if (error_state || ! is)
 	return false;
-      if (swap)
-	swap_4_bytes (X_CAST (char *, &len));
-      OCTAVE_LOCAL_BUFFER (char, btmp, len+1);
-      if (! is.read (X_CAST (char *, btmp), len))
-	return false;
-      if (len > max_len)
+      matrix = m;
+    }
+  else
+    {
+      charMatrix chm (elements, 0);
+      int max_len = 0;
+      for (int i = 0; i < elements; i++)
 	{
-	  max_len = len;
-	  chm.resize (elements, max_len, 0);
+	  FOUR_BYTE_INT len;
+	  if (! is.read (X_CAST (char *, &len), 4))
+	    return false;
+	  if (swap)
+	    swap_4_bytes (X_CAST (char *, &len));
+	  OCTAVE_LOCAL_BUFFER (char, btmp, len+1);
+	  if (! is.read (X_CAST (char *, btmp), len))
+	    return false;
+	  if (len > max_len)
+	    {
+	      max_len = len;
+	      chm.resize (elements, max_len, 0);
+	    }
+	  btmp [len] = '\0';
+	  chm.insert (btmp, i, 0);
 	}
-      btmp [len] = '\0';
-      chm.insert (btmp, i, 0);
+      matrix = chm;
     }
-
-  matrix = chm;
   return true;
 }
 
@@ -407,47 +496,43 @@
 octave_char_matrix_str::save_hdf5 (hid_t loc_id, const char *name,
 				   bool /* save_as_floats */)
 {
-  hsize_t dimens[3];
-  hid_t space_hid = -1, type_hid = -1, data_hid = -1;
-  bool retval = true;
+  dim_vector d = dims ();
+  int empty = save_hdf5_empty (loc_id, name, d);
+  if (empty != 0)
+    return (empty > 0);
 
-  int nr = rows ();
-  charMatrix chm = char_matrix_value ();
-  int nc = chm.cols ();
+  int rank = d.length ();
+  hid_t space_hid = -1, data_hid = -1;
+  bool retval = true;
+  charNDArray m = char_array_value ();
+
+  OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
 
-  // create datatype for (null-terminated) string to write from:
-  type_hid = H5Tcopy (H5T_C_S1); H5Tset_size (type_hid, nc + 1);
-  if (type_hid < 0) return false;
+  // Octave uses column-major, while HDF5 uses row-major ordering
+  for (int i = 0; i < rank; i++)
+    hdims[i] = d (rank-i-1);
+ 
+  space_hid = H5Screate_simple (rank, hdims, (hsize_t *)0);
+  if (space_hid < 0)
+    return false;
 
-  dimens[0] = nr;
-  space_hid = H5Screate_simple (nr > 0 ? 1 : 0, dimens, (hsize_t*) 0);
-  if (space_hid < 0)
+  data_hid = H5Dcreate (loc_id, name, H5T_NATIVE_CHAR, space_hid, 
+			H5P_DEFAULT);
+  if (data_hid < 0)
     {
-      H5Tclose (type_hid);
+      H5Sclose (space_hid);
       return false;
     }
 
-  data_hid = H5Dcreate (loc_id, name, type_hid, space_hid, H5P_DEFAULT);
-  if (data_hid < 0)
-    {
-      H5Sclose (space_hid);
-      H5Tclose (type_hid);
-      return false;
-    }
+  OCTAVE_LOCAL_BUFFER (char, s, d.numel ());
 
-  OCTAVE_LOCAL_BUFFER (char, s, nr * (nc + 1));
+  for (int i = 0; i < d.numel(); ++i)
+    s[i] = m(i);
 
-  for (int i = 0; i < nr; ++i)
-    {
-      std::string tstr = chm.row_as_string (i);
-      strcpy (s + i * (nc+1), tstr.c_str ());
-    }
-
-  retval = H5Dwrite (data_hid, type_hid, H5S_ALL, H5S_ALL, H5P_DEFAULT,
-		     (void*) s) >= 0;
+  retval = H5Dwrite (data_hid, H5T_NATIVE_CHAR, H5S_ALL, H5S_ALL, 
+		     H5P_DEFAULT, (void*) s) >= 0;
 
   H5Dclose (data_hid);
-  H5Tclose (type_hid);
   H5Sclose (space_hid);
   return retval;
 }
@@ -456,105 +541,162 @@
 octave_char_matrix_str::load_hdf5 (hid_t loc_id, const char *name,
 				   bool /* have_h5giterate_bug */)
 {
+  dim_vector dv;
+  int empty = load_hdf5_empty (loc_id, name, dv);
+  if (empty > 0)
+    matrix.resize(dv);
+  if (empty != 0)
+      return (empty > 0);
+
   hid_t data_hid = H5Dopen (loc_id, name);
   hid_t space_hid = H5Dget_space (data_hid);
   hsize_t rank = H5Sget_simple_extent_ndims (space_hid);
   hid_t type_hid = H5Dget_type (data_hid);
+  hid_t type_class_hid = H5Tget_class (type_hid);
 
-  if (rank == 0)
+  if (type_class_hid == H5T_INTEGER)
     {
-      // a single string:
-      int slen = H5Tget_size (type_hid);
-      if (slen < 0)
+      bool retval = false;
+      if (rank < 1)
 	{
 	  H5Tclose (type_hid);
 	  H5Sclose (space_hid);
 	  H5Dclose (data_hid);
 	  return false;
 	}
+
+      OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
+      OCTAVE_LOCAL_BUFFER (hsize_t, maxdims, rank);
+
+      H5Sget_simple_extent_dims (space_hid, hdims, maxdims);
+
+      // Octave uses column-major, while HDF5 uses row-major ordering
+      if (rank == 1)
+	{
+	  dv.resize (2);
+	  dv(0) = 1;
+	  dv(1) = hdims[0];
+	}
       else
 	{
-	  OCTAVE_LOCAL_BUFFER (char, s, slen);
-	  // create datatype for (null-terminated) string
-	  // to read into:
-	  hid_t st_id = H5Tcopy (H5T_C_S1);
-	  H5Tset_size (st_id, slen);
-	  if (H5Dread (data_hid, st_id, H5S_ALL, H5S_ALL, 
-		       H5P_DEFAULT, (void *) s) < 0)
+	  dv.resize (rank);
+	  for (int i = 0, j = rank - 1; i < (int)rank; i++, j--)
+	    dv(j) = hdims[i];
+	}
+
+      charNDArray m (dv);
+      char *str = m.fortran_vec ();
+      if (H5Dread (data_hid, H5T_NATIVE_CHAR, H5S_ALL, H5S_ALL, 
+		   H5P_DEFAULT, (void *) str) >= 0) 
+	{
+	  retval = true;
+	  matrix = m;
+	}
+
+      H5Tclose (type_hid);
+      H5Sclose (space_hid);
+      H5Dclose (data_hid);
+      return true;
+    }
+  else
+    {
+      // This is cruft for backward compatiability and easy data
+      // importation
+      if (rank == 0)
+	{
+	  // a single string:
+	  int slen = H5Tget_size (type_hid);
+	  if (slen < 0)
 	    {
-	      H5Tclose (st_id);
 	      H5Tclose (type_hid);
 	      H5Sclose (space_hid);
 	      H5Dclose (data_hid);
 	      return false;
 	    }
+	  else
+	    {
+	      OCTAVE_LOCAL_BUFFER (char, s, slen);
+	      // create datatype for (null-terminated) string
+	      // to read into:
+	      hid_t st_id = H5Tcopy (H5T_C_S1);
+	      H5Tset_size (st_id, slen);
+	      if (H5Dread (data_hid, st_id, H5S_ALL, H5S_ALL, 
+			   H5P_DEFAULT, (void *) s) < 0)
+		{
+		  H5Tclose (st_id);
+		  H5Tclose (type_hid);
+		  H5Sclose (space_hid);
+		  H5Dclose (data_hid);
+		  return false;
+		}
 
-	  matrix = charMatrix (s);
+	      matrix = charMatrix (s);
 	  
-	  H5Tclose (st_id);
-	  H5Tclose (type_hid);
-	  H5Sclose (space_hid);
-	  H5Dclose (data_hid);
-	  return true;
+	      H5Tclose (st_id);
+	      H5Tclose (type_hid);
+	      H5Sclose (space_hid);
+	      H5Dclose (data_hid);
+	      return true;
+	    }
 	}
-    }
-  else if (rank == 1)
-    {
-      // string vector
-      hsize_t elements, maxdim;
-      H5Sget_simple_extent_dims (space_hid, &elements, &maxdim);
-      int slen = H5Tget_size (type_hid);
-      if (slen < 0)
+      else if (rank == 1)
+	{
+	  // string vector
+	  hsize_t elements, maxdim;
+	  H5Sget_simple_extent_dims (space_hid, &elements, &maxdim);
+	  int slen = H5Tget_size (type_hid);
+	  if (slen < 0)
+	    {
+	      H5Tclose (type_hid);
+	      H5Sclose (space_hid);
+	      H5Dclose (data_hid);
+	      return false;
+	    }
+	  else
+	    {
+	      // hdf5 string arrays store strings of all the
+	      // same physical length (I think), which is
+	      // slightly wasteful, but oh well.
+	  
+	      OCTAVE_LOCAL_BUFFER (char, s, elements * slen);
+
+	      // create datatype for (null-terminated) string
+	      // to read into:
+	      hid_t st_id = H5Tcopy (H5T_C_S1);
+	      H5Tset_size (st_id, slen);
+
+	      if (H5Dread (data_hid, st_id, H5S_ALL, H5S_ALL, 
+			   H5P_DEFAULT, (void *) s) < 0)
+		{
+		  H5Tclose (st_id);
+		  H5Tclose (type_hid);
+		  H5Sclose (space_hid);
+		  H5Dclose (data_hid);
+		  return false;
+		}
+
+	      charMatrix chm (elements, slen - 1);
+	      for (hsize_t i = 0; i < elements; ++i)
+		{
+		  chm.insert (s + i*slen, i, 0);
+		}
+
+	      matrix = chm;
+
+	      H5Tclose (st_id);
+	      H5Tclose (type_hid);
+	      H5Sclose (space_hid);
+	      H5Dclose (data_hid);
+	      return true;
+	    }
+	}
+      else
 	{
 	  H5Tclose (type_hid);
 	  H5Sclose (space_hid);
 	  H5Dclose (data_hid);
 	  return false;
 	}
-      else
-	{
-	  // hdf5 string arrays store strings of all the
-	  // same physical length (I think), which is
-	  // slightly wasteful, but oh well.
-	  
-	  OCTAVE_LOCAL_BUFFER (char, s, elements * slen);
-
-	  // create datatype for (null-terminated) string
-	  // to read into:
-	  hid_t st_id = H5Tcopy (H5T_C_S1);
-	  H5Tset_size (st_id, slen);
-
-	  if (H5Dread (data_hid, st_id, H5S_ALL, H5S_ALL, 
-		       H5P_DEFAULT, (void *) s) < 0)
-	    {
-	      H5Tclose (st_id);
-	      H5Tclose (type_hid);
-	      H5Sclose (space_hid);
-	      H5Dclose (data_hid);
-	      return false;
-	    }
-
-	  charMatrix chm (elements, slen - 1);
-	  for (hsize_t i = 0; i < elements; ++i)
-	    {
-	      chm.insert (s + i*slen, i, 0);
-	    }
-
-	  matrix = chm;
-
-	  H5Tclose (st_id);
-	  H5Tclose (type_hid);
-	  H5Sclose (space_hid);
-	  H5Dclose (data_hid);
-	  return true;
-	}
-    }
-  else
-    {
-      H5Tclose (type_hid);
-      H5Sclose (space_hid);
-      H5Dclose (data_hid);
-      return false;
     }
 }
 #endif