THRIFT-625: Add support for 'Go'; provided by Aalok Shah.
git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1072478 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/go/thrift/tlist.go b/lib/go/thrift/tlist.go
new file mode 100644
index 0000000..778fc3b
--- /dev/null
+++ b/lib/go/thrift/tlist.go
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package thrift
+
+import (
+ "container/vector"
+)
+
+/**
+ * Helper class that encapsulates list metadata.
+ *
+ */
+type TList interface {
+ TContainer
+ ElemType() TType
+ At(i int) interface{}
+ Set(i int, data interface{})
+ Push(data interface{})
+ Pop() interface{}
+ Swap(i, j int)
+ Insert(i int, data interface{})
+ Delete(i int)
+ Less(i, j int) bool
+ Iter() <-chan interface{}
+}
+
+type tList struct {
+ elemType TType
+ l *vector.Vector
+}
+
+func NewTList(t TType, s int) TList {
+ var v vector.Vector
+ return &tList{elemType: t, l: v.Resize(s, s)}
+}
+
+func NewTListDefault() TList {
+ var v vector.Vector
+ return &tList{elemType: TType(STOP), l: &v}
+}
+
+func (p *tList) ElemType() TType {
+ return p.elemType
+}
+
+func (p *tList) Len() int {
+ return p.l.Len()
+}
+
+func (p *tList) At(i int) interface{} {
+ return p.l.At(i)
+}
+
+func (p *tList) Set(i int, data interface{}) {
+ if p.elemType.IsEmptyType() {
+ p.elemType = TypeFromValue(data)
+ }
+ if data, ok := p.elemType.CoerceData(data); ok {
+ p.l.Set(i, data)
+ }
+}
+
+func (p *tList) Push(data interface{}) {
+ if p.elemType.IsEmptyType() {
+ p.elemType = TypeFromValue(data)
+ }
+ data, ok := p.elemType.CoerceData(data)
+ if ok {
+ p.l.Push(data)
+ }
+}
+
+func (p *tList) Pop() interface{} {
+ return p.l.Pop()
+}
+
+func (p *tList) Swap(i, j int) {
+ p.l.Swap(i, j)
+}
+
+func (p *tList) Insert(i int, data interface{}) {
+ p.l.Insert(i, data)
+}
+
+func (p *tList) Delete(i int) {
+ p.l.Delete(i)
+}
+
+func (p *tList) Contains(data interface{}) bool {
+ return p.indexOf(data) >= 0
+}
+
+func (p *tList) Less(i, j int) bool {
+ return p.l.Less(i, j)
+}
+
+func (p *tList) Iter() <-chan interface{} {
+ c := make(chan interface{})
+ go p.iterate(c)
+ return c
+}
+
+func (p *tList) iterate(c chan<- interface{}) {
+ for _, elem := range *p.l {
+ c <- elem
+ }
+ close(c)
+}
+
+func (p *tList) indexOf(data interface{}) int {
+ if data == nil {
+ size := p.l.Len()
+ for i := 0; i < size; i++ {
+ if p.l.At(i) == nil {
+ return i
+ }
+ }
+ return -1
+ }
+ data, ok := p.elemType.CoerceData(data)
+ if data == nil || !ok {
+ return -1
+ }
+ size := p.l.Len()
+ if p.elemType.IsBaseType() || p.elemType.IsEnum() {
+ for i := 0; i < size; i++ {
+ if data == p.l.At(i) {
+ return i
+ }
+ }
+ return -1
+ }
+ if cmp, ok := data.(EqualsOtherInterface); ok {
+ for i := 0; i < size; i++ {
+ if cmp.Equals(p.l.At(i)) {
+ return i
+ }
+ }
+ return -1
+ }
+ switch p.elemType {
+ case MAP:
+ if cmp, ok := data.(EqualsMap); ok {
+ for i := 0; i < size; i++ {
+ v := p.l.At(i)
+ if v == nil {
+ continue
+ }
+ if cmp.Equals(v.(TMap)) {
+ return i
+ }
+ }
+ return -1
+ }
+ case SET:
+ if cmp, ok := data.(EqualsSet); ok {
+ for i := 0; i < size; i++ {
+ v := p.l.At(i)
+ if v == nil {
+ continue
+ }
+ if cmp.Equals(v.(TSet)) {
+ return i
+ }
+ }
+ return -1
+ }
+ case LIST:
+ if cmp, ok := data.(EqualsList); ok {
+ for i := 0; i < size; i++ {
+ v := p.l.At(i)
+ if v == nil {
+ continue
+ }
+ if cmp.Equals(v.(TList)) {
+ return i
+ }
+ }
+ return -1
+ }
+ case STRUCT:
+ if cmp, ok := data.(EqualsStruct); ok {
+ for i := 0; i < size; i++ {
+ v := p.l.At(i)
+ if v == nil {
+ continue
+ }
+ if cmp.Equals(v.(TStruct)) {
+ return i
+ }
+ }
+ return -1
+ }
+ }
+ return -1
+}
+
+func (p *tList) Equals(other interface{}) bool {
+ c, cok := p.CompareTo(other)
+ return cok && c == 0
+}
+
+func (p *tList) CompareTo(other interface{}) (int, bool) {
+ return TType(LIST).Compare(p, other)
+}