メインページ   クラス階層   構成   ファイル一覧   構成メンバ   ファイルメンバ  

data-conv.cc

解説を見る。
00001 /*
00002 
00003 Copyright (C) 1996, 1997 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 2, or (at your option) any
00010 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, write to the Free
00019 Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
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 // I'm not sure it is worth the trouble, but let's use a lookup table
00087 // for the types that are supposed to be a specific number of bits
00088 // wide.  Given the macros above, this should work as long as CHAR_BIT
00089 // is a multiple of 8 and there are types with the right sizes.
00090 //
00091 // The sized data type lookup table has the following format:
00092 //
00093 //                            bits
00094 //                    +----+----+----+----+
00095 //                    |  8 | 16 | 32 | 64 |
00096 //                    +----+----+----+----+
00097 //     signed integer |    |    |    |    |
00098 //                    +----+----+----+----+
00099 //   unsigned integer |    |    |    |    |
00100 //                    +----+----+----+----+
00101 //     floating point |    |    |    |    |
00102 //                    +----+----+----+----+
00103 //
00104 // So, the 0,3 element is supposed to contain the oct_data_conv enum
00105 // value corresponding to the correct native data type for a signed
00106 // 32-bit integer.
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 // Have to use copy here to avoid writing over data accessed via
00484 // Matrix::data().
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 // Loading variables from files.
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 // But first, some data conversion routines.
00519 
00520 // Currently, we only handle conversions for the IEEE types.  To fix
00521 // that, make more of the following routines work.
00522 
00523 // XXX FIXME XXX -- assumes sizeof (Complex) == 8
00524 // XXX FIXME XXX -- assumes sizeof (double) == 8
00525 // XXX FIXME XXX -- assumes sizeof (float) == 4
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 * /* d */, int /* len */)
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 * /* d */, int /* len */)
00541 {
00542   gripe_data_conversion ("VAX G float", "IEEE little endian format");
00543 }
00544 
00545 static void
00546 Cray_to_IEEE_little_double (void * /* d */, int /* len */)
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 * /* d */, int /* len */)
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 * /* d */, int /* len */)
00565 {
00566   gripe_data_conversion ("VAX G float", "IEEE little endian format");
00567 }
00568 
00569 static void
00570 Cray_to_IEEE_little_float (void * /* d */, int /* len */)
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 * /* d */, int /* len */)
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 * /* d */, int /* len */)
00589 {
00590   gripe_data_conversion ("VAX G float", "IEEE big endian format");
00591 }
00592 
00593 static void
00594 Cray_to_IEEE_big_double (void * /* d */, int /* len */)
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 * /* d */, int /* len */)
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 * /* d */, int /* len */)
00613 {
00614   gripe_data_conversion ("VAX G float", "IEEE big endian format");
00615 }
00616 
00617 static void
00618 Cray_to_IEEE_big_float (void * /* d */, int /* len */)
00619 {
00620   gripe_data_conversion ("Cray", "IEEE big endian format");
00621 }
00622 
00623 static void
00624 IEEE_little_double_to_VAX_D_double (void * /* d */, int /* len */)
00625 {
00626   gripe_data_conversion ("IEEE little endian", "VAX D");
00627 }
00628 
00629 static void
00630 IEEE_big_double_to_VAX_D_double (void * /* d */, int /* len */)
00631 {
00632   gripe_data_conversion ("IEEE big endian", "VAX D");
00633 }
00634 
00635 static void
00636 VAX_G_double_to_VAX_D_double (void * /* d */, int /* len */)
00637 {
00638   gripe_data_conversion ("VAX G float", "VAX D");
00639 }
00640 
00641 static void
00642 Cray_to_VAX_D_double (void * /* d */, int /* len */)
00643 {
00644   gripe_data_conversion ("Cray", "VAX D");
00645 }
00646 
00647 static void
00648 IEEE_little_float_to_VAX_D_float (void * /* d */, int /* len */)
00649 {
00650   gripe_data_conversion ("IEEE little endian", "VAX D");
00651 }
00652 
00653 static void
00654 IEEE_big_float_to_VAX_D_float (void * /* d */, int /* len */)
00655 {
00656   gripe_data_conversion ("IEEE big endian", "VAX D");
00657 }
00658 
00659 static void
00660 VAX_G_float_to_VAX_D_float (void * /* d */, int /* len */)
00661 {
00662   gripe_data_conversion ("VAX G float", "VAX D");
00663 }
00664 
00665 static void
00666 Cray_to_VAX_D_float (void * /* d */, int /* len */)
00667 {
00668   gripe_data_conversion ("Cray", "VAX D");
00669 }
00670 
00671 static void
00672 IEEE_little_double_to_VAX_G_double (void * /* d */, int /* len */)
00673 {
00674   gripe_data_conversion ("IEEE little endian", "VAX G");
00675 }
00676 
00677 static void
00678 IEEE_big_double_to_VAX_G_double (void * /* d */, int /* len */)
00679 {
00680   gripe_data_conversion ("IEEE big endian", "VAX G");
00681 }
00682 
00683 static void
00684 VAX_D_double_to_VAX_G_double (void * /* d */, int /* len */)
00685 {
00686   gripe_data_conversion ("VAX D float", "VAX G");
00687 }
00688 
00689 static void
00690 Cray_to_VAX_G_double (void * /* d */, int /* len */)
00691 {
00692   gripe_data_conversion ("VAX G float", "VAX G");
00693 }
00694 
00695 static void
00696 IEEE_little_float_to_VAX_G_float (void * /* d */, int /* len */)
00697 {
00698   gripe_data_conversion ("IEEE little endian", "VAX G");
00699 }
00700 
00701 static void
00702 IEEE_big_float_to_VAX_G_float (void * /* d */, int /* len */)
00703 {
00704   gripe_data_conversion ("IEEE big endian", "VAX G");
00705 }
00706 
00707 static void
00708 VAX_D_float_to_VAX_G_float (void * /* d */, int /* len */)
00709 {
00710   gripe_data_conversion ("VAX D float", "VAX G");
00711 }
00712 
00713 static void
00714 Cray_to_VAX_G_float (void * /* d */, int /* len */)
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: // No conversion necessary.
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: // No conversion necessary.
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 ;;; Local Variables: ***
01100 ;;; mode: C++ ***
01101 ;;; End: ***
01102 */

Wed Dec 29 11:51:10 2004に生成されました。 doxygen1.2.18
SEO [PR] 爆速!無料ブログ 無料ホームページ開設 無料ライブ放送