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

misc.h

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

Generated on Fri Aug 27 13:57:12 2004 for Crypto++ by doxygen 1.3.8