data-conv.cc

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 1996-2012 John W. Eaton
00004 
00005 This file is part of Octave.
00006 
00007 Octave is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 Octave is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Octave; see the file COPYING.  If not, see
00019 <http://www.gnu.org/licenses/>.
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 // I'm not sure it is worth the trouble, but let's use a lookup table
00095 // for the types that are supposed to be a specific number of bits
00096 // wide.  Given the macros above, this should work as long as CHAR_BIT
00097 // is a multiple of 8 and there are types with the right sizes.
00098 //
00099 // The sized data type lookup table has the following format:
00100 //
00101 //                            bits
00102 //                    +----+----+----+----+
00103 //                    |  8 | 16 | 32 | 64 |
00104 //                    +----+----+----+----+
00105 //     signed integer |    |    |    |    |
00106 //                    +----+----+----+----+
00107 //   unsigned integer |    |    |    |    |
00108 //                    +----+----+----+----+
00109 //     floating point |    |    |    |    |
00110 //                    +----+----+----+----+
00111 //
00112 // So, the 0,3 element is supposed to contain the oct_data_conv enum
00113 // value corresponding to the correct native data type for a signed
00114 // 32-bit integer.
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 // Have to use copy here to avoid writing over data accessed via
00499 // Matrix::data().
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 // Loading variables from files.
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 // But first, some data conversion routines.
00533 
00534 // Currently, we only handle conversions for the IEEE types.  To fix
00535 // that, make more of the following routines work.
00536 
00537 // FIXME -- assumes sizeof (Complex) == 8
00538 // FIXME -- assumes sizeof (double) == 8
00539 // FIXME -- assumes sizeof (float) == 4
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 * /* d */, octave_idx_type /* len */)
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 * /* d */, octave_idx_type /* len */)
00555 {
00556   gripe_data_conversion ("VAX G float", "IEEE little endian format");
00557 }
00558 
00559 static void
00560 Cray_to_IEEE_little_double (void * /* d */, octave_idx_type /* len */)
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 * /* d */, octave_idx_type /* len */)
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 * /* d */, octave_idx_type /* len */)
00579 {
00580   gripe_data_conversion ("VAX G float", "IEEE little endian format");
00581 }
00582 
00583 static void
00584 Cray_to_IEEE_little_float (void * /* d */, octave_idx_type /* len */)
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 * /* d */, octave_idx_type /* len */)
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 * /* d */, octave_idx_type /* len */)
00603 {
00604   gripe_data_conversion ("VAX G float", "IEEE big endian format");
00605 }
00606 
00607 static void
00608 Cray_to_IEEE_big_double (void * /* d */, octave_idx_type /* len */)
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 * /* d */, octave_idx_type /* len */)
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 * /* d */, octave_idx_type /* len */)
00627 {
00628   gripe_data_conversion ("VAX G float", "IEEE big endian format");
00629 }
00630 
00631 static void
00632 Cray_to_IEEE_big_float (void * /* d */, octave_idx_type /* len */)
00633 {
00634   gripe_data_conversion ("Cray", "IEEE big endian format");
00635 }
00636 
00637 static void
00638 IEEE_little_double_to_VAX_D_double (void * /* d */, octave_idx_type /* len */)
00639 {
00640   gripe_data_conversion ("IEEE little endian", "VAX D");
00641 }
00642 
00643 static void
00644 IEEE_big_double_to_VAX_D_double (void * /* d */, octave_idx_type /* len */)
00645 {
00646   gripe_data_conversion ("IEEE big endian", "VAX D");
00647 }
00648 
00649 static void
00650 VAX_G_double_to_VAX_D_double (void * /* d */, octave_idx_type /* len */)
00651 {
00652   gripe_data_conversion ("VAX G float", "VAX D");
00653 }
00654 
00655 static void
00656 Cray_to_VAX_D_double (void * /* d */, octave_idx_type /* len */)
00657 {
00658   gripe_data_conversion ("Cray", "VAX D");
00659 }
00660 
00661 static void
00662 IEEE_little_float_to_VAX_D_float (void * /* d */, octave_idx_type /* len */)
00663 {
00664   gripe_data_conversion ("IEEE little endian", "VAX D");
00665 }
00666 
00667 static void
00668 IEEE_big_float_to_VAX_D_float (void * /* d */, octave_idx_type /* len */)
00669 {
00670   gripe_data_conversion ("IEEE big endian", "VAX D");
00671 }
00672 
00673 static void
00674 VAX_G_float_to_VAX_D_float (void * /* d */, octave_idx_type /* len */)
00675 {
00676   gripe_data_conversion ("VAX G float", "VAX D");
00677 }
00678 
00679 static void
00680 Cray_to_VAX_D_float (void * /* d */, octave_idx_type /* len */)
00681 {
00682   gripe_data_conversion ("Cray", "VAX D");
00683 }
00684 
00685 static void
00686 IEEE_little_double_to_VAX_G_double (void * /* d */, octave_idx_type /* len */)
00687 {
00688   gripe_data_conversion ("IEEE little endian", "VAX G");
00689 }
00690 
00691 static void
00692 IEEE_big_double_to_VAX_G_double (void * /* d */, octave_idx_type /* len */)
00693 {
00694   gripe_data_conversion ("IEEE big endian", "VAX G");
00695 }
00696 
00697 static void
00698 VAX_D_double_to_VAX_G_double (void * /* d */, octave_idx_type /* len */)
00699 {
00700   gripe_data_conversion ("VAX D float", "VAX G");
00701 }
00702 
00703 static void
00704 Cray_to_VAX_G_double (void * /* d */, octave_idx_type /* len */)
00705 {
00706   gripe_data_conversion ("VAX G float", "VAX G");
00707 }
00708 
00709 static void
00710 IEEE_little_float_to_VAX_G_float (void * /* d */, octave_idx_type /* len */)
00711 {
00712   gripe_data_conversion ("IEEE little endian", "VAX G");
00713 }
00714 
00715 static void
00716 IEEE_big_float_to_VAX_G_float (void * /* d */, octave_idx_type /* len */)
00717 {
00718   gripe_data_conversion ("IEEE big endian", "VAX G");
00719 }
00720 
00721 static void
00722 VAX_D_float_to_VAX_G_float (void * /* d */, octave_idx_type /* len */)
00723 {
00724   gripe_data_conversion ("VAX D float", "VAX G");
00725 }
00726 
00727 static void
00728 Cray_to_VAX_G_float (void * /* d */, octave_idx_type /* len */)
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: // No conversion necessary.
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: // No conversion necessary.
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: // No conversion necessary.
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: // No conversion necessary.
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 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines