Home | History | Annotate | Download | only in IlmImf
      1 ///////////////////////////////////////////////////////////////////////////
      2 //
      3 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
      4 // Digital Ltd. LLC
      5 //
      6 // All rights reserved.
      7 //
      8 // Redistribution and use in source and binary forms, with or without
      9 // modification, are permitted provided that the following conditions are
     10 // met:
     11 // *       Redistributions of source code must retain the above copyright
     12 // notice, this list of conditions and the following disclaimer.
     13 // *       Redistributions in binary form must reproduce the above
     14 // copyright notice, this list of conditions and the following disclaimer
     15 // in the documentation and/or other materials provided with the
     16 // distribution.
     17 // *       Neither the name of Industrial Light & Magic nor the names of
     18 // its contributors may be used to endorse or promote products derived
     19 // from this software without specific prior written permission.
     20 //
     21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32 //
     33 ///////////////////////////////////////////////////////////////////////////
     34 
     35 
     36 #ifndef INCLUDED_IMF_XDR_H
     37 #define INCLUDED_IMF_XDR_H
     38 
     39 //----------------------------------------------------------------------------
     40 //
     41 //	Xdr -- routines to convert data between the machine's native
     42 //	format and a machine-independent external data representation:
     43 //
     44 //	    write<R> (T &o, S v);	converts a value, v, of type S
     45 //					into a machine-independent
     46 //					representation and stores the
     47 //					result in an output buffer, o.
     48 //
     49 //	    read<R> (T &i, S &v);	reads the machine-independent
     50 //					representation of a value of type
     51 //					S from input buffer i, converts
     52 //					the value into the machine's native
     53 //					representation, and stores the result
     54 //					in v.
     55 //
     56 //	    size<S>();			returns the size, in bytes, of the
     57 //					machine-independent representation
     58 //					of an object of type S.
     59 //
     60 //	The write() and read() routines are templates; data can be written
     61 //	to and read from any output or input buffer type T for which a helper
     62 //	class, R, exits.  Class R must define a method to store a char array
     63 //	in a T, and a method to read a char array from a T:
     64 //
     65 //	    struct R
     66 //	    {
     67 //	        static void
     68 //	        writeChars (T &o, const char c[/*n*/], int n)
     69 //	        {
     70 //	            ... // Write c[0], c[1] ... c[n-1] to output buffer o.
     71 //	        }
     72 //
     73 //	        static void
     74 //	        readChars (T &i, char c[/*n*/], int n)
     75 //	        {
     76 //	            ... // Read n characters from input buffer i
     77 //		        // and copy them to c[0], c[1] ... c[n-1].
     78 //	        }
     79 //	    };
     80 //
     81 //	Example - writing to and reading from iostreams:
     82 //
     83 //	    struct CharStreamIO
     84 //	    {
     85 //	        static void
     86 //	        writeChars (ostream &os, const char c[], int n)
     87 //	        {
     88 //	            os.write (c, n);
     89 //	        }
     90 //
     91 //	        static void
     92 //	        readChars (istream &is, char c[], int n)
     93 //	        {
     94 //	            is.read (c, n);
     95 //	        }
     96 //	    };
     97 //
     98 //          ...
     99 //
    100 //	    Xdr::write<CharStreamIO> (os, 3);
    101 //	    Xdr::write<CharStreamIO> (os, 5.0);
    102 //
    103 //----------------------------------------------------------------------------
    104 
    105 #include <ImfInt64.h>
    106 #include "IexMathExc.h"
    107 #include "half.h"
    108 #include <limits.h>
    109 
    110 namespace Imf {
    111 namespace Xdr {
    112 
    113 
    114 //-------------------------------
    115 // Write data to an output stream
    116 //-------------------------------
    117 
    118 template <class S, class T>
    119 void
    120 write (T &out, bool v);
    121 
    122 template <class S, class T>
    123 void
    124 write (T &out, char v);
    125 
    126 template <class S, class T>
    127 void
    128 write (T &out, signed char v);
    129 
    130 template <class S, class T>
    131 void
    132 write (T &out, unsigned char v);
    133 
    134 template <class S, class T>
    135 void
    136 write (T &out, signed short v);
    137 
    138 template <class S, class T>
    139 void
    140 write (T &out, unsigned short v);
    141 
    142 template <class S, class T>
    143 void
    144 write (T &out, signed int v);
    145 
    146 template <class S, class T>
    147 void
    148 write (T &out, unsigned int v);
    149 
    150 template <class S, class T>
    151 void
    152 write (T &out, signed long v);
    153 
    154 template <class S, class T>
    155 void
    156 write (T &out, unsigned long v);
    157 
    158 #if ULONG_MAX != 18446744073709551615LU
    159 
    160     template <class S, class T>
    161     void
    162     write (T &out, Int64 v);
    163 
    164 #endif
    165 
    166 template <class S, class T>
    167 void
    168 write (T &out, float v);
    169 
    170 template <class S, class T>
    171 void
    172 write (T &out, double v);
    173 
    174 template <class S, class T>
    175 void
    176 write (T &out, half v);
    177 
    178 template <class S, class T>
    179 void
    180 write (T &out, const char v[/*n*/], int n);	// fixed-size char array
    181 
    182 template <class S, class T>
    183 void
    184 write (T &out, const char v[]);			// zero-terminated string
    185 
    186 
    187 //-----------------------------------------
    188 // Append padding bytes to an output stream
    189 //-----------------------------------------
    190 
    191 template <class S, class T>
    192 void
    193 pad (T &out, int n);				// write n padding bytes
    194 
    195 
    196 
    197 //-------------------------------
    198 // Read data from an input stream
    199 //-------------------------------
    200 
    201 template <class S, class T>
    202 void
    203 read (T &in, bool &v);
    204 
    205 template <class S, class T>
    206 void
    207 read (T &in, char &v);
    208 
    209 template <class S, class T>
    210 void
    211 read (T &in, signed char &v);
    212 
    213 template <class S, class T>
    214 void
    215 read (T &in, unsigned char &v);
    216 
    217 template <class S, class T>
    218 void
    219 read (T &in, signed short &v);
    220 
    221 template <class S, class T>
    222 void
    223 read (T &in, unsigned short &v);
    224 
    225 template <class S, class T>
    226 void
    227 read (T &in, signed int &v);
    228 
    229 template <class S, class T>
    230 void
    231 read (T &in, unsigned int &v);
    232 
    233 template <class S, class T>
    234 void
    235 read (T &in, signed long &v);
    236 
    237 template <class S, class T>
    238 void
    239 read (T &in, unsigned long &v);
    240 
    241 #if ULONG_MAX != 18446744073709551615LU
    242 
    243     template <class S, class T>
    244     void
    245     read (T &in, Int64 &v);
    246 
    247 #endif
    248 
    249 template <class S, class T>
    250 void
    251 read (T &in, float &v);
    252 
    253 template <class S, class T>
    254 void
    255 read (T &in, double &v);
    256 
    257 template <class S, class T>
    258 void
    259 read (T &in, half &v);
    260 
    261 template <class S, class T>
    262 void
    263 read (T &in, char v[/*n*/], int n);		// fixed-size char array
    264 
    265 template <class S, class T>
    266 void
    267 read (T &in, int n, char v[/*n*/]);		// zero-terminated string
    268 
    269 
    270 //-------------------------------------------
    271 // Skip over padding bytes in an input stream
    272 //-------------------------------------------
    273 
    274 template <class S, class T>
    275 void
    276 skip (T &in, int n);				// skip n padding bytes
    277 
    278 
    279 
    280 //--------------------------------------
    281 // Size of the machine-independent
    282 // representation of an object of type S
    283 //--------------------------------------
    284 
    285 template <class S>
    286 int
    287 size ();
    288 
    289 
    290 //---------------
    291 // Implementation
    292 //---------------
    293 
    294 template <class S, class T>
    295 inline void
    296 writeSignedChars (T &out, const signed char c[], int n)
    297 {
    298     S::writeChars (out, (const char *) c, n);
    299 }
    300 
    301 
    302 template <class S, class T>
    303 inline void
    304 writeUnsignedChars (T &out, const unsigned char c[], int n)
    305 {
    306     S::writeChars (out, (const char *) c, n);
    307 }
    308 
    309 
    310 template <class S, class T>
    311 inline void
    312 readSignedChars (T &in, signed char c[], int n)
    313 {
    314     S::readChars (in, (char *) c, n);
    315 }
    316 
    317 
    318 template <class S, class T>
    319 inline void
    320 readUnsignedChars (T &in, unsigned char c[], int n)
    321 {
    322     S::readChars (in, (char *) c, n);
    323 }
    324 
    325 
    326 template <class S, class T>
    327 inline void
    328 write (T &out, bool v)
    329 {
    330     char c = !!v;
    331     S::writeChars (out, &c, 1);
    332 }
    333 
    334 
    335 template <class S, class T>
    336 inline void
    337 write (T &out, char v)
    338 {
    339     S::writeChars (out, &v, 1);
    340 }
    341 
    342 
    343 template <class S, class T>
    344 inline void
    345 write (T &out, signed char v)
    346 {
    347     writeSignedChars<S> (out, &v, 1);
    348 }
    349 
    350 
    351 template <class S, class T>
    352 inline void
    353 write (T &out, unsigned char v)
    354 {
    355     writeUnsignedChars<S> (out, &v, 1);
    356 }
    357 
    358 
    359 template <class S, class T>
    360 void
    361 write (T &out, signed short v)
    362 {
    363     signed char b[2];
    364 
    365     b[0] =  (signed char) (v);
    366     b[1] =  (signed char) (v >> 8);
    367 
    368     writeSignedChars<S> (out, b, 2);
    369 }
    370 
    371 
    372 template <class S, class T>
    373 void
    374 write (T &out, unsigned short v)
    375 {
    376     unsigned char b[2];
    377 
    378     b[0] =  (unsigned char) (v);
    379     b[1] =  (unsigned char) (v >> 8);
    380 
    381     writeUnsignedChars<S> (out, b, 2);
    382 }
    383 
    384 
    385 template <class S, class T>
    386 void
    387 write (T &out, signed int v)
    388 {
    389     signed char b[4];
    390 
    391     b[0] =  (signed char) (v);
    392     b[1] =  (signed char) (v >> 8);
    393     b[2] =  (signed char) (v >> 16);
    394     b[3] =  (signed char) (v >> 24);
    395 
    396     writeSignedChars<S> (out, b, 4);
    397 }
    398 
    399 
    400 template <class S, class T>
    401 void
    402 write (T &out, unsigned int v)
    403 {
    404     unsigned char b[4];
    405 
    406     b[0] =  (unsigned char) (v);
    407     b[1] =  (unsigned char) (v >> 8);
    408     b[2] =  (unsigned char) (v >> 16);
    409     b[3] =  (unsigned char) (v >> 24);
    410 
    411     writeUnsignedChars<S> (out, b, 4);
    412 }
    413 
    414 
    415 template <class S, class T>
    416 void
    417 write (T &out, signed long v)
    418 {
    419     signed char b[8];
    420 
    421     b[0] = (signed char) (v);
    422     b[1] = (signed char) (v >> 8);
    423     b[2] = (signed char) (v >> 16);
    424     b[3] = (signed char) (v >> 24);
    425 
    426     #if LONG_MAX == 2147483647
    427 
    428     if (v >= 0)
    429     {
    430         b[4] = 0;
    431         b[5] = 0;
    432         b[6] = 0;
    433         b[7] = 0;
    434     }
    435     else
    436     {
    437         b[4] = ~0;
    438         b[5] = ~0;
    439         b[6] = ~0;
    440         b[7] = ~0;
    441     }
    442 
    443     #elif LONG_MAX == 9223372036854775807L
    444 
    445     b[4] = (signed char) (v >> 32);
    446     b[5] = (signed char) (v >> 40);
    447     b[6] = (signed char) (v >> 48);
    448     b[7] = (signed char) (v >> 56);
    449 
    450     #else
    451 
    452     #error write<T> (T &out, signed long v) not implemented
    453 
    454     #endif
    455 
    456     writeSignedChars<S> (out, b, 8);
    457 }
    458 
    459 
    460 template <class S, class T>
    461 void
    462 write (T &out, unsigned long v)
    463 {
    464     unsigned char b[8];
    465 
    466     b[0] = (unsigned char) (v);
    467     b[1] = (unsigned char) (v >> 8);
    468     b[2] = (unsigned char) (v >> 16);
    469     b[3] = (unsigned char) (v >> 24);
    470 
    471     #if ULONG_MAX == 4294967295U
    472 
    473     b[4] = 0;
    474     b[5] = 0;
    475     b[6] = 0;
    476     b[7] = 0;
    477 
    478     #elif ULONG_MAX == 18446744073709551615LU
    479 
    480     b[4] = (unsigned char) (v >> 32);
    481     b[5] = (unsigned char) (v >> 40);
    482     b[6] = (unsigned char) (v >> 48);
    483     b[7] = (unsigned char) (v >> 56);
    484 
    485     #else
    486 
    487     #error write<T> (T &out, unsigned long v) not implemented
    488 
    489     #endif
    490 
    491     writeUnsignedChars<S> (out, b, 8);
    492 }
    493 
    494 
    495 #if ULONG_MAX != 18446744073709551615LU
    496 
    497     template <class S, class T>
    498     void
    499     write (T &out, Int64 v)
    500     {
    501         unsigned char b[8];
    502 
    503         b[0] = (unsigned char) (v);
    504         b[1] = (unsigned char) (v >> 8);
    505         b[2] = (unsigned char) (v >> 16);
    506         b[3] = (unsigned char) (v >> 24);
    507         b[4] = (unsigned char) (v >> 32);
    508         b[5] = (unsigned char) (v >> 40);
    509         b[6] = (unsigned char) (v >> 48);
    510         b[7] = (unsigned char) (v >> 56);
    511 
    512         writeUnsignedChars<S> (out, b, 8);
    513     }
    514 
    515 #endif
    516 
    517 
    518 template <class S, class T>
    519 void
    520 write (T &out, float v)
    521 {
    522     union {unsigned int i; float f;} u;
    523     u.f = v;
    524 
    525     unsigned char b[4];
    526 
    527     b[0] = (unsigned char) (u.i);
    528     b[1] = (unsigned char) (u.i >> 8);
    529     b[2] = (unsigned char) (u.i >> 16);
    530     b[3] = (unsigned char) (u.i >> 24);
    531 
    532     writeUnsignedChars<S> (out, b, 4);
    533 }
    534 
    535 
    536 template <class S, class T>
    537 void
    538 write (T &out, double v)
    539 {
    540     union {Int64 i; double d;} u;
    541     u.d = v;
    542 
    543     unsigned char b[8];
    544 
    545     b[0] = (unsigned char) (u.i);
    546     b[1] = (unsigned char) (u.i >> 8);
    547     b[2] = (unsigned char) (u.i >> 16);
    548     b[3] = (unsigned char) (u.i >> 24);
    549     b[4] = (unsigned char) (u.i >> 32);
    550     b[5] = (unsigned char) (u.i >> 40);
    551     b[6] = (unsigned char) (u.i >> 48);
    552     b[7] = (unsigned char) (u.i >> 56);
    553 
    554     writeUnsignedChars<S> (out, b, 8);
    555 }
    556 
    557 
    558 template <class S, class T>
    559 inline void
    560 write (T &out, half v)
    561 {
    562     unsigned char b[2];
    563 
    564     b[0] =  (unsigned char) (v.bits());
    565     b[1] =  (unsigned char) (v.bits() >> 8);
    566 
    567     writeUnsignedChars<S> (out, b, 2);
    568 }
    569 
    570 
    571 template <class S, class T>
    572 inline void
    573 write (T &out, const char v[], int n)	// fixed-size char array
    574 {
    575     S::writeChars (out, v, n);
    576 }
    577 
    578 
    579 template <class S, class T>
    580 void
    581 write (T &out, const char v[])		// zero-terminated string
    582 {
    583     while (*v)
    584     {
    585     S::writeChars (out, v, 1);
    586     ++v;
    587     }
    588 
    589     S::writeChars (out, v, 1);
    590 }
    591 
    592 
    593 template <class S, class T>
    594 void
    595 pad (T &out, int n)			// add n padding bytes
    596 {
    597     for (int i = 0; i < n; i++)
    598     {
    599     const char c = 0;
    600     S::writeChars (out, &c, 1);
    601     }
    602 }
    603 
    604 
    605 template <class S, class T>
    606 inline void
    607 read (T &in, bool &v)
    608 {
    609     char c;
    610 
    611     S::readChars (in, &c, 1);
    612     v = !!c;
    613 }
    614 
    615 
    616 template <class S, class T>
    617 inline void
    618 read (T &in, char &v)
    619 {
    620     S::readChars (in, &v, 1);
    621 }
    622 
    623 
    624 template <class S, class T>
    625 inline void
    626 read (T &in, signed char &v)
    627 {
    628     readSignedChars<S> (in, &v, 1);
    629 }
    630 
    631 
    632 template <class S, class T>
    633 inline void
    634 read (T &in, unsigned char &v)
    635 {
    636     readUnsignedChars<S> (in, &v, 1);
    637 }
    638 
    639 
    640 template <class S, class T>
    641 void
    642 read (T &in, signed short &v)
    643 {
    644     signed char b[2];
    645 
    646     readSignedChars<S> (in, b, 2);
    647 
    648     v = (b[0] & 0x00ff) |
    649     (b[1] << 8);
    650 }
    651 
    652 
    653 template <class S, class T>
    654 void
    655 read (T &in, unsigned short &v)
    656 {
    657     unsigned char b[2];
    658 
    659     readUnsignedChars<S> (in, b, 2);
    660 
    661     v = (b[0] & 0x00ff) |
    662     (b[1] << 8);
    663 }
    664 
    665 
    666 template <class S, class T>
    667 void
    668 read (T &in, signed int &v)
    669 {
    670     signed char b[4];
    671 
    672     readSignedChars<S> (in, b, 4);
    673 
    674     v =  (b[0]        & 0x000000ff) |
    675     ((b[1] << 8)  & 0x0000ff00) |
    676     ((b[2] << 16) & 0x00ff0000) |
    677      (b[3] << 24);
    678 }
    679 
    680 
    681 template <class S, class T>
    682 void
    683 read (T &in, unsigned int &v)
    684 {
    685     unsigned char b[4];
    686 
    687     readUnsignedChars<S> (in, b, 4);
    688 
    689     v =  (b[0]        & 0x000000ff) |
    690     ((b[1] << 8)  & 0x0000ff00) |
    691     ((b[2] << 16) & 0x00ff0000) |
    692      (b[3] << 24);
    693 }
    694 
    695 
    696 template <class S, class T>
    697 void
    698 read (T &in, signed long &v)
    699 {
    700     signed char b[8];
    701 
    702     readSignedChars<S> (in, b, 8);
    703 
    704     #if LONG_MAX == 2147483647
    705 
    706     v =  (b[0]        & 0x000000ff) |
    707         ((b[1] << 8)  & 0x0000ff00) |
    708         ((b[2] << 16) & 0x00ff0000) |
    709          (b[3] << 24);
    710 
    711     if (( b[4] ||  b[5] ||  b[6] ||  b[7]) &&
    712         (~b[4] || ~b[5] || ~b[6] || ~b[7]))
    713     {
    714         throw Iex::OverflowExc ("Long int overflow - read a large "
    715                     "64-bit integer in a 32-bit process.");
    716     }
    717 
    718     #elif LONG_MAX == 9223372036854775807L
    719 
    720     v =  ((long) b[0]        & 0x00000000000000ff) |
    721         (((long) b[1] << 8)  & 0x000000000000ff00) |
    722         (((long) b[2] << 16) & 0x0000000000ff0000) |
    723         (((long) b[3] << 24) & 0x00000000ff000000) |
    724         (((long) b[4] << 32) & 0x000000ff00000000) |
    725         (((long) b[5] << 40) & 0x0000ff0000000000) |
    726         (((long) b[6] << 48) & 0x00ff000000000000) |
    727          ((long) b[7] << 56);
    728 
    729     #else
    730 
    731     #error read<T> (T &in, signed long &v) not implemented
    732 
    733     #endif
    734 }
    735 
    736 
    737 template <class S, class T>
    738 void
    739 read (T &in, unsigned long &v)
    740 {
    741     unsigned char b[8];
    742 
    743     readUnsignedChars<S> (in, b, 8);
    744 
    745     #if ULONG_MAX == 4294967295U
    746 
    747     v =  (b[0]        & 0x000000ff) |
    748         ((b[1] << 8)  & 0x0000ff00) |
    749         ((b[2] << 16) & 0x00ff0000) |
    750          (b[3] << 24);
    751 
    752     if (b[4] || b[5] || b[6] || b[7])
    753     {
    754         throw Iex::OverflowExc ("Long int overflow - read a large "
    755                     "64-bit integer in a 32-bit process.");
    756     }
    757 
    758     #elif ULONG_MAX == 18446744073709551615LU
    759 
    760     v =  ((unsigned long) b[0]        & 0x00000000000000ff) |
    761         (((unsigned long) b[1] << 8)  & 0x000000000000ff00) |
    762         (((unsigned long) b[2] << 16) & 0x0000000000ff0000) |
    763         (((unsigned long) b[3] << 24) & 0x00000000ff000000) |
    764         (((unsigned long) b[4] << 32) & 0x000000ff00000000) |
    765         (((unsigned long) b[5] << 40) & 0x0000ff0000000000) |
    766         (((unsigned long) b[6] << 48) & 0x00ff000000000000) |
    767          ((unsigned long) b[7] << 56);
    768 
    769     #else
    770 
    771     #error read<T> (T &in, unsigned long &v) not implemented
    772 
    773     #endif
    774 }
    775 
    776 
    777 #if ULONG_MAX != 18446744073709551615LU
    778 
    779     template <class S, class T>
    780     void
    781     read (T &in, Int64 &v)
    782     {
    783         unsigned char b[8];
    784 
    785         readUnsignedChars<S> (in, b, 8);
    786 
    787         v =  ((Int64) b[0]        & 0x00000000000000ffLL) |
    788         (((Int64) b[1] << 8)  & 0x000000000000ff00LL) |
    789         (((Int64) b[2] << 16) & 0x0000000000ff0000LL) |
    790         (((Int64) b[3] << 24) & 0x00000000ff000000LL) |
    791         (((Int64) b[4] << 32) & 0x000000ff00000000LL) |
    792         (((Int64) b[5] << 40) & 0x0000ff0000000000LL) |
    793         (((Int64) b[6] << 48) & 0x00ff000000000000LL) |
    794         ((Int64) b[7] << 56);
    795     }
    796 
    797 #endif
    798 
    799 
    800 template <class S, class T>
    801 void
    802 read (T &in, float &v)
    803 {
    804     unsigned char b[4];
    805 
    806     readUnsignedChars<S> (in, b, 4);
    807 
    808     union {unsigned int i; float f;} u;
    809 
    810     u.i = (b[0]        & 0x000000ff) |
    811      ((b[1] << 8)  & 0x0000ff00) |
    812      ((b[2] << 16) & 0x00ff0000) |
    813       (b[3] << 24);
    814 
    815     v = u.f;
    816 }
    817 
    818 
    819 template <class S, class T>
    820 void
    821 read (T &in, double &v)
    822 {
    823     unsigned char b[8];
    824 
    825     readUnsignedChars<S> (in, b, 8);
    826 
    827     union {Int64 i; double d;} u;
    828 
    829     u.i = ((Int64) b[0]        & 0x00000000000000ffULL) |
    830      (((Int64) b[1] << 8)  & 0x000000000000ff00ULL) |
    831      (((Int64) b[2] << 16) & 0x0000000000ff0000ULL) |
    832      (((Int64) b[3] << 24) & 0x00000000ff000000ULL) |
    833      (((Int64) b[4] << 32) & 0x000000ff00000000ULL) |
    834      (((Int64) b[5] << 40) & 0x0000ff0000000000ULL) |
    835      (((Int64) b[6] << 48) & 0x00ff000000000000ULL) |
    836       ((Int64) b[7] << 56);
    837 
    838     v = u.d;
    839 }
    840 
    841 
    842 template <class S, class T>
    843 inline void
    844 read (T &in, half &v)
    845 {
    846     unsigned char b[2];
    847 
    848     readUnsignedChars<S> (in, b, 2);
    849 
    850     v.setBits ((b[0] & 0x00ff) | (b[1] << 8));
    851 }
    852 
    853 
    854 template <class S, class T>
    855 inline void
    856 read (T &in, char v[], int n)		// fixed-size char array
    857 {
    858     S::readChars (in, v, n);
    859 }
    860 
    861 
    862 template <class S, class T>
    863 void
    864 read (T &in, int n, char v[])		// zero-terminated string
    865 {
    866     while (n >= 0)
    867     {
    868     S::readChars (in, v, 1);
    869 
    870     if (*v == 0)
    871         break;
    872 
    873     --n;
    874     ++v;
    875     }
    876 }
    877 
    878 
    879 template <class S, class T>
    880 void
    881 skip (T &in, int n)			// skip n padding bytes
    882 {
    883     char c[1024];
    884 
    885     while (n >= (int) sizeof (c))
    886     {
    887     if (!S::readChars (in, c, sizeof (c)))
    888         return;
    889 
    890     n -= sizeof (c);
    891     }
    892 
    893     if (n >= 1)
    894     S::readChars (in, c, n);
    895 }
    896 
    897 
    898 template <> inline int size <bool> ()			{return 1;}
    899 template <> inline int size <char> ()			{return 1;}
    900 template <> inline int size <signed char> ()		{return 1;}
    901 template <> inline int size <unsigned char> ()		{return 1;}
    902 template <> inline int size <signed short> ()		{return 2;}
    903 template <> inline int size <unsigned short> ()		{return 2;}
    904 template <> inline int size <signed int> ()		{return 4;}
    905 template <> inline int size <unsigned int> ()		{return 4;}
    906 template <> inline int size <signed long> ()		{return 8;}
    907 template <> inline int size <unsigned long> ()		{return 8;}
    908 template <> inline int size <float> ()			{return 4;}
    909 template <> inline int size <double> ()			{return 8;}
    910 template <> inline int size <half> ()			{return 2;}
    911 
    912 
    913 } // namespace Xdr
    914 } // namespace Imf
    915 
    916 #endif
    917