LCOV - code coverage report
Current view: top level - typed_data-1.3.0/lib/src - typed_buffer.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 0 172 0.0 %
Date: 2021-11-28 14:37:50 Functions: 0 0 -

          Line data    Source code
       1             : // Copyright (c) 2020, 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             : import 'dart:collection' show ListBase;
       6             : import 'dart:typed_data';
       7             : 
       8             : abstract class TypedDataBuffer<E> extends ListBase<E> {
       9             :   static const int _initialLength = 8;
      10             : 
      11             :   /// The underlying data buffer.
      12             :   ///
      13             :   /// This is always both a List<E> and a TypedData, which we don't have a type
      14             :   /// for here. For example, for a `Uint8Buffer`, this is a `Uint8List`.
      15             :   List<E> _buffer;
      16             : 
      17             :   /// Returns a view of [_buffer] as a [TypedData].
      18           0 :   TypedData get _typedBuffer => _buffer as TypedData;
      19             : 
      20             :   /// The length of the list being built.
      21             :   int _length;
      22             : 
      23           0 :   TypedDataBuffer(List<E> buffer)
      24             :       : _buffer = buffer,
      25           0 :         _length = buffer.length;
      26             : 
      27           0 :   @override
      28           0 :   int get length => _length;
      29             : 
      30           0 :   @override
      31             :   E operator [](int index) {
      32           0 :     if (index >= length) throw RangeError.index(index, this);
      33           0 :     return _buffer[index];
      34             :   }
      35             : 
      36           0 :   @override
      37             :   void operator []=(int index, E value) {
      38           0 :     if (index >= length) throw RangeError.index(index, this);
      39           0 :     _buffer[index] = value;
      40             :   }
      41             : 
      42           0 :   @override
      43             :   set length(int newLength) {
      44           0 :     if (newLength < _length) {
      45           0 :       var defaultValue = _defaultValue;
      46           0 :       for (var i = newLength; i < _length; i++) {
      47           0 :         _buffer[i] = defaultValue;
      48             :       }
      49           0 :     } else if (newLength > _buffer.length) {
      50             :       List<E> newBuffer;
      51           0 :       if (_buffer.isEmpty) {
      52           0 :         newBuffer = _createBuffer(newLength);
      53             :       } else {
      54           0 :         newBuffer = _createBiggerBuffer(newLength);
      55             :       }
      56           0 :       newBuffer.setRange(0, _length, _buffer);
      57           0 :       _buffer = newBuffer;
      58             :     }
      59           0 :     _length = newLength;
      60             :   }
      61             : 
      62           0 :   void _add(E value) {
      63           0 :     if (_length == _buffer.length) _grow(_length);
      64           0 :     _buffer[_length++] = value;
      65             :   }
      66             : 
      67             :   // We override the default implementation of `add` because it grows the list
      68             :   // by setting the length in increments of one. We want to grow by doubling
      69             :   // capacity in most cases.
      70           0 :   @override
      71             :   void add(E value) {
      72           0 :     _add(value);
      73             :   }
      74             : 
      75             :   /// Appends all objects of [values] to the end of this buffer.
      76             :   ///
      77             :   /// This adds values from [start] (inclusive) to [end] (exclusive) in
      78             :   /// [values]. If [end] is omitted, it defaults to adding all elements of
      79             :   /// [values] after [start].
      80             :   ///
      81             :   /// The [start] value must be non-negative. The [values] iterable must have at
      82             :   /// least [start] elements, and if [end] is specified, it must be greater than
      83             :   /// or equal to [start] and [values] must have at least [end] elements.
      84           0 :   @override
      85             :   void addAll(Iterable<E> values, [int start = 0, int? end]) {
      86           0 :     RangeError.checkNotNegative(start, 'start');
      87           0 :     if (end != null && start > end) {
      88           0 :       throw RangeError.range(end, start, null, 'end');
      89             :     }
      90             : 
      91           0 :     _addAll(values, start, end);
      92             :   }
      93             : 
      94             :   /// Inserts all objects of [values] at position [index] in this list.
      95             :   ///
      96             :   /// This adds values from [start] (inclusive) to [end] (exclusive) in
      97             :   /// [values]. If [end] is omitted, it defaults to adding all elements of
      98             :   /// [values] after [start].
      99             :   ///
     100             :   /// The [start] value must be non-negative. The [values] iterable must have at
     101             :   /// least [start] elements, and if [end] is specified, it must be greater than
     102             :   /// or equal to [start] and [values] must have at least [end] elements.
     103           0 :   @override
     104             :   void insertAll(int index, Iterable<E> values, [int start = 0, int? end]) {
     105           0 :     RangeError.checkValidIndex(index, this, 'index', _length + 1);
     106           0 :     RangeError.checkNotNegative(start, 'start');
     107             :     if (end != null) {
     108           0 :       if (start > end) {
     109           0 :         throw RangeError.range(end, start, null, 'end');
     110             :       }
     111           0 :       if (start == end) return;
     112             :     }
     113             : 
     114             :     // If we're adding to the end of the list anyway, use [_addAll]. This lets
     115             :     // us avoid converting [values] into a list even if [end] is null, since we
     116             :     // can add values iteratively to the end of the list. We can't do so in the
     117             :     // center because copying the trailing elements every time is non-linear.
     118           0 :     if (index == _length) {
     119           0 :       _addAll(values, start, end);
     120             :       return;
     121             :     }
     122             : 
     123           0 :     if (end == null && values is List) {
     124           0 :       end = values.length;
     125             :     }
     126             :     if (end != null) {
     127           0 :       _insertKnownLength(index, values, start, end);
     128             :       return;
     129             :     }
     130             : 
     131             :     // Add elements at end, growing as appropriate, then put them back at
     132             :     // position [index] using flip-by-double-reverse.
     133           0 :     var writeIndex = _length;
     134             :     var skipCount = start;
     135           0 :     for (var value in values) {
     136           0 :       if (skipCount > 0) {
     137           0 :         skipCount--;
     138             :         continue;
     139             :       }
     140           0 :       if (writeIndex == _buffer.length) {
     141           0 :         _grow(writeIndex);
     142             :       }
     143           0 :       _buffer[writeIndex++] = value;
     144             :     }
     145             : 
     146           0 :     if (skipCount > 0) {
     147           0 :       throw StateError('Too few elements');
     148             :     }
     149           0 :     if (end != null && writeIndex < end) {
     150           0 :       throw RangeError.range(end, start, writeIndex, 'end');
     151             :     }
     152             : 
     153             :     // Swap [index.._length) and [_length..writeIndex) by double-reversing.
     154           0 :     _reverse(_buffer, index, _length);
     155           0 :     _reverse(_buffer, _length, writeIndex);
     156           0 :     _reverse(_buffer, index, writeIndex);
     157           0 :     _length = writeIndex;
     158             :     return;
     159             :   }
     160             : 
     161             :   // Reverses the range [start..end) of buffer.
     162           0 :   static void _reverse(List buffer, int start, int end) {
     163           0 :     end--; // Point to last element, not after last element.
     164           0 :     while (start < end) {
     165           0 :       var first = buffer[start];
     166           0 :       var last = buffer[end];
     167           0 :       buffer[end] = first;
     168           0 :       buffer[start] = last;
     169           0 :       start++;
     170           0 :       end--;
     171             :     }
     172             :   }
     173             : 
     174             :   /// Does the same thing as [addAll].
     175             :   ///
     176             :   /// This allows [addAll] and [insertAll] to share implementation without a
     177             :   /// subclass unexpectedly overriding both when it intended to only override
     178             :   /// [addAll].
     179           0 :   void _addAll(Iterable<E> values, [int start = 0, int? end]) {
     180           0 :     if (values is List) end ??= values.length;
     181             : 
     182             :     // If we know the length of the segment to add, do so with [addRange]. This
     183             :     // way we know how much to grow the buffer in advance, and it may be even
     184             :     // more efficient for typed data input.
     185             :     if (end != null) {
     186           0 :       _insertKnownLength(_length, values, start, end);
     187             :       return;
     188             :     }
     189             : 
     190             :     // Otherwise, just add values one at a time.
     191             :     var i = 0;
     192           0 :     for (var value in values) {
     193           0 :       if (i >= start) add(value);
     194           0 :       i++;
     195             :     }
     196           0 :     if (i < start) throw StateError('Too few elements');
     197             :   }
     198             : 
     199             :   /// Like [insertAll], but with a guaranteed non-`null` [start] and [end].
     200           0 :   void _insertKnownLength(int index, Iterable<E> values, int start, int end) {
     201           0 :     if (values is List) {
     202           0 :       if (start > values.length || end > values.length) {
     203           0 :         throw StateError('Too few elements');
     204             :       }
     205             :     }
     206             : 
     207           0 :     var valuesLength = end - start;
     208           0 :     var newLength = _length + valuesLength;
     209           0 :     _ensureCapacity(newLength);
     210             : 
     211           0 :     _buffer.setRange(
     212           0 :         index + valuesLength, _length + valuesLength, _buffer, index);
     213           0 :     _buffer.setRange(index, index + valuesLength, values, start);
     214           0 :     _length = newLength;
     215             :   }
     216             : 
     217           0 :   @override
     218             :   void insert(int index, E element) {
     219           0 :     if (index < 0 || index > _length) {
     220           0 :       throw RangeError.range(index, 0, _length);
     221             :     }
     222           0 :     if (_length < _buffer.length) {
     223           0 :       _buffer.setRange(index + 1, _length + 1, _buffer, index);
     224           0 :       _buffer[index] = element;
     225           0 :       _length++;
     226             :       return;
     227             :     }
     228           0 :     var newBuffer = _createBiggerBuffer(null);
     229           0 :     newBuffer.setRange(0, index, _buffer);
     230           0 :     newBuffer.setRange(index + 1, _length + 1, _buffer, index);
     231           0 :     newBuffer[index] = element;
     232           0 :     _length++;
     233           0 :     _buffer = newBuffer;
     234             :   }
     235             : 
     236             :   /// Ensures that [_buffer] is at least [requiredCapacity] long,
     237             :   ///
     238             :   /// Grows the buffer if necessary, preserving existing data.
     239           0 :   void _ensureCapacity(int requiredCapacity) {
     240           0 :     if (requiredCapacity <= _buffer.length) return;
     241           0 :     var newBuffer = _createBiggerBuffer(requiredCapacity);
     242           0 :     newBuffer.setRange(0, _length, _buffer);
     243           0 :     _buffer = newBuffer;
     244             :   }
     245             : 
     246             :   /// Create a bigger buffer.
     247             :   ///
     248             :   /// This method determines how much bigger a bigger buffer should
     249             :   /// be. If [requiredCapacity] is not null, it will be at least that
     250             :   /// size. It will always have at least have double the capacity of
     251             :   /// the current buffer.
     252           0 :   List<E> _createBiggerBuffer(int? requiredCapacity) {
     253           0 :     var newLength = _buffer.length * 2;
     254           0 :     if (requiredCapacity != null && newLength < requiredCapacity) {
     255             :       newLength = requiredCapacity;
     256           0 :     } else if (newLength < _initialLength) {
     257             :       newLength = _initialLength;
     258             :     }
     259           0 :     return _createBuffer(newLength);
     260             :   }
     261             : 
     262             :   /// Grows the buffer.
     263             :   ///
     264             :   /// This copies the first [length] elements into the new buffer.
     265           0 :   void _grow(int length) {
     266           0 :     _buffer = _createBiggerBuffer(null)..setRange(0, length, _buffer);
     267             :   }
     268             : 
     269           0 :   @override
     270             :   void setRange(int start, int end, Iterable<E> source, [int skipCount = 0]) {
     271           0 :     if (end > _length) throw RangeError.range(end, 0, _length);
     272           0 :     _setRange(start, end, source, skipCount);
     273             :   }
     274             : 
     275             :   /// Like [setRange], but with no bounds checking.
     276           0 :   void _setRange(int start, int end, Iterable<E> source, int skipCount) {
     277           0 :     if (source is TypedDataBuffer<E>) {
     278           0 :       _buffer.setRange(start, end, source._buffer, skipCount);
     279             :     } else {
     280           0 :       _buffer.setRange(start, end, source, skipCount);
     281             :     }
     282             :   }
     283             : 
     284             :   // TypedData.
     285             : 
     286           0 :   int get elementSizeInBytes => _typedBuffer.elementSizeInBytes;
     287             : 
     288           0 :   int get lengthInBytes => _length * _typedBuffer.elementSizeInBytes;
     289             : 
     290           0 :   int get offsetInBytes => _typedBuffer.offsetInBytes;
     291             : 
     292             :   /// Returns the underlying [ByteBuffer].
     293             :   ///
     294             :   /// The returned buffer may be replaced by operations that change the [length]
     295             :   /// of this list.
     296             :   ///
     297             :   /// The buffer may be larger than [lengthInBytes] bytes, but never smaller.
     298           0 :   ByteBuffer get buffer => _typedBuffer.buffer;
     299             : 
     300             :   // Specialization for the specific type.
     301             : 
     302             :   // Return zero for integers, 0.0 for floats, etc.
     303             :   // Used to fill buffer when changing length.
     304             :   E get _defaultValue;
     305             : 
     306             :   // Create a new typed list to use as buffer.
     307             :   List<E> _createBuffer(int size);
     308             : }
     309             : 
     310             : abstract class _IntBuffer extends TypedDataBuffer<int> {
     311           0 :   _IntBuffer(List<int> buffer) : super(buffer);
     312             : 
     313           0 :   @override
     314             :   int get _defaultValue => 0;
     315             : }
     316             : 
     317             : abstract class _FloatBuffer extends TypedDataBuffer<double> {
     318           0 :   _FloatBuffer(List<double> buffer) : super(buffer);
     319             : 
     320           0 :   @override
     321             :   double get _defaultValue => 0.0;
     322             : }
     323             : 
     324             : class Uint8Buffer extends _IntBuffer {
     325           0 :   Uint8Buffer([int initialLength = 0]) : super(Uint8List(initialLength));
     326             : 
     327           0 :   @override
     328           0 :   Uint8List _createBuffer(int size) => Uint8List(size);
     329             : }
     330             : 
     331             : class Int8Buffer extends _IntBuffer {
     332           0 :   Int8Buffer([int initialLength = 0]) : super(Int8List(initialLength));
     333             : 
     334           0 :   @override
     335           0 :   Int8List _createBuffer(int size) => Int8List(size);
     336             : }
     337             : 
     338             : class Uint8ClampedBuffer extends _IntBuffer {
     339           0 :   Uint8ClampedBuffer([int initialLength = 0])
     340           0 :       : super(Uint8ClampedList(initialLength));
     341             : 
     342           0 :   @override
     343           0 :   Uint8ClampedList _createBuffer(int size) => Uint8ClampedList(size);
     344             : }
     345             : 
     346             : class Uint16Buffer extends _IntBuffer {
     347           0 :   Uint16Buffer([int initialLength = 0]) : super(Uint16List(initialLength));
     348             : 
     349           0 :   @override
     350           0 :   Uint16List _createBuffer(int size) => Uint16List(size);
     351             : }
     352             : 
     353             : class Int16Buffer extends _IntBuffer {
     354           0 :   Int16Buffer([int initialLength = 0]) : super(Int16List(initialLength));
     355             : 
     356           0 :   @override
     357           0 :   Int16List _createBuffer(int size) => Int16List(size);
     358             : }
     359             : 
     360             : class Uint32Buffer extends _IntBuffer {
     361           0 :   Uint32Buffer([int initialLength = 0]) : super(Uint32List(initialLength));
     362             : 
     363           0 :   @override
     364           0 :   Uint32List _createBuffer(int size) => Uint32List(size);
     365             : }
     366             : 
     367             : class Int32Buffer extends _IntBuffer {
     368           0 :   Int32Buffer([int initialLength = 0]) : super(Int32List(initialLength));
     369             : 
     370           0 :   @override
     371           0 :   Int32List _createBuffer(int size) => Int32List(size);
     372             : }
     373             : 
     374             : class Uint64Buffer extends _IntBuffer {
     375           0 :   Uint64Buffer([int initialLength = 0]) : super(Uint64List(initialLength));
     376             : 
     377           0 :   @override
     378           0 :   Uint64List _createBuffer(int size) => Uint64List(size);
     379             : }
     380             : 
     381             : class Int64Buffer extends _IntBuffer {
     382           0 :   Int64Buffer([int initialLength = 0]) : super(Int64List(initialLength));
     383             : 
     384           0 :   @override
     385           0 :   Int64List _createBuffer(int size) => Int64List(size);
     386             : }
     387             : 
     388             : class Float32Buffer extends _FloatBuffer {
     389           0 :   Float32Buffer([int initialLength = 0]) : super(Float32List(initialLength));
     390             : 
     391           0 :   @override
     392           0 :   Float32List _createBuffer(int size) => Float32List(size);
     393             : }
     394             : 
     395             : class Float64Buffer extends _FloatBuffer {
     396           0 :   Float64Buffer([int initialLength = 0]) : super(Float64List(initialLength));
     397             : 
     398           0 :   @override
     399           0 :   Float64List _createBuffer(int size) => Float64List(size);
     400             : }
     401             : 
     402             : class Int32x4Buffer extends TypedDataBuffer<Int32x4> {
     403           0 :   static final Int32x4 _zero = Int32x4(0, 0, 0, 0);
     404             : 
     405           0 :   Int32x4Buffer([int initialLength = 0]) : super(Int32x4List(initialLength));
     406             : 
     407           0 :   @override
     408           0 :   Int32x4 get _defaultValue => _zero;
     409             : 
     410           0 :   @override
     411           0 :   Int32x4List _createBuffer(int size) => Int32x4List(size);
     412             : }
     413             : 
     414             : class Float32x4Buffer extends TypedDataBuffer<Float32x4> {
     415           0 :   Float32x4Buffer([int initialLength = 0])
     416           0 :       : super(Float32x4List(initialLength));
     417             : 
     418           0 :   @override
     419           0 :   Float32x4 get _defaultValue => Float32x4.zero();
     420             : 
     421           0 :   @override
     422           0 :   Float32x4List _createBuffer(int size) => Float32x4List(size);
     423             : }

Generated by: LCOV version 1.14