Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

# misc.h

    00001 #ifndef CRYPTOPP_MISC_H
    00002 #define CRYPTOPP_MISC_H
    00003
    00004 #include "cryptlib.h"
    00005
    00006 #ifdef INTEL_INTRINSICS
    00007 #include <stdlib.h>
    00008 #endif
    00009
    00010 NAMESPACE_BEGIN(CryptoPP)
    00011
    00012 // ************** compile-time assertion ***************
    00013
    00014 template <bool b>
    00015 struct CompileAssert
    00016 {
    00017         static char dummy[2*b-1];
    00018 };
    00019
    00020 #define CRYPTOPP_COMPILE_ASSERT(assertion) CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, __LINE__)
    00021 #if defined(CRYPTOPP_EXPORTS) || defined(CRYPTOPP_IMPORTS)
    00022 #define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance)
    00023 #else
    00024 #define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) static CompileAssert<(assertion)> CRYPTOPP_ASSERT_JOIN(cryptopp_assert_, instance)
    00025 #endif
    00026 #define CRYPTOPP_ASSERT_JOIN(X, Y) CRYPTOPP_DO_ASSERT_JOIN(X, Y)
    00027 #define CRYPTOPP_DO_ASSERT_JOIN(X, Y) X##Y
    00028
    00029 // ************** misc classes ***************
    00030
    00031 class CRYPTOPP_DLL Empty
    00032 {
    00033 };
    00034
    00035 template <class BASE1, class BASE2>
    00036 class TwoBases : public BASE1, public BASE2
    00037 {
    00038 };
    00039
    00040 template <class BASE1, class BASE2, class BASE3>
    00041 class ThreeBases : public BASE1, public BASE2, public BASE3
    00042 {
    00043 };
    00044
    00045 template <class T>
    00046 class ObjectHolder
    00047 {
    00048 protected:
    00049         T m_object;
    00050 };
    00051
    00052 class NotCopyable
    00053 {
    00054 public:
    00055         NotCopyable() {}
    00056 private:
    00057     NotCopyable(const NotCopyable &);
    00058     void operator=(const NotCopyable &);
    00059 };
    00060
    00061 // ************** misc functions ***************
    00062
    00063 // can't use std::min or std::max in MSVC60 or Cygwin 1.1.0
    00064 template <class _Tp> inline const _Tp& STDMIN(const _Tp& __a, const _Tp& __b)
    00065 {
    00066         return __b < __a ? __b : __a;
    00067 }
    00068
    00069 template <class _Tp> inline const _Tp& STDMAX(const _Tp& __a, const _Tp& __b)
    00070 {
    00071         return  __a < __b ? __b : __a;
    00072 }
    00073
    00074 #define RETURN_IF_NONZERO(x) unsigned int returnedValue = x; if (returnedValue) return returnedValue
    00075
    00076 // this version of the macro is fastest on Pentium 3 and Pentium 4 with MSVC 6 SP5 w/ Processor Pack
    00077 #define GETBYTE(x, y) (unsigned int)byte((x)>>(8*(y)))
    00078 // these may be faster on other CPUs/compilers
    00079 // #define GETBYTE(x, y) (unsigned int)(((x)>>(8*(y)))&255)
    00080 // #define GETBYTE(x, y) (((byte *)&(x))[y])
    00081
    00082 CRYPTOPP_DLL unsigned int Parity(unsigned long);
    00083 CRYPTOPP_DLL unsigned int BytePrecision(unsigned long);
    00084 CRYPTOPP_DLL unsigned int BitPrecision(unsigned long);
    00085 CRYPTOPP_DLL unsigned long Crop(unsigned long, unsigned int size);
    00086
    00087 inline unsigned int BitsToBytes(unsigned int bitCount)
    00088 {
    00089         return ((bitCount+7)/(8));
    00090 }
    00091
    00092 inline unsigned int BytesToWords(unsigned int byteCount)
    00093 {
    00094         return ((byteCount+WORD_SIZE-1)/WORD_SIZE);
    00095 }
    00096
    00097 inline unsigned int BitsToWords(unsigned int bitCount)
    00098 {
    00099         return ((bitCount+WORD_BITS-1)/(WORD_BITS));
    00100 }
    00101
    00102 CRYPTOPP_DLL void xorbuf(byte *buf, const byte *mask, unsigned int count);
    00103 CRYPTOPP_DLL void xorbuf(byte *output, const byte *input, const byte *mask, unsigned int count);
    00104
    00105 template <class T>
    00106 inline bool IsPowerOf2(T n)
    00107 {
    00108         return n > 0 && (n & (n-1)) == 0;
    00109 }
    00110
    00111 template <class T1, class T2>
    00112 inline T2 ModPowerOf2(T1 a, T2 b)
    00113 {
    00114         assert(IsPowerOf2(b));
    00115         return T2(a) & (b-1);
    00116 }
    00117
    00118 template <class T>
    00119 inline T RoundDownToMultipleOf(T n, T m)
    00120 {
    00121         return n - (IsPowerOf2(m) ? ModPowerOf2(n, m) : (n%m));
    00122 }
    00123
    00124 template <class T>
    00125 inline T RoundUpToMultipleOf(T n, T m)
    00126 {
    00127         return RoundDownToMultipleOf(n+m-1, m);
    00128 }
    00129
    00130 template <class T>
    00131 inline unsigned int GetAlignment(T *dummy=NULL) // VC60 workaround
    00132 {
    00133 #if (_MSC_VER >= 1300)
    00134         return __alignof(T);
    00135 #elif defined(__GNUC__)
    00136         return __alignof__(T);
    00137 #else
    00138         return sizeof(T);
    00139 #endif
    00140 }
    00141
    00142 inline bool IsAlignedOn(const void *p, unsigned int alignment)
    00143 {
    00144         return IsPowerOf2(alignment) ? ModPowerOf2((unsigned int)p, alignment) == 0 : (unsigned int)p % alignment == 0;
    00145 }
    00146
    00147 template <class T>
    00148 inline bool IsAligned(const void *p, T *dummy=NULL)     // VC60 workaround
    00149 {
    00150         return IsAlignedOn(p, GetAlignment<T>());
    00151 }
    00152
    00153 #ifdef IS_LITTLE_ENDIAN
    00154         typedef LittleEndian NativeByteOrder;
    00155 #else
    00156         typedef BigEndian NativeByteOrder;
    00157 #endif
    00158
    00159 inline ByteOrder GetNativeByteOrder()
    00160 {
    00161         return NativeByteOrder::ToEnum();
    00162 }
    00163
    00164 inline bool NativeByteOrderIs(ByteOrder order)
    00165 {
    00166         return order == GetNativeByteOrder();
    00167 }
    00168
    00169 template <class T>              // can't use <sstream> because GCC 2.95.2 doesn't have it
    00170 std::string IntToString(T a, unsigned int base = 10)
    00171 {
    00172         if (a == 0)
    00173                 return "0";
    00174         bool negate = false;
    00175         if (a < 0)
    00176         {
    00177                 negate = true;
    00178                 a = 0-a;        // VC .NET does not like -a
    00179         }
    00180         std::string result;
    00181         while (a > 0)
    00182         {
    00183                 T digit = a % base;
    00184                 result = char((digit < 10 ? '0' : ('a' - 10)) + digit) + result;
    00185                 a /= base;
    00186         }
    00187         if (negate)
    00188                 result = "-" + result;
    00189         return result;
    00190 }
    00191
    00192 template <class T1, class T2>
    00193 inline T1 SaturatingSubtract(T1 a, T2 b)
    00194 {
    00195         CRYPTOPP_COMPILE_ASSERT_INSTANCE(T1(-1)>0, 0);  // T1 is unsigned type
    00196         CRYPTOPP_COMPILE_ASSERT_INSTANCE(T2(-1)>0, 1);  // T2 is unsigned type
    00197         return T1((a > b) ? (a - b) : 0);
    00198 }
    00199
    00200 template <class T>
    00201 inline CipherDir GetCipherDir(const T &obj)
    00202 {
    00203         return obj.IsForwardTransformation() ? ENCRYPTION : DECRYPTION;
    00204 }
    00205
    00206 // ************** rotate functions ***************
    00207
    00208 template <class T> inline T rotlFixed(T x, unsigned int y)
    00209 {
    00210         assert(y < sizeof(T)*8);
    00211         return (x<<y) | (x>>(sizeof(T)*8-y));
    00212 }
    00213
    00214 template <class T> inline T rotrFixed(T x, unsigned int y)
    00215 {
    00216         assert(y < sizeof(T)*8);
    00217         return (x>>y) | (x<<(sizeof(T)*8-y));
    00218 }
    00219
    00220 template <class T> inline T rotlVariable(T x, unsigned int y)
    00221 {
    00222         assert(y < sizeof(T)*8);
    00223         return (x<<y) | (x>>(sizeof(T)*8-y));
    00224 }
    00225
    00226 template <class T> inline T rotrVariable(T x, unsigned int y)
    00227 {
    00228         assert(y < sizeof(T)*8);
    00229         return (x>>y) | (x<<(sizeof(T)*8-y));
    00230 }
    00231
    00232 template <class T> inline T rotlMod(T x, unsigned int y)
    00233 {
    00234         y %= sizeof(T)*8;
    00235         return (x<<y) | (x>>(sizeof(T)*8-y));
    00236 }
    00237
    00238 template <class T> inline T rotrMod(T x, unsigned int y)
    00239 {
    00240         y %= sizeof(T)*8;
    00241         return (x>>y) | (x<<(sizeof(T)*8-y));
    00242 }
    00243
    00244 #ifdef INTEL_INTRINSICS
    00245
    00246 #pragma intrinsic(_lrotl, _lrotr)
    00247
    00248 template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
    00249 {
    00250         assert(y < 32);
    00251         return y ? _lrotl(x, y) : x;
    00252 }
    00253
    00254 template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
    00255 {
    00256         assert(y < 32);
    00257         return y ? _lrotr(x, y) : x;
    00258 }
    00259
    00260 template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y)
    00261 {
    00262         assert(y < 32);
    00263         return _lrotl(x, y);
    00264 }
    00265
    00266 template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y)
    00267 {
    00268         assert(y < 32);
    00269         return _lrotr(x, y);
    00270 }
    00271
    00272 template<> inline word32 rotlMod<word32>(word32 x, unsigned int y)
    00273 {
    00274         return _lrotl(x, y);
    00275 }
    00276
    00277 template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
    00278 {
    00279         return _lrotr(x, y);
    00280 }
    00281
    00282 #endif // #ifdef INTEL_INTRINSICS
    00283
    00284 #ifdef PPC_INTRINSICS
    00285
    00286 template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
    00287 {
    00288         assert(y < 32);
    00289         return y ? __rlwinm(x,y,0,31) : x;
    00290 }
    00291
    00292 template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
    00293 {
    00294         assert(y < 32);
    00295         return y ? __rlwinm(x,32-y,0,31) : x;
    00296 }
    00297
    00298 template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y)
    00299 {
    00300         assert(y < 32);
    00301         return (__rlwnm(x,y,0,31));
    00302 }
    00303
    00304 template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y)
    00305 {
    00306         assert(y < 32);
    00307         return (__rlwnm(x,32-y,0,31));
    00308 }
    00309
    00310 template<> inline word32 rotlMod<word32>(word32 x, unsigned int y)
    00311 {
    00312         return (__rlwnm(x,y,0,31));
    00313 }
    00314
    00315 template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
    00316 {
    00317         return (__rlwnm(x,32-y,0,31));
    00318 }
    00319
    00320 #endif // #ifdef PPC_INTRINSICS
    00321
    00322 // ************** endian reversal ***************
    00323
    00324 template <class T>
    00325 inline unsigned int GetByte(ByteOrder order, T value, unsigned int index)
    00326 {
    00327         if (order == LITTLE_ENDIAN_ORDER)
    00328                 return GETBYTE(value, index);
    00329         else
    00330                 return GETBYTE(value, sizeof(T)-index-1);
    00331 }
    00332
    00333 inline byte ByteReverse(byte value)
    00334 {
    00335         return value;
    00336 }
    00337
    00338 inline word16 ByteReverse(word16 value)
    00339 {
    00340         return rotlFixed(value, 8U);
    00341 }
    00342
    00343 inline word32 ByteReverse(word32 value)
    00344 {
    00345 #ifdef PPC_INTRINSICS
    00346         // PPC: load reverse indexed instruction
    00347         return (word32)__lwbrx(&value,0);
    00348 #elif defined(FAST_ROTATE)
    00349         // 5 instructions with rotate instruction, 9 without
    00350         return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff);
    00351 #else
    00352         // 6 instructions with rotate instruction, 8 without
    00353         value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
    00354         return rotlFixed(value, 16U);
    00355 #endif
    00356 }
    00357
    00358 #ifdef WORD64_AVAILABLE
    00359 inline word64 ByteReverse(word64 value)
    00360 {
    00361 #ifdef SLOW_WORD64
    00362         return (word64(ByteReverse(word32(value))) << 32) | ByteReverse(word32(value>>32));
    00363 #else
    00364         value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8);
    00365         value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16);
    00366         return rotlFixed(value, 32U);
    00367 #endif
    00368 }
    00369 #endif
    00370
    00371 inline byte BitReverse(byte value)
    00372 {
    00373         value = ((value & 0xAA) >> 1) | ((value & 0x55) << 1);
    00374         value = ((value & 0xCC) >> 2) | ((value & 0x33) << 2);
    00375         return rotlFixed(value, 4);
    00376 }
    00377
    00378 inline word16 BitReverse(word16 value)
    00379 {
    00380         value = ((value & 0xAAAA) >> 1) | ((value & 0x5555) << 1);
    00381         value = ((value & 0xCCCC) >> 2) | ((value & 0x3333) << 2);
    00382         value = ((value & 0xF0F0) >> 4) | ((value & 0x0F0F) << 4);
    00383         return ByteReverse(value);
    00384 }
    00385
    00386 inline word32 BitReverse(word32 value)
    00387 {
    00388         value = ((value & 0xAAAAAAAA) >> 1) | ((value & 0x55555555) << 1);
    00389         value = ((value & 0xCCCCCCCC) >> 2) | ((value & 0x33333333) << 2);
    00390         value = ((value & 0xF0F0F0F0) >> 4) | ((value & 0x0F0F0F0F) << 4);
    00391         return ByteReverse(value);
    00392 }
    00393
    00394 #ifdef WORD64_AVAILABLE
    00395 inline word64 BitReverse(word64 value)
    00396 {
    00397 #ifdef SLOW_WORD64
    00398         return (word64(BitReverse(word32(value))) << 32) | BitReverse(word32(value>>32));
    00399 #else
    00400         value = ((value & W64LIT(0xAAAAAAAAAAAAAAAA)) >> 1) | ((value & W64LIT(0x5555555555555555)) << 1);
    00401         value = ((value & W64LIT(0xCCCCCCCCCCCCCCCC)) >> 2) | ((value & W64LIT(0x3333333333333333)) << 2);
    00402         value = ((value & W64LIT(0xF0F0F0F0F0F0F0F0)) >> 4) | ((value & W64LIT(0x0F0F0F0F0F0F0F0F)) << 4);
    00403         return ByteReverse(value);
    00404 #endif
    00405 }
    00406 #endif
    00407
    00408 template <class T>
    00409 inline T BitReverse(T value)
    00410 {
    00411         if (sizeof(T) == 1)
    00412                 return (T)BitReverse((byte)value);
    00413         else if (sizeof(T) == 2)
    00414                 return (T)BitReverse((word16)value);
    00415         else if (sizeof(T) == 4)
    00416                 return (T)BitReverse((word32)value);
    00417         else
    00418         {
    00419 #ifdef WORD64_AVAILABLE
    00420                 assert(sizeof(T) == 8);
    00421                 return (T)BitReverse((word64)value);
    00422 #else
    00423                 assert(false);
    00424                 return 0;
    00425 #endif
    00426         }
    00427 }
    00428
    00429 template <class T>
    00430 inline T ConditionalByteReverse(ByteOrder order, T value)
    00431 {
    00432         return NativeByteOrderIs(order) ? value : ByteReverse(value);
    00433 }
    00434
    00435 template <class T>
    00436 void ByteReverse(T *out, const T *in, unsigned int byteCount)
    00437 {
    00438         assert(byteCount % sizeof(T) == 0);
    00439         unsigned int count = byteCount/sizeof(T);
    00440         for (unsigned int i=0; i<count; i++)
    00441                 out[i] = ByteReverse(in[i]);
    00442 }
    00443
    00444 template <class T>
    00445 inline void ConditionalByteReverse(ByteOrder order, T *out, const T *in, unsigned int byteCount)
    00446 {
    00447         if (!NativeByteOrderIs(order))
    00448                 ByteReverse(out, in, byteCount);
    00449         else if (in != out)
    00450                 memcpy(out, in, byteCount);
    00451 }
    00452
    00453 template <class T>
    00454 inline void GetUserKey(ByteOrder order, T *out, unsigned int outlen, const byte *in, unsigned int inlen)
    00455 {
    00456         const unsigned int U = sizeof(T);
    00457         assert(inlen <= outlen*U);
    00458         memcpy(out, in, inlen);
    00459         memset((byte *)out+inlen, 0, outlen*U-inlen);
    00460         ConditionalByteReverse(order, out, out, RoundUpToMultipleOf(inlen, U));
    00461 }
    00462
    00463 inline byte UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, byte*)
    00464 {
    00465         return block[0];
    00466 }
    00467
    00468 inline word16 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, word16*)
    00469 {
    00470         return (order == BIG_ENDIAN_ORDER)
    00471                 ? block[1] | (block[0] << 8)
    00472                 : block[0] | (block[1] << 8);
    00473 }
    00474
    00475 inline word32 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, word32*)
    00476 {
    00477         return (order == BIG_ENDIAN_ORDER)
    00478                 ? word32(block[3]) | (word32(block[2]) << 8) | (word32(block[1]) << 16) | (word32(block[0]) << 24)
    00479                 : word32(block[0]) | (word32(block[1]) << 8) | (word32(block[2]) << 16) | (word32(block[3]) << 24);
    00480 }
    00481
    00482 template <class T>
    00483 inline T UnalignedGetWord(ByteOrder order, const byte *block, T*dummy=NULL)
    00484 {
    00485         return UnalignedGetWordNonTemplate(order, block, dummy);
    00486 }
    00487
    00488 inline void UnalignedPutWord(ByteOrder order, byte *block, byte value, const byte *xorBlock = NULL)
    00489 {
    00490         block[0] = xorBlock ? (value ^ xorBlock[0]) : value;
    00491 }
    00492
    00493 inline void UnalignedPutWord(ByteOrder order, byte *block, word16 value, const byte *xorBlock = NULL)
    00494 {
    00495         if (order == BIG_ENDIAN_ORDER)
    00496         {
    00497                 block[0] = GETBYTE(value, 1);
    00498                 block[1] = GETBYTE(value, 0);
    00499         }
    00500         else
    00501         {
    00502                 block[0] = GETBYTE(value, 0);
    00503                 block[1] = GETBYTE(value, 1);
    00504         }
    00505
    00506         if (xorBlock)
    00507         {
    00508                 block[0] ^= xorBlock[0];
    00509                 block[1] ^= xorBlock[1];
    00510         }
    00511 }
    00512
    00513 inline void UnalignedPutWord(ByteOrder order, byte *block, word32 value, const byte *xorBlock = NULL)
    00514 {
    00515         if (order == BIG_ENDIAN_ORDER)
    00516         {
    00517                 block[0] = GETBYTE(value, 3);
    00518                 block[1] = GETBYTE(value, 2);
    00519                 block[2] = GETBYTE(value, 1);
    00520                 block[3] = GETBYTE(value, 0);
    00521         }
    00522         else
    00523         {
    00524                 block[0] = GETBYTE(value, 0);
    00525                 block[1] = GETBYTE(value, 1);
    00526                 block[2] = GETBYTE(value, 2);
    00527                 block[3] = GETBYTE(value, 3);
    00528         }
    00529
    00530         if (xorBlock)
    00531         {
    00532                 block[0] ^= xorBlock[0];
    00533                 block[1] ^= xorBlock[1];
    00534                 block[2] ^= xorBlock[2];
    00535                 block[3] ^= xorBlock[3];
    00536         }
    00537 }
    00538
    00539 template <class T>
    00540 inline T GetWord(bool assumeAligned, ByteOrder order, const byte *block)
    00541 {
    00542         if (assumeAligned)
    00543         {
    00544                 assert(IsAligned<T>(block));
    00545                 return ConditionalByteReverse(order, *reinterpret_cast<const T *>(block));
    00546         }
    00547         else
    00548                 return UnalignedGetWord<T>(order, block);
    00549 }
    00550
    00551 template <class T>
    00552 inline void GetWord(bool assumeAligned, ByteOrder order, T &result, const byte *block)
    00553 {
    00554         result = GetWord<T>(assumeAligned, order, block);
    00555 }
    00556
    00557 template <class T>
    00558 inline void PutWord(bool assumeAligned, ByteOrder order, byte *block, T value, const byte *xorBlock = NULL)
    00559 {
    00560         if (assumeAligned)
    00561         {
    00562                 assert(IsAligned<T>(block));
    00563                 if (xorBlock)
    00564                         *reinterpret_cast<T *>(block) = ConditionalByteReverse(order, value) ^ *reinterpret_cast<const T *>(xorBlock);
    00565                 else
    00566                         *reinterpret_cast<T *>(block) = ConditionalByteReverse(order, value);
    00567         }
    00568         else
    00569                 UnalignedPutWord(order, block, value, xorBlock);
    00570 }
    00571
    00572 template <class T, class B, bool A=true>
    00573 class GetBlock
    00574 {
    00575 public:
    00576         GetBlock(const void *block)
    00577                 : m_block((const byte *)block) {}
    00578
    00579         template <class U>
    00580         inline GetBlock<T, B, A> & operator()(U &x)
    00581         {
    00582                 CRYPTOPP_COMPILE_ASSERT(sizeof(U) >= sizeof(T));
    00583                 x = GetWord<T>(A, B::ToEnum(), m_block);
    00584                 m_block += sizeof(T);
    00585                 return *this;
    00586         }
    00587
    00588 private:
    00589         const byte *m_block;
    00590 };
    00591
    00592 template <class T, class B, bool A=true>
    00593 class PutBlock
    00594 {
    00595 public:
    00596         PutBlock(const void *xorBlock, void *block)
    00597                 : m_xorBlock((const byte *)xorBlock), m_block((byte *)block) {}
    00598
    00599         template <class U>
    00600         inline PutBlock<T, B, A> & operator()(U x)
    00601         {
    00602                 PutWord(A, B::ToEnum(), m_block, (T)x, m_xorBlock);
    00603                 m_block += sizeof(T);
    00604                 if (m_xorBlock)
    00605                         m_xorBlock += sizeof(T);
    00606                 return *this;
    00607         }
    00608
    00609 private:
    00610         const byte *m_xorBlock;
    00611         byte *m_block;
    00612 };
    00613
    00614 template <class T, class B, bool A=true>
    00615 struct BlockGetAndPut
    00616 {
    00617         // function needed because of C++ grammatical ambiguity between expression-statements and declarations
    00618         static inline GetBlock<T, B, A> Get(const void *block) {return GetBlock<T, B, A>(block);}
    00619         typedef PutBlock<T, B, A> Put;
    00620 };
    00621
    00622 template <class T>
    00623 std::string WordToString(T value, ByteOrder order = BIG_ENDIAN_ORDER)
    00624 {
    00625         if (!NativeByteOrderIs(order))
    00626                 value = ByteReverse(value);
    00627
    00628         return std::string((char *)&value, sizeof(value));
    00629 }
    00630
    00631 template <class T>
    00632 T StringToWord(const std::string &str, ByteOrder order = BIG_ENDIAN_ORDER)
    00633 {
    00634         T value = 0;
    00635         memcpy(&value, str.data(), STDMIN(sizeof(value), str.size()));
    00636         return NativeByteOrderIs(order) ? value : ByteReverse(value);
    00637 }
    00638
    00639 // ************** help remove warning on g++ ***************
    00640
    00641 template <bool overflow> struct SafeShifter;
    00642
    00643 template<> struct SafeShifter<true>
    00644 {
    00645         template <class T>
    00646         static inline T RightShift(T value, unsigned int bits)
    00647         {
    00648                 return 0;
    00649         }
    00650
    00651         template <class T>
    00652         static inline T LeftShift(T value, unsigned int bits)
    00653         {
    00654                 return 0;
    00655         }
    00656 };
    00657
    00658 template<> struct SafeShifter<false>
    00659 {
    00660         template <class T>
    00661         static inline T RightShift(T value, unsigned int bits)
    00662         {
    00663                 return value >> bits;
    00664         }
    00665
    00666         template <class T>
    00667         static inline T LeftShift(T value, unsigned int bits)
    00668         {
    00669                 return value << bits;
    00670         }
    00671 };
    00672
    00673 template <unsigned int bits, class T>
    00674 inline T SafeRightShift(T value)
    00675 {
    00676         return SafeShifter<(bits>=(8*sizeof(T)))>::RightShift(value, bits);
    00677 }
    00678
    00679 template <unsigned int bits, class T>
    00680 inline T SafeLeftShift(T value)
    00681 {
    00682         return SafeShifter<(bits>=(8*sizeof(T)))>::LeftShift(value, bits);
    00683 }
    00684
    00685 NAMESPACE_END
    00686
    00687 #endif // MISC_H