changeset 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 ab87d08d9a1b
children 3c9acbb43f48
files src/ChangeLog src/ls-mat5.cc src/ov-struct.cc
diffstat 3 files changed, 62 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Tue Mar 03 14:10:54 2009 -0500
+++ b/src/ChangeLog	Tue Mar 03 18:52:07 2009 -0500
@@ -1,5 +1,10 @@
 2009-03-03  John W. Eaton  <jwe@octave.org>
 
+	* ov-struct.cc (octave_struct::save_ascii,
+	octave_struct::save_binary, octave_struct::save_hdf5):
+	Preserve order of structure fields.
+	* ls-mat5.cc (save_mat5_binary_element): Likewise.
+
 	* symtab.h (symbol_table::do_inherit): Only inherit values for
 	symbols from the donor_scope that already exist in the table.
 	(symbol_table::symbol_record::symbol_record_rep::dup): Now const.
--- a/src/ls-mat5.cc	Tue Mar 03 14:10:54 2009 -0500
+++ b/src/ls-mat5.cc	Tue Mar 03 18:52:07 2009 -0500
@@ -2187,21 +2187,27 @@
       {
 	char buf[64];
 	int32_t maxfieldnamelength = max_namelen + 1;
-	int fieldcnt = 0;
 
-	for (Octave_map::const_iterator i = m.begin (); i != m.end (); i++)
-	  fieldcnt++;
+	octave_idx_type nf = m.nfields ();
+
+	int fieldcnt = nf;
 
 	write_mat5_tag (os, miINT32, 4);
 	os.write (reinterpret_cast<char *> (&maxfieldnamelength), 4);
 	write_mat5_tag (os, miINT8, fieldcnt*maxfieldnamelength);
 
-	for (Octave_map::const_iterator i = m.begin (); i != m.end (); i++)
+	// 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++)
 	  {
+	    std::string key = keys(i);
+
 	    // write the name of each element
-	    std::string tstr = m.key (i);
 	    memset (buf, 0, max_namelen + 1);
-	    strncpy (buf, tstr.c_str (), max_namelen); // only 31 or 63 char names permitted
+	    // only 31 or 63 char names permitted
+	    strncpy (buf, key.c_str (), max_namelen);
 	    os.write (buf, max_namelen + 1);
 	  }
 
@@ -2211,9 +2217,11 @@
 	  {
 	    // write the data of each element
 
-	    for (Octave_map::const_iterator i = m.begin (); i != m.end (); i++)
+	    // Iterating over the list of keys will preserve the order
+	    // of the fields.
+	    for (octave_idx_type i = 0; i < nf; i++)
 	      {
-		Cell elts = m.contents (i);
+		Cell elts = m.contents (keys(i));
 
 		bool retval2 = save_mat5_binary_element (os, elts(j), "",
 							 mark_as_global,
--- a/src/ov-struct.cc	Tue Mar 03 14:10:54 2009 -0500
+++ b/src/ov-struct.cc	Tue Mar 03 18:52:07 2009 -0500
@@ -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)