00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026
00027 #include <cctype>
00028 #include <cstdlib>
00029
00030 #include <iostream>
00031 #include <vector>
00032
00033 #include "byte-swap.h"
00034 #include "data-conv.h"
00035 #include "lo-error.h"
00036 #include "lo-ieee.h"
00037 #include "oct-locbuf.h"
00038
00039 template void swap_bytes<2> (volatile void *, int);
00040 template void swap_bytes<4> (volatile void *, int);
00041 template void swap_bytes<8> (volatile void *, int);
00042
00043 #if defined HAVE_LONG_LONG_INT
00044 #define FIND_SIZED_INT_TYPE(VAL, BITS, TQ, Q) \
00045 do \
00046 { \
00047 int sz = BITS / CHAR_BIT; \
00048 if (sizeof (TQ char) == sz) \
00049 VAL = oct_data_conv::dt_ ## Q ## char; \
00050 else if (sizeof (TQ short) == sz) \
00051 VAL = oct_data_conv::dt_ ## Q ## short; \
00052 else if (sizeof (TQ int) == sz) \
00053 VAL = oct_data_conv::dt_ ## Q ## int; \
00054 else if (sizeof (TQ long) == sz) \
00055 VAL = oct_data_conv::dt_ ## Q ## long; \
00056 else if (sizeof (TQ long long) == sz) \
00057 VAL = oct_data_conv::dt_ ## Q ## longlong; \
00058 else \
00059 VAL = oct_data_conv::dt_unknown; \
00060 } \
00061 while (0)
00062 #else
00063 #define FIND_SIZED_INT_TYPE(VAL, BITS, TQ, Q) \
00064 do \
00065 { \
00066 int sz = BITS / CHAR_BIT; \
00067 if (sizeof (TQ char) == sz) \
00068 VAL = oct_data_conv::dt_ ## Q ## char; \
00069 else if (sizeof (TQ short) == sz) \
00070 VAL = oct_data_conv::dt_ ## Q ## short; \
00071 else if (sizeof (TQ int) == sz) \
00072 VAL = oct_data_conv::dt_ ## Q ## int; \
00073 else if (sizeof (TQ long) == sz) \
00074 VAL = oct_data_conv::dt_ ## Q ## long; \
00075 else \
00076 VAL = oct_data_conv::dt_unknown; \
00077 } \
00078 while (0)
00079 #endif
00080
00081 #define FIND_SIZED_FLOAT_TYPE(VAL, BITS) \
00082 do \
00083 { \
00084 int sz = BITS / CHAR_BIT; \
00085 if (sizeof (float) == sz) \
00086 VAL = oct_data_conv::dt_float; \
00087 else if (sizeof (double) == sz) \
00088 VAL = oct_data_conv::dt_double; \
00089 else \
00090 VAL = oct_data_conv::dt_unknown; \
00091 } \
00092 while (0)
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 static void
00117 init_sized_type_lookup_table (oct_data_conv::data_type table[3][4])
00118 {
00119 int bits = 8;
00120
00121 for (int i = 0; i < 4; i++)
00122 {
00123 FIND_SIZED_INT_TYPE (table[0][i], bits, , );
00124
00125 FIND_SIZED_INT_TYPE (table[1][i], bits, unsigned, u);
00126
00127 FIND_SIZED_FLOAT_TYPE (table[2][i], bits);
00128
00129 bits *= 2;
00130 }
00131 }
00132
00133 static std::string
00134 strip_spaces (const std::string& str)
00135 {
00136 size_t n = str.length ();
00137
00138 size_t k = 0;
00139
00140 std::string s (n, ' ');
00141
00142 for (size_t i = 0; i < n; i++)
00143 if (! isspace (str[i]))
00144 s[k++] = tolower (str[i]);
00145
00146 s.resize (k);
00147
00148 return s;
00149 }
00150
00151 #define GET_SIZED_INT_TYPE(T, U) \
00152 do \
00153 { \
00154 switch (sizeof (T)) \
00155 { \
00156 case 1: \
00157 retval = dt_ ## U ## int8; \
00158 break; \
00159 \
00160 case 2: \
00161 retval = dt_ ## U ## int16; \
00162 break; \
00163 \
00164 case 4: \
00165 retval = dt_ ## U ## int32; \
00166 break; \
00167 \
00168 case 8: \
00169 retval = dt_ ## U ## int64; \
00170 break; \
00171 \
00172 default: \
00173 retval = dt_unknown; \
00174 break; \
00175 } \
00176 } \
00177 while (0)
00178
00179 oct_data_conv::data_type
00180 oct_data_conv::string_to_data_type (const std::string& str)
00181 {
00182 data_type retval = dt_unknown;
00183
00184 static bool initialized = false;
00185
00186 static data_type sized_type_table[3][4];
00187
00188 if (! initialized)
00189 {
00190 init_sized_type_lookup_table (sized_type_table);
00191
00192 initialized = true;
00193 }
00194
00195 std::string s = strip_spaces (str);
00196
00197 if (s == "int8" || s == "integer*1")
00198 retval = dt_int8;
00199 else if (s == "uint8")
00200 retval = dt_uint8;
00201 else if (s == "int16" || s == "integer*2")
00202 retval = dt_int16;
00203 else if (s == "uint16")
00204 retval = dt_uint16;
00205 else if (s == "int32" || s == "integer*4")
00206 retval = dt_int32;
00207 else if (s == "uint32")
00208 retval = dt_uint32;
00209 else if (s == "int64" || s == "integer*8")
00210 retval = dt_int64;
00211 else if (s == "uint64")
00212 retval = dt_uint64;
00213 else if (s == "single" || s == "float32" || s == "real*4")
00214 retval = dt_single;
00215 else if (s == "double" || s == "float64" || s == "real*8")
00216 retval = dt_double;
00217 else if (s == "char" || s == "char*1")
00218 retval = dt_char;
00219 else if (s == "schar" || s == "signedchar")
00220 retval = dt_schar;
00221 else if (s == "uchar" || s == "unsignedchar")
00222 retval = dt_uchar;
00223 else if (s == "short")
00224 GET_SIZED_INT_TYPE (short, );
00225 else if (s == "ushort" || s == "unsignedshort")
00226 GET_SIZED_INT_TYPE (unsigned short, u);
00227 else if (s == "int")
00228 GET_SIZED_INT_TYPE (int, );
00229 else if (s == "uint" || s == "unsignedint")
00230 GET_SIZED_INT_TYPE (unsigned int, u);
00231 else if (s == "long")
00232 GET_SIZED_INT_TYPE (long, );
00233 else if (s == "ulong" || s == "unsignedlong")
00234 GET_SIZED_INT_TYPE (unsigned long, u);
00235 else if (s == "longlong")
00236 GET_SIZED_INT_TYPE (long long, );
00237 else if (s == "ulonglong" || s == "unsignedlonglong")
00238 GET_SIZED_INT_TYPE (unsigned long long, u);
00239 else if (s == "float")
00240 {
00241 if (sizeof (float) == sizeof (double))
00242 retval = dt_double;
00243 else
00244 retval = dt_single;
00245 }
00246 else if (s == "logical")
00247 retval = dt_logical;
00248 else
00249 (*current_liboctave_error_handler) ("invalid data type specified");
00250
00251 if (retval == dt_unknown)
00252 (*current_liboctave_error_handler)
00253 ("unable to find matching native data type for %s", s.c_str ());
00254
00255 return retval;
00256 }
00257
00258 void
00259 oct_data_conv::string_to_data_type
00260 (const std::string& str, int& block_size,
00261 oct_data_conv::data_type& input_type,
00262 oct_data_conv::data_type& output_type)
00263 {
00264 block_size = 1;
00265 input_type = dt_uchar;
00266 output_type = dt_double;
00267
00268 bool input_is_output = false;
00269
00270 std::string s = strip_spaces (str);
00271
00272 size_t pos = 0;
00273
00274 if (s[0] == '*')
00275 input_is_output = true;
00276 else
00277 {
00278 size_t len = s.length ();
00279
00280 while (pos < len && isdigit (s[pos]))
00281 pos++;
00282
00283 if (pos > 0)
00284 {
00285 if (s[pos] == '*')
00286 {
00287 block_size = atoi (s.c_str ());
00288 s = s.substr (pos+1);
00289 }
00290 else
00291 {
00292 (*current_liboctave_error_handler)
00293 ("invalid repeat count in '%s'", str.c_str ());
00294
00295 return;
00296 }
00297 }
00298 }
00299
00300 pos = s.find ('=');
00301
00302 if (pos != std::string::npos)
00303 {
00304 if (s[pos+1] == '>')
00305 {
00306 std::string s1;
00307
00308 if (input_is_output)
00309 {
00310 input_is_output = false;
00311
00312 s1 = s.substr (1, pos-1);
00313
00314 (*current_liboctave_warning_handler)
00315 ("warning: ignoring leading * in fread precision");
00316 }
00317 else
00318 s1 = s.substr (0, pos);
00319
00320 input_type = string_to_data_type (s1);
00321 output_type = string_to_data_type (s.substr (pos+2));
00322 }
00323 else
00324 (*current_liboctave_error_handler)
00325 ("fread: invalid precision specified");
00326 }
00327 else
00328 {
00329 if (input_is_output)
00330 s = s.substr (1);
00331
00332 input_type = string_to_data_type (s);
00333
00334 if (input_is_output)
00335 output_type = input_type;
00336 }
00337 }
00338
00339 void
00340 oct_data_conv::string_to_data_type
00341 (const std::string& str, int& block_size,
00342 oct_data_conv::data_type& output_type)
00343 {
00344 block_size = 1;
00345 output_type = dt_double;
00346
00347 std::string s = strip_spaces (str);
00348
00349 size_t pos = 0;
00350
00351 size_t len = s.length ();
00352
00353 while (pos < len && isdigit (s[pos]))
00354 pos++;
00355
00356 if (pos > 0)
00357 {
00358 if (s[pos] == '*')
00359 {
00360 block_size = atoi (s.c_str ());
00361 s = s.substr (pos+1);
00362 }
00363 else
00364 {
00365 (*current_liboctave_error_handler)
00366 ("invalid repeat count in '%s'", str.c_str ());
00367
00368 return;
00369 }
00370 }
00371
00372 output_type = string_to_data_type (s);
00373 }
00374
00375 std::string
00376 oct_data_conv::data_type_as_string (oct_data_conv::data_type dt)
00377 {
00378 std::string retval;
00379
00380 switch (dt)
00381 {
00382 case oct_data_conv::dt_int8:
00383 retval = "int8";
00384 break;
00385
00386 case oct_data_conv::dt_uint8:
00387 retval = "uint8";
00388 break;
00389
00390 case oct_data_conv::dt_int16:
00391 retval = "int16";
00392 break;
00393
00394 case oct_data_conv::dt_uint16:
00395 retval = "uint16";
00396 break;
00397
00398 case oct_data_conv::dt_int32:
00399 retval = "int32";
00400 break;
00401
00402 case oct_data_conv::dt_uint32:
00403 retval = "uint32";
00404 break;
00405
00406 case oct_data_conv::dt_int64:
00407 retval = "int64";
00408 break;
00409
00410 case oct_data_conv::dt_uint64:
00411 retval = "uint64";
00412 break;
00413
00414 case oct_data_conv::dt_single:
00415 retval = "single";
00416 break;
00417
00418 case oct_data_conv::dt_double:
00419 retval = "double";
00420 break;
00421
00422 case oct_data_conv::dt_char:
00423 retval = "char";
00424 break;
00425
00426 case oct_data_conv::dt_schar:
00427 retval = "signed char";
00428 break;
00429
00430 case oct_data_conv::dt_uchar:
00431 retval = "usigned char";
00432 break;
00433
00434 case oct_data_conv::dt_short:
00435 retval = "short";
00436 break;
00437
00438 case oct_data_conv::dt_ushort:
00439 retval = "unsigned short";
00440 break;
00441
00442 case oct_data_conv::dt_int:
00443 retval = "int";
00444 break;
00445
00446 case oct_data_conv::dt_uint:
00447 retval = "usigned int";
00448 break;
00449
00450 case oct_data_conv::dt_long:
00451 retval = "long";
00452 break;
00453
00454 case oct_data_conv::dt_ulong:
00455 retval = "usigned long";
00456 break;
00457
00458 case oct_data_conv::dt_longlong:
00459 retval = "long long";
00460 break;
00461
00462 case oct_data_conv::dt_ulonglong:
00463 retval = "unsigned long long";
00464 break;
00465
00466 case oct_data_conv::dt_float:
00467 retval = "float";
00468 break;
00469
00470 case oct_data_conv::dt_logical:
00471 retval = "logical";
00472 break;
00473
00474 case oct_data_conv::dt_unknown:
00475 default:
00476 retval = "unknown";
00477 break;
00478 }
00479
00480 return retval;
00481 }
00482
00483 #define LS_DO_READ(TYPE, swap, data, size, len, stream) \
00484 do \
00485 { \
00486 if (len > 0) \
00487 { \
00488 OCTAVE_LOCAL_BUFFER (TYPE, ptr, len); \
00489 stream.read (reinterpret_cast<char *> (ptr), size * len); \
00490 if (swap) \
00491 swap_bytes< size > (ptr, len); \
00492 for (octave_idx_type i = 0; i < len; i++) \
00493 data[i] = ptr[i]; \
00494 } \
00495 } \
00496 while (0)
00497
00498
00499
00500
00501 #define LS_DO_WRITE(TYPE, data, size, len, stream) \
00502 do \
00503 { \
00504 if (len > 0) \
00505 { \
00506 char tmp_type = type; \
00507 stream.write (&tmp_type, 1); \
00508 OCTAVE_LOCAL_BUFFER (TYPE, ptr, len); \
00509 for (octave_idx_type i = 0; i < len; i++) \
00510 ptr[i] = static_cast <TYPE> (data[i]); \
00511 stream.write (reinterpret_cast<char *> (ptr), size * len); \
00512 } \
00513 } \
00514 while (0)
00515
00516
00517
00518 static void
00519 gripe_unrecognized_float_fmt (void)
00520 {
00521 (*current_liboctave_error_handler)
00522 ("unrecognized floating point format requested");
00523 }
00524
00525 static void
00526 gripe_data_conversion (const char *from, const char *to)
00527 {
00528 (*current_liboctave_error_handler)
00529 ("unable to convert from %s to %s format", from, to);
00530 }
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541 static void
00542 IEEE_big_double_to_IEEE_little_double (void *d, octave_idx_type len)
00543 {
00544 swap_bytes<8> (d, len);
00545 }
00546
00547 static void
00548 VAX_D_double_to_IEEE_little_double (void * , octave_idx_type )
00549 {
00550 gripe_data_conversion ("VAX D float", "IEEE little endian format");
00551 }
00552
00553 static void
00554 VAX_G_double_to_IEEE_little_double (void * , octave_idx_type )
00555 {
00556 gripe_data_conversion ("VAX G float", "IEEE little endian format");
00557 }
00558
00559 static void
00560 Cray_to_IEEE_little_double (void * , octave_idx_type )
00561 {
00562 gripe_data_conversion ("Cray", "IEEE little endian format");
00563 }
00564
00565 static void
00566 IEEE_big_float_to_IEEE_little_float (void *d, octave_idx_type len)
00567 {
00568 swap_bytes<4> (d, len);
00569 }
00570
00571 static void
00572 VAX_D_float_to_IEEE_little_float (void * , octave_idx_type )
00573 {
00574 gripe_data_conversion ("VAX D float", "IEEE little endian format");
00575 }
00576
00577 static void
00578 VAX_G_float_to_IEEE_little_float (void * , octave_idx_type )
00579 {
00580 gripe_data_conversion ("VAX G float", "IEEE little endian format");
00581 }
00582
00583 static void
00584 Cray_to_IEEE_little_float (void * , octave_idx_type )
00585 {
00586 gripe_data_conversion ("Cray", "IEEE little endian format");
00587 }
00588
00589 static void
00590 IEEE_little_double_to_IEEE_big_double (void *d, octave_idx_type len)
00591 {
00592 swap_bytes<8> (d, len);
00593 }
00594
00595 static void
00596 VAX_D_double_to_IEEE_big_double (void * , octave_idx_type )
00597 {
00598 gripe_data_conversion ("VAX D float", "IEEE big endian format");
00599 }
00600
00601 static void
00602 VAX_G_double_to_IEEE_big_double (void * , octave_idx_type )
00603 {
00604 gripe_data_conversion ("VAX G float", "IEEE big endian format");
00605 }
00606
00607 static void
00608 Cray_to_IEEE_big_double (void * , octave_idx_type )
00609 {
00610 gripe_data_conversion ("Cray", "IEEE big endian format");
00611 }
00612
00613 static void
00614 IEEE_little_float_to_IEEE_big_float (void *d, octave_idx_type len)
00615 {
00616 swap_bytes<4> (d, len);
00617 }
00618
00619 static void
00620 VAX_D_float_to_IEEE_big_float (void * , octave_idx_type )
00621 {
00622 gripe_data_conversion ("VAX D float", "IEEE big endian format");
00623 }
00624
00625 static void
00626 VAX_G_float_to_IEEE_big_float (void * , octave_idx_type )
00627 {
00628 gripe_data_conversion ("VAX G float", "IEEE big endian format");
00629 }
00630
00631 static void
00632 Cray_to_IEEE_big_float (void * , octave_idx_type )
00633 {
00634 gripe_data_conversion ("Cray", "IEEE big endian format");
00635 }
00636
00637 static void
00638 IEEE_little_double_to_VAX_D_double (void * , octave_idx_type )
00639 {
00640 gripe_data_conversion ("IEEE little endian", "VAX D");
00641 }
00642
00643 static void
00644 IEEE_big_double_to_VAX_D_double (void * , octave_idx_type )
00645 {
00646 gripe_data_conversion ("IEEE big endian", "VAX D");
00647 }
00648
00649 static void
00650 VAX_G_double_to_VAX_D_double (void * , octave_idx_type )
00651 {
00652 gripe_data_conversion ("VAX G float", "VAX D");
00653 }
00654
00655 static void
00656 Cray_to_VAX_D_double (void * , octave_idx_type )
00657 {
00658 gripe_data_conversion ("Cray", "VAX D");
00659 }
00660
00661 static void
00662 IEEE_little_float_to_VAX_D_float (void * , octave_idx_type )
00663 {
00664 gripe_data_conversion ("IEEE little endian", "VAX D");
00665 }
00666
00667 static void
00668 IEEE_big_float_to_VAX_D_float (void * , octave_idx_type )
00669 {
00670 gripe_data_conversion ("IEEE big endian", "VAX D");
00671 }
00672
00673 static void
00674 VAX_G_float_to_VAX_D_float (void * , octave_idx_type )
00675 {
00676 gripe_data_conversion ("VAX G float", "VAX D");
00677 }
00678
00679 static void
00680 Cray_to_VAX_D_float (void * , octave_idx_type )
00681 {
00682 gripe_data_conversion ("Cray", "VAX D");
00683 }
00684
00685 static void
00686 IEEE_little_double_to_VAX_G_double (void * , octave_idx_type )
00687 {
00688 gripe_data_conversion ("IEEE little endian", "VAX G");
00689 }
00690
00691 static void
00692 IEEE_big_double_to_VAX_G_double (void * , octave_idx_type )
00693 {
00694 gripe_data_conversion ("IEEE big endian", "VAX G");
00695 }
00696
00697 static void
00698 VAX_D_double_to_VAX_G_double (void * , octave_idx_type )
00699 {
00700 gripe_data_conversion ("VAX D float", "VAX G");
00701 }
00702
00703 static void
00704 Cray_to_VAX_G_double (void * , octave_idx_type )
00705 {
00706 gripe_data_conversion ("VAX G float", "VAX G");
00707 }
00708
00709 static void
00710 IEEE_little_float_to_VAX_G_float (void * , octave_idx_type )
00711 {
00712 gripe_data_conversion ("IEEE little endian", "VAX G");
00713 }
00714
00715 static void
00716 IEEE_big_float_to_VAX_G_float (void * , octave_idx_type )
00717 {
00718 gripe_data_conversion ("IEEE big endian", "VAX G");
00719 }
00720
00721 static void
00722 VAX_D_float_to_VAX_G_float (void * , octave_idx_type )
00723 {
00724 gripe_data_conversion ("VAX D float", "VAX G");
00725 }
00726
00727 static void
00728 Cray_to_VAX_G_float (void * , octave_idx_type )
00729 {
00730 gripe_data_conversion ("VAX G float", "VAX G");
00731 }
00732
00733 void
00734 do_double_format_conversion (void *data, octave_idx_type len,
00735 oct_mach_info::float_format from_fmt,
00736 oct_mach_info::float_format to_fmt)
00737 {
00738 switch (to_fmt)
00739 {
00740 case oct_mach_info::flt_fmt_ieee_little_endian:
00741 switch (from_fmt)
00742 {
00743 case oct_mach_info::flt_fmt_ieee_little_endian:
00744 break;
00745
00746 case oct_mach_info::flt_fmt_ieee_big_endian:
00747 IEEE_big_double_to_IEEE_little_double (data, len);
00748 break;
00749
00750 case oct_mach_info::flt_fmt_vax_d:
00751 VAX_D_double_to_IEEE_little_double (data, len);
00752 break;
00753
00754 case oct_mach_info::flt_fmt_vax_g:
00755 VAX_G_double_to_IEEE_little_double (data, len);
00756 break;
00757
00758 case oct_mach_info::flt_fmt_cray:
00759 Cray_to_IEEE_little_double (data, len);
00760 break;
00761
00762 default:
00763 gripe_unrecognized_float_fmt ();
00764 break;
00765 }
00766 break;
00767
00768 case oct_mach_info::flt_fmt_ieee_big_endian:
00769 switch (from_fmt)
00770 {
00771 case oct_mach_info::flt_fmt_ieee_little_endian:
00772 IEEE_little_double_to_IEEE_big_double (data, len);
00773 break;
00774
00775 case oct_mach_info::flt_fmt_ieee_big_endian:
00776 break;
00777
00778 case oct_mach_info::flt_fmt_vax_d:
00779 VAX_D_double_to_IEEE_big_double (data, len);
00780 break;
00781
00782 case oct_mach_info::flt_fmt_vax_g:
00783 VAX_G_double_to_IEEE_big_double (data, len);
00784 break;
00785
00786 case oct_mach_info::flt_fmt_cray:
00787 Cray_to_IEEE_big_double (data, len);
00788 break;
00789
00790 default:
00791 gripe_unrecognized_float_fmt ();
00792 break;
00793 }
00794 break;
00795
00796 case oct_mach_info::flt_fmt_vax_d:
00797 switch (from_fmt)
00798 {
00799 case oct_mach_info::flt_fmt_ieee_little_endian:
00800 IEEE_little_double_to_VAX_D_double (data, len);
00801 break;
00802
00803 case oct_mach_info::flt_fmt_ieee_big_endian:
00804 IEEE_big_double_to_VAX_D_double (data, len);
00805 break;
00806
00807 case oct_mach_info::flt_fmt_vax_d:
00808 break;
00809
00810 case oct_mach_info::flt_fmt_vax_g:
00811 VAX_G_double_to_VAX_D_double (data, len);
00812 break;
00813
00814 case oct_mach_info::flt_fmt_cray:
00815 Cray_to_VAX_D_double (data, len);
00816 break;
00817
00818 default:
00819 gripe_unrecognized_float_fmt ();
00820 break;
00821 }
00822 break;
00823
00824 case oct_mach_info::flt_fmt_vax_g:
00825 switch (from_fmt)
00826 {
00827 case oct_mach_info::flt_fmt_ieee_little_endian:
00828 IEEE_little_double_to_VAX_G_double (data, len);
00829 break;
00830
00831 case oct_mach_info::flt_fmt_ieee_big_endian:
00832 IEEE_big_double_to_VAX_G_double (data, len);
00833 break;
00834
00835 case oct_mach_info::flt_fmt_vax_d:
00836 VAX_D_double_to_VAX_G_double (data, len);
00837 break;
00838
00839 case oct_mach_info::flt_fmt_vax_g:
00840 break;
00841
00842 case oct_mach_info::flt_fmt_cray:
00843 Cray_to_VAX_G_double (data, len);
00844 break;
00845
00846 default:
00847 gripe_unrecognized_float_fmt ();
00848 break;
00849 }
00850 break;
00851
00852 default:
00853 (*current_liboctave_error_handler)
00854 ("impossible state reached in file '%s' at line %d",
00855 __FILE__, __LINE__);
00856 break;
00857 }
00858 }
00859
00860 void
00861 do_float_format_conversion (void *data, octave_idx_type len,
00862 oct_mach_info::float_format from_fmt,
00863 oct_mach_info::float_format to_fmt)
00864 {
00865 switch (to_fmt)
00866 {
00867 case oct_mach_info::flt_fmt_ieee_little_endian:
00868 switch (from_fmt)
00869 {
00870 case oct_mach_info::flt_fmt_ieee_little_endian:
00871 break;
00872
00873 case oct_mach_info::flt_fmt_ieee_big_endian:
00874 IEEE_big_float_to_IEEE_little_float (data, len);
00875 break;
00876
00877 case oct_mach_info::flt_fmt_vax_d:
00878 VAX_D_float_to_IEEE_little_float (data, len);
00879 break;
00880
00881 case oct_mach_info::flt_fmt_vax_g:
00882 VAX_G_float_to_IEEE_little_float (data, len);
00883 break;
00884
00885 case oct_mach_info::flt_fmt_cray:
00886 Cray_to_IEEE_little_float (data, len);
00887 break;
00888
00889 default:
00890 gripe_unrecognized_float_fmt ();
00891 break;
00892 }
00893 break;
00894
00895 case oct_mach_info::flt_fmt_ieee_big_endian:
00896 switch (from_fmt)
00897 {
00898 case oct_mach_info::flt_fmt_ieee_little_endian:
00899 IEEE_little_float_to_IEEE_big_float (data, len);
00900 break;
00901
00902 case oct_mach_info::flt_fmt_ieee_big_endian:
00903 break;
00904
00905 case oct_mach_info::flt_fmt_vax_d:
00906 VAX_D_float_to_IEEE_big_float (data, len);
00907 break;
00908
00909 case oct_mach_info::flt_fmt_vax_g:
00910 VAX_G_float_to_IEEE_big_float (data, len);
00911 break;
00912
00913 case oct_mach_info::flt_fmt_cray:
00914 Cray_to_IEEE_big_float (data, len);
00915 break;
00916
00917 default:
00918 gripe_unrecognized_float_fmt ();
00919 break;
00920 }
00921 break;
00922
00923 case oct_mach_info::flt_fmt_vax_d:
00924 switch (from_fmt)
00925 {
00926 case oct_mach_info::flt_fmt_ieee_little_endian:
00927 IEEE_little_float_to_VAX_D_float (data, len);
00928 break;
00929
00930 case oct_mach_info::flt_fmt_ieee_big_endian:
00931 IEEE_big_float_to_VAX_D_float (data, len);
00932 break;
00933
00934 case oct_mach_info::flt_fmt_vax_d:
00935 break;
00936
00937 case oct_mach_info::flt_fmt_vax_g:
00938 VAX_G_float_to_VAX_D_float (data, len);
00939 break;
00940
00941 case oct_mach_info::flt_fmt_cray:
00942 Cray_to_VAX_D_float (data, len);
00943 break;
00944
00945 default:
00946 gripe_unrecognized_float_fmt ();
00947 break;
00948 }
00949 break;
00950
00951 case oct_mach_info::flt_fmt_vax_g:
00952 switch (from_fmt)
00953 {
00954 case oct_mach_info::flt_fmt_ieee_little_endian:
00955 IEEE_little_float_to_VAX_G_float (data, len);
00956 break;
00957
00958 case oct_mach_info::flt_fmt_ieee_big_endian:
00959 IEEE_big_float_to_VAX_G_float (data, len);
00960 break;
00961
00962 case oct_mach_info::flt_fmt_vax_d:
00963 VAX_D_float_to_VAX_G_float (data, len);
00964 break;
00965
00966 case oct_mach_info::flt_fmt_vax_g:
00967 break;
00968
00969 case oct_mach_info::flt_fmt_cray:
00970 Cray_to_VAX_G_float (data, len);
00971 break;
00972
00973 default:
00974 gripe_unrecognized_float_fmt ();
00975 break;
00976 }
00977 break;
00978
00979 default:
00980 (*current_liboctave_error_handler)
00981 ("impossible state reached in file '%s' at line %d",
00982 __FILE__, __LINE__);
00983 break;
00984 }
00985 }
00986
00987 void
00988 do_float_format_conversion (void *data, size_t sz, octave_idx_type len,
00989 oct_mach_info::float_format from_fmt,
00990 oct_mach_info::float_format to_fmt)
00991 {
00992 switch (sz)
00993 {
00994 case sizeof (float):
00995 do_float_format_conversion (data, len, from_fmt, to_fmt);
00996 break;
00997
00998 case sizeof (double):
00999 do_double_format_conversion (data, len, from_fmt, to_fmt);
01000 break;
01001
01002 default:
01003 (*current_liboctave_error_handler)
01004 ("impossible state reached in file '%s' at line %d",
01005 __FILE__, __LINE__);
01006 break;
01007 }
01008 }
01009
01010
01011 void
01012 read_doubles (std::istream& is, double *data, save_type type,
01013 octave_idx_type len, bool swap,
01014 oct_mach_info::float_format fmt)
01015 {
01016 switch (type)
01017 {
01018 case LS_U_CHAR:
01019 LS_DO_READ (uint8_t, swap, data, 1, len, is);
01020 break;
01021
01022 case LS_U_SHORT:
01023 LS_DO_READ (uint16_t, swap, data, 2, len, is);
01024 break;
01025
01026 case LS_U_INT:
01027 LS_DO_READ (uint32_t, swap, data, 4, len, is);
01028 break;
01029
01030 case LS_CHAR:
01031 LS_DO_READ (int8_t, swap, data, 1, len, is);
01032 break;
01033
01034 case LS_SHORT:
01035 LS_DO_READ (int16_t, swap, data, 2, len, is);
01036 break;
01037
01038 case LS_INT:
01039 LS_DO_READ (int32_t, swap, data, 4, len, is);
01040 break;
01041
01042 case LS_FLOAT:
01043 {
01044 OCTAVE_LOCAL_BUFFER (float, ptr, len);
01045 is.read (reinterpret_cast<char *> (ptr), 4 * len);
01046 do_float_format_conversion (ptr, len, fmt);
01047 for (octave_idx_type i = 0; i < len; i++)
01048 data[i] = ptr[i];
01049 }
01050 break;
01051
01052 case LS_DOUBLE:
01053 {
01054 is.read (reinterpret_cast<char *> (data), 8 * len);
01055 do_double_format_conversion (data, len, fmt);
01056
01057 for (int i = 0; i < len; i++)
01058 data[i] = __lo_ieee_replace_old_NA (data[i]);
01059 }
01060 break;
01061
01062 default:
01063 is.clear (std::ios::failbit|is.rdstate ());
01064 break;
01065 }
01066 }
01067
01068 void
01069 read_floats (std::istream& is, float *data, save_type type,
01070 octave_idx_type len, bool swap,
01071 oct_mach_info::float_format fmt)
01072 {
01073 switch (type)
01074 {
01075 case LS_U_CHAR:
01076 LS_DO_READ (uint8_t, swap, data, 1, len, is);
01077 break;
01078
01079 case LS_U_SHORT:
01080 LS_DO_READ (uint16_t, swap, data, 2, len, is);
01081 break;
01082
01083 case LS_U_INT:
01084 LS_DO_READ (uint32_t, swap, data, 4, len, is);
01085 break;
01086
01087 case LS_CHAR:
01088 LS_DO_READ (int8_t, swap, data, 1, len, is);
01089 break;
01090
01091 case LS_SHORT:
01092 LS_DO_READ (int16_t, swap, data, 2, len, is);
01093 break;
01094
01095 case LS_INT:
01096 LS_DO_READ (int32_t, swap, data, 4, len, is);
01097 break;
01098
01099 case LS_FLOAT:
01100 is.read (reinterpret_cast<char *> (data), 4 * len);
01101 do_float_format_conversion (data, len, fmt);
01102 break;
01103
01104 case LS_DOUBLE:
01105 {
01106 OCTAVE_LOCAL_BUFFER (double, ptr, len);
01107 is.read (reinterpret_cast<char *> (ptr), 8 * len);
01108 do_double_format_conversion (ptr, len, fmt);
01109 for (octave_idx_type i = 0; i < len; i++)
01110 data[i] = ptr[i];
01111 }
01112 break;
01113
01114 default:
01115 is.clear (std::ios::failbit|is.rdstate ());
01116 break;
01117 }
01118 }
01119
01120 void
01121 write_doubles (std::ostream& os, const double *data, save_type type,
01122 octave_idx_type len)
01123 {
01124 switch (type)
01125 {
01126 case LS_U_CHAR:
01127 LS_DO_WRITE (uint8_t, data, 1, len, os);
01128 break;
01129
01130 case LS_U_SHORT:
01131 LS_DO_WRITE (uint16_t, data, 2, len, os);
01132 break;
01133
01134 case LS_U_INT:
01135 LS_DO_WRITE (uint32_t, data, 4, len, os);
01136 break;
01137
01138 case LS_CHAR:
01139 LS_DO_WRITE (int8_t, data, 1, len, os);
01140 break;
01141
01142 case LS_SHORT:
01143 LS_DO_WRITE (int16_t, data, 2, len, os);
01144 break;
01145
01146 case LS_INT:
01147 LS_DO_WRITE (int32_t, data, 4, len, os);
01148 break;
01149
01150 case LS_FLOAT:
01151 LS_DO_WRITE (float, data, 4, len, os);
01152 break;
01153
01154 case LS_DOUBLE:
01155 {
01156 char tmp_type = static_cast<char> (type);
01157 os.write (&tmp_type, 1);
01158 os.write (reinterpret_cast <const char *> (data), 8 * len);
01159 }
01160 break;
01161
01162 default:
01163 (*current_liboctave_error_handler)
01164 ("unrecognized data format requested");
01165 break;
01166 }
01167 }
01168
01169 void
01170 write_floats (std::ostream& os, const float *data, save_type type,
01171 octave_idx_type len)
01172 {
01173 switch (type)
01174 {
01175 case LS_U_CHAR:
01176 LS_DO_WRITE (uint8_t, data, 1, len, os);
01177 break;
01178
01179 case LS_U_SHORT:
01180 LS_DO_WRITE (uint16_t, data, 2, len, os);
01181 break;
01182
01183 case LS_U_INT:
01184 LS_DO_WRITE (uint32_t, data, 4, len, os);
01185 break;
01186
01187 case LS_CHAR:
01188 LS_DO_WRITE (int8_t, data, 1, len, os);
01189 break;
01190
01191 case LS_SHORT:
01192 LS_DO_WRITE (int16_t, data, 2, len, os);
01193 break;
01194
01195 case LS_INT:
01196 LS_DO_WRITE (int32_t, data, 4, len, os);
01197 break;
01198
01199 case LS_FLOAT:
01200 {
01201 char tmp_type = static_cast<char> (type);
01202 os.write (&tmp_type, 1);
01203 os.write (reinterpret_cast <const char *> (data), 4 * len);
01204 }
01205 break;
01206
01207 case LS_DOUBLE:
01208 LS_DO_WRITE (double, data, 8, len, os);
01209 break;
01210
01211 default:
01212 (*current_liboctave_error_handler)
01213 ("unrecognized data format requested");
01214 break;
01215 }
01216 }