Mercurial > hg > octave-nkf
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 +++ b/src/ov-str-mat.cc @@ -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++ ***