From f7d1d601e92d3498f0fab5e80e5825d71f5d48fb Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 20 Mar 2015 11:45:45 +0100 Subject: common: make Value encodable with package rlp Value.{Encode,Decode} are gone. It implements rlp.Encoder and rlp.Decoder instead, so Value can be decoded into directly. --- common/value.go | 55 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 16 deletions(-) (limited to 'common/value.go') diff --git a/common/value.go b/common/value.go index 72a123772..f6150cb82 100644 --- a/common/value.go +++ b/common/value.go @@ -3,14 +3,29 @@ package common import ( "bytes" "fmt" + "io" "math/big" "reflect" "strconv" + + "github.com/ethereum/go-ethereum/rlp" ) -// Data values are returned by the rlp decoder. The data values represents -// one item within the rlp data structure. It's responsible for all the casting -// It always returns something valid +// Value can hold values of certain basic types and provides ways to +// convert between types without bothering to check whether the +// conversion is actually meaningful. +// +// It currently supports the following types: +// +// - int{,8,16,32,64} +// - uint{,8,16,32,64} +// - *big.Int +// - []byte, string +// - []interface{} +// +// Value is useful whenever you feel that Go's types limit your +// ability to express yourself. In these situations, use Value and +// forget about this strong typing nonsense. type Value struct { Val interface{} kind reflect.Value @@ -260,26 +275,34 @@ func (self *Value) DeepCmp(o *Value) bool { return bytes.Compare(self.Bytes(), o.Bytes()) == 0 } -func (val *Value) Encode() []byte { - return Encode(val.Val) +func (self *Value) DecodeRLP(s *rlp.Stream) error { + var v interface{} + if err := s.Decode(&v); err != nil { + return err + } + self.Val = v + return nil } -// Assume that the data we have is encoded -func (self *Value) Decode() { - v, _ := Decode(self.Bytes(), 0) - self.Val = v - //self.Val = DecodeWithReader(bytes.NewBuffer(self.Bytes())) +func (self *Value) EncodeRLP(w io.Writer) error { + if self == nil { + w.Write(rlp.EmptyList) + return nil + } else { + return rlp.Encode(w, self.Val) + } } +// NewValueFromBytes decodes RLP data. +// The contained value will be nil if data contains invalid RLP. func NewValueFromBytes(data []byte) *Value { + v := new(Value) if len(data) != 0 { - value := NewValue(data) - value.Decode() - - return value + if err := rlp.DecodeBytes(data, v); err != nil { + v.Val = nil + } } - - return NewValue(nil) + return v } // Value setters -- cgit v1.2.3 From dcb9614dfec3c8dcaaa47e9fa516528fdc47279b Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 20 Mar 2015 11:48:40 +0100 Subject: common: drop unused kind field from Value This makes Value 24 bytes smaller on 64bit systems. --- common/value.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'common/value.go') diff --git a/common/value.go b/common/value.go index f6150cb82..722e641b5 100644 --- a/common/value.go +++ b/common/value.go @@ -26,10 +26,7 @@ import ( // Value is useful whenever you feel that Go's types limit your // ability to express yourself. In these situations, use Value and // forget about this strong typing nonsense. -type Value struct { - Val interface{} - kind reflect.Value -} +type Value struct{ Val interface{} } func (val *Value) String() string { return fmt.Sprintf("%x", val.Val) @@ -53,7 +50,6 @@ func (val *Value) IsNil() bool { } func (val *Value) Len() int { - //return val.kind.Len() if data, ok := val.Val.([]interface{}); ok { return len(data) } -- cgit v1.2.3 From c161d73d429ef421cdb9c75b743c16d72aa8a89a Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 20 Mar 2015 13:33:11 +0100 Subject: common: drop accessors for Value.Val I don't see why we would need two different accessors for a public field. --- common/value.go | 8 -------- 1 file changed, 8 deletions(-) (limited to 'common/value.go') diff --git a/common/value.go b/common/value.go index 722e641b5..c3893d565 100644 --- a/common/value.go +++ b/common/value.go @@ -57,14 +57,6 @@ func (val *Value) Len() int { return len(val.Bytes()) } -func (val *Value) Raw() interface{} { - return val.Val -} - -func (val *Value) Interface() interface{} { - return val.Val -} - func (val *Value) Uint() uint64 { if Val, ok := val.Val.(uint8); ok { return uint64(Val) -- cgit v1.2.3