Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit aa0f644

Browse files
DropsOfSerenitycaitp
authored andcommitted
fix(angular.copy): support copying %TypedArray%s
angular.copy can now copy a %TypedArray%s. Limitations: It is not possible to update the length of a %TypedArray%, so currently an error is thrown if the destination object is a %TypedArray%. However, it is possible to change values in a typed array, so in the future this may only be a problem if the length of the source and destination is different. Closes #10745
1 parent e61eae1 commit aa0f644

File tree

3 files changed

+199
-0
lines changed

3 files changed

+199
-0
lines changed

docs/content/error/ng/cpta.ngdoc

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
@ngdoc error
2+
@name ng:cpta
3+
@fullName Copying TypedArray
4+
@description
5+
6+
Copying TypedArray's with a destination is not supported because TypedArray
7+
objects can not be mutated, they are fixed length.

src/Angular.js

+12
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,12 @@ function isPromiseLike(obj) {
584584
}
585585

586586

587+
var TYPED_ARRAY_REGEXP = /^\[object (Uint8(Clamped)?)|(Uint16)|(Uint32)|(Int8)|(Int16)|(Int32)|(Float(32)|(64))Array\]$/;
588+
function isTypedArray(value) {
589+
return TYPED_ARRAY_REGEXP.test(toString.call(value));
590+
}
591+
592+
587593
var trim = function(value) {
588594
return isString(value) ? value.trim() : value;
589595
};
@@ -705,12 +711,18 @@ function copy(source, destination, stackSource, stackDest) {
705711
throw ngMinErr('cpws',
706712
"Can't copy! Making copies of Window or Scope instances is not supported.");
707713
}
714+
if (isTypedArray(destination)) {
715+
throw ngMinErr('cpta',
716+
"Can't copy! TypedArray destination cannot be mutated.");
717+
}
708718

709719
if (!destination) {
710720
destination = source;
711721
if (source) {
712722
if (isArray(source)) {
713723
destination = copy(source, [], stackSource, stackDest);
724+
} else if (isTypedArray(source)) {
725+
destination = new source.constructor(source);
714726
} else if (isDate(source)) {
715727
destination = new Date(source.getTime());
716728
} else if (isRegExp(source)) {

test/AngularSpec.js

+180
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,186 @@ describe('angular', function() {
7878
expect(copy(objWithRegExp.re) === objWithRegExp.re).toBeFalsy();
7979
});
8080

81+
it("should copy a Uint8Array with no destination", function() {
82+
if (typeof Uint8Array !== 'undefined') {
83+
var src = new Uint8Array(2);
84+
src[1] = 1;
85+
var dst = copy(src);
86+
expect(copy(src) instanceof Uint8Array).toBeTruthy();
87+
expect(dst).toEqual(src);
88+
expect(dst).not.toBe(src);
89+
}
90+
});
91+
92+
it("should copy a Uint8ClampedArray with no destination", function() {
93+
if (typeof Uint8ClampedArray !== 'undefined') {
94+
var src = new Uint8ClampedArray(2);
95+
src[1] = 1;
96+
var dst = copy(src);
97+
expect(copy(src) instanceof Uint8ClampedArray).toBeTruthy();
98+
expect(dst).toEqual(src);
99+
expect(dst).not.toBe(src);
100+
}
101+
});
102+
103+
it("should copy a Uint16Array with no destination", function() {
104+
if (typeof Uint16Array !== 'undefined') {
105+
var src = new Uint16Array(2);
106+
src[1] = 1;
107+
var dst = copy(src);
108+
expect(copy(src) instanceof Uint16Array).toBeTruthy();
109+
expect(dst).toEqual(src);
110+
expect(dst).not.toBe(src);
111+
}
112+
});
113+
114+
it("should copy a Uint32Array with no destination", function() {
115+
if (typeof Uint32Array !== 'undefined') {
116+
var src = new Uint32Array(2);
117+
src[1] = 1;
118+
var dst = copy(src);
119+
expect(copy(src) instanceof Uint32Array).toBeTruthy();
120+
expect(dst).toEqual(src);
121+
expect(dst).not.toBe(src);
122+
}
123+
});
124+
125+
it("should copy a Int8Array with no destination", function() {
126+
if (typeof Int8Array !== 'undefined') {
127+
var src = new Int8Array(2);
128+
src[1] = 1;
129+
var dst = copy(src);
130+
expect(copy(src) instanceof Int8Array).toBeTruthy();
131+
expect(dst).toEqual(src);
132+
expect(dst).not.toBe(src);
133+
}
134+
});
135+
136+
it("should copy a Int16Array with no destination", function() {
137+
if (typeof Int16Array !== 'undefined') {
138+
var src = new Int16Array(2);
139+
src[1] = 1;
140+
var dst = copy(src);
141+
expect(copy(src) instanceof Int16Array).toBeTruthy();
142+
expect(dst).toEqual(src);
143+
expect(dst).not.toBe(src);
144+
}
145+
});
146+
147+
it("should copy a Int32Array with no destination", function() {
148+
if (typeof Int32Array !== 'undefined') {
149+
var src = new Int32Array(2);
150+
src[1] = 1;
151+
var dst = copy(src);
152+
expect(copy(src) instanceof Int32Array).toBeTruthy();
153+
expect(dst).toEqual(src);
154+
expect(dst).not.toBe(src);
155+
}
156+
});
157+
158+
it("should copy a Float32Array with no destination", function() {
159+
if (typeof Float32Array !== 'undefined') {
160+
var src = new Float32Array(2);
161+
src[1] = 1;
162+
var dst = copy(src);
163+
expect(copy(src) instanceof Float32Array).toBeTruthy();
164+
expect(dst).toEqual(src);
165+
expect(dst).not.toBe(src);
166+
}
167+
});
168+
169+
it("should copy a Float64Array with no destination", function() {
170+
if (typeof Float64Array !== 'undefined') {
171+
var src = new Float64Array(2);
172+
src[1] = 1;
173+
var dst = copy(src);
174+
expect(copy(src) instanceof Float64Array).toBeTruthy();
175+
expect(dst).toEqual(src);
176+
expect(dst).not.toBe(src);
177+
}
178+
});
179+
180+
it("should throw an exception if a Uint8Array is the destination", function() {
181+
if (typeof Uint8Array !== 'undefined') {
182+
var src = new Uint8Array();
183+
var dst = new Uint8Array(5);
184+
expect(function() { copy(src, dst); })
185+
.toThrowMinErr("ng", "cpta", "Can't copy! TypedArray destination cannot be mutated.");
186+
}
187+
});
188+
189+
it("should throw an exception if a Uint8ClampedArray is the destination", function() {
190+
if (typeof Uint8ClampedArray !== 'undefined') {
191+
var src = new Uint8ClampedArray();
192+
var dst = new Uint8ClampedArray(5);
193+
expect(function() { copy(src, dst); })
194+
.toThrowMinErr("ng", "cpta", "Can't copy! TypedArray destination cannot be mutated.");
195+
}
196+
});
197+
198+
it("should throw an exception if a Uint16Array is the destination", function() {
199+
if (typeof Uint16Array !== 'undefined') {
200+
var src = new Uint16Array();
201+
var dst = new Uint16Array(5);
202+
expect(function() { copy(src, dst); })
203+
.toThrowMinErr("ng", "cpta", "Can't copy! TypedArray destination cannot be mutated.");
204+
}
205+
});
206+
207+
it("should throw an exception if a Uint32Array is the destination", function() {
208+
if (typeof Uint32Array !== 'undefined') {
209+
var src = new Uint32Array();
210+
var dst = new Uint32Array(5);
211+
expect(function() { copy(src, dst); })
212+
.toThrowMinErr("ng", "cpta", "Can't copy! TypedArray destination cannot be mutated.");
213+
}
214+
});
215+
216+
it("should throw an exception if a Int8Array is the destination", function() {
217+
if (typeof Int8Array !== 'undefined') {
218+
var src = new Int8Array();
219+
var dst = new Int8Array(5);
220+
expect(function() { copy(src, dst); })
221+
.toThrowMinErr("ng", "cpta", "Can't copy! TypedArray destination cannot be mutated.");
222+
}
223+
});
224+
225+
it("should throw an exception if a Int16Array is the destination", function() {
226+
if (typeof Int16Array !== 'undefined') {
227+
var src = new Int16Array();
228+
var dst = new Int16Array(5);
229+
expect(function() { copy(src, dst); })
230+
.toThrowMinErr("ng", "cpta", "Can't copy! TypedArray destination cannot be mutated.");
231+
}
232+
});
233+
234+
it("should throw an exception if a Int32Array is the destination", function() {
235+
if (typeof Int32Array !== 'undefined') {
236+
var src = new Int32Array();
237+
var dst = new Int32Array(5);
238+
expect(function() { copy(src, dst); })
239+
.toThrowMinErr("ng", "cpta", "Can't copy! TypedArray destination cannot be mutated.");
240+
}
241+
});
242+
243+
it("should throw an exception if a Float32Array is the destination", function() {
244+
if (typeof Float32Array !== 'undefined') {
245+
var src = new Float32Array();
246+
var dst = new Float32Array(5);
247+
expect(function() { copy(src, dst); })
248+
.toThrowMinErr("ng", "cpta", "Can't copy! TypedArray destination cannot be mutated.");
249+
}
250+
});
251+
252+
it("should throw an exception if a Float64Array is the destination", function() {
253+
if (typeof Float64Array !== 'undefined') {
254+
var src = new Float64Array();
255+
var dst = new Float64Array(5);
256+
expect(function() { copy(src, dst); })
257+
.toThrowMinErr("ng", "cpta", "Can't copy! TypedArray destination cannot be mutated.");
258+
}
259+
});
260+
81261
it("should deeply copy an array into an existing array", function() {
82262
var src = [1, {name:"value"}];
83263
var dst = [{key:"v"}];

0 commit comments

Comments
 (0)