/* (non-Javadoc)
@see com.emc.ecs.nfsclient.nfs.Nfs#getRead(com.emc.ecs.nfsclient.nfs.NfsReadRequest, byte[], int)
327617
public Nfs3ReadResponse getRead(NfsReadRequest request, byte[] bytes, int position) throws IOException {
        Nfs3ReadResponse response = new Nfs3ReadResponse(bytes, position);
        _rpcWrapper.callRpcNaked(request, response);
        return response;
    }
1252402
public int read() throws IOException {
        synchronized (lock) {
            ensureOpen();
            for (;;) {
                if (nextChar >= nChars) {
                    fill();
                    if (nextChar >= nChars)
                        return -1;
                }
                if (skipLF) {
                    skipLF = false;
                    if (cb[nextChar] == '\n') {
                        nextChar++;
                        continue;
                    }
                }
                return cb[nextChar++];
            }
        }
    }
49621
public int read(byte[] buffer, int offset, int len) throws IOException {

		try {

			if (isEOF && currentMessageRemaining == 0) {
				return -1;
			}

			int read = 0;
			int wantsLength = len;
			while (read < wantsLength && !isEOF) {

				if (currentMessage == null || currentMessageRemaining == 0) {
					bufferNextMessage();
					if (isEOF && read == 0) {
						return -1;
					}
				}

				if (currentMessage == null)
					throw new IOException(
							"Failed to obtain file data or status from the SFTP server!");

				int count = Math.min(currentMessageRemaining, len);

				System.arraycopy(currentMessage.array(),
						currentMessage.getPosition(), buffer, offset, count);

				currentMessageRemaining -= count;
				currentMessage.skip(count);

				if (currentMessageRemaining == 0) {
					bufferNextMessage();
				}
				read += count;
				len -= count;
				offset += count;

			}

			return read;
		} catch (SshException ex) {
			throw new SshIOException(ex);
		} catch (SftpStatusException ex) {
			throw new IOException(ex.getMessage());
		}
	}
607277
@Override
	public int read() throws IOException {
		byte[] buf = new byte[1];

		int res = this.read(buf, 0, 1);

		if (res != -1) {
			return 0xFF & buf[0];
		}

		return res;
	}
1364190
public NfsReaddirResponse readdir(long cookie, long cookieverf, int count) throws IOException {
        return getNfs().wrapped_getReaddir(makeReaddirRequest(cookie, cookieverf, count));
    }
63632
@Override
	public int read(byte[] b, int off, int len) throws IOException {
		// Read from the queue
		synchronized(file) {
			while(true) {
				long fileLen=file.getLength();
				if(fileLen>=1) {
					long pos=file.getFirstIndex();
					file.file.seek(pos+16);
					int readSize=fileLen>len?len:(int)fileLen;
					// When at the end of the file, read the remaining bytes
					if((pos+readSize)>file.maxFifoLength) readSize=(int)(file.maxFifoLength-pos);

					// Read as many bytes as currently available
					int totalRead=file.file.read(b, off, readSize);
					if(totalRead==-1) throw new EOFException("Unexpected EOF");
					addStats(totalRead);
					long newFirstIndex=pos+totalRead;
					while(newFirstIndex>=file.maxFifoLength) newFirstIndex-=file.maxFifoLength;
					file.setFirstIndex(newFirstIndex);
					file.setLength(fileLen-totalRead);
					file.notify();
					return totalRead;
				}
				try {
					file.wait();
				} catch(InterruptedException err) {
					InterruptedIOException ioErr=new InterruptedIOException();
					ioErr.initCause(err);
					throw ioErr;
				}
			}
		}
	}
752931
public int read() throws IOException {
        byte[] b = new byte[1];
        int bytesRead = read(b, 0, 1);
        if (bytesRead == EOF) {
            return EOF;
        } else {
        //byte type in Java is from -128 to +127 and we are supposed to return 0-255
            return b[0] & 0xFF;
        }
    }
418346
private int read(final int off, final int len) throws IOException {
        if (len == 0) {
            return 0;
        }
        if (inputStream != null) {
            // Wrapped InputStream
            return inputStream.read(buf, off, len);
        } else {
            // Wrapped ByteBuffer
            final int bytesRemainingInBuf = byteBuffer != null ? byteBuffer.remaining() : buf.length - off;
            final int bytesRead = Math.max(0, Math.min(len, bytesRemainingInBuf));
            if (bytesRead == 0) {
                // Return -1, as per InputStream#read() contract
                return -1;
            }
            if (byteBuffer != null) {
                // Copy from the ByteBuffer into the byte array
                final int byteBufPositionBefore = byteBuffer.position();
                try {
                    byteBuffer.get(buf, off, bytesRead);
                } catch (final BufferUnderflowException e) {
                    // Should not happen
                    throw new IOException("Buffer underflow", e);
                }
                return byteBuffer.position() - byteBufPositionBefore;
            } else {
                // Nothing to read, since ByteBuffer is backed with an array
                return bytesRead;
            }
        }
    }
9465
@Override
	public int read (byte bytes[], int offset, int length) throws IOException {
		int	r;

		if ((r = in.read(bytes, offset, length)) == -1) return -1;

		md5.Update(bytes, offset, r);

		return r;
	}
768809
@Override
	public int read() throws IOException {
		int c = in.read();
		if (c == -1) return -1;

		md5.Update(c);

		return c;
	}
396441
@Override
    public int read() throws IOException {
        
        //Return -1 here because if we are closed or finished, we're at the end of the stream
        if(isClosed || isFinished()){
            if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                Tr.debug(tc, "Nothing to read, stream is closed : " + isClosed + ", or finished : " + isFinished());
            return -1;
        }
        
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
            Tr.entry(tc, "read" , "SRTInputStream31.read()");
        }
        
        int returnByte;
        
        if(this.request.isAsyncStarted()&& (this.getReadListener()!= null)){
            synchronized(this){
//                Check if isReady had returned false. If it did then an IllegalArgumentException will be thrown if a listener is set
                isReadyFalseCheck();
                returnByte = super.read();
            }
        } else{
            returnByte = super.read();
        }
        
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
            Tr.exit(tc, "read" , "SRTInputStream31.read() : " + returnByte);
        }
        
        return returnByte;
    }
1207808
public int read(byte[] b, int off, int len) throws IOException {
        checkForClosed();
        if (b == null) {
            throw new NullPointerException();
        } else if ((off < 0) || (len < 0) || ((off + len) > b.length)) {
            throw new IndexOutOfBoundsException();
        } else if (len == 0) {
            return 0;
        }

        loadBytesAsNeeded();
        int bytesImmediatelyAvailable = bytesLeftInBuffer();
        if (len <= bytesImmediatelyAvailable) {
            System.arraycopy(_bytes, _currentBufferPosition, b, off, len);
            _currentBufferPosition += len;
            return len;
        }

        int bytesRead = EOF;
        if (bytesImmediatelyAvailable > 0) {
            bytesRead = read(b, off, bytesImmediatelyAvailable);
            if (bytesRead != EOF) {
                int furtherBytesRead = read(b, off + bytesRead, len - bytesRead);
                if (furtherBytesRead != EOF) {
                    bytesRead += furtherBytesRead;
                }
            }
        }
        return bytesRead;
    }
222908
@Override
	public int read() throws IOException {
		byte[] b = new byte[1];
		int num = read(b);
		if(num == 0) {
			throw new IllegalStateException("read returned 0");
		}
		return num > 0 ? b[0] : -1;
	}
993511
@Override
    public int read()
        throws IOException
    {
        synchronized ( lock )
        {
            ensureOpen();
            if ( next >= length )
                return -1;
            return seq.charAt( next++ );
        }
    }
1107821
@Override
    public long read(long numBytes, int timeout) throws IOException {
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
            Tr.entry(tc, "read, numbytes=" + numBytes + ", vc=" + getVCHash());
        }

        // Access the read interface of the device side channel.
        if (deviceReadContext == null) {
            deviceReadContext = getConnLink().getDeviceReadInterface();
        }

        // Handle timing out of former read request.
        if (timeout == IMMED_TIMEOUT || timeout == ABORT_TIMEOUT) {
            if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                Tr.debug(tc, "Requested to timeout former request.  Calling device side.");
            }
            deviceReadContext.read(numBytes, timeout);
            if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
                Tr.exit(tc, "read");
            }
            return 0L;
        }

        // Reset some object variables.
        this.decryptedNetBufferReleaseRequired = false;
        this.callerRequiredAllocation = false;

        // Look for errors in the request.
        IOException exceptionInRequest = checkRequest(numBytes, false);
        if (exceptionInRequest != null) {
            // Found an error.
            throw exceptionInRequest;
        }

        // Track the number of bytes requested.
        this.bytesRequested = numBytes;

        // save the starting positions of the buffers to make a proper return value later
        saveDecryptedPositions();

        // Handle any left over data from a the previous read request.
        this.bytesProduced = readUnconsumedDecData();
        if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
            Tr.debug(tc, "Decrypted data left over from previous request: " + bytesProduced);
        }
        // Was data read to satisfy the request or was the request to get all data available?
        if ((bytesRequested > bytesProduced) || (bytesRequested == 0L)) {
            // Left over data didn't exist or was not enough to satisfy the request.
            long devBytesRead = 0;
            int loopCount = 0;
            long encryptedBytesAvailable = 0;
            long bufferSize = 0;

            // If bytesProduced > 0, then some date was left over in unconsumedDecData but it
            // wasn't enough. The data is currently between pos and lim, but now we need to
            // treat it like data that was already decrypted by the JSSE, pushing the data
            // behind the position.
            if (bytesProduced > 0L) {
                SSLUtils.positionToLimit(decryptedNetBuffers);
                // While we're at it, maximize the room for future reads.
                SSLUtils.limitToCapacity(decryptedNetBuffers);
                if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                    Tr.debug(tc, "Adjusted left over decNetBuffers: "
                                 + SSLUtils.getBufferTraceInfo(decryptedNetBuffers));
                }
            }

            // Calculate how much encrypted data is currently available if netbuffers already exists.
            if (null != this.netBuffer) {
                encryptedBytesAvailable = this.netBuffer.remaining();
            }
            // Adjust the buffer size if the number of bytes request was zero (read all).
            if (bytesRequested != 0L) {
                bufferSize = bytesRequested - bytesProduced;
            }
            // Allocate/reuse the buffer to be read into. Data remaining from a previous,
            // unconsumed read, will be put in these buffers before return. Note the size
            // provided is a guess. bytesToRead is decNet data (decrypted). This buffer
            // is for net data (encrypted).
            getNetworkBuffer(bufferSize);

            // Keep reading until enough data has been read to satisfy the request.
            while ((bytesProduced < bytesRequested) || (bytesRequested == 0L)) {
                // Adjust counter to know when first pass of loop took place.
                loopCount++;

                // Bypass a new read if data is available and this is the first loop iteration.
                // Future loop will require a read since as the JSSE's UNDERFLOW will indicate.
                if ((encryptedBytesAvailable > 0) && (loopCount == 1)) {
                    if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                        Tr.debug(tc, "No read needed.  Encrypted bytes already available: "
                                     + encryptedBytesAvailable);
                    }
                } else {
                    // Shift limit to capacity for all buffers to maximize room to read,
                    // reducing allocations.
                    this.netBuffer.limit(this.netBuffer.capacity());
                    long deviceReadRequestSize = 0;
                    if (bytesRequested != 0L && bytesRequested > bytesProduced) {
                        // Attempt to do as much reading as possible up front.
                        deviceReadRequestSize = bytesRequested - bytesProduced - encryptedBytesAvailable;
                        // PK32916 - 0 bytes is not valid in this case so protect against that
                        // boundary condition
                        if (0L >= deviceReadRequestSize) {
                            deviceReadRequestSize = 1;
                        }
                    } else if (bytesRequested == 0L) {
                        deviceReadRequestSize = 0L;
                    } else {
                        // Remember bytesRequested are decrypted bytes.
                        // devBytesRead are encrypted bytes. This case can and
                        // will happen so ensure some reading gets done. Set to 1.
                        deviceReadRequestSize = 1;
                    }
                    if (TraceComponent.isAnyTracingEnabled() && tc.isEventEnabled()) {
                        Tr.event(tc, "do sync read of : " + deviceReadRequestSize
                                     + " bytes into netBuffer..." + SSLUtils.getBufferTraceInfo(this.netBuffer));
                    }
                    try {
                        devBytesRead += deviceReadContext.read(deviceReadRequestSize, timeout);
                        if (deviceReadRequestSize == 0L && devBytesRead == 0L) {
                            // A request was made to read all available, and nothing was.
                            this.bytesProduced = 0L;

                            // Reset the buffers to contain previously read data between pos and lim.
                            this.netBuffer.limit(this.netBuffer.position());
                            this.netBuffer.position(netBufferMark);
                            break;
                        }
                    } catch (IOException e) {
                        // no FFDC required
                        // Protect future reads from thinking data was read.
                        // Reset the buffers to contain previously read data between pos and lim.
                        this.netBuffer.limit(this.netBuffer.position());
                        this.netBuffer.position(netBufferMark);
                        if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                            Tr.debug(tc, "Reset buffers after read error: vc=" + getVCHash()
                                         + ", netBuffer: " + SSLUtils.getBufferTraceInfo(this.netBuffer));
                        }
                        throw e;
                    }
                    if (TraceComponent.isAnyTracingEnabled() && tc.isEventEnabled()) {
                        Tr.event(tc, "read bytes (total): " + devBytesRead);
                    }
                }

                // Prepare the input buffer for calling unwrap.
                // Set the position to the mark, noting the beginning of the data just read.
                this.netBuffer.limit(this.netBuffer.position());
                this.netBuffer.position(netBufferMark);

                // decrypt the resulting message.
                Exception exception = decryptMessage(false);
                if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                    Tr.debug(tc, bytesProduced + " bytes produced of "
                                 + bytesRequested + " bytes requested");
                }

                // Calculate how much encrypted data is still available, for use in future iterations.
                encryptedBytesAvailable = this.netBuffer.remaining();

                if (exception == null) {
                    if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                        Tr.debug(tc, "Decryption succeeded.");
                    }
                    // Check if more reading is necessary.
                    if (0L == this.bytesRequested) {
                        break;
                    }
                    if (bytesProduced < bytesRequested) {
                        getNetworkBuffer(bytesRequested - bytesProduced);
                    }
                }

                else if (exception instanceof ReadNeededInternalException) {
                    if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                        Tr.debug(tc, "More data needs to be read, loop to another read");
                    }
                    if (0L == this.bytesRequested) {
                        break;
                    }
                    getNetworkBuffer(this.bytesRequested - this.bytesProduced);
                    continue;
                }

                else if (exception instanceof SessionClosedException) {
                    if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                        Tr.debug(tc, "SSL Session has been closed.");
                    }
                    // 238579 - inform channel above
                    throw new IOException("SSL connection was closed by peer");
                }

                else {
                    FFDCFilter.processException(exception, getClass().getName(), "118", this);
                    if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                        Tr.debug(tc, "Decryption unsuccessful, exception resulted: " + exception);
                    }
                    IOException exc = new IOException("Unable to decrypt message");
                    exc.initCause(exception);
                    throw exc;
                }
            } // end while
        }
        // A valid amount of data has been produced.
        if (this.bytesProduced > 0L) {
            prepareDataForNextChannel();
            // now figure out how much we're actually sending to the caller
            WsByteBuffer[] buffers = getBuffers();
            long count = 0L;
            for (int i = 0; i < buffers.length && count < this.bytesProduced; i++) {
                count += buffers[i].limit() - decryptedNetPosInfo[i];
            }
            this.bytesProduced = count;
        }

        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
            Tr.exit(tc, "read: " + this.bytesProduced);
        }
        return this.bytesProduced;
    }
433947
private void loadBytesAsNeeded() throws IOException {
        if (available() <= 0) {
            _isEof = true;
        }

        while ((!_isEof) && (bytesLeftInBuffer() <= 0)) {
            _currentBufferPosition = 0;
            NfsReadResponse response = _file.read(_offset, _bytes.length, _bytes, _currentBufferPosition);
            _bytesInBuffer = response.getBytesRead();
            _offset += _bytesInBuffer;
            _isEof = response.isEof();
        }
    }
234036
@Override
    public int read(byte[] b, int off, int len) throws IOException {
        int readLen = super.read(b, off, len);
        dataLength += readLen >= 0 ? readLen : 0;
        checkLength(readLen == -1);
        return readLen;
    }