📄 ddmreader.java
字号:
{ return readBytes((int)ddmScalarLen); } /** * Skip byte string value * @param length - length of string to skip * * @exception DRDProtocolException */ protected void skipBytes (int length) throws DRDAProtocolException { ensureBLayerDataInBuffer (length, ADJUST_LENGTHS); pos += length; } /** * Skip byte string value * * @exception DRDAProtocolException */ protected void skipBytes () throws DRDAProtocolException { skipBytes((int)ddmScalarLen); } /** * Skip remaining DSS * * @exception DRDAProtocolException */ protected void skipDss() throws DRDAProtocolException { while (dssIsContinued) { skipBytes((int)dssLength); readDSSContinuationHeader(); } skipBytes((int)dssLength); topDdmCollectionStack = EMPTY_STACK; ddmScalarLen = 0; dssLength = 0; } protected void clearBuffer() throws DRDAProtocolException { skipBytes(java.lang.Math.min(dssLength, count - pos)); dssIsChainedWithSameID = false; dssIsChainedWithDiffID = false; } /** * Convert EBCDIC byte array to unicode string * * @param buf - byte array * @return string */ protected String convertBytes(byte[] buf) { return ccsidManager.convertToUCS2 (buf, 0, buf.length); } // Private methods /** * Adjust remaining length * * @param length - adjustment length */ private void adjustLengths(int length) { ddmScalarLen -= length; for (int i = 0; i <= topDdmCollectionStack; i++) { ddmCollectionLenStack[i] -= length; } dssLength -= length; } /********************************************************************/ /* NetworkServerControl command protocol reading routines */ /********************************************************************/ /** * Read string value * @param length - length of string to read * @return value * * @exception DRDProtocolException */ protected String readCmdString (int length) throws DRDAProtocolException, java.io.UnsupportedEncodingException { if (length == 0) return null; ensureBLayerDataInBuffer (length, ADJUST_LENGTHS); String result = new String (buffer, pos, length, NetworkServerControlImpl.DEFAULT_ENCODING); pos += length; return result; } /** * Read string value * @return value * * @exception DRDProtocolException */ protected String readCmdString () throws DRDAProtocolException, java.io.UnsupportedEncodingException { int length = readNetworkShort(); return readCmdString(length); } /**************************************************************************/ /* Private methods /**************************************************************************/ /** * Make sure a certain amount of Layer A data is in the buffer. * The data will be in the buffer after this method is called. * * @param desiredDataSize - amount of data we need * * @exception DRDAProtocolException */ private void ensureALayerDataInBuffer (int desiredDataSize) throws DRDAProtocolException { // calulate the the number of bytes in the buffer. int avail = count - pos; // read more bytes off the network if the data is not in the buffer already. if (avail < desiredDataSize) { fill (desiredDataSize - avail); } } /** * Make sure a certain amount of Layer B data is in the buffer. * The data will be in the buffer after this method is called. * * @param desiredDataSize - amount of data we need * @param adjustLen - whether to adjust the remaining lengths * * @exception DRDProtocolException */ private void ensureBLayerDataInBuffer (int desiredDataSize, boolean adjustLen) throws DRDAProtocolException { ensureALayerDataInBuffer (desiredDataSize); if (dssIsContinued) { if (desiredDataSize > dssLength) { int continueDssHeaderCount = (((desiredDataSize - dssLength) / DssConstants.MAX_DSS_LENGTH) + 1); compressBLayerData (continueDssHeaderCount); } } if (adjustLen) adjustLengths(desiredDataSize); } /** * Compress B Layer data if extended total length is used * by removing the continuation headers * * @param continueDssHeaderCount - amount of data we need * * @exception throws DRDAProtocolException */ private void compressBLayerData (int continueDssHeaderCount) throws DRDAProtocolException { // jump to the last continuation header. int tempPos = 0; for (int i = 0; i < continueDssHeaderCount; i++) { // the first may be less than the size of a full DSS if (i == 0) { // only jump by the number of bytes remaining in the current DSS tempPos = pos + dssLength; } else { // all other jumps are for a full continued DSS tempPos += DssConstants.MAX_DSS_LENGTH; } } // for each of the DSS headers to remove, // read out the continuation header and increment the DSS length by the // size of the continuation bytes, then shift the continuation data as needed. int shiftSize = 0; int bytesToShift = 0; int continueHeaderLength = 0; int newdssLength = 0; for (int i = 0; i < continueDssHeaderCount; i++) { continueHeaderLength = ((buffer[tempPos] & 0xff) << 8) + ((buffer[tempPos + 1] & 0xff) << 0); if (i == 0) { // if this is the last one (farthest down stream and first to strip out) if ((continueHeaderLength & DssConstants.CONTINUATION_BIT) == DssConstants.CONTINUATION_BIT) { // the last DSS header is again continued continueHeaderLength = DssConstants.MAX_DSS_LENGTH; dssIsContinued = true; } else { // the last DSS header was not contiued so update continue state flag dssIsContinued = false; } // the very first shift size is 2 shiftSize = 2; } else { // already removed the last header so make sure the chaining flag is on if ((continueHeaderLength & DssConstants.CONTINUATION_BIT) == DssConstants.CONTINUATION_BIT) { continueHeaderLength = DssConstants.MAX_DSS_LENGTH; } else { // this is a syntax error but not really certain which one. // for now pick 0x02 which is DSS header Length does not // match the number // of bytes of data found. agent.throwSyntaxrm(CodePoint.SYNERRCD_DSS_LENGTH_BYTE_NUMBER_MISMATCH, DRDAProtocolException.NO_CODPNT_ARG); } // increase the shift size by 2 shiftSize += 2; } // it is a syntax error if the DSS continuation is less // than or equal to two if (continueHeaderLength <= 2) { agent.throwSyntaxrm(CodePoint.SYNERRCD_DSS_CONT_LESS_OR_EQUAL_2, DRDAProtocolException.NO_CODPNT_ARG); } newdssLength += continueHeaderLength; // calculate the number of bytes to shift if (i == (continueDssHeaderCount - 1)) bytesToShift = DssConstants.MAX_DSS_LENGTH; else bytesToShift = dssLength; tempPos -= (shiftSize - 1); System.arraycopy(buffer, tempPos, buffer, tempPos - bytesToShift + shiftSize , bytesToShift); tempPos -= bytesToShift; tempPos += (shiftSize + 1); } // reposition the start of the data after the final DSS shift. pos = tempPos; } /** * Methods to manage the data buffer. * Methods orginally from JCC * RESOLVE: need to check if this is the best performing way of doing this */ /** * This is a helper method which shifts the buffered bytes from * wherever they are in the current buffer to the beginning of * different buffer (note these buffers could be the same). * State information is updated as needed after the shift. * @param destinationBuffer - buffer to shift data to */ private void shiftBuffer (byte[] destinationBuffer) { // calculate the size of the data in the current buffer. int sz = count - pos; if (SanityManager.DEBUG) { if ((sz < 0 || pos < 0) ) { SanityManager.THROWASSERT( "Unexpected data size or position. sz=" + sz + " count=" + count +" pos=" + pos); } } // copy this data to the new buffer startsing at position 0. System.arraycopy (buffer, pos, destinationBuffer, 0, sz); // update the state information for data in the new buffer. pos = 0; count = sz; // replace the old buffer with the new buffer. buffer = destinationBuffer; } /** * This method makes sure there is enough room in the buffer * for a certain number of bytes. This method will allocate * a new buffer if needed and shift the bytes in the current buffer * to make ensure space is available for a fill. Right now * this method will shift bytes as needed to make sure there is * as much room as possible in the buffer before trying to * do the read. The idea is to try to have space to get as much data as possible * if we need to do a read on the socket's stream. * * @param desiredSpace - amount of data we need */ private void ensureSpaceInBufferForFill (int desiredSpace) { // calculate the total unused space in the buffer. // this includes any space at the end of the buffer and any free // space at the beginning resulting from bytes already read. int currentAvailableSpace = (buffer.length - count) + pos; // check to see if there is enough free space. if (currentAvailableSpace < desiredSpace) { // there is not enough free space so we need more storage. // we are going to double the buffer unless that happens to still be // too small. If more than double the buffer is needed, // use the smallest amount over this as possible. int doubleBufferSize = (2 * buffer.length); int minumNewBufferSize = (desiredSpace - currentAvailableSpace) + buffer.length; int newsz = minumNewBufferSize <= doubleBufferSize ? doubleBufferSize : minumNewBufferSize; byte[] newBuffer = new byte[newsz]; // shift everything from the old buffer to the new buffer shiftBuffer (newBuffer); } else { // there is enough free space in the buffer but let's make sure // it is all at the end. // this is also important because if we are going to do a read, // it would be nice // to get as much data as possible and making room at the end // if the buffer helps to ensure this. if (pos != 0) { shiftBuffer (buffer); } } } /** * This method will attempt to read a minimum number of bytes * from the underlying stream. This method will keep trying to * read bytes until it has obtained at least the minimum number. * @param minimumBytesNeeded - minimum required bytes * * @exception DRDProtocolException */ private void fill (int minimumBytesNeeded) throws DRDAProtocolException { // make sure that there is enough space in the buffer to hold // the minimum number of bytes needed. ensureSpaceInBufferForFill (minimumBytesNeeded); // read until the minimum number of bytes needed is now in the buffer. // hopefully the read method will return as many bytes as it can. int totalBytesRead = 0; int actualBytesRead = 0; do { try { actualBytesRead = inputStream.read ( buffer, count, buffer.length - count); } catch (java.io.IOException ioe) { agent.markCommunicationsFailure ("DDMReader.fill()", "InputStream.read()", ioe.getMessage(), "*"); } finally { if ((dssTrace != null) && dssTrace.isComBufferTraceOn()) dssTrace.writeComBufferData (buffer, count, actualBytesRead, DssTrace.TYPE_TRACE_RECEIVE, "Request", "fill", 5); } if (actualBytesRead != -1) { count += actualBytesRead; totalBytesRead += actualBytesRead; } } while ((totalBytesRead < minimumBytesNeeded) && (actualBytesRead != -1)); if (actualBytesRead == -1) { if (totalBytesRead < minimumBytesNeeded) { agent.markCommunicationsFailure ("DDMReader.fill()", "InputStream.read()", "insufficient data", "*"); } } } /** * Print a internal trace message */ private void trace(String msg) { if (agent != null) agent.trace(msg); } protected String toDebugString(String indent) { String s = indent + "***** DDMReader toDebugString ******\n"; int buflen = 0; if (buffer != null) buflen = buffer.length; s += indent + "Reader buffer length = " + buffer.length + "\n"; return s; } /** * Return chaining bit for current DSS. */ protected byte getCurrChainState() { if (!dssIsChainedWithSameID && !dssIsChainedWithDiffID) return DssConstants.DSS_NOCHAIN; if (dssIsChainedWithSameID) return DssConstants.DSSCHAIN_SAME_ID; return DssConstants.DSSCHAIN; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -