OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 // patch classes for Int8List ..... Float64List and ByteData implementations. | 5 // patch classes for Int8List ..... Float64List and ByteData implementations. |
6 | 6 |
7 patch class Int8List { | 7 patch class Int8List { |
8 /* patch */ factory Int8List(int length) { | 8 /* patch */ factory Int8List(int length) { |
9 return new _Int8Array(length); | 9 return new _Int8Array(length); |
10 } | 10 } |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
291 } | 291 } |
292 /* patch */ factory Int32x4.fromFloat32x4Bits(Float32x4 x) { | 292 /* patch */ factory Int32x4.fromFloat32x4Bits(Float32x4 x) { |
293 return new _Int32x4.fromFloat32x4Bits(x); | 293 return new _Int32x4.fromFloat32x4Bits(x); |
294 } | 294 } |
295 } | 295 } |
296 | 296 |
297 | 297 |
298 patch class ByteData { | 298 patch class ByteData { |
299 /* patch */ factory ByteData(int length) { | 299 /* patch */ factory ByteData(int length) { |
300 var list = new _Uint8Array(length); | 300 var list = new _Uint8Array(length); |
301 return new _ByteDataView(list.buffer, 0, length); | 301 return new _ByteDataView(list, 0, length); |
302 } | 302 } |
303 | 303 |
304 /* patch */ factory ByteData.view(ByteBuffer buffer, | 304 /* patch */ factory ByteData.view(ByteBuffer buffer, |
305 [int offsetInBytes = 0, int length]) { | 305 [int offsetInBytes = 0, int length]) { |
306 if (length == null) { | 306 if (length == null) { |
307 length = buffer.lengthInBytes - offsetInBytes; | 307 length = buffer.lengthInBytes - offsetInBytes; |
308 } | 308 } |
309 return new _ByteDataView(buffer, offsetInBytes, length); | 309 _ByteBuffer internalBuffer = buffer; |
310 return new _ByteDataView(internalBuffer._typedData, offsetInBytes, length); | |
310 } | 311 } |
312 | |
313 // Called directly from C code. | |
314 factory ByteData._view(TypedData typedData, int offsetInBytes, int length) | |
315 => new _ByteDataView(typedData, offsetInBytes, length); | |
311 } | 316 } |
312 | 317 |
313 | 318 |
314 // Based class for _TypedList that provides common methods for implementing | 319 // Based class for _TypedList that provides common methods for implementing |
315 // the collection and list interfaces. | 320 // the collection and list interfaces. |
316 | 321 |
317 abstract class _TypedListBase { | 322 abstract class _TypedListBase { |
318 | 323 |
319 // Method(s) implementing the Collection interface. | 324 // Method(s) implementing the Collection interface. |
320 bool contains(element) => IterableMixinWorkaround.contains(this, element); | 325 bool contains(element) => IterableMixinWorkaround.contains(this, element); |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
547 throw new StateError("Not enough elements"); | 552 throw new StateError("Not enough elements"); |
548 } | 553 } |
549 | 554 |
550 if (from is _TypedListBase) { | 555 if (from is _TypedListBase) { |
551 final needsClamping = | 556 final needsClamping = |
552 this._isClamped() && (this._isClamped() != from._isClamped()); | 557 this._isClamped() && (this._isClamped() != from._isClamped()); |
553 if (this.elementSizeInBytes == from.elementSizeInBytes) { | 558 if (this.elementSizeInBytes == from.elementSizeInBytes) { |
554 if (needsClamping) { | 559 if (needsClamping) { |
555 Lists.copy(from, skipCount, this, start, count); | 560 Lists.copy(from, skipCount, this, start, count); |
556 return; | 561 return; |
557 } else if (this.buffer._setRange( | 562 } |
558 start * elementSizeInBytes + this.offsetInBytes, | 563 _ByteBuffer buffer = this.buffer; |
559 count * elementSizeInBytes, | 564 _ByteBuffer fromBuffer = from.buffer; |
560 from.buffer, | 565 if (buffer._typedData._setRange( |
561 skipCount * elementSizeInBytes + from.offsetInBytes)) { | 566 start * elementSizeInBytes + this.offsetInBytes, |
567 count * elementSizeInBytes, | |
568 fromBuffer._typedData, | |
569 skipCount * elementSizeInBytes + from.offsetInBytes)) { | |
562 return; | 570 return; |
563 } | 571 } |
564 } else if (from.buffer == this.buffer) { | 572 } else if (from.buffer == this.buffer) { |
565 // Different element sizes, but same buffer means that we need | 573 // Different element sizes, but same buffer means that we need |
566 // an intermediate structure. | 574 // an intermediate structure. |
567 // TODO(srdjan): Optimize to skip copying if the range does not overlap. | 575 // TODO(srdjan): Optimize to skip copying if the range does not overlap. |
568 final temp_buffer = new List(count); | 576 final temp_buffer = new List(count); |
569 for (int i = 0; i < count; i++) { | 577 for (int i = 0; i < count; i++) { |
570 temp_buffer[i] = from[skipCount + i]; | 578 temp_buffer[i] = from[skipCount + i]; |
571 } | 579 } |
(...skipping 28 matching lines...) Expand all Loading... | |
600 | 608 |
601 // Returns true if operation succeeds. | 609 // Returns true if operation succeeds. |
602 // Returns false if 'from' and 'this' do not have the same element types. | 610 // Returns false if 'from' and 'this' do not have the same element types. |
603 // The copy occurs using a memory copy (no clamping, conversion, etc). | 611 // The copy occurs using a memory copy (no clamping, conversion, etc). |
604 bool _setRange(int startInBytes, int lengthInBytes, | 612 bool _setRange(int startInBytes, int lengthInBytes, |
605 _TypedListBase from, int startFromInBytes) | 613 _TypedListBase from, int startFromInBytes) |
606 native "TypedData_setRange"; | 614 native "TypedData_setRange"; |
607 } | 615 } |
608 | 616 |
609 | 617 |
610 abstract class _TypedList extends _TypedListBase implements ByteBuffer { | 618 abstract class _TypedList extends _TypedListBase { |
619 // The [buffer] getter should return the same value each time. | |
620 // Store it here the first time it is created. | |
621 // We don't want to store it on the object, since not all typed lists | |
622 // have a buffer extracted. | |
Søren Gjesse
2014/01/14 12:00:17
Is this just to save an instance variable? You are
Lasse Reichstein Nielsen
2014/01/14 12:19:17
Yes.
| |
623 static var _buffers = new Expando(); | |
624 | |
611 // Default method implementing parts of the TypedData interface. | 625 // Default method implementing parts of the TypedData interface. |
612 int get offsetInBytes { | 626 int get offsetInBytes { |
613 return 0; | 627 return 0; |
614 } | 628 } |
615 | 629 |
616 int get lengthInBytes { | 630 int get lengthInBytes { |
617 return length * elementSizeInBytes; | 631 return length * elementSizeInBytes; |
618 } | 632 } |
619 | 633 |
620 ByteBuffer get buffer { | 634 ByteBuffer get buffer { |
621 return this; | 635 _ByteBuffer buffer = _buffers[this]; |
636 if (buffer == null) { | |
637 buffer = new _ByteBuffer(this); | |
638 _buffers[this] = buffer; | |
639 } | |
640 return buffer; | |
622 } | 641 } |
623 | 642 |
624 // Methods implementing the collection interface. | 643 // Methods implementing the collection interface. |
625 | 644 |
626 int get length native "TypedData_length"; | 645 int get length native "TypedData_length"; |
627 | 646 |
628 // Internal utility methods. | 647 // Internal utility methods. |
629 | 648 |
630 int _getInt8(int offsetInBytes) native "TypedData_GetInt8"; | 649 int _getInt8(int offsetInBytes) native "TypedData_GetInt8"; |
631 void _setInt8(int offsetInBytes, int value) native "TypedData_SetInt8"; | 650 void _setInt8(int offsetInBytes, int value) native "TypedData_SetInt8"; |
(...skipping 1695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2327 _position = _length; | 2346 _position = _length; |
2328 _current = null; | 2347 _current = null; |
2329 return false; | 2348 return false; |
2330 } | 2349 } |
2331 | 2350 |
2332 E get current => _current; | 2351 E get current => _current; |
2333 } | 2352 } |
2334 | 2353 |
2335 | 2354 |
2336 class _TypedListView extends _TypedListBase implements TypedData { | 2355 class _TypedListView extends _TypedListBase implements TypedData { |
2356 final TypedData _typedData; | |
2357 final int offsetInBytes; | |
2358 final int length; | |
2359 | |
2337 _TypedListView(ByteBuffer _buffer, int _offset, int _length) | 2360 _TypedListView(ByteBuffer _buffer, int _offset, int _length) |
2338 : _typedData = _buffer, // This assignment is type safe. | 2361 : _typedData = (_buffer as _ByteBuffer)._typedData, |
2339 offsetInBytes = _offset, | 2362 offsetInBytes = _offset, |
2340 length = _length { | 2363 length = _length; |
2341 } | |
2342 | 2364 |
2343 // Method(s) implementing the TypedData interface. | 2365 // Method(s) implementing the TypedData interface. |
2344 | 2366 |
2345 int get lengthInBytes { | 2367 int get lengthInBytes { |
2346 return length * elementSizeInBytes; | 2368 return length * elementSizeInBytes; |
2347 } | 2369 } |
2348 | 2370 |
2349 ByteBuffer get buffer { | 2371 ByteBuffer get buffer { |
2350 return _typedData.buffer; | 2372 return _typedData.buffer; |
2351 } | 2373 } |
2352 | |
2353 final TypedData _typedData; | |
2354 final int offsetInBytes; | |
2355 final int length; | |
2356 } | 2374 } |
2357 | 2375 |
2358 | 2376 |
2359 class _Int8ArrayView extends _TypedListView implements Int8List { | 2377 class _Int8ArrayView extends _TypedListView implements Int8List { |
2360 // Constructor. | 2378 // Constructor. |
2361 _Int8ArrayView(ByteBuffer buffer, [int _offsetInBytes = 0, int _length]) | 2379 _Int8ArrayView(ByteBuffer buffer, [int _offsetInBytes = 0, int _length]) |
2362 : super(buffer, _offsetInBytes, | 2380 : super(buffer, _offsetInBytes, |
2363 _defaultIfNull(_length, | 2381 _defaultIfNull(_length, |
2364 ((buffer.lengthInBytes - _offsetInBytes) ~/ | 2382 ((buffer.lengthInBytes - _offsetInBytes) ~/ |
2365 Int8List.BYTES_PER_ELEMENT))) { | 2383 Int8List.BYTES_PER_ELEMENT))) { |
(...skipping 660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3026 | 3044 |
3027 // Internal utility methods. | 3045 // Internal utility methods. |
3028 | 3046 |
3029 Int32x4List _createList(int length) { | 3047 Int32x4List _createList(int length) { |
3030 return new Int32x4List(length); | 3048 return new Int32x4List(length); |
3031 } | 3049 } |
3032 } | 3050 } |
3033 | 3051 |
3034 | 3052 |
3035 class _ByteDataView implements ByteData { | 3053 class _ByteDataView implements ByteData { |
3036 _ByteDataView(ByteBuffer _buffer, int _offsetInBytes, int _lengthInBytes) | 3054 final TypedData _typedData; |
3037 : _typedData = _buffer, // _buffer is guaranteed to be a TypedData here. | 3055 final int _offset; |
3056 final int length; | |
3057 | |
3058 _ByteDataView(TypedData typedData, int _offsetInBytes, int _lengthInBytes) | |
3059 : _typedData = typedData, | |
3038 _offset = _offsetInBytes, | 3060 _offset = _offsetInBytes, |
3039 length = _lengthInBytes { | 3061 length = _lengthInBytes { |
3040 _rangeCheck(_buffer.lengthInBytes, _offset, length); | 3062 _rangeCheck(typedData.lengthInBytes, _offset, length); |
3041 } | 3063 } |
3042 | 3064 |
3043 | |
3044 // Method(s) implementing TypedData interface. | 3065 // Method(s) implementing TypedData interface. |
3045 | 3066 |
3046 ByteBuffer get buffer { | 3067 ByteBuffer get buffer { |
3047 return _typedData.buffer; | 3068 return _typedData.buffer; |
3048 } | 3069 } |
3049 | 3070 |
3050 int get lengthInBytes { | 3071 int get lengthInBytes { |
3051 return length; | 3072 return length; |
3052 } | 3073 } |
3053 | 3074 |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3304 static int _toEndianUint32(int host_value, bool little_endian) | 3325 static int _toEndianUint32(int host_value, bool little_endian) |
3305 native "ByteData_ToEndianUint32"; | 3326 native "ByteData_ToEndianUint32"; |
3306 static int _toEndianInt64(int host_value, bool little_endian) | 3327 static int _toEndianInt64(int host_value, bool little_endian) |
3307 native "ByteData_ToEndianInt64"; | 3328 native "ByteData_ToEndianInt64"; |
3308 static int _toEndianUint64(int host_value, bool little_endian) | 3329 static int _toEndianUint64(int host_value, bool little_endian) |
3309 native "ByteData_ToEndianUint64"; | 3330 native "ByteData_ToEndianUint64"; |
3310 static double _toEndianFloat32(double host_value, bool little_endian) | 3331 static double _toEndianFloat32(double host_value, bool little_endian) |
3311 native "ByteData_ToEndianFloat32"; | 3332 native "ByteData_ToEndianFloat32"; |
3312 static double _toEndianFloat64(double host_value, bool little_endian) | 3333 static double _toEndianFloat64(double host_value, bool little_endian) |
3313 native "ByteData_ToEndianFloat64"; | 3334 native "ByteData_ToEndianFloat64"; |
3314 | |
3315 | |
3316 final TypedData _typedData; | |
3317 final int _offset; | |
3318 final int length; | |
3319 } | 3335 } |
3320 | 3336 |
3321 | 3337 |
3322 // Top level utility methods. | 3338 // Top level utility methods. |
3323 int _toInt(int value, int mask) { | 3339 int _toInt(int value, int mask) { |
3324 value &= mask; | 3340 value &= mask; |
3325 if (value > (mask >> 1)) value -= mask + 1; | 3341 if (value > (mask >> 1)) value -= mask + 1; |
3326 return value; | 3342 return value; |
3327 } | 3343 } |
3328 | 3344 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3400 return value; | 3416 return value; |
3401 } | 3417 } |
3402 return object; | 3418 return object; |
3403 } | 3419 } |
3404 | 3420 |
3405 | 3421 |
3406 void _throwRangeError(int index, int length) { | 3422 void _throwRangeError(int index, int length) { |
3407 String message = "$index must be in the range [0..$length)"; | 3423 String message = "$index must be in the range [0..$length)"; |
3408 throw new RangeError(message); | 3424 throw new RangeError(message); |
3409 } | 3425 } |
3426 | |
3427 /** | |
3428 * Internal implementation of [ByteBuffer]. | |
3429 */ | |
3430 class _ByteBuffer implements ByteBuffer { | |
3431 final _TypedList _typedData; | |
3432 | |
3433 _ByteBuffer(this._typedData); | |
3434 | |
3435 int get lengthInBytes => _typedData.lengthInBytes; | |
3436 | |
3437 int get hashCode => _typedData.hashCode; | |
3438 bool operator==(Object other) => | |
3439 other is _ByteBuffer && _typedData == other._typedData; | |
3440 } | |
OLD | NEW |