00001 // This is core/vsl/vsl_binary_explicit_io.h 00002 #ifndef vsl_binary_explicit_io_h_ 00003 #define vsl_binary_explicit_io_h_ 00004 //: 00005 // \file 00006 // \brief Byte-swapping, arbitrary length integer conversion, and explicit I/O 00007 // \author Ian Scott (Manchester) April 2001 00008 // 00009 // Include this file if you want to perform integer IO using fixed size encoding. 00010 // 00011 // If you want to read or write a large number of floating points, then; 00012 // - Floats and doubles need byte swapped, and this can be done in situ. 00013 // - Shorts, ints and longs need converted to/from the arbitrary length format. 00014 // 00015 // \par Implementation details: 00016 // The arbitrary length encoding takes the number and breaks it into 7 bit 00017 // nibbles. Each nibble is saved with the 8th bit set if this is the last byte. 00018 // The nibbles are stored in little endian order. ie The first byte of the 00019 // encoded format represents the least significant 7 bits. 00020 // 00021 // The algorithm used to encode an unsigned value works as follows 00022 // \verbatim 00023 // while value is greater than 2^7-1 00024 // emit 0 bit 00025 // emit least significant 7 bits of value. 00026 // shift value right 7 bits 00027 // emit bit 1 00028 // emit value embedded in 7 bits 00029 // \endverbatim 00030 00031 #include <vxl_config.h> 00032 #include <vcl_cassert.h> 00033 #include <vcl_cstring.h> 00034 #include <vcl_cstddef.h> 00035 #include <vcl_iostream.h> 00036 #include "vsl_binary_io.h" 00037 00038 // Both VXL_LITTLE_ENDIAN && VXL_BIG_ENDIAN should be defined 00039 // One should equal 1 and the other equal 0; 00040 #if VXL_LITTLE_ENDIAN == VXL_BIG_ENDIAN 00041 extern "There is a problem with the ENDIAN indication macros."; 00042 #endif 00043 #if VXL_LITTLE_ENDIAN+VXL_BIG_ENDIAN != 1 00044 extern "There is a problem with the ENDIAN indication macros."; 00045 #endif 00046 00047 ///////////////////////////////////////////////////////////////////////// 00048 00049 00050 //: Perform byte swapping in situ 00051 // Where appropriate, swaps pairs of bytes (behaviour is system dependent) 00052 // Apply this function to your floating-point data to convert from system 00053 // format to I/O format. Apply the same function to do the reverse conversion. 00054 // 00055 // \param ptr The buffer to be byte-swapped. 00056 // \param nbyte The length of the fundamental type, e.g. sizeof(float). 00057 // \param nelem The number of elements in the buffer (default: 1). 00058 // 00059 // The standard I/O format is little-endian. The code assumes that 00060 // your system's floats and doubles are stored in memory in either 00061 // little-endian or big-endian IEEE floating point formats. 00062 // 00063 // Note: There is no point in #ifdef-ing out calls to byte-swapping if you 00064 // are on a little-endian machine. An optimising compiler will inline the 00065 // function to nothing for little-endian machines anyway. 00066 // 00067 // If your computer doesn't use IEEE format reals, then we really should 00068 // redesign the floating point IO. 00069 // Proposed design notes: 00070 // Should do conversion to and from a buffer, rather than in place, 00071 // (since size not known in general) 00072 // double and reals should be converted to IEEE format. 00073 // Someone needs to write a long double format anyway. 00074 // Don't forget to fix all the code that calls vsl_swap_bytes. 00075 // Really should check anything that #includes this file. 00076 00077 #if VXL_LITTLE_ENDIAN 00078 inline void vsl_swap_bytes(char*, int, int = 1) { return; } 00079 #else 00080 inline void vsl_swap_bytes( char * ptr, int nbyte, int nelem = 1) 00081 { 00082 // If the byte order of the file 00083 // does not match the intel byte order 00084 // then the bytes should be swapped 00085 char temp; 00086 char *ptr1, *ptr2; 00087 00088 int nbyte2 = nbyte/2; 00089 for (int n = 0; n < nelem; n++ ) { 00090 ptr1 = ptr; 00091 ptr2 = ptr1 + nbyte - 1; 00092 for (int i = 0; i < nbyte2; i++ ) { 00093 temp = *ptr1; 00094 *ptr1++ = *ptr2; 00095 *ptr2-- = temp; 00096 } 00097 ptr += nbyte; 00098 } 00099 } 00100 #endif 00101 00102 //: Perform byte swapping to a buffer 00103 // Same as vsl_swap_bytes, but saves the results in a buffer. 00104 // In general use vsl_swap_bytes where possible, because it is faster. 00105 inline void vsl_swap_bytes_to_buffer( const char * source, char * dest, int nbyte, int nelem = 1) 00106 { 00107 #if VXL_LITTLE_ENDIAN 00108 vcl_memcpy(dest, source, nbyte * nelem); 00109 #else 00110 00111 assert(source != dest); 00112 00113 // If the byte order of the file 00114 // does not match the intel byte order 00115 // then the bytes should be swapped 00116 00117 const int nbyte_x_2 = nbyte*2; 00118 dest += nbyte - 1; 00119 00120 for (int n = 0; n < nelem; n++ ) 00121 { 00122 for (int i = 0; i < nbyte; i++ ) 00123 *dest-- = *source++; 00124 00125 dest += nbyte_x_2; 00126 } 00127 #endif 00128 } 00129 00130 ///////////////////////////////////////////////////////////////////////// 00131 ///////////////////////////////////////////////////////////////////////// 00132 #ifndef DOXYGEN_SHOULD_SKIP_THIS 00133 #define macro( T ) \ 00134 inline const char * vsl_type_string(T /*dummy*/) { return #T; } 00135 macro (short); 00136 macro (unsigned short); 00137 macro (int); 00138 macro (unsigned int); 00139 macro (long); 00140 macro (unsigned long); 00141 #if VXL_HAS_INT_64 && !VXL_INT_64_IS_LONG 00142 macro (vxl_int_64); 00143 macro (vxl_uint_64); 00144 #endif 00145 #if 0 00146 // This test will be replaced with !VCL_PTRDIFF_T_IS_A_STANDARD_TYPE 00147 // When that macro is working. 00148 macro(vcl_ptrdiff_t); 00149 macro(vcl_size_t); 00150 #endif 00151 #undef macro 00152 #endif // DOXYGEN_SHOULD_SKIP_THIS 00153 00154 //: The maximum length of buffer to use with arbitrary length integers 00155 // This macro tells you the size of buffer you need when using 00156 // vsl_convert_ints_to_arbitrary_length(). 00157 // You should give the macro the size of the type you want to convert. 00158 // If you are converting several integers at once, multiply the value by 00159 // the number of integers. 00160 #define VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(size_of_type) \ 00161 (((size_of_type * 8)/7) + ((((size_of_type * 8) % 7) == 0) ? 0: 1)) 00162 00163 00164 //: Implement arbitrary length conversion for unsigned integers. 00165 // This function should only be used by this header file. 00166 // Returns the number of bytes written 00167 template <class T> 00168 inline vcl_size_t vsl_convert_to_arbitrary_length_unsigned_impl( 00169 const T* ints, unsigned char *buffer, vcl_size_t count) 00170 { 00171 unsigned char* ptr = buffer; 00172 while (count-- > 0) 00173 { 00174 // The inside of this loop is run once per integer 00175 T v = *(ints++); 00176 while (v > 127) 00177 { 00178 *(ptr++) = (unsigned char)(v & 127); 00179 v >>= 7; 00180 } 00181 *(ptr++) = (unsigned char)(v | 128); 00182 } 00183 return static_cast<vcl_size_t>(ptr - buffer); 00184 } 00185 00186 00187 //: Implement arbitrary length conversion for signed integers. 00188 // This function should only be used by this header file. 00189 // Returns the number of bytes written 00190 template <class T> 00191 inline vcl_size_t vsl_convert_to_arbitrary_length_signed_impl( 00192 const T* ints, unsigned char *buffer, vcl_size_t count) 00193 { 00194 unsigned char* ptr = buffer; 00195 while (count-- > 0) 00196 { 00197 // The inside of this loop is run once per integer 00198 T v = *(ints++); 00199 while (v > 63 || v < -64) 00200 { 00201 *(ptr++) = (unsigned char)(v & 127); 00202 v >>= 7; 00203 } 00204 *(ptr++) = (unsigned char)((v & 127) | 128); 00205 } 00206 return static_cast<vcl_size_t>(ptr - buffer); 00207 } 00208 00209 00210 //: Implement arbitrary length conversion for signed integers. 00211 // This function should only be used by this header file. 00212 template <class T> 00213 inline vcl_size_t vsl_convert_from_arbitrary_length_signed_impl( 00214 const unsigned char* buffer, T *ints, vcl_size_t count) 00215 { 00216 assert (count != 0); 00217 const unsigned char* ptr = buffer; 00218 while (count-- > 0) 00219 { 00220 // The inside of this loop is run once per integer 00221 00222 T v = 0; // The value being loaded 00223 unsigned char b= *(ptr++); 00224 int bitsLoaded = 0; 00225 while ((b & 128) == 0) 00226 { 00227 v += ((T)b) << bitsLoaded; 00228 bitsLoaded += 7; 00229 b = *(ptr++); 00230 } 00231 00232 // At the end of the loop, the last seven bits have not been added 00233 // Now check that number has not and will not overflow 00234 int bitsLeft = sizeof(T)*8 - bitsLoaded; 00235 if (bitsLeft < 7) 00236 { 00237 if (bitsLeft <= 0 || 00238 b & 64 ? 00239 (((signed char)b >> (bitsLeft-1)) != -1) : 00240 (((b & 127) >> (bitsLeft-1)) != 0) ) 00241 { 00242 vcl_cerr << "\nI/O ERROR: vsl_convert_from_arbitrary_length(.., " 00243 << vsl_type_string(T()) << "*,..)\n" 00244 << "has attempted to convert a number that is too large to fit into a " 00245 << vsl_type_string(T()) << '\n'; 00246 return 0; 00247 } 00248 } 00249 00250 // Now add the last 1<=n<=7 bits. 00251 *(ints++) = v | // the stuff found before the final 7 bits 00252 ( ((T)(b & 63)) << bitsLoaded) | // the value of the penultimate 6 bits 00253 ( ((T)(b & 64)) ? (-64 << bitsLoaded) : 0); // the value of the final bit. 00254 } 00255 return static_cast<vcl_size_t>(ptr - buffer); 00256 } 00257 00258 //: Implement arbitrary length conversion for unsigned integers. 00259 // This function should only be used by this header file. 00260 template <class T> 00261 inline vcl_size_t vsl_convert_from_arbitrary_length_unsigned_impl( 00262 const unsigned char* buffer, T *ints, vcl_size_t count = 1) 00263 { 00264 assert (count != 0); 00265 const unsigned char* ptr = buffer; 00266 while (count-- > 0) 00267 { 00268 // The inside of this loop is run once per integer 00269 T v = 0; 00270 unsigned char b = *(ptr++); 00271 int bitsLoaded = 0; 00272 while ((b & 128) == 0) 00273 { 00274 v += ((T)b) << bitsLoaded; 00275 bitsLoaded += 7; 00276 b = *(ptr++); 00277 } 00278 00279 // At the end of the loop, the last seven bits have not been added 00280 // First check that number has not and will not overflow 00281 int bitsLeft = sizeof(T)*8 - bitsLoaded; 00282 if (bitsLeft < 7) 00283 { 00284 if (bitsLeft <= 0 || ((b & 127) >> bitsLeft) != 0) 00285 { 00286 vcl_cerr << "\nI/O ERROR: vsl_convert_from_arbitrary_length(.., " 00287 << vsl_type_string(T()) << "*,..)\n" 00288 << "has attempted to convert a number that is too large to fit into a " 00289 << vsl_type_string(T()) << '\n'; 00290 return 0; 00291 } 00292 } 00293 00294 // Now add the last 7 bits. 00295 *(ints++) = T(v + ( ((T)(b & 127)) << bitsLoaded)); 00296 } 00297 return static_cast<vcl_size_t>(ptr - buffer); 00298 } 00299 00300 ///////////////////////////////////////////////////////////////////////// 00301 00302 //: Encode an array of ints into an arbitrary length format. 00303 // The return value is the number of bytes used. 00304 // buffer should be at least as long as 00305 // VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(unsigned long)) * count 00306 inline vcl_size_t vsl_convert_to_arbitrary_length(const unsigned long* ints, 00307 unsigned char *buffer, 00308 vcl_size_t count = 1) 00309 { 00310 return vsl_convert_to_arbitrary_length_unsigned_impl(ints, buffer, count); 00311 } 00312 00313 ///////////////////////////////////////////////////////////////////////// 00314 00315 //: Decode a buffer of arbitrary length integers 00316 // Converts from the integers from the arbitrary length format into 00317 // an array of normal longs. 00318 // \param buffer The buffer to be converted. 00319 // \param count Number of integers expected. Cannot be zero. 00320 // \param ints should point to a buffer at least as long as count. 00321 // \return the number of bytes used, or zero on error. 00322 inline vcl_size_t vsl_convert_from_arbitrary_length(const unsigned char* buffer, 00323 unsigned long *ints, 00324 vcl_size_t count = 1) 00325 { 00326 return vsl_convert_from_arbitrary_length_unsigned_impl(buffer, ints, count); 00327 } 00328 00329 00330 ///////////////////////////////////////////////////////////////////////// 00331 00332 //: Encode an array of ints into an arbitrary length format. 00333 // The return value is the number of bytes used. 00334 // buffer should be at least as long as 00335 // VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(long)) * count 00336 inline vcl_size_t vsl_convert_to_arbitrary_length(const long* ints, 00337 unsigned char *buffer, 00338 vcl_size_t count = 1) 00339 { 00340 return vsl_convert_to_arbitrary_length_signed_impl(ints, buffer, count); 00341 } 00342 00343 ///////////////////////////////////////////////////////////////////////// 00344 00345 //: Decode a buffer of arbitrary length integers 00346 // Converts from the integers from the arbitrary length format into 00347 // an array of normal longs. 00348 // \param buffer The buffer to be converted. 00349 // \param count Number of integers expected. Cannot be zero. 00350 // \param ints should point to a buffer at least as long as count. 00351 // \return the number of bytes used, or zero on error. 00352 inline vcl_size_t vsl_convert_from_arbitrary_length(const unsigned char* buffer, 00353 long *ints, 00354 vcl_size_t count = 1) 00355 { 00356 return vsl_convert_from_arbitrary_length_signed_impl(buffer, ints, count); 00357 } 00358 00359 00360 ///////////////////////////////////////////////////////////////////////// 00361 00362 //: Encode an array of ints into an arbitrary length format. 00363 // The return value is the number of bytes used. 00364 // buffer should be at least as long as 00365 // VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(unsigned int)) * count 00366 inline vcl_size_t vsl_convert_to_arbitrary_length(const unsigned int* ints, 00367 unsigned char *buffer, 00368 vcl_size_t count = 1) 00369 { 00370 return vsl_convert_to_arbitrary_length_unsigned_impl(ints, buffer, count); 00371 } 00372 00373 00374 ///////////////////////////////////////////////////////////////////////// 00375 00376 //: Decode a buffer of arbitrary length integers 00377 // Converts from the integers from the arbitrary length format into 00378 // an array of normal ints. 00379 // \param buffer The buffer to be converted. 00380 // \param count Number of integers expected. Cannot be zero. 00381 // \param ints should point to a buffer at least as long as count. 00382 // \return the number of bytes used, or zero on error. 00383 inline vcl_size_t vsl_convert_from_arbitrary_length(const unsigned char* buffer, 00384 unsigned int *ints, 00385 vcl_size_t count = 1) 00386 { 00387 return vsl_convert_from_arbitrary_length_unsigned_impl(buffer, ints, count); 00388 } 00389 00390 00391 ///////////////////////////////////////////////////////////////////////// 00392 00393 //: Encode an array of ints into an arbitrary length format. 00394 // The return value is the number of bytes used. 00395 // buffer should be at least as long as 00396 // VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(int)) * count 00397 inline vcl_size_t vsl_convert_to_arbitrary_length(const int* ints, 00398 unsigned char *buffer, 00399 vcl_size_t count = 1) 00400 { 00401 return vsl_convert_to_arbitrary_length_signed_impl(ints, buffer, count); 00402 } 00403 00404 00405 ///////////////////////////////////////////////////////////////////////// 00406 00407 //: Decode a buffer of arbitrary length integers 00408 // Converts from the integers from the arbitrary length format into 00409 // an array of normal ints. 00410 // \param buffer The buffer to be converted. 00411 // \param count Number of integers expected. Cannot be zero. 00412 // \param ints should point to a buffer at least as long as count. 00413 // \return the number of bytes used, or zero on error. 00414 inline vcl_size_t vsl_convert_from_arbitrary_length(const unsigned char* buffer, 00415 int *ints, 00416 vcl_size_t count = 1) 00417 { 00418 return vsl_convert_from_arbitrary_length_signed_impl(buffer, ints, count); 00419 } 00420 00421 00422 ///////////////////////////////////////////////////////////////////////// 00423 00424 //: Encode an array of ints into an arbitrary length format. 00425 // The return value is the number of bytes used. 00426 // buffer should be at least as long as 00427 // VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(unsigned short)) * count 00428 inline vcl_size_t vsl_convert_to_arbitrary_length(const unsigned short* ints, 00429 unsigned char *buffer, 00430 vcl_size_t count = 1) 00431 { 00432 return vsl_convert_to_arbitrary_length_unsigned_impl(ints, buffer, count); 00433 } 00434 00435 00436 ///////////////////////////////////////////////////////////////////////// 00437 00438 //: Decode a buffer of arbitrary length integers 00439 // Converts from the integers from the arbitrary length format into 00440 // an array of normal ints. 00441 // \param buffer The buffer to be converted. 00442 // \param count Number of integers expected. Cannot be zero. 00443 // \param ints should point to a buffer at least as long as count. 00444 // \return the number of bytes used, or zero on error. 00445 inline vcl_size_t vsl_convert_from_arbitrary_length(const unsigned char* buffer, 00446 unsigned short *ints, 00447 vcl_size_t count = 1) 00448 { 00449 return vsl_convert_from_arbitrary_length_unsigned_impl(buffer, ints, count); 00450 } 00451 00452 00453 ///////////////////////////////////////////////////////////////////////// 00454 00455 //: Encode an array of ints into an arbitrary length format. 00456 // The return value is the number of bytes used. 00457 // buffer should be at least as long as 00458 // VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(short)) * count 00459 inline vcl_size_t vsl_convert_to_arbitrary_length(const short* ints, 00460 unsigned char *buffer, 00461 vcl_size_t count = 1) 00462 { 00463 return vsl_convert_to_arbitrary_length_signed_impl(ints, buffer, count); 00464 } 00465 00466 00467 ///////////////////////////////////////////////////////////////////////// 00468 00469 //: Decode a buffer of arbitrary length integers 00470 // Converts from the integers from the arbitrary length format into 00471 // an array of normal ints. 00472 // \param buffer The buffer to be converted. 00473 // \param count Number of integers expected. Cannot be zero. 00474 // \param ints should point to a buffer at least as long as count. 00475 // \return the number of bytes used, or zero on error. 00476 inline vcl_size_t vsl_convert_from_arbitrary_length(const unsigned char* buffer, 00477 short *ints, 00478 vcl_size_t count = 1) 00479 { 00480 return vsl_convert_from_arbitrary_length_signed_impl(buffer, ints, count); 00481 } 00482 00483 ///////////////////////////////////////////////////////////////////////// 00484 00485 #if VXL_HAS_INT_64 && !VXL_INT_64_IS_LONG 00486 00487 //: Decode a buffer of arbitrary length integers 00488 // Converts from the integers from the arbitrary length format into 00489 // an array of normal longs. 00490 // \param buffer The buffer to be converted. 00491 // \param count Number of integers expected. Cannot be zero. 00492 // \param ints should point to a buffer at least as long as count. 00493 // \return the number of bytes used, or zero on error. 00494 inline vcl_size_t vsl_convert_from_arbitrary_length(const unsigned char* buffer, 00495 vxl_uint_64 *ints, 00496 vcl_size_t count = 1) 00497 { 00498 return vsl_convert_from_arbitrary_length_unsigned_impl(buffer, ints, count); 00499 } 00500 00501 //: Decode a buffer of arbitrary length integers 00502 // Converts from the integers from the arbitrary length format into 00503 // an array of normal longs. 00504 // \param buffer The buffer to be converted. 00505 // \param count Number of integers expected. Cannot be zero. 00506 // \param ints should point to a buffer at least as long as count. 00507 // \return the number of bytes used, or zero on error. 00508 inline vcl_size_t vsl_convert_from_arbitrary_length(const unsigned char* buffer, 00509 vxl_int_64 *ints, 00510 vcl_size_t count = 1) 00511 { 00512 return vsl_convert_from_arbitrary_length_signed_impl(buffer, ints, count); 00513 } 00514 00515 //: Encode an array of ints into an arbitrary length format. 00516 // The return value is the number of bytes used. 00517 // buffer should be at least as long as 00518 // VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(long)) * count 00519 inline vcl_size_t vsl_convert_to_arbitrary_length(const vxl_int_64* ints, 00520 unsigned char *buffer, 00521 vcl_size_t count = 1) 00522 { 00523 return vsl_convert_to_arbitrary_length_signed_impl(ints, buffer, count); 00524 } 00525 00526 //: Encode an array of ints into an arbitrary length format. 00527 // The return value is the number of bytes used. 00528 // buffer should be at least as long as 00529 // VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(unsigned long)) * count 00530 inline vcl_size_t vsl_convert_to_arbitrary_length(const vxl_uint_64* ints, 00531 unsigned char *buffer, 00532 vcl_size_t count = 1) 00533 { 00534 return vsl_convert_to_arbitrary_length_unsigned_impl(ints, buffer, count); 00535 } 00536 00537 #endif // VXL_HAS_INT_64 00538 00539 ///////////////////////////////////////////////////////////////////////// 00540 00541 #if 0 00542 // This test will be replaced with !VCL_PTRDIFF_T_IS_A_STANDARD_TYPE 00543 // When that macro is working. 00544 00545 //: Encode an array of ints into an arbitrary length format. 00546 // The return value is the number of bytes used. 00547 // buffer should be at least as long as 00548 // VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(vcl_size_t)) * count 00549 inline vcl_size_t vsl_convert_to_arbitrary_length(const vcl_size_t* ints, 00550 unsigned char *buffer, 00551 vcl_size_t count = 1) 00552 { 00553 return vsl_convert_to_arbitrary_length_unsigned_impl(ints, buffer, count); 00554 } 00555 00556 00557 ///////////////////////////////////////////////////////////////////////// 00558 00559 //: Decode a buffer of arbitrary length integers 00560 // Converts from the integers from the arbitrary length format into 00561 // an array of normal ints. 00562 // \param buffer The buffer to be converted. 00563 // \param count Number of integers expected. Cannot be zero. 00564 // \param ints should point to a buffer at least as long as count. 00565 // \return the number of bytes used, or zero on error. 00566 inline vcl_size_t vsl_convert_from_arbitrary_length(const unsigned char* buffer, 00567 vcl_size_t *ints, 00568 vcl_size_t count = 1) 00569 { 00570 return vsl_convert_from_arbitrary_length_unsigned_impl(buffer, ints, count); 00571 } 00572 00573 ///////////////////////////////////////////////////////////////////////// 00574 00575 //: Encode an array of ints into an arbitrary length format. 00576 // The return value is the number of bytes used. 00577 // buffer should be at least as long as 00578 // VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(vcl_ptrdiff_t)) * count 00579 inline vcl_size_t vsl_convert_to_arbitrary_length(const vcl_ptrdiff_t* ints, 00580 unsigned char *buffer, 00581 vcl_size_t count = 1) 00582 { 00583 return vsl_convert_to_arbitrary_length_signed_impl(ints, buffer, count); 00584 } 00585 00586 00587 ///////////////////////////////////////////////////////////////////////// 00588 00589 //: Decode a buffer of arbitrary length integers 00590 // Converts from the integers from the arbitrary length format into 00591 // an array of normal ints. 00592 // \param buffer The buffer to be converted. 00593 // \param count Number of integers expected. Cannot be zero. 00594 // \param ints should point to a buffer at least as long as count. 00595 // \return the number of bytes used, or zero on error. 00596 inline vcl_size_t vsl_convert_from_arbitrary_length(const unsigned char* buffer, 00597 vcl_ptrdiff_t *ints, 00598 vcl_size_t count = 1) 00599 { 00600 return vsl_convert_from_arbitrary_length_signed_impl(buffer, ints, count); 00601 } 00602 #endif // 0 00603 00604 ///////////////////////////////////////////////////////////////////////// 00605 ///////////////////////////////////////////////////////////////////////// 00606 00607 //: Write an unsigned int as 16 bits to vsl_b_ostream 00608 // If your signed int cannot be represented in 16 bits (e.g. on a 32 bit 00609 // platform) the stream's error flag will be set. 00610 // 00611 // Warning: This function should be used infrequently and carefully. Under 00612 // all normal circumstances, the generic vsl_b_read and vsl_b_write in 00613 // vsl_binary_io.h will be perfectly adequate. 00614 // 00615 // You must use vsl_b_read_uint_16() to read the value saved with this 00616 // function. 00617 inline void vsl_b_write_uint_16(vsl_b_ostream& os, unsigned long n ) 00618 { 00619 assert(n < (1 << 16)); 00620 vsl_swap_bytes(( char* )&n, sizeof(long) ); 00621 os.os().write( ( char* )&n, 2 ); 00622 } 00623 00624 //: Read an unsigned int as 16 bits from vsl_b_istream 00625 // 00626 // Warning: This function should be used infrequently and carefully. Under 00627 // all normal circumstances, the generic vsl_b_read and vsl_b_write in 00628 // vsl_binary_io.h will be perfectly adequate. 00629 // 00630 // This function will only read values saved using vsl_b_write_uint_16(). 00631 inline void vsl_b_read_uint_16(vsl_b_istream& is, unsigned long& n ) 00632 { 00633 n = 0; 00634 is.is().read( ( char* )&n, 2 ); 00635 vsl_swap_bytes(( char* )&n, sizeof(long) ); 00636 } 00637 00638 00639 ///////////////////////////////////////////////////////////////////////// 00640 00641 //: Write a signed int as 16 bits to vsl_b_ostream 00642 // If your signed int cannot be represented in 16 bits (e.g. on a 32 bit 00643 // platform) the stream's error flag will be set. 00644 // 00645 // Warning: This function should be used infrequently and carefully. Under 00646 // all normal circumstances, the generic vsl_b_read and vsl_b_write in 00647 // vsl_binary_io.h will be perfectly adequate. 00648 // 00649 // You must vsl_b_read_int_16() to read the value saved with this function. 00650 inline void vsl_b_write_int_16(vsl_b_ostream& os, long n ) 00651 { 00652 assert(n < 32768 && n >= - 32768); 00653 vsl_swap_bytes(( char* )&n, sizeof(long) ); 00654 os.os().write( ( char* )&n, 2 ); 00655 } 00656 00657 //: Read a signed int as 16 bits from vsl_b_istream 00658 // 00659 // Warning: This function should be used infrequently and carefully. Under 00660 // all normal circumstances, the generic vsl_b_read and vsl_b_write in 00661 // vsl_binary_io.h will be perfectly adequate. 00662 // 00663 // This function will only read values saved using vsl_b_write_int_16(). 00664 inline void vsl_b_read_int_16(vsl_b_istream& is, long& n ) 00665 { 00666 is.is().read( ( char* )&n, 2 ); 00667 if ((*(((unsigned char*)&n)+1) & 128) == 1) 00668 { 00669 vsl_swap_bytes(( char* )&n, sizeof(long) ); 00670 n |= -65536l; 00671 } 00672 else 00673 { 00674 vsl_swap_bytes(( char* )&n, sizeof(long) ); 00675 n &= 65535l; 00676 } 00677 } 00678 00679 00680 #endif // vsl_binary_explicit_io_h_
1.7.5.1