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 } }