diff options
Diffstat (limited to 'ethutil/value.go')
-rw-r--r-- | ethutil/value.go | 103 |
1 files changed, 99 insertions, 4 deletions
diff --git a/ethutil/value.go b/ethutil/value.go index 735a71dbc..608d332ba 100644 --- a/ethutil/value.go +++ b/ethutil/value.go @@ -1,7 +1,6 @@ package ethutil import ( - "bytes" "fmt" "math/big" "reflect" @@ -67,7 +66,7 @@ func (val *Value) Uint() uint64 { } else if Val, ok := val.Val.(uint); ok { return uint64(Val) } else if Val, ok := val.Val.([]byte); ok { - return ReadVarint(bytes.NewReader(Val)) + return new(big.Int).SetBytes(Val).Uint64() } else if Val, ok := val.Val.(*big.Int); ok { return Val.Uint64() } @@ -75,6 +74,30 @@ func (val *Value) Uint() uint64 { return 0 } +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() + } + + return 0 +} + func (val *Value) Byte() byte { if Val, ok := val.Val.(byte); ok { return Val @@ -123,6 +146,14 @@ func (val *Value) Bytes() []byte { return []byte{} } +func (val *Value) Err() error { + if err, ok := val.Val.(error); ok { + return err + } + + return nil +} + func (val *Value) Slice() []interface{} { if d, ok := val.Val.([]interface{}); ok { return d @@ -158,6 +189,11 @@ func (val *Value) IsStr() bool { return val.Type() == reflect.String } +func (self *Value) IsErr() bool { + _, ok := self.Val.(error) + return ok +} + // 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. @@ -207,6 +243,13 @@ func (val *Value) Cmp(o *Value) bool { return reflect.DeepEqual(val.Val, o.Val) } +func (self *Value) DeepCmp(o *Value) bool { + a := NewValue(self.BigInt()) + b := NewValue(o.BigInt()) + + return a.Cmp(b) +} + func (val *Value) Encode() []byte { return Encode(val.Val) } @@ -215,12 +258,15 @@ func (val *Value) Encode() []byte { func (self *Value) Decode() { v, _ := Decode(self.Bytes(), 0) self.Val = v + //self.Val = DecodeWithReader(bytes.NewBuffer(self.Bytes())) } func NewValueFromBytes(data []byte) *Value { if len(data) != 0 { - data, _ := Decode(data, 0) - return NewValue(data) + value := NewValue(data) + value.Decode() + + return value } return NewValue(nil) @@ -262,6 +308,55 @@ func (val *Value) Append(v interface{}) *Value { return val } +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) +} + type ValueIterator struct { value *Value currentValue *Value |