github.com/n1ghtfa1l/go-vnt@v0.6.4-alpha.6/accounts/abi/key.go (about) 1 // Copyright 2019 The go-vnt Authors 2 // This file is part of the go-vnt library. 3 // 4 // The go-vnt library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-vnt library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-vnt library. If not, see <http://www.gnu.org/licenses/>. 16 17 package abi 18 19 import ( 20 "fmt" 21 "strings" 22 ) 23 24 type StorageType uint64 25 26 const ( 27 NormalTy StorageType = iota 28 MappingKeyTy 29 ArrayIndexTy 30 MappingValueTy 31 ArrayValueTy 32 StructValueTy 33 LengthTy 34 ) 35 36 const ( 37 TY_INT32 int32 = 1 + iota 38 TY_INT64 39 TY_UINT32 40 TY_UINT64 41 TY_UINT256 42 TY_STRING 43 TY_ADDRESS 44 TY_BOOL 45 TY_POINTER 46 ) 47 48 type Key struct { 49 Name string `json:"name"` 50 Tables Tables `json:"tables"` 51 Types map[string]Type `json:"-"` 52 Keys map[string]Table `json:"keys"` 53 Connector map[string][]string 54 } 55 56 type Connector struct { 57 Name string 58 Type string 59 } 60 61 func errnotexist(name string) error { 62 return fmt.Errorf("Can not find name %s", name) 63 } 64 65 type Root struct { 66 Root map[string]*Node 67 } 68 69 type Node struct { 70 FieldName string `json:"name"` 71 FieldType string `json:"type"` 72 FieldLocation string `json:"-"` 73 StorageType StorageType `json:"storagetype"` 74 Children map[string]*Node `json:"children"` 75 Tables []*Node `json:"tables"` 76 } 77 78 func NewNode(fieldname string, fieldtype string, fieldlocation string) *Node { 79 return &Node{ 80 FieldName: fieldname, 81 FieldType: fieldtype, 82 FieldLocation: fieldlocation, 83 Children: make(map[string]*Node), 84 Tables: []*Node{}, 85 } 86 } 87 88 func (nd *Node) addchild(fieldname, fieldtype, fieldlocation, base string) *Node { 89 child, ok := nd.Children[base] 90 if !ok { 91 child = NewNode(fieldname, fieldtype, fieldlocation) 92 nd.Children[fieldname] = child 93 if child.FieldName != "mapping1537182776" && child.FieldName != "array1537182776" { 94 nd.Tables = append(nd.Tables, child) 95 } 96 97 } 98 return child 99 } 100 101 func (nd *Node) Add(fieldname string, fieldtype string, fieldlocation string, base string) *Node { 102 return nd.addchild(fieldname, fieldtype, fieldlocation, base) 103 } 104 105 func (nd *Node) Get(name string) (*Node, error) { 106 if _, ok := nd.Children[name]; !ok { 107 return &Node{}, errnotexist(name) 108 } 109 return nd, nil 110 } 111 112 func (nd *Node) Traversal(r Root) { 113 // fmt.Printf("Node %v\n", nd) 114 for _, v := range nd.Children { 115 if child, ok := r.Root[v.FieldType]; ok { 116 117 if v.FieldType != child.FieldType { 118 if child1, ok := r.Root[child.FieldType]; ok { 119 child = child1 120 } 121 } 122 v.FieldType = "" 123 cld := make(map[string]*Node) 124 tables := []*Node{} 125 for k, c := range child.Children { 126 cld[k] = c 127 128 if k != "mapping1537182776" && k != "array1537182776" { 129 tables = append(tables, c) 130 } 131 } 132 133 v.Children = cld 134 v.Tables = tables 135 136 //todo 优化 clang.go:204 137 var allkey = "" 138 for k, _ := range v.Children { 139 allkey = allkey + k 140 } 141 if strings.Contains(allkey, "mapping1537182776") { 142 v.FieldType = "mapping" 143 } else if strings.Contains(allkey, "array1537182776") { 144 v.FieldType = "array" 145 } else { 146 v.FieldType = "struct" 147 } 148 149 for k, c := range child.Children { 150 if v.FieldType == "mapping" { 151 if k == "key" { 152 c.StorageType = MappingKeyTy 153 } else if k == "value" { 154 c.StorageType = MappingValueTy 155 } else { 156 delete(v.Children, k) 157 } 158 } else if v.FieldType == "array" { 159 if k == "index" { 160 c.StorageType = ArrayIndexTy 161 } else if k == "value" { 162 c.StorageType = ArrayValueTy 163 } else if k == "length" { 164 c.StorageType = LengthTy 165 } else { 166 delete(v.Children, k) 167 } 168 } else if v.FieldType == "struct" { 169 c.StorageType = StructValueTy 170 } 171 } 172 173 v.Traversal(r) 174 } 175 176 } 177 } 178 179 func (r Root) Fulling() Root { 180 for _, v := range r.Root { 181 v.Traversal(r) 182 } 183 return r 184 } 185 186 func (key *Key) KeyTraversal() { 187 if key.Types == nil { 188 key.Types = make(map[string]Type) 189 } 190 if key.Keys == nil { 191 key.Keys = make(map[string]Table) 192 } 193 for _, v := range key.Tables { 194 v.Traversal(key.Name, key) 195 } 196 } 197 198 func KeyType(tp string) int32 { 199 switch tp { 200 case "int32": 201 return TY_INT32 202 case "int64": 203 return TY_INT64 204 case "uint32": 205 return TY_UINT32 206 case "uint64": 207 return TY_UINT64 208 case "uint256": 209 return TY_UINT256 210 case "string": 211 return TY_STRING 212 case "address": 213 return TY_ADDRESS 214 case "bool", "_Bool": //support stdbool.h 215 return TY_BOOL 216 case "pointer": 217 return TY_POINTER 218 default: 219 panic(fmt.Sprintf("Error: Unsupport Type %s", tp)) 220 } 221 }