| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | package ethutil | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"bytes" | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"math/big" | 
					
						
							|  |  |  | 	"reflect" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 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 | 
					
						
							|  |  |  | type Value struct { | 
					
						
							|  |  |  | 	Val  interface{} | 
					
						
							|  |  |  | 	kind reflect.Value | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (val *Value) String() string { | 
					
						
							|  |  |  | 	return fmt.Sprintf("%q", val.Val) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func NewValue(val interface{}) *Value { | 
					
						
							|  |  |  | 	return &Value{Val: val} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (val *Value) Type() reflect.Kind { | 
					
						
							|  |  |  | 	return reflect.TypeOf(val.Val).Kind() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (val *Value) IsNil() bool { | 
					
						
							|  |  |  | 	return val.Val == nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (val *Value) Len() int { | 
					
						
							|  |  |  | 	//return val.kind.Len() | 
					
						
							|  |  |  | 	if data, ok := val.Val.([]interface{}); ok { | 
					
						
							|  |  |  | 		return len(data) | 
					
						
							|  |  |  | 	} else if data, ok := val.Val.([]byte); ok { | 
					
						
							| 
									
										
										
										
											2014-02-20 23:10:05 +01:00
										 |  |  | 		return len(data) | 
					
						
							|  |  |  | 	} else if data, ok := val.Val.(string); ok { | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 		return len(data) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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) | 
					
						
							|  |  |  | 	} else if Val, ok := val.Val.(uint16); ok { | 
					
						
							|  |  |  | 		return uint64(Val) | 
					
						
							|  |  |  | 	} else if Val, ok := val.Val.(uint32); ok { | 
					
						
							|  |  |  | 		return uint64(Val) | 
					
						
							|  |  |  | 	} else if Val, ok := val.Val.(uint64); ok { | 
					
						
							|  |  |  | 		return Val | 
					
						
							| 
									
										
										
										
											2014-02-15 13:21:11 +01:00
										 |  |  | 	} else if Val, ok := val.Val.(int); ok { | 
					
						
							|  |  |  | 		return uint64(Val) | 
					
						
							|  |  |  | 	} else if Val, ok := val.Val.(uint); ok { | 
					
						
							|  |  |  | 		return uint64(Val) | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 	} else if Val, ok := val.Val.([]byte); ok { | 
					
						
							|  |  |  | 		return ReadVarint(bytes.NewReader(Val)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (val *Value) Byte() byte { | 
					
						
							|  |  |  | 	if Val, ok := val.Val.(byte); ok { | 
					
						
							|  |  |  | 		return Val | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0x0 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (val *Value) BigInt() *big.Int { | 
					
						
							|  |  |  | 	if a, ok := val.Val.([]byte); ok { | 
					
						
							|  |  |  | 		b := new(big.Int).SetBytes(a) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return b | 
					
						
							| 
									
										
										
										
											2014-02-16 20:30:33 +01:00
										 |  |  | 	} else if a, ok := val.Val.(*big.Int); ok { | 
					
						
							|  |  |  | 		return a | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		return big.NewInt(int64(val.Uint())) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return big.NewInt(0) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (val *Value) Str() string { | 
					
						
							|  |  |  | 	if a, ok := val.Val.([]byte); ok { | 
					
						
							|  |  |  | 		return string(a) | 
					
						
							|  |  |  | 	} else if a, ok := val.Val.(string); ok { | 
					
						
							|  |  |  | 		return a | 
					
						
							| 
									
										
										
										
											2014-02-17 20:29:54 +01:00
										 |  |  | 	} else if a, ok := val.Val.(byte); ok { | 
					
						
							|  |  |  | 		return string(a) | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return "" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (val *Value) Bytes() []byte { | 
					
						
							|  |  |  | 	if a, ok := val.Val.([]byte); ok { | 
					
						
							|  |  |  | 		return a | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-16 20:30:33 +01:00
										 |  |  | 	return []byte{} | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (val *Value) Slice() []interface{} { | 
					
						
							|  |  |  | 	if d, ok := val.Val.([]interface{}); ok { | 
					
						
							|  |  |  | 		return d | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return []interface{}{} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (val *Value) SliceFrom(from int) *Value { | 
					
						
							|  |  |  | 	slice := val.Slice() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return NewValue(slice[from:]) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (val *Value) SliceTo(to int) *Value { | 
					
						
							|  |  |  | 	slice := val.Slice() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return NewValue(slice[:to]) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (val *Value) SliceFromTo(from, to int) *Value { | 
					
						
							|  |  |  | 	slice := val.Slice() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return NewValue(slice[from:to]) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-20 23:10:05 +01:00
										 |  |  | // TODO More type checking methods | 
					
						
							|  |  |  | func (val *Value) IsSlice() bool { | 
					
						
							|  |  |  | 	return val.Type() == reflect.Slice | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (val *Value) IsStr() bool { | 
					
						
							|  |  |  | 	return val.Type() == reflect.String | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (val *Value) IsEmpty() bool { | 
					
						
							| 
									
										
										
										
											2014-02-21 12:36:22 +01:00
										 |  |  | 	return val.Val == nil || ((val.IsSlice() || val.IsStr()) && val.Len() == 0) | 
					
						
							| 
									
										
										
										
											2014-02-20 23:10:05 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | // Threat the value as a slice | 
					
						
							|  |  |  | func (val *Value) Get(idx int) *Value { | 
					
						
							|  |  |  | 	if d, ok := val.Val.([]interface{}); ok { | 
					
						
							|  |  |  | 		// Guard for oob | 
					
						
							|  |  |  | 		if len(d) <= idx { | 
					
						
							|  |  |  | 			return NewValue(nil) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if idx < 0 { | 
					
						
							| 
									
										
										
										
											2014-02-16 20:30:33 +01:00
										 |  |  | 			panic("negative idx for Value Get") | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return NewValue(d[idx]) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// If this wasn't a slice you probably shouldn't be using this function | 
					
						
							|  |  |  | 	return NewValue(nil) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (val *Value) Cmp(o *Value) bool { | 
					
						
							|  |  |  | 	return reflect.DeepEqual(val.Val, o.Val) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (val *Value) Encode() []byte { | 
					
						
							|  |  |  | 	return Encode(val.Val) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-16 20:30:33 +01:00
										 |  |  | func NewValueFromBytes(data []byte) *Value { | 
					
						
							|  |  |  | 	if len(data) != 0 { | 
					
						
							|  |  |  | 		data, _ := Decode(data, 0) | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 		return NewValue(data) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return NewValue(nil) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Value setters | 
					
						
							|  |  |  | func NewSliceValue(s interface{}) *Value { | 
					
						
							|  |  |  | 	list := EmptyValue() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if s != nil { | 
					
						
							|  |  |  | 		if slice, ok := s.([]interface{}); ok { | 
					
						
							|  |  |  | 			for _, val := range slice { | 
					
						
							|  |  |  | 				list.Append(val) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else if slice, ok := s.([]string); ok { | 
					
						
							|  |  |  | 			for _, val := range slice { | 
					
						
							|  |  |  | 				list.Append(val) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return list | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func EmptyValue() *Value { | 
					
						
							|  |  |  | 	return NewValue([]interface{}{}) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (val *Value) AppendList() *Value { | 
					
						
							|  |  |  | 	list := EmptyValue() | 
					
						
							|  |  |  | 	val.Val = append(val.Slice(), list) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return list | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (val *Value) Append(v interface{}) *Value { | 
					
						
							|  |  |  | 	val.Val = append(val.Slice(), v) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return val | 
					
						
							|  |  |  | } |