forked from TrueCloudLab/neoneo-go
c6cd0e0c21
1) Added new file map.go, map_test.go 2) Added Map, Hash Method to Item interface 3) Implemented Hash Method for every stack items (Boolean, Array, Int, ...)
83 lines
1.8 KiB
Go
83 lines
1.8 KiB
Go
package stack
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"fmt"
|
|
"math/big"
|
|
"strconv"
|
|
)
|
|
|
|
// ByteArray represents a slice of bytes on the stack
|
|
type ByteArray struct {
|
|
*abstractItem
|
|
val []byte
|
|
}
|
|
|
|
//NewByteArray returns a ByteArray stack item
|
|
// given a byte slice
|
|
func NewByteArray(val []byte) *ByteArray {
|
|
return &ByteArray{
|
|
&abstractItem{},
|
|
val,
|
|
}
|
|
}
|
|
|
|
//ByteArray overrides the default abstractItem Bytes array method
|
|
func (ba *ByteArray) ByteArray() (*ByteArray, error) {
|
|
return ba, nil
|
|
}
|
|
|
|
//Equals returns true, if two bytearrays are equal
|
|
func (ba *ByteArray) Equals(other *ByteArray) *Boolean {
|
|
// If either are nil, return false
|
|
if ba == nil || other == nil {
|
|
return NewBoolean(false)
|
|
}
|
|
return NewBoolean(bytes.Equal(ba.val, other.val))
|
|
}
|
|
|
|
//Integer overrides the default Integer method to convert an
|
|
// ByteArray Into an integer
|
|
func (ba *ByteArray) Integer() (*Int, error) {
|
|
dest := reverse(ba.val)
|
|
integerVal := new(big.Int).SetBytes(dest)
|
|
return NewInt(integerVal)
|
|
|
|
}
|
|
|
|
// Boolean will convert a byte array into a boolean stack item
|
|
func (ba *ByteArray) Boolean() (*Boolean, error) {
|
|
boolean, err := strconv.ParseBool(string(ba.val))
|
|
if err != nil {
|
|
return nil, errors.New("cannot convert byte array to a boolean")
|
|
}
|
|
return NewBoolean(boolean), nil
|
|
}
|
|
|
|
// XXX: move this into a pkg/util/slice folder
|
|
// Go mod not working
|
|
func reverse(b []byte) []byte {
|
|
if len(b) < 2 {
|
|
return b
|
|
}
|
|
|
|
dest := make([]byte, len(b))
|
|
|
|
for i, j := 0, len(b)-1; i < j+1; i, j = i+1, j-1 {
|
|
dest[i], dest[j] = b[j], b[i]
|
|
}
|
|
|
|
return dest
|
|
}
|
|
|
|
//Value returns the underlying ByteArray's value.
|
|
func (ba *ByteArray) Value() []byte {
|
|
return ba.val
|
|
}
|
|
|
|
// Hash overrides the default abstract hash method.
|
|
func (ba *ByteArray) Hash() (string, error) {
|
|
data := fmt.Sprintf("%T %v", ba, ba.Value())
|
|
return KeyGenerator([]byte(data))
|
|
}
|