Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(201)

Side by Side Diff: pkg/collection_helpers/test/typed_buffers_test.dart

Issue 26695002: Growable typed data buffers. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Don't expect failure on FF/Win since it's 32-bit. Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/collection_helpers/pubspec.yaml ('k') | pkg/pkg.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 // Tests typed-data buffer classes.
6
7 import "package:collection_helpers/all.dart";
8 import "package:unittest/unittest.dart";
9 import "dart:typed_data";
10
11 main() {
12 testUint(8, (l) => new Uint8Buffer(l));
13 testInt(8, (l) => new Int8Buffer(l));
14 test("Uint8ClampedBuffer", () {
15 testIntBuffer(8, 0, 255, (l) => new Uint8ClampedBuffer(l), clampUint8);
16 });
17 testUint(16, (l) => new Uint16Buffer(l));
18 testInt(16, (l) => new Int16Buffer(l));
19 testUint(32, (l) => new Uint32Buffer(l)); /// 01: ok
20 testInt(32, (l) => new Int32Buffer(l));
21 testUint(64, (l) => new Uint64Buffer(l)); /// 01: continued
22 testInt(64, (l) => new Int64Buffer(l)); /// 01: continued
23
24 testInt32x4Buffer(intSamples);
25
26 List roundedFloatSamples = floatSamples.map(roundToFloat).toList();
27 testFloatBuffer(32, roundedFloatSamples,
28 () => new Float32Buffer(),
29 roundToFloat);
30 testFloatBuffer(64, doubleSamples, () => new Float64Buffer(), (x) => x);
31
32 testFloat32x4Buffer(roundedFloatSamples);
33 }
34
35 double roundToFloat(double value) {
36 return (new Float32List(1)..[0] = value)[0];
37 }
38
39 typedef int Rounder(int value);
40
41 Rounder roundUint(bits) {
42 int halfbits = (1 << (bits ~/ 2)) - 1;
43 int mask = halfbits | (halfbits << (bits ~/ 2));
44 return (int x) => x & mask;
45 }
46
47 Rounder roundInt(bits) {
48 int highBit = 1 << (bits - 1);
49 int mask = highBit - 1;
50 return (int x) => (x & mask) - (x & highBit);
51 }
52
53 int clampUint8(x) => x < 0 ? 0 : x > 255 ? 255 : x;
54
55 void testUint(int bits, var buffer) {
56 int min = 0;
57 Function round = roundUint(bits);
58 int max = round(-1);
59 test("Uint${bits}Buffer", () {
60 testIntBuffer(bits, min, max, buffer, round);
61 });
62 }
63
64 void testInt(int bits, var buffer) {
65 int min = -(1 << (bits - 1));
66 int max = -(min + 1);
67 test("Int${bits}Buffer", () {
68 testIntBuffer(bits, min, max, buffer, roundInt(bits));
69 });
70 }
71
72 const List<int> intSamples = const [
73 0x10000000000000001,
74 0x10000000000000000, // 2^64
75 0x0ffffffffffffffff,
76 0xaaaaaaaaaaaaaaaa,
77 0x8000000000000001,
78 0x8000000000000000, // 2^63
79 0x7fffffffffffffff,
80 0x5555555555555555,
81 0x100000001,
82 0x100000000, // 2^32
83 0x0ffffffff,
84 0xaaaaaaaa,
85 0x80000001,
86 0x80000000, // 2^31
87 0x7fffffff,
88 0x55555555,
89 0x10001,
90 0x10000, // 2^16
91 0x0ffff,
92 0xaaaa,
93 0x8001,
94 0x8000, // 2^15
95 0x7fff,
96 0x5555,
97 0x101,
98 0x100, // 2^8
99 0x0ff,
100 0xaa,
101 0x81,
102 0x80, // 2^7
103 0x7f,
104 0x55,
105 0x02,
106 0x01,
107 0x00
108 ];
109
110 // Takes bit-size, min value, max value, function to create a buffer, and
111 // the rounding that is applied when storing values outside the valid range
112 // into the buffer.
113 void testIntBuffer(int bits, int min, int max,
114 create(int length),
115 int round(int)) {
116 assert(round(min) == min);
117 assert(round(max) == max);
118 // All int buffers default to the value 0.
119 var buffer = create(0);
120 List<int> list = buffer; // Check the type.
121 expect(buffer.length, equals(0));
122 var bytes = bits ~/ 8;
123
124 expect(buffer.elementSizeInBytes, equals(bytes));
125 expect(buffer.lengthInBytes, equals(0));
126 expect(buffer.offsetInBytes, equals(0));
127
128 buffer.add(min);
129 expect(buffer.length, equals(1));
130 expect(buffer[0], equals(min));
131
132 expect(buffer.elementSizeInBytes, equals(bytes));
133 expect(buffer.lengthInBytes, equals(bytes));
134 expect(buffer.offsetInBytes, equals(0));
135
136 buffer.length = 0;
137 expect(buffer.length, equals(0));
138
139 List samples = intSamples.toList()..addAll(intSamples.map((x) => -x));
140 for (int value in samples) {
141 int length = buffer.length;
142 buffer.add(value);
143 expect(buffer.length, equals(length + 1));
144 expect(buffer[length], equals(round(value)));
145 }
146 buffer.addAll(samples); // Add all the values at once.
147 for (int i = 0; i < samples.length; i++) {
148 expect(buffer[samples.length + i], equals(buffer[i]));
149 }
150
151 // Remove range works and changes length.
152 buffer.removeRange(samples.length, buffer.length);
153 expect(buffer.length, equals(samples.length));
154
155 // Both values are in `samples`, but equality is performed without rounding.
156 expect(buffer.contains(min - 1), isFalse);
157 expect(buffer.contains(max + 1), isFalse);
158 expect(buffer.contains(round(min - 1)), isTrue);
159 expect(buffer.contains(round(max + 1)), isTrue);
160
161 // Accessing the underlying buffer works.
162 buffer.length = 2;
163 buffer[0] = min;
164 buffer[1] = max;
165 var byteBuffer = new Uint8List.view(buffer.buffer);
166 int byteSize = buffer.elementSizeInBytes;
167 for (int i = 0; i < byteSize; i++) {
168 int tmp = byteBuffer[i];
169 byteBuffer[i] = byteBuffer[byteSize + i];
170 byteBuffer[byteSize + i] = tmp;
171 }
172 expect(buffer[0], equals(max));
173 expect(buffer[1], equals(min));
174 }
175
176 const List doubleSamples = const [
177 0.0,
178 5e-324, // Minimal denormal value.
179 2.225073858507201e-308, // Maximal denormal value.
180 2.2250738585072014e-308, // Minimal normal value.
181 0.9999999999999999, // Maximum value < 1.
182 1.0,
183 1.0000000000000002, // Minimum value > 1.
184 4294967295.0, // 2^32 -1.
185 4294967296.0, // 2^32.
186 4503599627370495.5, // Maximal fractional value.
187 9007199254740992.0, // Maximal exact value (adding one gets lost).
188 1.7976931348623157e+308, // Maximal value.
189 1.0/0.0, // Infinity.
190 0.0/0.0, // NaN.
191 0.49999999999999994, // Round-traps 1-3 (adding 0.5 and rounding towards
192 4503599627370497.0, // minus infinity will not be the same as rounding
193 9007199254740991.0 // to nearest with 0.5 rounding up).
194 ];
195
196 const List floatSamples = const [
197 0.0,
198 1.4e-45, // Minimal denormal value.
199 1.1754942E-38, // Maximal denormal value.
200 1.17549435E-38, // Minimal normal value.
201 0.99999994, // Maximal value < 1.
202 1.0,
203 1.0000001, // Minimal value > 1.
204 8388607.5, // Maximal fractional value.
205 16777216.0, // Maximal exact value.
206 3.4028235e+38, // Maximal value.
207 1.0/0.0, // Infinity.
208 0.0/0.0, // NaN.
209 0.99999994, // Round traps 1-3.
210 8388609.0,
211 16777215.0
212 ];
213
214 void doubleEqual(x, y) {
215 if (y.isNaN) {
216 expect(x.isNaN, isTrue);
217 } else {
218 if (x != y) {
219 }
220 expect(x, equals(y));
221 }
222 }
223
224 testFloatBuffer(int bitSize, List samples, create(), double round(double v)) {
225 test("Float${bitSize}Buffer", () {
226 var buffer = create();
227 List<double> list = buffer; // Test type.
228 int byteSize = bitSize ~/ 8;
229
230 expect(buffer.length, equals(0));
231 buffer.add(0.0);
232 expect(buffer.length, equals(1));
233 expect(buffer.removeLast(), equals(0.0));
234 expect(buffer.length, equals(0));
235
236 for (double value in samples) {
237 buffer.add(value);
238 doubleEqual(buffer[buffer.length - 1], round(value));
239 }
240 expect(buffer.length, equals(samples.length));
241
242 buffer.addAll(samples);
243 expect(buffer.length, equals(samples.length * 2));
244 for (int i = 0; i < samples.length; i++) {
245 doubleEqual(buffer[i], buffer[samples.length + i]);
246 }
247
248 buffer.removeRange(samples.length, buffer.length);
249 expect(buffer.length, equals(samples.length));
250
251 buffer.insertAll(0, samples);
252 expect(buffer.length, equals(samples.length * 2));
253 for (int i = 0; i < samples.length; i++) {
254 doubleEqual(buffer[i], buffer[samples.length + i]);
255 }
256
257 buffer.length = samples.length;
258 expect(buffer.length, equals(samples.length));
259
260 // TypedData.
261 expect(buffer.elementSizeInBytes, equals(byteSize));
262 expect(buffer.lengthInBytes, equals(byteSize * buffer.length));
263 expect(buffer.offsetInBytes, equals(0));
264
265 // Accessing the buffer works.
266 // Accessing the underlying buffer works.
267 buffer.length = 2;
268 buffer[0] = samples[0];
269 buffer[1] = samples[1];
270 var bytes = new Uint8List.view(buffer.buffer);
271 for (int i = 0; i < byteSize; i++) {
272 int tmp = bytes[i];
273 bytes[i] = bytes[byteSize + i];
274 bytes[byteSize + i] = tmp;
275 }
276 doubleEqual(buffer[0], round(samples[1]));
277 doubleEqual(buffer[1], round(samples[0]));
278 });
279 }
280
281 testFloat32x4Buffer(List floatSamples) {
282 List float4Samples = [];
283 for (int i = 0; i < floatSamples.length - 3; i++) {
284 float4Samples.add(new Float32x4(floatSamples[i],
285 floatSamples[i + 1],
286 floatSamples[i + 2],
287 floatSamples[i + 3]));
288 }
289
290 void floatEquals(x, y) {
291 if (y.isNaN) {
292 expect(x.isNaN, isTrue);
293 } else {
294 expect(x, equals(y));
295 }
296 }
297
298 void x4Equals(Float32x4 x, Float32x4 y) {
299 floatEquals(x.x, y.x);
300 floatEquals(x.y, y.y);
301 floatEquals(x.z, y.z);
302 floatEquals(x.w, y.w);
303 }
304
305 test("Float32x4Buffer", () {
306 var buffer = new Float32x4Buffer(5);
307 List<Float32x4> list = buffer;
308
309 expect(buffer.length, equals(5));
310 expect(buffer.elementSizeInBytes, equals(128 ~/ 8));
311 expect(buffer.lengthInBytes, equals(5 * 128 ~/ 8));
312 expect(buffer.offsetInBytes, equals(0));
313
314 x4Equals(buffer[0], new Float32x4.zero());
315 buffer.length = 0;
316 expect(buffer.length, equals(0));
317
318 for (var sample in float4Samples) {
319 buffer.add(sample);
320 x4Equals(buffer[buffer.length - 1], sample);
321 }
322 expect(buffer.length, equals(float4Samples.length));
323
324 buffer.addAll(float4Samples);
325 expect(buffer.length, equals(float4Samples.length * 2));
326 for (int i = 0; i < float4Samples.length; i++) {
327 x4Equals(buffer[i], buffer[float4Samples.length + i]);
328 }
329
330 buffer.removeRange(4, 4 + float4Samples.length);
331 for (int i = 0; i < float4Samples.length; i++) {
332 x4Equals(buffer[i], float4Samples[i]);
333 }
334
335 // Test underlying buffer.
336 buffer.length = 1;
337 buffer[0] = float4Samples[0]; // Does not contain NaN.
338
339 Float32List floats = new Float32List.view(buffer.buffer);
340 expect(floats[0], equals(buffer[0].x));
341 expect(floats[1], equals(buffer[0].y));
342 expect(floats[2], equals(buffer[0].z));
343 expect(floats[3], equals(buffer[0].w));
344 });
345 }
346
347 void testInt32x4Buffer(intSamples) {
348 test("Int32x4Buffer", () {
349 Function round = roundInt(32);
350 int bits = 128;
351 int bytes = 128 ~/ 8;
352 Matcher equals32x4(Int32x4 expected) => new MatchesInt32x4(expected);
353
354 var buffer = new Int32x4Buffer(0);
355 List<Int32x4> list = buffer; // It's a List.
356 expect(buffer.length, equals(0));
357
358 expect(buffer.elementSizeInBytes, equals(bytes));
359 expect(buffer.lengthInBytes, equals(0));
360 expect(buffer.offsetInBytes, equals(0));
361
362 Int32x4 sample = new Int32x4(-0x80000000, -1, 0, 0x7fffffff);
363 buffer.add(sample);
364 expect(buffer.length, equals(1));
365 expect(buffer[0], equals32x4(sample));
366
367 expect(buffer.elementSizeInBytes, equals(bytes));
368 expect(buffer.lengthInBytes, equals(bytes));
369 expect(buffer.offsetInBytes, equals(0));
370
371 buffer.length = 0;
372 expect(buffer.length, equals(0));
373
374 var samples = intSamples
375 .where((value) => value == round(value)) // Issue 15130
376 .map((value) => new Int32x4(value, -value, ~value, ~-value))
377 .toList();
378 for (Int32x4 value in samples) {
379 int length = buffer.length;
380 buffer.add(value);
381 expect(buffer.length, equals(length + 1));
382 expect(buffer[length], equals32x4(value));
383 }
384
385 buffer.addAll(samples); // Add all the values at once.
386 for (int i = 0; i < samples.length; i++) {
387 expect(buffer[samples.length + i], equals32x4(buffer[i]));
388 }
389
390 // Remove range works and changes length.
391 buffer.removeRange(samples.length, buffer.length);
392 expect(buffer.length, equals(samples.length));
393
394 // Accessing the underlying buffer works.
395 buffer.length = 2;
396 buffer[0] = new Int32x4(-80000000, 0x7fffffff, 0, -1);
397 var byteBuffer = new Uint8List.view(buffer.buffer);
398 int halfBytes = bytes ~/ 2;
399 for (int i = 0; i < halfBytes; i++) {
400 int tmp = byteBuffer[i];
401 byteBuffer[i] = byteBuffer[halfBytes + i];
402 byteBuffer[halfBytes + i] = tmp;
403 }
404 var result = new Int32x4(0, -1, -80000000, 0x7fffffff);
405 expect(buffer[0], equals32x4(result));
406 });
407 }
408
409 class MatchesInt32x4 extends Matcher {
410 Int32x4 result;
411 MatchesInt32x4(this.result);
412 bool matches(item, Map matchState) {
413 if (item is! Int32x4) return false;
414 Int32x4 value = item;
415 return result.x == value.x && result.y == value.y &&
416 result.z == value.z && result.w == value.w;
417 }
418
419 Description describe(Description description) =>
420 description.add('Int32x4.==');
421 }
OLDNEW
« no previous file with comments | « pkg/collection_helpers/pubspec.yaml ('k') | pkg/pkg.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698