The Tiny HTM Library
|
00001 00014 #ifndef HTM_VARINT_H 00015 #define HTM_VARINT_H 00016 00017 #include "common.h" 00018 00019 #ifdef __cplusplus 00020 extern "C" { 00021 #endif 00022 00029 HTM_INLINE unsigned int htm_varint_len(uint64_t val) 00030 { 00031 #ifdef __GNUC__ 00032 return val == 0 ? 1 : 1 + (66 - __builtin_clzll(val))/8; 00033 #else 00034 unsigned int n = 3; 00035 uint64_t v = val; 00036 while ((v >>= 1) != 0) { ++n; } 00037 return 1 + n/8; 00038 #endif 00039 } 00040 00044 HTM_INLINE unsigned int htm_varint_nfollow(unsigned char leadbyte) 00045 { 00046 return leadbyte >> 5; 00047 } 00048 00051 HTM_INLINE uint64_t htm_varint_decode(const unsigned char *buf) 00052 { 00053 uint64_t val = buf[0] & 0x1f; 00054 unsigned int nfollow = htm_varint_nfollow(buf[0]); 00055 switch (buf[0] >> 5) { 00056 case 7: val = (val << 8) | buf[nfollow - 6]; 00057 case 6: val = (val << 8) | buf[nfollow - 5]; 00058 case 5: val = (val << 8) | buf[nfollow - 4]; 00059 case 4: val = (val << 8) | buf[nfollow - 3]; 00060 case 3: val = (val << 8) | buf[nfollow - 2]; 00061 case 2: val = (val << 8) | buf[nfollow - 1]; 00062 case 1: val = (val << 8) | buf[nfollow]; 00063 case 0: break; 00064 } 00065 return val; 00066 } 00067 00072 HTM_INLINE unsigned int htm_varint_encode(unsigned char *buf, 00073 const uint64_t val) 00074 { 00075 unsigned int n = htm_varint_len(val) - 1; 00076 buf[0] = (n << 5) | ((val >> 8*n) & 0xff); 00077 switch (n) { 00078 case 7: buf[n - 6] = (val >> 48) & 0xff; 00079 case 6: buf[n - 5] = (val >> 40) & 0xff; 00080 case 5: buf[n - 4] = (val >> 32) & 0xff; 00081 case 4: buf[n - 3] = (val >> 24) & 0xff; 00082 case 3: buf[n - 2] = (val >> 16) & 0xff; 00083 case 2: buf[n - 1] = (val >> 8) & 0xff; 00084 case 1: buf[n] = val & 0xff; 00085 case 0: break; 00086 } 00087 return n + 1; 00088 } 00089 00095 HTM_INLINE unsigned int htm_varint_rencode(unsigned char *buf, 00096 const uint64_t val) 00097 { 00098 const unsigned int m = htm_varint_len(val); 00099 unsigned int n = m - 1; 00100 buf[n] = (n << 5) | ((val >> 8*n) & 0xff); 00101 switch (n) { 00102 case 7: --n; buf[n] = (val >> 48) & 0xff; 00103 case 6: --n; buf[n] = (val >> 40) & 0xff; 00104 case 5: --n; buf[n] = (val >> 32) & 0xff; 00105 case 4: --n; buf[n] = (val >> 24) & 0xff; 00106 case 3: --n; buf[n] = (val >> 16) & 0xff; 00107 case 2: --n; buf[n] = (val >> 8) & 0xff; 00108 case 1: --n; buf[n] = val & 0xff; 00109 case 0: break; 00110 } 00111 return m; 00112 } 00113 00114 00118 #ifdef __cplusplus 00119 } 00120 #endif 00121 00122 #endif /* HTM_VARINT_H */ 00123