-
Notifications
You must be signed in to change notification settings - Fork 13
/
varint.c
87 lines (81 loc) · 3.26 KB
/
varint.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include "varint.h"
#include "config.h"
const sqlite3_api_routines *sqlite3_api;
#include <stdint.h>
#define VARINT_END_BITMASK (1 << (BITSPERBYTE - 1))
/** Read integer in varint encoding from pBuf, return it as *out
* Returns number of bytes read.
*/
int readVarInt(unsigned char *pBuf, sqlite3_int64 *out){
/* Yes, it's ugly to unroll a loop manually, I didn't test to see if it's */
/* faster, it was just easier to write it this way without having unecessary */
/* checks all over the place. Also I don't see any reason to waste time */
/* designing a smart loop, when this works, and probably is faster :) */
*out = 0;
/* Read byte 0 */
*out |= (sqlite3_int64)(pBuf[0] & ~VARINT_END_BITMASK);
if(pBuf[0] & VARINT_END_BITMASK) return 1;
/* Read byte 1 */
*out |= ((sqlite3_int64)(pBuf[1] & ~VARINT_END_BITMASK)) << 7;
if(pBuf[1] & VARINT_END_BITMASK) return 2;
/* Read byte 2 */
*out |= ((sqlite3_int64)(pBuf[2] & ~VARINT_END_BITMASK)) << (7 * 2);
if(pBuf[2] & VARINT_END_BITMASK) return 3;
/* Read byte 3 */
*out |= ((sqlite3_int64)(pBuf[3] & ~VARINT_END_BITMASK)) << (7 * 3);
if(pBuf[3] & VARINT_END_BITMASK) return 4;
/* Read byte 4 */
*out |= ((sqlite3_int64)(pBuf[4] & ~VARINT_END_BITMASK)) << (7 * 4);
if(pBuf[4] & VARINT_END_BITMASK) return 5;
/* Read byte 5 */
*out |= ((sqlite3_int64)(pBuf[5] & ~VARINT_END_BITMASK)) << (7 * 5);
if(pBuf[5] & VARINT_END_BITMASK) return 6;
/* Read byte 6 */
*out |= ((sqlite3_int64)(pBuf[6] & ~VARINT_END_BITMASK)) << (7 * 6);
if(pBuf[6] & VARINT_END_BITMASK) return 7;
/* Read byte 7 */
*out |= ((sqlite3_int64)(pBuf[7] & ~VARINT_END_BITMASK)) << (7 * 7);
if(pBuf[7] & VARINT_END_BITMASK) return 8;
/* Read byte 8 (starting from 0) */
*out |= ((sqlite3_int64)pBuf[8]) << (7 * 8);
return 9;
}
/** Write an integer in varint encoding to pBuf
* Returns number of bytes written */
int writeVarInt(unsigned char *pBuf, sqlite3_int64 input){
/* Write byte 0 */
pBuf[0] = ((unsigned char)input) & ~VARINT_END_BITMASK;
input = input >> 7;
if(input == 0){ pBuf[0] |= VARINT_END_BITMASK; return 1;}
/* Write byte 1 */
pBuf[1] = ((unsigned char)input) & ~VARINT_END_BITMASK;
input = input >> 7;
if(input == 0){ pBuf[1] |= VARINT_END_BITMASK; return 2;}
/* Write byte 2 */
pBuf[2] = ((unsigned char)input) & ~VARINT_END_BITMASK;
input = input >> 7;
if(input == 0){ pBuf[2] |= VARINT_END_BITMASK; return 3;}
/* Write byte 3 */
pBuf[3] = ((unsigned char)input) & ~VARINT_END_BITMASK;
input = input >> 7;
if(input == 0){ pBuf[3] |= VARINT_END_BITMASK; return 4;}
/* Write byte 4 */
pBuf[4] = ((unsigned char)input) & ~VARINT_END_BITMASK;
input = input >> 7;
if(input == 0){ pBuf[4] |= VARINT_END_BITMASK; return 5;}
/* Write byte 5 */
pBuf[5] = ((unsigned char)input) & ~VARINT_END_BITMASK;
input = input >> 7;
if(input == 0){ pBuf[5] |= VARINT_END_BITMASK; return 6;}
/* Write byte 6 */
pBuf[6] = ((unsigned char)input) & ~VARINT_END_BITMASK;
input = input >> 7;
if(input == 0){ pBuf[6] |= VARINT_END_BITMASK; return 7;}
/* Write byte 7 */
pBuf[7] = ((unsigned char)input) & ~VARINT_END_BITMASK;
input = input >> 7;
if(input == 0){ pBuf[7] |= VARINT_END_BITMASK; return 8;}
/* Write byte 8 (starting from 0) */
pBuf[8] = ((unsigned char)input);
return 9;
}