github.com/ontio/ontology@v1.14.4/vm/neovm/types/struct_value.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 types
    20  
    21  import (
    22  	"fmt"
    23  
    24  	"github.com/ontio/ontology/vm/neovm/constants"
    25  	"github.com/ontio/ontology/vm/neovm/errors"
    26  )
    27  
    28  const (
    29  	MAX_STRUCT_DEPTH = 10
    30  	MAX_CLONE_LENGTH = 1024
    31  )
    32  
    33  // struct value is value type
    34  type StructValue struct {
    35  	Data []VmValue
    36  }
    37  
    38  func NewStructValue() *StructValue {
    39  	return &StructValue{Data: make([]VmValue, 0, initArraySize)}
    40  }
    41  
    42  func (self *StructValue) Append(item VmValue) error {
    43  	if len(self.Data) >= constants.MAX_ARRAY_SIZE {
    44  		return errors.ERR_OVER_MAX_ARRAY_SIZE
    45  	}
    46  	self.Data = append(self.Data, item)
    47  	return nil
    48  }
    49  
    50  func (self *StructValue) Len() int64 {
    51  	return int64(len(self.Data))
    52  }
    53  
    54  func (self *StructValue) Clone() (*StructValue, error) {
    55  	var i int
    56  	return cloneStruct(self, &i)
    57  }
    58  
    59  func cloneStruct(s *StructValue, length *int) (*StructValue, error) {
    60  	if *length > MAX_CLONE_LENGTH {
    61  		return nil, fmt.Errorf("%s", "over max struct clone length")
    62  	}
    63  	var arr []VmValue
    64  	for _, v := range s.Data {
    65  		*length++
    66  		if temp, err := v.AsStructValue(); err == nil {
    67  			vc, err := cloneStruct(temp, length)
    68  			if err != nil {
    69  				return nil, err
    70  			}
    71  			arr = append(arr, VmValueFromStructVal(vc))
    72  		} else {
    73  			arr = append(arr, v)
    74  		}
    75  	}
    76  	return &StructValue{Data: arr}, nil
    77  }