blob: b73469fde5c6c3305b40f595fa0968f631d90673 [file] [log] [blame]
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
part of protobuf;
typedef CheckFunc(x);
class PbList<E> extends Object with ListMixin<E> implements List<E> {
final List<E> _wrappedList;
final CheckFunc check;
PbList({this.check: _checkNotNull}) : _wrappedList = <E>[] {
assert(check != null);
}
PbList.from(List from)
: _wrappedList = new List<E>.from(from),
check = _checkNotNull;
factory PbList.forFieldType(int fieldType) =>
new PbList(check: getCheckFunction(fieldType));
bool operator ==(other) => (other is PbList) && _areListsEqual(other, this);
int get hashCode {
int hash = 0;
_wrappedList.forEach((E value) {
hash = (hash + value.hashCode) & 0x3fffffff;
hash = (hash + hash << 10) & 0x3fffffff;
hash = (hash ^ hash >> 6) & 0x3fffffff;
});
hash = (hash + hash << 3) & 0x3fffffff;
hash = (hash ^ hash >> 11) & 0x3fffffff;
hash = (hash + hash << 15) & 0x3fffffff;
return hash;
}
/**
* Returns an [Iterator] for the list.
*/
Iterator<E> get iterator => _wrappedList.iterator;
/**
* Returns the element at the given [index] in the list or throws
* an [IndexOutOfRangeException] if [index] is out of bounds.
*/
E operator [](int index) => _wrappedList[index];
/**
* Sets the entry at the given [index] in the list to [value].
* Throws an [IndexOutOfRangeException] if [index] is out of bounds.
*/
void operator []=(int index, E value) {
_validate(value);
_wrappedList[index] = value;
}
/**
* Unsupported -- violated non-null constraint imposed by protobufs.
*
* Changes the length of the list. If [newLength] is greater than
* the current [length], entries are initialized to [:null:]. Throws
* an [UnsupportedError] if the list is not extendable.
*/
void set length(int newLength) {
if (newLength > length) {
throw new ArgumentError('Extending protobuf lists is not supported');
}
_wrappedList.length = newLength;
}
/**
* Adds [value] at the end of the list, extending the length by
* one. Throws an [UnsupportedError] if the list is not
* extendable.
*/
void add(E value) {
_validate(value);
_wrappedList.add(value);
}
/**
* Appends all elements of the [collection] to the end of list.
* Extends the length of the list by the length of [collection].
* Throws an [UnsupportedError] if the list is not
* extendable.
*/
void addAll(Iterable<E> collection) {
collection.forEach(_validate);
_wrappedList.addAll(collection);
}
/**
* Copies [:end - start:] elements of the [from] array, starting
* from [skipCount], into [:this:], starting at [start].
* Throws an [UnsupportedError] if the list is
* not extendable.
*/
void setRange(int start, int end, Iterable<E> from, [int skipCount = 0]) {
// NOTE: In case `take()` returns less than `end - start` elements, the
// _wrappedList will fail with a `StateError`.
from.skip(skipCount).take(end - start).forEach(_validate);
_wrappedList.setRange(start, end, from, skipCount);
}
/**
* Inserts a new element in the list.
* The element must be valid (and not nullable) for the PbList type.
*/
void insert(int index, E element) {
_validate(element);
_wrappedList.insert(index, element);
}
/**
* Inserts all elements of [iterable] at position [index] in the list.
*
* Elements in [iterable] must be valid and not nullable for the PbList type.
*/
void insertAll(int index, Iterable<E> iterable) {
iterable.forEach(_validate);
_wrappedList.insertAll(index, iterable);
}
/**
* Overwrites elements of `this` with elements of [iterable] starting at
* position [index] in the list.
*
* Elements in [iterable] must be valid and not nullable for the PbList type.
*/
void setAll(int index, Iterable<E> iterable) {
iterable.forEach(_validate);
_wrappedList.setAll(index, iterable);
}
/**
* Returns the number of elements in this collection.
*/
int get length => _wrappedList.length;
void _validate(E val) {
check(val);
// TODO: remove after migration to check functions is finished
if (val is! E) {
throw new ArgumentError('Value ($val) is not of the correct type');
}
}
}