rlp: add RawValue

This commit is contained in:
Felix Lange 2015-09-09 03:34:15 +02:00
parent bc17dba8fb
commit 24bb68e7cf
5 changed files with 39 additions and 1 deletions

View File

@ -173,6 +173,8 @@ var (
func makeDecoder(typ reflect.Type, tags tags) (dec decoder, err error) { func makeDecoder(typ reflect.Type, tags tags) (dec decoder, err error) {
kind := typ.Kind() kind := typ.Kind()
switch { switch {
case typ == rawValueType:
return decodeRawValue, nil
case typ.Implements(decoderInterface): case typ.Implements(decoderInterface):
return decodeDecoder, nil return decodeDecoder, nil
case kind != reflect.Ptr && reflect.PtrTo(typ).Implements(decoderInterface): case kind != reflect.Ptr && reflect.PtrTo(typ).Implements(decoderInterface):
@ -203,6 +205,15 @@ func makeDecoder(typ reflect.Type, tags tags) (dec decoder, err error) {
} }
} }
func decodeRawValue(s *Stream, val reflect.Value) error {
r, err := s.Raw()
if err != nil {
return err
}
val.SetBytes(r)
return nil
}
func decodeUint(s *Stream, val reflect.Value) error { func decodeUint(s *Stream, val reflect.Value) error {
typ := val.Type() typ := val.Type()
num, err := s.uint(typ.Bits()) num, err := s.uint(typ.Bits())

View File

@ -438,6 +438,11 @@ var decodeTests = []decodeTest{
error: "rlp: expected input string or byte for uint, decoding into (rlp.recstruct).Child.I", error: "rlp: expected input string or byte for uint, decoding into (rlp.recstruct).Child.I",
}, },
// RawValue
{input: "01", ptr: new(RawValue), value: RawValue(unhex("01"))},
{input: "82FFFF", ptr: new(RawValue), value: RawValue(unhex("82FFFF"))},
{input: "C20102", ptr: new([]RawValue), value: []RawValue{unhex("01"), unhex("02")}},
// pointers // pointers
{input: "00", ptr: new(*[]byte), value: &[]byte{0}}, {input: "00", ptr: new(*[]byte), value: &[]byte{0}},
{input: "80", ptr: new(*uint), value: uintp(0)}, {input: "80", ptr: new(*uint), value: uintp(0)},

View File

@ -354,6 +354,8 @@ var (
func makeWriter(typ reflect.Type) (writer, error) { func makeWriter(typ reflect.Type) (writer, error) {
kind := typ.Kind() kind := typ.Kind()
switch { switch {
case typ == rawValueType:
return writeRawValue, nil
case typ.Implements(encoderInterface): case typ.Implements(encoderInterface):
return writeEncoder, nil return writeEncoder, nil
case kind != reflect.Ptr && reflect.PtrTo(typ).Implements(encoderInterface): case kind != reflect.Ptr && reflect.PtrTo(typ).Implements(encoderInterface):
@ -389,6 +391,11 @@ func isByte(typ reflect.Type) bool {
return typ.Kind() == reflect.Uint8 && !typ.Implements(encoderInterface) return typ.Kind() == reflect.Uint8 && !typ.Implements(encoderInterface)
} }
func writeRawValue(val reflect.Value, w *encbuf) error {
w.str = append(w.str, val.Bytes()...)
return nil
}
func writeUint(val reflect.Value, w *encbuf) error { func writeUint(val reflect.Value, w *encbuf) error {
i := val.Uint() i := val.Uint()
if i == 0 { if i == 0 {

View File

@ -204,6 +204,11 @@ var encTests = []encTest{
output: "F90200CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376", output: "F90200CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376",
}, },
// RawValue
{val: RawValue(unhex("01")), output: "01"},
{val: RawValue(unhex("82FFFF")), output: "82FFFF"},
{val: []RawValue{unhex("01"), unhex("02")}, output: "C20102"},
// structs // structs
{val: simplestruct{}, output: "C28080"}, {val: simplestruct{}, output: "C28080"},
{val: simplestruct{A: 3, B: "foo"}, output: "C50383666F6F"}, {val: simplestruct{A: 3, B: "foo"}, output: "C50383666F6F"},

View File

@ -16,7 +16,17 @@
package rlp package rlp
import "io" import (
"io"
"reflect"
)
// RawValue represents an encoded RLP value and can be used to delay
// RLP decoding or precompute an encoding. Note that the decoder does
// not verify whether the content of RawValues is valid RLP.
type RawValue []byte
var rawValueType = reflect.TypeOf(RawValue{})
// Split returns the content of first RLP value and any // Split returns the content of first RLP value and any
// bytes after the value as subslices of b. // bytes after the value as subslices of b.