The Tiny HTM Library
include/tinyhtm/varint.h
Go to the documentation of this file.
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