byteio - bigendianwriter_varint.go
1 package byteio
2
3 // maxBENineByte is the largest number that would be stored in 63 bits with
4 // this varint format without using a special case.
5 // This is needed to we can shift the bits to store the last bit within the
6 // carry bit of the ninth byte
7 // The byte structure would be as follows: -
8 // [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f]
9 // With the high bit of each of the first 8 bytes being the carry bit, this
10 // would lead to a number of 0xffffffffffffff7f, except that the carry bit also
11 // adds one to the value of each byte.
12 // Thus, we end up with a value of 0x80 for the first eight bytes, and 0x7f for
13 // the last.
14 // Numbers greater than this value use the high bit of the ninth byte to store
15 // the eighth bit of the number, shifting the remaining bits down by one.
16 const maxBENineByte = 0x80<<56 | 0x80<<49 | 0x80<<42 | 0x80<<35 | 0x80<<28 | 0x80<<21 | 0x80<<14 | 0x80<<7 | 0x7f
17
18 // WriteUintX writes the unsigned integer using a variable number of bytes
19 func (e *BigEndianWriter) WriteUintX(d uint64) (int, error) {
20 pos := 8
21 if d > maxBENineByte {
22 e.buffer[8] = byte(d)
23 d >>= 8
24 } else {
25 e.buffer[8] = byte(d & 0x7f)
26 d >>= 7
27 }
28 for ; d > 0; d >>= 7 {
29 pos--
30 d--
31 e.buffer[pos] = byte(d&0x7f) | 0x80
32 }
33 return e.Write(e.buffer[pos:])
34 }
35
36 // WriteIntX writes the integer using a variable number of bytes
37 func (e *BigEndianWriter) WriteIntX(d int64) (int, error) {
38 return e.WriteUintX(zigzag(d))
39 }
40