26#if defined (HAVE_CONFIG_H)
85#if defined (HAVE_ZLIB)
89#define READ_PAD(is_small_data_element, l) ((is_small_data_element) ? 4 : (((l)+7)/8)*8)
90#define PAD(l) (((l) > 0 && (l) <= 4) ? 4 : (((l)+7)/8)*8)
91#define INT8(l) ((l) == miINT8 || (l) == miUINT8 || (l) == miUTF8)
127read_mat5_binary_data (std::istream& is,
double *data,
129 octave::mach_info::float_format flt_fmt)
192read_mat5_binary_data (std::istream& is,
float *data,
194 octave::mach_info::float_format flt_fmt)
262#define READ_INTEGER_DATA(TYPE, swap, data, size, len, stream) \
267 OCTAVE_LOCAL_BUFFER (TYPE, ptr, len); \
268 std::streamsize n_bytes = size * static_cast<std::streamsize> (len); \
269 stream.read (reinterpret_cast<char *> (ptr), n_bytes); \
271 swap_bytes< size > (ptr, len); \
272 for (octave_idx_type i = 0; i < len; i++) \
324#undef READ_INTEGER_DATA
373#define OCTAVE_MAT5_INTEGER_READ(TYP) \
377 std::streampos tmp_pos; \
379 if (read_mat5_tag (is, swap, type, len, is_small_data_element)) \
380 error ("load: reading matrix data for '%s'", retval.c_str ()); \
382 octave_idx_type n = re.numel (); \
383 tmp_pos = is.tellg (); \
384 read_mat5_integer_data (is, re.rwdata (), n, swap, \
385 static_cast<enum mat5_data_type> (type)); \
388 error ("load: reading matrix data for '%s'", retval.c_str ()); \
390 is.seekg (tmp_pos + static_cast<std::streamoff> \
391 (READ_PAD (is_small_data_element, len))); \
398 if (read_mat5_tag (is, swap, type, len, is_small_data_element)) \
399 error ("load: reading matrix data for '%s'", \
403 read_mat5_binary_data (is, im.rwdata (), n, swap, \
404 static_cast<enum mat5_data_type> (type), flt_fmt); \
407 error ("load: reading imaginary matrix data for '%s'", \
410 ComplexNDArray ctmp (dims); \
412 for (octave_idx_type i = 0; i < n; i++) \
413 ctmp(i) = Complex (re(i).double_value (), im(i)); \
426read_mat5_tag (std::istream& is,
bool swap, int32_t& type, int32_t& bytes,
427 bool& is_small_data_element)
432 if (! is.read (
reinterpret_cast<char *
> (&temp), 4))
438 upper = (temp >> 16) & 0xffff;
439 type = temp & 0xffff;
445 is_small_data_element =
true;
449 if (! is.read (
reinterpret_cast<char *
> (&temp), 4))
454 is_small_data_element =
false;
461read_int (std::istream& is,
bool swap, int32_t& val)
463 is.read (
reinterpret_cast<char *
> (&val), 4);
490 bool isclass =
false;
495 std::string classname;
497 bool flt_fmt_is_big_endian
498 = (octave::mach_info::native_float_format ()
499 == octave::mach_info::flt_fmt_ieee_big_endian);
502 octave::mach_info::float_format flt_fmt = octave::mach_info::flt_fmt_unknown;
503 if ((flt_fmt_is_big_endian && ! swap) || (! flt_fmt_is_big_endian && swap))
504 flt_fmt = octave::mach_info::flt_fmt_ieee_big_endian;
506 flt_fmt = octave::mach_info::flt_fmt_ieee_little_endian;
510 int32_t element_length;
511 bool is_small_data_element;
512 if (read_mat5_tag (is, swap, type, element_length, is_small_data_element))
515 octave::interpreter& interp = octave::__get_interpreter__ ();
519#if defined (HAVE_ZLIB)
526 is.read (inbuf, element_length);
531 uLongf elt_len = element_length;
533 if (uncompress2 (
reinterpret_cast<Bytef *
> (tmp), &destLen,
534 reinterpret_cast<Bytef *
> (inbuf), &elt_len)
536 error (
"load: error probing size of compressed data element");
542 destLen = tmp[1] + 8;
543 std::string outbuf (destLen,
' ');
547 elt_len = element_length;
548 int err = uncompress2 (
reinterpret_cast<Bytef *
>
549 (
const_cast<char *
> (outbuf.c_str ())),
550 &destLen,
reinterpret_cast<Bytef *
> (inbuf),
557 if (err == Z_BUF_ERROR && destLen == tmp[1] + 8
558 && elt_len ==
static_cast<uLongf
> (element_length))
579 msg =
"stream error";
594 case Z_VERSION_ERROR:
595 msg =
"version error";
599 error (
"load: error uncompressing data element (%s from zlib)",
604 std::istringstream gz_is (outbuf);
621 error (
"load: invalid element type = %d", type);
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)
636 error (
"load: invalid array flags subelement");
641 imag = (flags & 0x0800) != 0;
643 global = (flags & 0x0400) != 0;
645 logicalvar = (flags & 0x0200) != 0;
658 if (read_mat5_tag (is, swap, type, dim_len, is_small_data_element)
660 error (
"load: invalid dimensions array subelement");
662 int ndims = dim_len / 4;
672 for (
int i = 0; i < ndims; i++)
679 std::streampos tmp_pos = is.tellg ();
680 is.seekg (tmp_pos +
static_cast<std::streamoff
>
681 (
READ_PAD (is_small_data_element, dim_len) - dim_len));
684 if (read_mat5_tag (is, swap, type,
len, is_small_data_element)
686 error (
"load: invalid array name subelement");
693 std::streampos tmp_pos = is.tellg ();
697 if (! is.read (name,
len))
698 goto data_read_error;
700 is.seekg (tmp_pos +
static_cast<std::streamoff
>
712 Cell cell_array (dims);
724 error (
"load: reading cell data for '%s'", nm.c_str ());
760 std::streampos tmp_pos;
762 if (read_mat5_tag (is, swap, type,
len, is_small_data_element))
763 error (
"load: reading sparse row data for '%s'", retval.c_str ());
765 tmp_pos = is.tellg ();
771 error (
"load: reading sparse row data for '%s'", retval.c_str ());
773 is.seekg (tmp_pos +
static_cast<std::streamoff
>
777 if (read_mat5_tag (is, swap, type,
len, is_small_data_element))
778 error (
"load: reading sparse column data for '%s'",
781 tmp_pos = is.tellg ();
787 error (
"load: reading sparse column data for '%s'",
790 is.seekg (tmp_pos +
static_cast<std::streamoff
>
794 if (read_mat5_tag (is, swap, type,
len, is_small_data_element))
795 error (
"load: reading sparse matrix data for '%s'",
806 tmp_pos = is.tellg ();
807 read_mat5_binary_data (is, data, nnz, swap,
812 error (
"load: reading sparse matrix data for '%s'",
815 is.seekg (tmp_pos +
static_cast<std::streamoff
>
823 if (read_mat5_tag (is, swap, type,
len, is_small_data_element))
824 error (
"load: reading sparse matrix data for '%s'",
827 read_mat5_binary_data (is, im.
rwdata (), nnz, swap,
832 error (
"load: reading imaginary sparse matrix data for '%s'",
852 goto data_read_error;
864 if (ftype ==
"simple" || ftype ==
"scopedfunction")
868 octave::tree_evaluator& tw = interp.get_evaluator ();
872 tc = tw.make_fcn_handle (fname);
878 if ((fpath.length () >= mroot.length ())
879 && fpath.substr (0, mroot.length ()) == mroot
880 && octave::config::octave_exec_home () != mroot)
891 = (octave::config::octave_exec_home ()
892 + fpath.substr (mroot.length ()));
894 if (octave::sys::file_exists (str))
897 = str.find_last_of (octave::sys::file_ops::dir_sep_chars ());
899 std::string dir_name = str.substr (0, xpos);
902 = octave::load_fcn_from_file (str, dir_name,
913 std::list<std::string> names;
914 names.push_back (fname +
".oct");
915 names.push_back (fname +
".mex");
916 names.push_back (fname +
".m");
918 octave::load_path& lp = interp.get_load_path ();
920 octave::directory_path p (lp.system_path ());
922 str = octave::sys::env::make_absolute (p.find_first_of (names));
925 = str.find_last_of (octave::sys::file_ops::dir_sep_chars ());
927 std::string dir_name = str.substr (0, xpos);
930 = octave::load_fcn_from_file (str, dir_name,
940 "load: can't find the file %s",
949 = fpath.find_last_of (octave::sys::file_ops::dir_sep_chars ());
951 std::string dir_name = fpath.substr (0, xpos);
954 = octave::load_fcn_from_file (fpath, dir_name,
963 "load: can't find the file %s",
970 else if (ftype ==
"nested")
973 "load: can't load nested function");
976 else if (ftype ==
"anonymous")
981 octave::stack_frame::local_vars_map local_vars;
989 for (
auto p0 = m2.
begin (); p0 != m2.
end (); p0++)
991 std::string key = m2.
key (p0);
994 local_vars[key] = val;
1004 octave::tree_evaluator& tw = interp.get_evaluator ();
1005 tw.push_dummy_scope (
"read_mat5_binary_element");
1007 octave::unwind_action act ([&tw] () { tw.pop_scope (); });
1018 = interp.eval_string (fname.substr (4),
true, parse_status);
1020 if (parse_status != 0)
1021 error (
"load: failed to load anonymous function handle");
1026 error (
"load: failed to load anonymous function handle");
1033 error (
"load: invalid function handle type");
1040 std::string type_system;
1041 if (read_mat5_tag (is, swap, type,
len, is_small_data_element)
1043 error (
"load: invalid type system");
1049 std::streampos tmp_pos = is.tellg ();
1053 if (! is.read (name,
len))
1054 goto data_read_error;
1056 is.seekg (tmp_pos +
static_cast<std::streamoff
>
1065 if (read_mat5_tag (is, swap, type,
len, is_small_data_element)
1067 error (
"load: invalid class name");
1073 std::streampos tmp_pos = is.tellg ();
1077 if (! is.read (name,
len))
1078 goto data_read_error;
1080 is.seekg (tmp_pos +
static_cast<std::streamoff
>
1091 goto data_read_error;
1093 if (type_system !=
"MCOS")
1099 "load: MATLAB class object with type system '%s' "
1100 "not supported. Loading as %s",
1101 type_system.c_str (),
1105 else if (classname ==
"FileWrapper__")
1116 "load: MATLAB enumeration classes are not "
1117 "supported. Loading as %s",
1126 tc = octave::load_mcos_object (objmetadata,
1127 classname ==
"function_handle_workspace");
1137 if (read_mat5_tag (is, swap, type,
len, is_small_data_element)
1139 error (
"load: invalid class name");
1144 std::streampos tmp_pos = is.tellg ();
1148 if (! is.read (name,
len))
1149 goto data_read_error;
1151 is.seekg (tmp_pos +
static_cast<std::streamoff
>
1166 int32_t field_name_length;
1172 if (read_mat5_tag (is, swap, fn_type, fn_len, is_small_data_element)
1174 error (
"load: invalid field name length subelement");
1176 if (! is.read (
reinterpret_cast<char *
> (&field_name_length), fn_len))
1177 goto data_read_error;
1184 if (read_mat5_tag (is, swap, fn_type, fn_len, is_small_data_element)
1185 || !
INT8 (fn_type))
1186 error (
"load: invalid field name subelement");
1192 fn_len =
READ_PAD (is_small_data_element, fn_len);
1196 if (! is.read (elname, fn_len))
1197 goto data_read_error;
1199 std::vector<Cell> elt (n_fields);
1202 elt[i] =
Cell (dims);
1214 elt[i](j) = fieldtc;
1220 const char *key = elname + i*field_name_length;
1228 octave::cdef_manager& cdm = interp.get_cdef_manager ();
1230 if (cdm.find_class (classname,
false,
true).ok ())
1234 "load: classdef element has been converted to a struct");
1240 std::list<std::string> ());
1247 "load: unable to reconstruct object inheritance");
1251 octave::load_path& lp = interp.get_load_path ();
1253 if (lp.find_method (classname,
"loadobj") !=
"")
1261 catch (
const octave::execution_exception&)
1263 goto data_read_error;
1271 "load: element has been converted to a structure");
1299 out(i) = in(i).bool_value ();
1336 std::streampos tmp_pos;
1338 if (read_mat5_tag (is, swap, type,
len, is_small_data_element))
1339 error (
"load: reading matrix data for '%s'", retval.c_str ());
1342 tmp_pos = is.tellg ();
1343 read_mat5_binary_data (is, re.
rwdata (), n, swap,
1348 error (
"load: reading matrix data for '%s'", retval.c_str ());
1350 is.seekg (tmp_pos +
static_cast<std::streamoff
>
1359 if (read_mat5_tag (is, swap, type,
len, is_small_data_element))
1360 error (
"load: reading matrix data for '%s'", retval.c_str ());
1363 read_mat5_binary_data (is, im.
rwdata (), n, swap,
1368 error (
"load: reading imaginary matrix data for '%s'",
1393 std::streampos tmp_pos;
1395 if (read_mat5_tag (is, swap, type,
len, is_small_data_element))
1396 error (
"load: reading matrix data for '%s'", retval.c_str ());
1399 tmp_pos = is.tellg ();
1400 read_mat5_binary_data (is, re.
rwdata (), n, swap,
1405 error (
"load: reading matrix data for '%s'", retval.c_str ());
1407 is.seekg (tmp_pos +
static_cast<std::streamoff
>
1419 out (i) =
static_cast<bool> (re (i));
1429 if (read_mat5_tag (is, swap, type,
len, is_small_data_element))
1430 error (
"load: reading matrix data for '%s'", retval.c_str ());
1433 read_mat5_binary_data (is, im.
rwdata (), n, swap,
1438 error (
"load: reading imaginary matrix data for '%s'",
1444 ctmp(i) =
Complex (re(i), im(i));
1450 bool converted =
false;
1454 const uint16_t *u16_str
1455 =
reinterpret_cast<const uint16_t *
> (u16.
data ());
1466 tc =
charMatrix (std::string (
reinterpret_cast<char *
> (u8_str), n8));
1474 const uint32_t *u32_str
1475 =
reinterpret_cast<const uint32_t *
> (u32.
data ());
1486 tc =
charMatrix (std::string (
reinterpret_cast<char *
> (u8_str), n8));
1504 bool found_big_char =
false;
1510 found_big_char =
true;
1516 "load: failed to convert from input to UTF-8; "
1517 "replacing non-ASCII characters with '?'");
1529 is.seekg (pos +
static_cast<std::streamoff
> (element_length));
1538 error (
"load: trouble reading binary file '%s'", filename.c_str ());
1542 "load: skipping over '%s'", retval.c_str ());
1543 is.seekg (pos +
static_cast<std::streamoff
> (element_length));
1549 const std::string& filename)
1551 int16_t version = 0;
1553 uint64_t subsys_offset;
1555 is.seekg (116, std::ios::beg);
1556 is.read (
reinterpret_cast<char *
> (&subsys_offset), 8);
1558 is.seekg (124, std::ios::beg);
1559 is.read (
reinterpret_cast<char *
> (&version), 2);
1560 is.read (
reinterpret_cast<char *
> (&magic), 2);
1562 if (magic == 0x4d49)
1564 else if (magic == 0x494d)
1569 error (
"load: can't read binary file");
1575 version = ((version >> 8) & 0xff) + ((version & 0xff) << 8);
1577 if (version != 1 && ! quiet)
1579 "load: found version %d binary MAT file, but only prepared for version 1",
1585 if (subsys_offset != UINT64_C (0x2020202020202020)
1586 && subsys_offset != UINT64_C (0))
1589 is.seekg (subsys_offset, std::ios::beg);
1604 std::string outbuf (ilen - 7,
' ');
1607 char *ctmp =
const_cast<char *
> (outbuf.c_str ());
1609 ctmp[j-8] = itmp(j).char_value ();
1611 std::istringstream fh_ws (outbuf);
1615 octave::subsystem_handler *sh = octave::__get_load_save_system__ ().get_subsystem_handler ();
1616 if (! sh->read_mat_subsystem (subsys_ov, swap))
1617 error (
"load: unable to read subsystem data from MAT-file '%s'", filename.c_str ());
1626 is.seekg (128, std::ios::beg);
1637 if (bytes > 0 && bytes <= 4)
1638 temp = (bytes << 16) + type;
1642 if (! is.write (
reinterpret_cast<char *
> (&temp), 4))
1647 if (! is.write (
reinterpret_cast<char *
> (&temp), 4))
1656#define MAT5_DO_WRITE(TYPE, data, count, stream) \
1659 OCTAVE_LOCAL_BUFFER (TYPE, ptr, count); \
1660 for (octave_idx_type i = 0; i < count; i++) \
1661 ptr[i] = static_cast<TYPE> (data[i]); \
1662 std::streamsize n_bytes = sizeof (TYPE) * static_cast<std::streamsize> (count); \
1663 stream.write (reinterpret_cast<char *> (ptr), n_bytes); \
1670write_mat5_array (std::ostream& os,
const NDArray& m,
bool save_as_floats)
1673 const double *data = m.
data ();
1680 "save: some values too large to save as floats -- saving as doubles instead");
1686 double max_val, min_val;
1688 st = octave::get_save_type (max_val, min_val);
1708 write_mat5_tag (os, mst,
len);
1750 os.write (
reinterpret_cast<const char *
> (data),
len);
1754 error (
"unrecognized data format requested");
1760 static char buf[9]=
"\x00\x00\x00\x00\x00\x00\x00\x00";
1766write_mat5_array (std::ostream& os,
const FloatNDArray& m,
bool)
1769 const float *data = m.
data ();
1771 float max_val, min_val;
1773 st = octave::get_save_type (max_val, min_val);
1793 write_mat5_tag (os, mst,
len);
1831 os.write (
reinterpret_cast<const char *
> (data),
len);
1839 error (
"unrecognized data format requested");
1845 static char buf[9]=
"\x00\x00\x00\x00\x00\x00\x00\x00";
1850template <
typename T>
1892 write_mat5_tag (os, mst,
len);
1894 os.write (
reinterpret_cast<const char *
> (m),
len);
1898 static char buf[9]=
"\x00\x00\x00\x00\x00\x00\x00\x00";
1943write_mat5_cell_array (std::ostream& os,
const Cell& cell,
1944 bool mark_global,
bool save_as_floats)
1953 false, save_as_floats))
1962 bool save_as_floats)
1973 double tmp = val[i];
1975 if (octave::math::isfinite (tmp)
1976 && fabs (tmp) > std::numeric_limits<float>::max ())
2028 return 8 + nel * size;
2084 return PAD ((nel * size <= 4 ? 4 : 8) + nel * size);
2092 bool save_as_floats)
2099 tmp[i] = std::real (val[i]);
2104 tmp[i] = std::imag (val[i]);
2113 bool save_as_floats)
2120 tmp[i] = std::real (val[i]);
2125 tmp[i] = std::imag (val[i]);
2133maybe_convert_to_u16 (
const charNDArray& chm, std::size_t& n16_str)
2138 if (chm.
ndims () == 2 && dv(0) == 1)
2140 const uint8_t *u8_str =
reinterpret_cast<const uint8_t *
> (chm.
data ());
2152 bool save_as_floats,
bool mat7_format)
2160 std::size_t max_namelen = 63;
2166 ret +=
PAD (
len > max_namelen ? max_namelen :
len);
2179 std::size_t n16_str;
2180 uint16_t *u16_str = maybe_convert_to_u16 (chm, n16_str);
2184 std::size_t sz_of = 1;
2193 str_len = chm.
numel ();
2196 ret +=
PAD (sz_of * str_len);
2208 ret +=
PAD (nnz *
sizeof (int32_t));
2210 ret +=
PAD ((nc + 1) *
sizeof (int32_t));
2220 ret +=
PAD (nnz *
sizeof (int32_t));
2222 ret +=
PAD ((nc + 1) *
sizeof (int32_t));
2226#define INT_LEN(nel, size) \
2229 octave_idx_type sz = nel * size; \
2234 else if (cname ==
"int8")
2236 else if (cname ==
"int16")
2238 else if (cname ==
"int32")
2240 else if (cname ==
"int64")
2242 else if (cname ==
"uint8")
2244 else if (cname ==
"uint16")
2246 else if (cname ==
"uint32")
2248 else if (cname ==
"uint64")
2270 for (
int i = 0; i < nel; i++)
2292 std::size_t classlen = cname.length ();
2295 ret +=
PAD (classlen > max_namelen ? max_namelen : classlen);
2298 int ndims = dv.
ndims ();
2299 int nobjs = dv.numel ();
2301 if (cname ==
"FileWrapper__")
2303 octave::load_save_system& lss = octave::__get_load_save_system__ ();
2305 = lss.get_subsystem_handler ()->get_serialized_data ();
2313 save_as_floats, mat7_format);
2326 std::size_t classlen = tc.
class_name ().length ();
2328 ret += 8 +
PAD (classlen > max_namelen ? max_namelen : classlen);
2331 for (
auto i = m.
begin (); i != m.
end (); i++)
2334 ret += 16 + fieldcnt * (max_namelen + 1);
2338 for (
auto i = m.
begin (); i != m.
end (); i++)
2354write_mat5_sparse_index_vector (std::ostream& os,
2358 int tmp =
sizeof (int32_t);
2363 tmp_idx[i] = idx[i];
2369warn_dim_too_large (
const std::string& name)
2372 "save: skipping %s: dimension too large for MAT format",
2381 bool mark_global,
bool mat7_format,
2382 bool save_as_floats,
bool compressing)
2388 "Saving classdef objects is not supported. "
2389 "Attempting to save object as struct.");
2398 std::size_t max_namelen = 63;
2401 int nd = tc.
ndims ();
2404 static octave_idx_type max_dim_val = std::numeric_limits<int32_t>::max ();
2408 uint16_t *u16_str =
nullptr;
2409 std::size_t n16_str;
2410 bool conv_u16 =
false;
2414 u16_str = maybe_convert_to_u16 (chm, n16_str);
2420 octave::unwind_action free_memory ([u16_str] ()
2421 {
if (u16_str !=
nullptr)
free (u16_str); });
2425 if (n16_str >
static_cast<std::size_t
> (max_dim_val))
2427 warn_dim_too_large (name);
2433 for (
int i = 0; i < nd; i++)
2435 if (dv(i) > max_dim_val)
2437 warn_dim_too_large (name);
2461 if (nnz > max_dim_val || nc + 1 > max_dim_val)
2463 warn_dim_too_large (name);
2469 else if (dv.
numel () > max_dim_val)
2471 warn_dim_too_large (name);
2475#if defined (HAVE_ZLIB)
2477 if (mat7_format && ! compressing)
2481 std::ostringstream buf;
2486 save_as_floats,
true);
2492 std::string buf_str = buf.str ();
2493 uLongf srcLen = buf_str.length ();
2494 uLongf destLen = compressBound (srcLen);
2497 if (compress (
reinterpret_cast<Bytef *
> (out_buf), &destLen,
2498 reinterpret_cast<const Bytef *
> (buf_str.c_str ()),
2501 error (
"save: error compressing data element");
2506 os.write (out_buf, destLen);
2514 octave_unused_parameter (compressing);
2519 (tc, name, save_as_floats, mat7_format));
2535 else if (cname ==
"int8")
2537 else if (cname ==
"int16")
2539 else if (cname ==
"int32")
2541 else if (cname ==
"int64")
2543 else if (cname ==
"uint8" || tc.
islogical ())
2545 else if (cname ==
"uint16")
2547 else if (cname ==
"uint32")
2549 else if (cname ==
"uint64")
2573 error (
"save: error while writing '%s' to MAT file", name.c_str ());
2576 os.write (
reinterpret_cast<char *
> (&flags), 4);
2581 os.write (
reinterpret_cast<char *
> (&nnz_32), 4);
2586 write_mat5_tag (os,
miINT32, dim_len);
2590 int32_t n[2] = {1,
static_cast<int32_t
> (n16_str)};
2591 os.write (
reinterpret_cast<char *
> (&n), 8);
2594 for (
int i = 0; i < nd; i++)
2597 os.write (
reinterpret_cast<char *
> (&n), 4);
2600 if (
PAD (dim_len) > dim_len)
2602 static char buf[9] =
"\x00\x00\x00\x00\x00\x00\x00\x00";
2603 os.write (buf,
PAD (dim_len) - dim_len);
2609 std::size_t namelen = name.length ();
2611 if (namelen > max_namelen)
2612 namelen = max_namelen;
2614 int paddedlength =
PAD (namelen);
2616 write_mat5_tag (os,
miINT8, namelen);
2618 memset (paddedname, 0, paddedlength);
2619 strncpy (paddedname, name.c_str (), namelen);
2620 os.write (paddedname, paddedlength);
2626 std::string type_system;
2628 type_system =
"MCOS";
2629 std::size_t type_sys_len = type_system.length ();
2630 int paddedlength =
PAD (type_sys_len);
2631 write_mat5_tag (os,
miINT8, type_sys_len);
2633 memset (paddedtype, 0, paddedlength);
2634 strncpy (paddedtype, type_system.c_str (), type_sys_len);
2635 os.write (paddedtype, paddedlength);
2638 std::size_t class_name_len = cname.length ();
2639 paddedlength =
PAD (class_name_len);
2640 write_mat5_tag (os,
miINT8, class_name_len);
2642 memset (paddedclass, 0, paddedlength);
2643 strncpy (paddedclass, cname.c_str (), class_name_len);
2644 os.write (paddedclass, paddedlength);
2657 paddedlength =
PAD (
len);
2661 os.write (
reinterpret_cast<char *
> (u16_str),
len);
2667 paddedlength =
PAD (
len);
2674 if (paddedlength >
len)
2676 static char padbuf[9] =
"\x00\x00\x00\x00\x00\x00\x00\x00";
2677 os.write (padbuf, paddedlength -
len);
2688 write_mat5_sparse_index_vector (os, m.
ridx (), nnz);
2689 write_mat5_sparse_index_vector (os, m.
cidx (), nc + 1);
2694 buf (i) = std::real (m.
data (i));
2696 write_mat5_array (os, buf, save_as_floats);
2699 buf (i) = std::imag (m.
data (i));
2701 write_mat5_array (os, buf, save_as_floats);
2709 write_mat5_sparse_index_vector (os, m.
ridx (), nnz);
2710 write_mat5_sparse_index_vector (os, m.
cidx (), nc + 1);
2716 for (
int i = 0; i < nnz; i++)
2717 buf (i) = m.
data (i);
2719 write_mat5_array (os, buf, save_as_floats);
2722 else if (cname ==
"int8")
2728 else if (cname ==
"int16")
2734 else if (cname ==
"int32")
2740 else if (cname ==
"int64")
2746 else if (cname ==
"uint8")
2752 else if (cname ==
"uint16")
2758 else if (cname ==
"uint32")
2764 else if (cname ==
"uint64")
2782 write_mat5_array (os, m, save_as_floats);
2788 write_mat5_array (os, m, save_as_floats);
2795 if (! write_mat5_cell_array (os, cell, mark_global, save_as_floats))
2796 error (
"save: error while writing '%s' to MAT file", name.c_str ());
2804 write_mat5_array (os,
::real (m_cmplx), save_as_floats);
2805 write_mat5_array (os,
::imag (m_cmplx), save_as_floats);
2811 write_mat5_array (os,
::real (m_cmplx), save_as_floats);
2812 write_mat5_array (os,
::imag (m_cmplx), save_as_floats);
2817 octave::subsystem_handler *sh
2818 = octave::__get_load_save_system__ ().get_subsystem_handler ();
2821 if (cname ==
"FileWrapper__")
2822 objmetadata = sh->get_serialized_data ();
2823 else if (sh->has_serialized_data ())
2831 "Object of class %s cannot be loaded in Octave due "
2832 "to issues with MAT-compatibility and is returned "
2838 objmetadata = sh->set_mcos_object_metadata (tc);
2841 false, save_as_floats);
2843 error (
"save: error while writing '%s' to MAT file",
2852 std::size_t namelen = classname.length ();
2854 if (namelen > max_namelen)
2855 namelen = max_namelen;
2857 int paddedlength =
PAD (namelen);
2859 write_mat5_tag (os,
miINT8, namelen);
2861 memset (paddedname, 0, paddedlength);
2862 strncpy (paddedname, classname.c_str (), namelen);
2863 os.write (paddedname, paddedlength);
2868 octave::interpreter& interp = octave::__get_interpreter__ ();
2870 octave::load_path& lp = interp.get_load_path ();
2873 && lp.find_method (tc.
class_name (),
"saveobj") !=
"")
2879 m = tmp(0).map_value ();
2881 catch (
const octave::execution_exception&)
2883 error (
"save: error while writing '%s' to MAT file",
2894 int32_t maxfieldnamelength = max_namelen + 1;
2898 write_mat5_tag (os,
miINT32, 4);
2899 os.write (
reinterpret_cast<char *
> (&maxfieldnamelength), 4);
2900 write_mat5_tag (os,
miINT8, nf*maxfieldnamelength);
2908 std::string key = keys(i);
2911 memset (buf, 0, max_namelen + 1);
2913 strncpy (buf, key.c_str (), max_namelen);
2914 os.write (buf, max_namelen + 1);
2921 std::vector<const octave_value *> elts (nf);
2937 error (
"save: error while writing '%s' to MAT file",
void swap_bytes< 8 >(void *ptr)
void swap_bytes< 4 >(void *ptr)
const dim_vector & dims() const
Return a const-reference so that dims ()(i) works efficiently.
bool isvector() const
Size of the specified dimension.
int ndims() const
Size of the specified dimension.
const T * data() const
Size of the specified dimension.
T * rwdata()
Size of the specified dimension.
octave_idx_type numel() const
Number of elements in the array.
bool all_integers(float &max_val, float &min_val) const
bool all_integers(double &max_val, double &min_val) const
bool too_large_for_float() const
octave_idx_type cols() const
octave_idx_type nzmax() const
Amount of storage for nonzero elements.
octave_idx_type nnz() const
Actual number of nonzero terms.
Vector representing the dimensions (size) of an Array.
octave_idx_type numel(int n=0) const
Number of elements that a matrix with this dimensions would have.
void resize(int n, int fill_value=0)
octave_idx_type ndims() const
Number of dimensions.
bool reconstruct_parents()
bool reconstruct_exemplar()
octave_map map_value() const
octave_idx_type nfields() const
const_iterator end() const
string_vector keys() const
const Cell & contents(const_iterator p) const
octave_idx_type numel() const
void assign(const std::string &k, const Cell &val)
const_iterator begin() const
const octave_value & contents(const_iterator p) const
const_iterator end() const
const_iterator begin() const
octave_idx_type nfields() const
std::string key(const_iterator p) const
bool is_classdef_object() const
boolNDArray bool_array_value(bool warn=false) const
SparseMatrix sparse_matrix_value(bool frc_str_conv=false) const
std::string class_name() const
bool is_inline_function() const
bool is_real_scalar() const
int32NDArray int32_array_value() const
uint16NDArray uint16_array_value() const
octave_classdef * classdef_object_value(bool silent=false) const
int16NDArray int16_array_value() const
int8NDArray int8_array_value() const
octave_scalar_map scalar_map_value() const
bool is_complex_scalar() const
ComplexNDArray complex_array_value(bool frc_str_conv=false) const
bool is_single_type() const
charNDArray char_array_value(bool frc_str_conv=false) const
bool is_uint8_type() const
uint64NDArray uint64_array_value() const
octave_map map_value() const
bool is_real_matrix() const
std::string string_value(bool force=false) const
octave_fcn_handle * fcn_handle_value(bool silent=false) const
int64NDArray int64_array_value() const
NDArray array_value(bool frc_str_conv=false) const
octave_idx_type length() const
octave_value convert_to_str(bool pad=false, bool force=false, char type='\'') const
uint8NDArray uint8_array_value() const
std::string type_name() const
FloatComplexNDArray float_complex_array_value(bool frc_str_conv=false) const
FloatNDArray float_array_value(bool frc_str_conv=false) const
uint32NDArray uint32_array_value() const
bool is_complex_matrix() const
SparseComplexMatrix sparse_complex_matrix_value(bool frc_str_conv=false) const
ColumnVector real(const ComplexColumnVector &a)
ColumnVector imag(const ComplexColumnVector &a)
void read_int(std::istream &is, bool swap_bytes, T &val)
void read_doubles(std::istream &is, double *data, save_type type, octave_idx_type len, bool swap, octave::mach_info::float_format fmt)
void read_floats(std::istream &is, float *data, save_type type, octave_idx_type len, bool swap, octave::mach_info::float_format fmt)
void warning_with_id(const char *id, const char *fmt,...)
void error(const char *fmt,...)
void err_disabled_feature(const std::string &fcn, const std::string &feature, const std::string &pkg)
void warn_wrong_type_arg(const char *name, const octave_value &tc)
bool too_large_for_float(double x)
#define READ_INTEGER_DATA(TYPE, swap, data, size, len, stream)
void write_mat5_integer_data(std::ostream &os, const T *m, int size, octave_idx_type nel)
bool save_mat5_binary_element(std::ostream &os, const octave_value &tc_in, const std::string &name, bool mark_global, bool mat7_format, bool save_as_floats, bool compressing)
#define MAT5_DO_WRITE(TYPE, data, count, stream)
int save_mat5_array_length(const double *val, octave_idx_type nel, bool save_as_floats)
#define OCTAVE_MAT5_INTEGER_READ(TYP)
@ MAT_FILE_WORKSPACE_CLASS
@ MAT_FILE_FUNCTION_CLASS
int save_mat5_element_length(const octave_value &tc_in, const std::string &name, bool save_as_floats, bool mat7_format)
int read_mat5_binary_file_header(std::istream &is, bool &swap, bool quiet, const std::string &filename)
#define INT_LEN(nel, size)
std::string read_mat5_binary_element(std::istream &is, const std::string &filename, bool swap, bool &global, octave_value &tc)
#define READ_PAD(is_small_data_element, l)
void read_mat5_integer_data(std::istream &is, T *m, octave_idx_type count, bool swap, mat5_data_type type)
std::complex< double > Complex
std::complex< float > FloatComplex
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
uint8_t * octave_u32_to_u8_wrapper(const uint32_t *src, size_t src_len, uint8_t *result_buf, size_t *lengthp)
uint16_t * octave_u8_to_u16_wrapper(const uint8_t *src, size_t src_len, uint16_t *result_buf, size_t *lengthp)
uint8_t * octave_u16_to_u8_wrapper(const uint16_t *src, size_t src_len, uint8_t *result_buf, size_t *lengthp)