Documentation ¶
Index ¶
- Variables
- func CountValues(b []byte) (int, error)
- func Decode(r io.Reader, val interface{}) error
- func DecodeBytes(b []byte, val interface{}) error
- func Encode(w io.Writer, val interface{}) error
- func EncodeToBytes(val interface{}) ([]byte, error)
- func EncodeToReader(val interface{}) (size int, r io.Reader, err error)
- func ListSize(contentSize uint64) uint64
- func SplitList(b []byte) (content, rest []byte, err error)
- func SplitString(b []byte) (content, rest []byte, err error)
- type ByteReader
- type Decoder
- type Encoder
- type Kind
- type RawValue
- type Stream
- func (s *Stream) Bool() (bool, error)
- func (s *Stream) Bytes() ([]byte, error)
- func (s *Stream) Decode(val interface{}) error
- func (s *Stream) Kind() (kind Kind, size uint64, err error)
- func (s *Stream) List() (size uint64, err error)
- func (s *Stream) ListEnd() error
- func (s *Stream) Raw() ([]byte, error)
- func (s *Stream) Reset(r io.Reader, inputLimit uint64)
- func (s *Stream) Uint() (uint64, error)
Examples ¶
Constants ¶
This section is empty.
Variables ¶
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") )
var ( //通用编码值。 //这些在实现encoderlp时很有用。 EmptyString = []byte{0x80} EmptyList = []byte{0xC0} )
Functions ¶
func Decode ¶
解码解析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 ¶
decodebytes将rlp数据从b解析为val。 解码规则见解码文档。 输入必须正好包含一个值,并且没有尾随数据。
func Encode ¶
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 ¶
encodeToBytes返回val的rlp编码。 编码规则请参见Encode文档。
func SplitString ¶
splitString将b拆分为rlp字符串的内容 以及字符串后的所有剩余字节。
Types ¶
type ByteReader ¶
type ByteReader interface { io.Reader io.ByteReader }
bytereader必须由流的任何输入读取器实现。它 由bufio.reader和bytes.reader等实现。
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 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 ¶
newliststream创建一个新的流,它假装被定位 在给定长度的编码列表中。
func NewStream ¶
Newstream创建了一个新的解码流读取R。
如果r实现了bytereader接口,那么流将 不要引入任何缓冲。
对于非顶级值,流返回errelemtoolarge 用于不适合封闭列表的值。
流支持可选的输入限制。如果设置了限制,则 任何顶级值的大小将与其余值进行检查 输入长度。遇到超过值的流操作 剩余的输入长度将返回errValuetoolArge。极限 可以通过为inputLimit传递非零值来设置。
如果r是bytes.reader或strings.reader,则输入限制设置为 r的基础数据的长度,除非显式限制为 提供。
func (*Stream) Kind ¶
kind返回 输入流。
返回的大小是组成该值的字节数。 对于kind==byte,大小为零,因为值为 包含在类型标记中。
第一次调用kind将从输入中读取大小信息 读卡器并将其保留在 价值。后续对kind的调用(直到值被解码) 不会提升输入读取器并返回缓存信息。