001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package com.sun.midp.ssl;
028:
029: import java.io.OutputStream;
030: import java.io.IOException;
031: import java.io.InterruptedIOException;
032:
033: /**
034: * This class is a subclass of OutputStream and is used for
035: * writing data to an SSL connection.
036: * <P />
037: * @see com.sun.midp.ssl.SSLStreamConnection
038: * @see com.sun.midp.ssl.In
039: */
040: class Out extends OutputStream {
041: /**
042: * The maximum SSL record size to write, currently 2048.
043: * RFC 2246 specifies it can be up to 2^14 + 2048, however
044: * breaking up streams into smaller chunks make more sense, lower
045: * memory usage for small devices and interspacing encryption and
046: * network writes may work better on congested wireless networks.
047: */
048: private static final int MAX_RECORD_SIZE = 2048;
049:
050: /** Indicates the output stream is closed. */
051: private boolean isClosed = false;
052:
053: /** Underlying SSL record layer to which bytes are written. */
054: private Record rec;
055: /** Handle to current SSL stream connection. */
056: private SSLStreamConnection ssc;
057: /** A reusable buffer for the <code>write</code> method. */
058: private byte[] buf = new byte[1];
059:
060: /**
061: * Creates a new Out object.
062: * <P />
063: * @param r SSL record layer object to which bytes are written
064: * @param c SSLStreamConnection object this Out object is a part of
065: */
066: Out(Record r, SSLStreamConnection c) {
067: rec = r;
068: ssc = c;
069: }
070:
071: /**
072: * Writes the specified byte to this output stream.
073: * <P />
074: * @param b byte to be written
075: * @exception IOException if I/O error occurs
076: */
077: public void write(int b) throws IOException {
078: buf[0] = (byte) b;
079: write(buf, 0, 1);
080: }
081:
082: /**
083: * Writes all the bytes in the specified byte array to this
084: * output stream. This is equivalent to write(b, 0, b.length).
085: * <P />
086: * @param b byte array containing data to be written
087: * @exception IOException if I/O error occurs
088: */
089: public void write(byte[] b) throws IOException {
090: write(b, 0, b.length);
091: }
092:
093: /**
094: * Writes <CODE>len</CODE> bytes starting at offset
095: * <CODE>off</CODE> from byte array <CODE>b</CODE> to this
096: * output stream.
097: * <P />
098: * @param b byte array containing data to be written
099: * @param off starting offset of data to be written
100: * @param len number of bytes to be written
101: * @exception IOException if I/O error occurs
102: */
103: public void write(byte[] b, int off, int len) throws IOException {
104: if (isClosed) {
105: throw new InterruptedIOException("Stream closed");
106: }
107:
108: synchronized (rec) {
109: int bytesToWrite = MAX_RECORD_SIZE;
110: while (len > 0) {
111: if (len < bytesToWrite) {
112: bytesToWrite = len;
113: }
114:
115: rec.wrRec(Record.APP, b, off, bytesToWrite);
116: len -= bytesToWrite;
117: off += bytesToWrite;
118: }
119: }
120: }
121:
122: /**
123: * Close the stream connection.
124: *
125: * @exception IOException is thrown, if an I/O error occurs while
126: * shutting down the connection
127: */
128: synchronized public void close() throws IOException {
129: if (isClosed) {
130: return;
131: }
132:
133: isClosed = true;
134: if (ssc != null) {
135: ssc.outputStreamState = SSLStreamConnection.CLOSED;
136: rec.closeOutputStream();
137: ssc.cleanupIfNeeded();
138: }
139: }
140:
141: // Other methods: flush() need not be over ridden
142: }
|