list.go 2.4 KB

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