PBRT
|
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