109 lines
1.9 KiB
Plaintext
109 lines
1.9 KiB
Plaintext
package bin
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
)
|
|
|
|
func PutVarInt32(w io.Writer, num int) (int, error) {
|
|
if num > 2147483647 {
|
|
return 0, fmt.Errorf("num %d overflows int32", num)
|
|
}
|
|
arr := make([]byte, 5)
|
|
for i := 0; i < 4; i++ {
|
|
arr[i] = byte(num & 127)
|
|
num >>= 7
|
|
if num == 0 {
|
|
arr[i] |= 128
|
|
return w.Write(arr[:i+1])
|
|
}
|
|
}
|
|
// в последнем 9м байте все биты значащие
|
|
arr[5] = byte(num)
|
|
return w.Write(arr)
|
|
}
|
|
|
|
func VarInt32(src io.ByteReader) (num int, err error) {
|
|
var (
|
|
b byte
|
|
off uint
|
|
)
|
|
for ; off < 28; off += 7 {
|
|
b, err = src.ReadByte()
|
|
if err != nil {
|
|
return
|
|
}
|
|
if b < 128 {
|
|
num |= int(b) << off
|
|
} else {
|
|
num |= int(b&127) << off
|
|
return
|
|
}
|
|
}
|
|
|
|
b, err = src.ReadByte()
|
|
if err != nil {
|
|
return
|
|
}
|
|
// в последнем 9м байте все биты значащие
|
|
num |= int(b&7) << 28
|
|
return
|
|
}
|
|
|
|
func PutVarUint(arr []byte, num uint64) int {
|
|
for i := 0; i < 8; i++ {
|
|
arr[i] = byte(num & 127)
|
|
num >>= 7
|
|
if num == 0 {
|
|
arr[i] |= 128
|
|
return i + 1
|
|
}
|
|
}
|
|
// в последнем 9м байте все биты значащие
|
|
arr[8] = byte(num)
|
|
return 9
|
|
}
|
|
|
|
func VarUint(src io.ByteReader) (num uint64, err error) {
|
|
var (
|
|
b byte
|
|
off uint
|
|
)
|
|
for ; off < 56; off += 7 {
|
|
b, err = src.ReadByte()
|
|
if err != nil {
|
|
return
|
|
}
|
|
if b < 128 {
|
|
num |= uint64(b) << off
|
|
} else {
|
|
num |= uint64(b&127) << off
|
|
return
|
|
}
|
|
}
|
|
|
|
b, err = src.ReadByte()
|
|
if err != nil {
|
|
return
|
|
}
|
|
// в последнем 9м байте все биты значащие
|
|
num |= uint64(b) << 56
|
|
return
|
|
}
|
|
|
|
/*
|
|
func PackVarUint32(num int) (err error) {
|
|
idx := 0
|
|
for num > 127 {
|
|
s.vint[idx] = byte(num & 127)
|
|
num >>= 7
|
|
idx++
|
|
}
|
|
// Даже в последнем байте отсекаем старший бит (знак)
|
|
s.vint[idx] = byte(num&127) | 128
|
|
|
|
_, err = s.dst.Write(s.vint[:idx+1])
|
|
return
|
|
}
|
|
*/
|