Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/jcl/src/openj9.dataaccess/share/classes/com/ibm/dataaccess/ByteArrayMarshaller.java
12558 views
1
/*[INCLUDE-IF DAA]*/
2
/*******************************************************************************
3
* Copyright (c) 2013, 2015 IBM Corp. and others
4
*
5
* This program and the accompanying materials are made available under
6
* the terms of the Eclipse Public License 2.0 which accompanies this
7
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
8
* or the Apache License, Version 2.0 which accompanies this distribution and
9
* is available at https://www.apache.org/licenses/LICENSE-2.0.
10
*
11
* This Source Code may also be made available under the following
12
* Secondary Licenses when the conditions for such availability set
13
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
14
* General Public License, version 2 with the GNU Classpath
15
* Exception [1] and GNU General Public License, version 2 with the
16
* OpenJDK Assembly Exception [2].
17
*
18
* [1] https://www.gnu.org/software/classpath/license.html
19
* [2] http://openjdk.java.net/legal/assembly-exception.html
20
*
21
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
22
*******************************************************************************/
23
24
package com.ibm.dataaccess;
25
26
/**
27
* Conversion routines to marshall Java binary types (short, int, long, float,
28
* double) to byte arrays.
29
*
30
* @author IBM
31
* @version $Revision$ on $Date$
32
*/
33
public class ByteArrayMarshaller {
34
35
private ByteArrayMarshaller() {
36
}
37
38
/**
39
* Copies the short value into two consecutive bytes of the byte array
40
* starting at the offset.
41
*
42
* @param value
43
* the short value to marshall
44
* @param byteArray
45
* destination
46
* @param offset
47
* offset in the byte array
48
* @param bigEndian
49
* if false the bytes will be copied in reverse (little endian)
50
* order
51
*
52
* @throws NullPointerException
53
* if <code>byteArray</code> is null
54
* @throws ArrayIndexOutOfBoundsException
55
* if an invalid array access occurs
56
*/
57
public static void writeShort(short value, byte[] byteArray, int offset,
58
boolean bigEndian) {
59
if ((offset + 2 > byteArray.length) || (offset < 0))
60
throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " +
61
"writeShort is trying to access byteArray[" + offset + "] and byteArray[" + (offset + 1) + "], " +
62
" but valid indices are from 0 to " + (byteArray.length - 1) + ".");
63
64
if (bigEndian)
65
{
66
writeShort_(value, byteArray, offset, true);
67
}
68
else
69
{
70
writeShort_(value, byteArray, offset, false);
71
}
72
}
73
74
private static void writeShort_(short value, byte[] byteArray, int offset,
75
boolean bigEndian)
76
{
77
if (bigEndian) {
78
byteArray[offset] = (byte) (value >> 8);
79
byteArray[offset + 1] = (byte) (value);
80
} else {
81
byteArray[offset + 1] = (byte) (value >> 8);
82
byteArray[offset] = (byte) (value);
83
}
84
}
85
86
87
/**
88
* Copies zero to two bytes of the short value into the byte array starting
89
* at the offset.
90
*
91
* @param value
92
* the short value to marshall
93
* @param byteArray
94
* destination
95
* @param offset
96
* offset in the byte array
97
* @param bigEndian
98
* if false the bytes will be copied in reverse (little endian)
99
* order
100
* @param numBytes
101
* the number of bytes to marshal, must be 0-2 inclusive
102
*
103
* @throws NullPointerException
104
* if <code>byteArray</code> is null
105
* @throws IllegalArgumentException
106
* if <code>numBytes &lt; 0</code> or
107
* <code>numBytes &gt; 2</code>
108
* @throws ArrayIndexOutOfBoundsException
109
* if an invalid array access occurs
110
*/
111
public static void writeShort(short value, byte[] byteArray, int offset,
112
boolean bigEndian, int numBytes) {
113
if ((offset + numBytes > byteArray.length) && (numBytes > 0) && (numBytes <= 2))
114
throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " +
115
"writeShort is trying to access byteArray[" + offset + "] to byteArray[" + (offset + numBytes - 1) + "]" +
116
" but valid indices are from 0 to " + (byteArray.length - 1) + ".");
117
if (offset < 0)
118
throw new ArrayIndexOutOfBoundsException("Access index must be positive or zero.");
119
120
if (numBytes < 0 || numBytes > 2)
121
throw new IllegalArgumentException("numBytes == " + numBytes);
122
123
if (bigEndian)
124
writeShort_(value, byteArray, offset, true, numBytes);
125
else
126
writeShort_(value, byteArray, offset, false, numBytes);
127
}
128
129
private static void writeShort_(short value, byte[] byteArray, int offset,
130
boolean bigEndian, int numBytes) {
131
int i = offset;
132
switch (numBytes) {
133
case 0:
134
break;
135
case 1:
136
byteArray[i] = (byte) value;
137
break;
138
case 2:
139
if (bigEndian) {
140
byteArray[i] = (byte) (value >> 8);
141
byteArray[i + 1] = (byte) (value);
142
} else {
143
byteArray[i + 1] = (byte) (value >> 8);
144
byteArray[i] = (byte) (value);
145
}
146
break;
147
}
148
}
149
150
/**
151
* Copies an int value into four consecutive bytes of the byte array
152
* starting at the offset.
153
*
154
* @param value
155
* the int value to marshall
156
* @param byteArray
157
* destination
158
* @param offset
159
* offset in the byte array
160
* @param bigEndian
161
* if false the bytes will be copied in reverse (little endian)
162
* order
163
*
164
* @throws NullPointerException
165
* if <code>byteArray</code> is null
166
* @throws ArrayIndexOutOfBoundsException
167
* if an invalid array access occurs
168
*/
169
public static void writeInt(int value, byte[] byteArray, int offset,
170
boolean bigEndian) {
171
if ((offset + 4 > byteArray.length) || (offset < 0))
172
throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " +
173
"writeInt is trying to access byteArray[" + offset + "] to byteArray[" + (offset + 3) + "], " +
174
" but valid indices are from 0 to " + (byteArray.length - 1) + ".");
175
176
if (bigEndian)
177
{
178
writeInt_(value, byteArray, offset, true);
179
}
180
else
181
{
182
writeInt_(value, byteArray, offset, false);
183
}
184
}
185
186
private static void writeInt_(int value, byte[] byteArray, int offset,
187
boolean bigEndian) {
188
if (bigEndian) {
189
byteArray[offset] = (byte) (value >> 24);
190
byteArray[offset + 1] = (byte) (value >> 16);
191
byteArray[offset + 2] = (byte) (value >> 8);
192
byteArray[offset + 3] = (byte) (value);
193
} else {
194
byteArray[offset + 3] = (byte) (value >> 24);
195
byteArray[offset + 2] = (byte) (value >> 16);
196
byteArray[offset + 1] = (byte) (value >> 8);
197
byteArray[offset] = (byte) (value);
198
}
199
}
200
201
/**
202
* Copies zero to four bytes of the int value into the byte array starting
203
* at the offset.
204
*
205
* @param value
206
* the int value to marshall
207
* @param byteArray
208
* destination
209
* @param offset
210
* offset in the byte array
211
* @param bigEndian
212
* if false the bytes will be copied in reverse (little endian)
213
* order
214
* @param numBytes
215
* the number of bytes to marshall, must be 0-4 inclusive
216
*
217
* @throws NullPointerException
218
* if byteArray is null
219
* @throws IllegalArgumentException
220
* if <code>numBytes &lt; 0</code> or
221
* <code>numBytes &gt; 4</code>
222
* @throws ArrayIndexOutOfBoundsException
223
* if an invalid array access occurs
224
*/
225
public static void writeInt(int value, byte[] byteArray, int offset,
226
boolean bigEndian, int numBytes) {
227
if ((offset + numBytes > byteArray.length) && (numBytes <= 4) && (numBytes > 0))
228
throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " +
229
"writeInt is trying to access byteArray[" + offset + "] to byteArray[" + (offset + numBytes - 1) + "]" +
230
" but valid indices are from 0 to " + (byteArray.length - 1) + ".");
231
if (offset < 0)
232
throw new ArrayIndexOutOfBoundsException("Access index must be positive or zero.");
233
if (numBytes < 0 || numBytes > 4)
234
throw new IllegalArgumentException("numBytes == " + numBytes);
235
236
if (bigEndian)
237
{
238
writeInt_(value, byteArray, offset, true, numBytes);
239
}
240
else
241
{
242
writeInt_(value, byteArray, offset, false, numBytes);
243
}
244
}
245
246
private static void writeInt_(int value, byte[] byteArray, int offset,
247
boolean bigEndian, int numBytes) {
248
int i = offset;
249
switch (numBytes) {
250
case 0:
251
break;
252
case 1:
253
byteArray[i] = (byte) value;
254
break;
255
case 2:
256
if (bigEndian) {
257
byteArray[i] = (byte) (value >> 8);
258
byteArray[i + 1] = (byte) (value);
259
} else {
260
byteArray[i + 1] = (byte) (value >> 8);
261
byteArray[i] = (byte) (value);
262
}
263
break;
264
case 3:
265
if (bigEndian) {
266
byteArray[i] = (byte) (value >> 16);
267
byteArray[i + 1] = (byte) (value >> 8);
268
byteArray[i + 2] = (byte) (value);
269
} else {
270
byteArray[i + 2] = (byte) (value >> 16);
271
byteArray[i + 1] = (byte) (value >> 8);
272
byteArray[i] = (byte) (value);
273
}
274
break;
275
case 4:
276
if (bigEndian) {
277
byteArray[i] = (byte) (value >> 24);
278
byteArray[i + 1] = (byte) (value >> 16);
279
byteArray[i + 2] = (byte) (value >> 8);
280
byteArray[i + 3] = (byte) (value);
281
} else {
282
byteArray[i + 3] = (byte) (value >> 24);
283
byteArray[i + 2] = (byte) (value >> 16);
284
byteArray[i + 1] = (byte) (value >> 8);
285
byteArray[i] = (byte) (value);
286
}
287
break;
288
}
289
}
290
291
/**
292
* Copies the long value into eight consecutive bytes of the byte array
293
* starting at the offset.
294
*
295
* @param value
296
* the long value to marshall
297
* @param byteArray
298
* destination
299
* @param offset
300
* offset in the byte array
301
* @param bigEndian
302
* if false the bytes will be copied in reverse (little endian)
303
* order
304
*
305
* @throws NullPointerException
306
* if <code>byteArray</code> is null
307
* @throws ArrayIndexOutOfBoundsException
308
* if an invalid array access occurs
309
*/
310
public static void writeLong(long value, byte[] byteArray, int offset,
311
boolean bigEndian) {
312
if ((offset + 8 > byteArray.length) || (offset < 0))
313
throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " +
314
"writeLong is trying to access byteArray[" + offset + "] to byteArray[" + (offset + 7) + "], " +
315
" but valid indices are from 0 to " + (byteArray.length - 1) + ".");
316
317
if (bigEndian)
318
{
319
writeLong_(value, byteArray, offset, true);
320
}
321
else
322
{
323
writeLong_(value, byteArray, offset, false);
324
}
325
}
326
327
private static void writeLong_(long value, byte[] byteArray, int offset,
328
boolean bigEndian) {
329
if (bigEndian) {
330
byteArray[offset] = (byte) (value >> 56);
331
byteArray[offset + 1] = (byte) (value >> 48);
332
byteArray[offset + 2] = (byte) (value >> 40);
333
byteArray[offset + 3] = (byte) (value >> 32);
334
byteArray[offset + 4] = (byte) (value >> 24);
335
byteArray[offset + 5] = (byte) (value >> 16);
336
byteArray[offset + 6] = (byte) (value >> 8);
337
byteArray[offset + 7] = (byte) (value);
338
} else {
339
byteArray[offset + 7] = (byte) (value >> 56);
340
byteArray[offset + 6] = (byte) (value >> 48);
341
byteArray[offset + 5] = (byte) (value >> 40);
342
byteArray[offset + 4] = (byte) (value >> 32);
343
byteArray[offset + 3] = (byte) (value >> 24);
344
byteArray[offset + 2] = (byte) (value >> 16);
345
byteArray[offset + 1] = (byte) (value >> 8);
346
byteArray[offset] = (byte) (value);
347
}
348
}
349
350
/**
351
* Copies zero to eight bytes of the long value into the byte array starting
352
* at the offset.
353
*
354
* @param value
355
* the long value to marshall
356
* @param byteArray
357
* destination
358
* @param offset
359
* offset in the byte array
360
* @param bigEndian
361
* if false the bytes will be copied in reverse (little endian)
362
* order
363
* @param numBytes
364
* the number of bytes to marshal, must be 0-8 inclusive
365
*
366
* @throws NullPointerException
367
* if <code>byteArray</code> is null
368
* @throws IllegalArgumentException
369
* if <code>numBytes &lt; 0</code> or
370
* <code>numBytes &gt; 8</code>
371
* @throws ArrayIndexOutOfBoundsException
372
* if an invalid array access occurs
373
*/
374
public static void writeLong(long value, byte[] byteArray, int offset,
375
boolean bigEndian, int numBytes) {
376
if ((offset + numBytes > byteArray.length) && (numBytes > 0) && (numBytes <=8))
377
throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " +
378
"writeLong is trying to access byteArray[" + offset + "] to byteArray[" + (offset + numBytes - 1) + "]" +
379
" but valid indices are from 0 to " + (byteArray.length - 1) + ".");
380
if (offset < 0)
381
throw new ArrayIndexOutOfBoundsException("Access index must be positive or zero.");
382
383
if (numBytes < 0 || numBytes > 8)
384
throw new IllegalArgumentException("numBytes == " + numBytes);
385
386
if (bigEndian)
387
writeLong_(value, byteArray, offset, true, numBytes);
388
else
389
writeLong_(value, byteArray, offset, false, numBytes);
390
}
391
392
private static void writeLong_(long value, byte[] byteArray, int offset,
393
boolean bigEndian, int numBytes) {
394
int i = offset;
395
switch (numBytes) {
396
case 0:
397
break;
398
case 1:
399
byteArray[i] = (byte) value;
400
break;
401
case 2:
402
if (bigEndian) {
403
byteArray[i] = (byte) (value >> 8);
404
byteArray[i + 1] = (byte) (value);
405
} else {
406
byteArray[i + 1] = (byte) (value >> 8);
407
byteArray[i] = (byte) (value);
408
}
409
break;
410
case 3:
411
if (bigEndian) {
412
byteArray[i] = (byte) (value >> 16);
413
byteArray[i + 1] = (byte) (value >> 8);
414
byteArray[i + 2] = (byte) (value);
415
} else {
416
byteArray[i + 2] = (byte) (value >> 16);
417
byteArray[i + 1] = (byte) (value >> 8);
418
byteArray[i] = (byte) (value);
419
}
420
break;
421
case 4:
422
if (bigEndian) {
423
byteArray[i] = (byte) (value >> 24);
424
byteArray[i + 1] = (byte) (value >> 16);
425
byteArray[i + 2] = (byte) (value >> 8);
426
byteArray[i + 3] = (byte) (value);
427
} else {
428
byteArray[i + 3] = (byte) (value >> 24);
429
byteArray[i + 2] = (byte) (value >> 16);
430
byteArray[i + 1] = (byte) (value >> 8);
431
byteArray[i] = (byte) (value);
432
}
433
break;
434
case 5:
435
if (bigEndian) {
436
byteArray[i] = (byte) (value >> 32);
437
byteArray[i + 1] = (byte) (value >> 24);
438
byteArray[i + 2] = (byte) (value >> 16);
439
byteArray[i + 3] = (byte) (value >> 8);
440
byteArray[i + 4] = (byte) (value);
441
} else {
442
byteArray[i + 4] = (byte) (value >> 32);
443
byteArray[i + 3] = (byte) (value >> 24);
444
byteArray[i + 2] = (byte) (value >> 16);
445
byteArray[i + 1] = (byte) (value >> 8);
446
byteArray[i] = (byte) (value);
447
}
448
break;
449
case 6:
450
if (bigEndian) {
451
byteArray[i] = (byte) (value >> 40);
452
byteArray[i + 1] = (byte) (value >> 32);
453
byteArray[i + 2] = (byte) (value >> 24);
454
byteArray[i + 3] = (byte) (value >> 16);
455
byteArray[i + 4] = (byte) (value >> 8);
456
byteArray[i + 5] = (byte) (value);
457
} else {
458
byteArray[i + 5] = (byte) (value >> 40);
459
byteArray[i + 4] = (byte) (value >> 32);
460
byteArray[i + 3] = (byte) (value >> 24);
461
byteArray[i + 2] = (byte) (value >> 16);
462
byteArray[i + 1] = (byte) (value >> 8);
463
byteArray[i] = (byte) (value);
464
}
465
break;
466
case 7:
467
if (bigEndian) {
468
byteArray[i] = (byte) (value >> 48);
469
byteArray[i + 1] = (byte) (value >> 40);
470
byteArray[i + 2] = (byte) (value >> 32);
471
byteArray[i + 3] = (byte) (value >> 24);
472
byteArray[i + 4] = (byte) (value >> 16);
473
byteArray[i + 5] = (byte) (value >> 8);
474
byteArray[i + 6] = (byte) (value);
475
} else {
476
byteArray[i + 6] = (byte) (value >> 48);
477
byteArray[i + 5] = (byte) (value >> 40);
478
byteArray[i + 4] = (byte) (value >> 32);
479
byteArray[i + 3] = (byte) (value >> 24);
480
byteArray[i + 2] = (byte) (value >> 16);
481
byteArray[i + 1] = (byte) (value >> 8);
482
byteArray[i] = (byte) (value);
483
}
484
break;
485
case 8:
486
if (bigEndian) {
487
byteArray[i] = (byte) (value >> 56);
488
byteArray[i + 1] = (byte) (value >> 48);
489
byteArray[i + 2] = (byte) (value >> 40);
490
byteArray[i + 3] = (byte) (value >> 32);
491
byteArray[i + 4] = (byte) (value >> 24);
492
byteArray[i + 5] = (byte) (value >> 16);
493
byteArray[i + 6] = (byte) (value >> 8);
494
byteArray[i + 7] = (byte) (value);
495
} else {
496
byteArray[i + 7] = (byte) (value >> 56);
497
byteArray[i + 6] = (byte) (value >> 48);
498
byteArray[i + 5] = (byte) (value >> 40);
499
byteArray[i + 4] = (byte) (value >> 32);
500
byteArray[i + 3] = (byte) (value >> 24);
501
byteArray[i + 2] = (byte) (value >> 16);
502
byteArray[i + 1] = (byte) (value >> 8);
503
byteArray[i] = (byte) (value);
504
}
505
break;
506
}
507
508
}
509
510
/**
511
* Copies the float value into four consecutive bytes of the byte array
512
* starting at the offset.
513
*
514
* @param value
515
* the float value to marshall
516
* @param byteArray
517
* destination
518
* @param offset
519
* offset in the byte array
520
* @param bigEndian
521
* if false the bytes will be copied in reverse (little endian)
522
* order
523
*
524
* @throws NullPointerException
525
* if <code>byteArray</code> is null
526
* @throws ArrayIndexOutOfBoundsException
527
* if an invalid array access occurs
528
*/
529
public static void writeFloat(float value, byte[] byteArray, int offset,
530
boolean bigEndian) {
531
if ((offset + 4 > byteArray.length) || (offset < 0))
532
throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " +
533
"writeFloat is trying to access byteArray[" + offset + "] to byteArray[" + (offset + 3) + "], " +
534
" but valid indices are from 0 to " + (byteArray.length - 1) + ".");
535
if (bigEndian)
536
writeFloat_(value, byteArray, offset, true);
537
else
538
writeFloat_(value, byteArray, offset, false);
539
}
540
541
private static void writeFloat_(float value, byte[] byteArray, int offset,
542
boolean bigEndian) {
543
writeInt(Float.floatToIntBits(value), byteArray, offset, bigEndian);
544
}
545
546
/**
547
* Copies the double value into eight consecutive bytes of the byte array
548
* starting at the offset.
549
*
550
* @param value
551
* the double value to marshall
552
* @param byteArray
553
* destination
554
* @param offset
555
* offset in the byte array
556
* @param bigEndian
557
* if false the bytes will be copied in reverse (little endian)
558
* order
559
*
560
* @throws NullPointerException
561
* if <code>byteArray</code> is null
562
* @throws ArrayIndexOutOfBoundsException
563
* if an invalid array access occurs
564
*/
565
public static void writeDouble(double value, byte[] byteArray, int offset,
566
boolean bigEndian) {
567
if ((offset + 8 > byteArray.length) || (offset < 0))
568
throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " +
569
"writeDouble is trying to access byteArray[" + offset + "] to byteArray[" + (offset + 7) + "], " +
570
" but valid indices are from 0 to " + (byteArray.length - 1) + ".");
571
572
if (bigEndian)
573
writeDouble_(value, byteArray, offset, true);
574
else
575
writeDouble_(value, byteArray, offset, false);
576
}
577
578
private static void writeDouble_(double value, byte[] byteArray, int offset,
579
boolean bigEndian) {
580
writeLong(Double.doubleToLongBits(value), byteArray, offset, bigEndian);
581
}
582
583
}
584
585