blob: 778fc3b6c9fb31da7b094ee60c1d5ac263a432c1 [file] [log] [blame]
Christian Lavoieafc6d8f2011-02-20 02:39:19 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20package thrift
21
22import (
23 "container/vector"
24)
25
26/**
27 * Helper class that encapsulates list metadata.
28 *
29 */
30type TList interface {
31 TContainer
32 ElemType() TType
33 At(i int) interface{}
34 Set(i int, data interface{})
35 Push(data interface{})
36 Pop() interface{}
37 Swap(i, j int)
38 Insert(i int, data interface{})
39 Delete(i int)
40 Less(i, j int) bool
41 Iter() <-chan interface{}
42}
43
44type tList struct {
45 elemType TType
46 l *vector.Vector
47}
48
49func NewTList(t TType, s int) TList {
50 var v vector.Vector
51 return &tList{elemType: t, l: v.Resize(s, s)}
52}
53
54func NewTListDefault() TList {
55 var v vector.Vector
56 return &tList{elemType: TType(STOP), l: &v}
57}
58
59func (p *tList) ElemType() TType {
60 return p.elemType
61}
62
63func (p *tList) Len() int {
64 return p.l.Len()
65}
66
67func (p *tList) At(i int) interface{} {
68 return p.l.At(i)
69}
70
71func (p *tList) Set(i int, data interface{}) {
72 if p.elemType.IsEmptyType() {
73 p.elemType = TypeFromValue(data)
74 }
75 if data, ok := p.elemType.CoerceData(data); ok {
76 p.l.Set(i, data)
77 }
78}
79
80func (p *tList) Push(data interface{}) {
81 if p.elemType.IsEmptyType() {
82 p.elemType = TypeFromValue(data)
83 }
84 data, ok := p.elemType.CoerceData(data)
85 if ok {
86 p.l.Push(data)
87 }
88}
89
90func (p *tList) Pop() interface{} {
91 return p.l.Pop()
92}
93
94func (p *tList) Swap(i, j int) {
95 p.l.Swap(i, j)
96}
97
98func (p *tList) Insert(i int, data interface{}) {
99 p.l.Insert(i, data)
100}
101
102func (p *tList) Delete(i int) {
103 p.l.Delete(i)
104}
105
106func (p *tList) Contains(data interface{}) bool {
107 return p.indexOf(data) >= 0
108}
109
110func (p *tList) Less(i, j int) bool {
111 return p.l.Less(i, j)
112}
113
114func (p *tList) Iter() <-chan interface{} {
115 c := make(chan interface{})
116 go p.iterate(c)
117 return c
118}
119
120func (p *tList) iterate(c chan<- interface{}) {
121 for _, elem := range *p.l {
122 c <- elem
123 }
124 close(c)
125}
126
127func (p *tList) indexOf(data interface{}) int {
128 if data == nil {
129 size := p.l.Len()
130 for i := 0; i < size; i++ {
131 if p.l.At(i) == nil {
132 return i
133 }
134 }
135 return -1
136 }
137 data, ok := p.elemType.CoerceData(data)
138 if data == nil || !ok {
139 return -1
140 }
141 size := p.l.Len()
142 if p.elemType.IsBaseType() || p.elemType.IsEnum() {
143 for i := 0; i < size; i++ {
144 if data == p.l.At(i) {
145 return i
146 }
147 }
148 return -1
149 }
150 if cmp, ok := data.(EqualsOtherInterface); ok {
151 for i := 0; i < size; i++ {
152 if cmp.Equals(p.l.At(i)) {
153 return i
154 }
155 }
156 return -1
157 }
158 switch p.elemType {
159 case MAP:
160 if cmp, ok := data.(EqualsMap); ok {
161 for i := 0; i < size; i++ {
162 v := p.l.At(i)
163 if v == nil {
164 continue
165 }
166 if cmp.Equals(v.(TMap)) {
167 return i
168 }
169 }
170 return -1
171 }
172 case SET:
173 if cmp, ok := data.(EqualsSet); ok {
174 for i := 0; i < size; i++ {
175 v := p.l.At(i)
176 if v == nil {
177 continue
178 }
179 if cmp.Equals(v.(TSet)) {
180 return i
181 }
182 }
183 return -1
184 }
185 case LIST:
186 if cmp, ok := data.(EqualsList); ok {
187 for i := 0; i < size; i++ {
188 v := p.l.At(i)
189 if v == nil {
190 continue
191 }
192 if cmp.Equals(v.(TList)) {
193 return i
194 }
195 }
196 return -1
197 }
198 case STRUCT:
199 if cmp, ok := data.(EqualsStruct); ok {
200 for i := 0; i < size; i++ {
201 v := p.l.At(i)
202 if v == nil {
203 continue
204 }
205 if cmp.Equals(v.(TStruct)) {
206 return i
207 }
208 }
209 return -1
210 }
211 }
212 return -1
213}
214
215func (p *tList) Equals(other interface{}) bool {
216 c, cok := p.CompareTo(other)
217 return cok && c == 0
218}
219
220func (p *tList) CompareTo(other interface{}) (int, bool) {
221 return TType(LIST).Compare(p, other)
222}