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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 result[i] = elements[i]; | 55 result[i] = elements[i]; |
56 } | 56 } |
57 return result; | 57 return result; |
58 } | 58 } |
59 | 59 |
60 /* patch */ factory Uint8ClampedList.view(ByteBuffer buffer, | 60 /* patch */ factory Uint8ClampedList.view(ByteBuffer buffer, |
61 [int offsetInBytes = 0, | 61 [int offsetInBytes = 0, |
62 int length]) { | 62 int length]) { |
63 return new _Uint8ClampedArrayView(buffer, offsetInBytes, length); | 63 return new _Uint8ClampedArrayView(buffer, offsetInBytes, length); |
64 } | 64 } |
| 65 |
| 66 bool _isClamped() { return true; } |
65 } | 67 } |
66 | 68 |
67 | 69 |
68 patch class Int16List { | 70 patch class Int16List { |
69 /* patch */ factory Int16List(int length) { | 71 /* patch */ factory Int16List(int length) { |
70 return new _Int16Array(length); | 72 return new _Int16Array(length); |
71 } | 73 } |
72 | 74 |
73 /* patch */ factory Int16List.fromList(List<int> elements) { | 75 /* patch */ factory Int16List.fromList(List<int> elements) { |
74 var result = new _Int16Array(elements.length); | 76 var result = new _Int16Array(elements.length); |
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 _rangeCheck(this.length, start, length); | 518 _rangeCheck(this.length, start, length); |
517 List result = _createList(length); | 519 List result = _createList(length); |
518 result.setRange(0, length, this, start); | 520 result.setRange(0, length, this, start); |
519 return result; | 521 return result; |
520 } | 522 } |
521 | 523 |
522 Iterable getRange(int start, [int end]) { | 524 Iterable getRange(int start, [int end]) { |
523 return IterableMixinWorkaround.getRangeList(this, start, end); | 525 return IterableMixinWorkaround.getRangeList(this, start, end); |
524 } | 526 } |
525 | 527 |
526 void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) { | 528 bool _isClamped() { return false; } |
527 if (!_setRange(start, end - start, iterable, skipCount)) { | 529 |
528 IterableMixinWorkaround.setRangeList(this, start, | 530 void setRange(int start, int end, Iterable from, [int skipCount = 0]) { |
529 end, iterable, skipCount); | 531 // Check ranges. |
| 532 if ((start < 0) || (start > length)) { |
| 533 _throwRangeError(start, length + 1); |
530 } | 534 } |
| 535 if ((end < 0) || (end > length)) { |
| 536 _throwRangeError(end, length + 1); |
| 537 } |
| 538 if (start > end) { |
| 539 _throwRangeError(start, end + 1); |
| 540 } |
| 541 if (skipCount < 0) { |
| 542 throw new ArgumentError(skipCount); |
| 543 } |
| 544 |
| 545 final count = end - start; |
| 546 if ((from.length - skipCount) < count) { |
| 547 throw new StateError("Not enough elements"); |
| 548 } |
| 549 |
| 550 if (from is _TypedListBase) { |
| 551 final needsClamping = |
| 552 this._isClamped() && (this._isClamped() != from._isClamped()); |
| 553 if (this.elementSizeInBytes == from.elementSizeInBytes) { |
| 554 if (needsClamping) { |
| 555 Lists.copy(from, skipCount, this, start, count); |
| 556 return; |
| 557 } else if (this.buffer._setRange( |
| 558 start * elementSizeInBytes + this.offsetInBytes, |
| 559 count * elementSizeInBytes, |
| 560 from.buffer, |
| 561 skipCount * elementSizeInBytes + from.offsetInBytes)) { |
| 562 return; |
| 563 } |
| 564 } else if (from.buffer == this.buffer) { |
| 565 // Different element sizes, but same buffer means that we need |
| 566 // an intermediate structure. |
| 567 // TODO(srdjan): Optimize to skip copying if the range does not overlap. |
| 568 final temp_buffer = new List(count); |
| 569 for (int i = 0; i < count; i++) { |
| 570 temp_buffer[i] = from[skipCount + i]; |
| 571 } |
| 572 for (int i = start; i < end; i++) { |
| 573 this[i] = temp_buffer[i - start]; |
| 574 } |
| 575 return; |
| 576 } |
| 577 } |
| 578 IterableMixinWorkaround.setRangeList(this, start, |
| 579 end, from, skipCount); |
531 } | 580 } |
532 | 581 |
533 void setAll(int index, Iterable iterable) { | 582 void setAll(int index, Iterable iterable) { |
534 IterableMixinWorkaround.setAllList(this, index, iterable); | 583 final end = iterable.length + index; |
| 584 setRange(index, end, iterable); |
535 } | 585 } |
536 | 586 |
537 void fillRange(int start, int end, [fillValue]) { | 587 void fillRange(int start, int end, [fillValue]) { |
538 IterableMixinWorkaround.fillRangeList(this, start, end, fillValue); | 588 IterableMixinWorkaround.fillRangeList(this, start, end, fillValue); |
539 } | 589 } |
540 | 590 |
541 | 591 |
542 // Method(s) implementing Object interface. | 592 // Method(s) implementing Object interface. |
543 | 593 |
544 String toString() { | 594 String toString() { |
545 return IterableMixinWorkaround.toStringIterable(this, '[', ']'); | 595 return IterableMixinWorkaround.toStringIterable(this, '[', ']'); |
546 } | 596 } |
547 | 597 |
548 | 598 |
549 // Internal utility methods. | 599 // Internal utility methods. |
550 | 600 |
551 bool _setRange(int start, int length, Iterable from, int startFrom) | 601 // Returns true if operation succeeds. |
| 602 // 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). |
| 604 bool _setRange(int startInBytes, int lengthInBytes, |
| 605 _TypedListBase from, int startFromInBytes) |
552 native "TypedData_setRange"; | 606 native "TypedData_setRange"; |
553 } | 607 } |
554 | 608 |
555 | 609 |
556 abstract class _TypedList extends _TypedListBase implements ByteBuffer { | 610 abstract class _TypedList extends _TypedListBase implements ByteBuffer { |
557 // Default method implementing parts of the TypedData interface. | 611 // Default method implementing parts of the TypedData interface. |
558 int get offsetInBytes { | 612 int get offsetInBytes { |
559 return 0; | 613 return 0; |
560 } | 614 } |
561 | 615 |
562 int get lengthInBytes { | 616 int get lengthInBytes { |
563 return length * elementSizeInBytes; | 617 return length * elementSizeInBytes; |
564 } | 618 } |
565 | 619 |
566 ByteBuffer get buffer { | 620 ByteBuffer get buffer { |
567 return this; | 621 return this; |
568 } | 622 } |
569 | 623 |
570 | |
571 // Methods implementing the collection interface. | 624 // Methods implementing the collection interface. |
572 | 625 |
573 int get length native "TypedData_length"; | 626 int get length native "TypedData_length"; |
574 | 627 |
575 | |
576 // Internal utility methods. | 628 // Internal utility methods. |
577 | 629 |
578 int _getInt8(int offsetInBytes) native "TypedData_GetInt8"; | 630 int _getInt8(int offsetInBytes) native "TypedData_GetInt8"; |
579 void _setInt8(int offsetInBytes, int value) native "TypedData_SetInt8"; | 631 void _setInt8(int offsetInBytes, int value) native "TypedData_SetInt8"; |
580 | 632 |
581 int _getUint8(int offsetInBytes) native "TypedData_GetUint8"; | 633 int _getUint8(int offsetInBytes) native "TypedData_GetUint8"; |
582 void _setUint8(int offsetInBytes, int value) native "TypedData_SetUint8"; | 634 void _setUint8(int offsetInBytes, int value) native "TypedData_SetUint8"; |
583 | 635 |
584 int _getInt16(int offsetInBytes) native "TypedData_GetInt16"; | 636 int _getInt16(int offsetInBytes) native "TypedData_GetInt16"; |
585 void _setInt16(int offsetInBytes, int value) native "TypedData_SetInt16"; | 637 void _setInt16(int offsetInBytes, int value) native "TypedData_SetInt16"; |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
731 } | 783 } |
732 | 784 |
733 factory _Uint8ClampedArray.view(ByteBuffer buffer, | 785 factory _Uint8ClampedArray.view(ByteBuffer buffer, |
734 [int offsetInBytes = 0, int length]) { | 786 [int offsetInBytes = 0, int length]) { |
735 if (length == null) { | 787 if (length == null) { |
736 length = buffer.lengthInBytes - offsetInBytes; | 788 length = buffer.lengthInBytes - offsetInBytes; |
737 } | 789 } |
738 return new _Uint8ClampedArrayView(buffer, offsetInBytes, length); | 790 return new _Uint8ClampedArrayView(buffer, offsetInBytes, length); |
739 } | 791 } |
740 | 792 |
| 793 bool _isClamped() { return true; } |
741 | 794 |
742 // Methods implementing List interface. | 795 // Methods implementing List interface. |
743 | 796 |
744 int operator[](int index) { | 797 int operator[](int index) { |
745 if (index < 0 || index >= length) { | 798 if (index < 0 || index >= length) { |
746 _throwRangeError(index, length); | 799 _throwRangeError(index, length); |
747 } | 800 } |
748 return _getUint8(index); | 801 return _getUint8(index); |
749 } | 802 } |
750 | 803 |
(...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1496 } | 1549 } |
1497 | 1550 |
1498 | 1551 |
1499 class _ExternalUint8ClampedArray extends _TypedList implements Uint8ClampedList
{ | 1552 class _ExternalUint8ClampedArray extends _TypedList implements Uint8ClampedList
{ |
1500 // Factory constructors. | 1553 // Factory constructors. |
1501 | 1554 |
1502 factory _ExternalUint8ClampedArray(int length) { | 1555 factory _ExternalUint8ClampedArray(int length) { |
1503 return _new(length); | 1556 return _new(length); |
1504 } | 1557 } |
1505 | 1558 |
| 1559 bool _isClamped() { return true; } |
1506 | 1560 |
1507 // Method(s) implementing the List interface. | 1561 // Method(s) implementing the List interface. |
1508 | 1562 |
1509 int operator[](int index) { | 1563 int operator[](int index) { |
1510 if (index < 0 || index >= length) { | 1564 if (index < 0 || index >= length) { |
1511 _throwRangeError(index, length); | 1565 _throwRangeError(index, length); |
1512 } | 1566 } |
1513 return _getUint8(index); | 1567 return _getUint8(index); |
1514 } | 1568 } |
1515 | 1569 |
(...skipping 763 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2279 } | 2333 } |
2280 | 2334 |
2281 | 2335 |
2282 class _TypedListView extends _TypedListBase implements TypedData { | 2336 class _TypedListView extends _TypedListBase implements TypedData { |
2283 _TypedListView(ByteBuffer _buffer, int _offset, int _length) | 2337 _TypedListView(ByteBuffer _buffer, int _offset, int _length) |
2284 : _typedData = _buffer, // This assignment is type safe. | 2338 : _typedData = _buffer, // This assignment is type safe. |
2285 offsetInBytes = _offset, | 2339 offsetInBytes = _offset, |
2286 length = _length { | 2340 length = _length { |
2287 } | 2341 } |
2288 | 2342 |
2289 | |
2290 // Method(s) implementing the TypedData interface. | 2343 // Method(s) implementing the TypedData interface. |
2291 | 2344 |
2292 int get lengthInBytes { | 2345 int get lengthInBytes { |
2293 return length * elementSizeInBytes; | 2346 return length * elementSizeInBytes; |
2294 } | 2347 } |
2295 | 2348 |
2296 ByteBuffer get buffer { | 2349 ByteBuffer get buffer { |
2297 return _typedData.buffer; | 2350 return _typedData.buffer; |
2298 } | 2351 } |
2299 | 2352 |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2412 : super(buffer, _offsetInBytes, | 2465 : super(buffer, _offsetInBytes, |
2413 _defaultIfNull(_length, | 2466 _defaultIfNull(_length, |
2414 ((buffer.lengthInBytes - _offsetInBytes) ~/ | 2467 ((buffer.lengthInBytes - _offsetInBytes) ~/ |
2415 Uint8List.BYTES_PER_ELEMENT))) { | 2468 Uint8List.BYTES_PER_ELEMENT))) { |
2416 _rangeCheck(buffer.lengthInBytes, | 2469 _rangeCheck(buffer.lengthInBytes, |
2417 offsetInBytes, | 2470 offsetInBytes, |
2418 length * Uint8List.BYTES_PER_ELEMENT); | 2471 length * Uint8List.BYTES_PER_ELEMENT); |
2419 } | 2472 } |
2420 | 2473 |
2421 | 2474 |
| 2475 bool _isClamped() { return true; } |
| 2476 |
2422 // Method(s) implementing List interface. | 2477 // Method(s) implementing List interface. |
2423 | 2478 |
2424 int operator[](int index) { | 2479 int operator[](int index) { |
2425 if (index < 0 || index >= length) { | 2480 if (index < 0 || index >= length) { |
2426 _throwRangeError(index, length); | 2481 _throwRangeError(index, length); |
2427 } | 2482 } |
2428 return _typedData._getUint8(offsetInBytes + | 2483 return _typedData._getUint8(offsetInBytes + |
2429 (index * Uint8List.BYTES_PER_ELEMENT)); | 2484 (index * Uint8List.BYTES_PER_ELEMENT)); |
2430 } | 2485 } |
2431 | 2486 |
(...skipping 913 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3345 return value; | 3400 return value; |
3346 } | 3401 } |
3347 return object; | 3402 return object; |
3348 } | 3403 } |
3349 | 3404 |
3350 | 3405 |
3351 void _throwRangeError(int index, int length) { | 3406 void _throwRangeError(int index, int length) { |
3352 String message = "$index must be in the range [0..$length)"; | 3407 String message = "$index must be in the range [0..$length)"; |
3353 throw new RangeError(message); | 3408 throw new RangeError(message); |
3354 } | 3409 } |
OLD | NEW |