| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // Copyright 2014 The go-ethereum Authors | 
					
						
							|  |  |  | // This file is part of go-ethereum. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // go-ethereum is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  | // it under the terms of the GNU Lesser General Public License as published by | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | // (at your option) any later version. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // go-ethereum is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  | // GNU Lesser General Public License for more details. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // You should have received a copy of the GNU Lesser General Public License | 
					
						
							|  |  |  | // along with go-ethereum.  If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | package common | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2014-09-13 13:14:24 +02:00
										 |  |  | 	"bytes" | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2015-03-20 11:45:45 +01:00
										 |  |  | 	"io" | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 	"math/big" | 
					
						
							|  |  |  | 	"reflect" | 
					
						
							| 
									
										
										
										
											2014-09-13 13:14:24 +02:00
										 |  |  | 	"strconv" | 
					
						
							| 
									
										
										
										
											2015-03-20 11:45:45 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/rlp" | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-20 11:45:45 +01:00
										 |  |  | // 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. | 
					
						
							| 
									
										
										
										
											2015-03-20 11:48:40 +01:00
										 |  |  | type Value struct{ Val interface{} } | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | func (val *Value) String() string { | 
					
						
							| 
									
										
										
										
											2014-05-22 17:35:26 +02:00
										 |  |  | 	return fmt.Sprintf("%x", val.Val) | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func NewValue(val interface{}) *Value { | 
					
						
							| 
									
										
										
										
											2014-04-26 01:47:55 +02:00
										 |  |  | 	t := val | 
					
						
							|  |  |  | 	if v, ok := val.(*Value); ok { | 
					
						
							|  |  |  | 		t = v.Val | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return &Value{Val: t} | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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 { | 
					
						
							|  |  |  | 	if data, ok := val.Val.([]interface{}); ok { | 
					
						
							|  |  |  | 		return len(data) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-17 11:21:18 +02:00
										 |  |  | 	return len(val.Bytes()) | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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-09-26 13:32:54 +02:00
										 |  |  | 	} else if Val, ok := val.Val.(float32); ok { | 
					
						
							|  |  |  | 		return uint64(Val) | 
					
						
							|  |  |  | 	} else if Val, ok := val.Val.(float64); ok { | 
					
						
							|  |  |  | 		return uint64(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 { | 
					
						
							| 
									
										
										
										
											2014-07-29 10:33:30 +02:00
										 |  |  | 		return new(big.Int).SetBytes(Val).Uint64() | 
					
						
							| 
									
										
										
										
											2014-07-22 16:16:00 +02:00
										 |  |  | 	} else if Val, ok := val.Val.(*big.Int); ok { | 
					
						
							|  |  |  | 		return Val.Uint64() | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-11 16:23:38 +02:00
										 |  |  | func (val *Value) Int() int64 { | 
					
						
							|  |  |  | 	if Val, ok := val.Val.(int8); ok { | 
					
						
							|  |  |  | 		return int64(Val) | 
					
						
							|  |  |  | 	} else if Val, ok := val.Val.(int16); ok { | 
					
						
							|  |  |  | 		return int64(Val) | 
					
						
							|  |  |  | 	} else if Val, ok := val.Val.(int32); ok { | 
					
						
							|  |  |  | 		return int64(Val) | 
					
						
							|  |  |  | 	} else if Val, ok := val.Val.(int64); ok { | 
					
						
							|  |  |  | 		return Val | 
					
						
							|  |  |  | 	} else if Val, ok := val.Val.(int); ok { | 
					
						
							|  |  |  | 		return int64(Val) | 
					
						
							|  |  |  | 	} else if Val, ok := val.Val.(float32); ok { | 
					
						
							|  |  |  | 		return int64(Val) | 
					
						
							|  |  |  | 	} else if Val, ok := val.Val.(float64); ok { | 
					
						
							|  |  |  | 		return int64(Val) | 
					
						
							|  |  |  | 	} else if Val, ok := val.Val.([]byte); ok { | 
					
						
							|  |  |  | 		return new(big.Int).SetBytes(Val).Int64() | 
					
						
							|  |  |  | 	} else if Val, ok := val.Val.(*big.Int); ok { | 
					
						
							|  |  |  | 		return Val.Int64() | 
					
						
							| 
									
										
										
										
											2014-09-13 13:14:24 +02:00
										 |  |  | 	} else if Val, ok := val.Val.(string); ok { | 
					
						
							|  |  |  | 		n, _ := strconv.Atoi(Val) | 
					
						
							|  |  |  | 		return int64(n) | 
					
						
							| 
									
										
										
										
											2014-08-11 16:23:38 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 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-09-22 14:50:53 +02:00
										 |  |  | 	} else if a, ok := val.Val.(string); ok { | 
					
						
							|  |  |  | 		return Big(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-06-18 13:47:40 +02:00
										 |  |  | 	} else if s, ok := val.Val.(byte); ok { | 
					
						
							|  |  |  | 		return []byte{s} | 
					
						
							| 
									
										
										
										
											2014-06-30 13:09:04 +02:00
										 |  |  | 	} else if s, ok := val.Val.(string); ok { | 
					
						
							|  |  |  | 		return []byte(s) | 
					
						
							| 
									
										
										
										
											2014-07-17 11:21:18 +02:00
										 |  |  | 	} else if s, ok := val.Val.(*big.Int); ok { | 
					
						
							|  |  |  | 		return s.Bytes() | 
					
						
							| 
									
										
										
										
											2014-08-22 11:34:59 +02:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		return big.NewInt(val.Int()).Bytes() | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-16 20:30:33 +01:00
										 |  |  | 	return []byte{} | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-04 16:25:53 +02:00
										 |  |  | func (val *Value) Err() error { | 
					
						
							|  |  |  | 	if err, ok := val.Val.(error); ok { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-04 16:25:53 +02:00
										 |  |  | func (self *Value) IsErr() bool { | 
					
						
							|  |  |  | 	_, ok := self.Val.(error) | 
					
						
							|  |  |  | 	return ok | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-27 19:42:01 +01:00
										 |  |  | // Special list checking function. Something is considered | 
					
						
							|  |  |  | // a list if it's of type []interface{}. The list is usually | 
					
						
							|  |  |  | // used in conjunction with rlp decoded streams. | 
					
						
							|  |  |  | func (val *Value) IsList() bool { | 
					
						
							|  |  |  | 	_, ok := val.Val.([]interface{}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ok | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-20 23:10:05 +01:00
										 |  |  | 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-05-30 11:48:37 +02:00
										 |  |  | 			return NewValue(nil) | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-15 00:25:49 +02:00
										 |  |  | func (self *Value) Copy() *Value { | 
					
						
							|  |  |  | 	switch val := self.Val.(type) { | 
					
						
							|  |  |  | 	case *big.Int: | 
					
						
							|  |  |  | 		return NewValue(new(big.Int).Set(val)) | 
					
						
							|  |  |  | 	case []byte: | 
					
						
							|  |  |  | 		return NewValue(CopyBytes(val)) | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		return NewValue(self.Val) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | func (val *Value) Cmp(o *Value) bool { | 
					
						
							|  |  |  | 	return reflect.DeepEqual(val.Val, o.Val) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-29 10:33:30 +02:00
										 |  |  | func (self *Value) DeepCmp(o *Value) bool { | 
					
						
							| 
									
										
										
										
											2014-09-13 13:14:24 +02:00
										 |  |  | 	return bytes.Compare(self.Bytes(), o.Bytes()) == 0 | 
					
						
							| 
									
										
										
										
											2014-07-29 10:33:30 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-20 11:45:45 +01:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-20 11:45:45 +01:00
										 |  |  | func (self *Value) EncodeRLP(w io.Writer) error { | 
					
						
							|  |  |  | 	if self == nil { | 
					
						
							|  |  |  | 		w.Write(rlp.EmptyList) | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		return rlp.Encode(w, self.Val) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-06-30 13:09:04 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-20 11:45:45 +01:00
										 |  |  | // NewValueFromBytes decodes RLP data. | 
					
						
							|  |  |  | // The contained value will be nil if data contains invalid RLP. | 
					
						
							| 
									
										
										
										
											2014-02-16 20:30:33 +01:00
										 |  |  | func NewValueFromBytes(data []byte) *Value { | 
					
						
							| 
									
										
										
										
											2015-03-20 11:45:45 +01:00
										 |  |  | 	v := new(Value) | 
					
						
							| 
									
										
										
										
											2014-02-16 20:30:33 +01:00
										 |  |  | 	if len(data) != 0 { | 
					
						
							| 
									
										
										
										
											2015-03-20 11:45:45 +01:00
										 |  |  | 		if err := rlp.DecodeBytes(data, v); err != nil { | 
					
						
							|  |  |  | 			v.Val = nil | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-03-20 11:45:45 +01:00
										 |  |  | 	return v | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 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 | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-03-05 10:42:51 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-29 10:33:30 +02:00
										 |  |  | const ( | 
					
						
							|  |  |  | 	valOpAdd = iota | 
					
						
							|  |  |  | 	valOpDiv | 
					
						
							|  |  |  | 	valOpMul | 
					
						
							|  |  |  | 	valOpPow | 
					
						
							|  |  |  | 	valOpSub | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Math stuff | 
					
						
							|  |  |  | func (self *Value) doOp(op int, other interface{}) *Value { | 
					
						
							|  |  |  | 	left := self.BigInt() | 
					
						
							|  |  |  | 	right := NewValue(other).BigInt() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch op { | 
					
						
							|  |  |  | 	case valOpAdd: | 
					
						
							|  |  |  | 		self.Val = left.Add(left, right) | 
					
						
							|  |  |  | 	case valOpDiv: | 
					
						
							|  |  |  | 		self.Val = left.Div(left, right) | 
					
						
							|  |  |  | 	case valOpMul: | 
					
						
							|  |  |  | 		self.Val = left.Mul(left, right) | 
					
						
							|  |  |  | 	case valOpPow: | 
					
						
							|  |  |  | 		self.Val = left.Exp(left, right, Big0) | 
					
						
							|  |  |  | 	case valOpSub: | 
					
						
							|  |  |  | 		self.Val = left.Sub(left, right) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return self | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *Value) Add(other interface{}) *Value { | 
					
						
							|  |  |  | 	return self.doOp(valOpAdd, other) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *Value) Sub(other interface{}) *Value { | 
					
						
							|  |  |  | 	return self.doOp(valOpSub, other) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *Value) Div(other interface{}) *Value { | 
					
						
							|  |  |  | 	return self.doOp(valOpDiv, other) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *Value) Mul(other interface{}) *Value { | 
					
						
							|  |  |  | 	return self.doOp(valOpMul, other) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self *Value) Pow(other interface{}) *Value { | 
					
						
							|  |  |  | 	return self.doOp(valOpPow, other) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-05 10:42:51 +01:00
										 |  |  | type ValueIterator struct { | 
					
						
							|  |  |  | 	value        *Value | 
					
						
							|  |  |  | 	currentValue *Value | 
					
						
							|  |  |  | 	idx          int | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (val *Value) NewIterator() *ValueIterator { | 
					
						
							|  |  |  | 	return &ValueIterator{value: val} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-29 10:34:40 +01:00
										 |  |  | func (it *ValueIterator) Len() int { | 
					
						
							|  |  |  | 	return it.value.Len() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-05 10:42:51 +01:00
										 |  |  | func (it *ValueIterator) Next() bool { | 
					
						
							|  |  |  | 	if it.idx >= it.value.Len() { | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	it.currentValue = it.value.Get(it.idx) | 
					
						
							|  |  |  | 	it.idx++ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return true | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (it *ValueIterator) Value() *Value { | 
					
						
							|  |  |  | 	return it.currentValue | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (it *ValueIterator) Idx() int { | 
					
						
							| 
									
										
										
										
											2014-12-18 11:55:46 +01:00
										 |  |  | 	return it.idx - 1 | 
					
						
							| 
									
										
										
										
											2014-03-05 10:42:51 +01:00
										 |  |  | } |