# HG changeset patch # User Risto Vanhanen # Date 1368733430 14400 # Node ID dddbb5dcbf6efa67be9bb72389a75dd09f2726b2 # Parent c7d4146c570d577bfaaec8768eea0fa2e3a505a6 read Level 5 MAT files not encoded with small data element format (bug #38870) * ls-mat5.cc (read_mat5_tag): New arg IS_SMALL_DATA_ELEMENT. All callers changed. (READ_PAD): New macro. (OCTAVE_MAT5_INTEGER_READ, read_mat5_binary_element): Use READ_PAD instead of PAD. diff -r c7d4146c570d -r dddbb5dcbf6e libinterp/interp-core/ls-mat5.cc --- a/libinterp/interp-core/ls-mat5.cc Thu May 16 14:32:54 2013 -0400 +++ b/libinterp/interp-core/ls-mat5.cc Thu May 16 15:43:50 2013 -0400 @@ -81,6 +81,7 @@ #include #endif +#define READ_PAD(is_small_data_element, l) ((is_small_data_element) ? 4 : (((l)+7)/8)*8) #define PAD(l) (((l) > 0 && (l) <= 4) ? 4 : (((l)+7)/8)*8) #define INT8(l) ((l) == miINT8 || (l) == miUINT8 || (l) == miUTF8) @@ -373,7 +374,7 @@ \ std::streampos tmp_pos; \ \ - if (read_mat5_tag (is, swap, type, len)) \ + if (read_mat5_tag (is, swap, type, len, is_small_data_element)) \ { \ error ("load: reading matrix data for '%s'", retval.c_str ()); \ goto data_read_error; \ @@ -390,14 +391,15 @@ goto data_read_error; \ } \ \ - is.seekg (tmp_pos + static_cast (PAD (len))); \ + is.seekg (tmp_pos + static_cast\ + (READ_PAD (is_small_data_element, len))); \ \ if (imag) \ { \ /* We don't handle imag integer types, convert to an array */ \ NDArray im (dims); \ \ - if (read_mat5_tag (is, swap, type, len)) \ + if (read_mat5_tag (is, swap, type, len, is_small_data_element)) \ { \ error ("load: reading matrix data for '%s'", \ retval.c_str ()); \ @@ -427,10 +429,12 @@ } // Read one element tag from stream IS, -// place the type code in TYPE and the byte count in BYTES +// place the type code in TYPE, the byte count in BYTES and true (false) to +// IS_SMALL_DATA_ELEMENT if the tag is 4 (8) bytes long. // return nonzero on error static int -read_mat5_tag (std::istream& is, bool swap, int32_t& type, int32_t& bytes) +read_mat5_tag (std::istream& is, bool swap, int32_t& type, int32_t& bytes, + bool& is_small_data_element) { unsigned int upper; int32_t temp; @@ -448,6 +452,7 @@ { // "compressed" format bytes = upper; + is_small_data_element = true; } else { @@ -456,6 +461,7 @@ if (swap) swap_bytes<4> (&temp); bytes = temp; + is_small_data_element = false; } return 0; @@ -509,10 +515,11 @@ else flt_fmt = oct_mach_info::flt_fmt_ieee_little_endian; - // element type and length + // element type, length and small data element flag int32_t type = 0; int32_t element_length; - if (read_mat5_tag (is, swap, type, element_length)) + bool is_small_data_element; + if (read_mat5_tag (is, swap, type, element_length, is_small_data_element)) return retval; // EOF if (type == miCOMPRESSED) @@ -623,7 +630,8 @@ // array flags subelement int32_t len; - if (read_mat5_tag (is, swap, type, len) || type != miUINT32 || len != 8) + if (read_mat5_tag (is, swap, type, len, is_small_data_element) || + type != miUINT32 || len != 8 || is_small_data_element) { error ("load: invalid array flags subelement"); goto early_read_error; @@ -649,7 +657,8 @@ { int32_t dim_len; - if (read_mat5_tag (is, swap, type, dim_len) || type != miINT32) + if (read_mat5_tag (is, swap, type, dim_len, is_small_data_element) || + type != miINT32) { error ("load: invalid dimensions array subelement"); goto early_read_error; @@ -665,7 +674,8 @@ } std::streampos tmp_pos = is.tellg (); - is.seekg (tmp_pos + static_cast (PAD (dim_len) - dim_len)); + is.seekg (tmp_pos + static_cast + (READ_PAD (is_small_data_element, dim_len) - dim_len)); } else { @@ -675,7 +685,7 @@ dims(1) = 1; } - if (read_mat5_tag (is, swap, type, len) || !INT8(type)) + if (read_mat5_tag (is, swap, type, len, is_small_data_element) || !INT8(type)) { error ("load: invalid array name subelement"); goto early_read_error; @@ -693,7 +703,8 @@ if (! is.read (name, len )) goto data_read_error; - is.seekg (tmp_pos + static_cast (PAD (len))); + is.seekg (tmp_pos + static_cast + (READ_PAD (is_small_data_element, len))); } name[len] = '\0'; @@ -757,7 +768,7 @@ // row indices std::streampos tmp_pos; - if (read_mat5_tag (is, swap, type, len)) + if (read_mat5_tag (is, swap, type, len, is_small_data_element)) { error ("load: reading sparse row data for '%s'", retval.c_str ()); goto data_read_error; @@ -774,10 +785,11 @@ goto data_read_error; } - is.seekg (tmp_pos + static_cast (PAD (len))); + is.seekg (tmp_pos + static_cast + (READ_PAD (is_small_data_element, len))); // col indices - if (read_mat5_tag (is, swap, type, len)) + if (read_mat5_tag (is, swap, type, len, is_small_data_element)) { error ("load: reading sparse column data for '%s'", retval.c_str ()); goto data_read_error; @@ -794,10 +806,11 @@ goto data_read_error; } - is.seekg (tmp_pos + static_cast (PAD (len))); + is.seekg (tmp_pos + static_cast + (READ_PAD (is_small_data_element, len))); // real data subelement - if (read_mat5_tag (is, swap, type, len)) + if (read_mat5_tag (is, swap, type, len, is_small_data_element)) { error ("load: reading sparse matrix data for '%s'", retval.c_str ()); goto data_read_error; @@ -821,14 +834,15 @@ goto data_read_error; } - is.seekg (tmp_pos + static_cast (PAD (len))); + is.seekg (tmp_pos + static_cast + (READ_PAD (is_small_data_element, len))); // imaginary data subelement if (imag) { NDArray im (dim_vector (static_cast (nnz), 1)); - if (read_mat5_tag (is, swap, type, len)) + if (read_mat5_tag (is, swap, type, len, is_small_data_element)) { error ("load: reading sparse matrix data for '%s'", retval.c_str ()); goto data_read_error; @@ -1060,7 +1074,8 @@ { int32_t fn_type; int32_t fn_len; - if (read_mat5_tag (is, swap, fn_type, fn_len) || !INT8(fn_type)) + if (read_mat5_tag (is, swap, fn_type, fn_len, is_small_data_element) || + !INT8(fn_type)) { error ("load: invalid field name subelement"); goto data_read_error; @@ -1075,8 +1090,8 @@ if (! is.read (elname, fn_len)) goto data_read_error; - is.seekg (tmp_pos + - static_cast (PAD (fn_len))); + is.seekg (tmp_pos + static_cast + (READ_PAD (is_small_data_element, fn_len))); } elname[fn_len] = '\0'; @@ -1121,7 +1136,8 @@ { isclass = true; - if (read_mat5_tag (is, swap, type, len) || !INT8(type)) + if (read_mat5_tag (is, swap, type, len, is_small_data_element) || + !INT8(type)) { error ("load: invalid class name"); goto skip_ahead; @@ -1137,7 +1153,8 @@ if (! is.read (name, len )) goto data_read_error; - is.seekg (tmp_pos + static_cast (PAD (len))); + is.seekg (tmp_pos + static_cast + (READ_PAD (is_small_data_element, len))); } name[len] = '\0'; @@ -1157,7 +1174,8 @@ // be 32. We read and use the actual value, on the theory // that eventually someone will recognize that's a waste of // space. - if (read_mat5_tag (is, swap, fn_type, fn_len) || fn_type != miINT32) + if (read_mat5_tag (is, swap, fn_type, fn_len, is_small_data_element) || + fn_type != miINT32) { error ("load: invalid field name length subelement"); goto data_read_error; @@ -1171,7 +1189,8 @@ // field name subelement. The length of this subelement tells // us how many fields there are. - if (read_mat5_tag (is, swap, fn_type, fn_len) || !INT8(fn_type)) + if (read_mat5_tag (is, swap, fn_type, fn_len, is_small_data_element) || + !INT8(fn_type)) { error ("load: invalid field name subelement"); goto data_read_error; @@ -1181,7 +1200,7 @@ if (n_fields > 0) { - fn_len = PAD (fn_len); + fn_len = READ_PAD (is_small_data_element, fn_len); OCTAVE_LOCAL_BUFFER (char, elname, fn_len); @@ -1320,7 +1339,7 @@ std::streampos tmp_pos; - if (read_mat5_tag (is, swap, type, len)) + if (read_mat5_tag (is, swap, type, len, is_small_data_element)) { error ("load: reading matrix data for '%s'", retval.c_str ()); goto data_read_error; @@ -1337,7 +1356,8 @@ goto data_read_error; } - is.seekg (tmp_pos + static_cast (PAD (len))); + is.seekg (tmp_pos + static_cast + (READ_PAD (is_small_data_element, len))); if (imag) { @@ -1345,7 +1365,7 @@ FloatNDArray im (dims); - if (read_mat5_tag (is, swap, type, len)) + if (read_mat5_tag (is, swap, type, len, is_small_data_element)) { error ("load: reading matrix data for '%s'", retval.c_str ()); goto data_read_error; @@ -1386,7 +1406,7 @@ std::streampos tmp_pos; - if (read_mat5_tag (is, swap, type, len)) + if (read_mat5_tag (is, swap, type, len, is_small_data_element)) { error ("load: reading matrix data for '%s'", retval.c_str ()); goto data_read_error; @@ -1403,7 +1423,8 @@ goto data_read_error; } - is.seekg (tmp_pos + static_cast (PAD (len))); + is.seekg (tmp_pos + static_cast + (READ_PAD (is_small_data_element, len))); if (logicalvar) { @@ -1424,7 +1445,7 @@ NDArray im (dims); - if (read_mat5_tag (is, swap, type, len)) + if (read_mat5_tag (is, swap, type, len, is_small_data_element)) { error ("load: reading matrix data for '%s'", retval.c_str ()); goto data_read_error;