octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Changset]: Loading and saving of classes


From: David Bateman
Subject: [Changset]: Loading and saving of classes
Date: Thu, 09 Oct 2008 20:14:29 +0100
User-agent: Mozilla-Thunderbird 2.0.0.16 (X11/20080724)

The attached changeset adds the possibility to save and load classes in all possible file types. It also adds the methods saveobj and loadobj that are called prior to saving and after reloading the object to manipulate the data appropriately if needed.

Regards
David

--
David Bateman                                address@hidden
35 rue Gambetta                              +33 1 46 04 02 18 (Home)
92100 Boulogne-Billancourt FRANCE            +33 6 72 01 06 33 (Mob)
# HG changeset patch
# User David Bateman <address@hidden>
# Date 1223579353 -3600
# Node ID 9320ad5376239be92a1c3681fabc073a5414b50f
# Parent  a8d349fb23490eaff31fd0e0f64146df766001ef
Allow saving/loading of classes. Add saveobj and loadobj methods

diff --git a/scripts/ChangeLog b/scripts/ChangeLog
--- a/scripts/ChangeLog
+++ b/scripts/ChangeLog
@@ -1,3 +1,8 @@
+2008-10-09  David Bateman  <address@hidden>
+
+       * general/loadobj.m, general/saveobj.m, general/display: New functions
+       * general/Makefile.in (SOURCES): Add then here.
+       
 2008-10-08  John W. Eaton  <address@hidden>
 
        * miscellaneous/fileparts.m: Handle "/file" properly.
diff --git a/scripts/general/Makefile.in b/scripts/general/Makefile.in
--- a/scripts/general/Makefile.in
+++ b/scripts/general/Makefile.in
@@ -36,17 +36,17 @@
 SOURCES = __isequal__.m __splinen__.m accumarray.m arrayfun.m \
   bicubic.m bitcmp.m bitget.m bitset.m blkdiag.m cart2pol.m \
   cart2sph.m cellidx.m cell2mat.m celldisp.m circshift.m common_size.m \
-  cplxpair.m cumtrapz.m dblquad.m deal.m del2.m diff.m flipdim.m fliplr.m \
-  flipud.m genvarname.m gradient.m idivide.m ind2sub.m int2str.m \
+  cplxpair.m cumtrapz.m dblquad.m deal.m del2.m diff.m display.m flipdim.m \
+  fliplr.m flipud.m genvarname.m gradient.m idivide.m ind2sub.m int2str.m \
   interp1.m interp1q.m interp2.m interp3.m interpn.m interpft.m \
   is_duplicate_entry.m isa.m isdefinite.m isdir.m isequal.m \
   isequalwithequalnans.m isscalar.m issquare.m issymmetric.m \
-  isvector.m logical.m logspace.m mod.m nargchk.m \
+  isvector.m loadobj.m logical.m logspace.m mod.m nargchk.m \
   nargoutchk.m nextpow2.m nthroot.m num2str.m perror.m pol2cart.m \
   polyarea.m postpad.m prepad.m quadgk.m quadl.m quadv.m randperm.m rat.m \
-  rem.m repmat.m rot90.m rotdim.m runlength.m shift.m shiftdim.m sortrows.m \
-  sph2cart.m strerror.m structfun.m sub2ind.m subsindex.m triplequad.m \
-  trapz.m tril.m triu.m
+  rem.m repmat.m rot90.m rotdim.m runlength.m saveobj.m shift.m shiftdim.m \
+  sortrows.m sph2cart.m strerror.m structfun.m sub2ind.m subsindex.m \
+  triplequad.m trapz.m tril.m triu.m
 
 DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
 
diff --git a/scripts/general/display.m b/scripts/general/display.m
new file mode 100644
--- /dev/null
+++ b/scripts/general/display.m
@@ -0,0 +1,37 @@
+## Copyright (C) 2008 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} display (@var{a})
+## Display the contents of an object. If @var{a} is an object of the
+## class "myclass", then @code{display} is called in a case like
+##
+## @example
+## myclass (@dots{})
+## @end example
+##
+## @noindent
+## where Octave is requried to display the contents of a variable of the
+## type "myclass".
+##
+## @seealso{class, subsref, subsasgn}
+## @end deftypefn
+
+function idx = display (a)
+  error ("display: not defined for class \"%s\"", class(a));
+endfunction
diff --git a/scripts/general/loadobj.m b/scripts/general/loadobj.m
new file mode 100644
--- /dev/null
+++ b/scripts/general/loadobj.m
@@ -0,0 +1,41 @@
+## Copyright (C) 2008 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} address@hidden =} loadobj (@var{a})
+## Methof of a class to manipulate an object after loading it tfrom a file. 
+## The function @code{loadobj} is called when the object @var{a} is loaded 
+## using the @code{load} function. An example of the use of @code{saveobj}
+## might be to add fields to an object that don't make sense to be saved.
+## For example
+##
+## @example
+## @group
+## function b = loadobj (a)
+##   b = a;
+##   b.addmssingfield = addfield (b;
+## endfunction
+## @end group
+## @end example
+##
+## @seealso{saveobj, class}
+## @end deftypefn
+
+function b = loadobj (a)
+  error ("loadobj: not defined for class \"%s\"", class(a));
+endfunction
diff --git a/scripts/general/saveobj.m b/scripts/general/saveobj.m
new file mode 100644
--- /dev/null
+++ b/scripts/general/saveobj.m
@@ -0,0 +1,44 @@
+## Copyright (C) 2008 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} address@hidden =} saveobj (@var{a})
+## Method of a class to manipulate an object prior to saving it to a file. 
+## The function @code{saveobj} is called when the object @var{a} is saved 
+## using the @code{save} function. An example of the use of @code{saveobj}
+## might be to remove fields of the object that don't make sense to be saved
+## or it might be used to ensure that certain fields of the object are
+## initialized before the object is saved. For example
+##
+## @example
+## @group
+## function b = saveobj (a)
+##   b = a;
+##   if (isempty (b.field))
+##      b.field = initfield(b);
+##   endif
+## endfunction
+## @end group
+## @end example
+##
+## @seealso{loadobj, class}
+## @end deftypefn
+
+function b = saveobj (a)
+  error ("saveobj: not defined for class \"%s\"", class(a));
+endfunction
diff --git a/src/ChangeLog b/src/ChangeLog
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,24 @@
+2008-10-09  David Bateman  <address@hidden>
+
+       * ov-class.cc (Octave_map octave_class::map_value (void) const): 
+       Remove.
+       (bool octave_class::save_ascii (std::ostream&), 
+       bool octave_class::load_ascii (std::istream&),
+       bool octave_class::save_binary (std::ostream&, bool&),
+       bool octave_class::save_binary (std::ostream&, bool&),
+       bool octave_class::save_hdf5 (hid_t, const char *, bool),
+       bool octave_class::load_hdf5 (hid_t, const char *, bool)):
+       Allow saving and reloading of classes.
+       * ov-class. (Octave_map octave_class::map_value (void) const): 
+       Remove.
+       * ls-mat.cc (std::string read_mat5_binary_element (std::istream&, 
+       const std::string&, bool, bool&, octave_value&), 
+       int save_mat5_element_length (const octave_value&, const std::string&,
+       bool, bool)): Allow saving and loading of classes. 
+       * ls-oct-ascii.h (template <class T> bool extract_keyword 
+       (std::istream&, const char *, T&, const bool)): Initialize value with
+       null constructor rather than 0.
+       
 2008-10-07  David Bateman  <address@hidden>
 
        * graphics.cc (F__go_delete__): Allow arrays of graphic handles.
diff --git a/src/ls-mat5.cc b/src/ls-mat5.cc
--- a/src/ls-mat5.cc
+++ b/src/ls-mat5.cc
@@ -58,6 +58,7 @@
 #include "oct-obj.h"
 #include "oct-map.h"
 #include "ov-cell.h"
+#include "ov-class.h"
 #include "ov-fcn-inline.h"
 #include "pager.h"
 #include "pt-exp.h"
@@ -1099,8 +1100,18 @@
              }
            else
              {
-               warning ("load: objects are not implemented");
-               goto skip_ahead;
+               tc = new octave_class (m, classname);
+
+               if (load_path::find_method (classname, "loadobj") != 
+                   std::string())
+                 {
+                   octave_value_list tmp = feval ("loadobj", tc, 1);
+
+                   if (! error_state)
+                     tc = tmp(0);
+                   else
+                     goto data_read_error;
+                 }
              }
          }
        else
@@ -1794,7 +1805,7 @@
       ret += save_mat5_array_length (m.fortran_vec (), m.nelem (),
                                     save_as_floats);
     }
-  else if (tc.is_map () || tc.is_inline_function ()) 
+  else if (tc.is_map () || tc.is_inline_function () || tc.is_object ()) 
     {
       int fieldcnt = 0;
       const Octave_map m = tc.map_value ();
@@ -1803,6 +1814,12 @@
       if (tc.is_inline_function ())
        // length of "inline" is 6
        ret += 8 + PAD (6 > max_namelen ? max_namelen : 6);
+      else if (tc.is_object ())
+       {
+         int classlen = tc.class_name (). length ();
+
+         ret += 8 + PAD (classlen > max_namelen ? max_namelen : classlen);
+       }
 
       for (Octave_map::const_iterator i = m.begin (); i != m.end (); i++)
        fieldcnt++;
@@ -1942,7 +1959,7 @@
     flags |= MAT_FILE_STRUCT_CLASS;
   else if (tc.is_cell ())
     flags |= MAT_FILE_CELL_CLASS;
-  else if (tc.is_inline_function ())
+  else if (tc.is_inline_function () || tc.is_object ())
     flags |= MAT_FILE_OBJECT_CLASS;
   else
     {
@@ -2131,12 +2148,11 @@
       write_mat5_array (os, ::real (m_cmplx), save_as_floats);
       write_mat5_array (os, ::imag (m_cmplx), save_as_floats);
     }
-  else if (tc.is_map () || tc.is_inline_function()) 
+  else if (tc.is_map () || tc.is_inline_function() || tc.is_object ()) 
     {
-      const Octave_map m = tc.map_value ();
-      if (tc.is_inline_function ())
+      if (tc.is_inline_function () || tc.is_object ())
        {
-         std::string classname = "inline";
+         std::string classname = tc.is_object() ? tc.class_name () : "inline";
          int namelen = classname.length ();
 
          if (namelen > max_namelen)
@@ -2150,6 +2166,20 @@
          strncpy (paddedname, classname.c_str (), namelen);
          os.write (paddedname, paddedlength);
        }
+
+      Octave_map m;
+
+      if (tc.is_object () &&
+         load_path::find_method (tc.class_name (), "saveobj") != std::string())
+       {
+         octave_value_list tmp = feval ("saveobj", tc, 1);
+         if (! error_state)
+           m = tmp(0).map_value ();
+         else
+           goto error_cleanup;
+       }
+      else
+       m = tc.map_value ();
 
       // an Octave structure */
       // recursively write each element of the structure
diff --git a/src/ls-oct-ascii.h b/src/ls-oct-ascii.h
--- a/src/ls-oct-ascii.h
+++ b/src/ls-oct-ascii.h
@@ -72,7 +72,7 @@
                 const bool next_only = false)
 {
   bool status = false;
-  value = 0;
+  value = T();
 
   char c;
   while (is.get (c))
diff --git a/src/ov-class.cc b/src/ov-class.cc
--- a/src/ov-class.cc
+++ b/src/ov-class.cc
@@ -614,14 +614,6 @@
   return retval;
 }
 
-Octave_map
-octave_class::map_value (void) const
-{
-  Octave_map retval;
-  gripe_wrong_type_arg ("octave_class::map_value()", type_name ());
-  return retval;
-}
-
 string_vector
 octave_class::map_keys (void) const
 {
@@ -688,68 +680,31 @@
     }
 }
 
-bool 
-octave_class::save_ascii (std::ostream&, bool&)
+bool
+octave_class::save_ascii (std::ostream& os)
 {
-  gripe_wrong_type_arg ("octave_class::save_ascii()", type_name ());
-  return false;
-}
+  os << "# classname: " << class_name () << "\n";
+  Octave_map m;
+  if (load_path::find_method (class_name (), "saveobj") != std::string())
+    {
+      octave_value in = new octave_class (*this);
+      octave_value_list tmp = feval ("saveobj", in, 1);
+      if (! error_state)
+       m = tmp(0).map_value ();
+      else
+       return false;
+    }
+  else
+    m = map_value ();
 
-bool 
-octave_class::load_ascii (std::istream&)
-{
-  gripe_wrong_type_arg ("octave_class::load_ascii()", type_name ());
-  return false;
-}
-
-bool 
-octave_class::save_binary (std::ostream&, bool&)
-{
-  gripe_wrong_type_arg ("octave_class::save_binary()", type_name ());
-  return false;
-}
-
-bool 
-octave_class::load_binary (std::istream&, bool,
-                               oct_mach_info::float_format)
-{
-  gripe_wrong_type_arg ("octave_class::load_binary()", type_name ());
-  return false;
-}
-
-#if defined (HAVE_HDF5)
-
-bool
-octave_class::save_hdf5 (hid_t, const char *, bool)
-{
-  gripe_wrong_type_arg ("octave_class::save_binary()", type_name ());
-
-  return false;
-}
-
-bool 
-octave_class::load_hdf5 (hid_t, const char *, bool)
-{
-  gripe_wrong_type_arg ("octave_class::load_binary()", type_name ());
-
-  return false;
-}
-
-#endif
-
-#if 0
-bool
-octave_class::save_ascii (std::ostream& os, bool& infnan_warned)
-{
-  Octave_map m = map_value ();
-  os << "# length: " << m.length () << "\n";
+  os << "# length: " << m.nfields () << "\n";
 
   Octave_map::iterator i = m.begin ();
   while (i != m.end ())
     {
       octave_value val = map.contents (i);
 
-      bool b = save_ascii_data (os, val, m.key (i), infnan_warned, false, 0);
+      bool b = save_ascii_data (os, val, m.key (i), false, 0);
       
       if (! b)
        return os;
@@ -764,54 +719,82 @@
 octave_class::load_ascii (std::istream& is)
 {
   octave_idx_type len = 0;
+  std::string classname;
   bool success = true;
 
-  if (extract_keyword (is, "length", len) && len >= 0)
+  if (extract_keyword (is, "classname", classname) && classname != "")
     {
-      if (len > 0)
+      if (extract_keyword (is, "length", len) && len >= 0)
        {
-         Octave_map m (map);
+         if (len > 0)
+           {
+             Octave_map m (map);
 
-         for (octave_idx_type j = 0; j < len; j++)
-           {
-             octave_value t2;
-             bool dummy;
+             for (octave_idx_type j = 0; j < len; j++)
+               {
+                 octave_value t2;
+                 bool dummy;
 
-             // recurse to read cell elements
-             std::string nm
-               = read_ascii_data (is, std::string (), dummy, t2, j);
+                 // recurse to read cell elements
+                 std::string nm
+                   = read_ascii_data (is, std::string (), dummy, t2, j);
 
-             if (!is)
-               break;
+                 if (!is)
+                   break;
 
-             Cell tcell = t2.is_cell () ? t2.cell_value () : Cell (t2);
+                 Cell tcell = t2.is_cell () ? t2.cell_value () : Cell (t2);
 
-             if (error_state)
-               {
-                 error ("load: internal error loading class elements");
-                 return false;
+                 if (error_state)
+                   {
+                     error ("load: internal error loading class elements");
+                     return false;
+                   }
+
+                 m.assign (nm, tcell);
                }
 
-             m.assign (nm, tcell);
+             if (is) 
+               {
+                 map = m;
+                 c_name = classname;
+
+                 if (load_path::find_method (classname, "loadobj") != 
+                     std::string())
+                   {
+                     octave_value in = new octave_class (*this);
+                     octave_value_list tmp = feval ("loadobj", in, 1);
+
+                     if (! error_state)
+                       map = tmp(0).map_value ();
+                     else
+                       success = false;
+                   }
+               }
+             else
+               {
+                 error ("load: failed to load class");
+                 success = false;
+               }
            }
-
-         if (is) 
-           map = m;
+         else if (len == 0 )
+           {
+             map = Octave_map (dim_vector (1, 1));
+             c_name = classname;
+           }
          else
-           {
-             error ("load: failed to load class");
-             success = false;
-           }
+           panic_impossible ();
        }
-      else if (len == 0 )
-       map = Octave_map (dim_vector (1, 1));
-      else
-       panic_impossible ();
+      else 
+       {
+         error ("load: failed to extract number of elements in class");
+         success = false;
+       }
     }
-  else {
-    error ("load: failed to extract number of elements in class");
-    success = false;
-  }
+  else
+    {
+      error ("load: failed to extract name of class");
+      success = false;
+    }
 
   return success;
 }
@@ -819,9 +802,25 @@
 bool 
 octave_class::save_binary (std::ostream& os, bool& save_as_floats)
 {
-  Octave_map m = map_value ();
+  int32_t classname_len = class_name().length ();
 
-  int32_t len = m.length();
+  os.write (reinterpret_cast<char *> (&classname_len), 4);
+  os << class_name ();
+
+  Octave_map m;
+  if (load_path::find_method (class_name (), "saveobj") != std::string())
+    {
+      octave_value in = new octave_class (*this);
+      octave_value_list tmp = feval ("saveobj", in, 1);
+      if (! error_state)
+       m = tmp(0).map_value ();
+      else
+       return false;
+    }
+  else
+    m = map_value ();
+
+  int32_t len = m.nfields();
   os.write (reinterpret_cast<char *> (&len), 4);
   
   Octave_map::iterator i = m.begin ();
@@ -845,6 +844,23 @@
                            oct_mach_info::float_format fmt)
 {
   bool success = true;
+
+  int32_t classname_len;
+
+  is.read (reinterpret_cast<char *> (&classname_len), 4);
+  if (! is)
+    return false;
+  else if (swap)
+    swap_bytes<4> (&classname_len);
+
+  {
+    OCTAVE_LOCAL_BUFFER (char, classname, classname_len+1);
+    classname[classname_len] = '\0';
+    if (! is.read (reinterpret_cast<char *> (classname), classname_len))
+      return false;
+    c_name = classname;
+  }
+
   int32_t len;
   if (! is.read (reinterpret_cast<char *> (&len), 4))
     return false;
@@ -880,7 +896,20 @@
        }
 
       if (is) 
-       map = m;
+       {
+         map = m;
+
+         if (load_path::find_method (class_name(), "loadobj") != std::string())
+           {
+             octave_value in = new octave_class (*this);
+             octave_value_list tmp = feval ("loadobj", in, 1);
+
+             if (! error_state)
+               map = tmp(0).map_value ();
+             else
+               success = false;
+           }
+       }
       else
        {
          error ("load: failed to load class");
@@ -900,14 +929,53 @@
 bool
 octave_class::save_hdf5 (hid_t loc_id, const char *name, bool save_as_floats)
 {
+  hsize_t hdims[3];
+  hid_t group_hid = -1;
+  hid_t type_hid = -1;
+  hid_t space_hid = -1;
+  hid_t class_hid = -1;
   hid_t data_hid = -1;
+  Octave_map m;
+  Octave_map::iterator i;
 
-  data_hid = H5Gcreate (loc_id, name, 0);
-  if (data_hid < 0) return false;
+  group_hid = H5Gcreate (loc_id, name, 0);
+  if (group_hid < 0)
+    goto error_cleanup;
+
+  // Add the class name to the group
+  type_hid = H5Tcopy (H5T_C_S1); H5Tset_size (type_hid, c_name.length () + 1);
+  if (type_hid < 0)
+    goto error_cleanup;
+
+  hdims[0] = 0;
+  space_hid = H5Screate_simple (0 , hdims, 0);
+  if (space_hid < 0)
+    goto error_cleanup;
+
+  class_hid = H5Dcreate (group_hid, "classname",  type_hid, space_hid,
+                        H5P_DEFAULT);
+  if (class_hid < 0 || H5Dwrite (class_hid, type_hid, H5S_ALL, H5S_ALL, 
+                                   H5P_DEFAULT, c_name.c_str ()) < 0)
+    goto error_cleanup;
+
+  data_hid = H5Gcreate (group_hid, "value", 0);
+  if (data_hid < 0)
+    goto error_cleanup;
+
+  if (load_path::find_method (class_name (), "saveobj") != std::string())
+    {
+      octave_value in = new octave_class (*this);
+      octave_value_list tmp = feval ("saveobj", in, 1);
+      if (! error_state)
+       m = tmp(0).map_value ();
+      else
+       goto error_cleanup;
+    }
+  else
+    m = map_value ();
 
   // recursively add each element of the class to this group
-  Octave_map m = map_value ();
-  Octave_map::iterator i = m.begin ();
+  i = m.begin ();
   while (i != m.end ())
     {
       octave_value val = map.contents (i);
@@ -921,7 +989,22 @@
       i++;
     }
 
-  H5Gclose (data_hid);
+ error_cleanup:
+
+  if (data_hid > 0)
+    H5Gclose (data_hid);
+
+  if (class_hid > 0)
+    H5Dclose (class_hid);
+
+  if (space_hid > 0)
+    H5Sclose (space_hid);
+
+  if (type_hid > 0)
+    H5Tclose (type_hid);
+
+  if (group_hid > 0)
+    H5Gclose (group_hid);
 
   return true;
 }
@@ -932,22 +1015,87 @@
 {
   bool retval = false;
 
+  hid_t group_hid = -1;
+  hid_t data_hid = -1;
+  hid_t type_hid = -1;
+  hid_t type_class_hid = -1;
+  hid_t space_hid = -1;
+  hid_t subgroup_hid = -1; 
+  hid_t st_id = -1;
+
   hdf5_callback_data dsub;
 
   herr_t retval2 = 0;
   Octave_map m (dim_vector (1, 1));
   int current_item = 0;
+  hsize_t num_obj = 0;
+  int slen = 0;
+  hsize_t rank = 0;
+
+  group_hid = H5Gopen (loc_id, name);
+  if (group_hid < 0)
+    goto error_cleanup;
+
+  
+  data_hid = H5Dopen (group_hid, "classname");
+
+  if (data_hid < 0)
+    goto error_cleanup;
+
+  type_hid = H5Dget_type (data_hid);
+
+  type_class_hid = H5Tget_class (type_hid);
+
+  if (type_class_hid != H5T_STRING)
+    goto error_cleanup;
+         
+  space_hid = H5Dget_space (data_hid);
+  rank = H5Sget_simple_extent_ndims (space_hid);
+
+  if (rank != 0)
+    goto error_cleanup;
+
+  slen = H5Tget_size (type_hid);
+  if (slen < 0)
+    goto error_cleanup;
+
+  // do-while loop here to prevent goto crossing initialization of classname
+  do
+    {
+      OCTAVE_LOCAL_BUFFER (char, classname, slen);
+
+      // create datatype for (null-terminated) string to read into:
+      st_id = H5Tcopy (H5T_C_S1);
+      H5Tset_size (st_id, slen);
+
+      if (H5Dread (data_hid, st_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, 
+                  classname) < 0)
+       {
+         H5Tclose (st_id);
+         H5Dclose (data_hid);
+         H5Gclose (group_hid);
+         return false;
+       }
+     
+      H5Tclose (st_id);
+      H5Dclose (data_hid);
+      data_hid = -1;
+
+      c_name = classname;
+    }
+  while (0);
+
+
 #ifdef HAVE_H5GGET_NUM_OBJS
-  hsize_t num_obj = 0;
-  hid_t group_id = H5Gopen (loc_id, name); 
-  H5Gget_num_objs (group_id, &num_obj);
-  H5Gclose (group_id);
+  subgroup_hid = H5Gopen (group_hid, name); 
+  H5Gget_num_objs (subgroup_hid, &num_obj);
+  H5Gclose (subgroup_hid);
 
   while (current_item < static_cast<int> (num_obj)
-        && (retval2 = H5Giterate (loc_id, name, &current_item,
+        && (retval2 = H5Giterate (group_hid, name, &current_item,
                                   hdf5_read_next_data, &dsub)) > 0)
 #else
-  while ((retval2 = H5Giterate (loc_id, name, &current_item,
+  while ((retval2 = H5Giterate (group_hid, name, &current_item,
                                hdf5_read_next_data, &dsub)) > 0)
 #endif
     {
@@ -970,13 +1118,33 @@
   if (retval2 >= 0)
     {
       map = m;
-      retval = true;
+
+      if (load_path::find_method (class_name(), "loadobj") != std::string())
+       {
+         octave_value in = new octave_class (*this);
+         octave_value_list tmp = feval ("loadobj", in, 1);
+
+         if (! error_state)
+           {
+             map = tmp(0).map_value ();
+             retval = true;
+           }
+         else
+           retval = false;
+       }
+      else
+       retval = true;
     }
   
+ error_cleanup:
+  if (data_hid > 0)
+    H5Dclose (data_hid);
+
+  if (data_hid > 0)
+    H5Gclose (group_hid);
+
   return retval;
 }
-
-#endif
 
 #endif
 
diff --git a/src/ov-class.h b/src/ov-class.h
--- a/src/ov-class.h
+++ b/src/ov-class.h
@@ -110,7 +110,7 @@
 
   bool is_object (void) const { return true; }
 
-  Octave_map map_value (void) const;
+  Octave_map map_value (void) const { return map; }
 
   string_vector map_keys (void) const;
 
@@ -123,7 +123,7 @@
   void print_with_name (std::ostream& os, const std::string& name, 
                        bool print_padding = true) const;
 
-  bool save_ascii (std::ostream& os, bool& infnan_warned);
+  bool save_ascii (std::ostream& os);
 
   bool load_ascii (std::istream& is);
 

reply via email to

[Prev in Thread] Current Thread [Next in Thread]