rlp

package
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 1, 2020 License: Apache-2.0 Imports: 10 Imported by: 31

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var (

	// EOL is not an actual error, it just indicates the end of a list is reached during streaming
	EOL = errors.New("rlp: end of list")

	// Actual Errors
	ErrExpectedString = errors.New("rlp: expected String or Byte")
	ErrExpectedList   = errors.New("rlp: expected List")
	// when data contains leading zero bytes
	ErrCanonInt         = errors.New("rlp: non-canonical integer format")
	ErrCanonSize        = errors.New("rlp: non-canonical size information")
	ErrElemTooLarge     = errors.New("rlp: element is larger than containing list")
	ErrValueTooLarge    = errors.New("rlp: value size exceeds available input length")
	ErrMoreThanOneValue = errors.New("rlp: input contains more than one value")
)
View Source
var (
	// the reason to define these two variables is easy usability
	EmptyString = []byte{0x80}
	EmptyList   = []byte{0xC0}
)

Functions

func CountValues

func CountValues(b []byte) (int, error)

CountValues counts the number of encoded values in b (list element).

func Decode

func Decode(r io.Reader, val interface{}) error

passed in io.Reader where the encoded data is stored in val interface -> a pointer pointed to the form of data you want to decoded as for example, a specific structure, uint, list, etc. metaphor: form of storage

Example
input, _ := hex.DecodeString("C90A1486666F6F626172")

type example struct {
	A, B    uint
	private uint // private fields are ignored
	String  string
}

var s example
err := Decode(bytes.NewReader(input), &s)
if err != nil {
	fmt.Printf("Error: %v\n", err)
} else {
	fmt.Printf("Decoded value: %#v\n", s)
}
Output:

Decoded value: rlp.example{A:0xa, B:0x14, private:0x0, String:"foobar"}
Example (StructTagNil)
// In this example, we'll use the "nil" struct tag to change
// how a pointer-typed field is decoded. The input contains an RLP
// list of one element, an empty string.
input := []byte{0xC1, 0x80}

// This type uses the normal rules.
// The empty input string is decoded as a pointer to an empty Go string.
var normalRules struct {
	String *string
}
Decode(bytes.NewReader(input), &normalRules)
fmt.Printf("normal: String = %q\n", *normalRules.String)

// This type uses the struct tag.
// The empty input string is decoded as a nil pointer.
var withEmptyOK struct {
	String *string `rlp:"nil"`
}
Decode(bytes.NewReader(input), &withEmptyOK)
fmt.Printf("with nil tag: String = %v\n", withEmptyOK.String)
Output:

normal: String = ""
with nil tag: String = <nil>

func DecodeBytes

func DecodeBytes(b []byte, val interface{}) error

similar to decoder but instead of pass in a reader, pass in the encoded data directly the reader will automatically initialized as bytes reader

func Encode

func Encode(w io.Writer, val interface{}) error

The main difference between Encode and EncodeToBytes is that Encode function allows custom io.writer function to be passed in. NOTE: io.Writer is a data/variable that implements writer function

func EncodeToBytes

func EncodeToBytes(val interface{}) ([]byte, error)

function that gets empty encbuf data structure and pass into encode function

func EncodeToReader

func EncodeToReader(val interface{}) (size int, r io.Reader, err error)

EncodeToReader returns a reader from which the RLP encoding of val can be read. The returned size is the total size of the encoded data. (encoded data + list headers)

func ListSize

func ListSize(contentSize uint64) uint64

ListSize returns the encoded size of an RLP list with the given content size. For example, if content size is smaller than 56, then the headsize will be 1, and the list size will be contentsize + 1

func SplitList

func SplitList(b []byte) (content, rest []byte, err error)

SplitList splits b into the content of a list and any remaining bytes after the list.

func SplitString

func SplitString(b []byte) (content, rest []byte, err error)

SplitString splits b into the content of an RLP string and any remaining bytes after the string.

Types

type ByteReader

type ByteReader interface {
	// Reader pops out number of data based on the size of the byte slice passed in, until EOF
	io.Reader
	// ByteReader pops out only one byte data each time until EOF
	io.ByteReader
}

Any data implements io.Reader or io.ByteReader interface also implements ByteReader Interface

type Decoder

type Decoder interface {
	DecodeRLP(*Stream) error
}

Decoder interface, allows user to implement custom decoding rules or need to decode into private fields through DecodeRLP interface

Example
err := Decode(exampleReader, dataStorage)
if err != nil {
	fmt.Println(err)
}
fmt.Println(*dataStorage)
Output:

false

type Encoder

type Encoder interface {
	// the writer passed into EncodeRLP will be func (w *encbuf) Write(b []byte) if it is called through EncodeToBytes function
	// writer can be defined by user if it is not called through EncodeToBytes function
	// EncodeRLP method is user defined, which will only be used if data belongs to Encoder Interface
	EncodeRLP(io.Writer) error
}

Encoder interface allow user to define custom encoding rules or to encode private fields because for encoding encoder interface, encoder will be using EncodeRLP methods

Example
package main

import "fmt"

type struct1 struct {
	Name string
	Age  uint
}

type struct2 struct {
	name []byte
	age  []byte
}

var personTest = struct1{"mzhang", 24}
var exampleWriter struct2

func (s *struct2) Write(p []byte) (n int, err error) {
	// it will get the encoded list header first
	// then get the encoded data content
	if p[0] < 0xBF {
		nameLength := int(p[0] - 0x80)
		for i := 1; i <= nameLength; i++ {
			s.name = append(s.name, p[i])
		}

		for i := nameLength + 1; i < len(p); i++ {
			s.age = append(s.age, p[i])
		}

		return len(p) - 1, nil
	}

	// list header, ignore
	return 0, nil

}

func main() {
	err := Encode(&exampleWriter, personTest)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(exampleWriter.name)
	fmt.Println(exampleWriter.age)
}
Output:

[109 122 104 97 110 103]
[24]

type Kind

type Kind int
const (
	Byte   Kind = iota // 0
	String             // 1
	List               // 2
)

data kinds are representing with integers 0, 1, 2 (Byte, String, List)

func Split

func Split(b []byte) (k Kind, content, rest []byte, err error)

Split returns the content of first RLP value and any bytes after the value as subslices of b.

type RawValue

type RawValue []byte

type Stream

type Stream struct {
	// contains filtered or unexported fields
}

core data structure

Example
input, _ := hex.DecodeString("C90A1486666F6F626172")
s := NewStream(bytes.NewReader(input), 0)

// Check what kind of value lies ahead
kind, size, _ := s.Kind()
fmt.Printf("Kind: %v size:%d\n", kind, size)

// Enter the list
if _, err := s.List(); err != nil {
	fmt.Printf("List error: %v\n", err)
	return
}

// Decode elements
fmt.Println(s.Uint())
fmt.Println(s.Uint())
fmt.Println(s.Bytes())

// Acknowledge end of list
if err := s.ListEnd(); err != nil {
	fmt.Printf("ListEnd error: %v\n", err)
}
Output:

Kind: 2 size:9
10 <nil>
20 <nil>
[102 111 111 98 97 114] <nil>

func NewStream

func NewStream(r io.Reader, inputLimit uint64) *Stream

declare and initialize a stream pointer data, and return it

func (*Stream) Bool

func (s *Stream) Bool() (bool, error)

func (*Stream) Bytes

func (s *Stream) Bytes() ([]byte, error)

Bytes reads an RLP string and returns its contents as a byte slice. NOTE: the content here means data without string headers

func (*Stream) Decode

func (s *Stream) Decode(val interface{}) error

decoded data will be stored into the value pointed by val

func (*Stream) Kind

func (s *Stream) Kind() (kind Kind, size uint64, err error)

this function performed additional error checking criteria on information returned by readKind() returns kind && size of encoded data

func (*Stream) List

func (s *Stream) List() (size uint64, err error)

validates the encoded data to see if it is list kind stores the basic information into stack, which is the position and the size of the list data content returns the size of encoded data content

func (*Stream) ListEnd

func (s *Stream) ListEnd() error

error checking after the list was decoded and pops out the list information from the stack

func (*Stream) Raw

func (s *Stream) Raw() ([]byte, error)

function on decoding Raw type variable NOTE: rawValue stores pre-encoded data

func (*Stream) Reset

func (s *Stream) Reset(r io.Reader, inputLimit uint64)

initialize stream. Passing in the RLP encoded data to s.r and initialize other aspects

func (*Stream) Uint

func (s *Stream) Uint() (uint64, error)

calls uint function with maxbits64 returns the uint64 representation of encoded data content

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL