Mercurial > hg > octave-lyh
diff src/ov-range.cc @ 4687:e95c86d48732
[project @ 2004-01-06 21:53:34 by jwe]
author | jwe |
---|---|
date | Tue, 06 Jan 2004 21:53:34 +0000 |
parents | d44675070f1a |
children | d2038299c683 |
line wrap: on
line diff
--- a/src/ov-range.cc +++ b/src/ov-range.cc @@ -41,6 +41,10 @@ #include "ov-scalar.h" #include "pr-output.h" +#include "byte-swap.h" +#include "ls-hdf5.h" +#include "ls-utils.h" + DEFINE_OCTAVE_ALLOCATOR (octave_range); DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_range, "range", "double"); @@ -250,6 +254,213 @@ return retval; } +// Skip white space and comments on stream IS. + +static void +skip_comments (std::istream& is) +{ + char c = '\0'; + while (is.get (c)) + { + if (c == ' ' || c == '\t' || c == '\n') + ; // Skip whitespace on way to beginning of next line. + else + break; + } + + for (;;) + { + if (is && (c == '%' || c == '#')) + while (is.get (c) && c != '\n') + ; // Skip to beginning of next line, ignoring everything. + else + break; + } +} + +bool +octave_range::save_ascii (std::ostream& os, bool& /* infnan_warned */, + bool /* strip_nan_and_inf */) +{ + Range r = range_value (); + double base = r.base (); + double limit = r.limit (); + double inc = r.inc (); + + os << "# base, limit, increment\n"; + octave_write_double (os, base); + os << " "; + octave_write_double (os, limit); + os << " "; + octave_write_double (os, inc); + os << "\n"; + + return true; +} + +bool +octave_range::load_ascii (std::istream& is) +{ + // # base, limit, range comment added by save (). + skip_comments (is); + + is >> range; + + if (!is) + { + error ("load: failed to load range constant"); + return false; + } + + return true; +} + +bool +octave_range::save_binary (std::ostream& os, bool& /* save_as_floats */) +{ + char tmp = (char) LS_DOUBLE; + os.write (X_CAST (char *, &tmp), 1); + Range r = range_value (); + double bas = r.base (); + double lim = r.limit (); + double inc = r.inc (); + os.write (X_CAST (char *, &bas), 8); + os.write (X_CAST (char *, &lim), 8); + os.write (X_CAST (char *, &inc), 8); + + return true; +} + +bool +octave_range::load_binary (std::istream& is, bool swap, + oct_mach_info::float_format /* fmt */) +{ + char tmp; + if (! is.read (X_CAST (char *, &tmp), 1)) + return false; + double bas, lim, inc; + if (! is.read (X_CAST (char *, &bas), 8)) + return false; + if (swap) + swap_8_bytes (X_CAST (char *, &bas)); + if (! is.read (X_CAST (char *, &lim), 8)) + return false; + if (swap) + swap_8_bytes (X_CAST (char *, &lim)); + if (! is.read (X_CAST (char *, &inc), 8)) + return false; + if (swap) + swap_8_bytes (X_CAST (char *, &inc)); + Range r (bas, lim, inc); + range = r; + return true; +} + +#if defined (HAVE_HDF5) +// The following subroutines creates an HDF5 representation of the way +// we will store Octave range types (triplets of floating-point numbers). +// NUM_TYPE is the HDF5 numeric type to use for storage (e.g. +// H5T_NATIVE_DOUBLE to save as 'double'). Note that any necessary +// conversions are handled automatically by HDF5. + +static hid_t +hdf5_make_range_type (hid_t num_type) +{ + hid_t type_id = H5Tcreate (H5T_COMPOUND, sizeof (double) * 3); + + H5Tinsert (type_id, "base", 0 * sizeof (double), num_type); + H5Tinsert (type_id, "limit", 1 * sizeof (double), num_type); + H5Tinsert (type_id, "increment", 2 * sizeof (double), num_type); + + return type_id; +} + +bool +octave_range::save_hdf5 (hid_t loc_id, const char *name, + bool /* save_as_floats */) +{ + hsize_t dims[3]; + hid_t space_hid = -1, type_hid = -1, data_hid = -1; + bool retval = true; + + space_hid = H5Screate_simple (0, dims, (hsize_t*) 0); + if (space_hid < 0) return false; + + type_hid = hdf5_make_range_type (H5T_NATIVE_DOUBLE); + if (type_hid < 0) + { + 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; + } + + Range r = range_value (); + double range_vals[3]; + range_vals[0] = r.base (); + range_vals[1] = r.limit (); + range_vals[2] = r.inc (); + + retval = H5Dwrite (data_hid, type_hid, H5S_ALL, H5S_ALL, H5P_DEFAULT, + (void*) range_vals) >= 0; + + H5Dclose (data_hid); + H5Tclose (type_hid); + H5Sclose (space_hid); + return retval; +} + +bool +octave_range::load_hdf5 (hid_t loc_id, const char *name, + bool /* have_h5giterate_bug */) +{ + bool retval = false; + hid_t data_hid = H5Dopen (loc_id, name); + hid_t type_hid = H5Dget_type (data_hid); + + hid_t range_type = hdf5_make_range_type (H5T_NATIVE_DOUBLE); + + if (! hdf5_types_compatible (type_hid, range_type)) + { + H5Tclose(range_type); + H5Dclose (data_hid); + return false; + } + + hid_t space_hid = H5Dget_space (data_hid); + hsize_t rank = H5Sget_simple_extent_ndims (space_hid); + + if (rank != 0) + { + H5Tclose(range_type); + H5Sclose (space_hid); + H5Dclose (data_hid); + return false; + } + + double rangevals[3]; + if (H5Dread (data_hid, range_type, H5S_ALL, H5S_ALL, H5P_DEFAULT, + (void *) rangevals) >= 0) + { + retval = true; + Range r (rangevals[0], rangevals[1], rangevals[2]); + range = r; + } + + H5Tclose(range_type); + H5Sclose (space_hid); + H5Dclose (data_hid); + return retval; + +} +#endif + /* ;;; Local Variables: *** ;;; mode: C++ ***