|
1 /* |
|
2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. |
|
8 * |
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
12 * version 2 for more details (a copy is included in the LICENSE file that |
|
13 * accompanied this code). |
|
14 * |
|
15 * You should have received a copy of the GNU General Public License version |
|
16 * 2 along with this work; if not, write to the Free Software Foundation, |
|
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
18 * |
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
20 * or visit www.oracle.com if you need additional information or have any |
|
21 * questions. |
|
22 */ |
|
23 |
|
24 /* @test |
|
25 * @summary Binary data and view tests for byte buffers |
|
26 * @bug 8159257 |
|
27 * @run testng ByteBufferViews |
|
28 */ |
|
29 |
|
30 import org.testng.annotations.DataProvider; |
|
31 import org.testng.annotations.Test; |
|
32 |
|
33 import java.nio.Buffer; |
|
34 import java.nio.ByteBuffer; |
|
35 import java.nio.ByteOrder; |
|
36 import java.nio.CharBuffer; |
|
37 import java.nio.DoubleBuffer; |
|
38 import java.nio.FloatBuffer; |
|
39 import java.nio.IntBuffer; |
|
40 import java.nio.LongBuffer; |
|
41 import java.nio.ShortBuffer; |
|
42 import java.util.List; |
|
43 import java.util.Map; |
|
44 import java.util.function.Function; |
|
45 import java.util.function.IntFunction; |
|
46 import java.util.function.IntUnaryOperator; |
|
47 import java.util.function.UnaryOperator; |
|
48 import java.util.stream.Collectors; |
|
49 |
|
50 import static org.testng.Assert.*; |
|
51 |
|
52 public class ByteBufferViews { |
|
53 static final int SIZE = 32; |
|
54 |
|
55 // List of buffer allocator functions |
|
56 static final List<Map.Entry<String, IntFunction<ByteBuffer>>> BYTE_BUFFER_ALLOCATE_FUNCTIONS = List.of( |
|
57 // Heap |
|
58 Map.entry("ByteBuffer.allocate(ba)", |
|
59 size -> ByteBuffer.allocate(size)), |
|
60 // Aligned |
|
61 Map.entry("ByteBuffer.allocate(size).position(8)", |
|
62 size -> ByteBuffer.allocate(size).position(8)), |
|
63 Map.entry("ByteBuffer.allocate(size).position(8).slice()", |
|
64 size -> ByteBuffer.allocate(size).position(8).slice()), |
|
65 Map.entry("ByteBuffer.allocate(size).position(8).slice().duplicate()", |
|
66 size -> ByteBuffer.allocate(size).position(8).slice().duplicate()), |
|
67 // Unaligned |
|
68 Map.entry("ByteBuffer.allocate(size).position(1)", |
|
69 size -> ByteBuffer.allocate(size).position(1)), |
|
70 Map.entry("ByteBuffer.allocate(size).position(1).slice()", |
|
71 size -> ByteBuffer.allocate(size).position(1).slice()), |
|
72 Map.entry("ByteBuffer.allocate(size).position(1).slice().duplicate()", |
|
73 size -> ByteBuffer.allocate(size).position(1).slice().duplicate()), |
|
74 |
|
75 // Off-heap |
|
76 Map.entry("ByteBuffer.allocateDirect(size)", |
|
77 size -> ByteBuffer.allocateDirect(size)), |
|
78 // Aligned |
|
79 Map.entry("ByteBuffer.allocateDirect(size).position(8)", |
|
80 size -> ByteBuffer.allocateDirect(size).position(8)), |
|
81 Map.entry("ByteBuffer.allocateDirect(size).position(8).slice()", |
|
82 size -> ByteBuffer.allocateDirect(size).position(8).slice()), |
|
83 Map.entry("ByteBuffer.allocateDirect(size).position(8).slice().duplicate()", |
|
84 size -> ByteBuffer.allocateDirect(size).position(8).slice().duplicate()), |
|
85 // Unaligned |
|
86 Map.entry("ByteBuffer.allocateDirect(size).position(1)", |
|
87 size -> ByteBuffer.allocateDirect(size).position(1)), |
|
88 Map.entry("ByteBuffer.allocateDirect(size).position(1).slice()", |
|
89 size -> ByteBuffer.allocateDirect(size).position(1).slice()), |
|
90 Map.entry("ByteBuffer.allocateDirect(size).position(1).slice().duplicate()", |
|
91 size -> ByteBuffer.allocateDirect(size).position(1).slice().duplicate()) |
|
92 ); |
|
93 |
|
94 // List of buffer byte order functions |
|
95 static final List<Map.Entry<String, UnaryOperator<ByteBuffer>>> BYTE_BUFFER_ORDER_FUNCTIONS = List.of( |
|
96 Map.entry("order(ByteOrder.BIG_ENDIAN)", |
|
97 (ByteBuffer bb) -> bb.order(ByteOrder.BIG_ENDIAN)), |
|
98 Map.entry("order(ByteOrder.LITTLE_ENDIAN)", |
|
99 (ByteBuffer bb) -> bb.order(ByteOrder.LITTLE_ENDIAN)) |
|
100 ); |
|
101 |
|
102 // Produce a composition of allocation and byte order buffer functions |
|
103 static List<Map.Entry<String, IntFunction<ByteBuffer>>> composeBufferFunctions( |
|
104 List<Map.Entry<String, IntFunction<ByteBuffer>>> af, |
|
105 List<Map.Entry<String, UnaryOperator<ByteBuffer>>> of) { |
|
106 return af.stream().flatMap(afe -> of.stream(). |
|
107 map(ofe -> { |
|
108 String s = afe.getKey() + "." + ofe.getKey(); |
|
109 IntFunction<ByteBuffer> f = size -> ofe.getValue(). |
|
110 apply(afe.getValue().apply(size)); |
|
111 return Map.entry(s, f); |
|
112 }) |
|
113 ).collect(Collectors.toList()); |
|
114 } |
|
115 |
|
116 // List of buffer allocator functions to test |
|
117 static final List<Map.Entry<String, IntFunction<ByteBuffer>>> BYTE_BUFFER_FUNCTIONS = |
|
118 composeBufferFunctions(BYTE_BUFFER_ALLOCATE_FUNCTIONS, BYTE_BUFFER_ORDER_FUNCTIONS); |
|
119 |
|
120 // Creates a cross product of test arguments for |
|
121 // buffer allocator functions and buffer view functions |
|
122 static Object[][] product(List<? extends Map.Entry<String, ?>> la, |
|
123 List<? extends Map.Entry<String, ?>> lb) { |
|
124 return la.stream().flatMap(lae -> lb.stream(). |
|
125 map(lbe -> List.of( |
|
126 lae.getKey() + " -> " + lbe.getKey(), |
|
127 lae.getValue(), |
|
128 lbe.getValue()).toArray() |
|
129 )).toArray(Object[][]::new); |
|
130 } |
|
131 |
|
132 static void assertValues(int i, Object bValue, Object bbValue, ByteBuffer bb) { |
|
133 if (!bValue.equals(bbValue)) { |
|
134 fail(String.format("Values %s and %s differ at index %d for %s", |
|
135 bValue, bbValue, i, bb)); |
|
136 } |
|
137 } |
|
138 |
|
139 static void assertValues(int i, Object bbValue, Object bvValue, ByteBuffer bb, Buffer bv) { |
|
140 if (!bbValue.equals(bvValue)) { |
|
141 fail(String.format("Values %s and %s differ at index %d for %s and %s", |
|
142 bbValue, bvValue, i, bb, bv)); |
|
143 } |
|
144 } |
|
145 |
|
146 static ByteBuffer allocate(IntFunction<ByteBuffer> f) { |
|
147 return allocate(f, i -> i); |
|
148 } |
|
149 |
|
150 static ByteBuffer allocate(IntFunction<ByteBuffer> f, IntUnaryOperator o) { |
|
151 return fill(f.apply(SIZE), o); |
|
152 } |
|
153 |
|
154 static ByteBuffer fill(ByteBuffer bb, IntUnaryOperator o) { |
|
155 for (int i = 0; i < bb.limit(); i++) { |
|
156 bb.put(i, (byte) o.applyAsInt(i)); |
|
157 } |
|
158 return bb; |
|
159 } |
|
160 |
|
161 |
|
162 @DataProvider |
|
163 public static Object[][] shortViewProvider() { |
|
164 List<Map.Entry<String, Function<ByteBuffer, ShortBuffer>>> bfs = List.of( |
|
165 Map.entry("bb.asShortBuffer()", |
|
166 bb -> bb.asShortBuffer()), |
|
167 Map.entry("bb.asShortBuffer().slice()", |
|
168 bb -> bb.asShortBuffer().slice()), |
|
169 Map.entry("bb.asShortBuffer().slice().duplicate()", |
|
170 bb -> bb.asShortBuffer().slice().duplicate()) |
|
171 ); |
|
172 |
|
173 return product(BYTE_BUFFER_FUNCTIONS, bfs); |
|
174 } |
|
175 |
|
176 @Test(dataProvider = "shortViewProvider") |
|
177 public void testShortGet(String desc, IntFunction<ByteBuffer> fbb, |
|
178 Function<ByteBuffer, ShortBuffer> fbi) { |
|
179 ByteBuffer bb = allocate(fbb); |
|
180 ShortBuffer vb = fbi.apply(bb); |
|
181 int o = bb.position(); |
|
182 |
|
183 for (int i = 0; i < vb.limit(); i++) { |
|
184 short fromBytes = getShortFromBytes(bb, o + i * 2); |
|
185 short fromMethodView = bb.getShort(o + i * 2); |
|
186 assertValues(i, fromBytes, fromMethodView, bb); |
|
187 |
|
188 short fromBufferView = vb.get(i); |
|
189 assertValues(i, fromMethodView, fromBufferView, bb, vb); |
|
190 } |
|
191 |
|
192 for (int i = 0; i < vb.limit(); i++) { |
|
193 short v = getShortFromBytes(bb, o + i * 2); |
|
194 short a = bb.getShort(); |
|
195 assertValues(i, v, a, bb); |
|
196 |
|
197 short b = vb.get(); |
|
198 assertValues(i, a, b, bb, vb); |
|
199 } |
|
200 |
|
201 } |
|
202 |
|
203 @Test(dataProvider = "shortViewProvider") |
|
204 public void testShortPut(String desc, IntFunction<ByteBuffer> fbb, |
|
205 Function<ByteBuffer, ShortBuffer> fbi) { |
|
206 ByteBuffer bbfilled = allocate(fbb); |
|
207 ByteBuffer bb = allocate(fbb, i -> 0); |
|
208 ShortBuffer vb = fbi.apply(bb); |
|
209 int o = bb.position(); |
|
210 |
|
211 for (int i = 0; i < vb.limit(); i++) { |
|
212 short fromFilled = bbfilled.getShort(o + i * 2); |
|
213 |
|
214 vb.put(i, fromFilled); |
|
215 short fromMethodView = bb.getShort(o + i * 2); |
|
216 assertValues(i, fromFilled, fromMethodView, bb, vb); |
|
217 } |
|
218 |
|
219 for (int i = 0; i < vb.limit(); i++) { |
|
220 short fromFilled = bbfilled.getShort(o + i * 2); |
|
221 |
|
222 vb.put(fromFilled); |
|
223 short fromMethodView = bb.getShort(); |
|
224 assertValues(i, fromFilled, fromMethodView, bb, vb); |
|
225 } |
|
226 |
|
227 |
|
228 fill(bb, i -> 0); |
|
229 bb.clear().position(o); |
|
230 vb.clear(); |
|
231 |
|
232 for (int i = 0; i < vb.limit(); i++) { |
|
233 short fromFilled = bbfilled.getShort(o + i * 2); |
|
234 |
|
235 bb.putShort(o + i * 2, fromFilled); |
|
236 short fromBufferView = vb.get(i); |
|
237 assertValues(i, fromFilled, fromBufferView, bb, vb); |
|
238 } |
|
239 |
|
240 for (int i = 0; i < vb.limit(); i++) { |
|
241 short fromFilled = bbfilled.getShort(o + i * 2); |
|
242 |
|
243 bb.putShort(fromFilled); |
|
244 short fromBufferView = vb.get(); |
|
245 assertValues(i, fromFilled, fromBufferView, bb, vb); |
|
246 } |
|
247 } |
|
248 |
|
249 static short getShortFromBytes(ByteBuffer bb, int i) { |
|
250 int a = bb.get(i) & 0xFF; |
|
251 int b = bb.get(i + 1) & 0xFF; |
|
252 |
|
253 if (bb.order() == ByteOrder.BIG_ENDIAN) { |
|
254 return (short) ((a << 8) | b); |
|
255 } |
|
256 else { |
|
257 return (short) ((b << 8) | a); |
|
258 } |
|
259 } |
|
260 |
|
261 @DataProvider |
|
262 public static Object[][] charViewProvider() { |
|
263 List<Map.Entry<String, Function<ByteBuffer, CharBuffer>>> bfs = List.of( |
|
264 Map.entry("bb.asCharBuffer()", |
|
265 bb -> bb.asCharBuffer()), |
|
266 Map.entry("bb.asCharBuffer().slice()", |
|
267 bb -> bb.asCharBuffer().slice()), |
|
268 Map.entry("bb.asCharBuffer().slice().duplicate()", |
|
269 bb -> bb.asCharBuffer().slice().duplicate()) |
|
270 ); |
|
271 |
|
272 return product(BYTE_BUFFER_FUNCTIONS, bfs); |
|
273 } |
|
274 |
|
275 @Test(dataProvider = "charViewProvider") |
|
276 public void testCharGet(String desc, IntFunction<ByteBuffer> fbb, |
|
277 Function<ByteBuffer, CharBuffer> fbi) { |
|
278 ByteBuffer bb = allocate(fbb); |
|
279 CharBuffer vb = fbi.apply(bb); |
|
280 int o = bb.position(); |
|
281 |
|
282 for (int i = 0; i < vb.limit(); i++) { |
|
283 char fromBytes = getCharFromBytes(bb, o + i * 2); |
|
284 char fromMethodView = bb.getChar(o + i * 2); |
|
285 assertValues(i, fromBytes, fromMethodView, bb); |
|
286 |
|
287 char fromBufferView = vb.get(i); |
|
288 assertValues(i, fromMethodView, fromBufferView, bb, vb); |
|
289 } |
|
290 |
|
291 for (int i = 0; i < vb.limit(); i++) { |
|
292 char fromBytes = getCharFromBytes(bb, o + i * 2); |
|
293 char fromMethodView = bb.getChar(); |
|
294 assertValues(i, fromBytes, fromMethodView, bb); |
|
295 |
|
296 char fromBufferView = vb.get(); |
|
297 assertValues(i, fromMethodView, fromBufferView, bb, vb); |
|
298 } |
|
299 |
|
300 } |
|
301 |
|
302 @Test(dataProvider = "charViewProvider") |
|
303 public void testCharPut(String desc, IntFunction<ByteBuffer> fbb, |
|
304 Function<ByteBuffer, CharBuffer> fbi) { |
|
305 ByteBuffer bbfilled = allocate(fbb); |
|
306 ByteBuffer bb = allocate(fbb, i -> 0); |
|
307 CharBuffer vb = fbi.apply(bb); |
|
308 int o = bb.position(); |
|
309 |
|
310 for (int i = 0; i < vb.limit(); i++) { |
|
311 char fromFilled = bbfilled.getChar(o + i * 2); |
|
312 |
|
313 vb.put(i, fromFilled); |
|
314 char fromMethodView = bb.getChar(o + i * 2); |
|
315 assertValues(i, fromFilled, fromMethodView, bb, vb); |
|
316 } |
|
317 |
|
318 for (int i = 0; i < vb.limit(); i++) { |
|
319 char fromFilled = bbfilled.getChar(o + i * 2); |
|
320 |
|
321 vb.put(fromFilled); |
|
322 char fromMethodView = bb.getChar(); |
|
323 assertValues(i, fromFilled, fromMethodView, bb, vb); |
|
324 } |
|
325 |
|
326 |
|
327 fill(bb, i -> 0); |
|
328 bb.clear().position(o); |
|
329 vb.clear(); |
|
330 |
|
331 for (int i = 0; i < vb.limit(); i++) { |
|
332 char fromFilled = bbfilled.getChar(o + i * 2); |
|
333 |
|
334 bb.putChar(o + i * 2, fromFilled); |
|
335 char fromBufferView = vb.get(i); |
|
336 assertValues(i, fromFilled, fromBufferView, bb, vb); |
|
337 } |
|
338 |
|
339 for (int i = 0; i < vb.limit(); i++) { |
|
340 char fromFilled = bbfilled.getChar(o + i * 2); |
|
341 |
|
342 bb.putChar(fromFilled); |
|
343 char fromBufferView = vb.get(); |
|
344 assertValues(i, fromFilled, fromBufferView, bb, vb); |
|
345 } |
|
346 } |
|
347 |
|
348 static char getCharFromBytes(ByteBuffer bb, int i) { |
|
349 return (char) getShortFromBytes(bb, i); |
|
350 } |
|
351 |
|
352 |
|
353 @DataProvider |
|
354 public static Object[][] intViewProvider() { |
|
355 List<Map.Entry<String, Function<ByteBuffer, IntBuffer>>> bfs = List.of( |
|
356 Map.entry("bb.asIntBuffer()", |
|
357 bb -> bb.asIntBuffer()), |
|
358 Map.entry("bb.asIntBuffer().slice()", |
|
359 bb -> bb.asIntBuffer().slice()), |
|
360 Map.entry("bb.asIntBuffer().slice().duplicate()", |
|
361 bb -> bb.asIntBuffer().slice().duplicate()) |
|
362 ); |
|
363 |
|
364 return product(BYTE_BUFFER_FUNCTIONS, bfs); |
|
365 } |
|
366 |
|
367 @Test(dataProvider = "intViewProvider") |
|
368 public void testIntGet(String desc, IntFunction<ByteBuffer> fbb, |
|
369 Function<ByteBuffer, IntBuffer> fbi) { |
|
370 ByteBuffer bb = allocate(fbb); |
|
371 IntBuffer vb = fbi.apply(bb); |
|
372 int o = bb.position(); |
|
373 |
|
374 for (int i = 0; i < vb.limit(); i++) { |
|
375 int fromBytes = getIntFromBytes(bb, o + i * 4); |
|
376 int fromMethodView = bb.getInt(o + i * 4); |
|
377 assertValues(i, fromBytes, fromMethodView, bb); |
|
378 |
|
379 int fromBufferView = vb.get(i); |
|
380 assertValues(i, fromMethodView, fromBufferView, bb, vb); |
|
381 } |
|
382 |
|
383 for (int i = 0; i < vb.limit(); i++) { |
|
384 int v = getIntFromBytes(bb, o + i * 4); |
|
385 int a = bb.getInt(); |
|
386 assertValues(i, v, a, bb); |
|
387 |
|
388 int b = vb.get(); |
|
389 assertValues(i, a, b, bb, vb); |
|
390 } |
|
391 |
|
392 } |
|
393 |
|
394 @Test(dataProvider = "intViewProvider") |
|
395 public void testIntPut(String desc, IntFunction<ByteBuffer> fbb, |
|
396 Function<ByteBuffer, IntBuffer> fbi) { |
|
397 ByteBuffer bbfilled = allocate(fbb); |
|
398 ByteBuffer bb = allocate(fbb, i -> 0); |
|
399 IntBuffer vb = fbi.apply(bb); |
|
400 int o = bb.position(); |
|
401 |
|
402 for (int i = 0; i < vb.limit(); i++) { |
|
403 int fromFilled = bbfilled.getInt(o + i * 4); |
|
404 |
|
405 vb.put(i, fromFilled); |
|
406 int fromMethodView = bb.getInt(o + i * 4); |
|
407 assertValues(i, fromFilled, fromMethodView, bb, vb); |
|
408 } |
|
409 |
|
410 for (int i = 0; i < vb.limit(); i++) { |
|
411 int fromFilled = bbfilled.getInt(o + i * 4); |
|
412 |
|
413 vb.put(fromFilled); |
|
414 int fromMethodView = bb.getInt(); |
|
415 assertValues(i, fromFilled, fromMethodView, bb, vb); |
|
416 } |
|
417 |
|
418 |
|
419 fill(bb, i -> 0); |
|
420 bb.clear().position(o); |
|
421 vb.clear(); |
|
422 |
|
423 for (int i = 0; i < vb.limit(); i++) { |
|
424 int fromFilled = bbfilled.getInt(o + i * 4); |
|
425 |
|
426 bb.putInt(o + i * 4, fromFilled); |
|
427 int fromBufferView = vb.get(i); |
|
428 assertValues(i, fromFilled, fromBufferView, bb, vb); |
|
429 } |
|
430 |
|
431 for (int i = 0; i < vb.limit(); i++) { |
|
432 int fromFilled = bbfilled.getInt(o + i * 4); |
|
433 |
|
434 bb.putInt(fromFilled); |
|
435 int fromBufferView = vb.get(); |
|
436 assertValues(i, fromFilled, fromBufferView, bb, vb); |
|
437 } |
|
438 } |
|
439 |
|
440 static int getIntFromBytes(ByteBuffer bb, int i) { |
|
441 int a = bb.get(i) & 0xFF; |
|
442 int b = bb.get(i + 1) & 0xFF; |
|
443 int c = bb.get(i + 2) & 0xFF; |
|
444 int d = bb.get(i + 3) & 0xFF; |
|
445 |
|
446 if (bb.order() == ByteOrder.BIG_ENDIAN) { |
|
447 return ((a << 24) | (b << 16) | (c << 8) | d); |
|
448 } |
|
449 else { |
|
450 return ((d << 24) | (c << 16) | (b << 8) | a); |
|
451 } |
|
452 } |
|
453 |
|
454 |
|
455 @DataProvider |
|
456 public static Object[][] longViewProvider() { |
|
457 List<Map.Entry<String, Function<ByteBuffer, LongBuffer>>> bfs = List.of( |
|
458 Map.entry("bb.asLongBuffer()", |
|
459 bb -> bb.asLongBuffer()), |
|
460 Map.entry("bb.asLongBuffer().slice()", |
|
461 bb -> bb.asLongBuffer().slice()), |
|
462 Map.entry("bb.asLongBuffer().slice().duplicate()", |
|
463 bb -> bb.asLongBuffer().slice().duplicate()) |
|
464 ); |
|
465 |
|
466 return product(BYTE_BUFFER_FUNCTIONS, bfs); |
|
467 } |
|
468 |
|
469 @Test(dataProvider = "longViewProvider") |
|
470 public void testLongGet(String desc, IntFunction<ByteBuffer> fbb, |
|
471 Function<ByteBuffer, LongBuffer> fbi) { |
|
472 ByteBuffer bb = allocate(fbb); |
|
473 LongBuffer vb = fbi.apply(bb); |
|
474 int o = bb.position(); |
|
475 |
|
476 for (int i = 0; i < vb.limit(); i++) { |
|
477 long fromBytes = getLongFromBytes(bb, o + i * 8); |
|
478 long fromMethodView = bb.getLong(o + i * 8); |
|
479 assertValues(i, fromBytes, fromMethodView, bb); |
|
480 |
|
481 long fromBufferView = vb.get(i); |
|
482 assertValues(i, fromMethodView, fromBufferView, bb, vb); |
|
483 } |
|
484 |
|
485 for (int i = 0; i < vb.limit(); i++) { |
|
486 long v = getLongFromBytes(bb, o + i * 8); |
|
487 long a = bb.getLong(); |
|
488 assertValues(i, v, a, bb); |
|
489 |
|
490 long b = vb.get(); |
|
491 assertValues(i, a, b, bb, vb); |
|
492 } |
|
493 |
|
494 } |
|
495 |
|
496 @Test(dataProvider = "longViewProvider") |
|
497 public void testLongPut(String desc, IntFunction<ByteBuffer> fbb, |
|
498 Function<ByteBuffer, LongBuffer> fbi) { |
|
499 ByteBuffer bbfilled = allocate(fbb); |
|
500 ByteBuffer bb = allocate(fbb, i -> 0); |
|
501 LongBuffer vb = fbi.apply(bb); |
|
502 int o = bb.position(); |
|
503 |
|
504 for (int i = 0; i < vb.limit(); i++) { |
|
505 long fromFilled = bbfilled.getLong(o + i * 8); |
|
506 |
|
507 vb.put(i, fromFilled); |
|
508 long fromMethodView = bb.getLong(o + i * 8); |
|
509 assertValues(i, fromFilled, fromMethodView, bb, vb); |
|
510 } |
|
511 |
|
512 for (int i = 0; i < vb.limit(); i++) { |
|
513 long fromFilled = bbfilled.getLong(o + i * 8); |
|
514 |
|
515 vb.put(fromFilled); |
|
516 long fromMethodView = bb.getLong(); |
|
517 assertValues(i, fromFilled, fromMethodView, bb, vb); |
|
518 } |
|
519 |
|
520 |
|
521 fill(bb, i -> 0); |
|
522 bb.clear().position(o); |
|
523 vb.clear(); |
|
524 |
|
525 for (int i = 0; i < vb.limit(); i++) { |
|
526 long fromFilled = bbfilled.getLong(o + i * 8); |
|
527 |
|
528 bb.putLong(o + i * 8, fromFilled); |
|
529 long fromBufferView = vb.get(i); |
|
530 assertValues(i, fromFilled, fromBufferView, bb, vb); |
|
531 } |
|
532 |
|
533 for (int i = 0; i < vb.limit(); i++) { |
|
534 long fromFilled = bbfilled.getLong(o + i * 8); |
|
535 |
|
536 bb.putLong(fromFilled); |
|
537 long fromBufferView = vb.get(); |
|
538 assertValues(i, fromFilled, fromBufferView, bb, vb); |
|
539 } |
|
540 } |
|
541 |
|
542 static long getLongFromBytes(ByteBuffer bb, int i) { |
|
543 long a = bb.get(i) & 0xFF; |
|
544 long b = bb.get(i + 1) & 0xFF; |
|
545 long c = bb.get(i + 2) & 0xFF; |
|
546 long d = bb.get(i + 3) & 0xFF; |
|
547 long e = bb.get(i + 4) & 0xFF; |
|
548 long f = bb.get(i + 5) & 0xFF; |
|
549 long g = bb.get(i + 6) & 0xFF; |
|
550 long h = bb.get(i + 7) & 0xFF; |
|
551 |
|
552 if (bb.order() == ByteOrder.BIG_ENDIAN) { |
|
553 return ((a << 56) | (b << 48) | (c << 40) | (d << 32) | |
|
554 (e << 24) | (f << 16) | (g << 8) | h); |
|
555 } |
|
556 else { |
|
557 return ((h << 56) | (g << 48) | (f << 40) | (e << 32) | |
|
558 (d << 24) | (c << 16) | (b << 8) | a); |
|
559 } |
|
560 } |
|
561 |
|
562 |
|
563 @DataProvider |
|
564 public static Object[][] floatViewProvider() { |
|
565 List<Map.Entry<String, Function<ByteBuffer, FloatBuffer>>> bfs = List.of( |
|
566 Map.entry("bb.asFloatBuffer()", |
|
567 bb -> bb.asFloatBuffer()), |
|
568 Map.entry("bb.asFloatBuffer().slice()", |
|
569 bb -> bb.asFloatBuffer().slice()), |
|
570 Map.entry("bb.asFloatBuffer().slice().duplicate()", |
|
571 bb -> bb.asFloatBuffer().slice().duplicate()) |
|
572 ); |
|
573 |
|
574 return product(BYTE_BUFFER_FUNCTIONS, bfs); |
|
575 } |
|
576 |
|
577 @Test(dataProvider = "floatViewProvider") |
|
578 public void testFloatGet(String desc, IntFunction<ByteBuffer> fbb, |
|
579 Function<ByteBuffer, FloatBuffer> fbi) { |
|
580 ByteBuffer bb = allocate(fbb); |
|
581 FloatBuffer vb = fbi.apply(bb); |
|
582 int o = bb.position(); |
|
583 |
|
584 for (int i = 0; i < vb.limit(); i++) { |
|
585 float fromBytes = getFloatFromBytes(bb, o + i * 4); |
|
586 float fromMethodView = bb.getFloat(o + i * 4); |
|
587 assertValues(i, fromBytes, fromMethodView, bb); |
|
588 |
|
589 float fromBufferView = vb.get(i); |
|
590 assertValues(i, fromMethodView, fromBufferView, bb, vb); |
|
591 } |
|
592 |
|
593 for (int i = 0; i < vb.limit(); i++) { |
|
594 float v = getFloatFromBytes(bb, o + i * 4); |
|
595 float a = bb.getFloat(); |
|
596 assertValues(i, v, a, bb); |
|
597 |
|
598 float b = vb.get(); |
|
599 assertValues(i, a, b, bb, vb); |
|
600 } |
|
601 |
|
602 } |
|
603 |
|
604 @Test(dataProvider = "floatViewProvider") |
|
605 public void testFloatPut(String desc, IntFunction<ByteBuffer> fbb, |
|
606 Function<ByteBuffer, FloatBuffer> fbi) { |
|
607 ByteBuffer bbfilled = allocate(fbb); |
|
608 ByteBuffer bb = allocate(fbb, i -> 0); |
|
609 FloatBuffer vb = fbi.apply(bb); |
|
610 int o = bb.position(); |
|
611 |
|
612 for (int i = 0; i < vb.limit(); i++) { |
|
613 float fromFilled = bbfilled.getFloat(o + i * 4); |
|
614 |
|
615 vb.put(i, fromFilled); |
|
616 float fromMethodView = bb.getFloat(o + i * 4); |
|
617 assertValues(i, fromFilled, fromMethodView, bb, vb); |
|
618 } |
|
619 |
|
620 for (int i = 0; i < vb.limit(); i++) { |
|
621 float fromFilled = bbfilled.getFloat(o + i * 4); |
|
622 |
|
623 vb.put(fromFilled); |
|
624 float fromMethodView = bb.getFloat(); |
|
625 assertValues(i, fromFilled, fromMethodView, bb, vb); |
|
626 } |
|
627 |
|
628 |
|
629 fill(bb, i -> 0); |
|
630 bb.clear().position(o); |
|
631 vb.clear(); |
|
632 |
|
633 for (int i = 0; i < vb.limit(); i++) { |
|
634 float fromFilled = bbfilled.getFloat(o + i * 4); |
|
635 |
|
636 bb.putFloat(o + i * 4, fromFilled); |
|
637 float fromBufferView = vb.get(i); |
|
638 assertValues(i, fromFilled, fromBufferView, bb, vb); |
|
639 } |
|
640 |
|
641 for (int i = 0; i < vb.limit(); i++) { |
|
642 float fromFilled = bbfilled.getFloat(o + i * 4); |
|
643 |
|
644 bb.putFloat(fromFilled); |
|
645 float fromBufferView = vb.get(); |
|
646 assertValues(i, fromFilled, fromBufferView, bb, vb); |
|
647 } |
|
648 } |
|
649 |
|
650 static float getFloatFromBytes(ByteBuffer bb, int i) { |
|
651 return Float.intBitsToFloat(getIntFromBytes(bb, i)); |
|
652 } |
|
653 |
|
654 |
|
655 |
|
656 @DataProvider |
|
657 public static Object[][] doubleViewProvider() { |
|
658 List<Map.Entry<String, Function<ByteBuffer, DoubleBuffer>>> bfs = List.of( |
|
659 Map.entry("bb.asDoubleBuffer()", |
|
660 bb -> bb.asDoubleBuffer()), |
|
661 Map.entry("bb.asDoubleBuffer().slice()", |
|
662 bb -> bb.asDoubleBuffer().slice()), |
|
663 Map.entry("bb.asDoubleBuffer().slice().duplicate()", |
|
664 bb -> bb.asDoubleBuffer().slice().duplicate()) |
|
665 ); |
|
666 |
|
667 return product(BYTE_BUFFER_FUNCTIONS, bfs); |
|
668 } |
|
669 |
|
670 @Test(dataProvider = "doubleViewProvider") |
|
671 public void testDoubleGet(String desc, IntFunction<ByteBuffer> fbb, |
|
672 Function<ByteBuffer, DoubleBuffer> fbi) { |
|
673 ByteBuffer bb = allocate(fbb); |
|
674 DoubleBuffer vb = fbi.apply(bb); |
|
675 int o = bb.position(); |
|
676 |
|
677 for (int i = 0; i < vb.limit(); i++) { |
|
678 double fromBytes = getDoubleFromBytes(bb, o + i * 8); |
|
679 double fromMethodView = bb.getDouble(o + i * 8); |
|
680 assertValues(i, fromBytes, fromMethodView, bb); |
|
681 |
|
682 double fromBufferView = vb.get(i); |
|
683 assertValues(i, fromMethodView, fromBufferView, bb, vb); |
|
684 } |
|
685 |
|
686 for (int i = 0; i < vb.limit(); i++) { |
|
687 double v = getDoubleFromBytes(bb, o + i * 8); |
|
688 double a = bb.getDouble(); |
|
689 assertValues(i, v, a, bb); |
|
690 |
|
691 double b = vb.get(); |
|
692 assertValues(i, a, b, bb, vb); |
|
693 } |
|
694 |
|
695 } |
|
696 |
|
697 @Test(dataProvider = "doubleViewProvider") |
|
698 public void testDoublePut(String desc, IntFunction<ByteBuffer> fbb, |
|
699 Function<ByteBuffer, DoubleBuffer> fbi) { |
|
700 ByteBuffer bbfilled = allocate(fbb); |
|
701 ByteBuffer bb = allocate(fbb, i -> 0); |
|
702 DoubleBuffer vb = fbi.apply(bb); |
|
703 int o = bb.position(); |
|
704 |
|
705 for (int i = 0; i < vb.limit(); i++) { |
|
706 double fromFilled = bbfilled.getDouble(o + i * 8); |
|
707 |
|
708 vb.put(i, fromFilled); |
|
709 double fromMethodView = bb.getDouble(o + i * 8); |
|
710 assertValues(i, fromFilled, fromMethodView, bb, vb); |
|
711 } |
|
712 |
|
713 for (int i = 0; i < vb.limit(); i++) { |
|
714 double fromFilled = bbfilled.getDouble(o + i * 8); |
|
715 |
|
716 vb.put(fromFilled); |
|
717 double fromMethodView = bb.getDouble(); |
|
718 assertValues(i, fromFilled, fromMethodView, bb, vb); |
|
719 } |
|
720 |
|
721 |
|
722 fill(bb, i -> 0); |
|
723 bb.clear().position(o); |
|
724 vb.clear(); |
|
725 |
|
726 for (int i = 0; i < vb.limit(); i++) { |
|
727 double fromFilled = bbfilled.getDouble(o + i * 8); |
|
728 |
|
729 bb.putDouble(o + i * 8, fromFilled); |
|
730 double fromBufferView = vb.get(i); |
|
731 assertValues(i, fromFilled, fromBufferView, bb, vb); |
|
732 } |
|
733 |
|
734 for (int i = 0; i < vb.limit(); i++) { |
|
735 double fromFilled = bbfilled.getDouble(o + i * 8); |
|
736 |
|
737 bb.putDouble(fromFilled); |
|
738 double fromBufferView = vb.get(); |
|
739 assertValues(i, fromFilled, fromBufferView, bb, vb); |
|
740 } |
|
741 } |
|
742 |
|
743 static double getDoubleFromBytes(ByteBuffer bb, int i) { |
|
744 return Double.longBitsToDouble(getLongFromBytes(bb, i)); |
|
745 } |
|
746 } |