github.com/ontio/ontology@v1.14.4/vm/neovm/params_builder.go (about) 1 /* 2 * Copyright (C) 2018 The ontology Authors 3 * This file is part of The ontology library. 4 * 5 * The ontology is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU Lesser General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * The ontology is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with The ontology. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 package neovm 20 21 import ( 22 "bytes" 23 "encoding/binary" 24 "math/big" 25 26 "github.com/ontio/ontology/common" 27 ) 28 29 type ParamsBuilder struct { 30 buffer *bytes.Buffer 31 } 32 33 func NewParamsBuilder(buffer *bytes.Buffer) *ParamsBuilder { 34 return &ParamsBuilder{buffer} 35 } 36 37 func (p *ParamsBuilder) Emit(op OpCode) { 38 p.buffer.WriteByte(byte(op)) 39 } 40 41 func (p *ParamsBuilder) EmitPushBool(data bool) { 42 if data { 43 p.Emit(PUSHT) 44 return 45 } 46 p.Emit(PUSHF) 47 } 48 49 func (p *ParamsBuilder) EmitPushInteger(data *big.Int) { 50 if data.Cmp(big.NewInt(int64(-1))) == 0 { 51 p.Emit(PUSHM1) 52 return 53 } 54 if data.Sign() == 0 { 55 p.Emit(PUSH0) 56 return 57 } 58 59 if data.Cmp(big.NewInt(int64(0))) == 1 && data.Cmp(big.NewInt(int64(16))) == -1 { 60 p.Emit(OpCode(int(PUSH1) - 1 + int(data.Int64()))) 61 return 62 } 63 64 bytes := common.BigIntToNeoBytes(data) 65 p.EmitPushByteArray(bytes) 66 } 67 68 func (p *ParamsBuilder) EmitPushByteArray(data []byte) { 69 l := len(data) 70 if l < int(PUSHBYTES75) { 71 p.buffer.WriteByte(byte(l)) 72 } else if l < 0x100 { 73 p.Emit(PUSHDATA1) 74 p.buffer.WriteByte(byte(l)) 75 } else if l < 0x10000 { 76 p.Emit(PUSHDATA2) 77 b := make([]byte, 2) 78 binary.LittleEndian.PutUint16(b, uint16(l)) 79 p.buffer.Write(b) 80 } else { 81 p.Emit(PUSHDATA4) 82 b := make([]byte, 4) 83 binary.LittleEndian.PutUint32(b, uint32(l)) 84 p.buffer.Write(b) 85 } 86 p.buffer.Write(data) 87 } 88 89 func (p *ParamsBuilder) EmitPushCall(address []byte) { 90 p.Emit(APPCALL) 91 p.buffer.Write(address) 92 } 93 94 func (p *ParamsBuilder) ToArray() []byte { 95 return p.buffer.Bytes() 96 }