PBRT
/home/felix/UBC/projects/AdaptiveLightfieldSampling/pbrt_v2/src/3rdparty/openexr-1.7.0/ImfXdr.h
00001 
00002 //
00003 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
00004 // Digital Ltd. LLC
00005 // 
00006 // All rights reserved.
00007 // 
00008 // Redistribution and use in source and binary forms, with or without
00009 // modification, are permitted provided that the following conditions are
00010 // met:
00011 // *       Redistributions of source code must retain the above copyright
00012 // notice, this list of conditions and the following disclaimer.
00013 // *       Redistributions in binary form must reproduce the above
00014 // copyright notice, this list of conditions and the following disclaimer
00015 // in the documentation and/or other materials provided with the
00016 // distribution.
00017 // *       Neither the name of Industrial Light & Magic nor the names of
00018 // its contributors may be used to endorse or promote products derived
00019 // from this software without specific prior written permission. 
00020 // 
00021 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00024 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00025 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00027 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00028 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00029 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00031 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032 //
00034 
00035 
00036 #ifndef INCLUDED_IMF_XDR_H
00037 #define INCLUDED_IMF_XDR_H
00038 
00039 //----------------------------------------------------------------------------
00040 //
00041 //      Xdr -- routines to convert data between the machine's native
00042 //      format and a machine-independent external data representation:
00043 //
00044 //          write<R> (T &o, S v);       converts a value, v, of type S
00045 //                                      into a machine-independent
00046 //                                      representation and stores the
00047 //                                      result in an output buffer, o.
00048 //
00049 //          read<R> (T &i, S &v);       reads the machine-independent
00050 //                                      representation of a value of type
00051 //                                      S from input buffer i, converts
00052 //                                      the value into the machine's native
00053 //                                      representation, and stores the result
00054 //                                      in v.
00055 //
00056 //          size<S>();                  returns the size, in bytes, of the
00057 //                                      machine-independent representation
00058 //                                      of an object of type S.
00059 //                                      
00060 //      The write() and read() routines are templates; data can be written
00061 //      to and read from any output or input buffer type T for which a helper
00062 //      class, R, exits.  Class R must define a method to store a char array
00063 //      in a T, and a method to read a char array from a T:
00064 //
00065 //          struct R
00066 //          {
00067 //              static void
00068 //              writeChars (T &o, const char c[/*n*/], int n)
00069 //              {
00070 //                  ... // Write c[0], c[1] ... c[n-1] to output buffer o.
00071 //              }
00072 //
00073 //              static void
00074 //              readChars (T &i, char c[/*n*/], int n)
00075 //              {
00076 //                  ... // Read n characters from input buffer i
00077 //                      // and copy them to c[0], c[1] ... c[n-1].
00078 //              }
00079 //          };
00080 //
00081 //      Example - writing to and reading from iostreams:
00082 //
00083 //          struct CharStreamIO
00084 //          {
00085 //              static void
00086 //              writeChars (ostream &os, const char c[], int n)
00087 //              {
00088 //                  os.write (c, n);
00089 //              }
00090 //
00091 //              static void
00092 //              readChars (istream &is, char c[], int n)
00093 //              {
00094 //                  is.read (c, n);
00095 //              }
00096 //          };
00097 //
00098 //          ...
00099 //
00100 //          Xdr::write<CharStreamIO> (os, 3);
00101 //          Xdr::write<CharStreamIO> (os, 5.0);
00102 //
00103 //----------------------------------------------------------------------------
00104 
00105 #include <ImfInt64.h>
00106 #include "IexMathExc.h"
00107 #include "half.h"
00108 #include <limits.h>
00109 
00110 namespace Imf {
00111 namespace Xdr {
00112 
00113 
00114 //-------------------------------
00115 // Write data to an output stream
00116 //-------------------------------
00117 
00118 template <class S, class T>
00119 void
00120 write (T &out, bool v);
00121 
00122 template <class S, class T>
00123 void
00124 write (T &out, char v);
00125 
00126 template <class S, class T>
00127 void
00128 write (T &out, signed char v);
00129 
00130 template <class S, class T>
00131 void
00132 write (T &out, unsigned char v);
00133 
00134 template <class S, class T>
00135 void
00136 write (T &out, signed short v);
00137 
00138 template <class S, class T>
00139 void
00140 write (T &out, unsigned short v);
00141 
00142 template <class S, class T>
00143 void
00144 write (T &out, signed int v);
00145 
00146 template <class S, class T>
00147 void
00148 write (T &out, unsigned int v);
00149 
00150 template <class S, class T>
00151 void
00152 write (T &out, signed long v);
00153 
00154 template <class S, class T>
00155 void
00156 write (T &out, unsigned long v);
00157 
00158 #if ULONG_MAX != 18446744073709551615LU
00159 
00160     template <class S, class T>
00161     void
00162     write (T &out, Int64 v);
00163 
00164 #endif
00165 
00166 template <class S, class T>
00167 void
00168 write (T &out, float v);
00169 
00170 template <class S, class T>
00171 void
00172 write (T &out, double v);
00173 
00174 template <class S, class T>
00175 void
00176 write (T &out, half v);
00177 
00178 template <class S, class T>
00179 void
00180 write (T &out, const char v[/*n*/], int n);     // fixed-size char array
00181 
00182 template <class S, class T>
00183 void
00184 write (T &out, const char v[]);                 // zero-terminated string
00185 
00186 
00187 //-----------------------------------------
00188 // Append padding bytes to an output stream
00189 //-----------------------------------------
00190 
00191 template <class S, class T>
00192 void
00193 pad (T &out, int n);                            // write n padding bytes
00194 
00195 
00196 
00197 //-------------------------------
00198 // Read data from an input stream
00199 //-------------------------------
00200 
00201 template <class S, class T>
00202 void
00203 read (T &in, bool &v);
00204 
00205 template <class S, class T>
00206 void
00207 read (T &in, char &v);
00208 
00209 template <class S, class T>
00210 void
00211 read (T &in, signed char &v);
00212 
00213 template <class S, class T>
00214 void
00215 read (T &in, unsigned char &v);
00216 
00217 template <class S, class T>
00218 void
00219 read (T &in, signed short &v);
00220 
00221 template <class S, class T>
00222 void
00223 read (T &in, unsigned short &v);
00224 
00225 template <class S, class T>
00226 void
00227 read (T &in, signed int &v);
00228 
00229 template <class S, class T>
00230 void
00231 read (T &in, unsigned int &v);
00232 
00233 template <class S, class T>
00234 void
00235 read (T &in, signed long &v);
00236 
00237 template <class S, class T>
00238 void
00239 read (T &in, unsigned long &v);
00240 
00241 #if ULONG_MAX != 18446744073709551615LU
00242 
00243     template <class S, class T>
00244     void
00245     read (T &in, Int64 &v);
00246 
00247 #endif
00248 
00249 template <class S, class T>
00250 void
00251 read (T &in, float &v);
00252 
00253 template <class S, class T>
00254 void
00255 read (T &in, double &v);
00256 
00257 template <class S, class T>
00258 void
00259 read (T &in, half &v);
00260 
00261 template <class S, class T>
00262 void
00263 read (T &in, char v[/*n*/], int n);             // fixed-size char array
00264 
00265 template <class S, class T>
00266 void
00267 read (T &in, int n, char v[/*n*/]);             // zero-terminated string
00268 
00269 
00270 //-------------------------------------------
00271 // Skip over padding bytes in an input stream
00272 //-------------------------------------------
00273 
00274 template <class S, class T>
00275 void
00276 skip (T &in, int n);                            // skip n padding bytes
00277 
00278 
00279 
00280 //--------------------------------------
00281 // Size of the machine-independent
00282 // representation of an object of type S
00283 //--------------------------------------
00284 
00285 template <class S>
00286 int
00287 size ();
00288 
00289 
00290 //---------------
00291 // Implementation
00292 //---------------
00293 
00294 template <class S, class T>
00295 inline void
00296 writeSignedChars (T &out, const signed char c[], int n)
00297 {
00298     S::writeChars (out, (const char *) c, n);
00299 }
00300 
00301 
00302 template <class S, class T>
00303 inline void
00304 writeUnsignedChars (T &out, const unsigned char c[], int n)
00305 {
00306     S::writeChars (out, (const char *) c, n);
00307 }
00308 
00309 
00310 template <class S, class T>
00311 inline void
00312 readSignedChars (T &in, signed char c[], int n)
00313 {
00314     S::readChars (in, (char *) c, n);
00315 }
00316 
00317 
00318 template <class S, class T>
00319 inline void
00320 readUnsignedChars (T &in, unsigned char c[], int n)
00321 {
00322     S::readChars (in, (char *) c, n);
00323 }
00324 
00325 
00326 template <class S, class T>
00327 inline void
00328 write (T &out, bool v)
00329 {
00330     char c = !!v;
00331     S::writeChars (out, &c, 1);
00332 }
00333 
00334 
00335 template <class S, class T>
00336 inline void
00337 write (T &out, char v)
00338 {
00339     S::writeChars (out, &v, 1);
00340 }
00341 
00342 
00343 template <class S, class T>
00344 inline void
00345 write (T &out, signed char v)
00346 {
00347     writeSignedChars<S> (out, &v, 1);
00348 }
00349 
00350 
00351 template <class S, class T>
00352 inline void
00353 write (T &out, unsigned char v)
00354 {
00355     writeUnsignedChars<S> (out, &v, 1);
00356 }
00357 
00358 
00359 template <class S, class T>
00360 void
00361 write (T &out, signed short v)
00362 {
00363     signed char b[2];
00364 
00365     b[0] =  (signed char) (v);
00366     b[1] =  (signed char) (v >> 8);
00367 
00368     writeSignedChars<S> (out, b, 2);
00369 }
00370 
00371 
00372 template <class S, class T>
00373 void
00374 write (T &out, unsigned short v)
00375 {
00376     unsigned char b[2];
00377 
00378     b[0] =  (unsigned char) (v);
00379     b[1] =  (unsigned char) (v >> 8);
00380 
00381     writeUnsignedChars<S> (out, b, 2);
00382 }
00383 
00384 
00385 template <class S, class T>
00386 void
00387 write (T &out, signed int v)
00388 {
00389     signed char b[4];
00390 
00391     b[0] =  (signed char) (v);
00392     b[1] =  (signed char) (v >> 8);
00393     b[2] =  (signed char) (v >> 16);
00394     b[3] =  (signed char) (v >> 24);
00395 
00396     writeSignedChars<S> (out, b, 4);
00397 }
00398 
00399 
00400 template <class S, class T>
00401 void
00402 write (T &out, unsigned int v)
00403 {
00404     unsigned char b[4];
00405 
00406     b[0] =  (unsigned char) (v);
00407     b[1] =  (unsigned char) (v >> 8);
00408     b[2] =  (unsigned char) (v >> 16);
00409     b[3] =  (unsigned char) (v >> 24);
00410 
00411     writeUnsignedChars<S> (out, b, 4);
00412 }
00413 
00414 
00415 template <class S, class T>
00416 void
00417 write (T &out, signed long v)
00418 {
00419     signed char b[8];
00420 
00421     b[0] = (signed char) (v);
00422     b[1] = (signed char) (v >> 8);
00423     b[2] = (signed char) (v >> 16);
00424     b[3] = (signed char) (v >> 24);
00425 
00426     #if LONG_MAX == 2147483647
00427 
00428         if (v >= 0)
00429         {
00430             b[4] = 0;
00431             b[5] = 0;
00432             b[6] = 0;
00433             b[7] = 0;
00434         }
00435         else
00436         {
00437             b[4] = ~0;
00438             b[5] = ~0;
00439             b[6] = ~0;
00440             b[7] = ~0;
00441         }
00442 
00443     #elif LONG_MAX == 9223372036854775807L
00444 
00445         b[4] = (signed char) (v >> 32);
00446         b[5] = (signed char) (v >> 40);
00447         b[6] = (signed char) (v >> 48);
00448         b[7] = (signed char) (v >> 56);
00449 
00450     #else
00451         
00452         #error write<T> (T &out, signed long v) not implemented
00453 
00454     #endif
00455 
00456     writeSignedChars<S> (out, b, 8);
00457 }
00458 
00459 
00460 template <class S, class T>
00461 void
00462 write (T &out, unsigned long v)
00463 {
00464     unsigned char b[8];
00465 
00466     b[0] = (unsigned char) (v);
00467     b[1] = (unsigned char) (v >> 8);
00468     b[2] = (unsigned char) (v >> 16);
00469     b[3] = (unsigned char) (v >> 24);
00470 
00471     #if ULONG_MAX == 4294967295U
00472 
00473         b[4] = 0;
00474         b[5] = 0;
00475         b[6] = 0;
00476         b[7] = 0;
00477 
00478     #elif ULONG_MAX == 18446744073709551615LU
00479 
00480         b[4] = (unsigned char) (v >> 32);
00481         b[5] = (unsigned char) (v >> 40);
00482         b[6] = (unsigned char) (v >> 48);
00483         b[7] = (unsigned char) (v >> 56);
00484 
00485     #else
00486         
00487         #error write<T> (T &out, unsigned long v) not implemented
00488 
00489     #endif
00490 
00491     writeUnsignedChars<S> (out, b, 8);
00492 }
00493 
00494 
00495 #if ULONG_MAX != 18446744073709551615LU
00496 
00497     template <class S, class T>
00498     void
00499     write (T &out, Int64 v)
00500     {
00501         unsigned char b[8];
00502 
00503         b[0] = (unsigned char) (v);
00504         b[1] = (unsigned char) (v >> 8);
00505         b[2] = (unsigned char) (v >> 16);
00506         b[3] = (unsigned char) (v >> 24);
00507         b[4] = (unsigned char) (v >> 32);
00508         b[5] = (unsigned char) (v >> 40);
00509         b[6] = (unsigned char) (v >> 48);
00510         b[7] = (unsigned char) (v >> 56);
00511 
00512         writeUnsignedChars<S> (out, b, 8);
00513     }
00514 
00515 #endif
00516 
00517 
00518 template <class S, class T>
00519 void
00520 write (T &out, float v)
00521 {
00522     union {unsigned int i; float f;} u;
00523     u.f = v;
00524 
00525     unsigned char b[4];
00526 
00527     b[0] = (unsigned char) (u.i);
00528     b[1] = (unsigned char) (u.i >> 8);
00529     b[2] = (unsigned char) (u.i >> 16);
00530     b[3] = (unsigned char) (u.i >> 24);
00531 
00532     writeUnsignedChars<S> (out, b, 4);
00533 }
00534 
00535 
00536 template <class S, class T>
00537 void
00538 write (T &out, double v)
00539 {
00540     union {Int64 i; double d;} u;
00541     u.d = v;
00542 
00543     unsigned char b[8];
00544 
00545     b[0] = (unsigned char) (u.i);
00546     b[1] = (unsigned char) (u.i >> 8);
00547     b[2] = (unsigned char) (u.i >> 16);
00548     b[3] = (unsigned char) (u.i >> 24);
00549     b[4] = (unsigned char) (u.i >> 32);
00550     b[5] = (unsigned char) (u.i >> 40);
00551     b[6] = (unsigned char) (u.i >> 48);
00552     b[7] = (unsigned char) (u.i >> 56);
00553 
00554     writeUnsignedChars<S> (out, b, 8);
00555 }
00556 
00557 
00558 template <class S, class T>
00559 inline void
00560 write (T &out, half v)
00561 {
00562     unsigned char b[2];
00563 
00564     b[0] =  (unsigned char) (v.bits());
00565     b[1] =  (unsigned char) (v.bits() >> 8);
00566 
00567     writeUnsignedChars<S> (out, b, 2);
00568 }
00569 
00570 
00571 template <class S, class T>
00572 inline void
00573 write (T &out, const char v[], int n)   // fixed-size char array
00574 {
00575     S::writeChars (out, v, n);
00576 }
00577 
00578 
00579 template <class S, class T>
00580 void
00581 write (T &out, const char v[])          // zero-terminated string
00582 {
00583     while (*v)
00584     {
00585         S::writeChars (out, v, 1);
00586         ++v;
00587     }
00588 
00589     S::writeChars (out, v, 1);
00590 }
00591 
00592 
00593 template <class S, class T>
00594 void
00595 pad (T &out, int n)                     // add n padding bytes
00596 {
00597     for (int i = 0; i < n; i++)
00598     {
00599         const char c = 0;
00600         S::writeChars (out, &c, 1);
00601     }
00602 }
00603 
00604 
00605 template <class S, class T>
00606 inline void
00607 read (T &in, bool &v)
00608 {
00609     char c;
00610 
00611     S::readChars (in, &c, 1);
00612     v = !!c;
00613 }
00614 
00615 
00616 template <class S, class T>
00617 inline void
00618 read (T &in, char &v)
00619 {
00620     S::readChars (in, &v, 1);
00621 }
00622 
00623 
00624 template <class S, class T>
00625 inline void
00626 read (T &in, signed char &v)
00627 {
00628     readSignedChars<S> (in, &v, 1);
00629 }
00630 
00631 
00632 template <class S, class T>
00633 inline void
00634 read (T &in, unsigned char &v)
00635 {
00636     readUnsignedChars<S> (in, &v, 1);
00637 }
00638 
00639 
00640 template <class S, class T>
00641 void
00642 read (T &in, signed short &v)
00643 {
00644     signed char b[2];
00645 
00646     readSignedChars<S> (in, b, 2);
00647 
00648     v = (b[0] & 0x00ff) |
00649         (b[1] << 8);
00650 }
00651 
00652 
00653 template <class S, class T>
00654 void
00655 read (T &in, unsigned short &v)
00656 {
00657     unsigned char b[2];
00658 
00659     readUnsignedChars<S> (in, b, 2);
00660 
00661     v = (b[0] & 0x00ff) |
00662         (b[1] << 8);
00663 }
00664 
00665 
00666 template <class S, class T>
00667 void
00668 read (T &in, signed int &v)
00669 {
00670     signed char b[4];
00671 
00672     readSignedChars<S> (in, b, 4);
00673 
00674     v =  (b[0]        & 0x000000ff) |
00675         ((b[1] << 8)  & 0x0000ff00) |
00676         ((b[2] << 16) & 0x00ff0000) |
00677          (b[3] << 24);
00678 }
00679 
00680 
00681 template <class S, class T>
00682 void
00683 read (T &in, unsigned int &v)
00684 {
00685     unsigned char b[4];
00686 
00687     readUnsignedChars<S> (in, b, 4);
00688 
00689     v =  (b[0]        & 0x000000ff) |
00690         ((b[1] << 8)  & 0x0000ff00) |
00691         ((b[2] << 16) & 0x00ff0000) |
00692          (b[3] << 24);
00693 }
00694 
00695 
00696 template <class S, class T>
00697 void
00698 read (T &in, signed long &v)
00699 {
00700     signed char b[8];
00701 
00702     readSignedChars<S> (in, b, 8);
00703 
00704     #if LONG_MAX == 2147483647
00705 
00706         v =  (b[0]        & 0x000000ff) |
00707             ((b[1] << 8)  & 0x0000ff00) |
00708             ((b[2] << 16) & 0x00ff0000) |
00709              (b[3] << 24);
00710 
00711         if (( b[4] ||  b[5] ||  b[6] ||  b[7]) &&
00712             (~b[4] || ~b[5] || ~b[6] || ~b[7]))
00713         {
00714             throw Iex::OverflowExc ("Long int overflow - read a large "
00715                                     "64-bit integer in a 32-bit process.");
00716         }
00717 
00718     #elif LONG_MAX == 9223372036854775807L
00719 
00720         v =  ((long) b[0]        & 0x00000000000000ff) |
00721             (((long) b[1] << 8)  & 0x000000000000ff00) |
00722             (((long) b[2] << 16) & 0x0000000000ff0000) |
00723             (((long) b[3] << 24) & 0x00000000ff000000) |
00724             (((long) b[4] << 32) & 0x000000ff00000000) |
00725             (((long) b[5] << 40) & 0x0000ff0000000000) |
00726             (((long) b[6] << 48) & 0x00ff000000000000) |
00727              ((long) b[7] << 56);
00728 
00729     #else
00730 
00731         #error read<T> (T &in, signed long &v) not implemented
00732 
00733     #endif
00734 }
00735 
00736 
00737 template <class S, class T>
00738 void
00739 read (T &in, unsigned long &v)
00740 {
00741     unsigned char b[8];
00742 
00743     readUnsignedChars<S> (in, b, 8);
00744 
00745     #if ULONG_MAX == 4294967295U
00746 
00747         v =  (b[0]        & 0x000000ff) |
00748             ((b[1] << 8)  & 0x0000ff00) |
00749             ((b[2] << 16) & 0x00ff0000) |
00750              (b[3] << 24);
00751 
00752         if (b[4] || b[5] || b[6] || b[7])
00753         {
00754             throw Iex::OverflowExc ("Long int overflow - read a large "
00755                                     "64-bit integer in a 32-bit process.");
00756         }
00757 
00758     #elif ULONG_MAX == 18446744073709551615LU
00759 
00760         v =  ((unsigned long) b[0]        & 0x00000000000000ff) |
00761             (((unsigned long) b[1] << 8)  & 0x000000000000ff00) |
00762             (((unsigned long) b[2] << 16) & 0x0000000000ff0000) |
00763             (((unsigned long) b[3] << 24) & 0x00000000ff000000) |
00764             (((unsigned long) b[4] << 32) & 0x000000ff00000000) |
00765             (((unsigned long) b[5] << 40) & 0x0000ff0000000000) |
00766             (((unsigned long) b[6] << 48) & 0x00ff000000000000) |
00767              ((unsigned long) b[7] << 56);
00768 
00769     #else
00770 
00771         #error read<T> (T &in, unsigned long &v) not implemented
00772 
00773     #endif
00774 }
00775 
00776 
00777 #if ULONG_MAX != 18446744073709551615LU
00778 
00779     template <class S, class T>
00780     void
00781     read (T &in, Int64 &v)
00782     {
00783         unsigned char b[8];
00784 
00785         readUnsignedChars<S> (in, b, 8);
00786 
00787         v =  ((Int64) b[0]        & 0x00000000000000ffLL) |
00788             (((Int64) b[1] << 8)  & 0x000000000000ff00LL) |
00789             (((Int64) b[2] << 16) & 0x0000000000ff0000LL) |
00790             (((Int64) b[3] << 24) & 0x00000000ff000000LL) |
00791             (((Int64) b[4] << 32) & 0x000000ff00000000LL) |
00792             (((Int64) b[5] << 40) & 0x0000ff0000000000LL) |
00793             (((Int64) b[6] << 48) & 0x00ff000000000000LL) |
00794             ((Int64) b[7] << 56);
00795     }
00796 
00797 #endif
00798 
00799 
00800 template <class S, class T>
00801 void
00802 read (T &in, float &v)
00803 {
00804     unsigned char b[4];
00805 
00806     readUnsignedChars<S> (in, b, 4);
00807 
00808     union {unsigned int i; float f;} u;
00809 
00810     u.i = (b[0]        & 0x000000ff) |
00811          ((b[1] << 8)  & 0x0000ff00) |
00812          ((b[2] << 16) & 0x00ff0000) |
00813           (b[3] << 24);
00814 
00815     v = u.f;
00816 }
00817 
00818 
00819 template <class S, class T>
00820 void
00821 read (T &in, double &v)
00822 {
00823     unsigned char b[8];
00824 
00825     readUnsignedChars<S> (in, b, 8);
00826 
00827     union {Int64 i; double d;} u;
00828 
00829     u.i = ((Int64) b[0]        & 0x00000000000000ffULL) |
00830          (((Int64) b[1] << 8)  & 0x000000000000ff00ULL) |
00831          (((Int64) b[2] << 16) & 0x0000000000ff0000ULL) |
00832          (((Int64) b[3] << 24) & 0x00000000ff000000ULL) |
00833          (((Int64) b[4] << 32) & 0x000000ff00000000ULL) |
00834          (((Int64) b[5] << 40) & 0x0000ff0000000000ULL) |
00835          (((Int64) b[6] << 48) & 0x00ff000000000000ULL) |
00836           ((Int64) b[7] << 56);
00837 
00838     v = u.d;
00839 }
00840 
00841 
00842 template <class S, class T>
00843 inline void
00844 read (T &in, half &v)
00845 {
00846     unsigned char b[2];
00847 
00848     readUnsignedChars<S> (in, b, 2);
00849 
00850     v.setBits ((b[0] & 0x00ff) | (b[1] << 8));
00851 }
00852 
00853 
00854 template <class S, class T>
00855 inline void
00856 read (T &in, char v[], int n)           // fixed-size char array
00857 {
00858     S::readChars (in, v, n);
00859 }
00860 
00861 
00862 template <class S, class T>
00863 void
00864 read (T &in, int n, char v[])           // zero-terminated string
00865 {
00866     while (n >= 0)
00867     {
00868         S::readChars (in, v, 1);
00869 
00870         if (*v == 0)
00871             break;
00872 
00873         --n;
00874         ++v;
00875     }
00876 }
00877 
00878 
00879 template <class S, class T>
00880 void
00881 skip (T &in, int n)                     // skip n padding bytes
00882 {
00883     char c[1024];
00884 
00885     while (n >= (int) sizeof (c))
00886     {
00887         if (!S::readChars (in, c, sizeof (c)))
00888             return;
00889 
00890         n -= sizeof (c);
00891     }
00892 
00893     if (n >= 1)
00894         S::readChars (in, c, n);
00895 }
00896 
00897 
00898 template <> inline int size <bool> ()                   {return 1;}
00899 template <> inline int size <char> ()                   {return 1;}
00900 template <> inline int size <signed char> ()            {return 1;}
00901 template <> inline int size <unsigned char> ()          {return 1;}
00902 template <> inline int size <signed short> ()           {return 2;}
00903 template <> inline int size <unsigned short> ()         {return 2;}
00904 template <> inline int size <signed int> ()             {return 4;}
00905 template <> inline int size <unsigned int> ()           {return 4;}
00906 template <> inline int size <signed long> ()            {return 8;}
00907 template <> inline int size <unsigned long> ()          {return 8;}
00908 template <> inline int size <float> ()                  {return 4;}
00909 template <> inline int size <double> ()                 {return 8;}
00910 template <> inline int size <half> ()                   {return 2;}
00911 
00912 
00913 } // namespace Xdr
00914 } // namespace Imf
00915 
00916 #endif