26#if defined (HAVE_CONFIG_H)
49#if defined (OCTAVE_HAVE_LONG_LONG_INT)
50# define FIND_SIZED_INT_TYPE(VAL, BITS, TQ, Q) \
53 int sz = BITS / std::numeric_limits<unsigned char>::digits; \
54 if (sizeof (TQ char) == sz) \
55 VAL = oct_data_conv::dt_ ## Q ## char; \
56 else if (sizeof (TQ short) == sz) \
57 VAL = oct_data_conv::dt_ ## Q ## short; \
58 else if (sizeof (TQ int) == sz) \
59 VAL = oct_data_conv::dt_ ## Q ## int; \
60 else if (sizeof (TQ long) == sz) \
61 VAL = oct_data_conv::dt_ ## Q ## long; \
62 else if (sizeof (TQ long long) == sz) \
63 VAL = oct_data_conv::dt_ ## Q ## longlong; \
65 VAL = oct_data_conv::dt_unknown; \
69# define FIND_SIZED_INT_TYPE(VAL, BITS, TQ, Q) \
72 int sz = BITS / std::numeric_limits<unsigned char>::digits; \
73 if (sizeof (TQ char) == sz) \
74 VAL = oct_data_conv::dt_ ## Q ## char; \
75 else if (sizeof (TQ short) == sz) \
76 VAL = oct_data_conv::dt_ ## Q ## short; \
77 else if (sizeof (TQ int) == sz) \
78 VAL = oct_data_conv::dt_ ## Q ## int; \
79 else if (sizeof (TQ long) == sz) \
80 VAL = oct_data_conv::dt_ ## Q ## long; \
82 VAL = oct_data_conv::dt_unknown; \
87#define FIND_SIZED_FLOAT_TYPE(VAL, BITS) \
90 int sz = BITS / std::numeric_limits<unsigned char>::digits; \
91 if (sizeof (float) == sz) \
92 VAL = oct_data_conv::dt_float; \
93 else if (sizeof (double) == sz) \
94 VAL = oct_data_conv::dt_double; \
96 VAL = oct_data_conv::dt_unknown; \
128 for (
int i = 0; i < 4; i++)
141strip_spaces (
const std::string& str)
143 std::size_t n = str.length ();
147 std::string s (n,
'\0');
149 for (std::size_t i = 0; i < n; i++)
150 if (! isspace (str[i]))
151 s[k++] = tolower (str[i]);
158#define GET_SIZED_INT_TYPE(T, U) \
161 switch (sizeof (T)) \
164 retval = dt_ ## U ## int8; \
168 retval = dt_ ## U ## int16; \
172 retval = dt_ ## U ## int32; \
176 retval = dt_ ## U ## int64; \
180 retval = dt_unknown; \
189 std::size_t retval = -1;
194 retval =
sizeof (int8_t);
198 retval =
sizeof (uint8_t);
202 retval =
sizeof (int16_t);
206 retval =
sizeof (uint16_t);
210 retval =
sizeof (int32_t);
214 retval =
sizeof (uint32_t);
218 retval =
sizeof (int64_t);
222 retval =
sizeof (uint64_t);
227 retval =
sizeof (
float);
235 retval =
sizeof (char);
239 retval =
sizeof (
signed char);
243 retval =
sizeof (
unsigned char);
247 retval =
sizeof (short);
251 retval =
sizeof (
unsigned short);
255 retval =
sizeof (
int);
259 retval =
sizeof (
unsigned int);
263 retval =
sizeof (long);
267 retval =
sizeof (
unsigned long);
271 retval =
sizeof (
long long);
275 retval =
sizeof (
unsigned long long);
279 retval =
sizeof (
bool);
284 (*current_liboctave_error_handler)
285 (
"oct_data_conv::data_type_size: unknown data type");
297 static bool initialized =
false;
303 init_sized_type_lookup_table (sized_type_table);
308 std::string s = strip_spaces (str);
313 else if (s ==
"double" || s ==
"float64" || s ==
"real*8")
315 else if (s ==
"single" || s ==
"float" || s ==
"float32" || s ==
"real*4")
317 else if (s ==
"char" || s ==
"char*1")
321 else if (s ==
"uchar" || s ==
"unsignedchar")
323 else if (s ==
"schar" || s ==
"signedchar")
325 else if (s ==
"int8" || s ==
"integer*1")
327 else if (s ==
"int16" || s ==
"integer*2")
329 else if (s ==
"uint16")
331 else if (s ==
"int32" || s ==
"integer*4")
333 else if (s ==
"uint32")
335 else if (s ==
"int64" || s ==
"integer*8")
337 else if (s ==
"uint64")
339 else if (s ==
"short")
341 else if (s ==
"ushort" || s ==
"unsignedshort")
343 else if (s ==
"uint" || s ==
"unsignedint")
345 else if (s ==
"long")
347 else if (s ==
"ulong" || s ==
"unsignedlong")
350 else if (s ==
"longlong")
352 else if (s ==
"ulonglong" || s ==
"unsignedlonglong")
354 else if (s ==
"logical")
360 (*current_liboctave_error_handler)
361 (
"unable to find matching native data type for %s", s.c_str ());
375 bool input_is_output =
false;
377 std::string s = strip_spaces (str);
382 input_is_output =
true;
385 std::size_t
len = s.length ();
387 while (pos <
len && isdigit (s[pos]))
396 block_size = std::stoi (s);
397 s = s.substr (pos+1);
399 catch (
const std::invalid_argument&)
401 (*current_liboctave_error_handler)
402 (
"invalid repeat count in '%s'", s.c_str ());
404 catch (
const std::out_of_range&)
406 (*current_liboctave_error_handler)
407 (
"repeat count out of range in '%s'", s.c_str ());
412 (
"invalid repeat count in '%s'", str.c_str ());
418 if (pos != std::string::npos)
426 s1 = s.substr (1, pos-1);
428 (*current_liboctave_warning_with_id_handler)
429 (
"Octave:fread-precision-syntax",
430 "warning: ignoring leading * in fread precision");
433 s1 = s.substr (0, pos);
440 (
"fread: invalid precision specified");
450 output_type = input_type;
461 std::string s = strip_spaces (str);
465 std::size_t
len = s.length ();
467 while (pos <
len && isdigit (s[pos]))
476 block_size = std::stoi (s);
477 s = s.substr (pos+1);
479 catch (
const std::invalid_argument&)
481 (*current_liboctave_error_handler)
482 (
"invalid repeat count in '%s'", s.c_str ());
484 catch (
const std::out_of_range&)
486 (*current_liboctave_error_handler)
487 (
"repeat count out of range in '%s'", s.c_str ());
492 (
"invalid repeat count in '%s'", str.c_str ());
550 retval =
"signed char";
554 retval =
"unsigned char";
562 retval =
"unsigned short";
570 retval =
"unsigned int";
578 retval =
"unsigned long";
582 retval =
"long long";
586 retval =
"unsigned long long";
606#define LS_DO_READ(TYPE, swap, data, size, len, stream) \
611 OCTAVE_LOCAL_BUFFER (TYPE, ptr, len); \
612 std::streamsize n_bytes = size * static_cast<std::streamsize> (len); \
613 do_read (stream, reinterpret_cast<char *> (ptr), n_bytes); \
617 swap_bytes< size > (ptr, len); \
618 for (octave_idx_type i = 0; i < len; i++) \
627#define LS_DO_WRITE(TYPE, data, size, len, stream) \
630 char tmp_type = type; \
631 stream.write (&tmp_type, 1); \
634 OCTAVE_LOCAL_BUFFER (TYPE, ptr, len); \
635 for (octave_idx_type i = 0; i < len; i++) \
636 ptr[i] = static_cast<TYPE> (data[i]); \
637 std::streamsize n_bytes = size * static_cast<std::streamsize> (len); \
638 do_write (stream, reinterpret_cast<const char *> (ptr), n_bytes); \
645OCTAVE_NORETURN
static
647err_unrecognized_float_fmt ()
649 (*current_liboctave_error_handler)
650 (
"unrecognized floating point format requested");
688 octave::mach_info::float_format from_fmt,
689 octave::mach_info::float_format to_fmt)
693 case octave::mach_info::flt_fmt_ieee_little_endian:
696 case octave::mach_info::flt_fmt_ieee_little_endian:
699 case octave::mach_info::flt_fmt_ieee_big_endian:
700 IEEE_big_double_to_IEEE_little_double (data,
len);
704 err_unrecognized_float_fmt ();
709 case octave::mach_info::flt_fmt_ieee_big_endian:
712 case octave::mach_info::flt_fmt_ieee_little_endian:
713 IEEE_little_double_to_IEEE_big_double (data,
len);
716 case octave::mach_info::flt_fmt_ieee_big_endian:
720 err_unrecognized_float_fmt ();
726 (*current_liboctave_error_handler)
727 (
"impossible state reached in file '%s' at line %d",
735 octave::mach_info::float_format from_fmt,
736 octave::mach_info::float_format to_fmt)
740 case octave::mach_info::flt_fmt_ieee_little_endian:
743 case octave::mach_info::flt_fmt_ieee_little_endian:
746 case octave::mach_info::flt_fmt_ieee_big_endian:
747 IEEE_big_float_to_IEEE_little_float (data,
len);
751 err_unrecognized_float_fmt ();
756 case octave::mach_info::flt_fmt_ieee_big_endian:
759 case octave::mach_info::flt_fmt_ieee_little_endian:
760 IEEE_little_float_to_IEEE_big_float (data,
len);
763 case octave::mach_info::flt_fmt_ieee_big_endian:
767 err_unrecognized_float_fmt ();
773 (*current_liboctave_error_handler)
774 (
"impossible state reached in file '%s' at line %d",
782 octave::mach_info::float_format from_fmt,
783 octave::mach_info::float_format to_fmt)
796 (*current_liboctave_error_handler)
797 (
"impossible state reached in file '%s' at line %d",
804do_read (std::istream& is,
char *byte_data, std::streamsize n_bytes)
807 constexpr std::streamsize chunk_size = 64 * 1024 * 1024;
808 for (std::streamsize offset = 0; offset < n_bytes; )
810 std::streamsize to_read = std::min (chunk_size, n_bytes - offset);
811 is.read (byte_data + offset, to_read);
822 octave::mach_info::float_format fmt)
853 std::streamsize n_bytes =
sizeof (
float) *
static_cast<std::streamsize
> (
len);
854 do_read (is,
reinterpret_cast<char *
> (ptr), n_bytes);
865 std::streamsize n_bytes =
sizeof (
double) *
static_cast<std::streamsize
> (
len);
866 do_read (is,
reinterpret_cast<char *
> (data), n_bytes);
878 is.clear (std::ios::failbit | is.rdstate ());
886 octave::mach_info::float_format fmt)
916 std::streamsize n_bytes =
sizeof (
float) *
static_cast<std::streamsize
> (
len);
917 do_read (is,
reinterpret_cast<char *
> (data), n_bytes);
927 std::streamsize n_bytes = 8 *
static_cast<std::streamsize
> (
len);
928 do_read (is,
reinterpret_cast<char *
> (ptr), n_bytes);
938 is.clear (std::ios::failbit | is.rdstate ());
944do_write (std::ostream& os,
const char *byte_data, std::streamsize n_bytes)
947 constexpr std::streamsize chunk_size = 64 * 1024 * 1024;
948 for (std::streamsize written = 0; written < n_bytes; )
950 std::streamsize remaining = n_bytes - written;
951 std::streamsize to_write = std::min (chunk_size, remaining);
952 os.write (byte_data + written, to_write);
995 char tmp_type =
static_cast<char> (type);
996 os.write (&tmp_type, 1);
998 std::streamsize n_bytes =
sizeof (
double) *
static_cast<std::streamsize
> (
len);
999 do_write (os,
reinterpret_cast<const char *
> (data), n_bytes);
1004 (*current_liboctave_error_handler)
1005 (
"unrecognized data format requested");
1042 char tmp_type =
static_cast<char> (type);
1043 os.write (&tmp_type, 1);
1044 std::streamsize n_bytes =
sizeof (
float) *
static_cast<std::streamsize
> (
len);
1045 do_write (os,
reinterpret_cast<const char *
> (data), n_bytes);
1054 (*current_liboctave_error_handler)
1055 (
"unrecognized data format requested");
void swap_bytes< 8 >(void *ptr)
void swap_bytes< 4 >(void *ptr)
static std::size_t data_type_size(data_type dt)
static std::string data_type_as_string(data_type dt)
static data_type string_to_data_type(const std::string &s)
void do_float_format_conversion(void *data, octave_idx_type len, octave::mach_info::float_format from_fmt, octave::mach_info::float_format to_fmt)
#define LS_DO_READ(TYPE, swap, data, size, len, stream)
#define FIND_SIZED_INT_TYPE(VAL, BITS, TQ, Q)
#define GET_SIZED_INT_TYPE(T, U)
void read_doubles(std::istream &is, double *data, save_type type, octave_idx_type len, bool swap, octave::mach_info::float_format fmt)
void write_doubles(std::ostream &os, const double *data, save_type type, octave_idx_type len)
void write_floats(std::ostream &os, const float *data, save_type type, octave_idx_type len)
#define LS_DO_WRITE(TYPE, data, size, len, stream)
void read_floats(std::istream &is, float *data, save_type type, octave_idx_type len, bool swap, octave::mach_info::float_format fmt)
void do_double_format_conversion(void *data, octave_idx_type len, octave::mach_info::float_format from_fmt, octave::mach_info::float_format to_fmt)
#define FIND_SIZED_FLOAT_TYPE(VAL, BITS)
OCTAVE_NORETURN liboctave_error_handler current_liboctave_error_handler
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d