github.com/datachainlab/burrow@v0.25.0/execution/evm/asm/bc/helpers.go (about) 1 package bc 2 3 import ( 4 "fmt" 5 6 "github.com/hyperledger/burrow/execution/evm/asm" 7 ) 8 9 type ByteSlicable interface { 10 Bytes() []byte 11 } 12 13 // Concatenate multiple byte slices without unnecessary copying 14 func Concat(bss ...[]byte) []byte { 15 offset := 0 16 for _, bs := range bss { 17 offset += len(bs) 18 } 19 bytes := make([]byte, offset) 20 offset = 0 21 for _, bs := range bss { 22 for i, b := range bs { 23 bytes[offset+i] = b 24 } 25 offset += len(bs) 26 } 27 return bytes 28 } 29 30 // Splice or panic 31 func MustSplice(bytelikes ...interface{}) []byte { 32 spliced, err := Splice(bytelikes...) 33 if err != nil { 34 panic(err) 35 } 36 return spliced 37 } 38 39 // Convenience function to allow us to mix bytes, ints, and OpCodes that 40 // represent bytes in an EVM assembly code to make assembly more readable. 41 // Also allows us to splice together assembly 42 // fragments because any []byte arguments are flattened in the result. 43 func Splice(bytelikes ...interface{}) ([]byte, error) { 44 bytes := make([]byte, 0, len(bytelikes)) 45 for _, bytelike := range bytelikes { 46 bs, err := byteSlicify(bytelike) 47 if err != nil { 48 return nil, err 49 } 50 bytes = append(bytes, bs...) 51 } 52 return bytes, nil 53 } 54 55 // Convert anything byte or byte slice like to a byte slice 56 func byteSlicify(bytelike interface{}) ([]byte, error) { 57 switch b := bytelike.(type) { 58 case byte: 59 return []byte{b}, nil 60 case asm.OpCode: 61 return []byte{byte(b)}, nil 62 case int: 63 if int(byte(b)) != b { 64 return nil, fmt.Errorf("the int %v does not fit inside a byte", b) 65 } 66 return []byte{byte(b)}, nil 67 case int64: 68 if int64(byte(b)) != b { 69 return nil, fmt.Errorf("the int64 %v does not fit inside a byte", b) 70 } 71 return []byte{byte(b)}, nil 72 case uint64: 73 if uint64(byte(b)) != b { 74 return nil, fmt.Errorf("the uint64 %v does not fit inside a byte", b) 75 } 76 return []byte{byte(b)}, nil 77 case string: 78 return []byte(b), nil 79 case ByteSlicable: 80 return b.Bytes(), nil 81 case []byte: 82 return b, nil 83 default: 84 return nil, fmt.Errorf("could not convert %s to a byte or sequence of bytes", bytelike) 85 } 86 }