Path: blob/master/jcl/src/openj9.dataaccess/share/classes/com/ibm/dataaccess/ByteArrayMarshaller.java
12558 views
/*[INCLUDE-IF DAA]*/1/*******************************************************************************2* Copyright (c) 2013, 2015 IBM Corp. and others3*4* This program and the accompanying materials are made available under5* the terms of the Eclipse Public License 2.0 which accompanies this6* distribution and is available at https://www.eclipse.org/legal/epl-2.0/7* or the Apache License, Version 2.0 which accompanies this distribution and8* is available at https://www.apache.org/licenses/LICENSE-2.0.9*10* This Source Code may also be made available under the following11* Secondary Licenses when the conditions for such availability set12* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU13* General Public License, version 2 with the GNU Classpath14* Exception [1] and GNU General Public License, version 2 with the15* OpenJDK Assembly Exception [2].16*17* [1] https://www.gnu.org/software/classpath/license.html18* [2] http://openjdk.java.net/legal/assembly-exception.html19*20* 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-exception21*******************************************************************************/2223package com.ibm.dataaccess;2425/**26* Conversion routines to marshall Java binary types (short, int, long, float,27* double) to byte arrays.28*29* @author IBM30* @version $Revision$ on $Date$31*/32public class ByteArrayMarshaller {3334private ByteArrayMarshaller() {35}3637/**38* Copies the short value into two consecutive bytes of the byte array39* starting at the offset.40*41* @param value42* the short value to marshall43* @param byteArray44* destination45* @param offset46* offset in the byte array47* @param bigEndian48* if false the bytes will be copied in reverse (little endian)49* order50*51* @throws NullPointerException52* if <code>byteArray</code> is null53* @throws ArrayIndexOutOfBoundsException54* if an invalid array access occurs55*/56public static void writeShort(short value, byte[] byteArray, int offset,57boolean bigEndian) {58if ((offset + 2 > byteArray.length) || (offset < 0))59throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " +60"writeShort is trying to access byteArray[" + offset + "] and byteArray[" + (offset + 1) + "], " +61" but valid indices are from 0 to " + (byteArray.length - 1) + ".");6263if (bigEndian)64{65writeShort_(value, byteArray, offset, true);66}67else68{69writeShort_(value, byteArray, offset, false);70}71}7273private static void writeShort_(short value, byte[] byteArray, int offset,74boolean bigEndian)75{76if (bigEndian) {77byteArray[offset] = (byte) (value >> 8);78byteArray[offset + 1] = (byte) (value);79} else {80byteArray[offset + 1] = (byte) (value >> 8);81byteArray[offset] = (byte) (value);82}83}848586/**87* Copies zero to two bytes of the short value into the byte array starting88* at the offset.89*90* @param value91* the short value to marshall92* @param byteArray93* destination94* @param offset95* offset in the byte array96* @param bigEndian97* if false the bytes will be copied in reverse (little endian)98* order99* @param numBytes100* the number of bytes to marshal, must be 0-2 inclusive101*102* @throws NullPointerException103* if <code>byteArray</code> is null104* @throws IllegalArgumentException105* if <code>numBytes < 0</code> or106* <code>numBytes > 2</code>107* @throws ArrayIndexOutOfBoundsException108* if an invalid array access occurs109*/110public static void writeShort(short value, byte[] byteArray, int offset,111boolean bigEndian, int numBytes) {112if ((offset + numBytes > byteArray.length) && (numBytes > 0) && (numBytes <= 2))113throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " +114"writeShort is trying to access byteArray[" + offset + "] to byteArray[" + (offset + numBytes - 1) + "]" +115" but valid indices are from 0 to " + (byteArray.length - 1) + ".");116if (offset < 0)117throw new ArrayIndexOutOfBoundsException("Access index must be positive or zero.");118119if (numBytes < 0 || numBytes > 2)120throw new IllegalArgumentException("numBytes == " + numBytes);121122if (bigEndian)123writeShort_(value, byteArray, offset, true, numBytes);124else125writeShort_(value, byteArray, offset, false, numBytes);126}127128private static void writeShort_(short value, byte[] byteArray, int offset,129boolean bigEndian, int numBytes) {130int i = offset;131switch (numBytes) {132case 0:133break;134case 1:135byteArray[i] = (byte) value;136break;137case 2:138if (bigEndian) {139byteArray[i] = (byte) (value >> 8);140byteArray[i + 1] = (byte) (value);141} else {142byteArray[i + 1] = (byte) (value >> 8);143byteArray[i] = (byte) (value);144}145break;146}147}148149/**150* Copies an int value into four consecutive bytes of the byte array151* starting at the offset.152*153* @param value154* the int value to marshall155* @param byteArray156* destination157* @param offset158* offset in the byte array159* @param bigEndian160* if false the bytes will be copied in reverse (little endian)161* order162*163* @throws NullPointerException164* if <code>byteArray</code> is null165* @throws ArrayIndexOutOfBoundsException166* if an invalid array access occurs167*/168public static void writeInt(int value, byte[] byteArray, int offset,169boolean bigEndian) {170if ((offset + 4 > byteArray.length) || (offset < 0))171throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " +172"writeInt is trying to access byteArray[" + offset + "] to byteArray[" + (offset + 3) + "], " +173" but valid indices are from 0 to " + (byteArray.length - 1) + ".");174175if (bigEndian)176{177writeInt_(value, byteArray, offset, true);178}179else180{181writeInt_(value, byteArray, offset, false);182}183}184185private static void writeInt_(int value, byte[] byteArray, int offset,186boolean bigEndian) {187if (bigEndian) {188byteArray[offset] = (byte) (value >> 24);189byteArray[offset + 1] = (byte) (value >> 16);190byteArray[offset + 2] = (byte) (value >> 8);191byteArray[offset + 3] = (byte) (value);192} else {193byteArray[offset + 3] = (byte) (value >> 24);194byteArray[offset + 2] = (byte) (value >> 16);195byteArray[offset + 1] = (byte) (value >> 8);196byteArray[offset] = (byte) (value);197}198}199200/**201* Copies zero to four bytes of the int value into the byte array starting202* at the offset.203*204* @param value205* the int value to marshall206* @param byteArray207* destination208* @param offset209* offset in the byte array210* @param bigEndian211* if false the bytes will be copied in reverse (little endian)212* order213* @param numBytes214* the number of bytes to marshall, must be 0-4 inclusive215*216* @throws NullPointerException217* if byteArray is null218* @throws IllegalArgumentException219* if <code>numBytes < 0</code> or220* <code>numBytes > 4</code>221* @throws ArrayIndexOutOfBoundsException222* if an invalid array access occurs223*/224public static void writeInt(int value, byte[] byteArray, int offset,225boolean bigEndian, int numBytes) {226if ((offset + numBytes > byteArray.length) && (numBytes <= 4) && (numBytes > 0))227throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " +228"writeInt is trying to access byteArray[" + offset + "] to byteArray[" + (offset + numBytes - 1) + "]" +229" but valid indices are from 0 to " + (byteArray.length - 1) + ".");230if (offset < 0)231throw new ArrayIndexOutOfBoundsException("Access index must be positive or zero.");232if (numBytes < 0 || numBytes > 4)233throw new IllegalArgumentException("numBytes == " + numBytes);234235if (bigEndian)236{237writeInt_(value, byteArray, offset, true, numBytes);238}239else240{241writeInt_(value, byteArray, offset, false, numBytes);242}243}244245private static void writeInt_(int value, byte[] byteArray, int offset,246boolean bigEndian, int numBytes) {247int i = offset;248switch (numBytes) {249case 0:250break;251case 1:252byteArray[i] = (byte) value;253break;254case 2:255if (bigEndian) {256byteArray[i] = (byte) (value >> 8);257byteArray[i + 1] = (byte) (value);258} else {259byteArray[i + 1] = (byte) (value >> 8);260byteArray[i] = (byte) (value);261}262break;263case 3:264if (bigEndian) {265byteArray[i] = (byte) (value >> 16);266byteArray[i + 1] = (byte) (value >> 8);267byteArray[i + 2] = (byte) (value);268} else {269byteArray[i + 2] = (byte) (value >> 16);270byteArray[i + 1] = (byte) (value >> 8);271byteArray[i] = (byte) (value);272}273break;274case 4:275if (bigEndian) {276byteArray[i] = (byte) (value >> 24);277byteArray[i + 1] = (byte) (value >> 16);278byteArray[i + 2] = (byte) (value >> 8);279byteArray[i + 3] = (byte) (value);280} else {281byteArray[i + 3] = (byte) (value >> 24);282byteArray[i + 2] = (byte) (value >> 16);283byteArray[i + 1] = (byte) (value >> 8);284byteArray[i] = (byte) (value);285}286break;287}288}289290/**291* Copies the long value into eight consecutive bytes of the byte array292* starting at the offset.293*294* @param value295* the long value to marshall296* @param byteArray297* destination298* @param offset299* offset in the byte array300* @param bigEndian301* if false the bytes will be copied in reverse (little endian)302* order303*304* @throws NullPointerException305* if <code>byteArray</code> is null306* @throws ArrayIndexOutOfBoundsException307* if an invalid array access occurs308*/309public static void writeLong(long value, byte[] byteArray, int offset,310boolean bigEndian) {311if ((offset + 8 > byteArray.length) || (offset < 0))312throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " +313"writeLong is trying to access byteArray[" + offset + "] to byteArray[" + (offset + 7) + "], " +314" but valid indices are from 0 to " + (byteArray.length - 1) + ".");315316if (bigEndian)317{318writeLong_(value, byteArray, offset, true);319}320else321{322writeLong_(value, byteArray, offset, false);323}324}325326private static void writeLong_(long value, byte[] byteArray, int offset,327boolean bigEndian) {328if (bigEndian) {329byteArray[offset] = (byte) (value >> 56);330byteArray[offset + 1] = (byte) (value >> 48);331byteArray[offset + 2] = (byte) (value >> 40);332byteArray[offset + 3] = (byte) (value >> 32);333byteArray[offset + 4] = (byte) (value >> 24);334byteArray[offset + 5] = (byte) (value >> 16);335byteArray[offset + 6] = (byte) (value >> 8);336byteArray[offset + 7] = (byte) (value);337} else {338byteArray[offset + 7] = (byte) (value >> 56);339byteArray[offset + 6] = (byte) (value >> 48);340byteArray[offset + 5] = (byte) (value >> 40);341byteArray[offset + 4] = (byte) (value >> 32);342byteArray[offset + 3] = (byte) (value >> 24);343byteArray[offset + 2] = (byte) (value >> 16);344byteArray[offset + 1] = (byte) (value >> 8);345byteArray[offset] = (byte) (value);346}347}348349/**350* Copies zero to eight bytes of the long value into the byte array starting351* at the offset.352*353* @param value354* the long value to marshall355* @param byteArray356* destination357* @param offset358* offset in the byte array359* @param bigEndian360* if false the bytes will be copied in reverse (little endian)361* order362* @param numBytes363* the number of bytes to marshal, must be 0-8 inclusive364*365* @throws NullPointerException366* if <code>byteArray</code> is null367* @throws IllegalArgumentException368* if <code>numBytes < 0</code> or369* <code>numBytes > 8</code>370* @throws ArrayIndexOutOfBoundsException371* if an invalid array access occurs372*/373public static void writeLong(long value, byte[] byteArray, int offset,374boolean bigEndian, int numBytes) {375if ((offset + numBytes > byteArray.length) && (numBytes > 0) && (numBytes <=8))376throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " +377"writeLong is trying to access byteArray[" + offset + "] to byteArray[" + (offset + numBytes - 1) + "]" +378" but valid indices are from 0 to " + (byteArray.length - 1) + ".");379if (offset < 0)380throw new ArrayIndexOutOfBoundsException("Access index must be positive or zero.");381382if (numBytes < 0 || numBytes > 8)383throw new IllegalArgumentException("numBytes == " + numBytes);384385if (bigEndian)386writeLong_(value, byteArray, offset, true, numBytes);387else388writeLong_(value, byteArray, offset, false, numBytes);389}390391private static void writeLong_(long value, byte[] byteArray, int offset,392boolean bigEndian, int numBytes) {393int i = offset;394switch (numBytes) {395case 0:396break;397case 1:398byteArray[i] = (byte) value;399break;400case 2:401if (bigEndian) {402byteArray[i] = (byte) (value >> 8);403byteArray[i + 1] = (byte) (value);404} else {405byteArray[i + 1] = (byte) (value >> 8);406byteArray[i] = (byte) (value);407}408break;409case 3:410if (bigEndian) {411byteArray[i] = (byte) (value >> 16);412byteArray[i + 1] = (byte) (value >> 8);413byteArray[i + 2] = (byte) (value);414} else {415byteArray[i + 2] = (byte) (value >> 16);416byteArray[i + 1] = (byte) (value >> 8);417byteArray[i] = (byte) (value);418}419break;420case 4:421if (bigEndian) {422byteArray[i] = (byte) (value >> 24);423byteArray[i + 1] = (byte) (value >> 16);424byteArray[i + 2] = (byte) (value >> 8);425byteArray[i + 3] = (byte) (value);426} else {427byteArray[i + 3] = (byte) (value >> 24);428byteArray[i + 2] = (byte) (value >> 16);429byteArray[i + 1] = (byte) (value >> 8);430byteArray[i] = (byte) (value);431}432break;433case 5:434if (bigEndian) {435byteArray[i] = (byte) (value >> 32);436byteArray[i + 1] = (byte) (value >> 24);437byteArray[i + 2] = (byte) (value >> 16);438byteArray[i + 3] = (byte) (value >> 8);439byteArray[i + 4] = (byte) (value);440} else {441byteArray[i + 4] = (byte) (value >> 32);442byteArray[i + 3] = (byte) (value >> 24);443byteArray[i + 2] = (byte) (value >> 16);444byteArray[i + 1] = (byte) (value >> 8);445byteArray[i] = (byte) (value);446}447break;448case 6:449if (bigEndian) {450byteArray[i] = (byte) (value >> 40);451byteArray[i + 1] = (byte) (value >> 32);452byteArray[i + 2] = (byte) (value >> 24);453byteArray[i + 3] = (byte) (value >> 16);454byteArray[i + 4] = (byte) (value >> 8);455byteArray[i + 5] = (byte) (value);456} else {457byteArray[i + 5] = (byte) (value >> 40);458byteArray[i + 4] = (byte) (value >> 32);459byteArray[i + 3] = (byte) (value >> 24);460byteArray[i + 2] = (byte) (value >> 16);461byteArray[i + 1] = (byte) (value >> 8);462byteArray[i] = (byte) (value);463}464break;465case 7:466if (bigEndian) {467byteArray[i] = (byte) (value >> 48);468byteArray[i + 1] = (byte) (value >> 40);469byteArray[i + 2] = (byte) (value >> 32);470byteArray[i + 3] = (byte) (value >> 24);471byteArray[i + 4] = (byte) (value >> 16);472byteArray[i + 5] = (byte) (value >> 8);473byteArray[i + 6] = (byte) (value);474} else {475byteArray[i + 6] = (byte) (value >> 48);476byteArray[i + 5] = (byte) (value >> 40);477byteArray[i + 4] = (byte) (value >> 32);478byteArray[i + 3] = (byte) (value >> 24);479byteArray[i + 2] = (byte) (value >> 16);480byteArray[i + 1] = (byte) (value >> 8);481byteArray[i] = (byte) (value);482}483break;484case 8:485if (bigEndian) {486byteArray[i] = (byte) (value >> 56);487byteArray[i + 1] = (byte) (value >> 48);488byteArray[i + 2] = (byte) (value >> 40);489byteArray[i + 3] = (byte) (value >> 32);490byteArray[i + 4] = (byte) (value >> 24);491byteArray[i + 5] = (byte) (value >> 16);492byteArray[i + 6] = (byte) (value >> 8);493byteArray[i + 7] = (byte) (value);494} else {495byteArray[i + 7] = (byte) (value >> 56);496byteArray[i + 6] = (byte) (value >> 48);497byteArray[i + 5] = (byte) (value >> 40);498byteArray[i + 4] = (byte) (value >> 32);499byteArray[i + 3] = (byte) (value >> 24);500byteArray[i + 2] = (byte) (value >> 16);501byteArray[i + 1] = (byte) (value >> 8);502byteArray[i] = (byte) (value);503}504break;505}506507}508509/**510* Copies the float value into four consecutive bytes of the byte array511* starting at the offset.512*513* @param value514* the float value to marshall515* @param byteArray516* destination517* @param offset518* offset in the byte array519* @param bigEndian520* if false the bytes will be copied in reverse (little endian)521* order522*523* @throws NullPointerException524* if <code>byteArray</code> is null525* @throws ArrayIndexOutOfBoundsException526* if an invalid array access occurs527*/528public static void writeFloat(float value, byte[] byteArray, int offset,529boolean bigEndian) {530if ((offset + 4 > byteArray.length) || (offset < 0))531throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " +532"writeFloat is trying to access byteArray[" + offset + "] to byteArray[" + (offset + 3) + "], " +533" but valid indices are from 0 to " + (byteArray.length - 1) + ".");534if (bigEndian)535writeFloat_(value, byteArray, offset, true);536else537writeFloat_(value, byteArray, offset, false);538}539540private static void writeFloat_(float value, byte[] byteArray, int offset,541boolean bigEndian) {542writeInt(Float.floatToIntBits(value), byteArray, offset, bigEndian);543}544545/**546* Copies the double value into eight consecutive bytes of the byte array547* starting at the offset.548*549* @param value550* the double value to marshall551* @param byteArray552* destination553* @param offset554* offset in the byte array555* @param bigEndian556* if false the bytes will be copied in reverse (little endian)557* order558*559* @throws NullPointerException560* if <code>byteArray</code> is null561* @throws ArrayIndexOutOfBoundsException562* if an invalid array access occurs563*/564public static void writeDouble(double value, byte[] byteArray, int offset,565boolean bigEndian) {566if ((offset + 8 > byteArray.length) || (offset < 0))567throw new ArrayIndexOutOfBoundsException("Array access index out of bounds. " +568"writeDouble is trying to access byteArray[" + offset + "] to byteArray[" + (offset + 7) + "], " +569" but valid indices are from 0 to " + (byteArray.length - 1) + ".");570571if (bigEndian)572writeDouble_(value, byteArray, offset, true);573else574writeDouble_(value, byteArray, offset, false);575}576577private static void writeDouble_(double value, byte[] byteArray, int offset,578boolean bigEndian) {579writeLong(Double.doubleToLongBits(value), byteArray, offset, bigEndian);580}581582}583584585