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