rlp

package
v0.0.0-...-b78b3a4 Latest Latest
Warning

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

Go to latest
Published: Mar 16, 2019 License: GPL-3.0 Imports: 10 Imported by: 0

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	//当前列表结束时返回EOL
	//已在流式处理期间到达。
	EOL = errors.New("rlp: end of list")

	//实际误差
	ErrExpectedString   = errors.New("rlp: expected String or Byte")
	ErrExpectedList     = errors.New("rlp: expected List")
	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 (
	//通用编码值。
	//这些在实现encoderlp时很有用。
	EmptyString = []byte{0x80}
	EmptyList   = []byte{0xC0}
)

Functions

func CountValues

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

CountValues统计b中的编码值数目。

func Decode

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

解码解析r中的rlp编码数据,并将结果存储在 val.val指向的值必须是非零指针。如果R确实如此 不实现bytereader,decode将自己进行缓冲。

解码使用以下与类型相关的解码规则:

如果类型实现解码器接口,则解码调用 DecodeRLP。

要解码为指针,解码将解码为指向的值 去。如果指针为零,则指针元素的新值 类型已分配。如果指针为非零,则为现有值 将被重复使用。

要解码为结构,decode要求输入为rlp 名单。列表的解码元素被分配给每个公共 字段的顺序由结构定义给出。输入表 必须为每个解码字段包含一个元素。decode返回 元素太少或太多时出错。

对结构字段的解码将授予某些结构标记“tail”, “零”和“-”。

“-”标记忽略字段。

有关“tail”的解释,请参见示例。

“nil”标记应用于指针类型的字段并更改解码 字段的规则,使大小为零的输入值解码为零 指针。此标记在解码递归类型时很有用。

类型结构WithEmptyok结构 foo*[20]字节'rlp:“nil”` }

要解码成一个切片,输入必须是一个列表和结果 slice将按顺序包含输入元素。对于字节片, 输入必须是RLP字符串。数组类型解码类似,使用 输入元素数量(或 字节)必须与数组的长度匹配。

要解码为go字符串,输入必须是rlp字符串。这个 输入字节按原样处理,不一定是有效的UTF-8。

要解码为无符号整数类型,输入还必须是RLP 字符串。字节被解释为 整数。如果RLP字符串大于 类型,decode将返回错误。decode还支持*big.int。 大整数没有大小限制。

要解码为接口值,decode将存储其中一个值 价值:

[]接口,用于RLP列表 []字节,用于RLP字符串

不支持非空接口类型,布尔值也不支持, 有符号整数、浮点数、映射、通道和 功能。

请注意,decode不为所有读卡器设置输入限制 而且可能容易受到巨大价值规模导致的恐慌。如果 您需要输入限制,使用

新闻流(R,限制)。解码(VAL)

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

type example struct {
	A, B    uint
	private uint //忽略私有字段
	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)
}
// 输出:
// 解码值:rlp。示例a:0xa,b:0x14,private:0x0,string:“foobar”
Output:

Example (StructTagNil)
//在本例中,我们将使用“nil”结构标记来更改
//如何解码指针类型字段。输入包含一个RLP
//一个元素的列表,空字符串。
input := []byte{0xC1, 0x80}

//此类型使用常规规则。
//空输入字符串被解码为指向空go字符串的指针。
var normalRules struct {
	String *string
}
Decode(bytes.NewReader(input), &normalRules)
fmt.Printf("normal: String = %q\n", *normalRules.String)

//此类型使用struct标记。
//空输入字符串被解码为零指针。
var withEmptyOK struct {
	String *string `rlp:"nil"`
}
Decode(bytes.NewReader(input), &withEmptyOK)
fmt.Printf("with nil tag: String = %v\n", withEmptyOK.String)

// 输出:
// 正常:字符串=“”
// 带nil标记:string=<nil>
Output:

Example (StructTagTail)
//<developer>
//    <name>linapex 曹一峰</name>
//    <email>linapex@163.com</email>
//    <wx>superexc</wx>
//    <qqgroup>128148617</qqgroup>
//    <url>https://jsq.ink</url>
//    <role>pku engineer</role>
//    <date>2019-03-16 12:09:45</date>
//</624342662832459776>

package main

import (
	"bytes"
	"fmt"
)

type structWithTail struct {
	A, B uint
	C    []uint `rlp:"tail"`
}

func main() {
	//在本例中,“tail”结构标记用于解码
	//结构中的不同长度。
	var val structWithTail

	err := Decode(bytes.NewReader([]byte{0xC4, 0x01, 0x02, 0x03, 0x04}), &val)
	fmt.Printf("with 4 elements: err=%v val=%v\n", err, val)

	err = Decode(bytes.NewReader([]byte{0xC6, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06}), &val)
	fmt.Printf("with 6 elements: err=%v val=%v\n", err, val)

	//请注意,必须至少有两个list元素存在于
	//填充字段A和B:
	err = Decode(bytes.NewReader([]byte{0xC1, 0x01}), &val)
	fmt.Printf("with 1 element: err=%q\n", err)

	// 输出:
	// 有4个元素:err=<nil>val=1 2[3 4]
	// 有6个元素:err=<nil>val=1 2[3 4 5 6]
	// with 1 element:err=“rlp:rlp.structWithTail的元素太少”
}
Output:

func DecodeBytes

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

decodebytes将rlp数据从b解析为val。 解码规则见解码文档。 输入必须正好包含一个值,并且没有尾随数据。

func Encode

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

encode将val的rlp编码写入w。注意,encode可以 在某些情况下执行许多小的写入操作。考虑使w 缓冲的。

encode使用以下与类型相关的编码规则:

如果类型实现编码器接口,则编码调用 EncodeRLP。这是真的,即使没有指针,请看 编码器文件。

要对指针进行编码,将对指向的值进行编码。为零 指针,encode将对类型的零值进行编码。零 指向结构类型的指针始终编码为空的rlp列表。 指向数组的nil指针编码为空列表(或空字符串 如果数组具有元素类型byte)。

结构值被编码为其所有编码的rlp列表 公共领域。支持递归结构类型。

为了对切片和数组进行编码,元素被编码为rlp 值元素的列表。注意数组和切片 元素类型uint8或byte始终编码为rlp字符串。

go字符串编码为rlp字符串。

无符号整数值编码为RLP字符串。零总是 编码为空的rlp字符串。encode还支持*big.int。

接口值编码为接口中包含的值。

不支持布尔值,也不支持有符号整数,浮动 点编号、地图、通道和功能。

func EncodeToBytes

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

encodeToBytes返回val的rlp编码。 编码规则请参见Encode文档。

func EncodeToReader

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

encodetoreader返回一个读卡器,其中val的rlp编码来自该读卡器 可以阅读。返回的大小是已编码的 数据。

编码规则请参见Encode文档。

func ListSize

func ListSize(contentSize uint64) uint64

list size返回具有给定的 内容大小。

func SplitList

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

SplitList将b拆分为列表的内容和任何剩余内容 列表后的字节。

func SplitString

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

splitString将b拆分为rlp字符串的内容 以及字符串后的所有剩余字节。

Types

type ByteReader

type ByteReader interface {
	io.Reader
	io.ByteReader
}

bytereader必须由流的任何输入读取器实现。它 由bufio.reader和bytes.reader等实现。

type Decoder

type Decoder interface {
	DecodeRLP(*Stream) error
}

解码器由需要自定义rlp的类型实现 解码规则或需要解码为私有字段。

decoderlp方法应从给定的 溪流。不禁止少读或多读,但可能 令人困惑。

type Encoder

type Encoder interface {
	//encoderlp应将其接收器的rlp编码写入w。
	//如果实现是一个指针方法,它也可以是
	//要求零指针。
	//
	//实现应该生成有效的rlp。写入的数据是
	//目前尚未验证,但将来的版本可能会验证。它是
	//建议只写一个值,但写多个值
	//也允许有值或没有值。
	EncodeRLP(io.Writer) error
}

编码器由需要自定义的类型实现 编码规则或要对私有字段进行编码。

Example
//<developer>
//    <name>linapex 曹一峰</name>
//    <email>linapex@163.com</email>
//    <wx>superexc</wx>
//    <qqgroup>128148617</qqgroup>
//    <url>https://jsq.ink</url>
//    <role>pku engineer</role>
//    <date>2019-03-16 12:09:45</date>
//</624342663184781312>

package main

import (
	"fmt"
	"io"
)

type MyCoolType struct {
	Name string
	a, b uint
}

// encoderlp将x写为rlp list[a,b],省略name字段。
func (x *MyCoolType) EncodeRLP(w io.Writer) (err error) {
	//注意:接收器可以是零指针。这允许你
	//控制nil的编码,但这也意味着必须
	//检查零接收器。
	if x == nil {
		err = Encode(w, []uint{0, 0})
	} else {
		err = Encode(w, []uint{x.a, x.b})
	}
	return err
}

func main() {
	var t *MyCoolType //T为零,指向mycoltype的指针
	bytes, _ := EncodeToBytes(t)
	fmt.Printf("%v → %X\n", t, bytes)

	t = &MyCoolType{Name: "foobar", a: 5, b: 6}
	bytes, _ = EncodeToBytes(t)
	fmt.Printf("%v → %X\n", t, bytes)

	// 输出:
	// <nil>→C28080
	// &foobar 5 6→C20506
}
Output:

type Kind

type Kind int

kind表示RLP流中包含的值的类型。

const (
	Byte Kind = iota
	String
	List
)

func Split

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

split返回第一个rlp值和任何 值后的字节作为b的子片。

func (Kind) String

func (k Kind) String() string

type RawValue

type RawValue []byte

rawvalue表示已编码的rlp值,可用于延迟 RLP解码或预计算编码。注意解码器可以 不验证rawvalues的内容是否是有效的rlp。

type Stream

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

流可用于输入流的逐段解码。这个 如果输入非常大或解码规则 类型取决于输入结构。流不保留 内部缓冲区。解码值后,输入读卡器将 位于下一个值的类型信息之前。

当解码列表时,输入位置达到声明的 列表的长度,所有操作都将返回错误eol。 必须使用list end继续确认列表结尾 正在读取封闭列表。

流对于并发使用不安全。

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

//检查前面有什么价值
kind, size, _ := s.Kind()
fmt.Printf("Kind: %v size:%d\n", kind, size)

//进入列表
if _, err := s.List(); err != nil {
	fmt.Printf("List error: %v\n", err)
	return
}

//解码元件
fmt.Println(s.Uint())
fmt.Println(s.Uint())
fmt.Println(s.Bytes())

//确认列表结尾
if err := s.ListEnd(); err != nil {
	fmt.Printf("ListEnd error: %v\n", err)
}
// 输出:
// 种类:列表大小:9
// 10 <NIL >
// 20 <NIL >
// [102 111 111 98 97 114]<nil>
Output:

func NewListStream

func NewListStream(r io.Reader, len uint64) *Stream

newliststream创建一个新的流,它假装被定位 在给定长度的编码列表中。

func NewStream

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

Newstream创建了一个新的解码流读取R。

如果r实现了bytereader接口,那么流将 不要引入任何缓冲。

对于非顶级值,流返回errelemtoolarge 用于不适合封闭列表的值。

流支持可选的输入限制。如果设置了限制,则 任何顶级值的大小将与其余值进行检查 输入长度。遇到超过值的流操作 剩余的输入长度将返回errValuetoolArge。极限 可以通过为inputLimit传递非零值来设置。

如果r是bytes.reader或strings.reader,则输入限制设置为 r的基础数据的长度,除非显式限制为 提供。

func (*Stream) Bool

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

bool读取最多1字节的rlp字符串并返回其内容 作为布尔值。如果输入不包含rlp字符串,则 返回的错误将是errExpectedString。

func (*Stream) Bytes

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

字节读取一个rlp字符串并将其内容作为字节片返回。 如果输入不包含rlp字符串,则返回 错误将是errExpectedString。

func (*Stream) Decode

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

解码解码解码值并将结果存储在指向的值中 按VAL。有关解码功能,请参阅文档。 了解解码规则。

func (*Stream) Kind

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

kind返回 输入流。

返回的大小是组成该值的字节数。 对于kind==byte,大小为零,因为值为 包含在类型标记中。

第一次调用kind将从输入中读取大小信息 读卡器并将其保留在 价值。后续对kind的调用(直到值被解码) 不会提升输入读取器并返回缓存信息。

func (*Stream) List

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

list开始解码rlp列表。如果输入不包含 列表中,返回的错误将是errExpectedList。当名单的 已到达END,任何流操作都将返回EOL。

func (*Stream) ListEnd

func (s *Stream) ListEnd() error

listened返回到封闭列表。 输入读取器必须位于列表的末尾。

func (*Stream) Raw

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

raw读取包含rlp类型信息的原始编码值。

func (*Stream) Reset

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

重置将丢弃有关当前解码上下文的任何信息 并从R开始读取。此方法旨在促进重用 在许多解码操作中预先分配的流。

如果r不同时实现bytereader,则流将自己执行。 缓冲。

func (*Stream) Uint

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

uint读取最多8个字节的rlp字符串并返回其内容 作为无符号整数。如果输入不包含rlp字符串,则 返回的错误将是errExpectedString。

Jump to

Keyboard shortcuts

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