All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.com.ibm.as400.access.BinaryConverter Maven / Gradle / Ivy

There is a newer version: 11.1
Show newest version
///////////////////////////////////////////////////////////////////////////////
//                                                                             
// JTOpen (IBM Toolbox for Java - OSS version)                              
//                                                                             
// Filename: BinaryConverter.java
//                                                                             
// The source code contained herein is licensed under the IBM Public License   
// Version 1.0, which has been approved by the Open Source Initiative.         
// Copyright (C) 1997-2003 International Business Machines Corporation and     
// others. All rights reserved.                                                
//                                                                             
///////////////////////////////////////////////////////////////////////////////

package com.ibm.as400.access;

/**
 A binary types converter between Java byte arrays and Java simple types.
 

Note: Some methods of this class accept an array-valued argument in addition to arguments that specify an array offset and possibly also a length. All such methods will throw an {@link ArrayIndexOutOfBoundsException ArrayIndexOutOfBoundsException} if the offset and/or length are not valid for the array. **/ public class BinaryConverter { // Don't allow instances of this class. private BinaryConverter() { } /** Convert the specified short into IBM i format in the specified byte array. The converted value will occupy 2 bytes. @param shortValue The value to be converted to IBM i format. @param serverValue The array to receive the data type in IBM i format. @param offset The offset into the byte array for the start of the IBM i value. **/ public static void shortToByteArray(short shortValue, byte[] serverValue, int offset) { if (serverValue == null) throw new NullPointerException("serverValue"); serverValue[offset] = (byte)(shortValue >>> 8); serverValue[offset+1] = (byte) shortValue; } /** Convert the specified short into IBM i format in a byte array. @param shortValue The value to be converted to IBM i format. @return An array (of length 2) with the data type in IBM i format. **/ public static byte[] shortToByteArray(short shortValue) { byte[] serverValue = new byte[2]; shortToByteArray(shortValue, serverValue, 0); return serverValue; } /** Convert the specified IBM i data type to a short. @param serverValue The array containing the data type in IBM i format. @param offset The offset into the byte array for the start of the IBM i value. @return a short corresponding to the data type. **/ public static short byteArrayToShort(byte[] serverValue, int offset) { checkArgs(serverValue, offset); return(short)(((serverValue[offset] & 0xFF) << 8) + (serverValue[offset+1] & 0xFF)); } /** Convert the specified int into IBM i format in the specified byte array. The converted value will occupy 4 bytes. @param intValue The value to be converted to IBM i format. @param serverValue The array to receive the data type in IBM i format. @param offset The offset into the byte array for the start of the IBM i value. **/ public static void intToByteArray(int intValue, byte[] serverValue, int offset) { checkArgs(serverValue, offset); serverValue[offset] = (byte)(intValue >>> 24); serverValue[offset+1] = (byte)(intValue >>> 16); serverValue[offset+2] = (byte)(intValue >>> 8); serverValue[offset+3] = (byte) intValue; } /** Convert the specified int into IBM i format in a byte array. @param intValue The value to be converted to IBM i format. @return An array (of length 4) with the data type in IBM i format. **/ public static byte[] intToByteArray(int intValue) { byte[] serverValue = new byte[4]; intToByteArray(intValue, serverValue, 0); return serverValue; } /** Convert the specified IBM i data type to an int. @param serverValue The array containing the data type in IBM i format. @param offset The offset into the byte array for the start of the IBM i value. @return an int corresponding to the data type. **/ public static int byteArrayToInt(byte[] serverValue, int offset) { checkArgs(serverValue, offset); return((serverValue[offset] & 0xFF) << 24) + ((serverValue[offset+1] & 0xFF) << 16) + ((serverValue[offset+2] & 0xFF) << 8) + (serverValue[offset+3] & 0xFF); } /** Convert the specified float into IBM i format in the specified byte array. The converted value will occupy 4 bytes. @param floatValue The value to be converted to IBM i format. @param serverValue The array to receive the data type in IBM i format. @param offset The offset into the byte array for the start of the IBM i value. **/ public static void floatToByteArray(float floatValue, byte[] serverValue, int offset) { checkArgs(serverValue, offset); int bits = Float.floatToIntBits(floatValue); serverValue[offset] = (byte)(bits >>> 24); serverValue[offset+1] = (byte)(bits >>> 16); serverValue[offset+2] = (byte)(bits >>> 8); serverValue[offset+3] = (byte) bits; } /** Convert the specified float into IBM i format in a byte array. @param floatValue The value to be converted to IBM i format. @return An array (of length 4) with the data type in IBM i format. @deprecated Use floatToByteArray(float) instead. **/ public static byte[] floatToByteArray(int floatValue) { byte[] serverValue = new byte[4]; floatToByteArray(floatValue, serverValue, 0); return serverValue; } /** Convert the specified float into IBM i format in a byte array. @param floatValue The value to be converted to IBM i format. @return An array (of length 4) with the data type in IBM i format. **/ public static byte[] floatToByteArray(float floatValue) { byte[] serverValue = new byte[4]; floatToByteArray(floatValue, serverValue, 0); return serverValue; } /** Convert the specified IBM i data type to a float. @param serverValue The array containing the data type in IBM i format. @param offset The offset into the byte array for the start of the IBM i value. @return a float corresponding to the data type. **/ public static float byteArrayToFloat(byte[] serverValue, int offset) { checkArgs(serverValue, offset); int bits = ((serverValue[offset] & 0xFF) << 24) + ((serverValue[offset+1] & 0xFF) << 16) + ((serverValue[offset+2] & 0xFF) << 8) + (serverValue[offset+3] & 0xFF); return Float.intBitsToFloat(bits); } /** Convert the specified double into IBM i format in the specified byte array. The converted value will occupy 8 bytes. @param doubleValue The value to be converted to IBM i format. @param serverValue The array to receive the data type in IBM i format. @param offset The offset into the byte array for the start of the IBM i value. **/ public static void doubleToByteArray(double doubleValue, byte[] serverValue, int offset) { checkArgs(serverValue, offset); long bits = Double.doubleToLongBits(doubleValue); // Do in two parts to avoid long temps. int high = (int)(bits >>> 32); int low = (int)bits; serverValue[offset] = (byte)(high >>> 24); serverValue[offset+1] = (byte)(high >>> 16); serverValue[offset+2] = (byte)(high >>> 8); serverValue[offset+3] = (byte) high; serverValue[offset+4] = (byte)(low >>> 24); serverValue[offset+5] = (byte)(low >>> 16); serverValue[offset+6] = (byte)(low >>> 8); serverValue[offset+7] = (byte) low; } /** Convert the specified double into IBM i format in a byte array. @param doubleValue The value to be converted to IBM i format. @return An array (of length 8) with the data type in IBM i format. **/ public static byte[] doubleToByteArray(double doubleValue) { byte[] serverValue = new byte[8]; doubleToByteArray(doubleValue, serverValue, 0); return serverValue; } /** Convert the specified IBM i data type to a double. @param serverValue The array containing the data type in IBM i format. @param offset The offset into the byte array for the start of the IBM i value. @return a double corresponding to the data type. **/ public static double byteArrayToDouble(byte[] serverValue, int offset) { checkArgs(serverValue, offset); // Do in two parts to avoid long temps. int firstPart = ((serverValue[offset] & 0xFF) << 24) + ((serverValue[offset+1] & 0xFF) << 16) + ((serverValue[offset+2] & 0xFF) << 8) + (serverValue[offset+3] & 0xFF); int secondPart = ((serverValue[offset+4] & 0xFF) << 24) + ((serverValue[offset+5] & 0xFF) << 16) + ((serverValue[offset+6] & 0xFF) << 8) + (serverValue[offset+7] & 0xFF); long bits = ((long)firstPart << 32) + (secondPart & 0xFFFFFFFFL); return Double.longBitsToDouble(bits); } /** Convert the specified int into IBM i format in the specified byte array. The converted value will occupy 2 bytes. @param intValue The value to be converted to IBM i format. The integer should be greater than or equal to zero and representable in two bytes. @param serverValue The array to receive the data type in IBM i format. @param offset The offset into the byte array for the start of the IBM i value. **/ public static void unsignedShortToByteArray(int intValue, byte[] serverValue, int offset) { checkArgs(serverValue, offset); serverValue[offset] = (byte)(intValue >>> 8); serverValue[offset+1] = (byte) intValue; } /** Convert the specified int into IBM i format in a byte array. @param intValue The value to be converted to IBM i format. The integer should be greater than or equal to zero and representable in two bytes. @return An array (of length 2) with the data type in IBM i format. **/ public static byte[] unsignedShortToByteArray(int intValue) { byte[] serverValue = new byte[2]; unsignedShortToByteArray(intValue, serverValue, 0); return serverValue; } /** Convert the specified IBM i data type to an int. @param serverValue The array containing the data type in IBM i format. @param offset The offset into the byte array for the start of the IBM i value. @return an int corresponding to the data type, derived from the 2 bytes of data starting at the specified offset. **/ public static int byteArrayToUnsignedShort(byte[] serverValue, int offset) { checkArgs(serverValue, offset); return((serverValue[offset] & 0xFF) << 8) + (serverValue[offset+1] & 0xFF); } /** Convert the specified long into IBM i format in the specified byte array. The converted value will occupy 4 bytes. @param longValue The value to be converted to IBM i format. The long should be greater than or equal to zero and representable in four bytes. @param serverValue The array to receive the data type in IBM i format. @param offset The offset into the byte array for the start of the IBM i value. **/ public static void unsignedIntToByteArray(long longValue, byte[] serverValue, int offset) { checkArgs(serverValue, offset); // Grab bits into int to avoid long temps. int bits = (int)longValue; serverValue[offset] = (byte)(bits >>> 24); serverValue[offset+1] = (byte)(bits >>> 16); serverValue[offset+2] = (byte)(bits >>> 8); serverValue[offset+3] = (byte) bits; } /** Convert the specified long into IBM i format in a byte array. @param longValue The value to be converted to IBM i format. The long should be greater than or equal to zero and representable in four bytes. @return An array (of length 4) with the data type in IBM i format. **/ public static byte[] unsignedIntToByteArray(long longValue) { byte[] serverValue = new byte[4]; unsignedIntToByteArray(longValue, serverValue, 0); return serverValue; } /** Convert the specified IBM i data type to a long. @param serverValue The array containing the data type in IBM i format. @param offset The offset into the byte array for the start of the IBM i value. @return a long corresponding to the data type. **/ public static long byteArrayToUnsignedInt(byte[] serverValue, int offset) { checkArgs(serverValue, offset); return(((serverValue[offset] & 0xFF) << 24) + ((serverValue[offset+1] & 0xFF) << 16) + ((serverValue[offset+2] & 0xFF) << 8) + (serverValue[offset+3] & 0xFF)) & 0xFFFFFFFFL; } /** Convert the specified long into IBM i format in the specified byte array. The converted value will occupy 8 bytes. @param longValue The value to be converted to IBM i format. @param serverValue The array to receive the data type in IBM i format. @param offset The offset into the byte array for the start of the IBM i value. **/ public static void longToByteArray(long longValue, byte[] serverValue, int offset) { checkArgs(serverValue, offset); // Do in two parts to avoid long temps. int high = (int)(longValue >>> 32); int low = (int)longValue; serverValue[offset] = (byte)(high >>> 24); serverValue[offset+1] = (byte)(high >>> 16); serverValue[offset+2] = (byte)(high >>> 8); serverValue[offset+3] = (byte) high; serverValue[offset+4] = (byte)(low >>> 24); serverValue[offset+5] = (byte)(low >>> 16); serverValue[offset+6] = (byte)(low >>> 8); serverValue[offset+7] = (byte) low; } /** Convert the specified long into IBM i format in a byte array. @param longValue The value to be converted to IBM i format. @return An array (of length 8) with the data type in IBM i format. **/ public static byte[] longToByteArray(long longValue) { byte[] serverValue = new byte[8]; longToByteArray(longValue, serverValue, 0); return serverValue; } /** Convert the specified IBM i data type to a long. @param serverValue The array containing the data type in IBM i format. @param offset The offset into the byte array for the start of the IBM i value. @return a long corresponding to the data type. **/ public static long byteArrayToLong(byte[] serverValue, int offset) { checkArgs(serverValue, offset); // Do in two parts to avoid long temps. int firstPart = ((serverValue[offset] & 0xFF) << 24) + ((serverValue[offset+1] & 0xFF) << 16) + ((serverValue[offset+2] & 0xFF) << 8) + (serverValue[offset+3] & 0xFF); int secondPart = ((serverValue[offset+4] & 0xFF) << 24) + ((serverValue[offset+5] & 0xFF) << 16) + ((serverValue[offset+6] & 0xFF) << 8) + (serverValue[offset+7] & 0xFF); return((long)firstPart << 32) + (secondPart & 0xFFFFFFFFL); } static byte[] charArrayToByteArray(char[] charValue) { if (charValue == null) return null; byte[] byteValue = new byte[charValue.length * 2]; int inPos = 0; int outPos = 0; while (inPos < charValue.length) { byteValue[outPos++] = (byte)(charValue[inPos] >> 8); byteValue[outPos++] = (byte)charValue[inPos++]; } return byteValue; } static char[] byteArrayToCharArray(byte[] byteValue) { if (byteValue == null) return null; char[] charValue = new char[byteValue.length / 2]; int inPos = 0; int outPos = 0; while (inPos < byteValue.length) { charValue[outPos++] = (char)(((byteValue[inPos++] & 0xFF) << 8) + (byteValue[inPos++] & 0xFF)); } return charValue; } // Constant used in bytesToHexString() private static final char[] c_ = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; static final char hiNibbleToChar(byte b) { return c_[(b >>> 4) & 0x0F]; } static final char loNibbleToChar(byte b) { return c_[b & 0x0F]; } /** Convert the specified byte array to its hexadecimal String representation. Example generated string: "010203047E7F". @param b The array containing the data. @return A String containing the hex characters that represent the byte data. @deprecated Replaced by bytesToHexString(). (Same implementation, better name.) **/ public static final String bytesToString(final byte[] b) { if (b == null) throw new NullPointerException("b"); return bytesToHexString(b, 0, b.length); } /** Convert the specified byte array to its hexadecimal String representation. Example generated string: "010203047E7F". @param b The array containing the data. @param offset The offset into the array at which to begin reading bytes. @param length The number of bytes to read out of the array. @return A String containing the hex characters that represent the byte data. @deprecated Replaced by bytesToHexString(). (Same implementation, better name.) **/ public static final String bytesToString(final byte[] b, int offset, int length) { return bytesToHexString(b, offset, length); } /** Convert the specified byte array to its hexadecimal String representation. Example generated string: "010203047E7F". @param b The array containing the data. @return A String containing the hex characters that represent the byte data. **/ public static final String bytesToHexString(final byte[] b) { if (b == null) throw new NullPointerException("b"); return bytesToHexString(b, 0, b.length); } /** Convert the specified byte array to its hexadecimal String representation. Example generated string: "010203047E7F". @param b The array containing the data. @param offset The offset into the array at which to begin reading bytes. @param length The number of bytes to read out of the array. @return A String containing the hex characters that represent the byte data. **/ public static final String bytesToHexString(final byte[] b, int offset, int length) { if (b == null) throw new NullPointerException("b"); char[] c = new char[length*2]; int num = bytesToHexString(b, offset, length, c, 0); return new String(c, 0, num); } // Helper method to convert a byte array into its hex string representation. // This is faster than calling Integer.toHexString(...) static final int bytesToHexString(final byte[] b, int offset, int length, final char[] c, int coffset) { for (int i=0; i>>4) & 0x0F); final byte lo = (byte)((b[i+offset] & 0x0F)); c[j+coffset] = c_[hi]; c[j+coffset+1] = c_[lo]; } return length*2; } // Constant used in stringToBytes() // Note that 0x11 is "undefined". private static final byte[] b_ = { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 }; static final byte charsToByte(char hi, char lo) throws NumberFormatException { int c1 = 0x00FFFF & hi; int c2 = 0x00FFFF & lo; if (c1 > 255 || c2 > 255) throw new NumberFormatException(); byte b1 = b_[c1]; byte b2 = b_[c2]; if (b1 == 0x11 || b2 == 0x11) return 0; return(byte)(((byte)(b1 << 4)) + b2); } static final void checkArgs(byte[] serverValue, int offset) throws NullPointerException { if (serverValue == null) throw new NullPointerException("serverValue"); if (offset < 0 || (offset > serverValue.length-1)) { if (Trace.traceOn_) Trace.log(Trace.ERROR, "Offset " + offset + " was specified for array of length " + serverValue.length + "."); ArrayIndexOutOfBoundsException ex =new ArrayIndexOutOfBoundsException(String.valueOf(offset)); if (Trace.traceOn_) Trace.log(Trace.ERROR, ex); throw ex; } } /** Convert the specified hexadecimal String into a byte array containing the byte values for the hexadecimal characters in the String. If the String contains characters other than those allowed for a hexadecimal String (0-9 and A-F), an exception will be thrown. @param s The String containing the hexadecimal representation of the data. @return A byte array containing the byte values of the hex characters. * @throws NumberFormatException If the number cannot be formatted **/ public static final byte[] stringToBytes(String s) throws NumberFormatException { if (s == null) throw new NullPointerException("s"); int stringLength = s.length(); //@KBA check for empty string if(stringLength > 2) //@KBA //@pdc allow for input single digit input like "X" so NumberFormatException is thrown instead of array bounds error { //@KBA if(s.charAt(0) == '0' && (s.charAt(1) == 'x' || s.charAt(1) == 'X')) //@KBA s = s.substring(2); //@KBA else if((s.charAt(0) == 'x' || s.charAt(0) == 'X') && s.charAt(1) == '\'') //@KBA { //@KBA if(s.charAt(stringLength - 1) == '\'') //@KBA s = s.substring(2, stringLength-1); //@KBA else //@KBA throw new NumberFormatException(); //@KBA } //@KBA } //@KBA //check if an odd number of characters //@KBA if(s.length()%2 != 0) //@KBA s = "0" + s; //@KBA char[] c = s.toCharArray(); return stringToBytes(c, 0, c.length); } static final byte[] stringToBytes(char[] hex, int offset, int length) { if (hex.length == 0) return new byte[0]; byte[] buf = new byte[(length+1)/2]; int num = stringToBytes(hex, offset, length, buf, 0); if (num < buf.length) { byte[] temp = buf; buf = new byte[num]; System.arraycopy(temp, 0, buf, 0, num); } return buf; } // Helper method to convert a String in hex into its corresponding byte array. // Called only by HexReaderInputStream // length is the length of the string static final int stringToBytes(char[] hex, int offset, int length, final byte[] b, int boff) throws NumberFormatException { if (hex.length == 0) return 0; // account for char[] of odd length //@KBD if (hex.length % 2 == 1) //@KBD put checks in stringToBytes(String s) //@KBD { //@KBD char[] temp = hex; //@KBD hex = new char[temp.length+1]; //@KBD System.arraycopy(temp, 0, hex, 0, temp.length-1); //@KBD hex[hex.length-2] = '0'; //@KBD hex[hex.length-1] = temp[temp.length-1]; //@KBD } //@KBD if (hex[offset] == '0' && (hex.length > offset+1 && (hex[offset+1] == 'X' || hex[offset+1] == 'x'))) //@KBD { //@KBD offset += 2; //@KBD length -= 2; //@KBD } // Fixed loop condition to be length / 2 not b.length for (int i=0; i< length / 2; ++i) { final int j = i*2; final int c1 = 0x00FFFF & hex[j+offset]; final int c2 = 0x00FFFF & hex[j+offset+1]; if (c1 > 255 || c2 > 255) // out of range { //b[i+boff] = 0x00; throw new NumberFormatException(); } else { final byte b1 = b_[c1]; final byte b2 = b_[c2]; if (b1 == 0x11 || b2 == 0x11) // out of range { //b[i+boff] = 0x00; throw new NumberFormatException(); } else { final byte hi = (byte)(b1<<4); b[i+boff] = (byte)(hi + b2); } } } return length / 2; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy