github.com/jonasnick/go-ethereum@v0.7.12-0.20150216215225-22176f05d387/ethutil/list.go (about)

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