github.com/jeffallen/go-ethereum@v1.1.4-0.20150910155051-571d3236c49c/common/list.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum 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-ethereum 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-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package common 18 19 import ( 20 "encoding/json" 21 "reflect" 22 "sync" 23 ) 24 25 // The list type is an anonymous slice handler which can be used 26 // for containing any slice type to use in an environment which 27 // does not support slice types (e.g., JavaScript, QML) 28 type List struct { 29 mut sync.Mutex 30 val interface{} 31 list reflect.Value 32 Length int 33 } 34 35 // Initialise a new list. Panics if non-slice type is given. 36 func NewList(t interface{}) *List { 37 list := reflect.ValueOf(t) 38 if list.Kind() != reflect.Slice { 39 panic("list container initialized with a non-slice type") 40 } 41 42 return &List{sync.Mutex{}, t, list, list.Len()} 43 } 44 45 func EmptyList() *List { 46 return NewList([]interface{}{}) 47 } 48 49 // Get N element from the embedded slice. Returns nil if OOB. 50 func (self *List) Get(i int) interface{} { 51 if self.list.Len() > i { 52 self.mut.Lock() 53 defer self.mut.Unlock() 54 55 i := self.list.Index(i).Interface() 56 57 return i 58 } 59 60 return nil 61 } 62 63 func (self *List) GetAsJson(i int) interface{} { 64 e := self.Get(i) 65 66 r, _ := json.Marshal(e) 67 68 return string(r) 69 } 70 71 // Appends value at the end of the slice. Panics when incompatible value 72 // is given. 73 func (self *List) Append(v interface{}) { 74 self.mut.Lock() 75 defer self.mut.Unlock() 76 77 self.list = reflect.Append(self.list, reflect.ValueOf(v)) 78 self.Length = self.list.Len() 79 } 80 81 // Returns the underlying slice as interface. 82 func (self *List) Interface() interface{} { 83 return self.list.Interface() 84 } 85 86 // For JavaScript <3 87 func (self *List) ToJSON() string { 88 // make(T, 0) != nil 89 list := make([]interface{}, 0) 90 for i := 0; i < self.Length; i++ { 91 list = append(list, self.Get(i)) 92 } 93 94 data, _ := json.Marshal(list) 95 96 return string(data) 97 }