-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvlcode.go
More file actions
61 lines (50 loc) · 1.58 KB
/
Copy pathvlcode.go
File metadata and controls
61 lines (50 loc) · 1.58 KB
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
// Package vlcode implements an SMF styled Variable Length Code (VLC) Encoder and Decoder.
package vlcode
import "math/bits"
const Version = "1.0.0"
// Encode encodes a uint into a Variable Length Code (VLC) byte array.
// It follows the SMF styled VLC encoding scheme.
func Encode(v uint) []byte {
// Determine the number of bits needed to represent v
n_bits := bits.Len(v)
if n_bits == 0 {
return []byte{0x00}
}
// Calculate the number of bytes required for the encoded VLC
n_bytes := (n_bits + 6) / 7
// Create a byte slice to hold the encoded VLC
bytes := make([]byte, n_bytes)
bytes[n_bytes-1] = byte(v & 0x7F)
// Encode v into bytes using SMF styled VLC encoding
for i := n_bytes - 2; i >= 0; i-- {
shift := (n_bytes - 1 - i) * 7
bytes[i] = byte((v >> shift) & 0x7F) | 0x80
}
return bytes
}
// Decode decodes a Variable Length Code (VLC) byte array into a uint.
// It follows the SMF styled VLC decoding scheme.
// Returns the decoded value and the number of bytes read from b.
func Decode(b []byte) (uint, uint) {
sz := uint(len(b))
if sz == 0 {
return 0, 0
}
n_left := sz - 1
value := uint(b[0] & 0x7F)
if b[0]&0x80 != 0 {
// Decode bytes using SMF styled VLC decoding
for i := uint(1); i < sz; i++ {
if n_left == 0 {
return 0, 0
}
value <<= 7
value |= uint(b[i] & 0x7F)
if b[i]&0x80 == 0 {
break
}
n_left--
}
}
return value, (sz - n_left)
}