blob: 46644e598a6312c8c6737e603f9d0ec8102eecde [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;
class PbList<E> extends Object with ListMixin<E> implements List<E> {
PbList() : _wrappedList = <E>[];
PbList.from(List from) : _wrappedList = new List<E>.from(from);
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);
}
/**
* Overrites 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) {
if (val == null) {
throw new ArgumentError('Value is null');
}
if (val is! E) {
throw new ArgumentError(
'Value ($val) is not of the correct type');
}
_validateElement(val);
}
void _validateElement(E val) {}
final List<E> _wrappedList;
}
/**
* A [PbList] that requires its elements to be [int]s in the range
* [:-2^31, 2^31 - 1:].
*/
class PbSint32List extends PbList<int> {
void _validateElement(int val) {
if (!_isSigned32(val)) {
throw new ArgumentError('Illegal to add value (${val}): out '
'of range for int32');
}
}
}
/**
* A [PbList] that requires its elements to be [int]s in the range
* [:0, 2^32 - 1:].
*/
class PbUint32List extends PbList<int> {
void _validateElement(int val) {
if (!_isUnsigned32(val)) {
throw new ArgumentError('Illegal to add value (${val}):'
' out of range for uint32');
}
}
}
/**
* A [PbList] that requires its elements to be [int]s in the range
* [:2^-63, 2^63 - 1:].
*/
class PbSint64List extends PbList<Int64> {
void _validateElement(Int64 val) {
if (!_isSigned64(val)) {
throw new ArgumentError('Illegal to add value (${val}):'
' out of range for sint64');
}
}
}
/**
* A [PbList] that requires its elements to be [int]s in the range
* [:0, 2^64 - 1:].
*/
class PbUint64List extends PbList<Int64> {
void _validateElement(Int64 val) {
if (!_isUnsigned64(val)) {
throw new ArgumentError('Illegal to add value (${val}):'
' out of range for uint64');
}
}
}
/**
* A [PbList] that requires its elements to be [double]s in the range
* [:-3.4E38, 3.4E38:], i.e., with the IEEE single-precision range.
*/
class PbFloatList extends PbList<double> {
void _validateElement(double val) {
if (!_isFloat32(val)) {
throw new ArgumentError('Illegal to add value (${val}):'
' out of range for float');
}
}
}