mirror of
https://github.com/muun/recovery.git
synced 2025-11-10 14:09:50 -05:00
Release v0.3.0
This commit is contained in:
207
vendor/github.com/lightningnetwork/lnd/tlv/truncated.go
generated
vendored
Normal file
207
vendor/github.com/lightningnetwork/lnd/tlv/truncated.go
generated
vendored
Normal file
@@ -0,0 +1,207 @@
|
||||
package tlv
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"io"
|
||||
)
|
||||
|
||||
// ErrTUintNotMinimal signals that decoding a truncated uint failed because the
|
||||
// value was not minimally encoded.
|
||||
var ErrTUintNotMinimal = errors.New("truncated uint not minimally encoded")
|
||||
|
||||
// numLeadingZeroBytes16 computes the number of leading zeros for a uint16.
|
||||
func numLeadingZeroBytes16(v uint16) uint64 {
|
||||
switch {
|
||||
case v == 0:
|
||||
return 2
|
||||
case v&0xff00 == 0:
|
||||
return 1
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
// SizeTUint16 returns the number of bytes remaining in a uint16 after
|
||||
// truncating the leading zeros.
|
||||
func SizeTUint16(v uint16) uint64 {
|
||||
return 2 - numLeadingZeroBytes16(v)
|
||||
}
|
||||
|
||||
// ETUint16 is an Encoder for truncated uint16 values, where leading zeros will
|
||||
// be omitted. An error is returned if val is not a *uint16.
|
||||
func ETUint16(w io.Writer, val interface{}, buf *[8]byte) error {
|
||||
if t, ok := val.(*uint16); ok {
|
||||
binary.BigEndian.PutUint16(buf[:2], *t)
|
||||
numZeros := numLeadingZeroBytes16(*t)
|
||||
_, err := w.Write(buf[numZeros:2])
|
||||
return err
|
||||
}
|
||||
return NewTypeForEncodingErr(val, "uint16")
|
||||
}
|
||||
|
||||
// ETUint16T is an Encoder for truncated uint16 values, where leading zeros will
|
||||
// be omitted. An error is returned if val is not a *uint16.
|
||||
func ETUint16T(w io.Writer, val uint16, buf *[8]byte) error {
|
||||
binary.BigEndian.PutUint16(buf[:2], val)
|
||||
numZeros := numLeadingZeroBytes16(val)
|
||||
_, err := w.Write(buf[numZeros:2])
|
||||
return err
|
||||
}
|
||||
|
||||
// DTUint16 is an Decoder for truncated uint16 values, where leading zeros will
|
||||
// be resurrected. An error is returned if val is not a *uint16.
|
||||
func DTUint16(r io.Reader, val interface{}, buf *[8]byte, l uint64) error {
|
||||
if t, ok := val.(*uint16); ok && l <= 2 {
|
||||
_, err := io.ReadFull(r, buf[2-l:2])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
zero(buf[:2-l])
|
||||
*t = binary.BigEndian.Uint16(buf[:2])
|
||||
if 2-numLeadingZeroBytes16(*t) != l {
|
||||
return ErrTUintNotMinimal
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return NewTypeForDecodingErr(val, "uint16", l, 2)
|
||||
}
|
||||
|
||||
// numLeadingZeroBytes16 computes the number of leading zeros for a uint32.
|
||||
func numLeadingZeroBytes32(v uint32) uint64 {
|
||||
switch {
|
||||
case v == 0:
|
||||
return 4
|
||||
case v&0xffffff00 == 0:
|
||||
return 3
|
||||
case v&0xffff0000 == 0:
|
||||
return 2
|
||||
case v&0xff000000 == 0:
|
||||
return 1
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
// SizeTUint32 returns the number of bytes remaining in a uint32 after
|
||||
// truncating the leading zeros.
|
||||
func SizeTUint32(v uint32) uint64 {
|
||||
return 4 - numLeadingZeroBytes32(v)
|
||||
}
|
||||
|
||||
// ETUint32 is an Encoder for truncated uint32 values, where leading zeros will
|
||||
// be omitted. An error is returned if val is not a *uint32.
|
||||
func ETUint32(w io.Writer, val interface{}, buf *[8]byte) error {
|
||||
if t, ok := val.(*uint32); ok {
|
||||
binary.BigEndian.PutUint32(buf[:4], *t)
|
||||
numZeros := numLeadingZeroBytes32(*t)
|
||||
_, err := w.Write(buf[numZeros:4])
|
||||
return err
|
||||
}
|
||||
return NewTypeForEncodingErr(val, "uint32")
|
||||
}
|
||||
|
||||
// ETUint32T is an Encoder for truncated uint32 values, where leading zeros will
|
||||
// be omitted. An error is returned if val is not a *uint32.
|
||||
func ETUint32T(w io.Writer, val uint32, buf *[8]byte) error {
|
||||
binary.BigEndian.PutUint32(buf[:4], val)
|
||||
numZeros := numLeadingZeroBytes32(val)
|
||||
_, err := w.Write(buf[numZeros:4])
|
||||
return err
|
||||
}
|
||||
|
||||
// DTUint32 is an Decoder for truncated uint32 values, where leading zeros will
|
||||
// be resurrected. An error is returned if val is not a *uint32.
|
||||
func DTUint32(r io.Reader, val interface{}, buf *[8]byte, l uint64) error {
|
||||
if t, ok := val.(*uint32); ok && l <= 4 {
|
||||
_, err := io.ReadFull(r, buf[4-l:4])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
zero(buf[:4-l])
|
||||
*t = binary.BigEndian.Uint32(buf[:4])
|
||||
if 4-numLeadingZeroBytes32(*t) != l {
|
||||
return ErrTUintNotMinimal
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return NewTypeForDecodingErr(val, "uint32", l, 4)
|
||||
}
|
||||
|
||||
// numLeadingZeroBytes64 computes the number of leading zeros for a uint32.
|
||||
//
|
||||
// TODO(conner): optimize using unrolled binary search
|
||||
func numLeadingZeroBytes64(v uint64) uint64 {
|
||||
switch {
|
||||
case v == 0:
|
||||
return 8
|
||||
case v&0xffffffffffffff00 == 0:
|
||||
return 7
|
||||
case v&0xffffffffffff0000 == 0:
|
||||
return 6
|
||||
case v&0xffffffffff000000 == 0:
|
||||
return 5
|
||||
case v&0xffffffff00000000 == 0:
|
||||
return 4
|
||||
case v&0xffffff0000000000 == 0:
|
||||
return 3
|
||||
case v&0xffff000000000000 == 0:
|
||||
return 2
|
||||
case v&0xff00000000000000 == 0:
|
||||
return 1
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
// SizeTUint64 returns the number of bytes remaining in a uint64 after
|
||||
// truncating the leading zeros.
|
||||
func SizeTUint64(v uint64) uint64 {
|
||||
return 8 - numLeadingZeroBytes64(v)
|
||||
}
|
||||
|
||||
// ETUint64 is an Encoder for truncated uint64 values, where leading zeros will
|
||||
// be omitted. An error is returned if val is not a *uint64.
|
||||
func ETUint64(w io.Writer, val interface{}, buf *[8]byte) error {
|
||||
if t, ok := val.(*uint64); ok {
|
||||
binary.BigEndian.PutUint64(buf[:], *t)
|
||||
numZeros := numLeadingZeroBytes64(*t)
|
||||
_, err := w.Write(buf[numZeros:])
|
||||
return err
|
||||
}
|
||||
return NewTypeForEncodingErr(val, "uint64")
|
||||
}
|
||||
|
||||
// ETUint64T is an Encoder for truncated uint64 values, where leading zeros will
|
||||
// be omitted. An error is returned if val is not a *uint64.
|
||||
func ETUint64T(w io.Writer, val uint64, buf *[8]byte) error {
|
||||
binary.BigEndian.PutUint64(buf[:], val)
|
||||
numZeros := numLeadingZeroBytes64(val)
|
||||
_, err := w.Write(buf[numZeros:])
|
||||
return err
|
||||
}
|
||||
|
||||
// DTUint64 is an Decoder for truncated uint64 values, where leading zeros will
|
||||
// be resurrected. An error is returned if val is not a *uint64.
|
||||
func DTUint64(r io.Reader, val interface{}, buf *[8]byte, l uint64) error {
|
||||
if t, ok := val.(*uint64); ok && l <= 8 {
|
||||
_, err := io.ReadFull(r, buf[8-l:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
zero(buf[:8-l])
|
||||
*t = binary.BigEndian.Uint64(buf[:])
|
||||
if 8-numLeadingZeroBytes64(*t) != l {
|
||||
return ErrTUintNotMinimal
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return NewTypeForDecodingErr(val, "uint64", l, 8)
|
||||
}
|
||||
|
||||
// zero clears the passed byte slice.
|
||||
func zero(b []byte) {
|
||||
for i := range b {
|
||||
b[i] = 0x00
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user