diff src/ov-str-mat.cc @ 4687:e95c86d48732

[project @ 2004-01-06 21:53:34 by jwe]
author jwe
date Tue, 06 Jan 2004 21:53:34 +0000
parents 7849788ca4bd
children 14dc2267c343
line wrap: on
line diff
--- a/src/ov-str-mat.cc	Tue Jan 06 19:31:57 2004 +0000
+++ b/src/ov-str-mat.cc	Tue Jan 06 21:53:34 2004 +0000
@@ -41,6 +41,11 @@
 #include "pr-output.h"
 #include "pt-mat.h"
 
+#include "byte-swap.h"
+#include "ls-oct-ascii.h"
+#include "ls-hdf5.h"
+#include "ls-utils.h"
+
 DEFINE_OCTAVE_ALLOCATOR (octave_char_matrix_str);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_char_matrix_str, "string", "char");
@@ -229,6 +234,330 @@
 			 current_print_indent_level (), true);
 }
 
+bool 
+octave_char_matrix_str::save_ascii (std::ostream& os,
+				    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++)
+    {
+      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;
+}
+
+bool 
+octave_char_matrix_str::load_ascii (std::istream& is)
+{
+  int elements;
+  bool success = true;
+  std::streampos pos = is.tellg ();
+
+  if (extract_keyword (is, "elements", elements, true))
+    {
+
+      if (elements >= 0)
+	{
+	  // XXX FIXME XXX -- need to be able to get max length
+	  // before doing anything.
+
+	  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
+	{
+	  error ("load: failed to extract number of string elements");
+	  success = false;
+	}
+    }
+  else
+    {
+      // re-read the same line again
+      is.clear ();
+      is.seekg (pos);
+
+      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
+	    {
+	      tmp [len] = '\0';
+
+	      if (is)
+		matrix = charMatrix (tmp);
+	      else
+		error ("load: failed to load string constant");
+	    }
+	}
+    }
+
+  return success;
+}
+
+bool 
+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++)
+    {
+      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);
+    }
+  return true;
+}
+
+bool 
+octave_char_matrix_str::load_binary (std::istream& is, bool swap,
+				     oct_mach_info::float_format /* fmt */)
+{
+  FOUR_BYTE_INT elements;
+  if (! is.read (X_CAST (char *, &elements), 4))
+    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++)
+    {
+      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);
+    }
+
+  matrix = chm;
+  return true;
+}
+
+#if defined (HAVE_HDF5)
+bool
+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;
+
+  int nr = rows ();
+  charMatrix chm = char_matrix_value ();
+  int nc = chm.cols ();
+
+  // 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;
+
+  dimens[0] = nr;
+  space_hid = H5Screate_simple (nr > 0 ? 1 : 0, dimens, (hsize_t*) 0);
+  if (space_hid < 0)
+    {
+      H5Tclose (type_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, nr * (nc + 1));
+
+  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;
+
+  H5Dclose (data_hid);
+  H5Tclose (type_hid);
+  H5Sclose (space_hid);
+  return retval;
+}
+
+bool 
+octave_char_matrix_str::load_hdf5 (hid_t loc_id, const char *name,
+				   bool /* have_h5giterate_bug */)
+{
+  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);
+
+  if (rank == 0)
+    {
+      // a single string:
+      int slen = H5Tget_size (type_hid);
+      if (slen < 0)
+	{
+	  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);
+	  
+	  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)
+	{
+	  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
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***