diff src/ov-struct.cc @ 8907:5a956c026b6c

preserve field order when saving structs
author John W. Eaton <jwe@octave.org>
date Tue, 03 Mar 2009 18:52:07 -0500
parents 280fae940bb0
children eb63fbe60fab
line wrap: on
line diff
--- a/src/ov-struct.cc
+++ b/src/ov-struct.cc
@@ -1202,19 +1202,25 @@
 octave_struct::save_ascii (std::ostream& os)
 {
   Octave_map m = map_value ();
-  os << "# length: " << m.nfields () << "\n";
+
+  octave_idx_type nf = m.nfields ();
+
+  os << "# length: " << nf << "\n";
 
-  Octave_map::iterator i = m.begin ();
-  while (i != m.end ())
+  // Iterating over the list of keys will preserve the order of the
+  // fields.
+  string_vector keys = m.keys ();
+
+  for (octave_idx_type i = 0; i < nf; i++)
     {
-      octave_value val = map.contents (i);
+      std::string key = keys(i);
 
-      bool b = save_ascii_data (os, val, m.key (i), false, 0);
+      octave_value val = map.contents (key);
+
+      bool b = save_ascii_data (os, val, key, false, 0);
       
       if (! b)
 	return os;
-
-      i++;
     }
 
   return true;
@@ -1281,20 +1287,25 @@
 {
   Octave_map m = map_value ();
 
-  int32_t len = m.nfields ();
+  octave_idx_type nf = m.nfields ();
+
+  int32_t len = nf;
   os.write (reinterpret_cast<char *> (&len), 4);
-  
-  Octave_map::iterator i = m.begin ();
-  while (i != m.end ())
+
+  // Iterating over the list of keys will preserve the order of the
+  // fields.
+  string_vector keys = m.keys ();
+
+  for (octave_idx_type i = 0; i < nf; i++)
     {
-      octave_value val = map.contents (i);
+      std::string key = keys(i);
 
-      bool b = save_binary_data (os, val, m.key (i), "", 0, save_as_floats);
+      octave_value val = map.contents (key);
+
+      bool b = save_binary_data (os, val, key, "", 0, save_as_floats);
       
       if (! b)
 	return os;
-
-      i++;
     }
 
   return true;
@@ -1367,18 +1378,24 @@
 
   // recursively add each element of the structure to this group
   Octave_map m = map_value ();
-  Octave_map::iterator i = m.begin ();
-  while (i != m.end ())
+
+  octave_idx_type nf = m.nfields ();
+
+  // Iterating over the list of keys will preserve the order of the
+  // fields.
+  string_vector keys = m.keys ();
+
+  for (octave_idx_type i = 0; i < nf; i++)
     {
-      octave_value val = map.contents (i);
+      std::string key = keys(i);
 
-      bool retval2 = add_hdf5_data (data_hid, val, m.key (i), "", false, 
+      octave_value val = map.contents (key);
+
+      bool retval2 = add_hdf5_data (data_hid, val, key, "", false, 
 				    save_as_floats);
 
       if (! retval2)
 	break;
-
-      i++;
     }
 
   H5Gclose (data_hid);
@@ -1403,6 +1420,9 @@
   H5Gget_num_objs (group_id, &num_obj);
   H5Gclose (group_id);
 
+  // FIXME -- fields appear to be sorted alphabetically on loading.
+  // Why is that happening?
+
   while (current_item < static_cast<int> (num_obj)
 	 && (retval2 = H5Giterate (loc_id, name, &current_item,
 				   hdf5_read_next_data, &dsub)) > 0)