@ SuppressWarnings ( "unchecked" ) public VirtualConnection read ( long numBytes , WsByteBuffer [ ] requestBuffers ) { if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isDebugEnabled ( ) ) { Tr . debug ( tc , "read entry: stream " + myID + " request: " + requestBuffers + " num bytes requested: " + numBytes ) ; } long streamByteCount = streamReadSize ; // number of bytes available on this stream long requestByteCount = bytesRemaining ( requestBuffers ) ; // total capacity of the caller byte array int reqArrayIndex = 0 ; // keep track of where we are in the caller's array // if at least numBytes are ready to be processed as part of the HTTP Request/Response, then load it up if ( numBytes > streamReadSize || requestBuffers == null ) { if ( this . headersCompleted ) { return h2HttpInboundLinkWrap . getVirtualConnection ( ) ; } else { if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isDebugEnabled ( ) ) { Tr . debug ( tc , "read exit: stream " + myID + " more bytes requested than available for read: " + numBytes + " > " + streamReadSize ) ; } return null ; } } if ( streamByteCount < requestByteCount ) { // the byte count requested exceeds the caller array capacity actualReadCount = streamByteCount ; } else { actualReadCount = requestByteCount ; } // copy bytes from this stream into the caller arrays for ( int bytesRead = 0 ; bytesRead < actualReadCount ; bytesRead ++ ) { // find the first buffer from the caller that has remaining capacity while ( ( requestBuffers [ reqArrayIndex ] . position ( ) == requestBuffers [ reqArrayIndex ] . limit ( ) ) ) { reqArrayIndex ++ ; } // find the next stream buffer that has data while ( ! streamReadReady . isEmpty ( ) && ! streamReadReady . get ( 0 ) . hasRemaining ( ) ) { streamReadReady . get ( 0 ) . release ( ) ; streamReadReady . remove ( 0 ) ; } requestBuffers [ reqArrayIndex ] . put ( streamReadReady . get ( 0 ) . get ( ) ) ; } // put stream array back in shape streamReadSize = 0 ; readLatch = new CountDownLatch ( 1 ) ; for ( WsByteBuffer buffer : ( ( ArrayList < WsByteBuffer > ) streamReadReady . clone ( ) ) ) { streamReadReady . clear ( ) ; if ( buffer . hasRemaining ( ) ) { moveDataIntoReadBufferArray ( buffer . slice ( ) ) ; } } if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isDebugEnabled ( ) ) { Tr . debug ( tc , "read exit: " + streamId ( ) ) ; } // return the vc since this was a successful read return h2HttpInboundLinkWrap . getVirtualConnection ( ) ; }
Read the HTTP header and data bytes for this stream