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*, unsigned, vcl_size_t = 1) { return; } 00079 #else 00080 inline void vsl_swap_bytes( char * ptr, unsigned nbyte, vcl_size_t 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 unsigned nbyte2 = nbyte/2; 00089 for (vcl_size_t n = 0; n < nelem; n++ ) { 00090 ptr1 = ptr; 00091 ptr2 = ptr1 + nbyte - 1; 00092 for (unsigned 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, unsigned nbyte, vcl_size_t 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 unsigned nbyte_x_2 = nbyte*2; 00118 dest += nbyte - 1; 00119 00120 for (vcl_size_t n = 0; n < nelem; n++ ) 00121 { 00122 for (unsigned 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 { 00243 vcl_cerr << "\nI/O ERROR: vsl_convert_from_arbitrary_length(.., " 00244 << vsl_type_string(T()) << "*,..)\n" 00245 << "has attempted to convert a number that is too large to fit into a " 00246 << vsl_type_string(T()) << '\n'; 00247 return 0; 00248 } 00249 } 00250 00251 // Now add the last 1<=n<=7 bits. 00252 *(ints++) = v | // the stuff found before the final 7 bits 00253 ( ((T)(b & 63)) << bitsLoaded) | // the value of the penultimate 6 bits 00254 ( ((T)(b & 64)) ? (-64 << bitsLoaded) : 0); // the value of the final bit. 00255 } 00256 return static_cast<vcl_size_t>(ptr - buffer); 00257 } 00258 00259 //: Implement arbitrary length conversion for unsigned integers. 00260 // This function should only be used by this header file. 00261 template <class T> 00262 inline vcl_size_t vsl_convert_from_arbitrary_length_unsigned_impl( 00263 const unsigned char* buffer, T *ints, vcl_size_t count = 1) 00264 { 00265 assert (count != 0); 00266 const unsigned char* ptr = buffer; 00267 while (count-- > 0) 00268 { 00269 // The inside of this loop is run once per integer 00270 T v = 0; 00271 unsigned char b = *(ptr++); 00272 int bitsLoaded = 0; 00273 while ((b & 128) == 0) 00274 { 00275 v += ((T)b) << bitsLoaded; 00276 bitsLoaded += 7; 00277 b = *(ptr++); 00278 } 00279 00280 // At the end of the loop, the last seven bits have not been added 00281 // First check that number has not and will not overflow 00282 int bitsLeft = sizeof(T)*8 - bitsLoaded; 00283 if (bitsLeft < 7) 00284 { 00285 if (bitsLeft <= 0 || ((b & 127) >> bitsLeft) != 0) 00286 { 00287 vcl_cerr << "\nI/O ERROR: vsl_convert_from_arbitrary_length(.., " 00288 << vsl_type_string(T()) << "*,..)\n" 00289 << "has attempted to convert a number that is too large to fit into a " 00290 << vsl_type_string(T()) << '\n'; 00291 return 0; 00292 } 00293 } 00294 00295 // Now add the last 7 bits. 00296 *(ints++) = T(v + ( ((T)(b & 127)) << bitsLoaded)); 00297 } 00298 return static_cast<vcl_size_t>(ptr - buffer); 00299 } 00300 00301 ///////////////////////////////////////////////////////////////////////// 00302 00303 //: Encode an array of ints into an arbitrary length format. 00304 // The return value is the number of bytes used. 00305 // buffer should be at least as long as 00306 // VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(unsigned long)) * count 00307 inline vcl_size_t vsl_convert_to_arbitrary_length(const unsigned long* ints, 00308 unsigned char *buffer, 00309 vcl_size_t count = 1) 00310 { 00311 return vsl_convert_to_arbitrary_length_unsigned_impl(ints, buffer, count); 00312 } 00313 00314 ///////////////////////////////////////////////////////////////////////// 00315 00316 //: Decode a buffer of arbitrary length integers 00317 // Converts from the integers from the arbitrary length format into 00318 // an array of normal longs. 00319 // \param buffer The buffer to be converted. 00320 // \param count Number of integers expected. Cannot be zero. 00321 // \param ints should point to a buffer at least as long as count. 00322 // \return the number of bytes used, or zero on error. 00323 inline vcl_size_t vsl_convert_from_arbitrary_length(const unsigned char* buffer, 00324 unsigned long *ints, 00325 vcl_size_t count = 1) 00326 { 00327 return vsl_convert_from_arbitrary_length_unsigned_impl(buffer, ints, count); 00328 } 00329 00330 00331 ///////////////////////////////////////////////////////////////////////// 00332 00333 //: Encode an array of ints into an arbitrary length format. 00334 // The return value is the number of bytes used. 00335 // buffer should be at least as long as 00336 // VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(long)) * count 00337 inline vcl_size_t vsl_convert_to_arbitrary_length(const long* ints, 00338 unsigned char *buffer, 00339 vcl_size_t count = 1) 00340 { 00341 return vsl_convert_to_arbitrary_length_signed_impl(ints, buffer, count); 00342 } 00343 00344 ///////////////////////////////////////////////////////////////////////// 00345 00346 //: Decode a buffer of arbitrary length integers 00347 // Converts from the integers from the arbitrary length format into 00348 // an array of normal longs. 00349 // \param buffer The buffer to be converted. 00350 // \param count Number of integers expected. Cannot be zero. 00351 // \param ints should point to a buffer at least as long as count. 00352 // \return the number of bytes used, or zero on error. 00353 inline vcl_size_t vsl_convert_from_arbitrary_length(const unsigned char* buffer, 00354 long *ints, 00355 vcl_size_t count = 1) 00356 { 00357 return vsl_convert_from_arbitrary_length_signed_impl(buffer, ints, count); 00358 } 00359 00360 00361 ///////////////////////////////////////////////////////////////////////// 00362 00363 //: Encode an array of ints into an arbitrary length format. 00364 // The return value is the number of bytes used. 00365 // buffer should be at least as long as 00366 // VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(unsigned int)) * count 00367 inline vcl_size_t vsl_convert_to_arbitrary_length(const unsigned int* ints, 00368 unsigned char *buffer, 00369 vcl_size_t count = 1) 00370 { 00371 return vsl_convert_to_arbitrary_length_unsigned_impl(ints, buffer, count); 00372 } 00373 00374 00375 ///////////////////////////////////////////////////////////////////////// 00376 00377 //: Decode a buffer of arbitrary length integers 00378 // Converts from the integers from the arbitrary length format into 00379 // an array of normal ints. 00380 // \param buffer The buffer to be converted. 00381 // \param count Number of integers expected. Cannot be zero. 00382 // \param ints should point to a buffer at least as long as count. 00383 // \return the number of bytes used, or zero on error. 00384 inline vcl_size_t vsl_convert_from_arbitrary_length(const unsigned char* buffer, 00385 unsigned int *ints, 00386 vcl_size_t count = 1) 00387 { 00388 return vsl_convert_from_arbitrary_length_unsigned_impl(buffer, ints, count); 00389 } 00390 00391 00392 ///////////////////////////////////////////////////////////////////////// 00393 00394 //: Encode an array of ints into an arbitrary length format. 00395 // The return value is the number of bytes used. 00396 // buffer should be at least as long as 00397 // VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(int)) * count 00398 inline vcl_size_t vsl_convert_to_arbitrary_length(const int* ints, 00399 unsigned char *buffer, 00400 vcl_size_t count = 1) 00401 { 00402 return vsl_convert_to_arbitrary_length_signed_impl(ints, buffer, count); 00403 } 00404 00405 00406 ///////////////////////////////////////////////////////////////////////// 00407 00408 //: Decode a buffer of arbitrary length integers 00409 // Converts from the integers from the arbitrary length format into 00410 // an array of normal ints. 00411 // \param buffer The buffer to be converted. 00412 // \param count Number of integers expected. Cannot be zero. 00413 // \param ints should point to a buffer at least as long as count. 00414 // \return the number of bytes used, or zero on error. 00415 inline vcl_size_t vsl_convert_from_arbitrary_length(const unsigned char* buffer, 00416 int *ints, 00417 vcl_size_t count = 1) 00418 { 00419 return vsl_convert_from_arbitrary_length_signed_impl(buffer, ints, count); 00420 } 00421 00422 00423 ///////////////////////////////////////////////////////////////////////// 00424 00425 //: Encode an array of ints into an arbitrary length format. 00426 // The return value is the number of bytes used. 00427 // buffer should be at least as long as 00428 // VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(unsigned short)) * count 00429 inline vcl_size_t vsl_convert_to_arbitrary_length(const unsigned short* ints, 00430 unsigned char *buffer, 00431 vcl_size_t count = 1) 00432 { 00433 return vsl_convert_to_arbitrary_length_unsigned_impl(ints, buffer, count); 00434 } 00435 00436 00437 ///////////////////////////////////////////////////////////////////////// 00438 00439 //: Decode a buffer of arbitrary length integers 00440 // Converts from the integers from the arbitrary length format into 00441 // an array of normal ints. 00442 // \param buffer The buffer to be converted. 00443 // \param count Number of integers expected. Cannot be zero. 00444 // \param ints should point to a buffer at least as long as count. 00445 // \return the number of bytes used, or zero on error. 00446 inline vcl_size_t vsl_convert_from_arbitrary_length(const unsigned char* buffer, 00447 unsigned short *ints, 00448 vcl_size_t count = 1) 00449 { 00450 return vsl_convert_from_arbitrary_length_unsigned_impl(buffer, ints, count); 00451 } 00452 00453 00454 ///////////////////////////////////////////////////////////////////////// 00455 00456 //: Encode an array of ints into an arbitrary length format. 00457 // The return value is the number of bytes used. 00458 // buffer should be at least as long as 00459 // VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(short)) * count 00460 inline vcl_size_t vsl_convert_to_arbitrary_length(const short* ints, 00461 unsigned char *buffer, 00462 vcl_size_t count = 1) 00463 { 00464 return vsl_convert_to_arbitrary_length_signed_impl(ints, buffer, count); 00465 } 00466 00467 00468 ///////////////////////////////////////////////////////////////////////// 00469 00470 //: Decode a buffer of arbitrary length integers 00471 // Converts from the integers from the arbitrary length format into 00472 // an array of normal ints. 00473 // \param buffer The buffer to be converted. 00474 // \param count Number of integers expected. Cannot be zero. 00475 // \param ints should point to a buffer at least as long as count. 00476 // \return the number of bytes used, or zero on error. 00477 inline vcl_size_t vsl_convert_from_arbitrary_length(const unsigned char* buffer, 00478 short *ints, 00479 vcl_size_t count = 1) 00480 { 00481 return vsl_convert_from_arbitrary_length_signed_impl(buffer, ints, count); 00482 } 00483 00484 ///////////////////////////////////////////////////////////////////////// 00485 00486 #if VXL_HAS_INT_64 && !VXL_INT_64_IS_LONG 00487 00488 //: Decode a buffer of arbitrary length integers 00489 // Converts from the integers from the arbitrary length format into 00490 // an array of normal longs. 00491 // \param buffer The buffer to be converted. 00492 // \param count Number of integers expected. Cannot be zero. 00493 // \param ints should point to a buffer at least as long as count. 00494 // \return the number of bytes used, or zero on error. 00495 inline vcl_size_t vsl_convert_from_arbitrary_length(const unsigned char* buffer, 00496 vxl_uint_64 *ints, 00497 vcl_size_t count = 1) 00498 { 00499 return vsl_convert_from_arbitrary_length_unsigned_impl(buffer, ints, count); 00500 } 00501 00502 //: Decode a buffer of arbitrary length integers 00503 // Converts from the integers from the arbitrary length format into 00504 // an array of normal longs. 00505 // \param buffer The buffer to be converted. 00506 // \param count Number of integers expected. Cannot be zero. 00507 // \param ints should point to a buffer at least as long as count. 00508 // \return the number of bytes used, or zero on error. 00509 inline vcl_size_t vsl_convert_from_arbitrary_length(const unsigned char* buffer, 00510 vxl_int_64 *ints, 00511 vcl_size_t count = 1) 00512 { 00513 return vsl_convert_from_arbitrary_length_signed_impl(buffer, ints, count); 00514 } 00515 00516 //: Encode an array of ints into an arbitrary length format. 00517 // The return value is the number of bytes used. 00518 // buffer should be at least as long as 00519 // VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(long)) * count 00520 inline vcl_size_t vsl_convert_to_arbitrary_length(const vxl_int_64* ints, 00521 unsigned char *buffer, 00522 vcl_size_t count = 1) 00523 { 00524 return vsl_convert_to_arbitrary_length_signed_impl(ints, buffer, count); 00525 } 00526 00527 //: Encode an array of ints into an arbitrary length format. 00528 // The return value is the number of bytes used. 00529 // buffer should be at least as long as 00530 // VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(unsigned long)) * count 00531 inline vcl_size_t vsl_convert_to_arbitrary_length(const vxl_uint_64* ints, 00532 unsigned char *buffer, 00533 vcl_size_t count = 1) 00534 { 00535 return vsl_convert_to_arbitrary_length_unsigned_impl(ints, buffer, count); 00536 } 00537 00538 #endif // VXL_HAS_INT_64 00539 00540 ///////////////////////////////////////////////////////////////////////// 00541 00542 #if 0 00543 // This test will be replaced with !VCL_PTRDIFF_T_IS_A_STANDARD_TYPE 00544 // When that macro is working. 00545 00546 //: Encode an array of ints into an arbitrary length format. 00547 // The return value is the number of bytes used. 00548 // buffer should be at least as long as 00549 // VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(vcl_size_t)) * count 00550 inline vcl_size_t vsl_convert_to_arbitrary_length(const vcl_size_t* ints, 00551 unsigned char *buffer, 00552 vcl_size_t count = 1) 00553 { 00554 return vsl_convert_to_arbitrary_length_unsigned_impl(ints, buffer, count); 00555 } 00556 00557 00558 ///////////////////////////////////////////////////////////////////////// 00559 00560 //: Decode a buffer of arbitrary length integers 00561 // Converts from the integers from the arbitrary length format into 00562 // an array of normal ints. 00563 // \param buffer The buffer to be converted. 00564 // \param count Number of integers expected. Cannot be zero. 00565 // \param ints should point to a buffer at least as long as count. 00566 // \return the number of bytes used, or zero on error. 00567 inline vcl_size_t vsl_convert_from_arbitrary_length(const unsigned char* buffer, 00568 vcl_size_t *ints, 00569 vcl_size_t count = 1) 00570 { 00571 return vsl_convert_from_arbitrary_length_unsigned_impl(buffer, ints, count); 00572 } 00573 00574 ///////////////////////////////////////////////////////////////////////// 00575 00576 //: Encode an array of ints into an arbitrary length format. 00577 // The return value is the number of bytes used. 00578 // buffer should be at least as long as 00579 // VSL_MAX_ARBITRARY_INT_BUFFER_LENGTH(sizeof(vcl_ptrdiff_t)) * count 00580 inline vcl_size_t vsl_convert_to_arbitrary_length(const vcl_ptrdiff_t* ints, 00581 unsigned char *buffer, 00582 vcl_size_t count = 1) 00583 { 00584 return vsl_convert_to_arbitrary_length_signed_impl(ints, buffer, count); 00585 } 00586 00587 00588 ///////////////////////////////////////////////////////////////////////// 00589 00590 //: Decode a buffer of arbitrary length integers 00591 // Converts from the integers from the arbitrary length format into 00592 // an array of normal ints. 00593 // \param buffer The buffer to be converted. 00594 // \param count Number of integers expected. Cannot be zero. 00595 // \param ints should point to a buffer at least as long as count. 00596 // \return the number of bytes used, or zero on error. 00597 inline vcl_size_t vsl_convert_from_arbitrary_length(const unsigned char* buffer, 00598 vcl_ptrdiff_t *ints, 00599 vcl_size_t count = 1) 00600 { 00601 return vsl_convert_from_arbitrary_length_signed_impl(buffer, ints, count); 00602 } 00603 #endif // 0 00604 00605 ///////////////////////////////////////////////////////////////////////// 00606 ///////////////////////////////////////////////////////////////////////// 00607 00608 //: Write an unsigned int as 16 bits to vsl_b_ostream 00609 // If your signed int cannot be represented in 16 bits (e.g. on a 32 bit 00610 // platform) the stream's error flag will be set. 00611 // 00612 // Warning: This function should be used infrequently and carefully. Under 00613 // all normal circumstances, the generic vsl_b_read and vsl_b_write in 00614 // vsl_binary_io.h will be perfectly adequate. 00615 // 00616 // You must use vsl_b_read_uint_16() to read the value saved with this 00617 // function. 00618 inline void vsl_b_write_uint_16(vsl_b_ostream& os, unsigned long n ) 00619 { 00620 assert(n < (1 << 16)); 00621 vsl_swap_bytes(( char* )&n, sizeof(long) ); 00622 os.os().write( ( char* )&n, 2 ); 00623 } 00624 00625 //: Read an unsigned int as 16 bits from vsl_b_istream 00626 // 00627 // Warning: This function should be used infrequently and carefully. Under 00628 // all normal circumstances, the generic vsl_b_read and vsl_b_write in 00629 // vsl_binary_io.h will be perfectly adequate. 00630 // 00631 // This function will only read values saved using vsl_b_write_uint_16(). 00632 inline void vsl_b_read_uint_16(vsl_b_istream& is, unsigned long& n ) 00633 { 00634 n = 0; 00635 is.is().read( ( char* )&n, 2 ); 00636 vsl_swap_bytes(( char* )&n, sizeof(long) ); 00637 } 00638 00639 00640 ///////////////////////////////////////////////////////////////////////// 00641 00642 //: Write a signed int as 16 bits to vsl_b_ostream 00643 // If your signed int cannot be represented in 16 bits (e.g. on a 32 bit 00644 // platform) the stream's error flag will be set. 00645 // 00646 // Warning: This function should be used infrequently and carefully. Under 00647 // all normal circumstances, the generic vsl_b_read and vsl_b_write in 00648 // vsl_binary_io.h will be perfectly adequate. 00649 // 00650 // You must vsl_b_read_int_16() to read the value saved with this function. 00651 inline void vsl_b_write_int_16(vsl_b_ostream& os, long n ) 00652 { 00653 assert(n < 32768 && n >= - 32768); 00654 vsl_swap_bytes(( char* )&n, sizeof(long) ); 00655 os.os().write( ( char* )&n, 2 ); 00656 } 00657 00658 //: Read a signed int as 16 bits from vsl_b_istream 00659 // 00660 // Warning: This function should be used infrequently and carefully. Under 00661 // all normal circumstances, the generic vsl_b_read and vsl_b_write in 00662 // vsl_binary_io.h will be perfectly adequate. 00663 // 00664 // This function will only read values saved using vsl_b_write_int_16(). 00665 inline void vsl_b_read_int_16(vsl_b_istream& is, long& n ) 00666 { 00667 is.is().read( ( char* )&n, 2 ); 00668 if ((*(((unsigned char*)&n)+1) & 128) == 1) 00669 { 00670 vsl_swap_bytes(( char* )&n, sizeof(long) ); 00671 n |= -65536l; 00672 } 00673 else 00674 { 00675 vsl_swap_bytes(( char* )&n, sizeof(long) ); 00676 n &= 65535l; 00677 } 00678 } 00679 00680 00681 //: Write a vcl_size_t as 64 bits to vsl_b_ostream 00682 // Will assert if your vcl_size_t cannot be represented in 64 bits (e.g. on some 128 bit 00683 // platforms). 00684 // 00685 // Warning: This function should be used infrequently and carefully. Under 00686 // all normal circumstances, the generic vsl_b_read and vsl_b_write in 00687 // vsl_binary_io.h will be perfectly adequate. 00688 // 00689 // You must use vsl_b_read_uint_64() to read the value saved with this 00690 // function. 00691 inline void vsl_b_write_uint_64(vsl_b_ostream& os, vcl_size_t n ) 00692 { 00693 assert(sizeof(vcl_size_t) <= 8 || n >> 16 >> 16 >> 16 >> 16 == 0); 00694 vsl_swap_bytes(( char* )&n, sizeof(long) ); 00695 os.os().write( ( char* )&n, 8 ); 00696 } 00697 00698 //: Read a vcl_size_t as 64 bits from vsl_b_istream 00699 // 00700 // Warning: This function should be used infrequently and carefully. Under 00701 // all normal circumstances, the generic vsl_b_read and vsl_b_write in 00702 // vsl_binary_io.h will be perfectly adequate. 00703 // 00704 // This function will only read values saved using vsl_b_write_uint_64(). 00705 inline void vsl_b_read_uint_64(vsl_b_istream& is, vcl_size_t& n ) 00706 { 00707 n = 0; 00708 is.is().read( ( char* )&n, 8 ); 00709 vsl_swap_bytes(( char* )&n, sizeof(long) ); 00710 } 00711 00712 00713 #endif // vsl_binary_explicit_io_h_