# HG changeset patch # User John W. Eaton # Date 1236124327 18000 # Node ID 5a956c026b6cb703810db9f949a5ee382340a8df # Parent ab87d08d9a1b3d566f983f54b66567b386ba564e preserve field order when saving structs diff -r ab87d08d9a1b -r 5a956c026b6c src/ChangeLog --- 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 + * 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. diff -r ab87d08d9a1b -r 5a956c026b6c src/ls-mat5.cc --- 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 (&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, diff -r ab87d08d9a1b -r 5a956c026b6c src/ov-struct.cc --- 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 (&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 (num_obj) && (retval2 = H5Giterate (loc_id, name, ¤t_item, hdf5_read_next_data, &dsub)) > 0)