mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-02-24 06:47:44 +01:00
147 lines
3.2 KiB
Go
147 lines
3.2 KiB
Go
|
package migration32
|
||
|
|
||
|
import (
|
||
|
"encoding/binary"
|
||
|
"fmt"
|
||
|
"io"
|
||
|
|
||
|
"github.com/btcsuite/btcd/wire"
|
||
|
lnwire "github.com/lightningnetwork/lnd/channeldb/migration/lnwire21"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
// Big endian is the preferred byte order, due to cursor scans over
|
||
|
// integer keys iterating in order.
|
||
|
byteOrder = binary.BigEndian
|
||
|
)
|
||
|
|
||
|
// ReadElement is a one-stop utility function to deserialize any datastructure
|
||
|
// encoded using the serialization format of the database.
|
||
|
func ReadElement(r io.Reader, element interface{}) error {
|
||
|
switch e := element.(type) {
|
||
|
case *uint32:
|
||
|
if err := binary.Read(r, byteOrder, e); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
case *lnwire.MilliSatoshi:
|
||
|
var a uint64
|
||
|
if err := binary.Read(r, byteOrder, &a); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
*e = lnwire.MilliSatoshi(a)
|
||
|
|
||
|
case *[]byte:
|
||
|
bytes, err := wire.ReadVarBytes(r, 0, 66000, "[]byte")
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
*e = bytes
|
||
|
|
||
|
case *int64, *uint64:
|
||
|
if err := binary.Read(r, byteOrder, e); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
case *bool:
|
||
|
if err := binary.Read(r, byteOrder, e); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
case *int32:
|
||
|
if err := binary.Read(r, byteOrder, e); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
default:
|
||
|
return UnknownElementType{"ReadElement", e}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// ReadElements deserializes a variable number of elements into the passed
|
||
|
// io.Reader, with each element being deserialized according to the ReadElement
|
||
|
// function.
|
||
|
func ReadElements(r io.Reader, elements ...interface{}) error {
|
||
|
for _, element := range elements {
|
||
|
err := ReadElement(r, element)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// UnknownElementType is an error returned when the codec is unable to encode or
|
||
|
// decode a particular type.
|
||
|
type UnknownElementType struct {
|
||
|
method string
|
||
|
element interface{}
|
||
|
}
|
||
|
|
||
|
// Error returns the name of the method that encountered the error, as well as
|
||
|
// the type that was unsupported.
|
||
|
func (e UnknownElementType) Error() string {
|
||
|
return fmt.Sprintf("Unknown type in %s: %T", e.method, e.element)
|
||
|
}
|
||
|
|
||
|
// WriteElement is a one-stop shop to write the big endian representation of
|
||
|
// any element which is to be serialized for storage on disk. The passed
|
||
|
// io.Writer should be backed by an appropriately sized byte slice, or be able
|
||
|
// to dynamically expand to accommodate additional data.
|
||
|
func WriteElement(w io.Writer, element interface{}) error {
|
||
|
switch e := element.(type) {
|
||
|
case int64, uint64:
|
||
|
if err := binary.Write(w, byteOrder, e); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
case uint32:
|
||
|
if err := binary.Write(w, byteOrder, e); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
case int32:
|
||
|
if err := binary.Write(w, byteOrder, e); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
case bool:
|
||
|
if err := binary.Write(w, byteOrder, e); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
case lnwire.MilliSatoshi:
|
||
|
if err := binary.Write(w, byteOrder, uint64(e)); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
case []byte:
|
||
|
if err := wire.WriteVarBytes(w, 0, e); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
default:
|
||
|
return UnknownElementType{"WriteElement", e}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// WriteElements is writes each element in the elements slice to the passed
|
||
|
// io.Writer using WriteElement.
|
||
|
func WriteElements(w io.Writer, elements ...interface{}) error {
|
||
|
for _, element := range elements {
|
||
|
err := WriteElement(w, element)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|