2014-02-15 00:56:09 +02:00
|
|
|
package ethutil
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/binary"
|
|
|
|
"fmt"
|
2014-05-29 00:16:54 +03:00
|
|
|
"math/big"
|
2014-06-18 12:55:05 +03:00
|
|
|
"strings"
|
2014-02-15 00:56:09 +02:00
|
|
|
)
|
|
|
|
|
2014-04-27 18:15:44 +03:00
|
|
|
// Number to bytes
|
|
|
|
//
|
|
|
|
// Returns the number in bytes with the specified base
|
2014-02-15 00:56:09 +02:00
|
|
|
func NumberToBytes(num interface{}, bits int) []byte {
|
|
|
|
buf := new(bytes.Buffer)
|
|
|
|
err := binary.Write(buf, binary.BigEndian, num)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println("NumberToBytes failed:", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return buf.Bytes()[buf.Len()-(bits/8):]
|
|
|
|
}
|
|
|
|
|
2014-04-27 18:15:44 +03:00
|
|
|
// Bytes to number
|
|
|
|
//
|
|
|
|
// Attempts to cast a byte slice to a unsigned integer
|
2014-02-15 00:56:09 +02:00
|
|
|
func BytesToNumber(b []byte) uint64 {
|
|
|
|
var number uint64
|
|
|
|
|
|
|
|
// Make sure the buffer is 64bits
|
|
|
|
data := make([]byte, 8)
|
|
|
|
data = append(data[:len(b)], b...)
|
|
|
|
|
|
|
|
buf := bytes.NewReader(data)
|
|
|
|
err := binary.Read(buf, binary.BigEndian, &number)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println("BytesToNumber failed:", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return number
|
|
|
|
}
|
|
|
|
|
2014-04-27 18:15:44 +03:00
|
|
|
// Read variable int
|
|
|
|
//
|
|
|
|
// Read a variable length number in big endian byte order
|
2014-02-15 00:56:09 +02:00
|
|
|
func ReadVarint(reader *bytes.Reader) (ret uint64) {
|
|
|
|
if reader.Len() == 8 {
|
|
|
|
var num uint64
|
|
|
|
binary.Read(reader, binary.BigEndian, &num)
|
|
|
|
ret = uint64(num)
|
|
|
|
} else if reader.Len() == 4 {
|
|
|
|
var num uint32
|
|
|
|
binary.Read(reader, binary.BigEndian, &num)
|
|
|
|
ret = uint64(num)
|
|
|
|
} else if reader.Len() == 2 {
|
|
|
|
var num uint16
|
|
|
|
binary.Read(reader, binary.BigEndian, &num)
|
|
|
|
ret = uint64(num)
|
|
|
|
} else {
|
|
|
|
var num uint8
|
|
|
|
binary.Read(reader, binary.BigEndian, &num)
|
|
|
|
ret = uint64(num)
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret
|
|
|
|
}
|
|
|
|
|
2014-04-27 18:15:44 +03:00
|
|
|
// Binary length
|
|
|
|
//
|
|
|
|
// Returns the true binary length of the given number
|
2014-02-15 00:56:09 +02:00
|
|
|
func BinaryLength(num int) int {
|
|
|
|
if num == 0 {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1 + BinaryLength(num>>8)
|
|
|
|
}
|
2014-04-29 13:36:27 +03:00
|
|
|
|
|
|
|
// Copy bytes
|
|
|
|
//
|
|
|
|
// Returns an exact copy of the provided bytes
|
|
|
|
func CopyBytes(b []byte) (copiedBytes []byte) {
|
|
|
|
copiedBytes = make([]byte, len(b))
|
|
|
|
copy(copiedBytes, b)
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
2014-05-05 16:48:17 +03:00
|
|
|
|
|
|
|
func IsHex(str string) bool {
|
|
|
|
l := len(str)
|
|
|
|
return l >= 4 && l%2 == 0 && str[0:2] == "0x"
|
|
|
|
}
|
2014-05-28 14:14:56 +03:00
|
|
|
|
|
|
|
func StringToByteFunc(str string, cb func(str string) []byte) (ret []byte) {
|
2014-06-18 12:55:05 +03:00
|
|
|
if len(str) > 1 && str[0:2] == "0x" && !strings.Contains(str, "\n") {
|
2014-05-28 14:14:56 +03:00
|
|
|
ret = FromHex(str[2:])
|
|
|
|
} else {
|
|
|
|
ret = cb(str)
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
2014-05-29 00:16:54 +03:00
|
|
|
|
|
|
|
func FormatData(data string) []byte {
|
|
|
|
if len(data) == 0 {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
// Simple stupid
|
|
|
|
d := new(big.Int)
|
|
|
|
if data[0:1] == "\"" && data[len(data)-1:] == "\"" {
|
|
|
|
d.SetBytes([]byte(data[1 : len(data)-1]))
|
|
|
|
} else if len(data) > 1 && data[:2] == "0x" {
|
|
|
|
d.SetBytes(FromHex(data[2:]))
|
|
|
|
} else {
|
|
|
|
d.SetString(data, 0)
|
|
|
|
}
|
|
|
|
|
|
|
|
return BigToBytes(d, 256)
|
|
|
|
}
|