GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
data-conv.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1996-2024 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include <cctype>
31 #include <cstdlib>
32 
33 #include <istream>
34 #include <limits>
35 #include <ostream>
36 #include <vector>
37 
38 #include "byte-swap.h"
39 #include "data-conv.h"
40 #include "lo-error.h"
41 #include "lo-ieee.h"
42 #include "oct-locbuf.h"
43 
44 // FIXME: Almost all platform-dependent sizes such as "short" are now defined
45 // to take fixed values (such as 2B). This was instigated for Matlab
46 // compatibility (bug #41672). It means a lot of this code is probably
47 // obsolete and could be pared down or removed entirely.
48 
49 #if defined (OCTAVE_HAVE_LONG_LONG_INT)
50 # define FIND_SIZED_INT_TYPE(VAL, BITS, TQ, Q) \
51  do \
52  { \
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; \
64  else \
65  VAL = oct_data_conv::dt_unknown; \
66  } \
67  while (0)
68 #else
69 # define FIND_SIZED_INT_TYPE(VAL, BITS, TQ, Q) \
70  do \
71  { \
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; \
81  else \
82  VAL = oct_data_conv::dt_unknown; \
83  } \
84  while (0)
85 #endif
86 
87 #define FIND_SIZED_FLOAT_TYPE(VAL, BITS) \
88  do \
89  { \
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; \
95  else \
96  VAL = oct_data_conv::dt_unknown; \
97  } \
98  while (0)
99 
100 // I'm not sure it is worth the trouble, but let's use a lookup table
101 // for the types that are supposed to be a specific number of bits
102 // wide. Given the macros above, this should work as long as
103 // std::numeric_limits<unsigned char>::digits is a multiple of 8 and
104 // there are types with the right sizes.
105 //
106 // The sized data type lookup table has the following format:
107 //
108 // bits
109 // +----+----+----+----+
110 // | 8 | 16 | 32 | 64 |
111 // +----+----+----+----+
112 // signed integer | | | | |
113 // +----+----+----+----+
114 // unsigned integer | | | | |
115 // +----+----+----+----+
116 // floating point | | | | |
117 // +----+----+----+----+
118 //
119 // So, the 0,3 element is supposed to contain the oct_data_conv enum
120 // value corresponding to the correct native data type for a signed
121 // 32-bit integer.
122 
123 static void
124 init_sized_type_lookup_table (oct_data_conv::data_type table[3][4])
125 {
126  int bits = 8;
127 
128  for (int i = 0; i < 4; i++)
129  {
130  FIND_SIZED_INT_TYPE (table[0][i], bits, , );
131 
132  FIND_SIZED_INT_TYPE (table[1][i], bits, unsigned, u);
133 
134  FIND_SIZED_FLOAT_TYPE (table[2][i], bits);
135 
136  bits *= 2;
137  }
138 }
139 
140 static std::string
141 strip_spaces (const std::string& str)
142 {
143  std::size_t n = str.length ();
144 
145  std::size_t k = 0;
146 
147  std::string s (n, '\0');
148 
149  for (std::size_t i = 0; i < n; i++)
150  if (! isspace (str[i]))
151  s[k++] = tolower (str[i]);
152 
153  s.resize (k);
154 
155  return s;
156 }
157 
158 #define GET_SIZED_INT_TYPE(T, U) \
159  do \
160  { \
161  switch (sizeof (T)) \
162  { \
163  case 1: \
164  retval = dt_ ## U ## int8; \
165  break; \
166  \
167  case 2: \
168  retval = dt_ ## U ## int16; \
169  break; \
170  \
171  case 4: \
172  retval = dt_ ## U ## int32; \
173  break; \
174  \
175  case 8: \
176  retval = dt_ ## U ## int64; \
177  break; \
178  \
179  default: \
180  retval = dt_unknown; \
181  break; \
182  } \
183  } \
184  while (0)
185 
186 std::size_t
188 {
189  std::size_t retval = -1;
190 
191  switch (dt)
192  {
194  retval = sizeof (int8_t);
195  break;
196 
198  retval = sizeof (uint8_t);
199  break;
200 
202  retval = sizeof (int16_t);
203  break;
204 
206  retval = sizeof (uint16_t);
207  break;
208 
210  retval = sizeof (int32_t);
211  break;
212 
214  retval = sizeof (uint32_t);
215  break;
216 
218  retval = sizeof (int64_t);
219  break;
220 
222  retval = sizeof (uint64_t);
223  break;
224 
227  retval = sizeof (float);
228  break;
229 
231  retval = sizeof (double);
232  break;
233 
235  retval = sizeof (char);
236  break;
237 
239  retval = sizeof (signed char);
240  break;
241 
243  retval = sizeof (unsigned char);
244  break;
245 
247  retval = sizeof (short);
248  break;
249 
251  retval = sizeof (unsigned short);
252  break;
253 
255  retval = sizeof (int);
256  break;
257 
259  retval = sizeof (unsigned int);
260  break;
261 
263  retval = sizeof (long);
264  break;
265 
267  retval = sizeof (unsigned long);
268  break;
269 
271  retval = sizeof (long long);
272  break;
273 
275  retval = sizeof (unsigned long long);
276  break;
277 
279  retval = sizeof (bool);
280  break;
281 
283  default:
284  (*current_liboctave_error_handler)
285  ("oct_data_conv::data_type_size: unknown data type");
286  break;
287  }
288 
289  return retval;
290 }
291 
293 oct_data_conv::string_to_data_type (const std::string& str)
294 {
295  data_type retval = dt_unknown;
296 
297  static bool initialized = false;
298 
299  static data_type sized_type_table[3][4];
300 
301  if (! initialized)
302  {
303  init_sized_type_lookup_table (sized_type_table);
304 
305  initialized = true;
306  }
307 
308  std::string s = strip_spaces (str);
309 
310  // Organized so most frequent precision appears first
311  if (s == "uint8")
312  retval = dt_uint8;
313  else if (s == "double" || s == "float64" || s == "real*8")
314  retval = dt_double;
315  else if (s == "single" || s == "float" || s == "float32" || s == "real*4")
316  retval = dt_single;
317  else if (s == "char" || s == "char*1")
318  retval = dt_char;
319  else if (s == "int")
320  retval = dt_int32;
321  else if (s == "uchar" || s == "unsignedchar")
322  retval = dt_uint8;
323  else if (s == "schar" || s == "signedchar")
324  retval = dt_int8;
325  else if (s == "int8" || s == "integer*1")
326  retval = dt_int8;
327  else if (s == "int16" || s == "integer*2")
328  retval = dt_int16;
329  else if (s == "uint16")
330  retval = dt_uint16;
331  else if (s == "int32" || s == "integer*4")
332  retval = dt_int32;
333  else if (s == "uint32")
334  retval = dt_uint32;
335  else if (s == "int64" || s == "integer*8")
336  retval = dt_int64;
337  else if (s == "uint64")
338  retval = dt_uint64;
339  else if (s == "short")
340  retval = dt_int16;
341  else if (s == "ushort" || s == "unsignedshort")
342  retval = dt_uint16;
343  else if (s == "uint" || s == "unsignedint")
344  retval = dt_uint32;
345  else if (s == "long")
346  retval = dt_int32;
347  else if (s == "ulong" || s == "unsignedlong")
348  retval = dt_uint32;
349  // FIXME: The following are undocumented precisions
350  else if (s == "longlong")
351  GET_SIZED_INT_TYPE (long long, );
352  else if (s == "ulonglong" || s == "unsignedlonglong")
353  GET_SIZED_INT_TYPE (unsigned long long, u);
354  else if (s == "logical")
355  retval = dt_logical;
356  else
357  (*current_liboctave_error_handler) ("invalid data type specified");
358 
359  if (retval == dt_unknown)
360  (*current_liboctave_error_handler)
361  ("unable to find matching native data type for %s", s.c_str ());
362 
363  return retval;
364 }
365 
366 void
367 oct_data_conv::string_to_data_type (const std::string& str, int& block_size,
368  oct_data_conv::data_type& input_type,
369  oct_data_conv::data_type& output_type)
370 {
371  block_size = 1;
372  input_type = dt_uchar;
373  output_type = dt_double;
374 
375  bool input_is_output = false;
376 
377  std::string s = strip_spaces (str);
378 
379  std::size_t pos = 0;
380 
381  if (s[0] == '*')
382  input_is_output = true;
383  else
384  {
385  std::size_t len = s.length ();
386 
387  while (pos < len && isdigit (s[pos]))
388  pos++;
389 
390  if (pos > 0)
391  {
392  if (s[pos] == '*')
393  {
394  block_size = atoi (s.c_str ());
395  s = s.substr (pos+1);
396  }
397  else
399  ("invalid repeat count in '%s'", str.c_str ());
400  }
401  }
402 
403  pos = s.find ('=');
404 
405  if (pos != std::string::npos)
406  {
407  if (s[pos+1] == '>')
408  {
409  std::string s1;
410 
411  if (input_is_output)
412  {
413  s1 = s.substr (1, pos-1);
414 
415  (*current_liboctave_warning_with_id_handler)
416  ("Octave:fread-precision-syntax",
417  "warning: ignoring leading * in fread precision");
418  }
419  else
420  s1 = s.substr (0, pos);
421 
422  input_type = string_to_data_type (s1);
423  output_type = string_to_data_type (s.substr (pos+2));
424  }
425  else
427  ("fread: invalid precision specified");
428  }
429  else
430  {
431  if (input_is_output)
432  s = s.substr (1);
433 
434  input_type = string_to_data_type (s);
435 
436  if (input_is_output)
437  output_type = input_type;
438  }
439 }
440 
441 void
442 oct_data_conv::string_to_data_type (const std::string& str, int& block_size,
443  oct_data_conv::data_type& output_type)
444 {
445  block_size = 1;
446  output_type = dt_double;
447 
448  std::string s = strip_spaces (str);
449 
450  std::size_t pos = 0;
451 
452  std::size_t len = s.length ();
453 
454  while (pos < len && isdigit (s[pos]))
455  pos++;
456 
457  if (pos > 0)
458  {
459  if (s[pos] == '*')
460  {
461  block_size = atoi (s.c_str ());
462  s = s.substr (pos+1);
463  }
464  else
466  ("invalid repeat count in '%s'", str.c_str ());
467  }
468 
469  output_type = string_to_data_type (s);
470 }
471 
472 std::string
474 {
475  std::string retval;
476 
477  switch (dt)
478  {
480  retval = "int8";
481  break;
482 
484  retval = "uint8";
485  break;
486 
488  retval = "int16";
489  break;
490 
492  retval = "uint16";
493  break;
494 
496  retval = "int32";
497  break;
498 
500  retval = "uint32";
501  break;
502 
504  retval = "int64";
505  break;
506 
508  retval = "uint64";
509  break;
510 
512  retval = "single";
513  break;
514 
516  retval = "double";
517  break;
518 
520  retval = "char";
521  break;
522 
524  retval = "signed char";
525  break;
526 
528  retval = "unsigned char";
529  break;
530 
532  retval = "short";
533  break;
534 
536  retval = "unsigned short";
537  break;
538 
540  retval = "int";
541  break;
542 
544  retval = "unsigned int";
545  break;
546 
548  retval = "long";
549  break;
550 
552  retval = "unsigned long";
553  break;
554 
556  retval = "long long";
557  break;
558 
560  retval = "unsigned long long";
561  break;
562 
564  retval = "float";
565  break;
566 
568  retval = "logical";
569  break;
570 
572  default:
573  retval = "unknown";
574  break;
575  }
576 
577  return retval;
578 }
579 
580 #define LS_DO_READ(TYPE, swap, data, size, len, stream) \
581  do \
582  { \
583  if (len > 0) \
584  { \
585  OCTAVE_LOCAL_BUFFER (TYPE, ptr, len); \
586  std::streamsize n_bytes = size * static_cast<std::streamsize> (len); \
587  stream.read (reinterpret_cast<char *> (ptr), n_bytes); \
588  if (swap) \
589  swap_bytes< size > (ptr, len); \
590  for (octave_idx_type i = 0; i < len; i++) \
591  data[i] = ptr[i]; \
592  } \
593  } \
594  while (0)
595 
596 // Have to use copy here to avoid writing over data accessed via
597 // Matrix::data ().
598 
599 #define LS_DO_WRITE(TYPE, data, size, len, stream) \
600  do \
601  { \
602  if (len > 0) \
603  { \
604  char tmp_type = type; \
605  stream.write (&tmp_type, 1); \
606  OCTAVE_LOCAL_BUFFER (TYPE, ptr, len); \
607  for (octave_idx_type i = 0; i < len; i++) \
608  ptr[i] = static_cast<TYPE> (data[i]); \
609  std::streamsize n_bytes = size * static_cast<std::streamsize> (len); \
610  stream.write (reinterpret_cast<char *> (ptr), n_bytes); \
611  } \
612  } \
613  while (0)
614 
615 // Loading variables from files.
616 
617 OCTAVE_NORETURN static
618 void
619 err_unrecognized_float_fmt ()
620 {
621  (*current_liboctave_error_handler)
622  ("unrecognized floating point format requested");
623 }
624 
625 // But first, some data conversion routines.
626 
627 // Currently, we only handle conversions for the IEEE types. To fix
628 // that, make more of the following routines work.
629 
630 // FIXME: assumes sizeof (Complex) == 8
631 // FIXME: assumes sizeof (double) == 8
632 // FIXME: assumes sizeof (float) == 4
633 
634 static void
635 IEEE_big_double_to_IEEE_little_double (void *d, octave_idx_type len)
636 {
637  swap_bytes<8> (d, len);
638 }
639 
640 static void
641 IEEE_big_float_to_IEEE_little_float (void *d, octave_idx_type len)
642 {
643  swap_bytes<4> (d, len);
644 }
645 
646 static void
647 IEEE_little_double_to_IEEE_big_double (void *d, octave_idx_type len)
648 {
649  swap_bytes<8> (d, len);
650 }
651 
652 static void
653 IEEE_little_float_to_IEEE_big_float (void *d, octave_idx_type len)
654 {
655  swap_bytes<4> (d, len);
656 }
657 
658 void
662 {
663  switch (to_fmt)
664  {
666  switch (from_fmt)
667  {
669  break;
670 
672  IEEE_big_double_to_IEEE_little_double (data, len);
673  break;
674 
675  default:
676  err_unrecognized_float_fmt ();
677  break;
678  }
679  break;
680 
682  switch (from_fmt)
683  {
685  IEEE_little_double_to_IEEE_big_double (data, len);
686  break;
687 
689  break;
690 
691  default:
692  err_unrecognized_float_fmt ();
693  break;
694  }
695  break;
696 
697  default:
698  (*current_liboctave_error_handler)
699  ("impossible state reached in file '%s' at line %d",
700  __FILE__, __LINE__);
701  break;
702  }
703 }
704 
705 void
709 {
710  switch (to_fmt)
711  {
713  switch (from_fmt)
714  {
716  break;
717 
719  IEEE_big_float_to_IEEE_little_float (data, len);
720  break;
721 
722  default:
723  err_unrecognized_float_fmt ();
724  break;
725  }
726  break;
727 
729  switch (from_fmt)
730  {
732  IEEE_little_float_to_IEEE_big_float (data, len);
733  break;
734 
736  break;
737 
738  default:
739  err_unrecognized_float_fmt ();
740  break;
741  }
742  break;
743 
744  default:
745  (*current_liboctave_error_handler)
746  ("impossible state reached in file '%s' at line %d",
747  __FILE__, __LINE__);
748  break;
749  }
750 }
751 
752 void
753 do_float_format_conversion (void *data, std::size_t sz, octave_idx_type len,
756 {
757  switch (sz)
758  {
759  case sizeof (float):
760  do_float_format_conversion (data, len, from_fmt, to_fmt);
761  break;
762 
763  case sizeof (double):
764  do_double_format_conversion (data, len, from_fmt, to_fmt);
765  break;
766 
767  default:
768  (*current_liboctave_error_handler)
769  ("impossible state reached in file '%s' at line %d",
770  __FILE__, __LINE__);
771  break;
772  }
773 }
774 
775 void
776 read_doubles (std::istream& is, double *data, save_type type,
777  octave_idx_type len, bool swap,
779 {
780  switch (type)
781  {
782  case LS_U_CHAR:
783  LS_DO_READ (uint8_t, swap, data, 1, len, is);
784  break;
785 
786  case LS_U_SHORT:
787  LS_DO_READ (uint16_t, swap, data, 2, len, is);
788  break;
789 
790  case LS_U_INT:
791  LS_DO_READ (uint32_t, swap, data, 4, len, is);
792  break;
793 
794  case LS_CHAR:
795  LS_DO_READ (int8_t, swap, data, 1, len, is);
796  break;
797 
798  case LS_SHORT:
799  LS_DO_READ (int16_t, swap, data, 2, len, is);
800  break;
801 
802  case LS_INT:
803  LS_DO_READ (int32_t, swap, data, 4, len, is);
804  break;
805 
806  case LS_FLOAT:
807  {
808  OCTAVE_LOCAL_BUFFER (float, ptr, len);
809  std::streamsize n_bytes = 4 * static_cast<std::streamsize> (len);
810  is.read (reinterpret_cast<char *> (ptr), n_bytes);
811  do_float_format_conversion (ptr, len, fmt);
812  for (octave_idx_type i = 0; i < len; i++)
813  data[i] = ptr[i];
814  }
815  break;
816 
817  case LS_DOUBLE: // No conversion necessary.
818  {
819  std::streamsize n_bytes = 8 * static_cast<std::streamsize> (len);
820  is.read (reinterpret_cast<char *> (data), n_bytes);
821  do_double_format_conversion (data, len, fmt);
822  // FIXME: Potentially add conversion code for MIPS NA here, Bug #59830.
823  //
824  // for (int i = 0; i < len; i++)
825  // data[i] = __lo_ieee_replace_MIPS_NA (data[i]);
826  }
827  break;
828 
829  default:
830  is.clear (std::ios::failbit | is.rdstate ());
831  break;
832  }
833 }
834 
835 void
836 read_floats (std::istream& is, float *data, save_type type,
837  octave_idx_type len, bool swap,
839 {
840  switch (type)
841  {
842  case LS_U_CHAR:
843  LS_DO_READ (uint8_t, swap, data, 1, len, is);
844  break;
845 
846  case LS_U_SHORT:
847  LS_DO_READ (uint16_t, swap, data, 2, len, is);
848  break;
849 
850  case LS_U_INT:
851  LS_DO_READ (uint32_t, swap, data, 4, len, is);
852  break;
853 
854  case LS_CHAR:
855  LS_DO_READ (int8_t, swap, data, 1, len, is);
856  break;
857 
858  case LS_SHORT:
859  LS_DO_READ (int16_t, swap, data, 2, len, is);
860  break;
861 
862  case LS_INT:
863  LS_DO_READ (int32_t, swap, data, 4, len, is);
864  break;
865 
866  case LS_FLOAT: // No conversion necessary.
867  {
868  std::streamsize n_bytes = 4 * static_cast<std::streamsize> (len);
869  is.read (reinterpret_cast<char *> (data), n_bytes);
870  do_float_format_conversion (data, len, fmt);
871  }
872  break;
873 
874  case LS_DOUBLE:
875  {
876  OCTAVE_LOCAL_BUFFER (double, ptr, len);
877  std::streamsize n_bytes = 8 * static_cast<std::streamsize> (len);
878  is.read (reinterpret_cast<char *> (ptr), n_bytes);
879  do_double_format_conversion (ptr, len, fmt);
880  for (octave_idx_type i = 0; i < len; i++)
881  data[i] = ptr[i];
882  }
883  break;
884 
885  default:
886  is.clear (std::ios::failbit | is.rdstate ());
887  break;
888  }
889 }
890 
891 void
892 write_doubles (std::ostream& os, const double *data, save_type type,
894 {
895  switch (type)
896  {
897  case LS_U_CHAR:
898  LS_DO_WRITE (uint8_t, data, 1, len, os);
899  break;
900 
901  case LS_U_SHORT:
902  LS_DO_WRITE (uint16_t, data, 2, len, os);
903  break;
904 
905  case LS_U_INT:
906  LS_DO_WRITE (uint32_t, data, 4, len, os);
907  break;
908 
909  case LS_CHAR:
910  LS_DO_WRITE (int8_t, data, 1, len, os);
911  break;
912 
913  case LS_SHORT:
914  LS_DO_WRITE (int16_t, data, 2, len, os);
915  break;
916 
917  case LS_INT:
918  LS_DO_WRITE (int32_t, data, 4, len, os);
919  break;
920 
921  case LS_FLOAT:
922  LS_DO_WRITE (float, data, 4, len, os);
923  break;
924 
925  case LS_DOUBLE: // No conversion necessary.
926  {
927  char tmp_type = static_cast<char> (type);
928  os.write (&tmp_type, 1);
929  std::streamsize n_bytes = 8 * static_cast<std::streamsize> (len);
930  os.write (reinterpret_cast<const char *> (data), n_bytes);
931  }
932  break;
933 
934  default:
935  (*current_liboctave_error_handler)
936  ("unrecognized data format requested");
937  break;
938  }
939 }
940 
941 void
942 write_floats (std::ostream& os, const float *data, save_type type,
944 {
945  switch (type)
946  {
947  case LS_U_CHAR:
948  LS_DO_WRITE (uint8_t, data, 1, len, os);
949  break;
950 
951  case LS_U_SHORT:
952  LS_DO_WRITE (uint16_t, data, 2, len, os);
953  break;
954 
955  case LS_U_INT:
956  LS_DO_WRITE (uint32_t, data, 4, len, os);
957  break;
958 
959  case LS_CHAR:
960  LS_DO_WRITE (int8_t, data, 1, len, os);
961  break;
962 
963  case LS_SHORT:
964  LS_DO_WRITE (int16_t, data, 2, len, os);
965  break;
966 
967  case LS_INT:
968  LS_DO_WRITE (int32_t, data, 4, len, os);
969  break;
970 
971  case LS_FLOAT: // No conversion necessary.
972  {
973  char tmp_type = static_cast<char> (type);
974  os.write (&tmp_type, 1);
975  std::streamsize n_bytes = 4 * static_cast<std::streamsize> (len);
976  os.write (reinterpret_cast<const char *> (data), n_bytes);
977  }
978  break;
979 
980  case LS_DOUBLE:
981  LS_DO_WRITE (double, data, 8, len, os);
982  break;
983 
984  default:
985  (*current_liboctave_error_handler)
986  ("unrecognized data format requested");
987  break;
988  }
989 }
void swap_bytes< 8 >(void *ptr)
Definition: byte-swap.h:71
void swap_bytes< 4 >(void *ptr)
Definition: byte-swap.h:63
static std::size_t data_type_size(data_type dt)
Definition: data-conv.cc:187
static std::string data_type_as_string(data_type dt)
Definition: data-conv.cc:473
static data_type string_to_data_type(const std::string &s)
Definition: data-conv.cc:293
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)
Definition: data-conv.cc:706
#define LS_DO_READ(TYPE, swap, data, size, len, stream)
Definition: data-conv.cc:580
#define FIND_SIZED_INT_TYPE(VAL, BITS, TQ, Q)
Definition: data-conv.cc:69
#define GET_SIZED_INT_TYPE(T, U)
Definition: data-conv.cc:158
void read_doubles(std::istream &is, double *data, save_type type, octave_idx_type len, bool swap, octave::mach_info::float_format fmt)
Definition: data-conv.cc:776
void write_doubles(std::ostream &os, const double *data, save_type type, octave_idx_type len)
Definition: data-conv.cc:892
void write_floats(std::ostream &os, const float *data, save_type type, octave_idx_type len)
Definition: data-conv.cc:942
#define LS_DO_WRITE(TYPE, data, size, len, stream)
Definition: data-conv.cc:599
void read_floats(std::istream &is, float *data, save_type type, octave_idx_type len, bool swap, octave::mach_info::float_format fmt)
Definition: data-conv.cc:836
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)
Definition: data-conv.cc:659
#define FIND_SIZED_FLOAT_TYPE(VAL, BITS)
Definition: data-conv.cc:87
save_type
Definition: data-conv.h:87
@ LS_U_CHAR
Definition: data-conv.h:88
@ LS_DOUBLE
Definition: data-conv.h:95
@ LS_U_SHORT
Definition: data-conv.h:89
@ LS_FLOAT
Definition: data-conv.h:94
@ LS_SHORT
Definition: data-conv.h:92
@ LS_CHAR
Definition: data-conv.h:91
@ LS_INT
Definition: data-conv.h:93
@ LS_U_INT
Definition: data-conv.h:90
OCTAVE_NORETURN liboctave_error_handler current_liboctave_error_handler
Definition: lo-error.c:41
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d
float_format
Definition: mach-info.h:38
@ flt_fmt_ieee_big_endian
Definition: mach-info.h:44
@ flt_fmt_ieee_little_endian
Definition: mach-info.h:43
octave_idx_type n
Definition: mx-inlines.cc:761
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
Definition: oct-locbuf.h:44
F77_RET_T len
Definition: xerbla.cc:61