001: /*
002: * @(#)In.java 1.20 02/07/24 @(#)
003: *
004: * Copyright (c) 2000-2002 Sun Microsystems, Inc. All rights reserved.
005: * PROPRIETARY/CONFIDENTIAL
006: * Use is subject to license terms.
007: */
008:
009: package com.sun.portal.kssl;
010:
011: import java.io.InputStream;
012: import java.io.IOException;
013: import java.io.InterruptedIOException;
014:
015: /**
016: * This class is a subclass of InputStream and obtains its input bytes
017: * from an SSL connection.
018: * <P />
019: * @see com.sun.kssl.SSLStreamConnection
020: * @see com.sun.kssl.Out
021: */
022: class In extends InputStream {
023: /** Underlying SSL record layer from which bytes are read. */
024: private Record rec;
025:
026: /** Start of plain text in data buffer. */
027: private int start;
028: /** Count of unread bytes left in data buffer. */
029: private int cnt;
030: /** Handle for current SSL stream connection. */
031: private SSLStreamConnection ssc;
032: /** Signals end of stream. */
033: private boolean endOfStream = false;
034:
035: /**
036: * Refills the internal store of decrypted bytes. Called when
037: * the byte count in the store reaches zero.
038: * @exception IOException is thrown, if an I/O error occurs filling the
039: * the buffer
040: */
041: private void refill() throws IOException {
042: if (endOfStream) {
043: return;
044: }
045:
046: rec.rdRec(Record.APP);
047: if (rec.plainTextLength == -1) {
048: endOfStream = true;
049: return;
050: }
051:
052: cnt = rec.plainTextLength;
053: start = rec.plainTextOffset;
054: }
055:
056: /**
057: * Creates a new In object.
058: * <P />
059: * @param r Record layer object from which input bytes are read
060: * @param c SSLStreamConnection object this In object is a part of
061: */
062: In(Record r, SSLStreamConnection c) {
063: rec = r;
064: ssc = c;
065: }
066:
067: /**
068: * Reads a byte from this input stream. The method blocks if no
069: * input is available.
070: * <P />
071: * @return the next byte of data, or -1 if end of stream is reached
072: * @exception IOException if an I/O error occurs
073: */
074: public int read() throws IOException {
075: int val;
076:
077: if (rec == null) {
078: throw new InterruptedIOException("Stream closed");
079: }
080:
081: if (cnt == 0) {
082: refill();
083: if (cnt == 0) {
084: return -1; // end of stream
085: }
086: }
087:
088: val = rec.inputData[start++] & 0xff;
089: cnt--;
090:
091: return val;
092: }
093:
094: /**
095: * Reads up to <CODE>b.length</CODE> bytes of data from this
096: * input stream into the byte array <CODE>b</CODE>. Blocks until
097: * some input is available. This is equivalent to
098: * <CODE>read(b, 0, b.length)</CODE>.
099: * <P />
100: * @param b the buffer into which data is read
101: * @return the actual number of bytes read into the buffer, or -1
102: * if there is no more data and the end of input stream has been
103: * reached
104: * @exception IOException if an I/O error occurs
105: */
106: public int read(byte[] b) throws IOException {
107: return read(b, 0, b.length);
108: }
109:
110: /**
111: * Reads up to <CODE>len</CODE> bytes of data from this input stream
112: * into <CODE>b</CODE> starting at offset <CODE>off</CODE>.
113: * <P />
114: * @param b buffer into which data is read
115: * @param off starting offset where data is read
116: * @param len maximum number of bytes to be read
117: * return the actual number of bytes read into the buffer, or -1
118: * if there is no more data and the end of input stream has been
119: * reached
120: * @return number of bytes read
121: * @exception IOException if an I/O error occurs
122: */
123: synchronized public int read(byte[] b, int off, int len)
124: throws IOException {
125: int i = 0;
126: int numBytes;
127:
128: if (rec == null) {
129: throw new InterruptedIOException("Stream closed");
130: }
131:
132: if (cnt == 0) {
133: refill();
134: if (cnt == 0) {
135: return -1; // end of stream
136: }
137: }
138:
139: if (len > cnt) {
140: numBytes = cnt;
141: } else {
142: numBytes = len;
143: }
144:
145: System.arraycopy(rec.inputData, start, b, off, numBytes);
146: start += numBytes;
147: cnt -= numBytes;
148:
149: return numBytes;
150: }
151:
152: /**
153: * Close the stream connection.
154: *
155: * @exception IOException is thrown, if an I/O error occurs while
156: * shutting down the connection
157: */
158: synchronized public void close() throws IOException {
159: if (ssc != null) {
160: ssc.inputStreamState = SSLStreamConnection.CLOSED;
161: ssc.cleanupIfNeeded();
162: ssc = null;
163: rec = null;
164: }
165: }
166:
167: /*
168: * The remaining methods: available(), markSupported(), mark(int),
169: * reset() need not be overridden
170: */
171: }
|