GNU Octave 10.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
data-conv.cc
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 1996-2025 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
123static void
124init_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
140static std::string
141strip_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
186std::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
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
366void
367oct_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 try
395 {
396 block_size = std::stoi (s);
397 s = s.substr (pos+1);
398 }
399 catch (const std::invalid_argument&)
400 {
401 (*current_liboctave_error_handler)
402 ("invalid repeat count in '%s'", s.c_str ());
403 }
404 catch (const std::out_of_range&)
405 {
406 (*current_liboctave_error_handler)
407 ("repeat count out of range in '%s'", s.c_str ());
408 }
409 }
410 else
412 ("invalid repeat count in '%s'", str.c_str ());
413 }
414 }
415
416 pos = s.find ('=');
417
418 if (pos != std::string::npos)
419 {
420 if (s[pos+1] == '>')
421 {
422 std::string s1;
423
424 if (input_is_output)
425 {
426 s1 = s.substr (1, pos-1);
427
428 (*current_liboctave_warning_with_id_handler)
429 ("Octave:fread-precision-syntax",
430 "warning: ignoring leading * in fread precision");
431 }
432 else
433 s1 = s.substr (0, pos);
434
435 input_type = string_to_data_type (s1);
436 output_type = string_to_data_type (s.substr (pos+2));
437 }
438 else
440 ("fread: invalid precision specified");
441 }
442 else
443 {
444 if (input_is_output)
445 s = s.substr (1);
446
447 input_type = string_to_data_type (s);
448
449 if (input_is_output)
450 output_type = input_type;
451 }
452}
453
454void
455oct_data_conv::string_to_data_type (const std::string& str, int& block_size,
456 oct_data_conv::data_type& output_type)
457{
458 block_size = 1;
459 output_type = dt_double;
460
461 std::string s = strip_spaces (str);
462
463 std::size_t pos = 0;
464
465 std::size_t len = s.length ();
466
467 while (pos < len && isdigit (s[pos]))
468 pos++;
469
470 if (pos > 0)
471 {
472 if (s[pos] == '*')
473 {
474 try
475 {
476 block_size = std::stoi (s);
477 s = s.substr (pos+1);
478 }
479 catch (const std::invalid_argument&)
480 {
481 (*current_liboctave_error_handler)
482 ("invalid repeat count in '%s'", s.c_str ());
483 }
484 catch (const std::out_of_range&)
485 {
486 (*current_liboctave_error_handler)
487 ("repeat count out of range in '%s'", s.c_str ());
488 }
489 }
490 else
492 ("invalid repeat count in '%s'", str.c_str ());
493 }
494
495 output_type = string_to_data_type (s);
496}
497
498std::string
500{
501 std::string retval;
502
503 switch (dt)
504 {
506 retval = "int8";
507 break;
508
510 retval = "uint8";
511 break;
512
514 retval = "int16";
515 break;
516
518 retval = "uint16";
519 break;
520
522 retval = "int32";
523 break;
524
526 retval = "uint32";
527 break;
528
530 retval = "int64";
531 break;
532
534 retval = "uint64";
535 break;
536
538 retval = "single";
539 break;
540
542 retval = "double";
543 break;
544
546 retval = "char";
547 break;
548
550 retval = "signed char";
551 break;
552
554 retval = "unsigned char";
555 break;
556
558 retval = "short";
559 break;
560
562 retval = "unsigned short";
563 break;
564
566 retval = "int";
567 break;
568
570 retval = "unsigned int";
571 break;
572
574 retval = "long";
575 break;
576
578 retval = "unsigned long";
579 break;
580
582 retval = "long long";
583 break;
584
586 retval = "unsigned long long";
587 break;
588
590 retval = "float";
591 break;
592
594 retval = "logical";
595 break;
596
598 default:
599 retval = "unknown";
600 break;
601 }
602
603 return retval;
604}
605
606#define LS_DO_READ(TYPE, swap, data, size, len, stream) \
607 do \
608 { \
609 if (len > 0) \
610 { \
611 OCTAVE_LOCAL_BUFFER (TYPE, ptr, len); \
612 std::streamsize n_bytes = size * static_cast<std::streamsize> (len); \
613 stream.read (reinterpret_cast<char *> (ptr), n_bytes); \
614 if (swap) \
615 swap_bytes< size > (ptr, len); \
616 for (octave_idx_type i = 0; i < len; i++) \
617 data[i] = ptr[i]; \
618 } \
619 } \
620 while (0)
621
622// Have to use copy here to avoid writing over data accessed via
623// Matrix::data ().
624
625#define LS_DO_WRITE(TYPE, data, size, len, stream) \
626 do \
627 { \
628 if (len > 0) \
629 { \
630 char tmp_type = type; \
631 stream.write (&tmp_type, 1); \
632 OCTAVE_LOCAL_BUFFER (TYPE, ptr, len); \
633 for (octave_idx_type i = 0; i < len; i++) \
634 ptr[i] = static_cast<TYPE> (data[i]); \
635 std::streamsize n_bytes = size * static_cast<std::streamsize> (len); \
636 stream.write (reinterpret_cast<char *> (ptr), n_bytes); \
637 } \
638 } \
639 while (0)
640
641// Loading variables from files.
642
643OCTAVE_NORETURN static
644void
645err_unrecognized_float_fmt ()
646{
647 (*current_liboctave_error_handler)
648 ("unrecognized floating point format requested");
649}
650
651// But first, some data conversion routines.
652
653// Currently, we only handle conversions for the IEEE types. To fix
654// that, make more of the following routines work.
655
656// FIXME: assumes sizeof (Complex) == 8
657// FIXME: assumes sizeof (double) == 8
658// FIXME: assumes sizeof (float) == 4
659
660static void
661IEEE_big_double_to_IEEE_little_double (void *d, octave_idx_type len)
662{
664}
665
666static void
667IEEE_big_float_to_IEEE_little_float (void *d, octave_idx_type len)
668{
670}
671
672static void
673IEEE_little_double_to_IEEE_big_double (void *d, octave_idx_type len)
674{
676}
677
678static void
679IEEE_little_float_to_IEEE_big_float (void *d, octave_idx_type len)
680{
682}
683
684void
686 octave::mach_info::float_format from_fmt,
687 octave::mach_info::float_format to_fmt)
688{
689 switch (to_fmt)
690 {
691 case octave::mach_info::flt_fmt_ieee_little_endian:
692 switch (from_fmt)
693 {
694 case octave::mach_info::flt_fmt_ieee_little_endian:
695 break;
696
697 case octave::mach_info::flt_fmt_ieee_big_endian:
698 IEEE_big_double_to_IEEE_little_double (data, len);
699 break;
700
701 default:
702 err_unrecognized_float_fmt ();
703 break;
704 }
705 break;
706
707 case octave::mach_info::flt_fmt_ieee_big_endian:
708 switch (from_fmt)
709 {
710 case octave::mach_info::flt_fmt_ieee_little_endian:
711 IEEE_little_double_to_IEEE_big_double (data, len);
712 break;
713
714 case octave::mach_info::flt_fmt_ieee_big_endian:
715 break;
716
717 default:
718 err_unrecognized_float_fmt ();
719 break;
720 }
721 break;
722
723 default:
724 (*current_liboctave_error_handler)
725 ("impossible state reached in file '%s' at line %d",
726 __FILE__, __LINE__);
727 break;
728 }
729}
730
731void
733 octave::mach_info::float_format from_fmt,
734 octave::mach_info::float_format to_fmt)
735{
736 switch (to_fmt)
737 {
738 case octave::mach_info::flt_fmt_ieee_little_endian:
739 switch (from_fmt)
740 {
741 case octave::mach_info::flt_fmt_ieee_little_endian:
742 break;
743
744 case octave::mach_info::flt_fmt_ieee_big_endian:
745 IEEE_big_float_to_IEEE_little_float (data, len);
746 break;
747
748 default:
749 err_unrecognized_float_fmt ();
750 break;
751 }
752 break;
753
754 case octave::mach_info::flt_fmt_ieee_big_endian:
755 switch (from_fmt)
756 {
757 case octave::mach_info::flt_fmt_ieee_little_endian:
758 IEEE_little_float_to_IEEE_big_float (data, len);
759 break;
760
761 case octave::mach_info::flt_fmt_ieee_big_endian:
762 break;
763
764 default:
765 err_unrecognized_float_fmt ();
766 break;
767 }
768 break;
769
770 default:
771 (*current_liboctave_error_handler)
772 ("impossible state reached in file '%s' at line %d",
773 __FILE__, __LINE__);
774 break;
775 }
776}
777
778void
779do_float_format_conversion (void *data, std::size_t sz, octave_idx_type len,
780 octave::mach_info::float_format from_fmt,
781 octave::mach_info::float_format to_fmt)
782{
783 switch (sz)
784 {
785 case sizeof (float):
786 do_float_format_conversion (data, len, from_fmt, to_fmt);
787 break;
788
789 case sizeof (double):
790 do_double_format_conversion (data, len, from_fmt, to_fmt);
791 break;
792
793 default:
794 (*current_liboctave_error_handler)
795 ("impossible state reached in file '%s' at line %d",
796 __FILE__, __LINE__);
797 break;
798 }
799}
800
801void
802read_doubles (std::istream& is, double *data, save_type type,
803 octave_idx_type len, bool swap,
804 octave::mach_info::float_format fmt)
805{
806 switch (type)
807 {
808 case LS_U_CHAR:
809 LS_DO_READ (uint8_t, swap, data, 1, len, is);
810 break;
811
812 case LS_U_SHORT:
813 LS_DO_READ (uint16_t, swap, data, 2, len, is);
814 break;
815
816 case LS_U_INT:
817 LS_DO_READ (uint32_t, swap, data, 4, len, is);
818 break;
819
820 case LS_CHAR:
821 LS_DO_READ (int8_t, swap, data, 1, len, is);
822 break;
823
824 case LS_SHORT:
825 LS_DO_READ (int16_t, swap, data, 2, len, is);
826 break;
827
828 case LS_INT:
829 LS_DO_READ (int32_t, swap, data, 4, len, is);
830 break;
831
832 case LS_FLOAT:
833 {
834 OCTAVE_LOCAL_BUFFER (float, ptr, len);
835 std::streamsize n_bytes = 4 * static_cast<std::streamsize> (len);
836 is.read (reinterpret_cast<char *> (ptr), n_bytes);
838 for (octave_idx_type i = 0; i < len; i++)
839 data[i] = ptr[i];
840 }
841 break;
842
843 case LS_DOUBLE: // No conversion necessary.
844 {
845 std::streamsize n_bytes = 8 * static_cast<std::streamsize> (len);
846 is.read (reinterpret_cast<char *> (data), n_bytes);
847 do_double_format_conversion (data, len, fmt);
848 // FIXME: Potentially add conversion code for MIPS NA here, Bug #59830.
849 //
850 // for (int i = 0; i < len; i++)
851 // data[i] = __lo_ieee_replace_MIPS_NA (data[i]);
852 }
853 break;
854
855 default:
856 is.clear (std::ios::failbit | is.rdstate ());
857 break;
858 }
859}
860
861void
862read_floats (std::istream& is, float *data, save_type type,
863 octave_idx_type len, bool swap,
864 octave::mach_info::float_format fmt)
865{
866 switch (type)
867 {
868 case LS_U_CHAR:
869 LS_DO_READ (uint8_t, swap, data, 1, len, is);
870 break;
871
872 case LS_U_SHORT:
873 LS_DO_READ (uint16_t, swap, data, 2, len, is);
874 break;
875
876 case LS_U_INT:
877 LS_DO_READ (uint32_t, swap, data, 4, len, is);
878 break;
879
880 case LS_CHAR:
881 LS_DO_READ (int8_t, swap, data, 1, len, is);
882 break;
883
884 case LS_SHORT:
885 LS_DO_READ (int16_t, swap, data, 2, len, is);
886 break;
887
888 case LS_INT:
889 LS_DO_READ (int32_t, swap, data, 4, len, is);
890 break;
891
892 case LS_FLOAT: // No conversion necessary.
893 {
894 std::streamsize n_bytes = 4 * static_cast<std::streamsize> (len);
895 is.read (reinterpret_cast<char *> (data), n_bytes);
896 do_float_format_conversion (data, len, fmt);
897 }
898 break;
899
900 case LS_DOUBLE:
901 {
902 OCTAVE_LOCAL_BUFFER (double, ptr, len);
903 std::streamsize n_bytes = 8 * static_cast<std::streamsize> (len);
904 is.read (reinterpret_cast<char *> (ptr), n_bytes);
906 for (octave_idx_type i = 0; i < len; i++)
907 data[i] = ptr[i];
908 }
909 break;
910
911 default:
912 is.clear (std::ios::failbit | is.rdstate ());
913 break;
914 }
915}
916
917void
918write_doubles (std::ostream& os, const double *data, save_type type,
920{
921 switch (type)
922 {
923 case LS_U_CHAR:
924 LS_DO_WRITE (uint8_t, data, 1, len, os);
925 break;
926
927 case LS_U_SHORT:
928 LS_DO_WRITE (uint16_t, data, 2, len, os);
929 break;
930
931 case LS_U_INT:
932 LS_DO_WRITE (uint32_t, data, 4, len, os);
933 break;
934
935 case LS_CHAR:
936 LS_DO_WRITE (int8_t, data, 1, len, os);
937 break;
938
939 case LS_SHORT:
940 LS_DO_WRITE (int16_t, data, 2, len, os);
941 break;
942
943 case LS_INT:
944 LS_DO_WRITE (int32_t, data, 4, len, os);
945 break;
946
947 case LS_FLOAT:
948 LS_DO_WRITE (float, data, 4, len, os);
949 break;
950
951 case LS_DOUBLE: // No conversion necessary.
952 {
953 char tmp_type = static_cast<char> (type);
954 os.write (&tmp_type, 1);
955 std::streamsize n_bytes = 8 * static_cast<std::streamsize> (len);
956 os.write (reinterpret_cast<const char *> (data), n_bytes);
957 }
958 break;
959
960 default:
961 (*current_liboctave_error_handler)
962 ("unrecognized data format requested");
963 break;
964 }
965}
966
967void
968write_floats (std::ostream& os, const float *data, save_type type,
970{
971 switch (type)
972 {
973 case LS_U_CHAR:
974 LS_DO_WRITE (uint8_t, data, 1, len, os);
975 break;
976
977 case LS_U_SHORT:
978 LS_DO_WRITE (uint16_t, data, 2, len, os);
979 break;
980
981 case LS_U_INT:
982 LS_DO_WRITE (uint32_t, data, 4, len, os);
983 break;
984
985 case LS_CHAR:
986 LS_DO_WRITE (int8_t, data, 1, len, os);
987 break;
988
989 case LS_SHORT:
990 LS_DO_WRITE (int16_t, data, 2, len, os);
991 break;
992
993 case LS_INT:
994 LS_DO_WRITE (int32_t, data, 4, len, os);
995 break;
996
997 case LS_FLOAT: // No conversion necessary.
998 {
999 char tmp_type = static_cast<char> (type);
1000 os.write (&tmp_type, 1);
1001 std::streamsize n_bytes = 4 * static_cast<std::streamsize> (len);
1002 os.write (reinterpret_cast<const char *> (data), n_bytes);
1003 }
1004 break;
1005
1006 case LS_DOUBLE:
1007 LS_DO_WRITE (double, data, 8, len, os);
1008 break;
1009
1010 default:
1011 (*current_liboctave_error_handler)
1012 ("unrecognized data format requested");
1013 break;
1014 }
1015}
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:499
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:732
#define LS_DO_READ(TYPE, swap, data, size, len, stream)
Definition data-conv.cc:606
#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:802
void write_doubles(std::ostream &os, const double *data, save_type type, octave_idx_type len)
Definition data-conv.cc:918
void write_floats(std::ostream &os, const float *data, save_type type, octave_idx_type len)
Definition data-conv.cc:968
#define LS_DO_WRITE(TYPE, data, size, len, stream)
Definition data-conv.cc:625
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:862
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:685
#define FIND_SIZED_FLOAT_TYPE(VAL, BITS)
Definition data-conv.cc:87
save_type
Definition data-conv.h:85
@ LS_U_CHAR
Definition data-conv.h:86
@ LS_DOUBLE
Definition data-conv.h:93
@ LS_U_SHORT
Definition data-conv.h:87
@ LS_FLOAT
Definition data-conv.h:92
@ LS_SHORT
Definition data-conv.h:90
@ LS_CHAR
Definition data-conv.h:89
@ LS_INT
Definition data-conv.h:91
@ LS_U_INT
Definition data-conv.h:88
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
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
Definition oct-locbuf.h:44
F77_RET_T len
Definition xerbla.cc:61