52 lines
1.4 KiB
Go
52 lines
1.4 KiB
Go
package ledger
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"fmt"
|
|
|
|
"github.com/golang/protobuf/proto"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
func EncodeUint64(number uint64) []byte {
|
|
bytes := make([]byte, 8)
|
|
binary.BigEndian.PutUint64(bytes, number)
|
|
startingIndex := 0
|
|
size := 0
|
|
for i, b := range bytes {
|
|
if b != 0x00 {
|
|
startingIndex = i
|
|
size = 8 - i
|
|
break
|
|
}
|
|
}
|
|
sizeBytes := proto.EncodeVarint(uint64(size))
|
|
if len(sizeBytes) > 1 {
|
|
panic(fmt.Errorf("[]sizeBytes should not be more than one byte because the max number it needs to hold is 8. size=%d", size))
|
|
}
|
|
encodedBytes := make([]byte, size+1)
|
|
encodedBytes[0] = sizeBytes[0]
|
|
copy(encodedBytes[1:], bytes[startingIndex:])
|
|
return encodedBytes
|
|
}
|
|
|
|
func DecodeUint64(bytes []byte) (uint64, int, error) {
|
|
s, numBytes := proto.DecodeVarint(bytes)
|
|
|
|
switch {
|
|
case numBytes != 1:
|
|
return 0, 0, errors.Errorf("number of consumed bytes from DecodeVarint is invalid, expected 1, but got %d", numBytes)
|
|
case s > 8:
|
|
return 0, 0, errors.Errorf("decoded size from DecodeVarint is invalid, expected <=8, but got %d", s)
|
|
case int(s) > len(bytes)-1:
|
|
return 0, 0, errors.Errorf("decoded size (%d) from DecodeVarint is more than available bytes (%d)", s, len(bytes)-1)
|
|
default:
|
|
// no error
|
|
size := int(s)
|
|
decodedBytes := make([]byte, 8)
|
|
copy(decodedBytes[8-size:], bytes[1:size+1])
|
|
numBytesConsumed := size + 1
|
|
return binary.BigEndian.Uint64(decodedBytes), numBytesConsumed, nil
|
|
}
|
|
}
|