v2 / vlib / encoding / leb128 / leb128.v
129 lines · 121 sloc · 2.63 KB · e265e99a64771198e18e84670a28c706ab9608da
Raw
1module leb128
2
3// encode_i32 encodes the `value` as leb128 encoded byte array
4pub fn encode_i32(value i32) []u8 {
5 mut result := []u8{cap: 4}
6 mut val := value
7 mut i := 0
8 for {
9 mut b := u8(val & 0x7f)
10 val >>= 7
11 if (val == 0 && b & 0x40 == 0) || (val == -1 && b & 0x40 != 0) {
12 result << b
13 break
14 }
15 result << b | 0x80
16 i++
17 }
18 return result
19}
20
21// encode_i64 encodes the `value` as leb128 encoded byte array
22pub fn encode_i64(value i64) []u8 {
23 mut result := []u8{cap: 8}
24 mut val := value
25 for {
26 mut b := u8(val & 0x7f)
27 val >>= 7
28 if (val == 0 && b & 0x40 == 0) || (val == -1 && b & 0x40 != 0) {
29 result << b
30 break
31 }
32 result << b | 0x80
33 }
34 return result
35}
36
37// encode_u64 encodes the `value` as leb128 encoded byte array
38pub fn encode_u64(value u64) []u8 {
39 mut result := []u8{cap: 8}
40 mut val := value
41 for {
42 mut b := u8(val & 0x7f)
43 val >>= 7
44 if val == 0 {
45 result << b
46 break
47 }
48 result << b | 0x80
49 }
50 return result
51}
52
53// encode_u32 encodes the `value` as leb128 encoded byte array
54pub fn encode_u32(value u32) []u8 {
55 mut result := []u8{cap: 4}
56 mut val := value
57 for {
58 mut b := u8(val & 0x7f)
59 val >>= 7
60 if val == 0 {
61 result << b
62 break
63 }
64 result << b | 0x80
65 }
66 return result
67}
68
69// decode_i32 decodes an i32 and returns the number of bytes used from the given leb128 encoded array `value`
70pub fn decode_i32(value []u8) (i32, int) {
71 mut result := u32(0)
72 mut shift := 0
73 for b in value {
74 result |= u32(b & 0x7f) << shift
75 shift += 7
76 if b & 0x80 == 0 {
77 if shift < 32 && b & 0x40 != 0 {
78 result |= u32(~0) << shift
79 }
80 break
81 }
82 }
83 return i32(result), shift / 7
84}
85
86// decode_i64 decodes an i64 and returns the number of bytes used from the given leb128 encoded array `value`
87pub fn decode_i64(value []u8) (i64, int) {
88 mut result := u64(0)
89 mut shift := 0
90 for b in value {
91 result |= u64(b & 0x7f) << shift
92 shift += 7
93 if b & 0x80 == 0 {
94 if shift < 64 && b & 0x40 != 0 {
95 result |= ~u64(0) << shift
96 }
97 break
98 }
99 }
100 return i64(result), shift / 7
101}
102
103// decode_u64 decodes an u64 and returns the number of bytes used from the given leb128 encoded array `value`
104pub fn decode_u64(value []u8) (u64, int) {
105 mut result := u64(0)
106 mut shift := 0
107 for b in value {
108 result |= u64(b & 0x7f) << shift
109 if b & 0x80 == 0 {
110 break
111 }
112 shift += 7
113 }
114 return result, shift / 7 + 1
115}
116
117// decode_u32 decodes an u32 and returns the number of bytes used from the given leb128 encoded array `value`
118pub fn decode_u32(value []u8) (u32, int) {
119 mut result := u32(0)
120 mut shift := 0
121 for b in value {
122 result |= u32(b & 0x7f) << shift
123 if b & 0x80 == 0 {
124 break
125 }
126 shift += 7
127 }
128 return result, shift / 7 + 1
129}
130