Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/java/io/DataOutputStream.java
41152 views
1
/*
2
* Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package java.io;
27
28
/**
29
* A data output stream lets an application write primitive Java data
30
* types to an output stream in a portable way. An application can
31
* then use a data input stream to read the data back in.
32
* <p>
33
* A DataOutputStream is not safe for use by multiple concurrent
34
* threads. If a DataOutputStream is to be used by more than one
35
* thread then access to the data output stream should be controlled
36
* by appropriate synchronization.
37
*
38
* @see java.io.DataInputStream
39
* @since 1.0
40
*/
41
public class DataOutputStream extends FilterOutputStream implements DataOutput {
42
/**
43
* The number of bytes written to the data output stream so far.
44
* If this counter overflows, it will be wrapped to Integer.MAX_VALUE.
45
*/
46
protected int written;
47
48
/**
49
* bytearr is initialized on demand by writeUTF
50
*/
51
private byte[] bytearr = null;
52
53
private final byte[] writeBuffer = new byte[8];
54
55
/**
56
* Creates a new data output stream to write data to the specified
57
* underlying output stream. The counter {@code written} is
58
* set to zero.
59
*
60
* @param out the underlying output stream, to be saved for later
61
* use.
62
* @see java.io.FilterOutputStream#out
63
*/
64
public DataOutputStream(OutputStream out) {
65
super(out);
66
}
67
68
/**
69
* Increases the written counter by the specified value
70
* until it reaches Integer.MAX_VALUE.
71
*/
72
private void incCount(int value) {
73
int temp = written + value;
74
if (temp < 0) {
75
temp = Integer.MAX_VALUE;
76
}
77
written = temp;
78
}
79
80
/**
81
* Writes the specified byte (the low eight bits of the argument
82
* {@code b}) to the underlying output stream. If no exception
83
* is thrown, the counter {@code written} is incremented by
84
* {@code 1}.
85
* <p>
86
* Implements the {@code write} method of {@code OutputStream}.
87
*
88
* @param b the {@code byte} to be written.
89
* @throws IOException if an I/O error occurs.
90
* @see java.io.FilterOutputStream#out
91
*/
92
public synchronized void write(int b) throws IOException {
93
out.write(b);
94
incCount(1);
95
}
96
97
/**
98
* Writes {@code len} bytes from the specified byte array
99
* starting at offset {@code off} to the underlying output stream.
100
* If no exception is thrown, the counter {@code written} is
101
* incremented by {@code len}.
102
*
103
* @param b the data.
104
* @param off the start offset in the data.
105
* @param len the number of bytes to write.
106
* @throws IOException if an I/O error occurs.
107
* @see java.io.FilterOutputStream#out
108
*/
109
public synchronized void write(byte b[], int off, int len)
110
throws IOException
111
{
112
out.write(b, off, len);
113
incCount(len);
114
}
115
116
/**
117
* Flushes this data output stream. This forces any buffered output
118
* bytes to be written out to the stream.
119
* <p>
120
* The {@code flush} method of {@code DataOutputStream}
121
* calls the {@code flush} method of its underlying output stream.
122
*
123
* @throws IOException if an I/O error occurs.
124
* @see java.io.FilterOutputStream#out
125
* @see java.io.OutputStream#flush()
126
*/
127
public void flush() throws IOException {
128
out.flush();
129
}
130
131
/**
132
* Writes a {@code boolean} to the underlying output stream as
133
* a 1-byte value. The value {@code true} is written out as the
134
* value {@code (byte)1}; the value {@code false} is
135
* written out as the value {@code (byte)0}. If no exception is
136
* thrown, the counter {@code written} is incremented by
137
* {@code 1}.
138
*
139
* @param v a {@code boolean} value to be written.
140
* @throws IOException if an I/O error occurs.
141
* @see java.io.FilterOutputStream#out
142
*/
143
public final void writeBoolean(boolean v) throws IOException {
144
out.write(v ? 1 : 0);
145
incCount(1);
146
}
147
148
/**
149
* Writes out a {@code byte} to the underlying output stream as
150
* a 1-byte value. If no exception is thrown, the counter
151
* {@code written} is incremented by {@code 1}.
152
*
153
* @param v a {@code byte} value to be written.
154
* @throws IOException if an I/O error occurs.
155
* @see java.io.FilterOutputStream#out
156
*/
157
public final void writeByte(int v) throws IOException {
158
out.write(v);
159
incCount(1);
160
}
161
162
/**
163
* Writes a {@code short} to the underlying output stream as two
164
* bytes, high byte first. If no exception is thrown, the counter
165
* {@code written} is incremented by {@code 2}.
166
*
167
* @param v a {@code short} to be written.
168
* @throws IOException if an I/O error occurs.
169
* @see java.io.FilterOutputStream#out
170
*/
171
public final void writeShort(int v) throws IOException {
172
writeBuffer[0] = (byte)(v >>> 8);
173
writeBuffer[1] = (byte)(v >>> 0);
174
out.write(writeBuffer, 0, 2);
175
incCount(2);
176
}
177
178
/**
179
* Writes a {@code char} to the underlying output stream as a
180
* 2-byte value, high byte first. If no exception is thrown, the
181
* counter {@code written} is incremented by {@code 2}.
182
*
183
* @param v a {@code char} value to be written.
184
* @throws IOException if an I/O error occurs.
185
* @see java.io.FilterOutputStream#out
186
*/
187
public final void writeChar(int v) throws IOException {
188
writeBuffer[0] = (byte)(v >>> 8);
189
writeBuffer[1] = (byte)(v >>> 0);
190
out.write(writeBuffer, 0, 2);
191
incCount(2);
192
}
193
194
/**
195
* Writes an {@code int} to the underlying output stream as four
196
* bytes, high byte first. If no exception is thrown, the counter
197
* {@code written} is incremented by {@code 4}.
198
*
199
* @param v an {@code int} to be written.
200
* @throws IOException if an I/O error occurs.
201
* @see java.io.FilterOutputStream#out
202
*/
203
public final void writeInt(int v) throws IOException {
204
writeBuffer[0] = (byte)(v >>> 24);
205
writeBuffer[1] = (byte)(v >>> 16);
206
writeBuffer[2] = (byte)(v >>> 8);
207
writeBuffer[3] = (byte)(v >>> 0);
208
out.write(writeBuffer, 0, 4);
209
incCount(4);
210
}
211
212
/**
213
* Writes a {@code long} to the underlying output stream as eight
214
* bytes, high byte first. In no exception is thrown, the counter
215
* {@code written} is incremented by {@code 8}.
216
*
217
* @param v a {@code long} to be written.
218
* @throws IOException if an I/O error occurs.
219
* @see java.io.FilterOutputStream#out
220
*/
221
public final void writeLong(long v) throws IOException {
222
writeBuffer[0] = (byte)(v >>> 56);
223
writeBuffer[1] = (byte)(v >>> 48);
224
writeBuffer[2] = (byte)(v >>> 40);
225
writeBuffer[3] = (byte)(v >>> 32);
226
writeBuffer[4] = (byte)(v >>> 24);
227
writeBuffer[5] = (byte)(v >>> 16);
228
writeBuffer[6] = (byte)(v >>> 8);
229
writeBuffer[7] = (byte)(v >>> 0);
230
out.write(writeBuffer, 0, 8);
231
incCount(8);
232
}
233
234
/**
235
* Converts the float argument to an {@code int} using the
236
* {@code floatToIntBits} method in class {@code Float},
237
* and then writes that {@code int} value to the underlying
238
* output stream as a 4-byte quantity, high byte first. If no
239
* exception is thrown, the counter {@code written} is
240
* incremented by {@code 4}.
241
*
242
* @param v a {@code float} value to be written.
243
* @throws IOException if an I/O error occurs.
244
* @see java.io.FilterOutputStream#out
245
* @see java.lang.Float#floatToIntBits(float)
246
*/
247
public final void writeFloat(float v) throws IOException {
248
writeInt(Float.floatToIntBits(v));
249
}
250
251
/**
252
* Converts the double argument to a {@code long} using the
253
* {@code doubleToLongBits} method in class {@code Double},
254
* and then writes that {@code long} value to the underlying
255
* output stream as an 8-byte quantity, high byte first. If no
256
* exception is thrown, the counter {@code written} is
257
* incremented by {@code 8}.
258
*
259
* @param v a {@code double} value to be written.
260
* @throws IOException if an I/O error occurs.
261
* @see java.io.FilterOutputStream#out
262
* @see java.lang.Double#doubleToLongBits(double)
263
*/
264
public final void writeDouble(double v) throws IOException {
265
writeLong(Double.doubleToLongBits(v));
266
}
267
268
/**
269
* Writes out the string to the underlying output stream as a
270
* sequence of bytes. Each character in the string is written out, in
271
* sequence, by discarding its high eight bits. If no exception is
272
* thrown, the counter {@code written} is incremented by the
273
* length of {@code s}.
274
*
275
* @param s a string of bytes to be written.
276
* @throws IOException if an I/O error occurs.
277
* @see java.io.FilterOutputStream#out
278
*/
279
public final void writeBytes(String s) throws IOException {
280
int len = s.length();
281
for (int i = 0 ; i < len ; i++) {
282
out.write((byte)s.charAt(i));
283
}
284
incCount(len);
285
}
286
287
/**
288
* Writes a string to the underlying output stream as a sequence of
289
* characters. Each character is written to the data output stream as
290
* if by the {@code writeChar} method. If no exception is
291
* thrown, the counter {@code written} is incremented by twice
292
* the length of {@code s}.
293
*
294
* @param s a {@code String} value to be written.
295
* @throws IOException if an I/O error occurs.
296
* @see java.io.DataOutputStream#writeChar(int)
297
* @see java.io.FilterOutputStream#out
298
*/
299
public final void writeChars(String s) throws IOException {
300
int len = s.length();
301
for (int i = 0 ; i < len ; i++) {
302
int v = s.charAt(i);
303
writeBuffer[0] = (byte)(v >>> 8);
304
writeBuffer[1] = (byte)(v >>> 0);
305
out.write(writeBuffer, 0, 2);
306
}
307
incCount(len * 2);
308
}
309
310
/**
311
* Writes a string to the underlying output stream using
312
* <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
313
* encoding in a machine-independent manner.
314
* <p>
315
* First, two bytes are written to the output stream as if by the
316
* {@code writeShort} method giving the number of bytes to
317
* follow. This value is the number of bytes actually written out,
318
* not the length of the string. Following the length, each character
319
* of the string is output, in sequence, using the modified UTF-8 encoding
320
* for the character. If no exception is thrown, the counter
321
* {@code written} is incremented by the total number of
322
* bytes written to the output stream. This will be at least two
323
* plus the length of {@code str}, and at most two plus
324
* thrice the length of {@code str}.
325
*
326
* @param str a string to be written.
327
* @throws UTFDataFormatException if the modified UTF-8 encoding of
328
* {@code str} would exceed 65535 bytes in length
329
* @throws IOException if some other I/O error occurs.
330
* @see #writeChars(String)
331
*/
332
public final void writeUTF(String str) throws IOException {
333
writeUTF(str, this);
334
}
335
336
/**
337
* Writes a string to the specified DataOutput using
338
* <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
339
* encoding in a machine-independent manner.
340
* <p>
341
* First, two bytes are written to out as if by the {@code writeShort}
342
* method giving the number of bytes to follow. This value is the number of
343
* bytes actually written out, not the length of the string. Following the
344
* length, each character of the string is output, in sequence, using the
345
* modified UTF-8 encoding for the character. If no exception is thrown, the
346
* counter {@code written} is incremented by the total number of
347
* bytes written to the output stream. This will be at least two
348
* plus the length of {@code str}, and at most two plus
349
* thrice the length of {@code str}.
350
*
351
* @param str a string to be written.
352
* @param out destination to write to
353
* @return The number of bytes written out.
354
* @throws UTFDataFormatException if the modified UTF-8 encoding of
355
* {@code str} would exceed 65535 bytes in length
356
* @throws IOException if some other I/O error occurs.
357
*/
358
static int writeUTF(String str, DataOutput out) throws IOException {
359
final int strlen = str.length();
360
int utflen = strlen; // optimized for ASCII
361
362
for (int i = 0; i < strlen; i++) {
363
int c = str.charAt(i);
364
if (c >= 0x80 || c == 0)
365
utflen += (c >= 0x800) ? 2 : 1;
366
}
367
368
if (utflen > 65535 || /* overflow */ utflen < strlen)
369
throw new UTFDataFormatException(tooLongMsg(str, utflen));
370
371
final byte[] bytearr;
372
if (out instanceof DataOutputStream dos) {
373
if (dos.bytearr == null || (dos.bytearr.length < (utflen + 2)))
374
dos.bytearr = new byte[(utflen*2) + 2];
375
bytearr = dos.bytearr;
376
} else {
377
bytearr = new byte[utflen + 2];
378
}
379
380
int count = 0;
381
bytearr[count++] = (byte) ((utflen >>> 8) & 0xFF);
382
bytearr[count++] = (byte) ((utflen >>> 0) & 0xFF);
383
384
int i = 0;
385
for (i = 0; i < strlen; i++) { // optimized for initial run of ASCII
386
int c = str.charAt(i);
387
if (c >= 0x80 || c == 0) break;
388
bytearr[count++] = (byte) c;
389
}
390
391
for (; i < strlen; i++) {
392
int c = str.charAt(i);
393
if (c < 0x80 && c != 0) {
394
bytearr[count++] = (byte) c;
395
} else if (c >= 0x800) {
396
bytearr[count++] = (byte) (0xE0 | ((c >> 12) & 0x0F));
397
bytearr[count++] = (byte) (0x80 | ((c >> 6) & 0x3F));
398
bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
399
} else {
400
bytearr[count++] = (byte) (0xC0 | ((c >> 6) & 0x1F));
401
bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
402
}
403
}
404
out.write(bytearr, 0, utflen + 2);
405
return utflen + 2;
406
}
407
408
private static String tooLongMsg(String s, int bits32) {
409
int slen = s.length();
410
String head = s.substring(0, 8);
411
String tail = s.substring(slen - 8, slen);
412
// handle int overflow with max 3x expansion
413
long actualLength = (long)slen + Integer.toUnsignedLong(bits32 - slen);
414
return "encoded string (" + head + "..." + tail + ") too long: "
415
+ actualLength + " bytes";
416
}
417
418
/**
419
* Returns the current value of the counter {@code written},
420
* the number of bytes written to this data output stream so far.
421
* If the counter overflows, it will be wrapped to Integer.MAX_VALUE.
422
*
423
* @return the value of the {@code written} field.
424
* @see java.io.DataOutputStream#written
425
*/
426
public final int size() {
427
return written;
428
}
429
}
430
431