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 java.io;
028:
029: /**
030: * A data output stream lets an application write primitive Java data
031: * types to an output stream in a portable way. An application can
032: * then use a data input stream to read the data back in.
033: *
034: * @version 12/17/01 (CLDC 1.1)
035: * @see java.io.DataInputStream
036: * @since JDK1.0, CLDC 1.0
037: */
038: public class DataOutputStream extends OutputStream implements
039: DataOutput {
040:
041: /**
042: * The output stream.
043: */
044: protected OutputStream out;
045:
046: /**
047: * Creates a new data output stream to write data to the specified
048: * underlying output stream.
049: *
050: * @param out the underlying output stream, to be saved for later
051: * use.
052: */
053: public DataOutputStream(OutputStream out) {
054: this .out = out;
055: }
056:
057: /**
058: * Writes the specified byte (the low eight bits of the argument
059: * <code>b</code>) to the underlying output stream.
060: * <p>
061: * Implements the <code>write</code> method of <code>OutputStream</code>.
062: *
063: * @param b the <code>byte</code> to be written.
064: * @exception IOException if an I/O error occurs.
065: */
066: public void write(int b) throws IOException {
067: out.write(b);
068: }
069:
070: /**
071: * Writes <code>len</code> bytes from the specified byte array
072: * starting at offset <code>off</code> to the underlying output stream.
073: *
074: * @param b the data.
075: * @param off the start offset in the data.
076: * @param len the number of bytes to write.
077: * @exception IOException if an I/O error occurs.
078: */
079: public void write(byte b[], int off, int len) throws IOException {
080: out.write(b, off, len);
081: }
082:
083: /**
084: * Flushes this data output stream. This forces any buffered output
085: * bytes to be written out to the stream.
086: * <p>
087: * The <code>flush</code> method of <code>DataOutputStream</code>
088: * calls the <code>flush</code> method of its underlying output stream.
089: *
090: * @exception IOException if an I/O error occurs.
091: */
092: public void flush() throws IOException {
093: out.flush();
094: }
095:
096: /**
097: * Closes this output stream and releases any system resources
098: * associated with the stream.
099: * <p>
100: * The <code>close</code> method
101: * calls its <code>flush</code> method, and then calls the
102: * <code>close</code> method of its underlying output stream.
103: *
104: * @exception IOException if an I/O error occurs.
105: */
106: public void close() throws IOException {
107: try {
108: flush();
109: } catch (IOException e) {
110: }
111: out.close();
112: }
113:
114: /**
115: * Writes a <code>boolean</code> to the underlying output stream as
116: * a 1-byte value. The value <code>true</code> is written out as the
117: * value <code>(byte)1</code>; the value <code>false</code> is
118: * written out as the value <code>(byte)0</code>.
119: *
120: * @param v a <code>boolean</code> value to be written.
121: * @exception IOException if an I/O error occurs.
122: */
123: public final void writeBoolean(boolean v) throws IOException {
124: write(v ? 1 : 0);
125: }
126:
127: /**
128: * Writes out a <code>byte</code> to the underlying output stream as
129: * a 1-byte value.
130: *
131: * @param v a <code>byte</code> value to be written.
132: * @exception IOException if an I/O error occurs.
133: */
134: public final void writeByte(int v) throws IOException {
135: write(v);
136: }
137:
138: /**
139: * Writes a <code>short</code> to the underlying output stream as two
140: * bytes, high byte first.
141: *
142: * @param v a <code>short</code> to be written.
143: * @exception IOException if an I/O error occurs.
144: */
145: public final void writeShort(int v) throws IOException {
146: write((v >>> 8) & 0xFF);
147: write((v >>> 0) & 0xFF);
148: }
149:
150: /**
151: * Writes a <code>char</code> to the underlying output stream as a
152: * 2-byte value, high byte first.
153: *
154: * @param v a <code>char</code> value to be written.
155: * @exception IOException if an I/O error occurs.
156: */
157: public final void writeChar(int v) throws IOException {
158: write((v >>> 8) & 0xFF);
159: write((v >>> 0) & 0xFF);
160: }
161:
162: /**
163: * Writes an <code>int</code> to the underlying output stream as four
164: * bytes, high byte first.
165: *
166: * @param v an <code>int</code> to be written.
167: * @exception IOException if an I/O error occurs.
168: */
169: public final void writeInt(int v) throws IOException {
170: write((v >>> 24) & 0xFF);
171: write((v >>> 16) & 0xFF);
172: write((v >>> 8) & 0xFF);
173: write((v >>> 0) & 0xFF);
174: }
175:
176: /**
177: * Writes a <code>long</code> to the underlying output stream as eight
178: * bytes, high byte first.
179: *
180: * @param v a <code>long</code> to be written.
181: * @exception IOException if an I/O error occurs.
182: */
183: public final void writeLong(long v) throws IOException {
184: write((int) (v >>> 56) & 0xFF);
185: write((int) (v >>> 48) & 0xFF);
186: write((int) (v >>> 40) & 0xFF);
187: write((int) (v >>> 32) & 0xFF);
188: write((int) (v >>> 24) & 0xFF);
189: write((int) (v >>> 16) & 0xFF);
190: write((int) (v >>> 8) & 0xFF);
191: write((int) (v >>> 0) & 0xFF);
192: }
193:
194: /**
195: * Converts the float argument to an <code>int</code> using the
196: * <code>floatToIntBits</code> method in class <code>Float</code>,
197: * and then writes that <code>int</code> value to the underlying
198: * output stream as a 4-byte quantity, high byte first.
199: *
200: * @param v a <code>float</code> value to be written.
201: * @exception IOException if an I/O error occurs.
202: * @see java.lang.Float#floatToIntBits(float)
203: * @since CLDC 1.1
204: */
205: public final void writeFloat(float v) throws IOException {
206: writeInt(Float.floatToIntBits(v));
207: }
208:
209: /**
210: * Converts the double argument to a <code>long</code> using the
211: * <code>doubleToLongBits</code> method in class <code>Double</code>,
212: * and then writes that <code>long</code> value to the underlying
213: * output stream as an 8-byte quantity, high byte first.
214: *
215: * @param v a <code>double</code> value to be written.
216: * @exception IOException if an I/O error occurs.
217: * @see java.lang.Double#doubleToLongBits(double)
218: * @since CLDC 1.1
219: */
220: public final void writeDouble(double v) throws IOException {
221: writeLong(Double.doubleToLongBits(v));
222: }
223:
224: /**
225: * Writes a string to the underlying output stream as a sequence of
226: * characters. Each character is written to the data output stream as
227: * if by the <code>writeChar</code> method.
228: *
229: * @param s a <code>String</code> value to be written.
230: * @exception IOException if an I/O error occurs.
231: * @see java.io.DataOutputStream#writeChar(int)
232: */
233: public final void writeChars(String s) throws IOException {
234: int len = s.length();
235: for (int i = 0; i < len; i++) {
236: int v = s.charAt(i);
237: write((v >>> 8) & 0xFF);
238: write((v >>> 0) & 0xFF);
239: }
240: }
241:
242: /**
243: * Writes a string to the underlying output stream using UTF-8
244: * encoding in a machine-independent manner.
245: * <p>
246: * First, two bytes are written to the output stream as if by the
247: * <code>writeShort</code> method giving the number of bytes to
248: * follow. This value is the number of bytes actually written out,
249: * not the length of the string. Following the length, each character
250: * of the string is output, in sequence, using the UTF-8 encoding
251: * for the character.
252: *
253: * @param str a string to be written.
254: * @exception IOException if an I/O error occurs.
255: */
256: public final void writeUTF(String str) throws IOException {
257: writeUTF(str, this );
258: }
259:
260: /**
261: * Writes a string to the specified DataOutput using UTF-8 encoding in a
262: * machine-independent manner.
263: * <p>
264: * First, two bytes are written to out as if by the <code>writeShort</code>
265: * method giving the number of bytes to follow. This value is the number of
266: * bytes actually written out, not the length of the string. Following the
267: * length, each character of the string is output, in sequence, using the
268: * UTF-8 encoding for the character.
269: *
270: * @param str a string to be written.
271: * @param out destination to write to
272: * @return The number of bytes written out.
273: * @exception IOException if an I/O error occurs.
274: */
275: static final int writeUTF(String str, DataOutput out)
276: throws IOException {
277: int strlen = str.length();
278: int utflen = 0;
279: char[] charr = new char[strlen];
280: int c, count = 0;
281:
282: str.getChars(0, strlen, charr, 0);
283:
284: for (int i = 0; i < strlen; i++) {
285: c = charr[i];
286: if ((c >= 0x0001) && (c <= 0x007F)) {
287: utflen++;
288: } else if (c > 0x07FF) {
289: utflen += 3;
290: } else {
291: utflen += 2;
292: }
293: }
294:
295: if (utflen > 65535) {
296: throw new UTFDataFormatException();
297: }
298:
299: byte[] bytearr = new byte[utflen + 2];
300: bytearr[count++] = (byte) ((utflen >>> 8) & 0xFF);
301: bytearr[count++] = (byte) ((utflen >>> 0) & 0xFF);
302: for (int i = 0; i < strlen; i++) {
303: c = charr[i];
304: if ((c >= 0x0001) && (c <= 0x007F)) {
305: bytearr[count++] = (byte) c;
306: } else if (c > 0x07FF) {
307: bytearr[count++] = (byte) (0xE0 | ((c >> 12) & 0x0F));
308: bytearr[count++] = (byte) (0x80 | ((c >> 6) & 0x3F));
309: bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
310: } else {
311: bytearr[count++] = (byte) (0xC0 | ((c >> 6) & 0x1F));
312: bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
313: }
314: }
315: out.write(bytearr);
316:
317: return utflen + 2;
318: }
319:
320: }
|