diff options
author | Felix Lange <fjl@twurst.com> | 2014-10-23 21:01:27 +0800 |
---|---|---|
committer | Felix Lange <fjl@twurst.com> | 2014-10-23 21:01:27 +0800 |
commit | 69baa465ea69ae60eed802445cf0132b9eb69934 (patch) | |
tree | b09da7582b5c4850d4db13aee808f2fef2f97de0 /ethutil/bytes.go | |
parent | 50fd46924900869e7210217c6a07979b544991c8 (diff) | |
parent | feef194829b07570e91873ed5d1e8cc51e8fa430 (diff) | |
download | go-tangerine-69baa465ea69ae60eed802445cf0132b9eb69934.tar.gz go-tangerine-69baa465ea69ae60eed802445cf0132b9eb69934.tar.zst go-tangerine-69baa465ea69ae60eed802445cf0132b9eb69934.zip |
Merge eth-go repository into go-ethereum
mist, etheruem have been moved to cmd/
Diffstat (limited to 'ethutil/bytes.go')
-rw-r--r-- | ethutil/bytes.go | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/ethutil/bytes.go b/ethutil/bytes.go new file mode 100644 index 000000000..bd294f28a --- /dev/null +++ b/ethutil/bytes.go @@ -0,0 +1,234 @@ +package ethutil + +import ( + "bytes" + "encoding/binary" + "encoding/hex" + "fmt" + "math/big" + "strings" +) + +type Bytes []byte + +func (self Bytes) String() string { + return string(self) +} + +func DeleteFromByteSlice(s [][]byte, hash []byte) [][]byte { + for i, h := range s { + if bytes.Compare(h, hash) == 0 { + return append(s[:i:i], s[i+1:]...) + } + } + + return s +} + +// Number to bytes +// +// Returns the number in bytes with the specified base +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):] +} + +// Bytes to number +// +// Attempts to cast a byte slice to a unsigned integer +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 +} + +// Read variable int +// +// Read a variable length number in big endian byte order +func ReadVarInt(buff []byte) (ret uint64) { + switch l := len(buff); { + case l > 4: + d := LeftPadBytes(buff, 8) + binary.Read(bytes.NewReader(d), binary.BigEndian, &ret) + case l > 2: + var num uint32 + d := LeftPadBytes(buff, 4) + binary.Read(bytes.NewReader(d), binary.BigEndian, &num) + ret = uint64(num) + case l > 1: + var num uint16 + d := LeftPadBytes(buff, 2) + binary.Read(bytes.NewReader(d), binary.BigEndian, &num) + ret = uint64(num) + default: + var num uint8 + binary.Read(bytes.NewReader(buff), binary.BigEndian, &num) + ret = uint64(num) + } + + return +} + +// Binary length +// +// Returns the true binary length of the given number +func BinaryLength(num int) int { + if num == 0 { + return 0 + } + + return 1 + BinaryLength(num>>8) +} + +// 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 +} + +func IsHex(str string) bool { + l := len(str) + return l >= 4 && l%2 == 0 && str[0:2] == "0x" +} + +func Bytes2Hex(d []byte) string { + return hex.EncodeToString(d) +} + +func Hex2Bytes(str string) []byte { + h, _ := hex.DecodeString(str) + + return h +} + +func StringToByteFunc(str string, cb func(str string) []byte) (ret []byte) { + if len(str) > 1 && str[0:2] == "0x" && !strings.Contains(str, "\n") { + ret = Hex2Bytes(str[2:]) + } else { + ret = cb(str) + } + + return +} + +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:] == "\"" { + return RightPadBytes([]byte(data[1:len(data)-1]), 32) + } else if len(data) > 1 && data[:2] == "0x" { + d.SetBytes(Hex2Bytes(data[2:])) + } else { + d.SetString(data, 0) + } + + return BigToBytes(d, 256) +} + +func ParseData(data ...interface{}) (ret []byte) { + for _, item := range data { + switch t := item.(type) { + case string: + var str []byte + if IsHex(t) { + str = Hex2Bytes(t[2:]) + } else { + str = []byte(t) + } + + ret = append(ret, RightPadBytes(str, 32)...) + case []byte: + ret = append(ret, LeftPadBytes(t, 32)...) + } + } + + return +} + +func RightPadBytes(slice []byte, l int) []byte { + if l < len(slice) { + return slice + } + + padded := make([]byte, l) + copy(padded[0:len(slice)], slice) + + return padded +} + +func LeftPadBytes(slice []byte, l int) []byte { + if l < len(slice) { + return slice + } + + padded := make([]byte, l) + copy(padded[l-len(slice):], slice) + + return padded +} + +func LeftPadString(str string, l int) string { + if l < len(str) { + return str + } + + zeros := Bytes2Hex(make([]byte, (l-len(str))/2)) + + return zeros + str + +} + +func RightPadString(str string, l int) string { + if l < len(str) { + return str + } + + zeros := Bytes2Hex(make([]byte, (l-len(str))/2)) + + return str + zeros + +} + +func Address(slice []byte) (addr []byte) { + if len(slice) < 20 { + addr = LeftPadBytes(slice, 20) + } else if len(slice) > 20 { + addr = slice[len(slice)-20:] + } else { + addr = slice + } + + addr = CopyBytes(addr) + + return +} + +func ByteSliceToInterface(slice [][]byte) (ret []interface{}) { + for _, i := range slice { + ret = append(ret, i) + } + + return +} |