📄 ddmreader.java
字号:
magnitude[8] = (byte)(value[2] >>> 24); magnitude[9] = (byte)(value[2] >>> 16); magnitude[10] = (byte)(value[2] >>> 8); magnitude[11] = (byte)(value[2]); pos += length; return new java.math.BigDecimal (new java.math.BigInteger(signum, magnitude), scale); } else if (precision <= 31) { // get the value of last 9 digits (5 bytes). int lo = packedNybblesToInt(buffer, pos, (length-5)*2, 9); // get the value of another 9 digits (5 bytes). int meLo = packedNybblesToInt(buffer, pos, (length-10)*2+1, 9); // get the value of another 9 digits (5 bytes). int meHi = packedNybblesToInt(buffer, pos, (length-14)*2, 9); // get the value of the rest digits. int hi = packedNybblesToInt(buffer, pos, 0, (length-14)*2); // compute the int array of magnitude. int[] value = computeMagnitude(new int[] {hi, meHi, meLo, lo}); // convert value to a byte array of magnitude. byte[] magnitude = new byte[16]; magnitude[0] = (byte)(value[0] >>> 24); magnitude[1] = (byte)(value[0] >>> 16); magnitude[2] = (byte)(value[0] >>> 8); magnitude[3] = (byte)(value[0]); magnitude[4] = (byte)(value[1] >>> 24); magnitude[5] = (byte)(value[1] >>> 16); magnitude[6] = (byte)(value[1] >>> 8); magnitude[7] = (byte)(value[1]); magnitude[8] = (byte)(value[2] >>> 24); magnitude[9] = (byte)(value[2] >>> 16); magnitude[10] = (byte)(value[2] >>> 8); magnitude[11] = (byte)(value[2]); magnitude[12] = (byte)(value[3] >>> 24); magnitude[13] = (byte)(value[3] >>> 16); magnitude[14] = (byte)(value[3] >>> 8); magnitude[15] = (byte)(value[3]); pos += length; return new java.math.BigDecimal (new java.math.BigInteger(signum, magnitude), scale); } else { pos += length; // throw an exception here if nibbles is greater than 31 throw new java.lang.IllegalArgumentException("Decimal may only be up to 31 digits!"); } } byte[] getExtData (boolean checkNullability) throws DRDAProtocolException { return getExtData(ddmScalarLen, checkNullability); } byte[] getExtData (long desiredLength, boolean checkNullability) throws DRDAProtocolException { boolean readHeader; int copySize; ByteArrayOutputStream baos; boolean isLengthAndNullabilityUnknown = false; if (desiredLength != -1) { // allocate a stream based on a known amount of data baos = new ByteArrayOutputStream ((int) desiredLength); } else { // allocate a stream to hold an unknown amount of data baos = new ByteArrayOutputStream (); //isLengthAndNullabilityUnknown = true; // If we aren't given a length get the whole thing. desiredLength = MAX_EXTDTA_SIZE; } // check for a null EXTDTA value, if it is nullable and if streaming if (checkNullability) if (isEXTDTANull()) return null; // set the amount to read for the first segment copySize = (int) Math.min(dssLength,desiredLength); //note: has already been adjusted for headers //if (checkNullability) // don't count the null byte we've already read //copySize--; do { // determine if a continuation header needs to be read after the data if (dssIsContinued) readHeader = true; else readHeader = false; // read the segment ensureALayerDataInBuffer (copySize); adjustLengths (copySize); baos.write (buffer, pos, copySize); pos += copySize; desiredLength -= copySize; // read the continuation header, if necessary if (readHeader) readDSSContinuationHeader (); copySize = (int) Math.min(dssLength,desiredLength); //note: has already been adjusted for headers } while (readHeader == true && desiredLength > 0); return baos.toByteArray(); } // reads a DSS continuation header // prereq: pos is positioned on the first byte of the two-byte header // post: dssIsContinued is set to true if the continuation bit is on, false otherwise // dssLength is set to DssConstants.MAXDSS_LEN - 2 (don't count the header for the next read) // helper method for getEXTDTAData private void readDSSContinuationHeader () throws DRDAProtocolException { ensureALayerDataInBuffer(2); dssLength = ((buffer[pos++]&0xFF) << 8) + ((buffer[pos++]&0xFF) << 0); if ((dssLength & 0x8000) == 0x8000) { dssLength = DssConstants.MAX_DSS_LENGTH; dssIsContinued = true; } else { dssIsContinued = false; } // it is a syntax error if the dss continuation header length // is less than or equal to two if (dssLength <= 2) { agent.throwSyntaxrm(CodePoint.SYNERRCD_DSS_CONT_LESS_OR_EQUAL_2, DRDAProtocolException.NO_CODPNT_ARG); } dssLength -= 2; // avoid consuming the DSS cont header }// checks the null EXTDTA byte // returns true if null, false otherwise // helper method for getEXTDTAData private boolean isEXTDTANull () throws DRDAProtocolException { // make sure that the null byte is in the buffer ensureALayerDataInBuffer (1); adjustLengths (1); // examine the null byte byte nullByte = buffer[pos++]; if (nullByte == (byte)0x00) return false; return true; } /** * Convert a range of packed nybbles (up to 9 digits without overflow) to an int. * Note that for performance purpose, it does not do array-out-of-bound checking. * @param buffer buffer to read from * @param offset offset in the buffer * @param startNybble start nybble * @param numberOfNybbles number of nybbles * @return an int value */ private int packedNybblesToInt (byte[] buffer, int offset, int startNybble, int numberOfNybbles) { int value = 0; int i = startNybble / 2; if ((startNybble % 2) != 0) { // process low nybble of the first byte if necessary. value += buffer[offset+i] & 0x0F; i++; } int endNybble = startNybble + numberOfNybbles -1; for (; i<(endNybble+1)/2; i++) { value = value*10 + ((buffer[offset+i] & 0xF0) >>> 4); // high nybble. value = value*10 + (buffer[offset+i] & 0x0F); // low nybble. } if ((endNybble % 2) == 0) { // process high nybble of the last byte if necessary. value = value*10 + ((buffer[offset+i] & 0xF0) >>> 4); } return value; } /** * Convert a range of packed nybbles (up to 18 digits without overflow) to a long. * Note that for performance purpose, it does not do array-out-of-bound checking. * @param buffer buffer to read from * @param offset offset in the buffer * @param startNybble start nybble * @param numberOfNybbles number of nybbles * @return an long value */ private long packedNybblesToLong (byte[] buffer, int offset, int startNybble, int numberOfNybbles) { long value = 0; int i = startNybble / 2; if ((startNybble % 2) != 0) { // process low nybble of the first byte if necessary. value += buffer[offset+i] & 0x0F; i++; } int endNybble = startNybble + numberOfNybbles -1; for (; i<(endNybble+1)/2; i++) { value = value*10 + ((buffer[offset+i] & 0xF0) >>> 4); // high nybble. value = value*10 + (buffer[offset+i] & 0x0F); // low nybble. } if ((endNybble % 2) == 0) { // process high nybble of the last byte if necessary. value = value*10 + ((buffer[offset+i] & 0xF0) >>> 4); } return value; } /** * Compute the int array of magnitude from input value segments. * @param input value segments * @return array of int magnitudes */ private int[] computeMagnitude(int[] input) { int length = input.length; int[] mag = new int[length]; mag[length-1] = input[length-1]; for (int i=0; i<length-1; i++) { int carry = 0; int j = tenRadixMagnitude[i].length-1; int k = length-1; for (; j>=0; j--, k--) { long product = (input[length-2-i] & 0xFFFFFFFFL) * (tenRadixMagnitude[i][j] & 0xFFFFFFFFL) + (mag[k] & 0xFFFFFFFFL) // add previous value + (carry & 0xFFFFFFFFL); // add carry carry = (int) (product >>> 32); mag[k] = (int) (product & 0xFFFFFFFFL); } mag[k] = (int) carry; } return mag; } /** * Read boolean value * @return value * * @exception DRDProtocolException */ protected boolean readBoolean () throws DRDAProtocolException { ensureBLayerDataInBuffer (1, ADJUST_LENGTHS); return buffer[pos++] != 0; } /** * Read encrypted string * @param decryptM decryption manager * @param securityMechanism security mechanism * @param initVector initialization vector for cipher * @param sourcePublicKey public key (as in Deffie-Hellman algorithm) * from source (encryptor) * @return decrypted string * * @exception DRDProtocolException, SQLException(wrapping any exception in decryption) */ protected String readEncryptedString (DecryptionManager decryptM, int securityMechanism, byte[] initVector, byte[] sourcePublicKey) throws DRDAProtocolException, java.sql.SQLException { byte[] cipherText = readBytes(); byte[] plainText = null; plainText = decryptM.decryptData(cipherText, securityMechanism, initVector, sourcePublicKey); if (plainText == null) return null; else return ccsidManager.convertToUCS2(plainText); } /** * Read string value * Strings in DRDA protocol are encoded in EBCDIC by default so we * need to convert to UCS2 * @param length - length of string to read * @return value * * @exception DRDProtocolException */ protected String readString (int length) throws DRDAProtocolException { ensureBLayerDataInBuffer (length, ADJUST_LENGTHS); String result = ccsidManager.convertToUCS2 (buffer, pos, length); pos += length; return result; } /** * Read string value into a <code>DRDAString</code> object. * * @param dst destination for the read string * @param size size (in bytes) of string to read * @param unpad if true, remove padding (trailing spaces) * * @exception DRDAProtocolException */ protected void readString(DRDAString dst, int size, boolean unpad) throws DRDAProtocolException { ensureBLayerDataInBuffer(size, ADJUST_LENGTHS); int startPos = pos; pos += size; if (unpad) { while ((size > 0) && (buffer[startPos + size - 1] == ccsidManager.space)) { --size; } } dst.setBytes(buffer, startPos, size); } /** * Read encoded string value * @param length - length of string to read * @return value * * @exception DRDProtocolException */ protected String readString (int length, String encoding) throws DRDAProtocolException { ensureBLayerDataInBuffer (length, ADJUST_LENGTHS); String s = null; try { s = new String (buffer, pos, length, encoding); } catch (java.io.UnsupportedEncodingException e) { agent.agentError("UnsupportedEncodingException in readString, encoding = " + encoding); e.printStackTrace(agent.getServer().logWriter); } pos += length; return s; } /** * Read string value in DDM data with default encoding * @return value * * @exception DRDProtocolException */ protected String readStringData() throws DRDAProtocolException { return readString((int)ddmScalarLen, NetworkServerControlImpl.DEFAULT_ENCODING); } /** * Read specified length of string value in DDM data with default encoding * @param length - length of string to read * @return value * * @exception DRDProtocolException */ protected String readStringData(int length) throws DRDAProtocolException { return readString(length, NetworkServerControlImpl.DEFAULT_ENCODING); } /** * Read length delimited string value in DDM data with default encoding * @return value * * @exception DRDProtocolException */ protected String readLDStringData(String encoding) throws DRDAProtocolException { int length = readNetworkShort(); return readString(length, encoding); } /** * Read string value * @param length - length of string to read * @return value * * @exception DRDProtocolException */ protected String readString () throws DRDAProtocolException { return readString((int)ddmScalarLen); } /** * Read byte string value * @param length - length of string to read * @return byte array * * @exception DRDProtocolException */ protected byte[] readBytes (int length) throws DRDAProtocolException { byte[] b; if (length < dssLength) { ensureBLayerDataInBuffer (length, ADJUST_LENGTHS); b = new byte[length]; System.arraycopy(buffer,pos,b,0,length); pos +=length; } else b = getExtData(length,false); return b; } /** * Read byte string value * @return byte array * * @exception DRDProtocolException */ protected byte[] readBytes () throws DRDAProtocolException
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -