Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1723)

Side by Side Diff: lib/protobuf/runtime/PbList.dart

Issue 10595002: Protocol Buffer runtime library and 'protoc' plugin (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Work around http://code.google.com/p/dart/issues/detail?id=3806 Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « lib/protobuf/runtime/PbInputStreamReader.dart ('k') | lib/protobuf/runtime/PbReader.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 typedef B PartialFunction<A,B>(A a);
6
7 class PbList<E> implements List<E> {
8
9 PbList(this._listener)
10 : _mutableList = null,
11 _immutableList = const [] {
12 _wrappedList = _immutableList;
13 }
14
15 PbList.from(List from, this._listener)
16 : _mutableList = null {
17 if (from is PbImmutableList) {
18 _immutableList = from;
19 } else {
20 _immutableList = new PbImmutableList.from(from);
21 }
22 _wrappedList = _immutableList;
23 }
24
25 /**
26 * Returns an [Iterator] for the list.
27 */
28 Iterator<E> iterator() => _wrappedList.iterator();
29
30 /**
31 * Returns the element at the given [index] in the list or throws
32 * an [IndexOutOfRangeException] if [index] is out of bounds.
33 */
34 E operator [](int index) => _wrappedList[index];
35
36 /**
37 * Sets the entry at the given [index] in the list to [value].
38 * Throws an [IndexOutOfRangeException] if [index] is out of bounds.
39 */
40 void operator []=(int index, E value) {
41 _validate(value);
42 _ensureMutable();
43 _wrappedList[index] = value;
44 _modified();
45 }
46
47 /**
48 * Unsupported -- violated non-null constraint imposed by protobufs.
49 *
50 * Changes the length of the list. If [newLength] is greater than
51 * the current [length], entries are initialized to [:null:]. Throws
52 * an [UnsupportedOperationException] if the list is not extendable.
53 */
54 void set length(int newLength) {
55 throw const UnsupportedOperationException("length");
56 }
57
58 /**
59 * Adds [value] at the end of the list, extending the length by
60 * one. Throws an [UnsupportedOperationException] if the list is not
61 * extendable.
62 */
63 void add(E value) {
64 _validate(value);
65 _ensureMutable();
66 _wrappedList.add(value);
67 _modified();
68 }
69
70 /**
71 * Adds [value] at the end of the list, extending the length by
72 * one. Throws an [UnsupportedOperationException] if the list is not
73 * extendable.
74 */
75 void addLast(E value) {
76 add(value);
77 }
78
79 /**
80 * Appends all elements of the [collection] to the end of list.
81 * Extends the length of the list by the length of [collection].
82 * Throws an [UnsupportedOperationException] if the list is not
83 * extendable.
84 */
85 void addAll(Collection<E> collection) {
86 collection.forEach((E i){ _validate(i); });
87 _ensureMutable();
88 _wrappedList.addAll(collection);
89 _modified();
90 }
91
92 /**
93 * Sorts the list according to the order specified by the comparator.
94 * The order specified by the comparator must be reflexive,
95 * anti-symmetric, and transitive.
96 *
97 * The comparator function [compare] must take two arguments [a] and [b]
98 * and return
99 *
100 * an integer strictly less than 0 if a < b,
101 * 0 if a = b, and
102 * an integer strictly greater than 0 if a > b.
103 */
104 void sort(int compare(E a, E b)) {
105 _ensureMutable();
106 _wrappedList.sort(compare);
107 _modified();
108 }
109
110 /**
111 * Returns the first index of [element] in this list. Searches this
112 * list from index [start] to the length of the list. Returns
113 * -1 if [element] is not found.
114 */
115 int indexOf(E element, [int start = 0]) =>
116 _wrappedList.indexOf(element, start);
117
118 /**
119 * Returns the last index of [element] in this list. Searches this
120 * list from index [start] (inclusive) to 0. Returns -1 if
121 * [element] is not found.
122 */
123 int lastIndexOf(E element, [int start = null]) =>
124 _wrappedList.lastIndexOf(element, start);
125
126 /**
127 * Removes all elements in the list. The length of the list
128 * becomes zero. Throws an [UnsupportedOperationException] if
129 * the list is not extendable.
130 */
131 void clear() {
132 _ensureMutable();
133 _wrappedList.clear();
134 _modified();
135 }
136
137 /**
138 * Pops and returns the last element of the list.
139 * Throws a [UnsupportedOperationException] if the length of the
140 * list cannot be changed.
141 */
142 E removeLast() {
143 _ensureMutable();
144 var value = _wrappedList.removeLast();
145 _modified();
146 return value;
147 }
148
149 /**
150 * Returns the last element of the list, or throws an out of bounds
151 * exception if the list is empty.
152 */
153 E last() => _wrappedList.last();
154
155 /**
156 * Returns a sub list copy of this list, from [start] to
157 * [:start + length:].
158 * Returns an empty list if [length] is 0.
159 * Throws an [IllegalArgumentException] if [length] is negative.
160 * Throws an [IndexOutOfRangeException] if [start] or
161 * [:start + length:] are out of range.
162 */
163 List<E> getRange(int start, int length) =>
164 _wrappedList.getRange(start, length);
165
166 /**
167 * Copies [length] elements of the [from] array, starting
168 * from [startFrom], into [:this:], starting at [start].
169 * Throws an [UnsupportedOperationException] if the list is
170 * not extendable.
171 * If [length] is 0, this method does not do anything.
172 * Throws an [IllegalArgumentException] if [length] is negative.
173 * Throws an [IndexOutOfRangeException] if [start] or
174 * [:start + length:] are out of range for [:this:], or if
175 * [startFrom] is out of range for [from].
176 */
177 void setRange(int start, int length, List<E> from, [int startFrom = 0]) {
178 from.getRange(startFrom, length).forEach((E i){ return _validate(i); });
179 _ensureMutable();
180 _wrappedList.setRange(start, length, from, startFrom);
181 _modified();
182 }
183
184 /**
185 * Removes the range in the list starting from [start] to
186 * [:start + length:].
187 * Throws an [UnsupportedOperationException] if the list is
188 * not extendable.
189 * If [length] is 0, this method does not do anything.
190 * Throws an [IllegalArgumentException] if [length] is negative.
191 * Throws an [IndexOutOfRangeException] if [start] or
192 * [:start + length:] are out of range.
193 */
194 void removeRange(int start, int length) {
195 _ensureMutable();
196 _wrappedList.removeRange(start, length);
197 _modified();
198 }
199
200 /**
201 * UNSUPPORTED. Not of clear value.
202 *
203 * Inserts a new range in the list, starting from [start] to
204 * [:start + length:]. The entries are filled with [initialValue].
205 * Throws an [UnsupportedOperationException] if the list is
206 * not extendable.
207 * If [length] is 0, this method does not do anything.
208 * If [start] is the length of the array, this method inserts the
209 * range at the end of the array.
210 * Throws an [IllegalArgumentException] if [length] is negative.
211 * Throws an [IndexOutOfRangeException] if [start] or
212 * [:start + length:] are out of range.
213 */
214 void insertRange(int start, int length, [E initialValue]) {
215 throw const UnsupportedOperationException("insertRange");
216 }
217
218 /**
219 * Applies the function [f] to each element of this collection.
220 */
221 void forEach(void f(E element)) => _wrappedList.forEach(f);
222
223 /**
224 * Returns a new collection with the elements of this collection
225 * that satisfy the predicate [f].
226 *
227 * An element satisfies the predicate [f] if [:f(element):]
228 * returns true.
229 */
230 Collection<E> filter(bool f(E element)) => _wrappedList.filter(f);
231
232 /**
233 * Returns true if every elements of this collection satisify the
234 * predicate [f]. Returns false otherwise.
235 */
236 bool every(bool f(E element)) => _wrappedList.every(f);
237
238 /**
239 * Returns true if one element of this collection satisfies the
240 * predicate [f]. Returns false otherwise.
241 */
242 bool some(bool f(E element)) => _wrappedList.some(f);
243
244 /**
245 * Returns true if there is no element in this collection.
246 */
247 bool isEmpty() => _wrappedList.isEmpty();
248
249 /**
250 * Returns the number of elements in this collection.
251 */
252 int get length() => _wrappedList.length;
253
254 /*
255 * Return immutable copy of the list.
256 */
257 List<E> asImmutable([PartialFunction<E, E> transform = null]) {
258 if (_immutableList == null) {
259 if (transform == null) {
260 _immutableList = new PbImmutableList.from(_mutableList);
261 } else {
262 List<E> tempList = new List(_mutableList.length);
263 int i = 0;
264 for (E e in _mutableList) {
265 tempList[i] = transform(e);
266 i++;
267 }
268 _immutableList = new PbImmutableList.from(tempList);
269 }
270 _wrappedList = _immutableList;
271 _mutableList = null;
272 }
273 return _immutableList;
274 }
275
276 void _validate(E val) {
277 if (val === null) {
278 throw new NullPointerException();
279 }
280 // Note: the generic parameter [E] is not preserved by the dart2js compiler.
281 // For this reason, in that context both `val is E` and `val is! E` return
282 // true. We write this condition as `!(val isE)` so that the check is done
283 // at least on the dartvm.
284 // TODO(rice,sigmund): remove this trick.
285 if (!(val is E)) {
286 throw new IllegalArgumentException(
287 "Value ($val) is not of the correct type");
288 }
289 }
290
291 void _ensureMutable() {
292 if (_mutableList == null) {
293 _mutableList = new List.from(_immutableList);
294 _wrappedList = _mutableList;
295 _immutableList = null;
296 }
297 }
298
299 void _modified() {
300 // clear local cache of _immutableList
301 if (_listener !== null) _listener.onChanged();
302 }
303
304 Collection map(f(E element)) {
305 throw "not implemented";
306 }
307
308 ChangeListener _listener;
309 List<E> _mutableList;
310 List<E> _immutableList;
311 List<E> _wrappedList;
312 }
313
314 /**
315 * A [PbList] that requires its elements to be [int]s in the range
316 * [:-2^31, 2^31 - 1:].
317 */
318 class PbSint32List extends PbList<int> {
319
320 PbSint32List(ChangeListener listener) : super(listener);
321
322 void _validate(int val) {
323 super._validate(val);
324 if (val < _Constants.MIN_SINT32 || val > _Constants.MAX_SINT32) {
325 throw new IllegalArgumentException("Illegal to add value (${val}): out "
326 "of range for int32");
327 }
328 }
329 }
330
331 /**
332 * A [PbList] that requires its elements to be [int]s in the range
333 * [:0, 2^32 - 1:].
334 */
335 class PbUint32List extends PbList<int> {
336
337 PbUint32List(ChangeListener listener) : super(listener);
338
339 void _validate(int val) {
340 super._validate(val);
341 if (val < 0 || val > _Constants.MAX_UINT32) {
342 throw new IllegalArgumentException("Illegal to add value (${val}):"
343 " out of range for uint32");
344 }
345 }
346 }
347
348 /**
349 * A [PbList] that requires its elements to be [int]s in the range
350 * [:2^-63, 2^63 - 1:] or instances of [Packed64].
351 */
352 class PbSint64List extends PbList<Dynamic> {
353
354 PbSint64List(ChangeListener listener) : super(listener);
355
356 void _validate(int val) {
357 super._validate(val);
358 if (val is Packed64) {
359 return;
360 } else if ((val is num) && (val.floor() == val)) {
361 if (val < _Constants.MIN_SINT64 || val > _Constants.MAX_SINT64) {
362 throw new IllegalArgumentException("Illegal to add value (${val}):"
363 " out of range for sint64");
364 }
365 } else {
366 throw new IllegalArgumentException("Value is not int or Packed64");
367 }
368 }
369 }
370
371 /**
372 * A [PbList] that requires its elements to be [int]s in the range
373 * [:0, 2^64 - 1:] or instances of [Packed64].
374 */
375 class PbUint64List extends PbList<Dynamic> {
376
377 PbUint64List(ChangeListener listener) : super(listener);
378
379 void _validate(int val) {
380 super._validate(val);
381 if (val is Packed64) {
382 return;
383 } else if ((val is num) && (val.floor() == val)) {
384 if (val < 0 || val > _Constants.MAX_UINT64) {
385 throw new IllegalArgumentException("Illegal to add value (${val}):"
386 " out of range for uint64");
387 }
388 } else {
389 throw new IllegalArgumentException("Value is not int or Packed64");
390 }
391 }
392 }
393
394 /**
395 * A [PbList] that requires its elements to be [double]s in the range
396 * [:-3.4E38, 3.4E38:], i.e., with the IEEE single-precision range.
397 */
398 class PbFloatList extends PbList<double> {
399
400 PbFloatList(ChangeListener listener) : super(listener);
401
402 void _validate(double val) {
403 super._validate(val);
404 if (val < -_Constants.MAX_FLOAT || val > _Constants.MAX_FLOAT) {
405 throw new IllegalArgumentException("Illegal to add value (${val}):"
406 " out of range for float");
407 }
408 }
409 }
OLDNEW
« no previous file with comments | « lib/protobuf/runtime/PbInputStreamReader.dart ('k') | lib/protobuf/runtime/PbReader.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698