1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package java.io; 19 20import java.nio.ByteOrder; 21import java.nio.charset.ModifiedUtf8; 22import libcore.io.Memory; 23import libcore.io.SizeOf; 24 25/** 26 * Wraps an existing {@link OutputStream} and writes big-endian typed data to it. 27 * Typically, this stream can be read in by DataInputStream. Types that can be 28 * written include byte, 16-bit short, 32-bit int, 32-bit float, 64-bit long, 29 * 64-bit double, byte strings, and {@link DataInput MUTF-8} encoded strings. 30 * 31 * @see DataInputStream 32 */ 33public class DataOutputStream extends FilterOutputStream implements DataOutput { 34 private final byte[] scratch = new byte[8]; 35 36 /** 37 * The number of bytes written out so far. 38 */ 39 protected int written; 40 41 /** 42 * Constructs a new {@code DataOutputStream} on the {@code OutputStream} 43 * {@code out}. Note that data written by this stream is not in a human 44 * readable form but can be reconstructed by using a {@link DataInputStream} 45 * on the resulting output. 46 * 47 * @param out 48 * the target stream for writing. 49 */ 50 public DataOutputStream(OutputStream out) { 51 super(out); 52 } 53 54 /** 55 * Flushes this stream to ensure all pending data is sent out to the target 56 * stream. This implementation then also flushes the target stream. 57 * 58 * @throws IOException 59 * if an error occurs attempting to flush this stream. 60 */ 61 @Override 62 public void flush() throws IOException { 63 super.flush(); 64 } 65 66 /** 67 * Returns the total number of bytes written to the target stream so far. 68 * 69 * @return the number of bytes written to the target stream. 70 */ 71 public final int size() { 72 if (written < 0) { 73 written = Integer.MAX_VALUE; 74 } 75 return written; 76 } 77 78 /** 79 * Writes {@code count} bytes from the byte array {@code buffer} starting at 80 * {@code offset} to the target stream. 81 * 82 * @param buffer 83 * the buffer to write to the target stream. 84 * @param offset 85 * the index of the first byte in {@code buffer} to write. 86 * @param count 87 * the number of bytes from the {@code buffer} to write. 88 * @throws IOException 89 * if an error occurs while writing to the target stream. 90 * @throws NullPointerException 91 * if {@code buffer} is {@code null}. 92 */ 93 @Override 94 public void write(byte[] buffer, int offset, int count) throws IOException { 95 if (buffer == null) { 96 throw new NullPointerException("buffer == null"); 97 } 98 out.write(buffer, offset, count); 99 written += count; 100 } 101 102 /** 103 * Writes a byte to the target stream. Only the least significant byte of 104 * the integer {@code oneByte} is written. 105 * 106 * @param oneByte 107 * the byte to write to the target stream. 108 * @throws IOException 109 * if an error occurs while writing to the target stream. 110 * @see DataInputStream#readByte() 111 */ 112 @Override 113 public void write(int oneByte) throws IOException { 114 out.write(oneByte); 115 written++; 116 } 117 118 /** 119 * Writes a boolean to the target stream. 120 * 121 * @param val 122 * the boolean value to write to the target stream. 123 * @throws IOException 124 * if an error occurs while writing to the target stream. 125 * @see DataInputStream#readBoolean() 126 */ 127 public final void writeBoolean(boolean val) throws IOException { 128 out.write(val ? 1 : 0); 129 written++; 130 } 131 132 /** 133 * Writes an 8-bit byte to the target stream. Only the least significant 134 * byte of the integer {@code val} is written. 135 * 136 * @param val 137 * the byte value to write to the target stream. 138 * @throws IOException 139 * if an error occurs while writing to the target stream. 140 * @see DataInputStream#readByte() 141 * @see DataInputStream#readUnsignedByte() 142 */ 143 public final void writeByte(int val) throws IOException { 144 out.write(val); 145 written++; 146 } 147 148 public final void writeBytes(String str) throws IOException { 149 if (str.length() == 0) { 150 return; 151 } 152 byte[] bytes = new byte[str.length()]; 153 for (int index = 0; index < str.length(); index++) { 154 bytes[index] = (byte) str.charAt(index); 155 } 156 out.write(bytes); 157 written += bytes.length; 158 } 159 160 public final void writeChar(int val) throws IOException { 161 writeShort(val); 162 } 163 164 public final void writeChars(String str) throws IOException { 165 byte[] bytes = str.getBytes("UTF-16BE"); 166 out.write(bytes); 167 written += bytes.length; 168 } 169 170 public final void writeDouble(double val) throws IOException { 171 writeLong(Double.doubleToLongBits(val)); 172 } 173 174 public final void writeFloat(float val) throws IOException { 175 writeInt(Float.floatToIntBits(val)); 176 } 177 178 public final void writeInt(int val) throws IOException { 179 Memory.pokeInt(scratch, 0, val, ByteOrder.BIG_ENDIAN); 180 out.write(scratch, 0, SizeOf.INT); 181 written += SizeOf.INT; 182 } 183 184 public final void writeLong(long val) throws IOException { 185 Memory.pokeLong(scratch, 0, val, ByteOrder.BIG_ENDIAN); 186 out.write(scratch, 0, SizeOf.LONG); 187 written += SizeOf.LONG; 188 } 189 190 public final void writeShort(int val) throws IOException { 191 Memory.pokeShort(scratch, 0, (short) val, ByteOrder.BIG_ENDIAN); 192 out.write(scratch, 0, SizeOf.SHORT); 193 written += SizeOf.SHORT; 194 } 195 196 public final void writeUTF(String str) throws IOException { 197 write(ModifiedUtf8.encode(str)); 198 } 199} 200