2 * UCW Library -- Coding of u64 into variable length bytecode.
4 * (c) 2013 Tomas Valla <tom@ucw.cz>
6 * This software may be freely distributed and used according to the terms
7 * of the GNU Lesser General Public License.
11 #include <ucw/varint.h>
13 #define PUTB(j,i) p[j] = (byte)((u >> (8*(i))));
14 #define PUTB4(b) PUTB(0,b-1) PUTB(1,b-2) PUTB(2,b-3) PUTB(3,b-4)
15 uint varint_put_big(byte *p, u64 u)
17 ASSERT(u >= VARINT_SHIFT_L4);
19 if (u < VARINT_SHIFT_L5) {
26 if (u < VARINT_SHIFT_L6) {
33 if (u < VARINT_SHIFT_L7) {
37 PUTB(4,2) PUTB(5,1) PUTB(6,0)
40 if (u < VARINT_SHIFT_L8) {
43 PUTB(1,6) PUTB(2,5) PUTB(3,4) PUTB(4,3)
44 PUTB(5,2) PUTB(6,1) PUTB(7,0)
49 PUTB(1,7) PUTB(2,6) PUTB(3,5) PUTB(4,4)
50 PUTB(5,3) PUTB(6,2) PUTB(7,1) PUTB(8,0)
54 const byte *varint_get_big(const byte *p, u64 *r)
56 ASSERT((*p & 0xf0) == 0xf0);
60 *r = (u64)(p[0] & 7)<<32 | (u64)p[1]<<24 | (u64)p[2]<<16 | (u64)p[3]<<8 | (u64)p[4];
61 *r += VARINT_SHIFT_L4;
65 *r = (u64)(p[0] & 3)<<40 | (u64)p[1]<<32 | (u64)p[2]<<24 | (u64)p[3]<<16 | (u64)p[4]<<8 | (u64)p[5];
66 *r += VARINT_SHIFT_L5;
70 *r = (u64)(p[0] & 1)<<48 | (u64)p[1]<<40 | (u64)p[2]<<32 | (u64)p[3]<<24 | (u64)p[4]<<16 | (u64)p[5]<<8 | (u64)p[6];
71 *r += VARINT_SHIFT_L6;
75 *r = (u64)p[1]<<48 | (u64)p[2]<<40 | (u64)p[3]<<32 | (u64)p[4]<<24 | (u64)p[5]<<16 | (u64)p[6]<<8 | (u64)p[7];
76 *r += VARINT_SHIFT_L7;
79 *r = ((u64)p[1] << 56) | ((u64)p[2] << 48) | ((u64)p[3] << 40) | ((u64)p[4] << 32) | ((u64)p[5] << 24) | ((u64)p[6] << 16) | ((u64)p[7] << 8) | (u64)p[8];
80 *r += VARINT_SHIFT_L8;
91 int main(int argc, char **argv UNUSED)
93 byte buf[16] = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
96 if (scanf("%"SCNx64, &u) != 1) {
97 fprintf(stderr, "Invalid usage!\n");
101 int l = varint_len(buf[0]);
103 printf("%u %d %jx", varint_space(u), l, (uintmax_t) u);
105 for (int i=0; i<l; i++)
106 printf(" %x", buf[i]);