84 #define READ_PAD(is_small_data_element, l) ((is_small_data_element) ? 4 : (((l)+7)/8)*8)
85 #define PAD(l) (((l) > 0 && (l) <= 4) ? 4 : (((l)+7)/8)*8)
86 #define INT8(l) ((l) == miINT8 || (l) == miUINT8 || (l) == miUTF8)
261 #define READ_INTEGER_DATA(TYPE, swap, data, size, len, stream) \
266 OCTAVE_LOCAL_BUFFER (TYPE, ptr, len); \
267 stream.read (reinterpret_cast<char *> (ptr), size * len); \
269 swap_bytes< size > (ptr, len); \
270 for (octave_idx_type i = 0; i < len; i++) \
322 #undef READ_INTEGER_DATA
371 #define OCTAVE_MAT5_INTEGER_READ(TYP) \
375 std::streampos tmp_pos; \
377 if (read_mat5_tag (is, swap, type, len, is_small_data_element)) \
379 error ("load: reading matrix data for '%s'", retval.c_str ()); \
380 goto data_read_error; \
383 octave_idx_type n = re.numel (); \
384 tmp_pos = is.tellg (); \
385 read_mat5_integer_data (is, re.fortran_vec (), n, swap, \
386 static_cast<enum mat5_data_type> (type)); \
388 if (! is || error_state) \
390 error ("load: reading matrix data for '%s'", retval.c_str ()); \
391 goto data_read_error; \
394 is.seekg (tmp_pos + static_cast<std::streamoff>\
395 (READ_PAD (is_small_data_element, len))); \
402 if (read_mat5_tag (is, swap, type, len, is_small_data_element)) \
404 error ("load: reading matrix data for '%s'", \
406 goto data_read_error; \
410 read_mat5_binary_data (is, im.fortran_vec (), n, swap, \
411 static_cast<enum mat5_data_type> (type), flt_fmt); \
413 if (! is || error_state) \
415 error ("load: reading imaginary matrix data for '%s'", \
417 goto data_read_error; \
420 ComplexNDArray ctmp (dims); \
422 for (octave_idx_type i = 0; i < n; i++) \
423 ctmp(i) = Complex (re(i).double_value (), im(i)); \
437 bool& is_small_data_element)
442 if (! is.read (reinterpret_cast<char *> (&temp), 4 ))
443 goto data_read_error;
448 upper = (temp >> 16) & 0xffff;
449 type = temp & 0xffff;
455 is_small_data_element =
true;
459 if (! is.read (reinterpret_cast<char *> (&temp), 4 ))
460 goto data_read_error;
464 is_small_data_element =
false;
474 read_int (std::istream& is,
bool swap, int32_t& val)
476 is.read (reinterpret_cast<char *> (&val), 4);
503 bool isclass =
false;
507 int16_t number = *(
reinterpret_cast<const int16_t *
>(
"\x00\x01"));
509 std::string classname;
513 if ((number == 1) ^ swap)
520 int32_t element_length;
521 bool is_small_data_element;
522 if (
read_mat5_tag (is, swap, type, element_length, is_small_data_element))
534 is.read (inbuf, element_length);
540 if (uncompress (reinterpret_cast<Bytef *> (tmp), &destLen,
541 reinterpret_cast<Bytef *> (inbuf), element_length)
548 destLen = tmp[1] + 8;
549 std::string outbuf (destLen,
' ');
553 int err = uncompress (reinterpret_cast<Bytef *>
554 (const_cast<char *> (outbuf.c_str ())),
555 &destLen,
reinterpret_cast<Bytef *
> (inbuf),
576 msg =
"stream error";
591 case Z_VERSION_ERROR:
592 msg =
"version error";
596 error (
"load: error uncompressing data element (%s from zlib)",
601 std::istringstream gz_is (outbuf);
607 error (
"load: error probing size of compressed data element");
611 error (
"load: zlib unavailable, cannot read compressed data element");
620 error (
"load: invalid element type = %d", type);
621 goto early_read_error;
624 if (element_length == 0)
634 if (
read_mat5_tag (is, swap, type, len, is_small_data_element) ||
635 type !=
miUINT32 || len != 8 || is_small_data_element)
637 error (
"load: invalid array flags subelement");
638 goto early_read_error;
644 imag = (flags & 0x0800) != 0;
646 global = (flags & 0x0400) != 0;
648 logicalvar = (flags & 0x0200) != 0;
661 if (
read_mat5_tag (is, swap, type, dim_len, is_small_data_element) ||
664 error (
"load: invalid dimensions array subelement");
665 goto early_read_error;
668 int ndims = dim_len / 4;
670 for (
int i = 0; i < ndims; i++)
677 std::streampos tmp_pos = is.tellg ();
678 is.seekg (tmp_pos + static_cast<std::streamoff>
679 (
READ_PAD (is_small_data_element, dim_len) - dim_len));
691 error (
"load: invalid array name subelement");
692 goto early_read_error;
700 std::streampos tmp_pos = is.tellg ();
704 if (! is.read (name, len ))
705 goto data_read_error;
707 is.seekg (tmp_pos + static_cast<std::streamoff>
708 (
READ_PAD (is_small_data_element, len)));
719 Cell cell_array (dims);
732 error (
"load: reading cell data for '%s'", nm.c_str ());
733 goto data_read_error;
770 std::streampos tmp_pos;
772 if (
read_mat5_tag (is, swap, type, len, is_small_data_element))
774 error (
"load: reading sparse row data for '%s'", retval.c_str ());
775 goto data_read_error;
778 tmp_pos = is.tellg ();
781 static_cast<enum mat5_data_type> (type));
785 error (
"load: reading sparse row data for '%s'", retval.c_str ());
786 goto data_read_error;
789 is.seekg (tmp_pos + static_cast<std::streamoff>
790 (
READ_PAD (is_small_data_element, len)));
793 if (
read_mat5_tag (is, swap, type, len, is_small_data_element))
795 error (
"load: reading sparse column data for '%s'",
797 goto data_read_error;
800 tmp_pos = is.tellg ();
803 static_cast<enum mat5_data_type> (type));
807 error (
"load: reading sparse column data for '%s'",
809 goto data_read_error;
812 is.seekg (tmp_pos + static_cast<std::streamoff>
813 (
READ_PAD (is_small_data_element, len)));
816 if (
read_mat5_tag (is, swap, type, len, is_small_data_element))
818 error (
"load: reading sparse matrix data for '%s'",
820 goto data_read_error;
831 tmp_pos = is.tellg ();
833 static_cast<enum mat5_data_type> (type),
838 error (
"load: reading sparse matrix data for '%s'",
840 goto data_read_error;
843 is.seekg (tmp_pos + static_cast<std::streamoff>
844 (
READ_PAD (is_small_data_element, len)));
851 if (
read_mat5_tag (is, swap, type, len, is_small_data_element))
853 error (
"load: reading sparse matrix data for '%s'",
855 goto data_read_error;
864 error (
"load: reading imaginary sparse matrix data for '%s'",
866 goto data_read_error;
886 goto data_read_error;
898 if (ftype ==
"simple" || ftype ==
"scopedfunction")
900 if (fpath.length () == 0)
908 if ((fpath.length () >= mroot.length ()) &&
909 fpath.substr (0, mroot.length ()) == mroot &&
921 fpath.substr (mroot.length ());
929 std::string dir_name = str.substr (0, xpos);
946 names(0) = fname +
".oct";
947 names(1) = fname +
".mex";
948 names(2) = fname +
".m";
958 std::string dir_name = str.substr (0, xpos);
972 warning (
"load: can't find the file %s",
983 std::string dir_name = fpath.substr (0, xpos);
996 warning (
"load: can't find the file %s",
1003 else if (ftype ==
"nested")
1005 warning (
"load: can't load nested function");
1008 else if (ftype ==
"anonymous")
1038 p0 != m2.
end (); p0++)
1040 std::string key = m2.
key (p0);
1049 eval_string (fname.substr (4),
true, parse_status);
1051 if (parse_status == 0)
1060 error (
"load: failed to load anonymous function handle");
1066 error (
"load: failed to load anonymous function handle");
1074 error (
"load: invalid function handle type");
1086 for (
int i = 0; i < n_fields; i++)
1090 if (
read_mat5_tag (is, swap, fn_type, fn_len, is_small_data_element)
1093 error (
"load: invalid field name subelement");
1094 goto data_read_error;
1099 std::streampos tmp_pos = is.tellg ();
1103 if (! is.read (elname, fn_len))
1104 goto data_read_error;
1106 is.seekg (tmp_pos + static_cast<std::streamoff>
1107 (
READ_PAD (is_small_data_element, fn_len)));
1110 elname[fn_len] =
'\0';
1115 std::vector<Cell> elt (n_fields);
1118 elt[i] =
Cell (dims);
1127 if (field(i) ==
"MCOS")
1133 goto data_read_error;
1135 elt[i](j) = fieldtc;
1143 m.
assign (field (i), elt[i]);
1152 if (
read_mat5_tag (is, swap, type, len, is_small_data_element) ||
1155 error (
"load: invalid class name");
1162 std::streampos tmp_pos = is.tellg ();
1166 if (! is.read (name, len ))
1167 goto data_read_error;
1169 is.seekg (tmp_pos + static_cast<std::streamoff>
1170 (
READ_PAD (is_small_data_element, len)));
1183 int32_t field_name_length;
1189 if (
read_mat5_tag (is, swap, fn_type, fn_len, is_small_data_element)
1192 error (
"load: invalid field name length subelement");
1193 goto data_read_error;
1196 if (! is.read (reinterpret_cast<char *> (&field_name_length), fn_len ))
1197 goto data_read_error;
1204 if (
read_mat5_tag (is, swap, fn_type, fn_len, is_small_data_element)
1207 error (
"load: invalid field name subelement");
1208 goto data_read_error;
1215 fn_len =
READ_PAD (is_small_data_element, fn_len);
1219 if (! is.read (elname, fn_len))
1220 goto data_read_error;
1222 std::vector<Cell> elt (n_fields);
1225 elt[i] =
Cell (dims);
1237 elt[i](j) = fieldtc;
1243 const char *key = elname + i*field_name_length;
1251 if (classname ==
"inline")
1257 m.
contents (
"args")(0).string_value ());
1263 std::list<std::string> ());
1269 warning (
"load: unable to reconstruct object inheritance");
1280 goto data_read_error;
1286 warning (
"load: element has been converted to a structure");
1314 out(i) = in(i).bool_value ();
1352 std::streampos tmp_pos;
1354 if (
read_mat5_tag (is, swap, type, len, is_small_data_element))
1356 error (
"load: reading matrix data for '%s'", retval.c_str ());
1357 goto data_read_error;
1361 tmp_pos = is.tellg ();
1368 error (
"load: reading matrix data for '%s'", retval.c_str ());
1369 goto data_read_error;
1372 is.seekg (tmp_pos + static_cast<std::streamoff>
1373 (
READ_PAD (is_small_data_element, len)));
1381 if (
read_mat5_tag (is, swap, type, len, is_small_data_element))
1383 error (
"load: reading matrix data for '%s'", retval.c_str ());
1384 goto data_read_error;
1394 error (
"load: reading imaginary matrix data for '%s'",
1396 goto data_read_error;
1421 std::streampos tmp_pos;
1423 if (
read_mat5_tag (is, swap, type, len, is_small_data_element))
1425 error (
"load: reading matrix data for '%s'", retval.c_str ());
1426 goto data_read_error;
1430 tmp_pos = is.tellg ();
1437 error (
"load: reading matrix data for '%s'", retval.c_str ());
1438 goto data_read_error;
1441 is.seekg (tmp_pos + static_cast<std::streamoff>
1442 (
READ_PAD (is_small_data_element, len)));
1453 out (i) =
static_cast<bool> (re (i));
1463 if (
read_mat5_tag (is, swap, type, len, is_small_data_element))
1465 error (
"load: reading matrix data for '%s'", retval.c_str ());
1466 goto data_read_error;
1476 error (
"load: reading imaginary matrix data for '%s'",
1478 goto data_read_error;
1484 ctmp(i) =
Complex (re(i), im(i));
1494 bool found_big_char =
false;
1500 found_big_char =
true;
1505 warning (
"load: can not read non-ASCII portions of UTF characters; replacing unreadable characters with '?'");
1512 bool utf8_multi_byte =
false;
1515 unsigned char a =
static_cast<unsigned char> (re(i));
1517 utf8_multi_byte =
true;
1520 if (utf8_multi_byte)
1522 warning (
"load: can not read multi-byte encoded UTF8 characters; replacing unreadable characters with '?'");
1526 =
static_cast<unsigned char> (re(i));
1541 is.seekg (pos + static_cast<std::streamoff> (element_length));
1550 error (
"load: trouble reading binary file '%s'", filename.c_str ());
1551 return std::string ();
1554 warning (
"skipping over '%s'", retval.c_str ());
1555 is.seekg (pos + static_cast<std::streamoff> (element_length));
1561 const std::string& filename)
1563 int16_t version=0, magic=0;
1564 uint64_t subsys_offset;
1566 is.seekg (116, std::ios::beg);
1567 is.read (reinterpret_cast<char *> (&subsys_offset), 8);
1569 is.seekg (124, std::ios::beg);
1570 is.read (reinterpret_cast<char *> (&version), 2);
1571 is.read (reinterpret_cast<char *> (&magic), 2);
1573 if (magic == 0x4d49)
1575 else if (magic == 0x494d)
1580 error (
"load: can't read binary file");
1585 version = ((version >> 8) & 0xff) + ((version & 0xff) << 8);
1587 if (version != 1 && !quiet)
1588 warning (
"load: found version %d binary MAT file, "
1589 "but only prepared for version 1", version);
1594 if (subsys_offset != 0x2020202020202020ULL && subsys_offset != 0ULL)
1597 is.seekg (subsys_offset, std::ios::beg);
1612 std::string outbuf (ilen - 7,
' ');
1615 char *ctmp =
const_cast<char *
> (outbuf.c_str ());
1617 ctmp[j-8] = itmp(j).char_value ();
1619 std::istringstream fh_ws (outbuf);
1630 is.seekg (128, std::ios::beg);
1641 if (bytes > 0 && bytes <= 4)
1642 temp = (bytes << 16) + type;
1646 if (! is.write (reinterpret_cast<char *> (&temp), 4))
1647 goto data_write_error;
1651 if (! is.write (reinterpret_cast<char *> (&temp), 4))
1652 goto data_write_error;
1663 #define MAT5_DO_WRITE(TYPE, data, count, stream) \
1666 OCTAVE_LOCAL_BUFFER (TYPE, ptr, count); \
1667 for (octave_idx_type i = 0; i < count; i++) \
1668 ptr[i] = static_cast<TYPE> (data[i]); \
1669 stream.write (reinterpret_cast<char *> (ptr), count * sizeof (TYPE)); \
1679 const double *data = m.
data ();
1685 warning (
"save: some values too large to save as floats --");
1686 warning (
"save: saving as doubles instead");
1692 double max_val, min_val;
1756 os.write (reinterpret_cast<const char *> (data), len);
1760 (*current_liboctave_error_handler)
1761 (
"unrecognized data format requested");
1765 if (
PAD (len) > len)
1767 static char buf[9]=
"\x00\x00\x00\x00\x00\x00\x00\x00";
1768 os.write (buf,
PAD (len) - len);
1776 const float *data = m.
data ();
1778 float max_val, min_val;
1838 os.write (reinterpret_cast<const char *> (data), len);
1846 (*current_liboctave_error_handler)
1847 (
"unrecognized data format requested");
1851 if (
PAD (len) > len)
1853 static char buf[9]=
"\x00\x00\x00\x00\x00\x00\x00\x00";
1854 os.write (buf,
PAD (len) - len);
1902 os.write (reinterpret_cast<const char *> (m), len);
1904 if (
PAD (len) > len)
1906 static char buf[9]=
"\x00\x00\x00\x00\x00\x00\x00\x00";
1907 os.write (buf,
PAD (len) - len);
1952 bool mark_as_global,
bool save_as_floats)
1961 false, save_as_floats))
1970 bool save_as_floats)
1978 bool too_large_for_float =
false;
1981 double tmp = val[i];
1986 too_large_for_float =
true;
1991 if (!too_large_for_float)
2036 return 8 + nel *
size;
2093 return PAD ((nel > 0 && nel * size <= 4 ? 4 : 8) + nel * size);
2101 bool save_as_floats)
2122 bool save_as_floats)
2143 bool save_as_floats,
bool mat7_format)
2145 size_t max_namelen = 63;
2146 size_t len = name.length ();
2151 ret +=
PAD (len > max_namelen ? max_namelen : len);
2159 if (chm.
numel () > 2)
2172 ret +=
PAD (nnz *
sizeof (int32_t));
2174 ret +=
PAD ((nc + 1) *
sizeof (int32_t));
2184 ret +=
PAD (nnz *
sizeof (int32_t));
2186 ret +=
PAD ((nc + 1) *
sizeof (int32_t));
2190 #define INT_LEN(nel, size) \
2193 octave_idx_type sz = nel * size; \
2198 else if (cname ==
"int8")
2200 else if (cname ==
"int16")
2202 else if (cname ==
"int32")
2204 else if (cname ==
"int64")
2206 else if (cname ==
"uint8")
2208 else if (cname ==
"uint16")
2210 else if (cname ==
"uint32")
2212 else if (cname ==
"uint64")
2236 for (
int i = 0; i < nel; i++)
2263 ret += 8 +
PAD (6 > max_namelen ? max_namelen : 6);
2268 ret += 8 +
PAD (classlen > max_namelen ? max_namelen : classlen);
2274 ret += 16 + fieldcnt * (max_namelen + 1);
2285 save_as_floats, mat7_format);
2300 int tmp =
sizeof (int32_t);
2305 tmp_idx[i] = idx[i];
2313 warning (
"save: skipping %s: dimension too large for MAT format",
2323 bool mark_as_global,
bool mat7_format,
2324 bool save_as_floats,
bool compressing)
2329 size_t max_namelen = 63;
2332 int nd = tc.
ndims ();
2337 for (
int i = 0; i < nd; i++)
2339 if (dv(i) > max_dim_val)
2364 if (nnz > max_dim_val || nc + 1 > max_dim_val)
2372 else if (dv.
numel () > max_dim_val)
2379 if (mat7_format && !compressing)
2383 std::ostringstream buf;
2388 save_as_floats,
true);
2394 std::string buf_str = buf.str ();
2395 uLongf srcLen = buf_str.length ();
2396 uLongf destLen = srcLen * 101 / 100 + 12;
2399 if (compress (reinterpret_cast<Bytef *> (out_buf), &destLen,
2400 reinterpret_cast<const Bytef *> (buf_str.c_str ()),
2405 static_cast<octave_idx_type> (destLen));
2407 os.write (out_buf, destLen);
2411 error (
"save: error compressing data element");
2421 (tc, name, save_as_floats, mat7_format));
2437 else if (cname ==
"int8")
2439 else if (cname ==
"int16")
2441 else if (cname ==
"int32")
2443 else if (cname ==
"int64")
2447 else if (cname ==
"uint16")
2449 else if (cname ==
"uint32")
2451 else if (cname ==
"uint64")
2475 os.write (reinterpret_cast<char *> (&flags), 4);
2480 os.write (reinterpret_cast<char *> (&nnz_32), 4);
2484 for (
int i = 0; i < nd; i++)
2487 os.write (reinterpret_cast<char *> (&n), 4);
2490 if (
PAD (dim_len) > dim_len)
2492 static char buf[9]=
"\x00\x00\x00\x00\x00\x00\x00\x00";
2493 os.write (buf,
PAD (dim_len) - dim_len);
2498 size_t namelen = name.length ();
2500 if (namelen > max_namelen)
2501 namelen = max_namelen;
2503 int paddedlength =
PAD (namelen);
2507 memset (paddedname, 0, paddedlength);
2508 strncpy (paddedname, name.c_str (), namelen);
2509 os.write (paddedname, paddedlength);
2523 const char *s = chm.
data ();
2526 buf[i] = *s++ & 0x00FF;
2528 os.write (reinterpret_cast<char *> (buf), len);
2530 if (paddedlength > len)
2532 static char padbuf[9]=
"\x00\x00\x00\x00\x00\x00\x00\x00";
2533 os.write (padbuf, paddedlength - len);
2572 for (
int i = 0; i < nnz; i++)
2573 buf (i) = m.
data (i);
2578 else if (cname ==
"int8")
2584 else if (cname ==
"int16")
2590 else if (cname ==
"int32")
2596 else if (cname ==
"int64")
2602 else if (cname ==
"uint8")
2608 else if (cname ==
"uint16")
2614 else if (cname ==
"uint32")
2620 else if (cname ==
"uint64")
2676 size_t namelen = classname.length ();
2678 if (namelen > max_namelen)
2679 namelen = max_namelen;
2681 int paddedlength =
PAD (namelen);
2685 memset (paddedname, 0, paddedlength);
2686 strncpy (paddedname, classname.c_str (), namelen);
2687 os.write (paddedname, paddedlength);
2694 "saveobj") != std::string ())
2698 m = tmp(0).map_value ();
2709 int32_t maxfieldnamelength = max_namelen + 1;
2714 os.write (reinterpret_cast<char *> (&maxfieldnamelength), 4);
2723 std::string key = keys(i);
2726 memset (buf, 0, max_namelen + 1);
2728 strncpy (buf, key.c_str (), max_namelen);
2729 os.write (buf, max_namelen + 1);
2736 std::vector<const octave_value *> elts (nf);
2765 error (
"save: error while writing '%s' to MAT file", name.c_str ());