History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/io (208 of 18352 files). Show all

Unified · Split

208 files
  1. java/pkg/java/io/Bits.class +0 −0
  2. java/pkg/java/io/Bits.java +123 −0
  3. java/pkg/java/io/BufferedInputStream.class +0 −0
  4. java/pkg/java/io/BufferedInputStream.java +478 −0
  5. java/pkg/java/io/BufferedOutputStream.class +0 −0
  6. java/pkg/java/io/BufferedOutputStream.java +143 −0
  7. java/pkg/java/io/BufferedReader.class +0 −0
  8. java/pkg/java/io/BufferedReader.java +522 −0
  9. java/pkg/java/io/BufferedWriter.class +0 −0
  10. java/pkg/java/io/BufferedWriter.java +272 −0
  11. java/pkg/java/io/ByteArrayInputStream.class +0 −0
  12. java/pkg/java/io/ByteArrayInputStream.java +283 −0
  13. java/pkg/java/io/ByteArrayOutputStream.class +0 −0
  14. java/pkg/java/io/ByteArrayOutputStream.java +272 −0
  15. java/pkg/java/io/CharArrayReader.class +0 −0
  16. java/pkg/java/io/CharArrayReader.java +232 −0
  17. java/pkg/java/io/CharArrayWriter.class +0 −0
  18. java/pkg/java/io/CharArrayWriter.java +280 −0
  19. java/pkg/java/io/CharConversionException.class +0 −0
  20. java/pkg/java/io/CharConversionException.java +51 −0
  21. java/pkg/java/io/Closeable.class +0 −0
  22. java/pkg/java/io/Closeable.java +48 −0
  23. java/pkg/java/io/Console$1.class +0 −0
  24. java/pkg/java/io/Console$2.class +0 −0
  25. java/pkg/java/io/Console$3.class +0 −0
  26. java/pkg/java/io/Console$LineReader.class +0 −0
  27. java/pkg/java/io/Console.class +0 −0
  28. java/pkg/java/io/Console.java +578 −0
  29. java/pkg/java/io/DataInput.class +0 −0
  30. java/pkg/java/io/DataInput.java +635 −0
  31. java/pkg/java/io/DataInputStream.class +0 −0
  32. java/pkg/java/io/DataInputStream.java +663 −0
  33. java/pkg/java/io/DataOutput.class +0 −0
  34. java/pkg/java/io/DataOutput.java +354 −0
  35. java/pkg/java/io/DataOutputStream.class +0 −0
  36. java/pkg/java/io/DataOutputStream.java +416 −0
  37. java/pkg/java/io/DeleteOnExitHook$1.class +0 −0
  38. java/pkg/java/io/DeleteOnExitHook.class +0 −0
  39. java/pkg/java/io/DeleteOnExitHook.java +83 −0
  40. java/pkg/java/io/EOFException.class +0 −0
  41. java/pkg/java/io/EOFException.java +65 −0
  42. java/pkg/java/io/ExpiringCache$1.class +0 −0
  43. java/pkg/java/io/ExpiringCache$Entry.class +0 −0
  44. java/pkg/java/io/ExpiringCache.class +0 −0
  45. java/pkg/java/io/ExpiringCache.java +127 −0
  46. java/pkg/java/io/Externalizable.class +0 −0
  47. java/pkg/java/io/Externalizable.java +97 −0
  48. java/pkg/java/io/File$TempDirectory.class +0 −0
  49. java/pkg/java/io/File.class +0 −0
  50. java/pkg/java/io/File.java +2076 −0
  51. java/pkg/java/io/FileFilter.class +0 −0
  52. java/pkg/java/io/FileFilter.java +50 −0
  53. java/pkg/java/io/FileInputStream.class +0 −0
  54. java/pkg/java/io/FileInputStream.java +408 −0
  55. java/pkg/java/io/FileNotFoundException.class +0 −0
  56. java/pkg/java/io/FileNotFoundException.java +82 −0
  57. java/pkg/java/io/FileOutputStream.class +0 −0
  58. java/pkg/java/io/FileOutputStream.java +451 −0
  59. java/pkg/java/io/FilePermission$1.class +0 −0
  60. java/pkg/java/io/FilePermission.class +0 −0
  61. java/pkg/java/io/FilePermission.java +859 −0
  62. java/pkg/java/io/FilePermissionCollection.class +0 −0
  63. java/pkg/java/io/FileReader.class +0 −0
  64. java/pkg/java/io/FileReader.java +85 −0
  65. java/pkg/java/io/FileSystem.class +0 −0
  66. java/pkg/java/io/FileSystem.java +252 −0
  67. java/pkg/java/io/FileWriter.class +0 −0
  68. java/pkg/java/io/FileWriter.java +119 −0
  69. java/pkg/java/io/FilenameFilter.class +0 −0
  70. java/pkg/java/io/FilenameFilter.java +53 −0
  71. java/pkg/java/io/FilterInputStream.class +0 −0
  72. java/pkg/java/io/FilterInputStream.java +245 −0
  73. java/pkg/java/io/FilterOutputStream.class +0 −0
  74. java/pkg/java/io/FilterOutputStream.java +162 −0
  75. java/pkg/java/io/FilterReader.class +0 −0
  76. java/pkg/java/io/FilterReader.java +124 −0
  77. java/pkg/java/io/FilterWriter.class +0 −0
  78. java/pkg/java/io/FilterWriter.java +107 −0
  79. java/pkg/java/io/Flushable.class +0 −0
  80. java/pkg/java/io/Flushable.java +47 −0
  81. java/pkg/java/io/IOError.class +0 −0
  82. java/pkg/java/io/IOError.java +50 −0
  83. java/pkg/java/io/IOException.class +0 −0
  84. java/pkg/java/io/IOException.java +101 −0
  85. java/pkg/java/io/InputStream.class +0 −0
  86. java/pkg/java/io/InputStream.java +370 −0
  87. java/pkg/java/io/InputStreamReader.class +0 −0
  88. java/pkg/java/io/InputStreamReader.java +201 −0
  89. java/pkg/java/io/InterruptedIOException.class +0 −0
  90. java/pkg/java/io/InterruptedIOException.java +74 −0
  91. java/pkg/java/io/InvalidClassException.class +0 −0
  92. java/pkg/java/io/InvalidClassException.java +81 −0
  93. java/pkg/java/io/InvalidObjectException.class +0 −0
  94. java/pkg/java/io/InvalidObjectException.java +51 −0
  95. java/pkg/java/io/LineNumberInputStream.class +0 −0
  96. java/pkg/java/io/LineNumberInputStream.java +292 −0
  97. java/pkg/java/io/LineNumberReader.class +0 −0
  98. java/pkg/java/io/LineNumberReader.java +281 −0
  99. java/pkg/java/io/NotActiveException.class +0 −0
  100. java/pkg/java/io/NotActiveException.java +53 −0
  101. java/pkg/java/io/NotSerializableException.class +0 −0
  102. java/pkg/java/io/NotSerializableException.java +55 −0
  103. java/pkg/java/io/ObjectInput.class +0 −0
  104. java/pkg/java/io/ObjectInput.java +107 −0
  105. java/pkg/java/io/ObjectInputStream$1.class +0 −0
  106. java/pkg/java/io/ObjectInputStream$BlockDataInputStream.class +0 −0
  107. java/pkg/java/io/ObjectInputStream$Caches.class +0 −0
  108. java/pkg/java/io/ObjectInputStream$GetField.class +0 −0
  109. java/pkg/java/io/ObjectInputStream$GetFieldImpl.class +0 −0
  110. java/pkg/java/io/ObjectInputStream$HandleTable$HandleList.class +0 −0
  111. java/pkg/java/io/ObjectInputStream$HandleTable.class +0 −0
  112. java/pkg/java/io/ObjectInputStream$PeekInputStream.class +0 −0
  113. java/pkg/java/io/ObjectInputStream$ValidationList$1.class +0 −0
  114. java/pkg/java/io/ObjectInputStream$ValidationList$Callback.class +0 −0
  115. java/pkg/java/io/ObjectInputStream$ValidationList.class +0 −0
  116. java/pkg/java/io/ObjectInputStream.class +0 −0
  117. java/pkg/java/io/ObjectInputStream.java +3508 −0
  118. java/pkg/java/io/ObjectInputValidation.class +0 −0
  119. java/pkg/java/io/ObjectInputValidation.java +45 −0
  120. java/pkg/java/io/ObjectOutput.class +0 −0
  121. java/pkg/java/io/ObjectOutput.java +90 −0
  122. java/pkg/java/io/ObjectOutputStream$1.class +0 −0
  123. java/pkg/java/io/ObjectOutputStream$BlockDataOutputStream.class +0 −0
  124. java/pkg/java/io/ObjectOutputStream$Caches.class +0 −0
  125. java/pkg/java/io/ObjectOutputStream$DebugTraceInfoStack.class +0 −0
  126. java/pkg/java/io/ObjectOutputStream$HandleTable.class +0 −0
  127. java/pkg/java/io/ObjectOutputStream$PutField.class +0 −0
  128. java/pkg/java/io/ObjectOutputStream$PutFieldImpl.class +0 −0
  129. java/pkg/java/io/ObjectOutputStream$ReplaceTable.class +0 −0
  130. java/pkg/java/io/ObjectOutputStream.class +0 −0
  131. java/pkg/java/io/ObjectOutputStream.java +2454 −0
  132. java/pkg/java/io/ObjectStreamClass$1.class +0 −0
  133. java/pkg/java/io/ObjectStreamClass$2.class +0 −0
  134. java/pkg/java/io/ObjectStreamClass$3.class +0 −0
  135. java/pkg/java/io/ObjectStreamClass$4.class +0 −0
  136. java/pkg/java/io/ObjectStreamClass$5.class +0 −0
  137. java/pkg/java/io/ObjectStreamClass$Caches.class +0 −0
  138. java/pkg/java/io/ObjectStreamClass$ClassDataSlot.class +0 −0
  139. java/pkg/java/io/ObjectStreamClass$EntryFuture$1.class +0 −0
  140. java/pkg/java/io/ObjectStreamClass$EntryFuture.class +0 −0
  141. java/pkg/java/io/ObjectStreamClass$FieldReflector.class +0 −0
  142. java/pkg/java/io/ObjectStreamClass$FieldReflectorKey.class +0 −0
  143. java/pkg/java/io/ObjectStreamClass$MemberSignature.class +0 −0
  144. java/pkg/java/io/ObjectStreamClass$WeakClassKey.class +0 −0
  145. java/pkg/java/io/ObjectStreamClass.class +0 −0
  146. java/pkg/java/io/ObjectStreamClass.java +2304 −0
  147. java/pkg/java/io/ObjectStreamConstants.class +0 −0
  148. java/pkg/java/io/ObjectStreamConstants.java +235 −0
  149. java/pkg/java/io/ObjectStreamException.class +0 −0
  150. java/pkg/java/io/ObjectStreamException.java +53 −0
  151. java/pkg/java/io/ObjectStreamField.class +0 −0
  152. java/pkg/java/io/ObjectStreamField.java +314 −0
  153. java/pkg/java/io/OptionalDataException.class +0 −0
  154. java/pkg/java/io/OptionalDataException.java +83 −0
  155. java/pkg/java/io/OutputStream.class +0 −0
  156. java/pkg/java/io/OutputStream.java +154 −0
  157. java/pkg/java/io/OutputStreamWriter.class +0 −0
  158. java/pkg/java/io/OutputStreamWriter.java +235 −0
  159. java/pkg/java/io/PipedInputStream.class +0 −0
  160. java/pkg/java/io/PipedInputStream.java +450 −0
  161. java/pkg/java/io/PipedOutputStream.class +0 −0
  162. java/pkg/java/io/PipedOutputStream.java +179 −0
  163. java/pkg/java/io/PipedReader.class +0 −0
  164. java/pkg/java/io/PipedReader.java +363 −0
  165. java/pkg/java/io/PipedWriter.class +0 −0
  166. java/pkg/java/io/PipedWriter.java +184 −0
  167. java/pkg/java/io/PrintStream.class +0 −0
  168. java/pkg/java/io/PrintStream.java +1129 −0
  169. java/pkg/java/io/PrintWriter.class +0 −0
  170. java/pkg/java/io/PrintWriter.java +1066 −0
  171. java/pkg/java/io/PushbackInputStream.class +0 −0
  172. java/pkg/java/io/PushbackInputStream.java +383 −0
  173. java/pkg/java/io/PushbackReader.class +0 −0
  174. java/pkg/java/io/PushbackReader.java +281 −0
  175. java/pkg/java/io/RandomAccessFile.class +0 −0
  176. java/pkg/java/io/RandomAccessFile.java +1125 −0
  177. java/pkg/java/io/Reader.class +0 −0
  178. java/pkg/java/io/Reader.java +262 −0
  179. java/pkg/java/io/SequenceInputStream.class +0 −0
  180. java/pkg/java/io/SequenceInputStream.java +235 −0
  181. java/pkg/java/io/SerialCallbackContext.class +0 −0
  182. java/pkg/java/io/SerialCallbackContext.java +54 −0
  183. java/pkg/java/io/Serializable.class +0 −0
  184. java/pkg/java/io/Serializable.java +170 −0
  185. java/pkg/java/io/SerializablePermission.class +0 −0
  186. java/pkg/java/io/SerializablePermission.java +132 −0
  187. java/pkg/java/io/StreamCorruptedException.class +0 −0
  188. java/pkg/java/io/StreamCorruptedException.java +54 −0
  189. java/pkg/java/io/StreamTokenizer.class +0 −0
  190. java/pkg/java/io/StreamTokenizer.java +834 −0
  191. java/pkg/java/io/StringBufferInputStream.class +0 −0
  192. java/pkg/java/io/StringBufferInputStream.java +172 −0
  193. java/pkg/java/io/StringReader.class +0 −0
  194. java/pkg/java/io/StringReader.java +201 −0
  195. java/pkg/java/io/StringWriter.class +0 −0
  196. java/pkg/java/io/StringWriter.java +236 −0
  197. java/pkg/java/io/SyncFailedException.class +0 −0
  198. java/pkg/java/io/SyncFailedException.java +48 −0
  199. java/pkg/java/io/UTFDataFormatException.class +0 −0
  200. java/pkg/java/io/UTFDataFormatException.java +69 −0
  201. java/pkg/java/io/UnsupportedEncodingException.class +0 −0
  202. java/pkg/java/io/UnsupportedEncodingException.java +52 −0
  203. java/pkg/java/io/WriteAbortedException.class +0 −0
  204. java/pkg/java/io/WriteAbortedException.java +93 −0
  205. java/pkg/java/io/Writer.class +0 −0
  206. java/pkg/java/io/Writer.java +325 −0
  207. java/pkg/java/io/mkfile +89 −0
  208. java/pkg/java/io/package.html +52 −0
java/pkg/java/io/Bits.class+0−0

Binary file not shown.

java/pkg/java/io/Bits.java+123−0
@@ -0,0 +1,123 @@
1/*
2 * Copyright (c) 2001, 2010, 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
26package java.io;
27
28/**
29 * Utility methods for packing/unpacking primitive values in/out of byte arrays
30 * using big-endian byte ordering.
31 */
32class Bits {
33
34 /*
35 * Methods for unpacking primitive values from byte arrays starting at
36 * given offsets.
37 */
38
39 static boolean getBoolean(byte[] b, int off) {
40 return b[off] != 0;
41 }
42
43 static char getChar(byte[] b, int off) {
44 return (char) ((b[off + 1] & 0xFF) +
45 (b[off] << 8));
46 }
47
48 static short getShort(byte[] b, int off) {
49 return (short) ((b[off + 1] & 0xFF) +
50 (b[off] << 8));
51 }
52
53 static int getInt(byte[] b, int off) {
54 return ((b[off + 3] & 0xFF) ) +
55 ((b[off + 2] & 0xFF) << 8) +
56 ((b[off + 1] & 0xFF) << 16) +
57 ((b[off ] ) << 24);
58 }
59
60 static float getFloat(byte[] b, int off) {
61 return Float.intBitsToFloat(getInt(b, off));
62 }
63
64 static long getLong(byte[] b, int off) {
65 return ((b[off + 7] & 0xFFL) ) +
66 ((b[off + 6] & 0xFFL) << 8) +
67 ((b[off + 5] & 0xFFL) << 16) +
68 ((b[off + 4] & 0xFFL) << 24) +
69 ((b[off + 3] & 0xFFL) << 32) +
70 ((b[off + 2] & 0xFFL) << 40) +
71 ((b[off + 1] & 0xFFL) << 48) +
72 (((long) b[off]) << 56);
73 }
74
75 static double getDouble(byte[] b, int off) {
76 return Double.longBitsToDouble(getLong(b, off));
77 }
78
79 /*
80 * Methods for packing primitive values into byte arrays starting at given
81 * offsets.
82 */
83
84 static void putBoolean(byte[] b, int off, boolean val) {
85 b[off] = (byte) (val ? 1 : 0);
86 }
87
88 static void putChar(byte[] b, int off, char val) {
89 b[off + 1] = (byte) (val );
90 b[off ] = (byte) (val >>> 8);
91 }
92
93 static void putShort(byte[] b, int off, short val) {
94 b[off + 1] = (byte) (val );
95 b[off ] = (byte) (val >>> 8);
96 }
97
98 static void putInt(byte[] b, int off, int val) {
99 b[off + 3] = (byte) (val );
100 b[off + 2] = (byte) (val >>> 8);
101 b[off + 1] = (byte) (val >>> 16);
102 b[off ] = (byte) (val >>> 24);
103 }
104
105 static void putFloat(byte[] b, int off, float val) {
106 putInt(b, off, Float.floatToIntBits(val));
107 }
108
109 static void putLong(byte[] b, int off, long val) {
110 b[off + 7] = (byte) (val );
111 b[off + 6] = (byte) (val >>> 8);
112 b[off + 5] = (byte) (val >>> 16);
113 b[off + 4] = (byte) (val >>> 24);
114 b[off + 3] = (byte) (val >>> 32);
115 b[off + 2] = (byte) (val >>> 40);
116 b[off + 1] = (byte) (val >>> 48);
117 b[off ] = (byte) (val >>> 56);
118 }
119
120 static void putDouble(byte[] b, int off, double val) {
121 putLong(b, off, Double.doubleToLongBits(val));
122 }
123}
java/pkg/java/io/BufferedInputStream.class+0−0

Binary file not shown.

java/pkg/java/io/BufferedInputStream.java+478−0
@@ -0,0 +1,478 @@
1/*
2 * Copyright (c) 1994, 2010, 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
26package java.io;
27import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
28
29/**
30 * A <code>BufferedInputStream</code> adds
31 * functionality to another input stream-namely,
32 * the ability to buffer the input and to
33 * support the <code>mark</code> and <code>reset</code>
34 * methods. When the <code>BufferedInputStream</code>
35 * is created, an internal buffer array is
36 * created. As bytes from the stream are read
37 * or skipped, the internal buffer is refilled
38 * as necessary from the contained input stream,
39 * many bytes at a time. The <code>mark</code>
40 * operation remembers a point in the input
41 * stream and the <code>reset</code> operation
42 * causes all the bytes read since the most
43 * recent <code>mark</code> operation to be
44 * reread before new bytes are taken from
45 * the contained input stream.
46 *
47 * @author Arthur van Hoff
48 * @since JDK1.0
49 */
50public
51class BufferedInputStream extends FilterInputStream {
52
53 private static int defaultBufferSize = 8192;
54
55 /**
56 * The internal buffer array where the data is stored. When necessary,
57 * it may be replaced by another array of
58 * a different size.
59 */
60 protected volatile byte buf[];
61
62 /**
63 * Atomic updater to provide compareAndSet for buf. This is
64 * necessary because closes can be asynchronous. We use nullness
65 * of buf[] as primary indicator that this stream is closed. (The
66 * "in" field is also nulled out on close.)
67 */
68 private static final
69 AtomicReferenceFieldUpdater<BufferedInputStream, byte[]> bufUpdater =
70 AtomicReferenceFieldUpdater.newUpdater
71 (BufferedInputStream.class, byte[].class, "buf");
72
73 /**
74 * The index one greater than the index of the last valid byte in
75 * the buffer.
76 * This value is always
77 * in the range <code>0</code> through <code>buf.length</code>;
78 * elements <code>buf[0]</code> through <code>buf[count-1]
79 * </code>contain buffered input data obtained
80 * from the underlying input stream.
81 */
82 protected int count;
83
84 /**
85 * The current position in the buffer. This is the index of the next
86 * character to be read from the <code>buf</code> array.
87 * <p>
88 * This value is always in the range <code>0</code>
89 * through <code>count</code>. If it is less
90 * than <code>count</code>, then <code>buf[pos]</code>
91 * is the next byte to be supplied as input;
92 * if it is equal to <code>count</code>, then
93 * the next <code>read</code> or <code>skip</code>
94 * operation will require more bytes to be
95 * read from the contained input stream.
96 *
97 * @see java.io.BufferedInputStream#buf
98 */
99 protected int pos;
100
101 /**
102 * The value of the <code>pos</code> field at the time the last
103 * <code>mark</code> method was called.
104 * <p>
105 * This value is always
106 * in the range <code>-1</code> through <code>pos</code>.
107 * If there is no marked position in the input
108 * stream, this field is <code>-1</code>. If
109 * there is a marked position in the input
110 * stream, then <code>buf[markpos]</code>
111 * is the first byte to be supplied as input
112 * after a <code>reset</code> operation. If
113 * <code>markpos</code> is not <code>-1</code>,
114 * then all bytes from positions <code>buf[markpos]</code>
115 * through <code>buf[pos-1]</code> must remain
116 * in the buffer array (though they may be
117 * moved to another place in the buffer array,
118 * with suitable adjustments to the values
119 * of <code>count</code>, <code>pos</code>,
120 * and <code>markpos</code>); they may not
121 * be discarded unless and until the difference
122 * between <code>pos</code> and <code>markpos</code>
123 * exceeds <code>marklimit</code>.
124 *
125 * @see java.io.BufferedInputStream#mark(int)
126 * @see java.io.BufferedInputStream#pos
127 */
128 protected int markpos = -1;
129
130 /**
131 * The maximum read ahead allowed after a call to the
132 * <code>mark</code> method before subsequent calls to the
133 * <code>reset</code> method fail.
134 * Whenever the difference between <code>pos</code>
135 * and <code>markpos</code> exceeds <code>marklimit</code>,
136 * then the mark may be dropped by setting
137 * <code>markpos</code> to <code>-1</code>.
138 *
139 * @see java.io.BufferedInputStream#mark(int)
140 * @see java.io.BufferedInputStream#reset()
141 */
142 protected int marklimit;
143
144 /**
145 * Check to make sure that underlying input stream has not been
146 * nulled out due to close; if not return it;
147 */
148 private InputStream getInIfOpen() throws IOException {
149 InputStream input = in;
150 if (input == null)
151 throw new IOException("Stream closed");
152 return input;
153 }
154
155 /**
156 * Check to make sure that buffer has not been nulled out due to
157 * close; if not return it;
158 */
159 private byte[] getBufIfOpen() throws IOException {
160 byte[] buffer = buf;
161 if (buffer == null)
162 throw new IOException("Stream closed");
163 return buffer;
164 }
165
166 /**
167 * Creates a <code>BufferedInputStream</code>
168 * and saves its argument, the input stream
169 * <code>in</code>, for later use. An internal
170 * buffer array is created and stored in <code>buf</code>.
171 *
172 * @param in the underlying input stream.
173 */
174 public BufferedInputStream(InputStream in) {
175 this(in, defaultBufferSize);
176 }
177
178 /**
179 * Creates a <code>BufferedInputStream</code>
180 * with the specified buffer size,
181 * and saves its argument, the input stream
182 * <code>in</code>, for later use. An internal
183 * buffer array of length <code>size</code>
184 * is created and stored in <code>buf</code>.
185 *
186 * @param in the underlying input stream.
187 * @param size the buffer size.
188 * @exception IllegalArgumentException if size <= 0.
189 */
190 public BufferedInputStream(InputStream in, int size) {
191 super(in);
192 if (size <= 0) {
193 throw new IllegalArgumentException("Buffer size <= 0");
194 }
195 buf = new byte[size];
196 }
197
198 /**
199 * Fills the buffer with more data, taking into account
200 * shuffling and other tricks for dealing with marks.
201 * Assumes that it is being called by a synchronized method.
202 * This method also assumes that all data has already been read in,
203 * hence pos > count.
204 */
205 private void fill() throws IOException {
206 byte[] buffer = getBufIfOpen();
207 if (markpos < 0)
208 pos = 0; /* no mark: throw away the buffer */
209 else if (pos >= buffer.length) /* no room left in buffer */
210 if (markpos > 0) { /* can throw away early part of the buffer */
211 int sz = pos - markpos;
212 System.arraycopy(buffer, markpos, buffer, 0, sz);
213 pos = sz;
214 markpos = 0;
215 } else if (buffer.length >= marklimit) {
216 markpos = -1; /* buffer got too big, invalidate mark */
217 pos = 0; /* drop buffer contents */
218 } else { /* grow buffer */
219 int nsz = pos * 2;
220 if (nsz > marklimit)
221 nsz = marklimit;
222 byte nbuf[] = new byte[nsz];
223 System.arraycopy(buffer, 0, nbuf, 0, pos);
224 if (!bufUpdater.compareAndSet(this, buffer, nbuf)) {
225 // Can't replace buf if there was an async close.
226 // Note: This would need to be changed if fill()
227 // is ever made accessible to multiple threads.
228 // But for now, the only way CAS can fail is via close.
229 // assert buf == null;
230 throw new IOException("Stream closed");
231 }
232 buffer = nbuf;
233 }
234 count = pos;
235 int n = getInIfOpen().read(buffer, pos, buffer.length - pos);
236 if (n > 0)
237 count = n + pos;
238 }
239
240 /**
241 * See
242 * the general contract of the <code>read</code>
243 * method of <code>InputStream</code>.
244 *
245 * @return the next byte of data, or <code>-1</code> if the end of the
246 * stream is reached.
247 * @exception IOException if this input stream has been closed by
248 * invoking its {@link #close()} method,
249 * or an I/O error occurs.
250 * @see java.io.FilterInputStream#in
251 */
252 public synchronized int read() throws IOException {
253 if (pos >= count) {
254 fill();
255 if (pos >= count)
256 return -1;
257 }
258 return getBufIfOpen()[pos++] & 0xff;
259 }
260
261 /**
262 * Read characters into a portion of an array, reading from the underlying
263 * stream at most once if necessary.
264 */
265 private int read1(byte[] b, int off, int len) throws IOException {
266 int avail = count - pos;
267 if (avail <= 0) {
268 /* If the requested length is at least as large as the buffer, and
269 if there is no mark/reset activity, do not bother to copy the
270 bytes into the local buffer. In this way buffered streams will
271 cascade harmlessly. */
272 if (len >= getBufIfOpen().length && markpos < 0) {
273 return getInIfOpen().read(b, off, len);
274 }
275 fill();
276 avail = count - pos;
277 if (avail <= 0) return -1;
278 }
279 int cnt = (avail < len) ? avail : len;
280 System.arraycopy(getBufIfOpen(), pos, b, off, cnt);
281 pos += cnt;
282 return cnt;
283 }
284
285 /**
286 * Reads bytes from this byte-input stream into the specified byte array,
287 * starting at the given offset.
288 *
289 * <p> This method implements the general contract of the corresponding
290 * <code>{@link InputStream#read(byte[], int, int) read}</code> method of
291 * the <code>{@link InputStream}</code> class. As an additional
292 * convenience, it attempts to read as many bytes as possible by repeatedly
293 * invoking the <code>read</code> method of the underlying stream. This
294 * iterated <code>read</code> continues until one of the following
295 * conditions becomes true: <ul>
296 *
297 * <li> The specified number of bytes have been read,
298 *
299 * <li> The <code>read</code> method of the underlying stream returns
300 * <code>-1</code>, indicating end-of-file, or
301 *
302 * <li> The <code>available</code> method of the underlying stream
303 * returns zero, indicating that further input requests would block.
304 *
305 * </ul> If the first <code>read</code> on the underlying stream returns
306 * <code>-1</code> to indicate end-of-file then this method returns
307 * <code>-1</code>. Otherwise this method returns the number of bytes
308 * actually read.
309 *
310 * <p> Subclasses of this class are encouraged, but not required, to
311 * attempt to read as many bytes as possible in the same fashion.
312 *
313 * @param b destination buffer.
314 * @param off offset at which to start storing bytes.
315 * @param len maximum number of bytes to read.
316 * @return the number of bytes read, or <code>-1</code> if the end of
317 * the stream has been reached.
318 * @exception IOException if this input stream has been closed by
319 * invoking its {@link #close()} method,
320 * or an I/O error occurs.
321 */
322 public synchronized int read(byte b[], int off, int len)
323 throws IOException
324 {
325 getBufIfOpen(); // Check for closed stream
326 if ((off | len | (off + len) | (b.length - (off + len))) < 0) {
327 throw new IndexOutOfBoundsException();
328 } else if (len == 0) {
329 return 0;
330 }
331
332 int n = 0;
333 for (;;) {
334 int nread = read1(b, off + n, len - n);
335 if (nread <= 0)
336 return (n == 0) ? nread : n;
337 n += nread;
338 if (n >= len)
339 return n;
340 // if not closed but no bytes available, return
341 InputStream input = in;
342 if (input != null && input.available() <= 0)
343 return n;
344 }
345 }
346
347 /**
348 * See the general contract of the <code>skip</code>
349 * method of <code>InputStream</code>.
350 *
351 * @exception IOException if the stream does not support seek,
352 * or if this input stream has been closed by
353 * invoking its {@link #close()} method, or an
354 * I/O error occurs.
355 */
356 public synchronized long skip(long n) throws IOException {
357 getBufIfOpen(); // Check for closed stream
358 if (n <= 0) {
359 return 0;
360 }
361 long avail = count - pos;
362
363 if (avail <= 0) {
364 // If no mark position set then don't keep in buffer
365 if (markpos <0)
366 return getInIfOpen().skip(n);
367
368 // Fill in buffer to save bytes for reset
369 fill();
370 avail = count - pos;
371 if (avail <= 0)
372 return 0;
373 }
374
375 long skipped = (avail < n) ? avail : n;
376 pos += skipped;
377 return skipped;
378 }
379
380 /**
381 * Returns an estimate of the number of bytes that can be read (or
382 * skipped over) from this input stream without blocking by the next
383 * invocation of a method for this input stream. The next invocation might be
384 * the same thread or another thread. A single read or skip of this
385 * many bytes will not block, but may read or skip fewer bytes.
386 * <p>
387 * This method returns the sum of the number of bytes remaining to be read in
388 * the buffer (<code>count&nbsp;- pos</code>) and the result of calling the
389 * {@link java.io.FilterInputStream#in in}.available().
390 *
391 * @return an estimate of the number of bytes that can be read (or skipped
392 * over) from this input stream without blocking.
393 * @exception IOException if this input stream has been closed by
394 * invoking its {@link #close()} method,
395 * or an I/O error occurs.
396 */
397 public synchronized int available() throws IOException {
398 int n = count - pos;
399 int avail = getInIfOpen().available();
400 return n > (Integer.MAX_VALUE - avail)
401 ? Integer.MAX_VALUE
402 : n + avail;
403 }
404
405 /**
406 * See the general contract of the <code>mark</code>
407 * method of <code>InputStream</code>.
408 *
409 * @param readlimit the maximum limit of bytes that can be read before
410 * the mark position becomes invalid.
411 * @see java.io.BufferedInputStream#reset()
412 */
413 public synchronized void mark(int readlimit) {
414 marklimit = readlimit;
415 markpos = pos;
416 }
417
418 /**
419 * See the general contract of the <code>reset</code>
420 * method of <code>InputStream</code>.
421 * <p>
422 * If <code>markpos</code> is <code>-1</code>
423 * (no mark has been set or the mark has been
424 * invalidated), an <code>IOException</code>
425 * is thrown. Otherwise, <code>pos</code> is
426 * set equal to <code>markpos</code>.
427 *
428 * @exception IOException if this stream has not been marked or,
429 * if the mark has been invalidated, or the stream
430 * has been closed by invoking its {@link #close()}
431 * method, or an I/O error occurs.
432 * @see java.io.BufferedInputStream#mark(int)
433 */
434 public synchronized void reset() throws IOException {
435 getBufIfOpen(); // Cause exception if closed
436 if (markpos < 0)
437 throw new IOException("Resetting to invalid mark");
438 pos = markpos;
439 }
440
441 /**
442 * Tests if this input stream supports the <code>mark</code>
443 * and <code>reset</code> methods. The <code>markSupported</code>
444 * method of <code>BufferedInputStream</code> returns
445 * <code>true</code>.
446 *
447 * @return a <code>boolean</code> indicating if this stream type supports
448 * the <code>mark</code> and <code>reset</code> methods.
449 * @see java.io.InputStream#mark(int)
450 * @see java.io.InputStream#reset()
451 */
452 public boolean markSupported() {
453 return true;
454 }
455
456 /**
457 * Closes this input stream and releases any system resources
458 * associated with the stream.
459 * Once the stream has been closed, further read(), available(), reset(),
460 * or skip() invocations will throw an IOException.
461 * Closing a previously closed stream has no effect.
462 *
463 * @exception IOException if an I/O error occurs.
464 */
465 public void close() throws IOException {
466 byte[] buffer;
467 while ( (buffer = buf) != null) {
468 if (bufUpdater.compareAndSet(this, buffer, null)) {
469 InputStream input = in;
470 in = null;
471 if (input != null)
472 input.close();
473 return;
474 }
475 // Else retry in case a new buf was CASed in fill()
476 }
477 }
478}
java/pkg/java/io/BufferedOutputStream.class+0−0

Binary file not shown.

java/pkg/java/io/BufferedOutputStream.java+143−0
@@ -0,0 +1,143 @@
1/*
2 * Copyright (c) 1994, 2003, 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
26package java.io;
27
28/**
29 * The class implements a buffered output stream. By setting up such
30 * an output stream, an application can write bytes to the underlying
31 * output stream without necessarily causing a call to the underlying
32 * system for each byte written.
33 *
34 * @author Arthur van Hoff
35 * @since JDK1.0
36 */
37public
38class BufferedOutputStream extends FilterOutputStream {
39 /**
40 * The internal buffer where data is stored.
41 */
42 protected byte buf[];
43
44 /**
45 * The number of valid bytes in the buffer. This value is always
46 * in the range <tt>0</tt> through <tt>buf.length</tt>; elements
47 * <tt>buf[0]</tt> through <tt>buf[count-1]</tt> contain valid
48 * byte data.
49 */
50 protected int count;
51
52 /**
53 * Creates a new buffered output stream to write data to the
54 * specified underlying output stream.
55 *
56 * @param out the underlying output stream.
57 */
58 public BufferedOutputStream(OutputStream out) {
59 this(out, 8192);
60 }
61
62 /**
63 * Creates a new buffered output stream to write data to the
64 * specified underlying output stream with the specified buffer
65 * size.
66 *
67 * @param out the underlying output stream.
68 * @param size the buffer size.
69 * @exception IllegalArgumentException if size &lt;= 0.
70 */
71 public BufferedOutputStream(OutputStream out, int size) {
72 super(out);
73 if (size <= 0) {
74 throw new IllegalArgumentException("Buffer size <= 0");
75 }
76 buf = new byte[size];
77 }
78
79 /** Flush the internal buffer */
80 private void flushBuffer() throws IOException {
81 if (count > 0) {
82 out.write(buf, 0, count);
83 count = 0;
84 }
85 }
86
87 /**
88 * Writes the specified byte to this buffered output stream.
89 *
90 * @param b the byte to be written.
91 * @exception IOException if an I/O error occurs.
92 */
93 public synchronized void write(int b) throws IOException {
94 if (count >= buf.length) {
95 flushBuffer();
96 }
97 buf[count++] = (byte)b;
98 }
99
100 /**
101 * Writes <code>len</code> bytes from the specified byte array
102 * starting at offset <code>off</code> to this buffered output stream.
103 *
104 * <p> Ordinarily this method stores bytes from the given array into this
105 * stream's buffer, flushing the buffer to the underlying output stream as
106 * needed. If the requested length is at least as large as this stream's
107 * buffer, however, then this method will flush the buffer and write the
108 * bytes directly to the underlying output stream. Thus redundant
109 * <code>BufferedOutputStream</code>s will not copy data unnecessarily.
110 *
111 * @param b the data.
112 * @param off the start offset in the data.
113 * @param len the number of bytes to write.
114 * @exception IOException if an I/O error occurs.
115 */
116 public synchronized void write(byte b[], int off, int len) throws IOException {
117 if (len >= buf.length) {
118 /* If the request length exceeds the size of the output buffer,
119 flush the output buffer and then write the data directly.
120 In this way buffered streams will cascade harmlessly. */
121 flushBuffer();
122 out.write(b, off, len);
123 return;
124 }
125 if (len > buf.length - count) {
126 flushBuffer();
127 }
128 System.arraycopy(b, off, buf, count, len);
129 count += len;
130 }
131
132 /**
133 * Flushes this buffered output stream. This forces any buffered
134 * output bytes to be written out to the underlying output stream.
135 *
136 * @exception IOException if an I/O error occurs.
137 * @see java.io.FilterOutputStream#out
138 */
139 public synchronized void flush() throws IOException {
140 flushBuffer();
141 out.flush();
142 }
143}
java/pkg/java/io/BufferedReader.class+0−0

Binary file not shown.

java/pkg/java/io/BufferedReader.java+522−0
@@ -0,0 +1,522 @@
1/*
2 * Copyright (c) 1996, 2011, 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
26package java.io;
27
28
29/**
30 * Reads text from a character-input stream, buffering characters so as to
31 * provide for the efficient reading of characters, arrays, and lines.
32 *
33 * <p> The buffer size may be specified, or the default size may be used. The
34 * default is large enough for most purposes.
35 *
36 * <p> In general, each read request made of a Reader causes a corresponding
37 * read request to be made of the underlying character or byte stream. It is
38 * therefore advisable to wrap a BufferedReader around any Reader whose read()
39 * operations may be costly, such as FileReaders and InputStreamReaders. For
40 * example,
41 *
42 * <pre>
43 * BufferedReader in
44 * = new BufferedReader(new FileReader("foo.in"));
45 * </pre>
46 *
47 * will buffer the input from the specified file. Without buffering, each
48 * invocation of read() or readLine() could cause bytes to be read from the
49 * file, converted into characters, and then returned, which can be very
50 * inefficient.
51 *
52 * <p> Programs that use DataInputStreams for textual input can be localized by
53 * replacing each DataInputStream with an appropriate BufferedReader.
54 *
55 * @see FileReader
56 * @see InputStreamReader
57 * @see java.nio.file.Files#newBufferedReader
58 *
59 * @author Mark Reinhold
60 * @since JDK1.1
61 */
62
63public class BufferedReader extends Reader {
64
65 private Reader in;
66
67 private char cb[];
68 private int nChars, nextChar;
69
70 private static final int INVALIDATED = -2;
71 private static final int UNMARKED = -1;
72 private int markedChar = UNMARKED;
73 private int readAheadLimit = 0; /* Valid only when markedChar > 0 */
74
75 /** If the next character is a line feed, skip it */
76 private boolean skipLF = false;
77
78 /** The skipLF flag when the mark was set */
79 private boolean markedSkipLF = false;
80
81 private static int defaultCharBufferSize = 8192;
82 private static int defaultExpectedLineLength = 80;
83
84 /**
85 * Creates a buffering character-input stream that uses an input buffer of
86 * the specified size.
87 *
88 * @param in A Reader
89 * @param sz Input-buffer size
90 *
91 * @exception IllegalArgumentException If sz is <= 0
92 */
93 public BufferedReader(Reader in, int sz) {
94 super(in);
95 if (sz <= 0)
96 throw new IllegalArgumentException("Buffer size <= 0");
97 this.in = in;
98 cb = new char[sz];
99 nextChar = nChars = 0;
100 }
101
102 /**
103 * Creates a buffering character-input stream that uses a default-sized
104 * input buffer.
105 *
106 * @param in A Reader
107 */
108 public BufferedReader(Reader in) {
109 this(in, defaultCharBufferSize);
110 }
111
112 /** Checks to make sure that the stream has not been closed */
113 private void ensureOpen() throws IOException {
114 if (in == null)
115 throw new IOException("Stream closed");
116 }
117
118 /**
119 * Fills the input buffer, taking the mark into account if it is valid.
120 */
121 private void fill() throws IOException {
122 int dst;
123 if (markedChar <= UNMARKED) {
124 /* No mark */
125 dst = 0;
126 } else {
127 /* Marked */
128 int delta = nextChar - markedChar;
129 if (delta >= readAheadLimit) {
130 /* Gone past read-ahead limit: Invalidate mark */
131 markedChar = INVALIDATED;
132 readAheadLimit = 0;
133 dst = 0;
134 } else {
135 if (readAheadLimit <= cb.length) {
136 /* Shuffle in the current buffer */
137 System.arraycopy(cb, markedChar, cb, 0, delta);
138 markedChar = 0;
139 dst = delta;
140 } else {
141 /* Reallocate buffer to accommodate read-ahead limit */
142 char ncb[] = new char[readAheadLimit];
143 System.arraycopy(cb, markedChar, ncb, 0, delta);
144 cb = ncb;
145 markedChar = 0;
146 dst = delta;
147 }
148 nextChar = nChars = delta;
149 }
150 }
151
152 int n;
153 do {
154 n = in.read(cb, dst, cb.length - dst);
155 } while (n == 0);
156 if (n > 0) {
157 nChars = dst + n;
158 nextChar = dst;
159 }
160 }
161
162 /**
163 * Reads a single character.
164 *
165 * @return The character read, as an integer in the range
166 * 0 to 65535 (<tt>0x00-0xffff</tt>), or -1 if the
167 * end of the stream has been reached
168 * @exception IOException If an I/O error occurs
169 */
170 public int read() throws IOException {
171 synchronized (lock) {
172 ensureOpen();
173 for (;;) {
174 if (nextChar >= nChars) {
175 fill();
176 if (nextChar >= nChars)
177 return -1;
178 }
179 if (skipLF) {
180 skipLF = false;
181 if (cb[nextChar] == '\n') {
182 nextChar++;
183 continue;
184 }
185 }
186 return cb[nextChar++];
187 }
188 }
189 }
190
191 /**
192 * Reads characters into a portion of an array, reading from the underlying
193 * stream if necessary.
194 */
195 private int read1(char[] cbuf, int off, int len) throws IOException {
196 if (nextChar >= nChars) {
197 /* If the requested length is at least as large as the buffer, and
198 if there is no mark/reset activity, and if line feeds are not
199 being skipped, do not bother to copy the characters into the
200 local buffer. In this way buffered streams will cascade
201 harmlessly. */
202 if (len >= cb.length && markedChar <= UNMARKED && !skipLF) {
203 return in.read(cbuf, off, len);
204 }
205 fill();
206 }
207 if (nextChar >= nChars) return -1;
208 if (skipLF) {
209 skipLF = false;
210 if (cb[nextChar] == '\n') {
211 nextChar++;
212 if (nextChar >= nChars)
213 fill();
214 if (nextChar >= nChars)
215 return -1;
216 }
217 }
218 int n = Math.min(len, nChars - nextChar);
219 System.arraycopy(cb, nextChar, cbuf, off, n);
220 nextChar += n;
221 return n;
222 }
223
224 /**
225 * Reads characters into a portion of an array.
226 *
227 * <p> This method implements the general contract of the corresponding
228 * <code>{@link Reader#read(char[], int, int) read}</code> method of the
229 * <code>{@link Reader}</code> class. As an additional convenience, it
230 * attempts to read as many characters as possible by repeatedly invoking
231 * the <code>read</code> method of the underlying stream. This iterated
232 * <code>read</code> continues until one of the following conditions becomes
233 * true: <ul>
234 *
235 * <li> The specified number of characters have been read,
236 *
237 * <li> The <code>read</code> method of the underlying stream returns
238 * <code>-1</code>, indicating end-of-file, or
239 *
240 * <li> The <code>ready</code> method of the underlying stream
241 * returns <code>false</code>, indicating that further input requests
242 * would block.
243 *
244 * </ul> If the first <code>read</code> on the underlying stream returns
245 * <code>-1</code> to indicate end-of-file then this method returns
246 * <code>-1</code>. Otherwise this method returns the number of characters
247 * actually read.
248 *
249 * <p> Subclasses of this class are encouraged, but not required, to
250 * attempt to read as many characters as possible in the same fashion.
251 *
252 * <p> Ordinarily this method takes characters from this stream's character
253 * buffer, filling it from the underlying stream as necessary. If,
254 * however, the buffer is empty, the mark is not valid, and the requested
255 * length is at least as large as the buffer, then this method will read
256 * characters directly from the underlying stream into the given array.
257 * Thus redundant <code>BufferedReader</code>s will not copy data
258 * unnecessarily.
259 *
260 * @param cbuf Destination buffer
261 * @param off Offset at which to start storing characters
262 * @param len Maximum number of characters to read
263 *
264 * @return The number of characters read, or -1 if the end of the
265 * stream has been reached
266 *
267 * @exception IOException If an I/O error occurs
268 */
269 public int read(char cbuf[], int off, int len) throws IOException {
270 synchronized (lock) {
271 ensureOpen();
272 if ((off < 0) || (off > cbuf.length) || (len < 0) ||
273 ((off + len) > cbuf.length) || ((off + len) < 0)) {
274 throw new IndexOutOfBoundsException();
275 } else if (len == 0) {
276 return 0;
277 }
278
279 int n = read1(cbuf, off, len);
280 if (n <= 0) return n;
281 while ((n < len) && in.ready()) {
282 int n1 = read1(cbuf, off + n, len - n);
283 if (n1 <= 0) break;
284 n += n1;
285 }
286 return n;
287 }
288 }
289
290 /**
291 * Reads a line of text. A line is considered to be terminated by any one
292 * of a line feed ('\n'), a carriage return ('\r'), or a carriage return
293 * followed immediately by a linefeed.
294 *
295 * @param ignoreLF If true, the next '\n' will be skipped
296 *
297 * @return A String containing the contents of the line, not including
298 * any line-termination characters, or null if the end of the
299 * stream has been reached
300 *
301 * @see java.io.LineNumberReader#readLine()
302 *
303 * @exception IOException If an I/O error occurs
304 */
305 String readLine(boolean ignoreLF) throws IOException {
306 StringBuffer s = null;
307 int startChar;
308
309 synchronized (lock) {
310 ensureOpen();
311 boolean omitLF = ignoreLF || skipLF;
312
313 bufferLoop:
314 for (;;) {
315
316 if (nextChar >= nChars)
317 fill();
318 if (nextChar >= nChars) { /* EOF */
319 if (s != null && s.length() > 0)
320 return s.toString();
321 else
322 return null;
323 }
324 boolean eol = false;
325 char c = 0;
326 int i;
327
328 /* Skip a leftover '\n', if necessary */
329 if (omitLF && (cb[nextChar] == '\n'))
330 nextChar++;
331 skipLF = false;
332 omitLF = false;
333
334 charLoop:
335 for (i = nextChar; i < nChars; i++) {
336 c = cb[i];
337 if ((c == '\n') || (c == '\r')) {
338 eol = true;
339 break charLoop;
340 }
341 }
342
343 startChar = nextChar;
344 nextChar = i;
345
346 if (eol) {
347 String str;
348 if (s == null) {
349 str = new String(cb, startChar, i - startChar);
350 } else {
351 s.append(cb, startChar, i - startChar);
352 str = s.toString();
353 }
354 nextChar++;
355 if (c == '\r') {
356 skipLF = true;
357 }
358 return str;
359 }
360
361 if (s == null)
362 s = new StringBuffer(defaultExpectedLineLength);
363 s.append(cb, startChar, i - startChar);
364 }
365 }
366 }
367
368 /**
369 * Reads a line of text. A line is considered to be terminated by any one
370 * of a line feed ('\n'), a carriage return ('\r'), or a carriage return
371 * followed immediately by a linefeed.
372 *
373 * @return A String containing the contents of the line, not including
374 * any line-termination characters, or null if the end of the
375 * stream has been reached
376 *
377 * @exception IOException If an I/O error occurs
378 *
379 * @see java.nio.file.Files#readAllLines
380 */
381 public String readLine() throws IOException {
382 return readLine(false);
383 }
384
385 /**
386 * Skips characters.
387 *
388 * @param n The number of characters to skip
389 *
390 * @return The number of characters actually skipped
391 *
392 * @exception IllegalArgumentException If <code>n</code> is negative.
393 * @exception IOException If an I/O error occurs
394 */
395 public long skip(long n) throws IOException {
396 if (n < 0L) {
397 throw new IllegalArgumentException("skip value is negative");
398 }
399 synchronized (lock) {
400 ensureOpen();
401 long r = n;
402 while (r > 0) {
403 if (nextChar >= nChars)
404 fill();
405 if (nextChar >= nChars) /* EOF */
406 break;
407 if (skipLF) {
408 skipLF = false;
409 if (cb[nextChar] == '\n') {
410 nextChar++;
411 }
412 }
413 long d = nChars - nextChar;
414 if (r <= d) {
415 nextChar += r;
416 r = 0;
417 break;
418 }
419 else {
420 r -= d;
421 nextChar = nChars;
422 }
423 }
424 return n - r;
425 }
426 }
427
428 /**
429 * Tells whether this stream is ready to be read. A buffered character
430 * stream is ready if the buffer is not empty, or if the underlying
431 * character stream is ready.
432 *
433 * @exception IOException If an I/O error occurs
434 */
435 public boolean ready() throws IOException {
436 synchronized (lock) {
437 ensureOpen();
438
439 /*
440 * If newline needs to be skipped and the next char to be read
441 * is a newline character, then just skip it right away.
442 */
443 if (skipLF) {
444 /* Note that in.ready() will return true if and only if the next
445 * read on the stream will not block.
446 */
447 if (nextChar >= nChars && in.ready()) {
448 fill();
449 }
450 if (nextChar < nChars) {
451 if (cb[nextChar] == '\n')
452 nextChar++;
453 skipLF = false;
454 }
455 }
456 return (nextChar < nChars) || in.ready();
457 }
458 }
459
460 /**
461 * Tells whether this stream supports the mark() operation, which it does.
462 */
463 public boolean markSupported() {
464 return true;
465 }
466
467 /**
468 * Marks the present position in the stream. Subsequent calls to reset()
469 * will attempt to reposition the stream to this point.
470 *
471 * @param readAheadLimit Limit on the number of characters that may be
472 * read while still preserving the mark. An attempt
473 * to reset the stream after reading characters
474 * up to this limit or beyond may fail.
475 * A limit value larger than the size of the input
476 * buffer will cause a new buffer to be allocated
477 * whose size is no smaller than limit.
478 * Therefore large values should be used with care.
479 *
480 * @exception IllegalArgumentException If readAheadLimit is < 0
481 * @exception IOException If an I/O error occurs
482 */
483 public void mark(int readAheadLimit) throws IOException {
484 if (readAheadLimit < 0) {
485 throw new IllegalArgumentException("Read-ahead limit < 0");
486 }
487 synchronized (lock) {
488 ensureOpen();
489 this.readAheadLimit = readAheadLimit;
490 markedChar = nextChar;
491 markedSkipLF = skipLF;
492 }
493 }
494
495 /**
496 * Resets the stream to the most recent mark.
497 *
498 * @exception IOException If the stream has never been marked,
499 * or if the mark has been invalidated
500 */
501 public void reset() throws IOException {
502 synchronized (lock) {
503 ensureOpen();
504 if (markedChar < 0)
505 throw new IOException((markedChar == INVALIDATED)
506 ? "Mark invalid"
507 : "Stream not marked");
508 nextChar = markedChar;
509 skipLF = markedSkipLF;
510 }
511 }
512
513 public void close() throws IOException {
514 synchronized (lock) {
515 if (in == null)
516 return;
517 in.close();
518 in = null;
519 cb = null;
520 }
521 }
522}
java/pkg/java/io/BufferedWriter.class+0−0

Binary file not shown.

java/pkg/java/io/BufferedWriter.java+272−0
@@ -0,0 +1,272 @@
1/*
2 * Copyright (c) 1996, 2011, 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
26package java.io;
27
28
29/**
30 * Writes text to a character-output stream, buffering characters so as to
31 * provide for the efficient writing of single characters, arrays, and strings.
32 *
33 * <p> The buffer size may be specified, or the default size may be accepted.
34 * The default is large enough for most purposes.
35 *
36 * <p> A newLine() method is provided, which uses the platform's own notion of
37 * line separator as defined by the system property <tt>line.separator</tt>.
38 * Not all platforms use the newline character ('\n') to terminate lines.
39 * Calling this method to terminate each output line is therefore preferred to
40 * writing a newline character directly.
41 *
42 * <p> In general, a Writer sends its output immediately to the underlying
43 * character or byte stream. Unless prompt output is required, it is advisable
44 * to wrap a BufferedWriter around any Writer whose write() operations may be
45 * costly, such as FileWriters and OutputStreamWriters. For example,
46 *
47 * <pre>
48 * PrintWriter out
49 * = new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));
50 * </pre>
51 *
52 * will buffer the PrintWriter's output to the file. Without buffering, each
53 * invocation of a print() method would cause characters to be converted into
54 * bytes that would then be written immediately to the file, which can be very
55 * inefficient.
56 *
57 * @see PrintWriter
58 * @see FileWriter
59 * @see OutputStreamWriter
60 * @see java.nio.file.Files#newBufferedWriter
61 *
62 * @author Mark Reinhold
63 * @since JDK1.1
64 */
65
66public class BufferedWriter extends Writer {
67
68 private Writer out;
69
70 private char cb[];
71 private int nChars, nextChar;
72
73 private static int defaultCharBufferSize = 8192;
74
75 /**
76 * Line separator string. This is the value of the line.separator
77 * property at the moment that the stream was created.
78 */
79 private String lineSeparator;
80
81 /**
82 * Creates a buffered character-output stream that uses a default-sized
83 * output buffer.
84 *
85 * @param out A Writer
86 */
87 public BufferedWriter(Writer out) {
88 this(out, defaultCharBufferSize);
89 }
90
91 /**
92 * Creates a new buffered character-output stream that uses an output
93 * buffer of the given size.
94 *
95 * @param out A Writer
96 * @param sz Output-buffer size, a positive integer
97 *
98 * @exception IllegalArgumentException If sz is <= 0
99 */
100 public BufferedWriter(Writer out, int sz) {
101 super(out);
102 if (sz <= 0)
103 throw new IllegalArgumentException("Buffer size <= 0");
104 this.out = out;
105 cb = new char[sz];
106 nChars = sz;
107 nextChar = 0;
108
109 lineSeparator = java.security.AccessController.doPrivileged(
110 new sun.security.action.GetPropertyAction("line.separator"));
111 }
112
113 /** Checks to make sure that the stream has not been closed */
114 private void ensureOpen() throws IOException {
115 if (out == null)
116 throw new IOException("Stream closed");
117 }
118
119 /**
120 * Flushes the output buffer to the underlying character stream, without
121 * flushing the stream itself. This method is non-private only so that it
122 * may be invoked by PrintStream.
123 */
124 void flushBuffer() throws IOException {
125 synchronized (lock) {
126 ensureOpen();
127 if (nextChar == 0)
128 return;
129 out.write(cb, 0, nextChar);
130 nextChar = 0;
131 }
132 }
133
134 /**
135 * Writes a single character.
136 *
137 * @exception IOException If an I/O error occurs
138 */
139 public void write(int c) throws IOException {
140 synchronized (lock) {
141 ensureOpen();
142 if (nextChar >= nChars)
143 flushBuffer();
144 cb[nextChar++] = (char) c;
145 }
146 }
147
148 /**
149 * Our own little min method, to avoid loading java.lang.Math if we've run
150 * out of file descriptors and we're trying to print a stack trace.
151 */
152 private int min(int a, int b) {
153 if (a < b) return a;
154 return b;
155 }
156
157 /**
158 * Writes a portion of an array of characters.
159 *
160 * <p> Ordinarily this method stores characters from the given array into
161 * this stream's buffer, flushing the buffer to the underlying stream as
162 * needed. If the requested length is at least as large as the buffer,
163 * however, then this method will flush the buffer and write the characters
164 * directly to the underlying stream. Thus redundant
165 * <code>BufferedWriter</code>s will not copy data unnecessarily.
166 *
167 * @param cbuf A character array
168 * @param off Offset from which to start reading characters
169 * @param len Number of characters to write
170 *
171 * @exception IOException If an I/O error occurs
172 */
173 public void write(char cbuf[], int off, int len) throws IOException {
174 synchronized (lock) {
175 ensureOpen();
176 if ((off < 0) || (off > cbuf.length) || (len < 0) ||
177 ((off + len) > cbuf.length) || ((off + len) < 0)) {
178 throw new IndexOutOfBoundsException();
179 } else if (len == 0) {
180 return;
181 }
182
183 if (len >= nChars) {
184 /* If the request length exceeds the size of the output buffer,
185 flush the buffer and then write the data directly. In this
186 way buffered streams will cascade harmlessly. */
187 flushBuffer();
188 out.write(cbuf, off, len);
189 return;
190 }
191
192 int b = off, t = off + len;
193 while (b < t) {
194 int d = min(nChars - nextChar, t - b);
195 System.arraycopy(cbuf, b, cb, nextChar, d);
196 b += d;
197 nextChar += d;
198 if (nextChar >= nChars)
199 flushBuffer();
200 }
201 }
202 }
203
204 /**
205 * Writes a portion of a String.
206 *
207 * <p> If the value of the <tt>len</tt> parameter is negative then no
208 * characters are written. This is contrary to the specification of this
209 * method in the {@linkplain java.io.Writer#write(java.lang.String,int,int)
210 * superclass}, which requires that an {@link IndexOutOfBoundsException} be
211 * thrown.
212 *
213 * @param s String to be written
214 * @param off Offset from which to start reading characters
215 * @param len Number of characters to be written
216 *
217 * @exception IOException If an I/O error occurs
218 */
219 public void write(String s, int off, int len) throws IOException {
220 synchronized (lock) {
221 ensureOpen();
222
223 int b = off, t = off + len;
224 while (b < t) {
225 int d = min(nChars - nextChar, t - b);
226 s.getChars(b, b + d, cb, nextChar);
227 b += d;
228 nextChar += d;
229 if (nextChar >= nChars)
230 flushBuffer();
231 }
232 }
233 }
234
235 /**
236 * Writes a line separator. The line separator string is defined by the
237 * system property <tt>line.separator</tt>, and is not necessarily a single
238 * newline ('\n') character.
239 *
240 * @exception IOException If an I/O error occurs
241 */
242 public void newLine() throws IOException {
243 write(lineSeparator);
244 }
245
246 /**
247 * Flushes the stream.
248 *
249 * @exception IOException If an I/O error occurs
250 */
251 public void flush() throws IOException {
252 synchronized (lock) {
253 flushBuffer();
254 out.flush();
255 }
256 }
257
258 public void close() throws IOException {
259 synchronized (lock) {
260 if (out == null) {
261 return;
262 }
263 try {
264 flushBuffer();
265 } finally {
266 out.close();
267 out = null;
268 cb = null;
269 }
270 }
271 }
272}
java/pkg/java/io/ByteArrayInputStream.class+0−0

Binary file not shown.

java/pkg/java/io/ByteArrayInputStream.java+283−0
@@ -0,0 +1,283 @@
1/*
2 * Copyright (c) 1994, 2010, 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
26package java.io;
27
28/**
29 * A <code>ByteArrayInputStream</code> contains
30 * an internal buffer that contains bytes that
31 * may be read from the stream. An internal
32 * counter keeps track of the next byte to
33 * be supplied by the <code>read</code> method.
34 * <p>
35 * Closing a <tt>ByteArrayInputStream</tt> has no effect. The methods in
36 * this class can be called after the stream has been closed without
37 * generating an <tt>IOException</tt>.
38 *
39 * @author Arthur van Hoff
40 * @see java.io.StringBufferInputStream
41 * @since JDK1.0
42 */
43public
44class ByteArrayInputStream extends InputStream {
45
46 /**
47 * An array of bytes that was provided
48 * by the creator of the stream. Elements <code>buf[0]</code>
49 * through <code>buf[count-1]</code> are the
50 * only bytes that can ever be read from the
51 * stream; element <code>buf[pos]</code> is
52 * the next byte to be read.
53 */
54 protected byte buf[];
55
56 /**
57 * The index of the next character to read from the input stream buffer.
58 * This value should always be nonnegative
59 * and not larger than the value of <code>count</code>.
60 * The next byte to be read from the input stream buffer
61 * will be <code>buf[pos]</code>.
62 */
63 protected int pos;
64
65 /**
66 * The currently marked position in the stream.
67 * ByteArrayInputStream objects are marked at position zero by
68 * default when constructed. They may be marked at another
69 * position within the buffer by the <code>mark()</code> method.
70 * The current buffer position is set to this point by the
71 * <code>reset()</code> method.
72 * <p>
73 * If no mark has been set, then the value of mark is the offset
74 * passed to the constructor (or 0 if the offset was not supplied).
75 *
76 * @since JDK1.1
77 */
78 protected int mark = 0;
79
80 /**
81 * The index one greater than the last valid character in the input
82 * stream buffer.
83 * This value should always be nonnegative
84 * and not larger than the length of <code>buf</code>.
85 * It is one greater than the position of
86 * the last byte within <code>buf</code> that
87 * can ever be read from the input stream buffer.
88 */
89 protected int count;
90
91 /**
92 * Creates a <code>ByteArrayInputStream</code>
93 * so that it uses <code>buf</code> as its
94 * buffer array.
95 * The buffer array is not copied.
96 * The initial value of <code>pos</code>
97 * is <code>0</code> and the initial value
98 * of <code>count</code> is the length of
99 * <code>buf</code>.
100 *
101 * @param buf the input buffer.
102 */
103 public ByteArrayInputStream(byte buf[]) {
104 this.buf = buf;
105 this.pos = 0;
106 this.count = buf.length;
107 }
108
109 /**
110 * Creates <code>ByteArrayInputStream</code>
111 * that uses <code>buf</code> as its
112 * buffer array. The initial value of <code>pos</code>
113 * is <code>offset</code> and the initial value
114 * of <code>count</code> is the minimum of <code>offset+length</code>
115 * and <code>buf.length</code>.
116 * The buffer array is not copied. The buffer's mark is
117 * set to the specified offset.
118 *
119 * @param buf the input buffer.
120 * @param offset the offset in the buffer of the first byte to read.
121 * @param length the maximum number of bytes to read from the buffer.
122 */
123 public ByteArrayInputStream(byte buf[], int offset, int length) {
124 this.buf = buf;
125 this.pos = offset;
126 this.count = Math.min(offset + length, buf.length);
127 this.mark = offset;
128 }
129
130 /**
131 * Reads the next byte of data from this input stream. The value
132 * byte is returned as an <code>int</code> in the range
133 * <code>0</code> to <code>255</code>. If no byte is available
134 * because the end of the stream has been reached, the value
135 * <code>-1</code> is returned.
136 * <p>
137 * This <code>read</code> method
138 * cannot block.
139 *
140 * @return the next byte of data, or <code>-1</code> if the end of the
141 * stream has been reached.
142 */
143 public synchronized int read() {
144 return (pos < count) ? (buf[pos++] & 0xff) : -1;
145 }
146
147 /**
148 * Reads up to <code>len</code> bytes of data into an array of bytes
149 * from this input stream.
150 * If <code>pos</code> equals <code>count</code>,
151 * then <code>-1</code> is returned to indicate
152 * end of file. Otherwise, the number <code>k</code>
153 * of bytes read is equal to the smaller of
154 * <code>len</code> and <code>count-pos</code>.
155 * If <code>k</code> is positive, then bytes
156 * <code>buf[pos]</code> through <code>buf[pos+k-1]</code>
157 * are copied into <code>b[off]</code> through
158 * <code>b[off+k-1]</code> in the manner performed
159 * by <code>System.arraycopy</code>. The
160 * value <code>k</code> is added into <code>pos</code>
161 * and <code>k</code> is returned.
162 * <p>
163 * This <code>read</code> method cannot block.
164 *
165 * @param b the buffer into which the data is read.
166 * @param off the start offset in the destination array <code>b</code>
167 * @param len the maximum number of bytes read.
168 * @return the total number of bytes read into the buffer, or
169 * <code>-1</code> if there is no more data because the end of
170 * the stream has been reached.
171 * @exception NullPointerException If <code>b</code> is <code>null</code>.
172 * @exception IndexOutOfBoundsException If <code>off</code> is negative,
173 * <code>len</code> is negative, or <code>len</code> is greater than
174 * <code>b.length - off</code>
175 */
176 public synchronized int read(byte b[], int off, int len) {
177 if (b == null) {
178 throw new NullPointerException();
179 } else if (off < 0 || len < 0 || len > b.length - off) {
180 throw new IndexOutOfBoundsException();
181 }
182
183 if (pos >= count) {
184 return -1;
185 }
186
187 int avail = count - pos;
188 if (len > avail) {
189 len = avail;
190 }
191 if (len <= 0) {
192 return 0;
193 }
194 System.arraycopy(buf, pos, b, off, len);
195 pos += len;
196 return len;
197 }
198
199 /**
200 * Skips <code>n</code> bytes of input from this input stream. Fewer
201 * bytes might be skipped if the end of the input stream is reached.
202 * The actual number <code>k</code>
203 * of bytes to be skipped is equal to the smaller
204 * of <code>n</code> and <code>count-pos</code>.
205 * The value <code>k</code> is added into <code>pos</code>
206 * and <code>k</code> is returned.
207 *
208 * @param n the number of bytes to be skipped.
209 * @return the actual number of bytes skipped.
210 */
211 public synchronized long skip(long n) {
212 long k = count - pos;
213 if (n < k) {
214 k = n < 0 ? 0 : n;
215 }
216
217 pos += k;
218 return k;
219 }
220
221 /**
222 * Returns the number of remaining bytes that can be read (or skipped over)
223 * from this input stream.
224 * <p>
225 * The value returned is <code>count&nbsp;- pos</code>,
226 * which is the number of bytes remaining to be read from the input buffer.
227 *
228 * @return the number of remaining bytes that can be read (or skipped
229 * over) from this input stream without blocking.
230 */
231 public synchronized int available() {
232 return count - pos;
233 }
234
235 /**
236 * Tests if this <code>InputStream</code> supports mark/reset. The
237 * <code>markSupported</code> method of <code>ByteArrayInputStream</code>
238 * always returns <code>true</code>.
239 *
240 * @since JDK1.1
241 */
242 public boolean markSupported() {
243 return true;
244 }
245
246 /**
247 * Set the current marked position in the stream.
248 * ByteArrayInputStream objects are marked at position zero by
249 * default when constructed. They may be marked at another
250 * position within the buffer by this method.
251 * <p>
252 * If no mark has been set, then the value of the mark is the
253 * offset passed to the constructor (or 0 if the offset was not
254 * supplied).
255 *
256 * <p> Note: The <code>readAheadLimit</code> for this class
257 * has no meaning.
258 *
259 * @since JDK1.1
260 */
261 public void mark(int readAheadLimit) {
262 mark = pos;
263 }
264
265 /**
266 * Resets the buffer to the marked position. The marked position
267 * is 0 unless another position was marked or an offset was specified
268 * in the constructor.
269 */
270 public synchronized void reset() {
271 pos = mark;
272 }
273
274 /**
275 * Closing a <tt>ByteArrayInputStream</tt> has no effect. The methods in
276 * this class can be called after the stream has been closed without
277 * generating an <tt>IOException</tt>.
278 * <p>
279 */
280 public void close() throws IOException {
281 }
282
283}
java/pkg/java/io/ByteArrayOutputStream.class+0−0

Binary file not shown.

java/pkg/java/io/ByteArrayOutputStream.java+272−0
@@ -0,0 +1,272 @@
1/*
2 * Copyright (c) 1994, 2010, 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
26package java.io;
27
28import java.util.Arrays;
29
30/**
31 * This class implements an output stream in which the data is
32 * written into a byte array. The buffer automatically grows as data
33 * is written to it.
34 * The data can be retrieved using <code>toByteArray()</code> and
35 * <code>toString()</code>.
36 * <p>
37 * Closing a <tt>ByteArrayOutputStream</tt> has no effect. The methods in
38 * this class can be called after the stream has been closed without
39 * generating an <tt>IOException</tt>.
40 *
41 * @author Arthur van Hoff
42 * @since JDK1.0
43 */
44
45public class ByteArrayOutputStream extends OutputStream {
46
47 /**
48 * The buffer where data is stored.
49 */
50 protected byte buf[];
51
52 /**
53 * The number of valid bytes in the buffer.
54 */
55 protected int count;
56
57 /**
58 * Creates a new byte array output stream. The buffer capacity is
59 * initially 32 bytes, though its size increases if necessary.
60 */
61 public ByteArrayOutputStream() {
62 this(32);
63 }
64
65 /**
66 * Creates a new byte array output stream, with a buffer capacity of
67 * the specified size, in bytes.
68 *
69 * @param size the initial size.
70 * @exception IllegalArgumentException if size is negative.
71 */
72 public ByteArrayOutputStream(int size) {
73 if (size < 0) {
74 throw new IllegalArgumentException("Negative initial size: "
75 + size);
76 }
77 buf = new byte[size];
78 }
79
80 /**
81 * Increases the capacity if necessary to ensure that it can hold
82 * at least the number of elements specified by the minimum
83 * capacity argument.
84 *
85 * @param minCapacity the desired minimum capacity
86 * @throws OutOfMemoryError if {@code minCapacity < 0}. This is
87 * interpreted as a request for the unsatisfiably large capacity
88 * {@code (long) Integer.MAX_VALUE + (minCapacity - Integer.MAX_VALUE)}.
89 */
90 private void ensureCapacity(int minCapacity) {
91 // overflow-conscious code
92 if (minCapacity - buf.length > 0)
93 grow(minCapacity);
94 }
95
96 /**
97 * Increases the capacity to ensure that it can hold at least the
98 * number of elements specified by the minimum capacity argument.
99 *
100 * @param minCapacity the desired minimum capacity
101 */
102 private void grow(int minCapacity) {
103 // overflow-conscious code
104 int oldCapacity = buf.length;
105 int newCapacity = oldCapacity << 1;
106 if (newCapacity - minCapacity < 0)
107 newCapacity = minCapacity;
108 if (newCapacity < 0) {
109 if (minCapacity < 0) // overflow
110 throw new OutOfMemoryError();
111 newCapacity = Integer.MAX_VALUE;
112 }
113 buf = Arrays.copyOf(buf, newCapacity);
114 }
115
116 /**
117 * Writes the specified byte to this byte array output stream.
118 *
119 * @param b the byte to be written.
120 */
121 public synchronized void write(int b) {
122 ensureCapacity(count + 1);
123 buf[count] = (byte) b;
124 count += 1;
125 }
126
127 /**
128 * Writes <code>len</code> bytes from the specified byte array
129 * starting at offset <code>off</code> to this byte array output stream.
130 *
131 * @param b the data.
132 * @param off the start offset in the data.
133 * @param len the number of bytes to write.
134 */
135 public synchronized void write(byte b[], int off, int len) {
136 if ((off < 0) || (off > b.length) || (len < 0) ||
137 ((off + len) - b.length > 0)) {
138 throw new IndexOutOfBoundsException();
139 }
140 ensureCapacity(count + len);
141 System.arraycopy(b, off, buf, count, len);
142 count += len;
143 }
144
145 /**
146 * Writes the complete contents of this byte array output stream to
147 * the specified output stream argument, as if by calling the output
148 * stream's write method using <code>out.write(buf, 0, count)</code>.
149 *
150 * @param out the output stream to which to write the data.
151 * @exception IOException if an I/O error occurs.
152 */
153 public synchronized void writeTo(OutputStream out) throws IOException {
154 out.write(buf, 0, count);
155 }
156
157 /**
158 * Resets the <code>count</code> field of this byte array output
159 * stream to zero, so that all currently accumulated output in the
160 * output stream is discarded. The output stream can be used again,
161 * reusing the already allocated buffer space.
162 *
163 * @see java.io.ByteArrayInputStream#count
164 */
165 public synchronized void reset() {
166 count = 0;
167 }
168
169 /**
170 * Creates a newly allocated byte array. Its size is the current
171 * size of this output stream and the valid contents of the buffer
172 * have been copied into it.
173 *
174 * @return the current contents of this output stream, as a byte array.
175 * @see java.io.ByteArrayOutputStream#size()
176 */
177 public synchronized byte toByteArray()[] {
178 return Arrays.copyOf(buf, count);
179 }
180
181 /**
182 * Returns the current size of the buffer.
183 *
184 * @return the value of the <code>count</code> field, which is the number
185 * of valid bytes in this output stream.
186 * @see java.io.ByteArrayOutputStream#count
187 */
188 public synchronized int size() {
189 return count;
190 }
191
192 /**
193 * Converts the buffer's contents into a string decoding bytes using the
194 * platform's default character set. The length of the new <tt>String</tt>
195 * is a function of the character set, and hence may not be equal to the
196 * size of the buffer.
197 *
198 * <p> This method always replaces malformed-input and unmappable-character
199 * sequences with the default replacement string for the platform's
200 * default character set. The {@linkplain java.nio.charset.CharsetDecoder}
201 * class should be used when more control over the decoding process is
202 * required.
203 *
204 * @return String decoded from the buffer's contents.
205 * @since JDK1.1
206 */
207 public synchronized String toString() {
208 return new String(buf, 0, count);
209 }
210
211 /**
212 * Converts the buffer's contents into a string by decoding the bytes using
213 * the specified {@link java.nio.charset.Charset charsetName}. The length of
214 * the new <tt>String</tt> is a function of the charset, and hence may not be
215 * equal to the length of the byte array.
216 *
217 * <p> This method always replaces malformed-input and unmappable-character
218 * sequences with this charset's default replacement string. The {@link
219 * java.nio.charset.CharsetDecoder} class should be used when more control
220 * over the decoding process is required.
221 *
222 * @param charsetName the name of a supported
223 * {@linkplain java.nio.charset.Charset </code>charset<code>}
224 * @return String decoded from the buffer's contents.
225 * @exception UnsupportedEncodingException
226 * If the named charset is not supported
227 * @since JDK1.1
228 */
229 public synchronized String toString(String charsetName)
230 throws UnsupportedEncodingException
231 {
232 return new String(buf, 0, count, charsetName);
233 }
234
235 /**
236 * Creates a newly allocated string. Its size is the current size of
237 * the output stream and the valid contents of the buffer have been
238 * copied into it. Each character <i>c</i> in the resulting string is
239 * constructed from the corresponding element <i>b</i> in the byte
240 * array such that:
241 * <blockquote><pre>
242 * c == (char)(((hibyte &amp; 0xff) &lt;&lt; 8) | (b &amp; 0xff))
243 * </pre></blockquote>
244 *
245 * @deprecated This method does not properly convert bytes into characters.
246 * As of JDK&nbsp;1.1, the preferred way to do this is via the
247 * <code>toString(String enc)</code> method, which takes an encoding-name
248 * argument, or the <code>toString()</code> method, which uses the
249 * platform's default character encoding.
250 *
251 * @param hibyte the high byte of each resulting Unicode character.
252 * @return the current contents of the output stream, as a string.
253 * @see java.io.ByteArrayOutputStream#size()
254 * @see java.io.ByteArrayOutputStream#toString(String)
255 * @see java.io.ByteArrayOutputStream#toString()
256 */
257 @Deprecated
258 public synchronized String toString(int hibyte) {
259 return new String(buf, hibyte, 0, count);
260 }
261
262 /**
263 * Closing a <tt>ByteArrayOutputStream</tt> has no effect. The methods in
264 * this class can be called after the stream has been closed without
265 * generating an <tt>IOException</tt>.
266 * <p>
267 *
268 */
269 public void close() throws IOException {
270 }
271
272}
java/pkg/java/io/CharArrayReader.class+0−0

Binary file not shown.

java/pkg/java/io/CharArrayReader.java+232−0
@@ -0,0 +1,232 @@
1/*
2 * Copyright (c) 1996, 2005, 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
26package java.io;
27
28/**
29 * This class implements a character buffer that can be used as a
30 * character-input stream.
31 *
32 * @author Herb Jellinek
33 * @since JDK1.1
34 */
35public class CharArrayReader extends Reader {
36 /** The character buffer. */
37 protected char buf[];
38
39 /** The current buffer position. */
40 protected int pos;
41
42 /** The position of mark in buffer. */
43 protected int markedPos = 0;
44
45 /**
46 * The index of the end of this buffer. There is not valid
47 * data at or beyond this index.
48 */
49 protected int count;
50
51 /**
52 * Creates a CharArrayReader from the specified array of chars.
53 * @param buf Input buffer (not copied)
54 */
55 public CharArrayReader(char buf[]) {
56 this.buf = buf;
57 this.pos = 0;
58 this.count = buf.length;
59 }
60
61 /**
62 * Creates a CharArrayReader from the specified array of chars.
63 *
64 * <p> The resulting reader will start reading at the given
65 * <tt>offset</tt>. The total number of <tt>char</tt> values that can be
66 * read from this reader will be either <tt>length</tt> or
67 * <tt>buf.length-offset</tt>, whichever is smaller.
68 *
69 * @throws IllegalArgumentException
70 * If <tt>offset</tt> is negative or greater than
71 * <tt>buf.length</tt>, or if <tt>length</tt> is negative, or if
72 * the sum of these two values is negative.
73 *
74 * @param buf Input buffer (not copied)
75 * @param offset Offset of the first char to read
76 * @param length Number of chars to read
77 */
78 public CharArrayReader(char buf[], int offset, int length) {
79 if ((offset < 0) || (offset > buf.length) || (length < 0) ||
80 ((offset + length) < 0)) {
81 throw new IllegalArgumentException();
82 }
83 this.buf = buf;
84 this.pos = offset;
85 this.count = Math.min(offset + length, buf.length);
86 this.markedPos = offset;
87 }
88
89 /** Checks to make sure that the stream has not been closed */
90 private void ensureOpen() throws IOException {
91 if (buf == null)
92 throw new IOException("Stream closed");
93 }
94
95 /**
96 * Reads a single character.
97 *
98 * @exception IOException If an I/O error occurs
99 */
100 public int read() throws IOException {
101 synchronized (lock) {
102 ensureOpen();
103 if (pos >= count)
104 return -1;
105 else
106 return buf[pos++];
107 }
108 }
109
110 /**
111 * Reads characters into a portion of an array.
112 * @param b Destination buffer
113 * @param off Offset at which to start storing characters
114 * @param len Maximum number of characters to read
115 * @return The actual number of characters read, or -1 if
116 * the end of the stream has been reached
117 *
118 * @exception IOException If an I/O error occurs
119 */
120 public int read(char b[], int off, int len) throws IOException {
121 synchronized (lock) {
122 ensureOpen();
123 if ((off < 0) || (off > b.length) || (len < 0) ||
124 ((off + len) > b.length) || ((off + len) < 0)) {
125 throw new IndexOutOfBoundsException();
126 } else if (len == 0) {
127 return 0;
128 }
129
130 if (pos >= count) {
131 return -1;
132 }
133 if (pos + len > count) {
134 len = count - pos;
135 }
136 if (len <= 0) {
137 return 0;
138 }
139 System.arraycopy(buf, pos, b, off, len);
140 pos += len;
141 return len;
142 }
143 }
144
145 /**
146 * Skips characters. Returns the number of characters that were skipped.
147 *
148 * <p>The <code>n</code> parameter may be negative, even though the
149 * <code>skip</code> method of the {@link Reader} superclass throws
150 * an exception in this case. If <code>n</code> is negative, then
151 * this method does nothing and returns <code>0</code>.
152 *
153 * @param n The number of characters to skip
154 * @return The number of characters actually skipped
155 * @exception IOException If the stream is closed, or an I/O error occurs
156 */
157 public long skip(long n) throws IOException {
158 synchronized (lock) {
159 ensureOpen();
160 if (pos + n > count) {
161 n = count - pos;
162 }
163 if (n < 0) {
164 return 0;
165 }
166 pos += n;
167 return n;
168 }
169 }
170
171 /**
172 * Tells whether this stream is ready to be read. Character-array readers
173 * are always ready to be read.
174 *
175 * @exception IOException If an I/O error occurs
176 */
177 public boolean ready() throws IOException {
178 synchronized (lock) {
179 ensureOpen();
180 return (count - pos) > 0;
181 }
182 }
183
184 /**
185 * Tells whether this stream supports the mark() operation, which it does.
186 */
187 public boolean markSupported() {
188 return true;
189 }
190
191 /**
192 * Marks the present position in the stream. Subsequent calls to reset()
193 * will reposition the stream to this point.
194 *
195 * @param readAheadLimit Limit on the number of characters that may be
196 * read while still preserving the mark. Because
197 * the stream's input comes from a character array,
198 * there is no actual limit; hence this argument is
199 * ignored.
200 *
201 * @exception IOException If an I/O error occurs
202 */
203 public void mark(int readAheadLimit) throws IOException {
204 synchronized (lock) {
205 ensureOpen();
206 markedPos = pos;
207 }
208 }
209
210 /**
211 * Resets the stream to the most recent mark, or to the beginning if it has
212 * never been marked.
213 *
214 * @exception IOException If an I/O error occurs
215 */
216 public void reset() throws IOException {
217 synchronized (lock) {
218 ensureOpen();
219 pos = markedPos;
220 }
221 }
222
223 /**
224 * Closes the stream and releases any system resources associated with
225 * it. Once the stream has been closed, further read(), ready(),
226 * mark(), reset(), or skip() invocations will throw an IOException.
227 * Closing a previously closed stream has no effect.
228 */
229 public void close() {
230 buf = null;
231 }
232}
java/pkg/java/io/CharArrayWriter.class+0−0

Binary file not shown.

java/pkg/java/io/CharArrayWriter.java+280−0
@@ -0,0 +1,280 @@
1/*
2 * Copyright (c) 1996, 2005, 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
26package java.io;
27
28import java.util.Arrays;
29
30/**
31 * This class implements a character buffer that can be used as an Writer.
32 * The buffer automatically grows when data is written to the stream. The data
33 * can be retrieved using toCharArray() and toString().
34 * <P>
35 * Note: Invoking close() on this class has no effect, and methods
36 * of this class can be called after the stream has closed
37 * without generating an IOException.
38 *
39 * @author Herb Jellinek
40 * @since JDK1.1
41 */
42public
43class CharArrayWriter extends Writer {
44 /**
45 * The buffer where data is stored.
46 */
47 protected char buf[];
48
49 /**
50 * The number of chars in the buffer.
51 */
52 protected int count;
53
54 /**
55 * Creates a new CharArrayWriter.
56 */
57 public CharArrayWriter() {
58 this(32);
59 }
60
61 /**
62 * Creates a new CharArrayWriter with the specified initial size.
63 *
64 * @param initialSize an int specifying the initial buffer size.
65 * @exception IllegalArgumentException if initialSize is negative
66 */
67 public CharArrayWriter(int initialSize) {
68 if (initialSize < 0) {
69 throw new IllegalArgumentException("Negative initial size: "
70 + initialSize);
71 }
72 buf = new char[initialSize];
73 }
74
75 /**
76 * Writes a character to the buffer.
77 */
78 public void write(int c) {
79 synchronized (lock) {
80 int newcount = count + 1;
81 if (newcount > buf.length) {
82 buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
83 }
84 buf[count] = (char)c;
85 count = newcount;
86 }
87 }
88
89 /**
90 * Writes characters to the buffer.
91 * @param c the data to be written
92 * @param off the start offset in the data
93 * @param len the number of chars that are written
94 */
95 public void write(char c[], int off, int len) {
96 if ((off < 0) || (off > c.length) || (len < 0) ||
97 ((off + len) > c.length) || ((off + len) < 0)) {
98 throw new IndexOutOfBoundsException();
99 } else if (len == 0) {
100 return;
101 }
102 synchronized (lock) {
103 int newcount = count + len;
104 if (newcount > buf.length) {
105 buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
106 }
107 System.arraycopy(c, off, buf, count, len);
108 count = newcount;
109 }
110 }
111
112 /**
113 * Write a portion of a string to the buffer.
114 * @param str String to be written from
115 * @param off Offset from which to start reading characters
116 * @param len Number of characters to be written
117 */
118 public void write(String str, int off, int len) {
119 synchronized (lock) {
120 int newcount = count + len;
121 if (newcount > buf.length) {
122 buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
123 }
124 str.getChars(off, off + len, buf, count);
125 count = newcount;
126 }
127 }
128
129 /**
130 * Writes the contents of the buffer to another character stream.
131 *
132 * @param out the output stream to write to
133 * @throws IOException If an I/O error occurs.
134 */
135 public void writeTo(Writer out) throws IOException {
136 synchronized (lock) {
137 out.write(buf, 0, count);
138 }
139 }
140
141 /**
142 * Appends the specified character sequence to this writer.
143 *
144 * <p> An invocation of this method of the form <tt>out.append(csq)</tt>
145 * behaves in exactly the same way as the invocation
146 *
147 * <pre>
148 * out.write(csq.toString()) </pre>
149 *
150 * <p> Depending on the specification of <tt>toString</tt> for the
151 * character sequence <tt>csq</tt>, the entire sequence may not be
152 * appended. For instance, invoking the <tt>toString</tt> method of a
153 * character buffer will return a subsequence whose content depends upon
154 * the buffer's position and limit.
155 *
156 * @param csq
157 * The character sequence to append. If <tt>csq</tt> is
158 * <tt>null</tt>, then the four characters <tt>"null"</tt> are
159 * appended to this writer.
160 *
161 * @return This writer
162 *
163 * @since 1.5
164 */
165 public CharArrayWriter append(CharSequence csq) {
166 String s = (csq == null ? "null" : csq.toString());
167 write(s, 0, s.length());
168 return this;
169 }
170
171 /**
172 * Appends a subsequence of the specified character sequence to this writer.
173 *
174 * <p> An invocation of this method of the form <tt>out.append(csq, start,
175 * end)</tt> when <tt>csq</tt> is not <tt>null</tt>, behaves in
176 * exactly the same way as the invocation
177 *
178 * <pre>
179 * out.write(csq.subSequence(start, end).toString()) </pre>
180 *
181 * @param csq
182 * The character sequence from which a subsequence will be
183 * appended. If <tt>csq</tt> is <tt>null</tt>, then characters
184 * will be appended as if <tt>csq</tt> contained the four
185 * characters <tt>"null"</tt>.
186 *
187 * @param start
188 * The index of the first character in the subsequence
189 *
190 * @param end
191 * The index of the character following the last character in the
192 * subsequence
193 *
194 * @return This writer
195 *
196 * @throws IndexOutOfBoundsException
197 * If <tt>start</tt> or <tt>end</tt> are negative, <tt>start</tt>
198 * is greater than <tt>end</tt>, or <tt>end</tt> is greater than
199 * <tt>csq.length()</tt>
200 *
201 * @since 1.5
202 */
203 public CharArrayWriter append(CharSequence csq, int start, int end) {
204 String s = (csq == null ? "null" : csq).subSequence(start, end).toString();
205 write(s, 0, s.length());
206 return this;
207 }
208
209 /**
210 * Appends the specified character to this writer.
211 *
212 * <p> An invocation of this method of the form <tt>out.append(c)</tt>
213 * behaves in exactly the same way as the invocation
214 *
215 * <pre>
216 * out.write(c) </pre>
217 *
218 * @param c
219 * The 16-bit character to append
220 *
221 * @return This writer
222 *
223 * @since 1.5
224 */
225 public CharArrayWriter append(char c) {
226 write(c);
227 return this;
228 }
229
230 /**
231 * Resets the buffer so that you can use it again without
232 * throwing away the already allocated buffer.
233 */
234 public void reset() {
235 count = 0;
236 }
237
238 /**
239 * Returns a copy of the input data.
240 *
241 * @return an array of chars copied from the input data.
242 */
243 public char toCharArray()[] {
244 synchronized (lock) {
245 return Arrays.copyOf(buf, count);
246 }
247 }
248
249 /**
250 * Returns the current size of the buffer.
251 *
252 * @return an int representing the current size of the buffer.
253 */
254 public int size() {
255 return count;
256 }
257
258 /**
259 * Converts input data to a string.
260 * @return the string.
261 */
262 public String toString() {
263 synchronized (lock) {
264 return new String(buf, 0, count);
265 }
266 }
267
268 /**
269 * Flush the stream.
270 */
271 public void flush() { }
272
273 /**
274 * Close the stream. This method does not release the buffer, since its
275 * contents might still be required. Note: Invoking this method in this class
276 * will have no effect.
277 */
278 public void close() { }
279
280}
java/pkg/java/io/CharConversionException.class+0−0

Binary file not shown.

java/pkg/java/io/CharConversionException.java+51−0
@@ -0,0 +1,51 @@
1/*
2 * Copyright (c) 1996, 2008, 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 */
25package java.io;
26
27/**
28 * Base class for character conversion exceptions.
29 *
30 * @author Asmus Freytag
31 * @since JDK1.1
32 */
33public class CharConversionException
34 extends java.io.IOException
35{
36 private static final long serialVersionUID = -8680016352018427031L;
37
38 /**
39 * This provides no detailed message.
40 */
41 public CharConversionException() {
42 }
43 /**
44 * This provides a detailed message.
45 *
46 * @param s the detailed message associated with the exception.
47 */
48 public CharConversionException(String s) {
49 super(s);
50 }
51}
java/pkg/java/io/Closeable.class+0−0

Binary file not shown.

java/pkg/java/io/Closeable.java+48−0
@@ -0,0 +1,48 @@
1/*
2 * Copyright (c) 2003, 2010, 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
26package java.io;
27
28import java.io.IOException;
29
30/**
31 * A {@code Closeable} is a source or destination of data that can be closed.
32 * The close method is invoked to release resources that the object is
33 * holding (such as open files).
34 *
35 * @since 1.5
36 */
37
38public interface Closeable extends AutoCloseable {
39
40 /**
41 * Closes this stream and releases any system resources associated
42 * with it. If the stream is already closed then invoking this
43 * method has no effect.
44 *
45 * @throws IOException if an I/O error occurs
46 */
47 public void close() throws IOException;
48}
java/pkg/java/io/Console$1.class+0−0

Binary file not shown.

java/pkg/java/io/Console$2.class+0−0

Binary file not shown.

java/pkg/java/io/Console$3.class+0−0

Binary file not shown.

java/pkg/java/io/Console$LineReader.class+0−0

Binary file not shown.

java/pkg/java/io/Console.class+0−0

Binary file not shown.

java/pkg/java/io/Console.java+578−0
@@ -0,0 +1,578 @@
1/*
2 * Copyright (c) 2005, 2011, 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
26package java.io;
27
28import java.util.*;
29import java.nio.charset.Charset;
30import sun.nio.cs.StreamDecoder;
31import sun.nio.cs.StreamEncoder;
32
33/**
34 * Methods to access the character-based console device, if any, associated
35 * with the current Java virtual machine.
36 *
37 * <p> Whether a virtual machine has a console is dependent upon the
38 * underlying platform and also upon the manner in which the virtual
39 * machine is invoked. If the virtual machine is started from an
40 * interactive command line without redirecting the standard input and
41 * output streams then its console will exist and will typically be
42 * connected to the keyboard and display from which the virtual machine
43 * was launched. If the virtual machine is started automatically, for
44 * example by a background job scheduler, then it will typically not
45 * have a console.
46 * <p>
47 * If this virtual machine has a console then it is represented by a
48 * unique instance of this class which can be obtained by invoking the
49 * {@link java.lang.System#console()} method. If no console device is
50 * available then an invocation of that method will return <tt>null</tt>.
51 * <p>
52 * Read and write operations are synchronized to guarantee the atomic
53 * completion of critical operations; therefore invoking methods
54 * {@link #readLine()}, {@link #readPassword()}, {@link #format format()},
55 * {@link #printf printf()} as well as the read, format and write operations
56 * on the objects returned by {@link #reader()} and {@link #writer()} may
57 * block in multithreaded scenarios.
58 * <p>
59 * Invoking <tt>close()</tt> on the objects returned by the {@link #reader()}
60 * and the {@link #writer()} will not close the underlying stream of those
61 * objects.
62 * <p>
63 * The console-read methods return <tt>null</tt> when the end of the
64 * console input stream is reached, for example by typing control-D on
65 * Unix or control-Z on Windows. Subsequent read operations will succeed
66 * if additional characters are later entered on the console's input
67 * device.
68 * <p>
69 * Unless otherwise specified, passing a <tt>null</tt> argument to any method
70 * in this class will cause a {@link NullPointerException} to be thrown.
71 * <p>
72 * <b>Security note:</b>
73 * If an application needs to read a password or other secure data, it should
74 * use {@link #readPassword()} or {@link #readPassword(String, Object...)} and
75 * manually zero the returned character array after processing to minimize the
76 * lifetime of sensitive data in memory.
77 *
78 * <blockquote><pre>
79 * Console cons;
80 * char[] passwd;
81 * if ((cons = System.console()) != null &&
82 * (passwd = cons.readPassword("[%s]", "Password:")) != null) {
83 * ...
84 * java.util.Arrays.fill(passwd, ' ');
85 * }
86 * </pre></blockquote>
87 *
88 * @author Xueming Shen
89 * @since 1.6
90 */
91
92public final class Console implements Flushable
93{
94 /**
95 * Retrieves the unique {@link java.io.PrintWriter PrintWriter} object
96 * associated with this console.
97 *
98 * @return The printwriter associated with this console
99 */
100 public PrintWriter writer() {
101 return pw;
102 }
103
104 /**
105 * Retrieves the unique {@link java.io.Reader Reader} object associated
106 * with this console.
107 * <p>
108 * This method is intended to be used by sophisticated applications, for
109 * example, a {@link java.util.Scanner} object which utilizes the rich
110 * parsing/scanning functionality provided by the <tt>Scanner</tt>:
111 * <blockquote><pre>
112 * Console con = System.console();
113 * if (con != null) {
114 * Scanner sc = new Scanner(con.reader());
115 * ...
116 * }
117 * </pre></blockquote>
118 * <p>
119 * For simple applications requiring only line-oriented reading, use
120 * <tt>{@link #readLine}</tt>.
121 * <p>
122 * The bulk read operations {@link java.io.Reader#read(char[]) read(char[]) },
123 * {@link java.io.Reader#read(char[], int, int) read(char[], int, int) } and
124 * {@link java.io.Reader#read(java.nio.CharBuffer) read(java.nio.CharBuffer)}
125 * on the returned object will not read in characters beyond the line
126 * bound for each invocation, even if the destination buffer has space for
127 * more characters. A line bound is considered to be any one of a line feed
128 * (<tt>'\n'</tt>), a carriage return (<tt>'\r'</tt>), a carriage return
129 * followed immediately by a linefeed, or an end of stream.
130 *
131 * @return The reader associated with this console
132 */
133 public Reader reader() {
134 return reader;
135 }
136
137 /**
138 * Writes a formatted string to this console's output stream using
139 * the specified format string and arguments.
140 *
141 * @param fmt
142 * A format string as described in <a
143 * href="../util/Formatter.html#syntax">Format string syntax</a>
144 *
145 * @param args
146 * Arguments referenced by the format specifiers in the format
147 * string. If there are more arguments than format specifiers, the
148 * extra arguments are ignored. The number of arguments is
149 * variable and may be zero. The maximum number of arguments is
150 * limited by the maximum dimension of a Java array as defined by
151 * <cite>The Java&trade; Virtual Machine Specification</cite>.
152 * The behaviour on a
153 * <tt>null</tt> argument depends on the <a
154 * href="../util/Formatter.html#syntax">conversion</a>.
155 *
156 * @throws IllegalFormatException
157 * If a format string contains an illegal syntax, a format
158 * specifier that is incompatible with the given arguments,
159 * insufficient arguments given the format string, or other
160 * illegal conditions. For specification of all possible
161 * formatting errors, see the <a
162 * href="../util/Formatter.html#detail">Details</a> section
163 * of the formatter class specification.
164 *
165 * @return This console
166 */
167 public Console format(String fmt, Object ...args) {
168 formatter.format(fmt, args).flush();
169 return this;
170 }
171
172 /**
173 * A convenience method to write a formatted string to this console's
174 * output stream using the specified format string and arguments.
175 *
176 * <p> An invocation of this method of the form <tt>con.printf(format,
177 * args)</tt> behaves in exactly the same way as the invocation of
178 * <pre>con.format(format, args)</pre>.
179 *
180 * @param format
181 * A format string as described in <a
182 * href="../util/Formatter.html#syntax">Format string syntax</a>.
183 *
184 * @param args
185 * Arguments referenced by the format specifiers in the format
186 * string. If there are more arguments than format specifiers, the
187 * extra arguments are ignored. The number of arguments is
188 * variable and may be zero. The maximum number of arguments is
189 * limited by the maximum dimension of a Java array as defined by
190 * <cite>The Java&trade; Virtual Machine Specification</cite>.
191 * The behaviour on a
192 * <tt>null</tt> argument depends on the <a
193 * href="../util/Formatter.html#syntax">conversion</a>.
194 *
195 * @throws IllegalFormatException
196 * If a format string contains an illegal syntax, a format
197 * specifier that is incompatible with the given arguments,
198 * insufficient arguments given the format string, or other
199 * illegal conditions. For specification of all possible
200 * formatting errors, see the <a
201 * href="../util/Formatter.html#detail">Details</a> section of the
202 * formatter class specification.
203 *
204 * @return This console
205 */
206 public Console printf(String format, Object ... args) {
207 return format(format, args);
208 }
209
210 /**
211 * Provides a formatted prompt, then reads a single line of text from the
212 * console.
213 *
214 * @param fmt
215 * A format string as described in <a
216 * href="../util/Formatter.html#syntax">Format string syntax</a>.
217 *
218 * @param args
219 * Arguments referenced by the format specifiers in the format
220 * string. If there are more arguments than format specifiers, the
221 * extra arguments are ignored. The maximum number of arguments is
222 * limited by the maximum dimension of a Java array as defined by
223 * <cite>The Java&trade; Virtual Machine Specification</cite>.
224 *
225 * @throws IllegalFormatException
226 * If a format string contains an illegal syntax, a format
227 * specifier that is incompatible with the given arguments,
228 * insufficient arguments given the format string, or other
229 * illegal conditions. For specification of all possible
230 * formatting errors, see the <a
231 * href="../util/Formatter.html#detail">Details</a> section
232 * of the formatter class specification.
233 *
234 * @throws IOError
235 * If an I/O error occurs.
236 *
237 * @return A string containing the line read from the console, not
238 * including any line-termination characters, or <tt>null</tt>
239 * if an end of stream has been reached.
240 */
241 public String readLine(String fmt, Object ... args) {
242 String line = null;
243 synchronized (writeLock) {
244 synchronized(readLock) {
245 if (fmt.length() != 0)
246 pw.format(fmt, args);
247 try {
248 char[] ca = readline(false);
249 if (ca != null)
250 line = new String(ca);
251 } catch (IOException x) {
252 throw new IOError(x);
253 }
254 }
255 }
256 return line;
257 }
258
259 /**
260 * Reads a single line of text from the console.
261 *
262 * @throws IOError
263 * If an I/O error occurs.
264 *
265 * @return A string containing the line read from the console, not
266 * including any line-termination characters, or <tt>null</tt>
267 * if an end of stream has been reached.
268 */
269 public String readLine() {
270 return readLine("");
271 }
272
273 /**
274 * Provides a formatted prompt, then reads a password or passphrase from
275 * the console with echoing disabled.
276 *
277 * @param fmt
278 * A format string as described in <a
279 * href="../util/Formatter.html#syntax">Format string syntax</a>
280 * for the prompt text.
281 *
282 * @param args
283 * Arguments referenced by the format specifiers in the format
284 * string. If there are more arguments than format specifiers, the
285 * extra arguments are ignored. The maximum number of arguments is
286 * limited by the maximum dimension of a Java array as defined by
287 * <cite>The Java&trade; Virtual Machine Specification</cite>.
288 *
289 * @throws IllegalFormatException
290 * If a format string contains an illegal syntax, a format
291 * specifier that is incompatible with the given arguments,
292 * insufficient arguments given the format string, or other
293 * illegal conditions. For specification of all possible
294 * formatting errors, see the <a
295 * href="../util/Formatter.html#detail">Details</a>
296 * section of the formatter class specification.
297 *
298 * @throws IOError
299 * If an I/O error occurs.
300 *
301 * @return A character array containing the password or passphrase read
302 * from the console, not including any line-termination characters,
303 * or <tt>null</tt> if an end of stream has been reached.
304 */
305 public char[] readPassword(String fmt, Object ... args) {
306 char[] passwd = null;
307 synchronized (writeLock) {
308 synchronized(readLock) {
309 try {
310 echoOff = echo(false);
311 } catch (IOException x) {
312 throw new IOError(x);
313 }
314 IOError ioe = null;
315 try {
316 if (fmt.length() != 0)
317 pw.format(fmt, args);
318 passwd = readline(true);
319 } catch (IOException x) {
320 ioe = new IOError(x);
321 } finally {
322 try {
323 echoOff = echo(true);
324 } catch (IOException x) {
325 if (ioe == null)
326 ioe = new IOError(x);
327 else
328 ioe.addSuppressed(x);
329 }
330 if (ioe != null)
331 throw ioe;
332 }
333 pw.println();
334 }
335 }
336 return passwd;
337 }
338
339 /**
340 * Reads a password or passphrase from the console with echoing disabled
341 *
342 * @throws IOError
343 * If an I/O error occurs.
344 *
345 * @return A character array containing the password or passphrase read
346 * from the console, not including any line-termination characters,
347 * or <tt>null</tt> if an end of stream has been reached.
348 */
349 public char[] readPassword() {
350 return readPassword("");
351 }
352
353 /**
354 * Flushes the console and forces any buffered output to be written
355 * immediately .
356 */
357 public void flush() {
358 pw.flush();
359 }
360
361 private Object readLock;
362 private Object writeLock;
363 private Reader reader;
364 private Writer out;
365 private PrintWriter pw;
366 private Formatter formatter;
367 private Charset cs;
368 private char[] rcb;
369 private static native String encoding();
370 private static native boolean echo(boolean on) throws IOException;
371 private static boolean echoOff;
372
373 private char[] readline(boolean zeroOut) throws IOException {
374 int len = reader.read(rcb, 0, rcb.length);
375 if (len < 0)
376 return null; //EOL
377 if (rcb[len-1] == '\r')
378 len--; //remove CR at end;
379 else if (rcb[len-1] == '\n') {
380 len--; //remove LF at end;
381 if (len > 0 && rcb[len-1] == '\r')
382 len--; //remove the CR, if there is one
383 }
384 char[] b = new char[len];
385 if (len > 0) {
386 System.arraycopy(rcb, 0, b, 0, len);
387 if (zeroOut) {
388 Arrays.fill(rcb, 0, len, ' ');
389 }
390 }
391 return b;
392 }
393
394 private char[] grow() {
395 assert Thread.holdsLock(readLock);
396 char[] t = new char[rcb.length * 2];
397 System.arraycopy(rcb, 0, t, 0, rcb.length);
398 rcb = t;
399 return rcb;
400 }
401
402 class LineReader extends Reader {
403 private Reader in;
404 private char[] cb;
405 private int nChars, nextChar;
406 boolean leftoverLF;
407 LineReader(Reader in) {
408 this.in = in;
409 cb = new char[1024];
410 nextChar = nChars = 0;
411 leftoverLF = false;
412 }
413 public void close () {}
414 public boolean ready() throws IOException {
415 //in.ready synchronizes on readLock already
416 return in.ready();
417 }
418
419 public int read(char cbuf[], int offset, int length)
420 throws IOException
421 {
422 int off = offset;
423 int end = offset + length;
424 if (offset < 0 || offset > cbuf.length || length < 0 ||
425 end < 0 || end > cbuf.length) {
426 throw new IndexOutOfBoundsException();
427 }
428 synchronized(readLock) {
429 boolean eof = false;
430 char c = 0;
431 for (;;) {
432 if (nextChar >= nChars) { //fill
433 int n = 0;
434 do {
435 n = in.read(cb, 0, cb.length);
436 } while (n == 0);
437 if (n > 0) {
438 nChars = n;
439 nextChar = 0;
440 if (n < cb.length &&
441 cb[n-1] != '\n' && cb[n-1] != '\r') {
442 /*
443 * we're in canonical mode so each "fill" should
444 * come back with an eol. if there no lf or nl at
445 * the end of returned bytes we reached an eof.
446 */
447 eof = true;
448 }
449 } else { /*EOF*/
450 if (off - offset == 0)
451 return -1;
452 return off - offset;
453 }
454 }
455 if (leftoverLF && cbuf == rcb && cb[nextChar] == '\n') {
456 /*
457 * if invoked by our readline, skip the leftover, otherwise
458 * return the LF.
459 */
460 nextChar++;
461 }
462 leftoverLF = false;
463 while (nextChar < nChars) {
464 c = cbuf[off++] = cb[nextChar];
465 cb[nextChar++] = 0;
466 if (c == '\n') {
467 return off - offset;
468 } else if (c == '\r') {
469 if (off == end) {
470 /* no space left even the next is LF, so return
471 * whatever we have if the invoker is not our
472 * readLine()
473 */
474 if (cbuf == rcb) {
475 cbuf = grow();
476 end = cbuf.length;
477 } else {
478 leftoverLF = true;
479 return off - offset;
480 }
481 }
482 if (nextChar == nChars && in.ready()) {
483 /*
484 * we have a CR and we reached the end of
485 * the read in buffer, fill to make sure we
486 * don't miss a LF, if there is one, it's possible
487 * that it got cut off during last round reading
488 * simply because the read in buffer was full.
489 */
490 nChars = in.read(cb, 0, cb.length);
491 nextChar = 0;
492 }
493 if (nextChar < nChars && cb[nextChar] == '\n') {
494 cbuf[off++] = '\n';
495 nextChar++;
496 }
497 return off - offset;
498 } else if (off == end) {
499 if (cbuf == rcb) {
500 cbuf = grow();
501 end = cbuf.length;
502 } else {
503 return off - offset;
504 }
505 }
506 }
507 if (eof)
508 return off - offset;
509 }
510 }
511 }
512 }
513
514 // Set up JavaIOAccess in SharedSecrets
515 static {
516 try {
517 // Add a shutdown hook to restore console's echo state should
518 // it be necessary.
519 sun.misc.SharedSecrets.getJavaLangAccess()
520 .registerShutdownHook(0 /* shutdown hook invocation order */,
521 false /* only register if shutdown is not in progress */,
522 new Runnable() {
523 public void run() {
524 try {
525 if (echoOff) {
526 echo(true);
527 }
528 } catch (IOException x) { }
529 }
530 });
531 } catch (IllegalStateException e) {
532 // shutdown is already in progress and console is first used
533 // by a shutdown hook
534 }
535
536 sun.misc.SharedSecrets.setJavaIOAccess(new sun.misc.JavaIOAccess() {
537 public Console console() {
538 if (istty()) {
539 if (cons == null)
540 cons = new Console();
541 return cons;
542 }
543 return null;
544 }
545
546 public Charset charset() {
547 // This method is called in sun.security.util.Password,
548 // cons already exists when this method is called
549 return cons.cs;
550 }
551 });
552 }
553 private static Console cons;
554 private native static boolean istty();
555 private Console() {
556 readLock = new Object();
557 writeLock = new Object();
558 String csname = encoding();
559 if (csname != null) {
560 try {
561 cs = Charset.forName(csname);
562 } catch (Exception x) {}
563 }
564 if (cs == null)
565 cs = Charset.defaultCharset();
566 out = StreamEncoder.forOutputStreamWriter(
567 new FileOutputStream(FileDescriptor.out),
568 writeLock,
569 cs);
570 pw = new PrintWriter(out, true) { public void close() {} };
571 formatter = new Formatter(out);
572 reader = new LineReader(StreamDecoder.forInputStreamReader(
573 new FileInputStream(FileDescriptor.in),
574 readLock,
575 cs));
576 rcb = new char[1024];
577 }
578}
java/pkg/java/io/DataInput.class+0−0

Binary file not shown.

java/pkg/java/io/DataInput.java+635−0
@@ -0,0 +1,635 @@
1/*
2 * Copyright (c) 1995, 2006, 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
26package java.io;
27
28/**
29 * The <code>DataInput</code> interface provides
30 * for reading bytes from a binary stream and
31 * reconstructing from them data in any of
32 * the Java primitive types. There is also
33 * a
34 * facility for reconstructing a <code>String</code>
35 * from data in
36 * <a href="#modified-utf-8">modified UTF-8</a>
37 * format.
38 * <p>
39 * It is generally true of all the reading
40 * routines in this interface that if end of
41 * file is reached before the desired number
42 * of bytes has been read, an <code>EOFException</code>
43 * (which is a kind of <code>IOException</code>)
44 * is thrown. If any byte cannot be read for
45 * any reason other than end of file, an <code>IOException</code>
46 * other than <code>EOFException</code> is
47 * thrown. In particular, an <code>IOException</code>
48 * may be thrown if the input stream has been
49 * closed.
50 *
51 * <h4><a name="modified-utf-8">Modified UTF-8</a></h4>
52 * <p>
53 * Implementations of the DataInput and DataOutput interfaces represent
54 * Unicode strings in a format that is a slight modification of UTF-8.
55 * (For information regarding the standard UTF-8 format, see section
56 * <i>3.9 Unicode Encoding Forms</i> of <i>The Unicode Standard, Version
57 * 4.0</i>).
58 * Note that in the following tables, the most significant bit appears in the
59 * far left-hand column.
60 * <p>
61 * All characters in the range <code>'&#92;u0001'</code> to
62 * <code>'&#92;u007F'</code> are represented by a single byte:
63 *
64 * <blockquote>
65 * <table border="1" cellspacing="0" cellpadding="8" width="50%"
66 * summary="Bit values and bytes">
67 * <tr>
68 * <td></td>
69 * <th id="bit">Bit Values</th>
70 * </tr>
71 * <tr>
72 * <th id="byte1">Byte 1</th>
73 * <td>
74 * <table border="1" cellspacing="0" width="100%">
75 * <tr>
76 * <td width="12%"><center>0</center>
77 * <td colspan="7"><center>bits 6-0</center>
78 * </tr>
79 * </table>
80 * </td>
81 * </tr>
82 * </table>
83 * </blockquote>
84 *
85 * <p>
86 * The null character <code>'&#92;u0000'</code> and characters in the
87 * range <code>'&#92;u0080'</code> to <code>'&#92;u07FF'</code> are
88 * represented by a pair of bytes:
89 *
90 * <blockquote>
91 * <table border="1" cellspacing="0" cellpadding="8" width="50%"
92 * summary="Bit values and bytes">
93 * <tr>
94 * <td></td>
95 * <th id="bit">Bit Values</th>
96 * </tr>
97 * <tr>
98 * <th id="byte1">Byte 1</th>
99 * <td>
100 * <table border="1" cellspacing="0" width="100%">
101 * <tr>
102 * <td width="12%"><center>1</center>
103 * <td width="13%"><center>1</center>
104 * <td width="12%"><center>0</center>
105 * <td colspan="5"><center>bits 10-6</center>
106 * </tr>
107 * </table>
108 * </td>
109 * </tr>
110 * <tr>
111 * <th id="byte2">Byte 2</th>
112 * <td>
113 * <table border="1" cellspacing="0" width="100%">
114 * <tr>
115 * <td width="12%"><center>1</center>
116 * <td width="13%"><center>0</center>
117 * <td colspan="6"><center>bits 5-0</center>
118 * </tr>
119 * </table>
120 * </td>
121 * </tr>
122 * </table>
123 * </blockquote>
124 *
125 * <br>
126 * <code>char</code> values in the range <code>'&#92;u0800'</code> to
127 * <code>'&#92;uFFFF'</code> are represented by three bytes:
128 *
129 * <blockquote>
130 * <table border="1" cellspacing="0" cellpadding="8" width="50%"
131 * summary="Bit values and bytes">
132 * <tr>
133 * <td></td>
134 * <th id="bit">Bit Values</th>
135 * </tr>
136 * <tr>
137 * <th id="byte1">Byte 1</th>
138 * <td>
139 * <table border="1" cellspacing="0" width="100%">
140 * <tr>
141 * <td width="12%"><center>1</center>
142 * <td width="13%"><center>1</center>
143 * <td width="12%"><center>1</center>
144 * <td width="13%"><center>0</center>
145 * <td colspan="4"><center>bits 15-12</center>
146 * </tr>
147 * </table>
148 * </td>
149 * </tr>
150 * <tr>
151 * <th id="byte2">Byte 2</th>
152 * <td>
153 * <table border="1" cellspacing="0" width="100%">
154 * <tr>
155 * <td width="12%"><center>1</center>
156 * <td width="13%"><center>0</center>
157 * <td colspan="6"><center>bits 11-6</center>
158 * </tr>
159 * </table>
160 * </td>
161 * </tr>
162 * <tr>
163 * <th id="byte3">Byte 3</th>
164 * <td>
165 * <table border="1" cellspacing="0" width="100%">
166 * <tr>
167 * <td width="12%"><center>1</center>
168 * <td width="13%"><center>0</center>
169 * <td colspan="6"><center>bits 5-0</center>
170 * </tr>
171 * </table>
172 * </td>
173 * </tr>
174 * </table>
175 * </blockquote>
176 *
177 * <p>
178 * The differences between this format and the
179 * standard UTF-8 format are the following:
180 * <ul>
181 * <li>The null byte <code>'&#92;u0000'</code> is encoded in 2-byte format
182 * rather than 1-byte, so that the encoded strings never have
183 * embedded nulls.
184 * <li>Only the 1-byte, 2-byte, and 3-byte formats are used.
185 * <li><a href="../lang/Character.html#unicode">Supplementary characters</a>
186 * are represented in the form of surrogate pairs.
187 * </ul>
188 * @author Frank Yellin
189 * @see java.io.DataInputStream
190 * @see java.io.DataOutput
191 * @since JDK1.0
192 */
193public
194interface DataInput {
195 /**
196 * Reads some bytes from an input
197 * stream and stores them into the buffer
198 * array <code>b</code>. The number of bytes
199 * read is equal
200 * to the length of <code>b</code>.
201 * <p>
202 * This method blocks until one of the
203 * following conditions occurs:<p>
204 * <ul>
205 * <li><code>b.length</code>
206 * bytes of input data are available, in which
207 * case a normal return is made.
208 *
209 * <li>End of
210 * file is detected, in which case an <code>EOFException</code>
211 * is thrown.
212 *
213 * <li>An I/O error occurs, in
214 * which case an <code>IOException</code> other
215 * than <code>EOFException</code> is thrown.
216 * </ul>
217 * <p>
218 * If <code>b</code> is <code>null</code>,
219 * a <code>NullPointerException</code> is thrown.
220 * If <code>b.length</code> is zero, then
221 * no bytes are read. Otherwise, the first
222 * byte read is stored into element <code>b[0]</code>,
223 * the next one into <code>b[1]</code>, and
224 * so on.
225 * If an exception is thrown from
226 * this method, then it may be that some but
227 * not all bytes of <code>b</code> have been
228 * updated with data from the input stream.
229 *
230 * @param b the buffer into which the data is read.
231 * @exception EOFException if this stream reaches the end before reading
232 * all the bytes.
233 * @exception IOException if an I/O error occurs.
234 */
235 void readFully(byte b[]) throws IOException;
236
237 /**
238 *
239 * Reads <code>len</code>
240 * bytes from
241 * an input stream.
242 * <p>
243 * This method
244 * blocks until one of the following conditions
245 * occurs:<p>
246 * <ul>
247 * <li><code>len</code> bytes
248 * of input data are available, in which case
249 * a normal return is made.
250 *
251 * <li>End of file
252 * is detected, in which case an <code>EOFException</code>
253 * is thrown.
254 *
255 * <li>An I/O error occurs, in
256 * which case an <code>IOException</code> other
257 * than <code>EOFException</code> is thrown.
258 * </ul>
259 * <p>
260 * If <code>b</code> is <code>null</code>,
261 * a <code>NullPointerException</code> is thrown.
262 * If <code>off</code> is negative, or <code>len</code>
263 * is negative, or <code>off+len</code> is
264 * greater than the length of the array <code>b</code>,
265 * then an <code>IndexOutOfBoundsException</code>
266 * is thrown.
267 * If <code>len</code> is zero,
268 * then no bytes are read. Otherwise, the first
269 * byte read is stored into element <code>b[off]</code>,
270 * the next one into <code>b[off+1]</code>,
271 * and so on. The number of bytes read is,
272 * at most, equal to <code>len</code>.
273 *
274 * @param b the buffer into which the data is read.
275 * @param off an int specifying the offset into the data.
276 * @param len an int specifying the number of bytes to read.
277 * @exception EOFException if this stream reaches the end before reading
278 * all the bytes.
279 * @exception IOException if an I/O error occurs.
280 */
281 void readFully(byte b[], int off, int len) throws IOException;
282
283 /**
284 * Makes an attempt to skip over
285 * <code>n</code> bytes
286 * of data from the input
287 * stream, discarding the skipped bytes. However,
288 * it may skip
289 * over some smaller number of
290 * bytes, possibly zero. This may result from
291 * any of a
292 * number of conditions; reaching
293 * end of file before <code>n</code> bytes
294 * have been skipped is
295 * only one possibility.
296 * This method never throws an <code>EOFException</code>.
297 * The actual
298 * number of bytes skipped is returned.
299 *
300 * @param n the number of bytes to be skipped.
301 * @return the number of bytes actually skipped.
302 * @exception IOException if an I/O error occurs.
303 */
304 int skipBytes(int n) throws IOException;
305
306 /**
307 * Reads one input byte and returns
308 * <code>true</code> if that byte is nonzero,
309 * <code>false</code> if that byte is zero.
310 * This method is suitable for reading
311 * the byte written by the <code>writeBoolean</code>
312 * method of interface <code>DataOutput</code>.
313 *
314 * @return the <code>boolean</code> value read.
315 * @exception EOFException if this stream reaches the end before reading
316 * all the bytes.
317 * @exception IOException if an I/O error occurs.
318 */
319 boolean readBoolean() throws IOException;
320
321 /**
322 * Reads and returns one input byte.
323 * The byte is treated as a signed value in
324 * the range <code>-128</code> through <code>127</code>,
325 * inclusive.
326 * This method is suitable for
327 * reading the byte written by the <code>writeByte</code>
328 * method of interface <code>DataOutput</code>.
329 *
330 * @return the 8-bit value read.
331 * @exception EOFException if this stream reaches the end before reading
332 * all the bytes.
333 * @exception IOException if an I/O error occurs.
334 */
335 byte readByte() throws IOException;
336
337 /**
338 * Reads one input byte, zero-extends
339 * it to type <code>int</code>, and returns
340 * the result, which is therefore in the range
341 * <code>0</code>
342 * through <code>255</code>.
343 * This method is suitable for reading
344 * the byte written by the <code>writeByte</code>
345 * method of interface <code>DataOutput</code>
346 * if the argument to <code>writeByte</code>
347 * was intended to be a value in the range
348 * <code>0</code> through <code>255</code>.
349 *
350 * @return the unsigned 8-bit value read.
351 * @exception EOFException if this stream reaches the end before reading
352 * all the bytes.
353 * @exception IOException if an I/O error occurs.
354 */
355 int readUnsignedByte() throws IOException;
356
357 /**
358 * Reads two input bytes and returns
359 * a <code>short</code> value. Let <code>a</code>
360 * be the first byte read and <code>b</code>
361 * be the second byte. The value
362 * returned
363 * is:
364 * <p><pre><code>(short)((a &lt;&lt; 8) | (b &amp; 0xff))
365 * </code></pre>
366 * This method
367 * is suitable for reading the bytes written
368 * by the <code>writeShort</code> method of
369 * interface <code>DataOutput</code>.
370 *
371 * @return the 16-bit value read.
372 * @exception EOFException if this stream reaches the end before reading
373 * all the bytes.
374 * @exception IOException if an I/O error occurs.
375 */
376 short readShort() throws IOException;
377
378 /**
379 * Reads two input bytes and returns
380 * an <code>int</code> value in the range <code>0</code>
381 * through <code>65535</code>. Let <code>a</code>
382 * be the first byte read and
383 * <code>b</code>
384 * be the second byte. The value returned is:
385 * <p><pre><code>(((a &amp; 0xff) &lt;&lt; 8) | (b &amp; 0xff))
386 * </code></pre>
387 * This method is suitable for reading the bytes
388 * written by the <code>writeShort</code> method
389 * of interface <code>DataOutput</code> if
390 * the argument to <code>writeShort</code>
391 * was intended to be a value in the range
392 * <code>0</code> through <code>65535</code>.
393 *
394 * @return the unsigned 16-bit value read.
395 * @exception EOFException if this stream reaches the end before reading
396 * all the bytes.
397 * @exception IOException if an I/O error occurs.
398 */
399 int readUnsignedShort() throws IOException;
400
401 /**
402 * Reads two input bytes and returns a <code>char</code> value.
403 * Let <code>a</code>
404 * be the first byte read and <code>b</code>
405 * be the second byte. The value
406 * returned is:
407 * <p><pre><code>(char)((a &lt;&lt; 8) | (b &amp; 0xff))
408 * </code></pre>
409 * This method
410 * is suitable for reading bytes written by
411 * the <code>writeChar</code> method of interface
412 * <code>DataOutput</code>.
413 *
414 * @return the <code>char</code> value read.
415 * @exception EOFException if this stream reaches the end before reading
416 * all the bytes.
417 * @exception IOException if an I/O error occurs.
418 */
419 char readChar() throws IOException;
420
421 /**
422 * Reads four input bytes and returns an
423 * <code>int</code> value. Let <code>a-d</code>
424 * be the first through fourth bytes read. The value returned is:
425 * <p><pre>
426 * <code>
427 * (((a &amp; 0xff) &lt;&lt; 24) | ((b &amp; 0xff) &lt;&lt; 16) |
428 * &#32;((c &amp; 0xff) &lt;&lt; 8) | (d &amp; 0xff))
429 * </code></pre>
430 * This method is suitable
431 * for reading bytes written by the <code>writeInt</code>
432 * method of interface <code>DataOutput</code>.
433 *
434 * @return the <code>int</code> value read.
435 * @exception EOFException if this stream reaches the end before reading
436 * all the bytes.
437 * @exception IOException if an I/O error occurs.
438 */
439 int readInt() throws IOException;
440
441 /**
442 * Reads eight input bytes and returns
443 * a <code>long</code> value. Let <code>a-h</code>
444 * be the first through eighth bytes read.
445 * The value returned is:
446 * <p><pre> <code>
447 * (((long)(a &amp; 0xff) &lt;&lt; 56) |
448 * ((long)(b &amp; 0xff) &lt;&lt; 48) |
449 * ((long)(c &amp; 0xff) &lt;&lt; 40) |
450 * ((long)(d &amp; 0xff) &lt;&lt; 32) |
451 * ((long)(e &amp; 0xff) &lt;&lt; 24) |
452 * ((long)(f &amp; 0xff) &lt;&lt; 16) |
453 * ((long)(g &amp; 0xff) &lt;&lt; 8) |
454 * ((long)(h &amp; 0xff)))
455 * </code></pre>
456 * <p>
457 * This method is suitable
458 * for reading bytes written by the <code>writeLong</code>
459 * method of interface <code>DataOutput</code>.
460 *
461 * @return the <code>long</code> value read.
462 * @exception EOFException if this stream reaches the end before reading
463 * all the bytes.
464 * @exception IOException if an I/O error occurs.
465 */
466 long readLong() throws IOException;
467
468 /**
469 * Reads four input bytes and returns
470 * a <code>float</code> value. It does this
471 * by first constructing an <code>int</code>
472 * value in exactly the manner
473 * of the <code>readInt</code>
474 * method, then converting this <code>int</code>
475 * value to a <code>float</code> in
476 * exactly the manner of the method <code>Float.intBitsToFloat</code>.
477 * This method is suitable for reading
478 * bytes written by the <code>writeFloat</code>
479 * method of interface <code>DataOutput</code>.
480 *
481 * @return the <code>float</code> value read.
482 * @exception EOFException if this stream reaches the end before reading
483 * all the bytes.
484 * @exception IOException if an I/O error occurs.
485 */
486 float readFloat() throws IOException;
487
488 /**
489 * Reads eight input bytes and returns
490 * a <code>double</code> value. It does this
491 * by first constructing a <code>long</code>
492 * value in exactly the manner
493 * of the <code>readlong</code>
494 * method, then converting this <code>long</code>
495 * value to a <code>double</code> in exactly
496 * the manner of the method <code>Double.longBitsToDouble</code>.
497 * This method is suitable for reading
498 * bytes written by the <code>writeDouble</code>
499 * method of interface <code>DataOutput</code>.
500 *
501 * @return the <code>double</code> value read.
502 * @exception EOFException if this stream reaches the end before reading
503 * all the bytes.
504 * @exception IOException if an I/O error occurs.
505 */
506 double readDouble() throws IOException;
507
508 /**
509 * Reads the next line of text from the input stream.
510 * It reads successive bytes, converting
511 * each byte separately into a character,
512 * until it encounters a line terminator or
513 * end of
514 * file; the characters read are then
515 * returned as a <code>String</code>. Note
516 * that because this
517 * method processes bytes,
518 * it does not support input of the full Unicode
519 * character set.
520 * <p>
521 * If end of file is encountered
522 * before even one byte can be read, then <code>null</code>
523 * is returned. Otherwise, each byte that is
524 * read is converted to type <code>char</code>
525 * by zero-extension. If the character <code>'\n'</code>
526 * is encountered, it is discarded and reading
527 * ceases. If the character <code>'\r'</code>
528 * is encountered, it is discarded and, if
529 * the following byte converts &#32;to the
530 * character <code>'\n'</code>, then that is
531 * discarded also; reading then ceases. If
532 * end of file is encountered before either
533 * of the characters <code>'\n'</code> and
534 * <code>'\r'</code> is encountered, reading
535 * ceases. Once reading has ceased, a <code>String</code>
536 * is returned that contains all the characters
537 * read and not discarded, taken in order.
538 * Note that every character in this string
539 * will have a value less than <code>&#92;u0100</code>,
540 * that is, <code>(char)256</code>.
541 *
542 * @return the next line of text from the input stream,
543 * or <CODE>null</CODE> if the end of file is
544 * encountered before a byte can be read.
545 * @exception IOException if an I/O error occurs.
546 */
547 String readLine() throws IOException;
548
549 /**
550 * Reads in a string that has been encoded using a
551 * <a href="#modified-utf-8">modified UTF-8</a>
552 * format.
553 * The general contract of <code>readUTF</code>
554 * is that it reads a representation of a Unicode
555 * character string encoded in modified
556 * UTF-8 format; this string of characters
557 * is then returned as a <code>String</code>.
558 * <p>
559 * First, two bytes are read and used to
560 * construct an unsigned 16-bit integer in
561 * exactly the manner of the <code>readUnsignedShort</code>
562 * method . This integer value is called the
563 * <i>UTF length</i> and specifies the number
564 * of additional bytes to be read. These bytes
565 * are then converted to characters by considering
566 * them in groups. The length of each group
567 * is computed from the value of the first
568 * byte of the group. The byte following a
569 * group, if any, is the first byte of the
570 * next group.
571 * <p>
572 * If the first byte of a group
573 * matches the bit pattern <code>0xxxxxxx</code>
574 * (where <code>x</code> means "may be <code>0</code>
575 * or <code>1</code>"), then the group consists
576 * of just that byte. The byte is zero-extended
577 * to form a character.
578 * <p>
579 * If the first byte
580 * of a group matches the bit pattern <code>110xxxxx</code>,
581 * then the group consists of that byte <code>a</code>
582 * and a second byte <code>b</code>. If there
583 * is no byte <code>b</code> (because byte
584 * <code>a</code> was the last of the bytes
585 * to be read), or if byte <code>b</code> does
586 * not match the bit pattern <code>10xxxxxx</code>,
587 * then a <code>UTFDataFormatException</code>
588 * is thrown. Otherwise, the group is converted
589 * to the character:<p>
590 * <pre><code>(char)(((a&amp; 0x1F) &lt;&lt; 6) | (b &amp; 0x3F))
591 * </code></pre>
592 * If the first byte of a group
593 * matches the bit pattern <code>1110xxxx</code>,
594 * then the group consists of that byte <code>a</code>
595 * and two more bytes <code>b</code> and <code>c</code>.
596 * If there is no byte <code>c</code> (because
597 * byte <code>a</code> was one of the last
598 * two of the bytes to be read), or either
599 * byte <code>b</code> or byte <code>c</code>
600 * does not match the bit pattern <code>10xxxxxx</code>,
601 * then a <code>UTFDataFormatException</code>
602 * is thrown. Otherwise, the group is converted
603 * to the character:<p>
604 * <pre><code>
605 * (char)(((a &amp; 0x0F) &lt;&lt; 12) | ((b &amp; 0x3F) &lt;&lt; 6) | (c &amp; 0x3F))
606 * </code></pre>
607 * If the first byte of a group matches the
608 * pattern <code>1111xxxx</code> or the pattern
609 * <code>10xxxxxx</code>, then a <code>UTFDataFormatException</code>
610 * is thrown.
611 * <p>
612 * If end of file is encountered
613 * at any time during this entire process,
614 * then an <code>EOFException</code> is thrown.
615 * <p>
616 * After every group has been converted to
617 * a character by this process, the characters
618 * are gathered, in the same order in which
619 * their corresponding groups were read from
620 * the input stream, to form a <code>String</code>,
621 * which is returned.
622 * <p>
623 * The <code>writeUTF</code>
624 * method of interface <code>DataOutput</code>
625 * may be used to write data that is suitable
626 * for reading by this method.
627 * @return a Unicode string.
628 * @exception EOFException if this stream reaches the end
629 * before reading all the bytes.
630 * @exception IOException if an I/O error occurs.
631 * @exception UTFDataFormatException if the bytes do not represent a
632 * valid modified UTF-8 encoding of a string.
633 */
634 String readUTF() throws IOException;
635}
java/pkg/java/io/DataInputStream.class+0−0

Binary file not shown.

java/pkg/java/io/DataInputStream.java+663−0
@@ -0,0 +1,663 @@
1/*
2 * Copyright (c) 1994, 2006, 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
26package java.io;
27
28/**
29 * A data input stream lets an application read primitive Java data
30 * types from an underlying input stream in a machine-independent
31 * way. An application uses a data output stream to write data that
32 * can later be read by a data input stream.
33 * <p>
34 * DataInputStream is not necessarily safe for multithreaded access.
35 * Thread safety is optional and is the responsibility of users of
36 * methods in this class.
37 *
38 * @author Arthur van Hoff
39 * @see java.io.DataOutputStream
40 * @since JDK1.0
41 */
42public
43class DataInputStream extends FilterInputStream implements DataInput {
44
45 /**
46 * Creates a DataInputStream that uses the specified
47 * underlying InputStream.
48 *
49 * @param in the specified input stream
50 */
51 public DataInputStream(InputStream in) {
52 super(in);
53 }
54
55 /**
56 * working arrays initialized on demand by readUTF
57 */
58 private byte bytearr[] = new byte[80];
59 private char chararr[] = new char[80];
60
61 /**
62 * Reads some number of bytes from the contained input stream and
63 * stores them into the buffer array <code>b</code>. The number of
64 * bytes actually read is returned as an integer. This method blocks
65 * until input data is available, end of file is detected, or an
66 * exception is thrown.
67 *
68 * <p>If <code>b</code> is null, a <code>NullPointerException</code> is
69 * thrown. If the length of <code>b</code> is zero, then no bytes are
70 * read and <code>0</code> is returned; otherwise, there is an attempt
71 * to read at least one byte. If no byte is available because the
72 * stream is at end of file, the value <code>-1</code> is returned;
73 * otherwise, at least one byte is read and stored into <code>b</code>.
74 *
75 * <p>The first byte read is stored into element <code>b[0]</code>, the
76 * next one into <code>b[1]</code>, and so on. The number of bytes read
77 * is, at most, equal to the length of <code>b</code>. Let <code>k</code>
78 * be the number of bytes actually read; these bytes will be stored in
79 * elements <code>b[0]</code> through <code>b[k-1]</code>, leaving
80 * elements <code>b[k]</code> through <code>b[b.length-1]</code>
81 * unaffected.
82 *
83 * <p>The <code>read(b)</code> method has the same effect as:
84 * <blockquote><pre>
85 * read(b, 0, b.length)
86 * </pre></blockquote>
87 *
88 * @param b the buffer into which the data is read.
89 * @return the total number of bytes read into the buffer, or
90 * <code>-1</code> if there is no more data because the end
91 * of the stream has been reached.
92 * @exception IOException if the first byte cannot be read for any reason
93 * other than end of file, the stream has been closed and the underlying
94 * input stream does not support reading after close, or another I/O
95 * error occurs.
96 * @see java.io.FilterInputStream#in
97 * @see java.io.InputStream#read(byte[], int, int)
98 */
99 public final int read(byte b[]) throws IOException {
100 return in.read(b, 0, b.length);
101 }
102
103 /**
104 * Reads up to <code>len</code> bytes of data from the contained
105 * input stream into an array of bytes. An attempt is made to read
106 * as many as <code>len</code> bytes, but a smaller number may be read,
107 * possibly zero. The number of bytes actually read is returned as an
108 * integer.
109 *
110 * <p> This method blocks until input data is available, end of file is
111 * detected, or an exception is thrown.
112 *
113 * <p> If <code>len</code> is zero, then no bytes are read and
114 * <code>0</code> is returned; otherwise, there is an attempt to read at
115 * least one byte. If no byte is available because the stream is at end of
116 * file, the value <code>-1</code> is returned; otherwise, at least one
117 * byte is read and stored into <code>b</code>.
118 *
119 * <p> The first byte read is stored into element <code>b[off]</code>, the
120 * next one into <code>b[off+1]</code>, and so on. The number of bytes read
121 * is, at most, equal to <code>len</code>. Let <i>k</i> be the number of
122 * bytes actually read; these bytes will be stored in elements
123 * <code>b[off]</code> through <code>b[off+</code><i>k</i><code>-1]</code>,
124 * leaving elements <code>b[off+</code><i>k</i><code>]</code> through
125 * <code>b[off+len-1]</code> unaffected.
126 *
127 * <p> In every case, elements <code>b[0]</code> through
128 * <code>b[off]</code> and elements <code>b[off+len]</code> through
129 * <code>b[b.length-1]</code> are unaffected.
130 *
131 * @param b the buffer into which the data is read.
132 * @param off the start offset in the destination array <code>b</code>
133 * @param len the maximum number of bytes read.
134 * @return the total number of bytes read into the buffer, or
135 * <code>-1</code> if there is no more data because the end
136 * of the stream has been reached.
137 * @exception NullPointerException If <code>b</code> is <code>null</code>.
138 * @exception IndexOutOfBoundsException If <code>off</code> is negative,
139 * <code>len</code> is negative, or <code>len</code> is greater than
140 * <code>b.length - off</code>
141 * @exception IOException if the first byte cannot be read for any reason
142 * other than end of file, the stream has been closed and the underlying
143 * input stream does not support reading after close, or another I/O
144 * error occurs.
145 * @see java.io.FilterInputStream#in
146 * @see java.io.InputStream#read(byte[], int, int)
147 */
148 public final int read(byte b[], int off, int len) throws IOException {
149 return in.read(b, off, len);
150 }
151
152 /**
153 * See the general contract of the <code>readFully</code>
154 * method of <code>DataInput</code>.
155 * <p>
156 * Bytes
157 * for this operation are read from the contained
158 * input stream.
159 *
160 * @param b the buffer into which the data is read.
161 * @exception EOFException if this input stream reaches the end before
162 * reading all the bytes.
163 * @exception IOException the stream has been closed and the contained
164 * input stream does not support reading after close, or
165 * another I/O error occurs.
166 * @see java.io.FilterInputStream#in
167 */
168 public final void readFully(byte b[]) throws IOException {
169 readFully(b, 0, b.length);
170 }
171
172 /**
173 * See the general contract of the <code>readFully</code>
174 * method of <code>DataInput</code>.
175 * <p>
176 * Bytes
177 * for this operation are read from the contained
178 * input stream.
179 *
180 * @param b the buffer into which the data is read.
181 * @param off the start offset of the data.
182 * @param len the number of bytes to read.
183 * @exception EOFException if this input stream reaches the end before
184 * reading all the bytes.
185 * @exception IOException the stream has been closed and the contained
186 * input stream does not support reading after close, or
187 * another I/O error occurs.
188 * @see java.io.FilterInputStream#in
189 */
190 public final void readFully(byte b[], int off, int len) throws IOException {
191 if (len < 0)
192 throw new IndexOutOfBoundsException();
193 int n = 0;
194 while (n < len) {
195 int count = in.read(b, off + n, len - n);
196 if (count < 0)
197 throw new EOFException();
198 n += count;
199 }
200 }
201
202 /**
203 * See the general contract of the <code>skipBytes</code>
204 * method of <code>DataInput</code>.
205 * <p>
206 * Bytes for this operation are read from the contained
207 * input stream.
208 *
209 * @param n the number of bytes to be skipped.
210 * @return the actual number of bytes skipped.
211 * @exception IOException if the contained input stream does not support
212 * seek, or the stream has been closed and
213 * the contained input stream does not support
214 * reading after close, or another I/O error occurs.
215 */
216 public final int skipBytes(int n) throws IOException {
217 int total = 0;
218 int cur = 0;
219
220 while ((total<n) && ((cur = (int) in.skip(n-total)) > 0)) {
221 total += cur;
222 }
223
224 return total;
225 }
226
227 /**
228 * See the general contract of the <code>readBoolean</code>
229 * method of <code>DataInput</code>.
230 * <p>
231 * Bytes for this operation are read from the contained
232 * input stream.
233 *
234 * @return the <code>boolean</code> value read.
235 * @exception EOFException if this input stream has reached the end.
236 * @exception IOException the stream has been closed and the contained
237 * input stream does not support reading after close, or
238 * another I/O error occurs.
239 * @see java.io.FilterInputStream#in
240 */
241 public final boolean readBoolean() throws IOException {
242 int ch = in.read();
243 if (ch < 0)
244 throw new EOFException();
245 return (ch != 0);
246 }
247
248 /**
249 * See the general contract of the <code>readByte</code>
250 * method of <code>DataInput</code>.
251 * <p>
252 * Bytes
253 * for this operation are read from the contained
254 * input stream.
255 *
256 * @return the next byte of this input stream as a signed 8-bit
257 * <code>byte</code>.
258 * @exception EOFException if this input stream has reached the end.
259 * @exception IOException the stream has been closed and the contained
260 * input stream does not support reading after close, or
261 * another I/O error occurs.
262 * @see java.io.FilterInputStream#in
263 */
264 public final byte readByte() throws IOException {
265 int ch = in.read();
266 if (ch < 0)
267 throw new EOFException();
268 return (byte)(ch);
269 }
270
271 /**
272 * See the general contract of the <code>readUnsignedByte</code>
273 * method of <code>DataInput</code>.
274 * <p>
275 * Bytes
276 * for this operation are read from the contained
277 * input stream.
278 *
279 * @return the next byte of this input stream, interpreted as an
280 * unsigned 8-bit number.
281 * @exception EOFException if this input stream has reached the end.
282 * @exception IOException the stream has been closed and the contained
283 * input stream does not support reading after close, or
284 * another I/O error occurs.
285 * @see java.io.FilterInputStream#in
286 */
287 public final int readUnsignedByte() throws IOException {
288 int ch = in.read();
289 if (ch < 0)
290 throw new EOFException();
291 return ch;
292 }
293
294 /**
295 * See the general contract of the <code>readShort</code>
296 * method of <code>DataInput</code>.
297 * <p>
298 * Bytes
299 * for this operation are read from the contained
300 * input stream.
301 *
302 * @return the next two bytes of this input stream, interpreted as a
303 * signed 16-bit number.
304 * @exception EOFException if this input stream reaches the end before
305 * reading two bytes.
306 * @exception IOException the stream has been closed and the contained
307 * input stream does not support reading after close, or
308 * another I/O error occurs.
309 * @see java.io.FilterInputStream#in
310 */
311 public final short readShort() throws IOException {
312 int ch1 = in.read();
313 int ch2 = in.read();
314 if ((ch1 | ch2) < 0)
315 throw new EOFException();
316 return (short)((ch1 << 8) + (ch2 << 0));
317 }
318
319 /**
320 * See the general contract of the <code>readUnsignedShort</code>
321 * method of <code>DataInput</code>.
322 * <p>
323 * Bytes
324 * for this operation are read from the contained
325 * input stream.
326 *
327 * @return the next two bytes of this input stream, interpreted as an
328 * unsigned 16-bit integer.
329 * @exception EOFException if this input stream reaches the end before
330 * reading two bytes.
331 * @exception IOException the stream has been closed and the contained
332 * input stream does not support reading after close, or
333 * another I/O error occurs.
334 * @see java.io.FilterInputStream#in
335 */
336 public final int readUnsignedShort() throws IOException {
337 int ch1 = in.read();
338 int ch2 = in.read();
339 if ((ch1 | ch2) < 0)
340 throw new EOFException();
341 return (ch1 << 8) + (ch2 << 0);
342 }
343
344 /**
345 * See the general contract of the <code>readChar</code>
346 * method of <code>DataInput</code>.
347 * <p>
348 * Bytes
349 * for this operation are read from the contained
350 * input stream.
351 *
352 * @return the next two bytes of this input stream, interpreted as a
353 * <code>char</code>.
354 * @exception EOFException if this input stream reaches the end before
355 * reading two bytes.
356 * @exception IOException the stream has been closed and the contained
357 * input stream does not support reading after close, or
358 * another I/O error occurs.
359 * @see java.io.FilterInputStream#in
360 */
361 public final char readChar() throws IOException {
362 int ch1 = in.read();
363 int ch2 = in.read();
364 if ((ch1 | ch2) < 0)
365 throw new EOFException();
366 return (char)((ch1 << 8) + (ch2 << 0));
367 }
368
369 /**
370 * See the general contract of the <code>readInt</code>
371 * method of <code>DataInput</code>.
372 * <p>
373 * Bytes
374 * for this operation are read from the contained
375 * input stream.
376 *
377 * @return the next four bytes of this input stream, interpreted as an
378 * <code>int</code>.
379 * @exception EOFException if this input stream reaches the end before
380 * reading four bytes.
381 * @exception IOException the stream has been closed and the contained
382 * input stream does not support reading after close, or
383 * another I/O error occurs.
384 * @see java.io.FilterInputStream#in
385 */
386 public final int readInt() throws IOException {
387 int ch1 = in.read();
388 int ch2 = in.read();
389 int ch3 = in.read();
390 int ch4 = in.read();
391 if ((ch1 | ch2 | ch3 | ch4) < 0)
392 throw new EOFException();
393 return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
394 }
395
396 private byte readBuffer[] = new byte[8];
397
398 /**
399 * See the general contract of the <code>readLong</code>
400 * method of <code>DataInput</code>.
401 * <p>
402 * Bytes
403 * for this operation are read from the contained
404 * input stream.
405 *
406 * @return the next eight bytes of this input stream, interpreted as a
407 * <code>long</code>.
408 * @exception EOFException if this input stream reaches the end before
409 * reading eight bytes.
410 * @exception IOException the stream has been closed and the contained
411 * input stream does not support reading after close, or
412 * another I/O error occurs.
413 * @see java.io.FilterInputStream#in
414 */
415 public final long readLong() throws IOException {
416 readFully(readBuffer, 0, 8);
417 return (((long)readBuffer[0] << 56) +
418 ((long)(readBuffer[1] & 255) << 48) +
419 ((long)(readBuffer[2] & 255) << 40) +
420 ((long)(readBuffer[3] & 255) << 32) +
421 ((long)(readBuffer[4] & 255) << 24) +
422 ((readBuffer[5] & 255) << 16) +
423 ((readBuffer[6] & 255) << 8) +
424 ((readBuffer[7] & 255) << 0));
425 }
426
427 /**
428 * See the general contract of the <code>readFloat</code>
429 * method of <code>DataInput</code>.
430 * <p>
431 * Bytes
432 * for this operation are read from the contained
433 * input stream.
434 *
435 * @return the next four bytes of this input stream, interpreted as a
436 * <code>float</code>.
437 * @exception EOFException if this input stream reaches the end before
438 * reading four bytes.
439 * @exception IOException the stream has been closed and the contained
440 * input stream does not support reading after close, or
441 * another I/O error occurs.
442 * @see java.io.DataInputStream#readInt()
443 * @see java.lang.Float#intBitsToFloat(int)
444 */
445 public final float readFloat() throws IOException {
446 return Float.intBitsToFloat(readInt());
447 }
448
449 /**
450 * See the general contract of the <code>readDouble</code>
451 * method of <code>DataInput</code>.
452 * <p>
453 * Bytes
454 * for this operation are read from the contained
455 * input stream.
456 *
457 * @return the next eight bytes of this input stream, interpreted as a
458 * <code>double</code>.
459 * @exception EOFException if this input stream reaches the end before
460 * reading eight bytes.
461 * @exception IOException the stream has been closed and the contained
462 * input stream does not support reading after close, or
463 * another I/O error occurs.
464 * @see java.io.DataInputStream#readLong()
465 * @see java.lang.Double#longBitsToDouble(long)
466 */
467 public final double readDouble() throws IOException {
468 return Double.longBitsToDouble(readLong());
469 }
470
471 private char lineBuffer[];
472
473 /**
474 * See the general contract of the <code>readLine</code>
475 * method of <code>DataInput</code>.
476 * <p>
477 * Bytes
478 * for this operation are read from the contained
479 * input stream.
480 *
481 * @deprecated This method does not properly convert bytes to characters.
482 * As of JDK&nbsp;1.1, the preferred way to read lines of text is via the
483 * <code>BufferedReader.readLine()</code> method. Programs that use the
484 * <code>DataInputStream</code> class to read lines can be converted to use
485 * the <code>BufferedReader</code> class by replacing code of the form:
486 * <blockquote><pre>
487 * DataInputStream d =&nbsp;new&nbsp;DataInputStream(in);
488 * </pre></blockquote>
489 * with:
490 * <blockquote><pre>
491 * BufferedReader d
492 * =&nbsp;new&nbsp;BufferedReader(new&nbsp;InputStreamReader(in));
493 * </pre></blockquote>
494 *
495 * @return the next line of text from this input stream.
496 * @exception IOException if an I/O error occurs.
497 * @see java.io.BufferedReader#readLine()
498 * @see java.io.FilterInputStream#in
499 */
500 @Deprecated
501 public final String readLine() throws IOException {
502 char buf[] = lineBuffer;
503
504 if (buf == null) {
505 buf = lineBuffer = new char[128];
506 }
507
508 int room = buf.length;
509 int offset = 0;
510 int c;
511
512loop: while (true) {
513 switch (c = in.read()) {
514 case -1:
515 case '\n':
516 break loop;
517
518 case '\r':
519 int c2 = in.read();
520 if ((c2 != '\n') && (c2 != -1)) {
521 if (!(in instanceof PushbackInputStream)) {
522 this.in = new PushbackInputStream(in);
523 }
524 ((PushbackInputStream)in).unread(c2);
525 }
526 break loop;
527
528 default:
529 if (--room < 0) {
530 buf = new char[offset + 128];
531 room = buf.length - offset - 1;
532 System.arraycopy(lineBuffer, 0, buf, 0, offset);
533 lineBuffer = buf;
534 }
535 buf[offset++] = (char) c;
536 break;
537 }
538 }
539 if ((c == -1) && (offset == 0)) {
540 return null;
541 }
542 return String.copyValueOf(buf, 0, offset);
543 }
544
545 /**
546 * See the general contract of the <code>readUTF</code>
547 * method of <code>DataInput</code>.
548 * <p>
549 * Bytes
550 * for this operation are read from the contained
551 * input stream.
552 *
553 * @return a Unicode string.
554 * @exception EOFException if this input stream reaches the end before
555 * reading all the bytes.
556 * @exception IOException the stream has been closed and the contained
557 * input stream does not support reading after close, or
558 * another I/O error occurs.
559 * @exception UTFDataFormatException if the bytes do not represent a valid
560 * modified UTF-8 encoding of a string.
561 * @see java.io.DataInputStream#readUTF(java.io.DataInput)
562 */
563 public final String readUTF() throws IOException {
564 return readUTF(this);
565 }
566
567 /**
568 * Reads from the
569 * stream <code>in</code> a representation
570 * of a Unicode character string encoded in
571 * <a href="DataInput.html#modified-utf-8">modified UTF-8</a> format;
572 * this string of characters is then returned as a <code>String</code>.
573 * The details of the modified UTF-8 representation
574 * are exactly the same as for the <code>readUTF</code>
575 * method of <code>DataInput</code>.
576 *
577 * @param in a data input stream.
578 * @return a Unicode string.
579 * @exception EOFException if the input stream reaches the end
580 * before all the bytes.
581 * @exception IOException the stream has been closed and the contained
582 * input stream does not support reading after close, or
583 * another I/O error occurs.
584 * @exception UTFDataFormatException if the bytes do not represent a
585 * valid modified UTF-8 encoding of a Unicode string.
586 * @see java.io.DataInputStream#readUnsignedShort()
587 */
588 public final static String readUTF(DataInput in) throws IOException {
589 int utflen = in.readUnsignedShort();
590 byte[] bytearr = null;
591 char[] chararr = null;
592 if (in instanceof DataInputStream) {
593 DataInputStream dis = (DataInputStream)in;
594 if (dis.bytearr.length < utflen){
595 dis.bytearr = new byte[utflen*2];
596 dis.chararr = new char[utflen*2];
597 }
598 chararr = dis.chararr;
599 bytearr = dis.bytearr;
600 } else {
601 bytearr = new byte[utflen];
602 chararr = new char[utflen];
603 }
604
605 int c, char2, char3;
606 int count = 0;
607 int chararr_count=0;
608
609 in.readFully(bytearr, 0, utflen);
610
611 while (count < utflen) {
612 c = (int) bytearr[count] & 0xff;
613 if (c > 127) break;
614 count++;
615 chararr[chararr_count++]=(char)c;
616 }
617
618 while (count < utflen) {
619 c = (int) bytearr[count] & 0xff;
620 switch (c >> 4) {
621 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
622 /* 0xxxxxxx*/
623 count++;
624 chararr[chararr_count++]=(char)c;
625 break;
626 case 12: case 13:
627 /* 110x xxxx 10xx xxxx*/
628 count += 2;
629 if (count > utflen)
630 throw new UTFDataFormatException(
631 "malformed input: partial character at end");
632 char2 = (int) bytearr[count-1];
633 if ((char2 & 0xC0) != 0x80)
634 throw new UTFDataFormatException(
635 "malformed input around byte " + count);
636 chararr[chararr_count++]=(char)(((c & 0x1F) << 6) |
637 (char2 & 0x3F));
638 break;
639 case 14:
640 /* 1110 xxxx 10xx xxxx 10xx xxxx */
641 count += 3;
642 if (count > utflen)
643 throw new UTFDataFormatException(
644 "malformed input: partial character at end");
645 char2 = (int) bytearr[count-2];
646 char3 = (int) bytearr[count-1];
647 if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
648 throw new UTFDataFormatException(
649 "malformed input around byte " + (count-1));
650 chararr[chararr_count++]=(char)(((c & 0x0F) << 12) |
651 ((char2 & 0x3F) << 6) |
652 ((char3 & 0x3F) << 0));
653 break;
654 default:
655 /* 10xx xxxx, 1111 xxxx */
656 throw new UTFDataFormatException(
657 "malformed input around byte " + count);
658 }
659 }
660 // The number of chars produced may be less than utflen
661 return new String(chararr, 0, chararr_count);
662 }
663}
java/pkg/java/io/DataOutput.class+0−0

Binary file not shown.

java/pkg/java/io/DataOutput.java+354−0
@@ -0,0 +1,354 @@
1/*
2 * Copyright (c) 1995, 2006, 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
26package java.io;
27
28/**
29 * The <code>DataOutput</code> interface provides
30 * for converting data from any of the Java
31 * primitive types to a series of bytes and
32 * writing these bytes to a binary stream.
33 * There is also a facility for converting
34 * a <code>String</code> into
35 * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
36 * format and writing the resulting series
37 * of bytes.
38 * <p>
39 * For all the methods in this interface that
40 * write bytes, it is generally true that if
41 * a byte cannot be written for any reason,
42 * an <code>IOException</code> is thrown.
43 *
44 * @author Frank Yellin
45 * @see java.io.DataInput
46 * @see java.io.DataOutputStream
47 * @since JDK1.0
48 */
49public
50interface DataOutput {
51 /**
52 * Writes to the output stream the eight
53 * low-order bits of the argument <code>b</code>.
54 * The 24 high-order bits of <code>b</code>
55 * are ignored.
56 *
57 * @param b the byte to be written.
58 * @throws IOException if an I/O error occurs.
59 */
60 void write(int b) throws IOException;
61
62 /**
63 * Writes to the output stream all the bytes in array <code>b</code>.
64 * If <code>b</code> is <code>null</code>,
65 * a <code>NullPointerException</code> is thrown.
66 * If <code>b.length</code> is zero, then
67 * no bytes are written. Otherwise, the byte
68 * <code>b[0]</code> is written first, then
69 * <code>b[1]</code>, and so on; the last byte
70 * written is <code>b[b.length-1]</code>.
71 *
72 * @param b the data.
73 * @throws IOException if an I/O error occurs.
74 */
75 void write(byte b[]) throws IOException;
76
77 /**
78 * Writes <code>len</code> bytes from array
79 * <code>b</code>, in order, to
80 * the output stream. If <code>b</code>
81 * is <code>null</code>, a <code>NullPointerException</code>
82 * is thrown. If <code>off</code> is negative,
83 * or <code>len</code> is negative, or <code>off+len</code>
84 * is greater than the length of the array
85 * <code>b</code>, then an <code>IndexOutOfBoundsException</code>
86 * is thrown. If <code>len</code> is zero,
87 * then no bytes are written. Otherwise, the
88 * byte <code>b[off]</code> is written first,
89 * then <code>b[off+1]</code>, and so on; the
90 * last byte written is <code>b[off+len-1]</code>.
91 *
92 * @param b the data.
93 * @param off the start offset in the data.
94 * @param len the number of bytes to write.
95 * @throws IOException if an I/O error occurs.
96 */
97 void write(byte b[], int off, int len) throws IOException;
98
99 /**
100 * Writes a <code>boolean</code> value to this output stream.
101 * If the argument <code>v</code>
102 * is <code>true</code>, the value <code>(byte)1</code>
103 * is written; if <code>v</code> is <code>false</code>,
104 * the value <code>(byte)0</code> is written.
105 * The byte written by this method may
106 * be read by the <code>readBoolean</code>
107 * method of interface <code>DataInput</code>,
108 * which will then return a <code>boolean</code>
109 * equal to <code>v</code>.
110 *
111 * @param v the boolean to be written.
112 * @throws IOException if an I/O error occurs.
113 */
114 void writeBoolean(boolean v) throws IOException;
115
116 /**
117 * Writes to the output stream the eight low-
118 * order bits of the argument <code>v</code>.
119 * The 24 high-order bits of <code>v</code>
120 * are ignored. (This means that <code>writeByte</code>
121 * does exactly the same thing as <code>write</code>
122 * for an integer argument.) The byte written
123 * by this method may be read by the <code>readByte</code>
124 * method of interface <code>DataInput</code>,
125 * which will then return a <code>byte</code>
126 * equal to <code>(byte)v</code>.
127 *
128 * @param v the byte value to be written.
129 * @throws IOException if an I/O error occurs.
130 */
131 void writeByte(int v) throws IOException;
132
133 /**
134 * Writes two bytes to the output
135 * stream to represent the value of the argument.
136 * The byte values to be written, in the order
137 * shown, are: <p>
138 * <pre><code>
139 * (byte)(0xff &amp; (v &gt;&gt; 8))
140 * (byte)(0xff &amp; v)
141 * </code> </pre> <p>
142 * The bytes written by this method may be
143 * read by the <code>readShort</code> method
144 * of interface <code>DataInput</code> , which
145 * will then return a <code>short</code> equal
146 * to <code>(short)v</code>.
147 *
148 * @param v the <code>short</code> value to be written.
149 * @throws IOException if an I/O error occurs.
150 */
151 void writeShort(int v) throws IOException;
152
153 /**
154 * Writes a <code>char</code> value, which
155 * is comprised of two bytes, to the
156 * output stream.
157 * The byte values to be written, in the order
158 * shown, are:
159 * <p><pre><code>
160 * (byte)(0xff &amp; (v &gt;&gt; 8))
161 * (byte)(0xff &amp; v)
162 * </code></pre><p>
163 * The bytes written by this method may be
164 * read by the <code>readChar</code> method
165 * of interface <code>DataInput</code> , which
166 * will then return a <code>char</code> equal
167 * to <code>(char)v</code>.
168 *
169 * @param v the <code>char</code> value to be written.
170 * @throws IOException if an I/O error occurs.
171 */
172 void writeChar(int v) throws IOException;
173
174 /**
175 * Writes an <code>int</code> value, which is
176 * comprised of four bytes, to the output stream.
177 * The byte values to be written, in the order
178 * shown, are:
179 * <p><pre><code>
180 * (byte)(0xff &amp; (v &gt;&gt; 24))
181 * (byte)(0xff &amp; (v &gt;&gt; 16))
182 * (byte)(0xff &amp; (v &gt;&gt; &#32; &#32;8))
183 * (byte)(0xff &amp; v)
184 * </code></pre><p>
185 * The bytes written by this method may be read
186 * by the <code>readInt</code> method of interface
187 * <code>DataInput</code> , which will then
188 * return an <code>int</code> equal to <code>v</code>.
189 *
190 * @param v the <code>int</code> value to be written.
191 * @throws IOException if an I/O error occurs.
192 */
193 void writeInt(int v) throws IOException;
194
195 /**
196 * Writes a <code>long</code> value, which is
197 * comprised of eight bytes, to the output stream.
198 * The byte values to be written, in the order
199 * shown, are:
200 * <p><pre><code>
201 * (byte)(0xff &amp; (v &gt;&gt; 56))
202 * (byte)(0xff &amp; (v &gt;&gt; 48))
203 * (byte)(0xff &amp; (v &gt;&gt; 40))
204 * (byte)(0xff &amp; (v &gt;&gt; 32))
205 * (byte)(0xff &amp; (v &gt;&gt; 24))
206 * (byte)(0xff &amp; (v &gt;&gt; 16))
207 * (byte)(0xff &amp; (v &gt;&gt; 8))
208 * (byte)(0xff &amp; v)
209 * </code></pre><p>
210 * The bytes written by this method may be
211 * read by the <code>readLong</code> method
212 * of interface <code>DataInput</code> , which
213 * will then return a <code>long</code> equal
214 * to <code>v</code>.
215 *
216 * @param v the <code>long</code> value to be written.
217 * @throws IOException if an I/O error occurs.
218 */
219 void writeLong(long v) throws IOException;
220
221 /**
222 * Writes a <code>float</code> value,
223 * which is comprised of four bytes, to the output stream.
224 * It does this as if it first converts this
225 * <code>float</code> value to an <code>int</code>
226 * in exactly the manner of the <code>Float.floatToIntBits</code>
227 * method and then writes the <code>int</code>
228 * value in exactly the manner of the <code>writeInt</code>
229 * method. The bytes written by this method
230 * may be read by the <code>readFloat</code>
231 * method of interface <code>DataInput</code>,
232 * which will then return a <code>float</code>
233 * equal to <code>v</code>.
234 *
235 * @param v the <code>float</code> value to be written.
236 * @throws IOException if an I/O error occurs.
237 */
238 void writeFloat(float v) throws IOException;
239
240 /**
241 * Writes a <code>double</code> value,
242 * which is comprised of eight bytes, to the output stream.
243 * It does this as if it first converts this
244 * <code>double</code> value to a <code>long</code>
245 * in exactly the manner of the <code>Double.doubleToLongBits</code>
246 * method and then writes the <code>long</code>
247 * value in exactly the manner of the <code>writeLong</code>
248 * method. The bytes written by this method
249 * may be read by the <code>readDouble</code>
250 * method of interface <code>DataInput</code>,
251 * which will then return a <code>double</code>
252 * equal to <code>v</code>.
253 *
254 * @param v the <code>double</code> value to be written.
255 * @throws IOException if an I/O error occurs.
256 */
257 void writeDouble(double v) throws IOException;
258
259 /**
260 * Writes a string to the output stream.
261 * For every character in the string
262 * <code>s</code>, taken in order, one byte
263 * is written to the output stream. If
264 * <code>s</code> is <code>null</code>, a <code>NullPointerException</code>
265 * is thrown.<p> If <code>s.length</code>
266 * is zero, then no bytes are written. Otherwise,
267 * the character <code>s[0]</code> is written
268 * first, then <code>s[1]</code>, and so on;
269 * the last character written is <code>s[s.length-1]</code>.
270 * For each character, one byte is written,
271 * the low-order byte, in exactly the manner
272 * of the <code>writeByte</code> method . The
273 * high-order eight bits of each character
274 * in the string are ignored.
275 *
276 * @param s the string of bytes to be written.
277 * @throws IOException if an I/O error occurs.
278 */
279 void writeBytes(String s) throws IOException;
280
281 /**
282 * Writes every character in the string <code>s</code>,
283 * to the output stream, in order,
284 * two bytes per character. If <code>s</code>
285 * is <code>null</code>, a <code>NullPointerException</code>
286 * is thrown. If <code>s.length</code>
287 * is zero, then no characters are written.
288 * Otherwise, the character <code>s[0]</code>
289 * is written first, then <code>s[1]</code>,
290 * and so on; the last character written is
291 * <code>s[s.length-1]</code>. For each character,
292 * two bytes are actually written, high-order
293 * byte first, in exactly the manner of the
294 * <code>writeChar</code> method.
295 *
296 * @param s the string value to be written.
297 * @throws IOException if an I/O error occurs.
298 */
299 void writeChars(String s) throws IOException;
300
301 /**
302 * Writes two bytes of length information
303 * to the output stream, followed
304 * by the
305 * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
306 * representation
307 * of every character in the string <code>s</code>.
308 * If <code>s</code> is <code>null</code>,
309 * a <code>NullPointerException</code> is thrown.
310 * Each character in the string <code>s</code>
311 * is converted to a group of one, two, or
312 * three bytes, depending on the value of the
313 * character.<p>
314 * If a character <code>c</code>
315 * is in the range <code>&#92;u0001</code> through
316 * <code>&#92;u007f</code>, it is represented
317 * by one byte:<p>
318 * <pre>(byte)c </pre> <p>
319 * If a character <code>c</code> is <code>&#92;u0000</code>
320 * or is in the range <code>&#92;u0080</code>
321 * through <code>&#92;u07ff</code>, then it is
322 * represented by two bytes, to be written
323 * in the order shown:<p> <pre><code>
324 * (byte)(0xc0 | (0x1f &amp; (c &gt;&gt; 6)))
325 * (byte)(0x80 | (0x3f &amp; c))
326 * </code></pre> <p> If a character
327 * <code>c</code> is in the range <code>&#92;u0800</code>
328 * through <code>uffff</code>, then it is
329 * represented by three bytes, to be written
330 * in the order shown:<p> <pre><code>
331 * (byte)(0xe0 | (0x0f &amp; (c &gt;&gt; 12)))
332 * (byte)(0x80 | (0x3f &amp; (c &gt;&gt; 6)))
333 * (byte)(0x80 | (0x3f &amp; c))
334 * </code></pre> <p> First,
335 * the total number of bytes needed to represent
336 * all the characters of <code>s</code> is
337 * calculated. If this number is larger than
338 * <code>65535</code>, then a <code>UTFDataFormatException</code>
339 * is thrown. Otherwise, this length is written
340 * to the output stream in exactly the manner
341 * of the <code>writeShort</code> method;
342 * after this, the one-, two-, or three-byte
343 * representation of each character in the
344 * string <code>s</code> is written.<p> The
345 * bytes written by this method may be read
346 * by the <code>readUTF</code> method of interface
347 * <code>DataInput</code> , which will then
348 * return a <code>String</code> equal to <code>s</code>.
349 *
350 * @param s the string value to be written.
351 * @throws IOException if an I/O error occurs.
352 */
353 void writeUTF(String s) throws IOException;
354}
java/pkg/java/io/DataOutputStream.class+0−0

Binary file not shown.

java/pkg/java/io/DataOutputStream.java+416−0
@@ -0,0 +1,416 @@
1/*
2 * Copyright (c) 1994, 2004, 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
26package 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 *
33 * @author unascribed
34 * @see java.io.DataInputStream
35 * @since JDK1.0
36 */
37public
38class DataOutputStream extends FilterOutputStream implements DataOutput {
39 /**
40 * The number of bytes written to the data output stream so far.
41 * If this counter overflows, it will be wrapped to Integer.MAX_VALUE.
42 */
43 protected int written;
44
45 /**
46 * bytearr is initialized on demand by writeUTF
47 */
48 private byte[] bytearr = null;
49
50 /**
51 * Creates a new data output stream to write data to the specified
52 * underlying output stream. The counter <code>written</code> is
53 * set to zero.
54 *
55 * @param out the underlying output stream, to be saved for later
56 * use.
57 * @see java.io.FilterOutputStream#out
58 */
59 public DataOutputStream(OutputStream out) {
60 super(out);
61 }
62
63 /**
64 * Increases the written counter by the specified value
65 * until it reaches Integer.MAX_VALUE.
66 */
67 private void incCount(int value) {
68 int temp = written + value;
69 if (temp < 0) {
70 temp = Integer.MAX_VALUE;
71 }
72 written = temp;
73 }
74
75 /**
76 * Writes the specified byte (the low eight bits of the argument
77 * <code>b</code>) to the underlying output stream. If no exception
78 * is thrown, the counter <code>written</code> is incremented by
79 * <code>1</code>.
80 * <p>
81 * Implements the <code>write</code> method of <code>OutputStream</code>.
82 *
83 * @param b the <code>byte</code> to be written.
84 * @exception IOException if an I/O error occurs.
85 * @see java.io.FilterOutputStream#out
86 */
87 public synchronized void write(int b) throws IOException {
88 out.write(b);
89 incCount(1);
90 }
91
92 /**
93 * Writes <code>len</code> bytes from the specified byte array
94 * starting at offset <code>off</code> to the underlying output stream.
95 * If no exception is thrown, the counter <code>written</code> is
96 * incremented by <code>len</code>.
97 *
98 * @param b the data.
99 * @param off the start offset in the data.
100 * @param len the number of bytes to write.
101 * @exception IOException if an I/O error occurs.
102 * @see java.io.FilterOutputStream#out
103 */
104 public synchronized void write(byte b[], int off, int len)
105 throws IOException
106 {
107 out.write(b, off, len);
108 incCount(len);
109 }
110
111 /**
112 * Flushes this data output stream. This forces any buffered output
113 * bytes to be written out to the stream.
114 * <p>
115 * The <code>flush</code> method of <code>DataOutputStream</code>
116 * calls the <code>flush</code> method of its underlying output stream.
117 *
118 * @exception IOException if an I/O error occurs.
119 * @see java.io.FilterOutputStream#out
120 * @see java.io.OutputStream#flush()
121 */
122 public void flush() throws IOException {
123 out.flush();
124 }
125
126 /**
127 * Writes a <code>boolean</code> to the underlying output stream as
128 * a 1-byte value. The value <code>true</code> is written out as the
129 * value <code>(byte)1</code>; the value <code>false</code> is
130 * written out as the value <code>(byte)0</code>. If no exception is
131 * thrown, the counter <code>written</code> is incremented by
132 * <code>1</code>.
133 *
134 * @param v a <code>boolean</code> value to be written.
135 * @exception IOException if an I/O error occurs.
136 * @see java.io.FilterOutputStream#out
137 */
138 public final void writeBoolean(boolean v) throws IOException {
139 out.write(v ? 1 : 0);
140 incCount(1);
141 }
142
143 /**
144 * Writes out a <code>byte</code> to the underlying output stream as
145 * a 1-byte value. If no exception is thrown, the counter
146 * <code>written</code> is incremented by <code>1</code>.
147 *
148 * @param v a <code>byte</code> value to be written.
149 * @exception IOException if an I/O error occurs.
150 * @see java.io.FilterOutputStream#out
151 */
152 public final void writeByte(int v) throws IOException {
153 out.write(v);
154 incCount(1);
155 }
156
157 /**
158 * Writes a <code>short</code> to the underlying output stream as two
159 * bytes, high byte first. If no exception is thrown, the counter
160 * <code>written</code> is incremented by <code>2</code>.
161 *
162 * @param v a <code>short</code> to be written.
163 * @exception IOException if an I/O error occurs.
164 * @see java.io.FilterOutputStream#out
165 */
166 public final void writeShort(int v) throws IOException {
167 out.write((v >>> 8) & 0xFF);
168 out.write((v >>> 0) & 0xFF);
169 incCount(2);
170 }
171
172 /**
173 * Writes a <code>char</code> to the underlying output stream as a
174 * 2-byte value, high byte first. If no exception is thrown, the
175 * counter <code>written</code> is incremented by <code>2</code>.
176 *
177 * @param v a <code>char</code> value to be written.
178 * @exception IOException if an I/O error occurs.
179 * @see java.io.FilterOutputStream#out
180 */
181 public final void writeChar(int v) throws IOException {
182 out.write((v >>> 8) & 0xFF);
183 out.write((v >>> 0) & 0xFF);
184 incCount(2);
185 }
186
187 /**
188 * Writes an <code>int</code> to the underlying output stream as four
189 * bytes, high byte first. If no exception is thrown, the counter
190 * <code>written</code> is incremented by <code>4</code>.
191 *
192 * @param v an <code>int</code> to be written.
193 * @exception IOException if an I/O error occurs.
194 * @see java.io.FilterOutputStream#out
195 */
196 public final void writeInt(int v) throws IOException {
197 out.write((v >>> 24) & 0xFF);
198 out.write((v >>> 16) & 0xFF);
199 out.write((v >>> 8) & 0xFF);
200 out.write((v >>> 0) & 0xFF);
201 incCount(4);
202 }
203
204 private byte writeBuffer[] = new byte[8];
205
206 /**
207 * Writes a <code>long</code> to the underlying output stream as eight
208 * bytes, high byte first. In no exception is thrown, the counter
209 * <code>written</code> is incremented by <code>8</code>.
210 *
211 * @param v a <code>long</code> to be written.
212 * @exception IOException if an I/O error occurs.
213 * @see java.io.FilterOutputStream#out
214 */
215 public final void writeLong(long v) throws IOException {
216 writeBuffer[0] = (byte)(v >>> 56);
217 writeBuffer[1] = (byte)(v >>> 48);
218 writeBuffer[2] = (byte)(v >>> 40);
219 writeBuffer[3] = (byte)(v >>> 32);
220 writeBuffer[4] = (byte)(v >>> 24);
221 writeBuffer[5] = (byte)(v >>> 16);
222 writeBuffer[6] = (byte)(v >>> 8);
223 writeBuffer[7] = (byte)(v >>> 0);
224 out.write(writeBuffer, 0, 8);
225 incCount(8);
226 }
227
228 /**
229 * Converts the float argument to an <code>int</code> using the
230 * <code>floatToIntBits</code> method in class <code>Float</code>,
231 * and then writes that <code>int</code> value to the underlying
232 * output stream as a 4-byte quantity, high byte first. If no
233 * exception is thrown, the counter <code>written</code> is
234 * incremented by <code>4</code>.
235 *
236 * @param v a <code>float</code> value to be written.
237 * @exception IOException if an I/O error occurs.
238 * @see java.io.FilterOutputStream#out
239 * @see java.lang.Float#floatToIntBits(float)
240 */
241 public final void writeFloat(float v) throws IOException {
242 writeInt(Float.floatToIntBits(v));
243 }
244
245 /**
246 * Converts the double argument to a <code>long</code> using the
247 * <code>doubleToLongBits</code> method in class <code>Double</code>,
248 * and then writes that <code>long</code> value to the underlying
249 * output stream as an 8-byte quantity, high byte first. If no
250 * exception is thrown, the counter <code>written</code> is
251 * incremented by <code>8</code>.
252 *
253 * @param v a <code>double</code> value to be written.
254 * @exception IOException if an I/O error occurs.
255 * @see java.io.FilterOutputStream#out
256 * @see java.lang.Double#doubleToLongBits(double)
257 */
258 public final void writeDouble(double v) throws IOException {
259 writeLong(Double.doubleToLongBits(v));
260 }
261
262 /**
263 * Writes out the string to the underlying output stream as a
264 * sequence of bytes. Each character in the string is written out, in
265 * sequence, by discarding its high eight bits. If no exception is
266 * thrown, the counter <code>written</code> is incremented by the
267 * length of <code>s</code>.
268 *
269 * @param s a string of bytes to be written.
270 * @exception IOException if an I/O error occurs.
271 * @see java.io.FilterOutputStream#out
272 */
273 public final void writeBytes(String s) throws IOException {
274 int len = s.length();
275 for (int i = 0 ; i < len ; i++) {
276 out.write((byte)s.charAt(i));
277 }
278 incCount(len);
279 }
280
281 /**
282 * Writes a string to the underlying output stream as a sequence of
283 * characters. Each character is written to the data output stream as
284 * if by the <code>writeChar</code> method. If no exception is
285 * thrown, the counter <code>written</code> is incremented by twice
286 * the length of <code>s</code>.
287 *
288 * @param s a <code>String</code> value to be written.
289 * @exception IOException if an I/O error occurs.
290 * @see java.io.DataOutputStream#writeChar(int)
291 * @see java.io.FilterOutputStream#out
292 */
293 public final void writeChars(String s) throws IOException {
294 int len = s.length();
295 for (int i = 0 ; i < len ; i++) {
296 int v = s.charAt(i);
297 out.write((v >>> 8) & 0xFF);
298 out.write((v >>> 0) & 0xFF);
299 }
300 incCount(len * 2);
301 }
302
303 /**
304 * Writes a string to the underlying output stream using
305 * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
306 * encoding in a machine-independent manner.
307 * <p>
308 * First, two bytes are written to the output stream as if by the
309 * <code>writeShort</code> method giving the number of bytes to
310 * follow. This value is the number of bytes actually written out,
311 * not the length of the string. Following the length, each character
312 * of the string is output, in sequence, using the modified UTF-8 encoding
313 * for the character. If no exception is thrown, the counter
314 * <code>written</code> is incremented by the total number of
315 * bytes written to the output stream. This will be at least two
316 * plus the length of <code>str</code>, and at most two plus
317 * thrice the length of <code>str</code>.
318 *
319 * @param str a string to be written.
320 * @exception IOException if an I/O error occurs.
321 */
322 public final void writeUTF(String str) throws IOException {
323 writeUTF(str, this);
324 }
325
326 /**
327 * Writes a string to the specified DataOutput using
328 * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
329 * encoding in a machine-independent manner.
330 * <p>
331 * First, two bytes are written to out as if by the <code>writeShort</code>
332 * method giving the number of bytes to follow. This value is the number of
333 * bytes actually written out, not the length of the string. Following the
334 * length, each character of the string is output, in sequence, using the
335 * modified UTF-8 encoding for the character. If no exception is thrown, the
336 * counter <code>written</code> is incremented by the total number of
337 * bytes written to the output stream. This will be at least two
338 * plus the length of <code>str</code>, and at most two plus
339 * thrice the length of <code>str</code>.
340 *
341 * @param str a string to be written.
342 * @param out destination to write to
343 * @return The number of bytes written out.
344 * @exception IOException if an I/O error occurs.
345 */
346 static int writeUTF(String str, DataOutput out) throws IOException {
347 int strlen = str.length();
348 int utflen = 0;
349 int c, count = 0;
350
351 /* use charAt instead of copying String to char array */
352 for (int i = 0; i < strlen; i++) {
353 c = str.charAt(i);
354 if ((c >= 0x0001) && (c <= 0x007F)) {
355 utflen++;
356 } else if (c > 0x07FF) {
357 utflen += 3;
358 } else {
359 utflen += 2;
360 }
361 }
362
363 if (utflen > 65535)
364 throw new UTFDataFormatException(
365 "encoded string too long: " + utflen + " bytes");
366
367 byte[] bytearr = null;
368 if (out instanceof DataOutputStream) {
369 DataOutputStream dos = (DataOutputStream)out;
370 if(dos.bytearr == null || (dos.bytearr.length < (utflen+2)))
371 dos.bytearr = new byte[(utflen*2) + 2];
372 bytearr = dos.bytearr;
373 } else {
374 bytearr = new byte[utflen+2];
375 }
376
377 bytearr[count++] = (byte) ((utflen >>> 8) & 0xFF);
378 bytearr[count++] = (byte) ((utflen >>> 0) & 0xFF);
379
380 int i=0;
381 for (i=0; i<strlen; i++) {
382 c = str.charAt(i);
383 if (!((c >= 0x0001) && (c <= 0x007F))) break;
384 bytearr[count++] = (byte) c;
385 }
386
387 for (;i < strlen; i++){
388 c = str.charAt(i);
389 if ((c >= 0x0001) && (c <= 0x007F)) {
390 bytearr[count++] = (byte) c;
391
392 } else if (c > 0x07FF) {
393 bytearr[count++] = (byte) (0xE0 | ((c >> 12) & 0x0F));
394 bytearr[count++] = (byte) (0x80 | ((c >> 6) & 0x3F));
395 bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
396 } else {
397 bytearr[count++] = (byte) (0xC0 | ((c >> 6) & 0x1F));
398 bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
399 }
400 }
401 out.write(bytearr, 0, utflen+2);
402 return utflen + 2;
403 }
404
405 /**
406 * Returns the current value of the counter <code>written</code>,
407 * the number of bytes written to this data output stream so far.
408 * If the counter overflows, it will be wrapped to Integer.MAX_VALUE.
409 *
410 * @return the value of the <code>written</code> field.
411 * @see java.io.DataOutputStream#written
412 */
413 public final int size() {
414 return written;
415 }
416}
java/pkg/java/io/DeleteOnExitHook$1.class+0−0

Binary file not shown.

java/pkg/java/io/DeleteOnExitHook.class+0−0

Binary file not shown.

java/pkg/java/io/DeleteOnExitHook.java+83−0
@@ -0,0 +1,83 @@
1/*
2 * Copyright (c) 2005, 2010, 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 */
25package java.io;
26
27import java.util.*;
28import java.io.File;
29
30/**
31 * This class holds a set of filenames to be deleted on VM exit through a shutdown hook.
32 * A set is used both to prevent double-insertion of the same file as well as offer
33 * quick removal.
34 */
35
36class DeleteOnExitHook {
37 private static LinkedHashSet<String> files = new LinkedHashSet<>();
38 static {
39 // DeleteOnExitHook must be the last shutdown hook to be invoked.
40 // Application shutdown hooks may add the first file to the
41 // delete on exit list and cause the DeleteOnExitHook to be
42 // registered during shutdown in progress. So set the
43 // registerShutdownInProgress parameter to true.
44 sun.misc.SharedSecrets.getJavaLangAccess()
45 .registerShutdownHook(2 /* Shutdown hook invocation order */,
46 true /* register even if shutdown in progress */,
47 new Runnable() {
48 public void run() {
49 runHooks();
50 }
51 }
52 );
53 }
54
55 private DeleteOnExitHook() {}
56
57 static synchronized void add(String file) {
58 if(files == null) {
59 // DeleteOnExitHook is running. Too late to add a file
60 throw new IllegalStateException("Shutdown in progress");
61 }
62
63 files.add(file);
64 }
65
66 static void runHooks() {
67 LinkedHashSet<String> theFiles;
68
69 synchronized (DeleteOnExitHook.class) {
70 theFiles = files;
71 files = null;
72 }
73
74 ArrayList<String> toBeDeleted = new ArrayList<>(theFiles);
75
76 // reverse the list to maintain previous jdk deletion order.
77 // Last in first deleted.
78 Collections.reverse(toBeDeleted);
79 for (String filename : toBeDeleted) {
80 (new File(filename)).delete();
81 }
82 }
83}
java/pkg/java/io/EOFException.class+0−0

Binary file not shown.

java/pkg/java/io/EOFException.java+65−0
@@ -0,0 +1,65 @@
1/*
2 * Copyright (c) 1995, 2008, 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
26package java.io;
27
28/**
29 * Signals that an end of file or end of stream has been reached
30 * unexpectedly during input.
31 * <p>
32 * This exception is mainly used by data input streams to signal end of
33 * stream. Note that many other input operations return a special value on
34 * end of stream rather than throwing an exception.
35 * <p>
36 *
37 * @author Frank Yellin
38 * @see java.io.DataInputStream
39 * @see java.io.IOException
40 * @since JDK1.0
41 */
42public
43class EOFException extends IOException {
44 private static final long serialVersionUID = 6433858223774886977L;
45
46 /**
47 * Constructs an <code>EOFException</code> with <code>null</code>
48 * as its error detail message.
49 */
50 public EOFException() {
51 super();
52 }
53
54 /**
55 * Constructs an <code>EOFException</code> with the specified detail
56 * message. The string <code>s</code> may later be retrieved by the
57 * <code>{@link java.lang.Throwable#getMessage}</code> method of class
58 * <code>java.lang.Throwable</code>.
59 *
60 * @param s the detail message.
61 */
62 public EOFException(String s) {
63 super(s);
64 }
65}
java/pkg/java/io/ExpiringCache$1.class+0−0

Binary file not shown.

java/pkg/java/io/ExpiringCache$Entry.class+0−0

Binary file not shown.

java/pkg/java/io/ExpiringCache.class+0−0

Binary file not shown.

java/pkg/java/io/ExpiringCache.java+127−0
@@ -0,0 +1,127 @@
1/*
2 * Copyright (c) 2002, 2004, 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/*
27 */
28
29package java.io;
30
31import java.util.Iterator;
32import java.util.Map;
33import java.util.LinkedHashMap;
34import java.util.Set;
35
36class ExpiringCache {
37 private long millisUntilExpiration;
38 private Map map;
39 // Clear out old entries every few queries
40 private int queryCount;
41 private int queryOverflow = 300;
42 private int MAX_ENTRIES = 200;
43
44 static class Entry {
45 private long timestamp;
46 private String val;
47
48 Entry(long timestamp, String val) {
49 this.timestamp = timestamp;
50 this.val = val;
51 }
52
53 long timestamp() { return timestamp; }
54 void setTimestamp(long timestamp) { this.timestamp = timestamp; }
55
56 String val() { return val; }
57 void setVal(String val) { this.val = val; }
58 }
59
60 ExpiringCache() {
61 this(30000);
62 }
63
64 ExpiringCache(long millisUntilExpiration) {
65 this.millisUntilExpiration = millisUntilExpiration;
66 map = new LinkedHashMap() {
67 protected boolean removeEldestEntry(Map.Entry eldest) {
68 return size() > MAX_ENTRIES;
69 }
70 };
71 }
72
73 synchronized String get(String key) {
74 if (++queryCount >= queryOverflow) {
75 cleanup();
76 }
77 Entry entry = entryFor(key);
78 if (entry != null) {
79 return entry.val();
80 }
81 return null;
82 }
83
84 synchronized void put(String key, String val) {
85 if (++queryCount >= queryOverflow) {
86 cleanup();
87 }
88 Entry entry = entryFor(key);
89 if (entry != null) {
90 entry.setTimestamp(System.currentTimeMillis());
91 entry.setVal(val);
92 } else {
93 map.put(key, new Entry(System.currentTimeMillis(), val));
94 }
95 }
96
97 synchronized void clear() {
98 map.clear();
99 }
100
101 private Entry entryFor(String key) {
102 Entry entry = (Entry) map.get(key);
103 if (entry != null) {
104 long delta = System.currentTimeMillis() - entry.timestamp();
105 if (delta < 0 || delta >= millisUntilExpiration) {
106 map.remove(key);
107 entry = null;
108 }
109 }
110 return entry;
111 }
112
113 private void cleanup() {
114 Set keySet = map.keySet();
115 // Avoid ConcurrentModificationExceptions
116 String[] keys = new String[keySet.size()];
117 int i = 0;
118 for (Iterator iter = keySet.iterator(); iter.hasNext(); ) {
119 String key = (String) iter.next();
120 keys[i++] = key;
121 }
122 for (int j = 0; j < keys.length; j++) {
123 entryFor(keys[j]);
124 }
125 queryCount = 0;
126 }
127}
java/pkg/java/io/Externalizable.class+0−0

Binary file not shown.

java/pkg/java/io/Externalizable.java+97−0
@@ -0,0 +1,97 @@
1/*
2 * Copyright (c) 1996, 2004, 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
26package java.io;
27
28import java.io.ObjectOutput;
29import java.io.ObjectInput;
30
31/**
32 * Only the identity of the class of an Externalizable instance is
33 * written in the serialization stream and it is the responsibility
34 * of the class to save and restore the contents of its instances.
35 *
36 * The writeExternal and readExternal methods of the Externalizable
37 * interface are implemented by a class to give the class complete
38 * control over the format and contents of the stream for an object
39 * and its supertypes. These methods must explicitly
40 * coordinate with the supertype to save its state. These methods supersede
41 * customized implementations of writeObject and readObject methods.<br>
42 *
43 * Object Serialization uses the Serializable and Externalizable
44 * interfaces. Object persistence mechanisms can use them as well. Each
45 * object to be stored is tested for the Externalizable interface. If
46 * the object supports Externalizable, the writeExternal method is called. If the
47 * object does not support Externalizable and does implement
48 * Serializable, the object is saved using
49 * ObjectOutputStream. <br> When an Externalizable object is
50 * reconstructed, an instance is created using the public no-arg
51 * constructor, then the readExternal method called. Serializable
52 * objects are restored by reading them from an ObjectInputStream.<br>
53 *
54 * An Externalizable instance can designate a substitution object via
55 * the writeReplace and readResolve methods documented in the Serializable
56 * interface.<br>
57 *
58 * @author unascribed
59 * @see java.io.ObjectOutputStream
60 * @see java.io.ObjectInputStream
61 * @see java.io.ObjectOutput
62 * @see java.io.ObjectInput
63 * @see java.io.Serializable
64 * @since JDK1.1
65 */
66public interface Externalizable extends java.io.Serializable {
67 /**
68 * The object implements the writeExternal method to save its contents
69 * by calling the methods of DataOutput for its primitive values or
70 * calling the writeObject method of ObjectOutput for objects, strings,
71 * and arrays.
72 *
73 * @serialData Overriding methods should use this tag to describe
74 * the data layout of this Externalizable object.
75 * List the sequence of element types and, if possible,
76 * relate the element to a public/protected field and/or
77 * method of this Externalizable class.
78 *
79 * @param out the stream to write the object to
80 * @exception IOException Includes any I/O exceptions that may occur
81 */
82 void writeExternal(ObjectOutput out) throws IOException;
83
84 /**
85 * The object implements the readExternal method to restore its
86 * contents by calling the methods of DataInput for primitive
87 * types and readObject for objects, strings and arrays. The
88 * readExternal method must read the values in the same sequence
89 * and with the same types as were written by writeExternal.
90 *
91 * @param in the stream to read data from in order to restore the object
92 * @exception IOException if I/O errors occur
93 * @exception ClassNotFoundException If the class for an object being
94 * restored cannot be found.
95 */
96 void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;
97}
java/pkg/java/io/File$TempDirectory.class+0−0

Binary file not shown.

java/pkg/java/io/File.class+0−0

Binary file not shown.

java/pkg/java/io/File.java+2076−0
@@ -0,0 +1,2076 @@
1/*
2 * Copyright (c) 1994, 2011, 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
26package java.io;
27
28import java.net.URI;
29import java.net.URL;
30import java.net.MalformedURLException;
31import java.net.URISyntaxException;
32import java.util.List;
33import java.util.ArrayList;
34import java.security.AccessController;
35import java.security.SecureRandom;
36import java.nio.file.Path;
37import java.nio.file.FileSystems;
38import sun.security.action.GetPropertyAction;
39
40/**
41 * An abstract representation of file and directory pathnames.
42 *
43 * <p> User interfaces and operating systems use system-dependent <em>pathname
44 * strings</em> to name files and directories. This class presents an
45 * abstract, system-independent view of hierarchical pathnames. An
46 * <em>abstract pathname</em> has two components:
47 *
48 * <ol>
49 * <li> An optional system-dependent <em>prefix</em> string,
50 * such as a disk-drive specifier, <code>"/"</code>&nbsp;for the UNIX root
51 * directory, or <code>"\\\\"</code>&nbsp;for a Microsoft Windows UNC pathname, and
52 * <li> A sequence of zero or more string <em>names</em>.
53 * </ol>
54 *
55 * The first name in an abstract pathname may be a directory name or, in the
56 * case of Microsoft Windows UNC pathnames, a hostname. Each subsequent name
57 * in an abstract pathname denotes a directory; the last name may denote
58 * either a directory or a file. The <em>empty</em> abstract pathname has no
59 * prefix and an empty name sequence.
60 *
61 * <p> The conversion of a pathname string to or from an abstract pathname is
62 * inherently system-dependent. When an abstract pathname is converted into a
63 * pathname string, each name is separated from the next by a single copy of
64 * the default <em>separator character</em>. The default name-separator
65 * character is defined by the system property <code>file.separator</code>, and
66 * is made available in the public static fields <code>{@link
67 * #separator}</code> and <code>{@link #separatorChar}</code> of this class.
68 * When a pathname string is converted into an abstract pathname, the names
69 * within it may be separated by the default name-separator character or by any
70 * other name-separator character that is supported by the underlying system.
71 *
72 * <p> A pathname, whether abstract or in string form, may be either
73 * <em>absolute</em> or <em>relative</em>. An absolute pathname is complete in
74 * that no other information is required in order to locate the file that it
75 * denotes. A relative pathname, in contrast, must be interpreted in terms of
76 * information taken from some other pathname. By default the classes in the
77 * <code>java.io</code> package always resolve relative pathnames against the
78 * current user directory. This directory is named by the system property
79 * <code>user.dir</code>, and is typically the directory in which the Java
80 * virtual machine was invoked.
81 *
82 * <p> The <em>parent</em> of an abstract pathname may be obtained by invoking
83 * the {@link #getParent} method of this class and consists of the pathname's
84 * prefix and each name in the pathname's name sequence except for the last.
85 * Each directory's absolute pathname is an ancestor of any <tt>File</tt>
86 * object with an absolute abstract pathname which begins with the directory's
87 * absolute pathname. For example, the directory denoted by the abstract
88 * pathname <tt>"/usr"</tt> is an ancestor of the directory denoted by the
89 * pathname <tt>"/usr/local/bin"</tt>.
90 *
91 * <p> The prefix concept is used to handle root directories on UNIX platforms,
92 * and drive specifiers, root directories and UNC pathnames on Microsoft Windows platforms,
93 * as follows:
94 *
95 * <ul>
96 *
97 * <li> For UNIX platforms, the prefix of an absolute pathname is always
98 * <code>"/"</code>. Relative pathnames have no prefix. The abstract pathname
99 * denoting the root directory has the prefix <code>"/"</code> and an empty
100 * name sequence.
101 *
102 * <li> For Microsoft Windows platforms, the prefix of a pathname that contains a drive
103 * specifier consists of the drive letter followed by <code>":"</code> and
104 * possibly followed by <code>"\\"</code> if the pathname is absolute. The
105 * prefix of a UNC pathname is <code>"\\\\"</code>; the hostname and the share
106 * name are the first two names in the name sequence. A relative pathname that
107 * does not specify a drive has no prefix.
108 *
109 * </ul>
110 *
111 * <p> Instances of this class may or may not denote an actual file-system
112 * object such as a file or a directory. If it does denote such an object
113 * then that object resides in a <i>partition</i>. A partition is an
114 * operating system-specific portion of storage for a file system. A single
115 * storage device (e.g. a physical disk-drive, flash memory, CD-ROM) may
116 * contain multiple partitions. The object, if any, will reside on the
117 * partition <a name="partName">named</a> by some ancestor of the absolute
118 * form of this pathname.
119 *
120 * <p> A file system may implement restrictions to certain operations on the
121 * actual file-system object, such as reading, writing, and executing. These
122 * restrictions are collectively known as <i>access permissions</i>. The file
123 * system may have multiple sets of access permissions on a single object.
124 * For example, one set may apply to the object's <i>owner</i>, and another
125 * may apply to all other users. The access permissions on an object may
126 * cause some methods in this class to fail.
127 *
128 * <p> Instances of the <code>File</code> class are immutable; that is, once
129 * created, the abstract pathname represented by a <code>File</code> object
130 * will never change.
131 *
132 * <h4>Interoperability with {@code java.nio.file} package</h4>
133 *
134 * <p> The <a href="../../java/nio/file/package-summary.html">{@code java.nio.file}</a>
135 * package defines interfaces and classes for the Java virtual machine to access
136 * files, file attributes, and file systems. This API may be used to overcome
137 * many of the limitations of the {@code java.io.File} class.
138 * The {@link #toPath toPath} method may be used to obtain a {@link
139 * Path} that uses the abstract path represented by a {@code File} object to
140 * locate a file. The resulting {@code Path} may be used with the {@link
141 * java.nio.file.Files} class to provide more efficient and extensive access to
142 * additional file operations, file attributes, and I/O exceptions to help
143 * diagnose errors when an operation on a file fails.
144 *
145 * @author unascribed
146 * @since JDK1.0
147 */
148
149public class File
150 implements Serializable, Comparable<File>
151{
152
153 /**
154 * The FileSystem object representing the platform's local file system.
155 */
156 static private FileSystem fs = FileSystem.getFileSystem();
157
158 /**
159 * This abstract pathname's normalized pathname string. A normalized
160 * pathname string uses the default name-separator character and does not
161 * contain any duplicate or redundant separators.
162 *
163 * @serial
164 */
165 private String path;
166
167 /**
168 * The length of this abstract pathname's prefix, or zero if it has no
169 * prefix.
170 */
171 private transient int prefixLength;
172
173 /**
174 * Returns the length of this abstract pathname's prefix.
175 * For use by FileSystem classes.
176 */
177 int getPrefixLength() {
178 return prefixLength;
179 }
180
181 /**
182 * The system-dependent default name-separator character. This field is
183 * initialized to contain the first character of the value of the system
184 * property <code>file.separator</code>. On UNIX systems the value of this
185 * field is <code>'/'</code>; on Microsoft Windows systems it is <code>'\\'</code>.
186 *
187 * @see java.lang.System#getProperty(java.lang.String)
188 */
189 public static final char separatorChar = fs.getSeparator();
190
191 /**
192 * The system-dependent default name-separator character, represented as a
193 * string for convenience. This string contains a single character, namely
194 * <code>{@link #separatorChar}</code>.
195 */
196 public static final String separator = "" + separatorChar;
197
198 /**
199 * The system-dependent path-separator character. This field is
200 * initialized to contain the first character of the value of the system
201 * property <code>path.separator</code>. This character is used to
202 * separate filenames in a sequence of files given as a <em>path list</em>.
203 * On UNIX systems, this character is <code>':'</code>; on Microsoft Windows systems it
204 * is <code>';'</code>.
205 *
206 * @see java.lang.System#getProperty(java.lang.String)
207 */
208 public static final char pathSeparatorChar = fs.getPathSeparator();
209
210 /**
211 * The system-dependent path-separator character, represented as a string
212 * for convenience. This string contains a single character, namely
213 * <code>{@link #pathSeparatorChar}</code>.
214 */
215 public static final String pathSeparator = "" + pathSeparatorChar;
216
217
218 /* -- Constructors -- */
219
220 /**
221 * Internal constructor for already-normalized pathname strings.
222 */
223 private File(String pathname, int prefixLength) {
224 this.path = pathname;
225 this.prefixLength = prefixLength;
226 }
227
228 /**
229 * Internal constructor for already-normalized pathname strings.
230 * The parameter order is used to disambiguate this method from the
231 * public(File, String) constructor.
232 */
233 private File(String child, File parent) {
234 assert parent.path != null;
235 assert (!parent.path.equals(""));
236 this.path = fs.resolve(parent.path, child);
237 this.prefixLength = parent.prefixLength;
238 }
239
240 /**
241 * Creates a new <code>File</code> instance by converting the given
242 * pathname string into an abstract pathname. If the given string is
243 * the empty string, then the result is the empty abstract pathname.
244 *
245 * @param pathname A pathname string
246 * @throws NullPointerException
247 * If the <code>pathname</code> argument is <code>null</code>
248 */
249 public File(String pathname) {
250 if (pathname == null) {
251 throw new NullPointerException();
252 }
253 this.path = fs.normalize(pathname);
254 this.prefixLength = fs.prefixLength(this.path);
255 }
256
257 /* Note: The two-argument File constructors do not interpret an empty
258 parent abstract pathname as the current user directory. An empty parent
259 instead causes the child to be resolved against the system-dependent
260 directory defined by the FileSystem.getDefaultParent method. On Unix
261 this default is "/", while on Microsoft Windows it is "\\". This is required for
262 compatibility with the original behavior of this class. */
263
264 /**
265 * Creates a new <code>File</code> instance from a parent pathname string
266 * and a child pathname string.
267 *
268 * <p> If <code>parent</code> is <code>null</code> then the new
269 * <code>File</code> instance is created as if by invoking the
270 * single-argument <code>File</code> constructor on the given
271 * <code>child</code> pathname string.
272 *
273 * <p> Otherwise the <code>parent</code> pathname string is taken to denote
274 * a directory, and the <code>child</code> pathname string is taken to
275 * denote either a directory or a file. If the <code>child</code> pathname
276 * string is absolute then it is converted into a relative pathname in a
277 * system-dependent way. If <code>parent</code> is the empty string then
278 * the new <code>File</code> instance is created by converting
279 * <code>child</code> into an abstract pathname and resolving the result
280 * against a system-dependent default directory. Otherwise each pathname
281 * string is converted into an abstract pathname and the child abstract
282 * pathname is resolved against the parent.
283 *
284 * @param parent The parent pathname string
285 * @param child The child pathname string
286 * @throws NullPointerException
287 * If <code>child</code> is <code>null</code>
288 */
289 public File(String parent, String child) {
290 if (child == null) {
291 throw new NullPointerException();
292 }
293 if (parent != null) {
294 if (parent.equals("")) {
295 this.path = fs.resolve(fs.getDefaultParent(),
296 fs.normalize(child));
297 } else {
298 this.path = fs.resolve(fs.normalize(parent),
299 fs.normalize(child));
300 }
301 } else {
302 this.path = fs.normalize(child);
303 }
304 this.prefixLength = fs.prefixLength(this.path);
305 }
306
307 /**
308 * Creates a new <code>File</code> instance from a parent abstract
309 * pathname and a child pathname string.
310 *
311 * <p> If <code>parent</code> is <code>null</code> then the new
312 * <code>File</code> instance is created as if by invoking the
313 * single-argument <code>File</code> constructor on the given
314 * <code>child</code> pathname string.
315 *
316 * <p> Otherwise the <code>parent</code> abstract pathname is taken to
317 * denote a directory, and the <code>child</code> pathname string is taken
318 * to denote either a directory or a file. If the <code>child</code>
319 * pathname string is absolute then it is converted into a relative
320 * pathname in a system-dependent way. If <code>parent</code> is the empty
321 * abstract pathname then the new <code>File</code> instance is created by
322 * converting <code>child</code> into an abstract pathname and resolving
323 * the result against a system-dependent default directory. Otherwise each
324 * pathname string is converted into an abstract pathname and the child
325 * abstract pathname is resolved against the parent.
326 *
327 * @param parent The parent abstract pathname
328 * @param child The child pathname string
329 * @throws NullPointerException
330 * If <code>child</code> is <code>null</code>
331 */
332 public File(File parent, String child) {
333 if (child == null) {
334 throw new NullPointerException();
335 }
336 if (parent != null) {
337 if (parent.path.equals("")) {
338 this.path = fs.resolve(fs.getDefaultParent(),
339 fs.normalize(child));
340 } else {
341 this.path = fs.resolve(parent.path,
342 fs.normalize(child));
343 }
344 } else {
345 this.path = fs.normalize(child);
346 }
347 this.prefixLength = fs.prefixLength(this.path);
348 }
349
350 /**
351 * Creates a new <tt>File</tt> instance by converting the given
352 * <tt>file:</tt> URI into an abstract pathname.
353 *
354 * <p> The exact form of a <tt>file:</tt> URI is system-dependent, hence
355 * the transformation performed by this constructor is also
356 * system-dependent.
357 *
358 * <p> For a given abstract pathname <i>f</i> it is guaranteed that
359 *
360 * <blockquote><tt>
361 * new File(</tt><i>&nbsp;f</i><tt>.{@link #toURI() toURI}()).equals(</tt><i>&nbsp;f</i><tt>.{@link #getAbsoluteFile() getAbsoluteFile}())
362 * </tt></blockquote>
363 *
364 * so long as the original abstract pathname, the URI, and the new abstract
365 * pathname are all created in (possibly different invocations of) the same
366 * Java virtual machine. This relationship typically does not hold,
367 * however, when a <tt>file:</tt> URI that is created in a virtual machine
368 * on one operating system is converted into an abstract pathname in a
369 * virtual machine on a different operating system.
370 *
371 * @param uri
372 * An absolute, hierarchical URI with a scheme equal to
373 * <tt>"file"</tt>, a non-empty path component, and undefined
374 * authority, query, and fragment components
375 *
376 * @throws NullPointerException
377 * If <tt>uri</tt> is <tt>null</tt>
378 *
379 * @throws IllegalArgumentException
380 * If the preconditions on the parameter do not hold
381 *
382 * @see #toURI()
383 * @see java.net.URI
384 * @since 1.4
385 */
386 public File(URI uri) {
387
388 // Check our many preconditions
389 if (!uri.isAbsolute())
390 throw new IllegalArgumentException("URI is not absolute");
391 if (uri.isOpaque())
392 throw new IllegalArgumentException("URI is not hierarchical");
393 String scheme = uri.getScheme();
394 if ((scheme == null) || !scheme.equalsIgnoreCase("file"))
395 throw new IllegalArgumentException("URI scheme is not \"file\"");
396 if (uri.getAuthority() != null)
397 throw new IllegalArgumentException("URI has an authority component");
398 if (uri.getFragment() != null)
399 throw new IllegalArgumentException("URI has a fragment component");
400 if (uri.getQuery() != null)
401 throw new IllegalArgumentException("URI has a query component");
402 String p = uri.getPath();
403 if (p.equals(""))
404 throw new IllegalArgumentException("URI path component is empty");
405
406 // Okay, now initialize
407 p = fs.fromURIPath(p);
408 if (File.separatorChar != '/')
409 p = p.replace('/', File.separatorChar);
410 this.path = fs.normalize(p);
411 this.prefixLength = fs.prefixLength(this.path);
412 }
413
414
415 /* -- Path-component accessors -- */
416
417 /**
418 * Returns the name of the file or directory denoted by this abstract
419 * pathname. This is just the last name in the pathname's name
420 * sequence. If the pathname's name sequence is empty, then the empty
421 * string is returned.
422 *
423 * @return The name of the file or directory denoted by this abstract
424 * pathname, or the empty string if this pathname's name sequence
425 * is empty
426 */
427 public String getName() {
428 int index = path.lastIndexOf(separatorChar);
429 if (index < prefixLength) return path.substring(prefixLength);
430 return path.substring(index + 1);
431 }
432
433 /**
434 * Returns the pathname string of this abstract pathname's parent, or
435 * <code>null</code> if this pathname does not name a parent directory.
436 *
437 * <p> The <em>parent</em> of an abstract pathname consists of the
438 * pathname's prefix, if any, and each name in the pathname's name
439 * sequence except for the last. If the name sequence is empty then
440 * the pathname does not name a parent directory.
441 *
442 * @return The pathname string of the parent directory named by this
443 * abstract pathname, or <code>null</code> if this pathname
444 * does not name a parent
445 */
446 public String getParent() {
447 int index = path.lastIndexOf(separatorChar);
448 if (index < prefixLength) {
449 if ((prefixLength > 0) && (path.length() > prefixLength))
450 return path.substring(0, prefixLength);
451 return null;
452 }
453 return path.substring(0, index);
454 }
455
456 /**
457 * Returns the abstract pathname of this abstract pathname's parent,
458 * or <code>null</code> if this pathname does not name a parent
459 * directory.
460 *
461 * <p> The <em>parent</em> of an abstract pathname consists of the
462 * pathname's prefix, if any, and each name in the pathname's name
463 * sequence except for the last. If the name sequence is empty then
464 * the pathname does not name a parent directory.
465 *
466 * @return The abstract pathname of the parent directory named by this
467 * abstract pathname, or <code>null</code> if this pathname
468 * does not name a parent
469 *
470 * @since 1.2
471 */
472 public File getParentFile() {
473 String p = this.getParent();
474 if (p == null) return null;
475 return new File(p, this.prefixLength);
476 }
477
478 /**
479 * Converts this abstract pathname into a pathname string. The resulting
480 * string uses the {@link #separator default name-separator character} to
481 * separate the names in the name sequence.
482 *
483 * @return The string form of this abstract pathname
484 */
485 public String getPath() {
486 return path;
487 }
488
489
490 /* -- Path operations -- */
491
492 /**
493 * Tests whether this abstract pathname is absolute. The definition of
494 * absolute pathname is system dependent. On UNIX systems, a pathname is
495 * absolute if its prefix is <code>"/"</code>. On Microsoft Windows systems, a
496 * pathname is absolute if its prefix is a drive specifier followed by
497 * <code>"\\"</code>, or if its prefix is <code>"\\\\"</code>.
498 *
499 * @return <code>true</code> if this abstract pathname is absolute,
500 * <code>false</code> otherwise
501 */
502 public boolean isAbsolute() {
503 return fs.isAbsolute(this);
504 }
505
506 /**
507 * Returns the absolute pathname string of this abstract pathname.
508 *
509 * <p> If this abstract pathname is already absolute, then the pathname
510 * string is simply returned as if by the <code>{@link #getPath}</code>
511 * method. If this abstract pathname is the empty abstract pathname then
512 * the pathname string of the current user directory, which is named by the
513 * system property <code>user.dir</code>, is returned. Otherwise this
514 * pathname is resolved in a system-dependent way. On UNIX systems, a
515 * relative pathname is made absolute by resolving it against the current
516 * user directory. On Microsoft Windows systems, a relative pathname is made absolute
517 * by resolving it against the current directory of the drive named by the
518 * pathname, if any; if not, it is resolved against the current user
519 * directory.
520 *
521 * @return The absolute pathname string denoting the same file or
522 * directory as this abstract pathname
523 *
524 * @throws SecurityException
525 * If a required system property value cannot be accessed.
526 *
527 * @see java.io.File#isAbsolute()
528 */
529 public String getAbsolutePath() {
530 return fs.resolve(this);
531 }
532
533 /**
534 * Returns the absolute form of this abstract pathname. Equivalent to
535 * <code>new&nbsp;File(this.{@link #getAbsolutePath})</code>.
536 *
537 * @return The absolute abstract pathname denoting the same file or
538 * directory as this abstract pathname
539 *
540 * @throws SecurityException
541 * If a required system property value cannot be accessed.
542 *
543 * @since 1.2
544 */
545 public File getAbsoluteFile() {
546 String absPath = getAbsolutePath();
547 return new File(absPath, fs.prefixLength(absPath));
548 }
549
550 /**
551 * Returns the canonical pathname string of this abstract pathname.
552 *
553 * <p> A canonical pathname is both absolute and unique. The precise
554 * definition of canonical form is system-dependent. This method first
555 * converts this pathname to absolute form if necessary, as if by invoking the
556 * {@link #getAbsolutePath} method, and then maps it to its unique form in a
557 * system-dependent way. This typically involves removing redundant names
558 * such as <tt>"."</tt> and <tt>".."</tt> from the pathname, resolving
559 * symbolic links (on UNIX platforms), and converting drive letters to a
560 * standard case (on Microsoft Windows platforms).
561 *
562 * <p> Every pathname that denotes an existing file or directory has a
563 * unique canonical form. Every pathname that denotes a nonexistent file
564 * or directory also has a unique canonical form. The canonical form of
565 * the pathname of a nonexistent file or directory may be different from
566 * the canonical form of the same pathname after the file or directory is
567 * created. Similarly, the canonical form of the pathname of an existing
568 * file or directory may be different from the canonical form of the same
569 * pathname after the file or directory is deleted.
570 *
571 * @return The canonical pathname string denoting the same file or
572 * directory as this abstract pathname
573 *
574 * @throws IOException
575 * If an I/O error occurs, which is possible because the
576 * construction of the canonical pathname may require
577 * filesystem queries
578 *
579 * @throws SecurityException
580 * If a required system property value cannot be accessed, or
581 * if a security manager exists and its <code>{@link
582 * java.lang.SecurityManager#checkRead}</code> method denies
583 * read access to the file
584 *
585 * @since JDK1.1
586 * @see Path#toRealPath
587 */
588 public String getCanonicalPath() throws IOException {
589 return fs.canonicalize(fs.resolve(this));
590 }
591
592 /**
593 * Returns the canonical form of this abstract pathname. Equivalent to
594 * <code>new&nbsp;File(this.{@link #getCanonicalPath})</code>.
595 *
596 * @return The canonical pathname string denoting the same file or
597 * directory as this abstract pathname
598 *
599 * @throws IOException
600 * If an I/O error occurs, which is possible because the
601 * construction of the canonical pathname may require
602 * filesystem queries
603 *
604 * @throws SecurityException
605 * If a required system property value cannot be accessed, or
606 * if a security manager exists and its <code>{@link
607 * java.lang.SecurityManager#checkRead}</code> method denies
608 * read access to the file
609 *
610 * @since 1.2
611 * @see Path#toRealPath
612 */
613 public File getCanonicalFile() throws IOException {
614 String canonPath = getCanonicalPath();
615 return new File(canonPath, fs.prefixLength(canonPath));
616 }
617
618 private static String slashify(String path, boolean isDirectory) {
619 String p = path;
620 if (File.separatorChar != '/')
621 p = p.replace(File.separatorChar, '/');
622 if (!p.startsWith("/"))
623 p = "/" + p;
624 if (!p.endsWith("/") && isDirectory)
625 p = p + "/";
626 return p;
627 }
628
629 /**
630 * Converts this abstract pathname into a <code>file:</code> URL. The
631 * exact form of the URL is system-dependent. If it can be determined that
632 * the file denoted by this abstract pathname is a directory, then the
633 * resulting URL will end with a slash.
634 *
635 * @return A URL object representing the equivalent file URL
636 *
637 * @throws MalformedURLException
638 * If the path cannot be parsed as a URL
639 *
640 * @see #toURI()
641 * @see java.net.URI
642 * @see java.net.URI#toURL()
643 * @see java.net.URL
644 * @since 1.2
645 *
646 * @deprecated This method does not automatically escape characters that
647 * are illegal in URLs. It is recommended that new code convert an
648 * abstract pathname into a URL by first converting it into a URI, via the
649 * {@link #toURI() toURI} method, and then converting the URI into a URL
650 * via the {@link java.net.URI#toURL() URI.toURL} method.
651 */
652 @Deprecated
653 public URL toURL() throws MalformedURLException {
654 return new URL("file", "", slashify(getAbsolutePath(), isDirectory()));
655 }
656
657 /**
658 * Constructs a <tt>file:</tt> URI that represents this abstract pathname.
659 *
660 * <p> The exact form of the URI is system-dependent. If it can be
661 * determined that the file denoted by this abstract pathname is a
662 * directory, then the resulting URI will end with a slash.
663 *
664 * <p> For a given abstract pathname <i>f</i>, it is guaranteed that
665 *
666 * <blockquote><tt>
667 * new {@link #File(java.net.URI) File}(</tt><i>&nbsp;f</i><tt>.toURI()).equals(</tt><i>&nbsp;f</i><tt>.{@link #getAbsoluteFile() getAbsoluteFile}())
668 * </tt></blockquote>
669 *
670 * so long as the original abstract pathname, the URI, and the new abstract
671 * pathname are all created in (possibly different invocations of) the same
672 * Java virtual machine. Due to the system-dependent nature of abstract
673 * pathnames, however, this relationship typically does not hold when a
674 * <tt>file:</tt> URI that is created in a virtual machine on one operating
675 * system is converted into an abstract pathname in a virtual machine on a
676 * different operating system.
677 *
678 * <p> Note that when this abstract pathname represents a UNC pathname then
679 * all components of the UNC (including the server name component) are encoded
680 * in the {@code URI} path. The authority component is undefined, meaning
681 * that it is represented as {@code null}. The {@link Path} class defines the
682 * {@link Path#toUri toUri} method to encode the server name in the authority
683 * component of the resulting {@code URI}. The {@link #toPath toPath} method
684 * may be used to obtain a {@code Path} representing this abstract pathname.
685 *
686 * @return An absolute, hierarchical URI with a scheme equal to
687 * <tt>"file"</tt>, a path representing this abstract pathname,
688 * and undefined authority, query, and fragment components
689 * @throws SecurityException If a required system property value cannot
690 * be accessed.
691 *
692 * @see #File(java.net.URI)
693 * @see java.net.URI
694 * @see java.net.URI#toURL()
695 * @since 1.4
696 */
697 public URI toURI() {
698 try {
699 File f = getAbsoluteFile();
700 String sp = slashify(f.getPath(), f.isDirectory());
701 if (sp.startsWith("//"))
702 sp = "//" + sp;
703 return new URI("file", null, sp, null);
704 } catch (URISyntaxException x) {
705 throw new Error(x); // Can't happen
706 }
707 }
708
709
710 /* -- Attribute accessors -- */
711
712 /**
713 * Tests whether the application can read the file denoted by this
714 * abstract pathname.
715 *
716 * @return <code>true</code> if and only if the file specified by this
717 * abstract pathname exists <em>and</em> can be read by the
718 * application; <code>false</code> otherwise
719 *
720 * @throws SecurityException
721 * If a security manager exists and its <code>{@link
722 * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
723 * method denies read access to the file
724 */
725 public boolean canRead() {
726 SecurityManager security = System.getSecurityManager();
727 if (security != null) {
728 security.checkRead(path);
729 }
730 return fs.checkAccess(this, FileSystem.ACCESS_READ);
731 }
732
733 /**
734 * Tests whether the application can modify the file denoted by this
735 * abstract pathname.
736 *
737 * @return <code>true</code> if and only if the file system actually
738 * contains a file denoted by this abstract pathname <em>and</em>
739 * the application is allowed to write to the file;
740 * <code>false</code> otherwise.
741 *
742 * @throws SecurityException
743 * If a security manager exists and its <code>{@link
744 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
745 * method denies write access to the file
746 */
747 public boolean canWrite() {
748 SecurityManager security = System.getSecurityManager();
749 if (security != null) {
750 security.checkWrite(path);
751 }
752 return fs.checkAccess(this, FileSystem.ACCESS_WRITE);
753 }
754
755 /**
756 * Tests whether the file or directory denoted by this abstract pathname
757 * exists.
758 *
759 * @return <code>true</code> if and only if the file or directory denoted
760 * by this abstract pathname exists; <code>false</code> otherwise
761 *
762 * @throws SecurityException
763 * If a security manager exists and its <code>{@link
764 * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
765 * method denies read access to the file or directory
766 */
767 public boolean exists() {
768 SecurityManager security = System.getSecurityManager();
769 if (security != null) {
770 security.checkRead(path);
771 }
772 return ((fs.getBooleanAttributes(this) & FileSystem.BA_EXISTS) != 0);
773 }
774
775 /**
776 * Tests whether the file denoted by this abstract pathname is a
777 * directory.
778 *
779 * <p> Where it is required to distinguish an I/O exception from the case
780 * that the file is not a directory, or where several attributes of the
781 * same file are required at the same time, then the {@link
782 * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
783 * Files.readAttributes} method may be used.
784 *
785 * @return <code>true</code> if and only if the file denoted by this
786 * abstract pathname exists <em>and</em> is a directory;
787 * <code>false</code> otherwise
788 *
789 * @throws SecurityException
790 * If a security manager exists and its <code>{@link
791 * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
792 * method denies read access to the file
793 */
794 public boolean isDirectory() {
795 SecurityManager security = System.getSecurityManager();
796 if (security != null) {
797 security.checkRead(path);
798 }
799 return ((fs.getBooleanAttributes(this) & FileSystem.BA_DIRECTORY)
800 != 0);
801 }
802
803 /**
804 * Tests whether the file denoted by this abstract pathname is a normal
805 * file. A file is <em>normal</em> if it is not a directory and, in
806 * addition, satisfies other system-dependent criteria. Any non-directory
807 * file created by a Java application is guaranteed to be a normal file.
808 *
809 * <p> Where it is required to distinguish an I/O exception from the case
810 * that the file is not a normal file, or where several attributes of the
811 * same file are required at the same time, then the {@link
812 * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
813 * Files.readAttributes} method may be used.
814 *
815 * @return <code>true</code> if and only if the file denoted by this
816 * abstract pathname exists <em>and</em> is a normal file;
817 * <code>false</code> otherwise
818 *
819 * @throws SecurityException
820 * If a security manager exists and its <code>{@link
821 * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
822 * method denies read access to the file
823 */
824 public boolean isFile() {
825 SecurityManager security = System.getSecurityManager();
826 if (security != null) {
827 security.checkRead(path);
828 }
829 return ((fs.getBooleanAttributes(this) & FileSystem.BA_REGULAR) != 0);
830 }
831
832 /**
833 * Tests whether the file named by this abstract pathname is a hidden
834 * file. The exact definition of <em>hidden</em> is system-dependent. On
835 * UNIX systems, a file is considered to be hidden if its name begins with
836 * a period character (<code>'.'</code>). On Microsoft Windows systems, a file is
837 * considered to be hidden if it has been marked as such in the filesystem.
838 *
839 * @return <code>true</code> if and only if the file denoted by this
840 * abstract pathname is hidden according to the conventions of the
841 * underlying platform
842 *
843 * @throws SecurityException
844 * If a security manager exists and its <code>{@link
845 * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
846 * method denies read access to the file
847 *
848 * @since 1.2
849 */
850 public boolean isHidden() {
851 SecurityManager security = System.getSecurityManager();
852 if (security != null) {
853 security.checkRead(path);
854 }
855 return ((fs.getBooleanAttributes(this) & FileSystem.BA_HIDDEN) != 0);
856 }
857
858 /**
859 * Returns the time that the file denoted by this abstract pathname was
860 * last modified.
861 *
862 * <p> Where it is required to distinguish an I/O exception from the case
863 * where {@code 0L} is returned, or where several attributes of the
864 * same file are required at the same time, or where the time of last
865 * access or the creation time are required, then the {@link
866 * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
867 * Files.readAttributes} method may be used.
868 *
869 * @return A <code>long</code> value representing the time the file was
870 * last modified, measured in milliseconds since the epoch
871 * (00:00:00 GMT, January 1, 1970), or <code>0L</code> if the
872 * file does not exist or if an I/O error occurs
873 *
874 * @throws SecurityException
875 * If a security manager exists and its <code>{@link
876 * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
877 * method denies read access to the file
878 */
879 public long lastModified() {
880 SecurityManager security = System.getSecurityManager();
881 if (security != null) {
882 security.checkRead(path);
883 }
884 return fs.getLastModifiedTime(this);
885 }
886
887 /**
888 * Returns the length of the file denoted by this abstract pathname.
889 * The return value is unspecified if this pathname denotes a directory.
890 *
891 * <p> Where it is required to distinguish an I/O exception from the case
892 * that {@code 0L} is returned, or where several attributes of the same file
893 * are required at the same time, then the {@link
894 * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
895 * Files.readAttributes} method may be used.
896 *
897 * @return The length, in bytes, of the file denoted by this abstract
898 * pathname, or <code>0L</code> if the file does not exist. Some
899 * operating systems may return <code>0L</code> for pathnames
900 * denoting system-dependent entities such as devices or pipes.
901 *
902 * @throws SecurityException
903 * If a security manager exists and its <code>{@link
904 * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
905 * method denies read access to the file
906 */
907 public long length() {
908 SecurityManager security = System.getSecurityManager();
909 if (security != null) {
910 security.checkRead(path);
911 }
912 return fs.getLength(this);
913 }
914
915
916 /* -- File operations -- */
917
918 /**
919 * Atomically creates a new, empty file named by this abstract pathname if
920 * and only if a file with this name does not yet exist. The check for the
921 * existence of the file and the creation of the file if it does not exist
922 * are a single operation that is atomic with respect to all other
923 * filesystem activities that might affect the file.
924 * <P>
925 * Note: this method should <i>not</i> be used for file-locking, as
926 * the resulting protocol cannot be made to work reliably. The
927 * {@link java.nio.channels.FileLock FileLock}
928 * facility should be used instead.
929 *
930 * @return <code>true</code> if the named file does not exist and was
931 * successfully created; <code>false</code> if the named file
932 * already exists
933 *
934 * @throws IOException
935 * If an I/O error occurred
936 *
937 * @throws SecurityException
938 * If a security manager exists and its <code>{@link
939 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
940 * method denies write access to the file
941 *
942 * @since 1.2
943 */
944 public boolean createNewFile() throws IOException {
945 SecurityManager security = System.getSecurityManager();
946 if (security != null) security.checkWrite(path);
947 return fs.createFileExclusively(path);
948 }
949
950 /**
951 * Deletes the file or directory denoted by this abstract pathname. If
952 * this pathname denotes a directory, then the directory must be empty in
953 * order to be deleted.
954 *
955 * <p> Note that the {@link java.nio.file.Files} class defines the {@link
956 * java.nio.file.Files#delete(Path) delete} method to throw an {@link IOException}
957 * when a file cannot be deleted. This is useful for error reporting and to
958 * diagnose why a file cannot be deleted.
959 *
960 * @return <code>true</code> if and only if the file or directory is
961 * successfully deleted; <code>false</code> otherwise
962 *
963 * @throws SecurityException
964 * If a security manager exists and its <code>{@link
965 * java.lang.SecurityManager#checkDelete}</code> method denies
966 * delete access to the file
967 */
968 public boolean delete() {
969 SecurityManager security = System.getSecurityManager();
970 if (security != null) {
971 security.checkDelete(path);
972 }
973 return fs.delete(this);
974 }
975
976 /**
977 * Requests that the file or directory denoted by this abstract
978 * pathname be deleted when the virtual machine terminates.
979 * Files (or directories) are deleted in the reverse order that
980 * they are registered. Invoking this method to delete a file or
981 * directory that is already registered for deletion has no effect.
982 * Deletion will be attempted only for normal termination of the
983 * virtual machine, as defined by the Java Language Specification.
984 *
985 * <p> Once deletion has been requested, it is not possible to cancel the
986 * request. This method should therefore be used with care.
987 *
988 * <P>
989 * Note: this method should <i>not</i> be used for file-locking, as
990 * the resulting protocol cannot be made to work reliably. The
991 * {@link java.nio.channels.FileLock FileLock}
992 * facility should be used instead.
993 *
994 * @throws SecurityException
995 * If a security manager exists and its <code>{@link
996 * java.lang.SecurityManager#checkDelete}</code> method denies
997 * delete access to the file
998 *
999 * @see #delete
1000 *
1001 * @since 1.2
1002 */
1003 public void deleteOnExit() {
1004 SecurityManager security = System.getSecurityManager();
1005 if (security != null) {
1006 security.checkDelete(path);
1007 }
1008 DeleteOnExitHook.add(path);
1009 }
1010
1011 /**
1012 * Returns an array of strings naming the files and directories in the
1013 * directory denoted by this abstract pathname.
1014 *
1015 * <p> If this abstract pathname does not denote a directory, then this
1016 * method returns {@code null}. Otherwise an array of strings is
1017 * returned, one for each file or directory in the directory. Names
1018 * denoting the directory itself and the directory's parent directory are
1019 * not included in the result. Each string is a file name rather than a
1020 * complete path.
1021 *
1022 * <p> There is no guarantee that the name strings in the resulting array
1023 * will appear in any specific order; they are not, in particular,
1024 * guaranteed to appear in alphabetical order.
1025 *
1026 * <p> Note that the {@link java.nio.file.Files} class defines the {@link
1027 * java.nio.file.Files#newDirectoryStream(Path) newDirectoryStream} method to
1028 * open a directory and iterate over the names of the files in the directory.
1029 * This may use less resources when working with very large directories, and
1030 * may be more responsive when working with remote directories.
1031 *
1032 * @return An array of strings naming the files and directories in the
1033 * directory denoted by this abstract pathname. The array will be
1034 * empty if the directory is empty. Returns {@code null} if
1035 * this abstract pathname does not denote a directory, or if an
1036 * I/O error occurs.
1037 *
1038 * @throws SecurityException
1039 * If a security manager exists and its {@link
1040 * SecurityManager#checkRead(String)} method denies read access to
1041 * the directory
1042 */
1043 public String[] list() {
1044 SecurityManager security = System.getSecurityManager();
1045 if (security != null) {
1046 security.checkRead(path);
1047 }
1048 return fs.list(this);
1049 }
1050
1051 /**
1052 * Returns an array of strings naming the files and directories in the
1053 * directory denoted by this abstract pathname that satisfy the specified
1054 * filter. The behavior of this method is the same as that of the
1055 * {@link #list()} method, except that the strings in the returned array
1056 * must satisfy the filter. If the given {@code filter} is {@code null}
1057 * then all names are accepted. Otherwise, a name satisfies the filter if
1058 * and only if the value {@code true} results when the {@link
1059 * FilenameFilter#accept FilenameFilter.accept(File,&nbsp;String)} method
1060 * of the filter is invoked on this abstract pathname and the name of a
1061 * file or directory in the directory that it denotes.
1062 *
1063 * @param filter
1064 * A filename filter
1065 *
1066 * @return An array of strings naming the files and directories in the
1067 * directory denoted by this abstract pathname that were accepted
1068 * by the given {@code filter}. The array will be empty if the
1069 * directory is empty or if no names were accepted by the filter.
1070 * Returns {@code null} if this abstract pathname does not denote
1071 * a directory, or if an I/O error occurs.
1072 *
1073 * @throws SecurityException
1074 * If a security manager exists and its {@link
1075 * SecurityManager#checkRead(String)} method denies read access to
1076 * the directory
1077 *
1078 * @see java.nio.file.Files#newDirectoryStream(Path,String)
1079 */
1080 public String[] list(FilenameFilter filter) {
1081 String names[] = list();
1082 if ((names == null) || (filter == null)) {
1083 return names;
1084 }
1085 List<String> v = new ArrayList<>();
1086 for (int i = 0 ; i < names.length ; i++) {
1087 if (filter.accept(this, names[i])) {
1088 v.add(names[i]);
1089 }
1090 }
1091 return v.toArray(new String[v.size()]);
1092 }
1093
1094 /**
1095 * Returns an array of abstract pathnames denoting the files in the
1096 * directory denoted by this abstract pathname.
1097 *
1098 * <p> If this abstract pathname does not denote a directory, then this
1099 * method returns {@code null}. Otherwise an array of {@code File} objects
1100 * is returned, one for each file or directory in the directory. Pathnames
1101 * denoting the directory itself and the directory's parent directory are
1102 * not included in the result. Each resulting abstract pathname is
1103 * constructed from this abstract pathname using the {@link #File(File,
1104 * String) File(File,&nbsp;String)} constructor. Therefore if this
1105 * pathname is absolute then each resulting pathname is absolute; if this
1106 * pathname is relative then each resulting pathname will be relative to
1107 * the same directory.
1108 *
1109 * <p> There is no guarantee that the name strings in the resulting array
1110 * will appear in any specific order; they are not, in particular,
1111 * guaranteed to appear in alphabetical order.
1112 *
1113 * <p> Note that the {@link java.nio.file.Files} class defines the {@link
1114 * java.nio.file.Files#newDirectoryStream(Path) newDirectoryStream} method
1115 * to open a directory and iterate over the names of the files in the
1116 * directory. This may use less resources when working with very large
1117 * directories.
1118 *
1119 * @return An array of abstract pathnames denoting the files and
1120 * directories in the directory denoted by this abstract pathname.
1121 * The array will be empty if the directory is empty. Returns
1122 * {@code null} if this abstract pathname does not denote a
1123 * directory, or if an I/O error occurs.
1124 *
1125 * @throws SecurityException
1126 * If a security manager exists and its {@link
1127 * SecurityManager#checkRead(String)} method denies read access to
1128 * the directory
1129 *
1130 * @since 1.2
1131 */
1132 public File[] listFiles() {
1133 String[] ss = list();
1134 if (ss == null) return null;
1135 int n = ss.length;
1136 File[] fs = new File[n];
1137 for (int i = 0; i < n; i++) {
1138 fs[i] = new File(ss[i], this);
1139 }
1140 return fs;
1141 }
1142
1143 /**
1144 * Returns an array of abstract pathnames denoting the files and
1145 * directories in the directory denoted by this abstract pathname that
1146 * satisfy the specified filter. The behavior of this method is the same
1147 * as that of the {@link #listFiles()} method, except that the pathnames in
1148 * the returned array must satisfy the filter. If the given {@code filter}
1149 * is {@code null} then all pathnames are accepted. Otherwise, a pathname
1150 * satisfies the filter if and only if the value {@code true} results when
1151 * the {@link FilenameFilter#accept
1152 * FilenameFilter.accept(File,&nbsp;String)} method of the filter is
1153 * invoked on this abstract pathname and the name of a file or directory in
1154 * the directory that it denotes.
1155 *
1156 * @param filter
1157 * A filename filter
1158 *
1159 * @return An array of abstract pathnames denoting the files and
1160 * directories in the directory denoted by this abstract pathname.
1161 * The array will be empty if the directory is empty. Returns
1162 * {@code null} if this abstract pathname does not denote a
1163 * directory, or if an I/O error occurs.
1164 *
1165 * @throws SecurityException
1166 * If a security manager exists and its {@link
1167 * SecurityManager#checkRead(String)} method denies read access to
1168 * the directory
1169 *
1170 * @since 1.2
1171 * @see java.nio.file.Files#newDirectoryStream(Path,String)
1172 */
1173 public File[] listFiles(FilenameFilter filter) {
1174 String ss[] = list();
1175 if (ss == null) return null;
1176 ArrayList<File> files = new ArrayList<>();
1177 for (String s : ss)
1178 if ((filter == null) || filter.accept(this, s))
1179 files.add(new File(s, this));
1180 return files.toArray(new File[files.size()]);
1181 }
1182
1183 /**
1184 * Returns an array of abstract pathnames denoting the files and
1185 * directories in the directory denoted by this abstract pathname that
1186 * satisfy the specified filter. The behavior of this method is the same
1187 * as that of the {@link #listFiles()} method, except that the pathnames in
1188 * the returned array must satisfy the filter. If the given {@code filter}
1189 * is {@code null} then all pathnames are accepted. Otherwise, a pathname
1190 * satisfies the filter if and only if the value {@code true} results when
1191 * the {@link FileFilter#accept FileFilter.accept(File)} method of the
1192 * filter is invoked on the pathname.
1193 *
1194 * @param filter
1195 * A file filter
1196 *
1197 * @return An array of abstract pathnames denoting the files and
1198 * directories in the directory denoted by this abstract pathname.
1199 * The array will be empty if the directory is empty. Returns
1200 * {@code null} if this abstract pathname does not denote a
1201 * directory, or if an I/O error occurs.
1202 *
1203 * @throws SecurityException
1204 * If a security manager exists and its {@link
1205 * SecurityManager#checkRead(String)} method denies read access to
1206 * the directory
1207 *
1208 * @since 1.2
1209 * @see java.nio.file.Files#newDirectoryStream(Path,java.nio.file.DirectoryStream.Filter)
1210 */
1211 public File[] listFiles(FileFilter filter) {
1212 String ss[] = list();
1213 if (ss == null) return null;
1214 ArrayList<File> files = new ArrayList<>();
1215 for (String s : ss) {
1216 File f = new File(s, this);
1217 if ((filter == null) || filter.accept(f))
1218 files.add(f);
1219 }
1220 return files.toArray(new File[files.size()]);
1221 }
1222
1223 /**
1224 * Creates the directory named by this abstract pathname.
1225 *
1226 * @return <code>true</code> if and only if the directory was
1227 * created; <code>false</code> otherwise
1228 *
1229 * @throws SecurityException
1230 * If a security manager exists and its <code>{@link
1231 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1232 * method does not permit the named directory to be created
1233 */
1234 public boolean mkdir() {
1235 SecurityManager security = System.getSecurityManager();
1236 if (security != null) {
1237 security.checkWrite(path);
1238 }
1239 return fs.createDirectory(this);
1240 }
1241
1242 /**
1243 * Creates the directory named by this abstract pathname, including any
1244 * necessary but nonexistent parent directories. Note that if this
1245 * operation fails it may have succeeded in creating some of the necessary
1246 * parent directories.
1247 *
1248 * @return <code>true</code> if and only if the directory was created,
1249 * along with all necessary parent directories; <code>false</code>
1250 * otherwise
1251 *
1252 * @throws SecurityException
1253 * If a security manager exists and its <code>{@link
1254 * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
1255 * method does not permit verification of the existence of the
1256 * named directory and all necessary parent directories; or if
1257 * the <code>{@link
1258 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1259 * method does not permit the named directory and all necessary
1260 * parent directories to be created
1261 */
1262 public boolean mkdirs() {
1263 if (exists()) {
1264 return false;
1265 }
1266 if (mkdir()) {
1267 return true;
1268 }
1269 File canonFile = null;
1270 try {
1271 canonFile = getCanonicalFile();
1272 } catch (IOException e) {
1273 return false;
1274 }
1275
1276 File parent = canonFile.getParentFile();
1277 return (parent != null && (parent.mkdirs() || parent.exists()) &&
1278 canonFile.mkdir());
1279 }
1280
1281 /**
1282 * Renames the file denoted by this abstract pathname.
1283 *
1284 * <p> Many aspects of the behavior of this method are inherently
1285 * platform-dependent: The rename operation might not be able to move a
1286 * file from one filesystem to another, it might not be atomic, and it
1287 * might not succeed if a file with the destination abstract pathname
1288 * already exists. The return value should always be checked to make sure
1289 * that the rename operation was successful.
1290 *
1291 * <p> Note that the {@link java.nio.file.Files} class defines the {@link
1292 * java.nio.file.Files#move move} method to move or rename a file in a
1293 * platform independent manner.
1294 *
1295 * @param dest The new abstract pathname for the named file
1296 *
1297 * @return <code>true</code> if and only if the renaming succeeded;
1298 * <code>false</code> otherwise
1299 *
1300 * @throws SecurityException
1301 * If a security manager exists and its <code>{@link
1302 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1303 * method denies write access to either the old or new pathnames
1304 *
1305 * @throws NullPointerException
1306 * If parameter <code>dest</code> is <code>null</code>
1307 */
1308 public boolean renameTo(File dest) {
1309 SecurityManager security = System.getSecurityManager();
1310 if (security != null) {
1311 security.checkWrite(path);
1312 security.checkWrite(dest.path);
1313 }
1314 return fs.rename(this, dest);
1315 }
1316
1317 /**
1318 * Sets the last-modified time of the file or directory named by this
1319 * abstract pathname.
1320 *
1321 * <p> All platforms support file-modification times to the nearest second,
1322 * but some provide more precision. The argument will be truncated to fit
1323 * the supported precision. If the operation succeeds and no intervening
1324 * operations on the file take place, then the next invocation of the
1325 * <code>{@link #lastModified}</code> method will return the (possibly
1326 * truncated) <code>time</code> argument that was passed to this method.
1327 *
1328 * @param time The new last-modified time, measured in milliseconds since
1329 * the epoch (00:00:00 GMT, January 1, 1970)
1330 *
1331 * @return <code>true</code> if and only if the operation succeeded;
1332 * <code>false</code> otherwise
1333 *
1334 * @throws IllegalArgumentException If the argument is negative
1335 *
1336 * @throws SecurityException
1337 * If a security manager exists and its <code>{@link
1338 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1339 * method denies write access to the named file
1340 *
1341 * @since 1.2
1342 */
1343 public boolean setLastModified(long time) {
1344 if (time < 0) throw new IllegalArgumentException("Negative time");
1345 SecurityManager security = System.getSecurityManager();
1346 if (security != null) {
1347 security.checkWrite(path);
1348 }
1349 return fs.setLastModifiedTime(this, time);
1350 }
1351
1352 /**
1353 * Marks the file or directory named by this abstract pathname so that
1354 * only read operations are allowed. After invoking this method the file
1355 * or directory is guaranteed not to change until it is either deleted or
1356 * marked to allow write access. Whether or not a read-only file or
1357 * directory may be deleted depends upon the underlying system.
1358 *
1359 * @return <code>true</code> if and only if the operation succeeded;
1360 * <code>false</code> otherwise
1361 *
1362 * @throws SecurityException
1363 * If a security manager exists and its <code>{@link
1364 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1365 * method denies write access to the named file
1366 *
1367 * @since 1.2
1368 */
1369 public boolean setReadOnly() {
1370 SecurityManager security = System.getSecurityManager();
1371 if (security != null) {
1372 security.checkWrite(path);
1373 }
1374 return fs.setReadOnly(this);
1375 }
1376
1377 /**
1378 * Sets the owner's or everybody's write permission for this abstract
1379 * pathname.
1380 *
1381 * <p> The {@link java.nio.file.Files} class defines methods that operate on
1382 * file attributes including file permissions. This may be used when finer
1383 * manipulation of file permissions is required.
1384 *
1385 * @param writable
1386 * If <code>true</code>, sets the access permission to allow write
1387 * operations; if <code>false</code> to disallow write operations
1388 *
1389 * @param ownerOnly
1390 * If <code>true</code>, the write permission applies only to the
1391 * owner's write permission; otherwise, it applies to everybody. If
1392 * the underlying file system can not distinguish the owner's write
1393 * permission from that of others, then the permission will apply to
1394 * everybody, regardless of this value.
1395 *
1396 * @return <code>true</code> if and only if the operation succeeded. The
1397 * operation will fail if the user does not have permission to change
1398 * the access permissions of this abstract pathname.
1399 *
1400 * @throws SecurityException
1401 * If a security manager exists and its <code>{@link
1402 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1403 * method denies write access to the named file
1404 *
1405 * @since 1.6
1406 */
1407 public boolean setWritable(boolean writable, boolean ownerOnly) {
1408 SecurityManager security = System.getSecurityManager();
1409 if (security != null) {
1410 security.checkWrite(path);
1411 }
1412 return fs.setPermission(this, FileSystem.ACCESS_WRITE, writable, ownerOnly);
1413 }
1414
1415 /**
1416 * A convenience method to set the owner's write permission for this abstract
1417 * pathname.
1418 *
1419 * <p> An invocation of this method of the form <tt>file.setWritable(arg)</tt>
1420 * behaves in exactly the same way as the invocation
1421 *
1422 * <pre>
1423 * file.setWritable(arg, true) </pre>
1424 *
1425 * @param writable
1426 * If <code>true</code>, sets the access permission to allow write
1427 * operations; if <code>false</code> to disallow write operations
1428 *
1429 * @return <code>true</code> if and only if the operation succeeded. The
1430 * operation will fail if the user does not have permission to
1431 * change the access permissions of this abstract pathname.
1432 *
1433 * @throws SecurityException
1434 * If a security manager exists and its <code>{@link
1435 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1436 * method denies write access to the file
1437 *
1438 * @since 1.6
1439 */
1440 public boolean setWritable(boolean writable) {
1441 return setWritable(writable, true);
1442 }
1443
1444 /**
1445 * Sets the owner's or everybody's read permission for this abstract
1446 * pathname.
1447 *
1448 * <p> The {@link java.nio.file.Files} class defines methods that operate on
1449 * file attributes including file permissions. This may be used when finer
1450 * manipulation of file permissions is required.
1451 *
1452 * @param readable
1453 * If <code>true</code>, sets the access permission to allow read
1454 * operations; if <code>false</code> to disallow read operations
1455 *
1456 * @param ownerOnly
1457 * If <code>true</code>, the read permission applies only to the
1458 * owner's read permission; otherwise, it applies to everybody. If
1459 * the underlying file system can not distinguish the owner's read
1460 * permission from that of others, then the permission will apply to
1461 * everybody, regardless of this value.
1462 *
1463 * @return <code>true</code> if and only if the operation succeeded. The
1464 * operation will fail if the user does not have permission to
1465 * change the access permissions of this abstract pathname. If
1466 * <code>readable</code> is <code>false</code> and the underlying
1467 * file system does not implement a read permission, then the
1468 * operation will fail.
1469 *
1470 * @throws SecurityException
1471 * If a security manager exists and its <code>{@link
1472 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1473 * method denies write access to the file
1474 *
1475 * @since 1.6
1476 */
1477 public boolean setReadable(boolean readable, boolean ownerOnly) {
1478 SecurityManager security = System.getSecurityManager();
1479 if (security != null) {
1480 security.checkWrite(path);
1481 }
1482 return fs.setPermission(this, FileSystem.ACCESS_READ, readable, ownerOnly);
1483 }
1484
1485 /**
1486 * A convenience method to set the owner's read permission for this abstract
1487 * pathname.
1488 *
1489 * <p>An invocation of this method of the form <tt>file.setReadable(arg)</tt>
1490 * behaves in exactly the same way as the invocation
1491 *
1492 * <pre>
1493 * file.setReadable(arg, true) </pre>
1494 *
1495 * @param readable
1496 * If <code>true</code>, sets the access permission to allow read
1497 * operations; if <code>false</code> to disallow read operations
1498 *
1499 * @return <code>true</code> if and only if the operation succeeded. The
1500 * operation will fail if the user does not have permission to
1501 * change the access permissions of this abstract pathname. If
1502 * <code>readable</code> is <code>false</code> and the underlying
1503 * file system does not implement a read permission, then the
1504 * operation will fail.
1505 *
1506 * @throws SecurityException
1507 * If a security manager exists and its <code>{@link
1508 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1509 * method denies write access to the file
1510 *
1511 * @since 1.6
1512 */
1513 public boolean setReadable(boolean readable) {
1514 return setReadable(readable, true);
1515 }
1516
1517 /**
1518 * Sets the owner's or everybody's execute permission for this abstract
1519 * pathname.
1520 *
1521 * <p> The {@link java.nio.file.Files} class defines methods that operate on
1522 * file attributes including file permissions. This may be used when finer
1523 * manipulation of file permissions is required.
1524 *
1525 * @param executable
1526 * If <code>true</code>, sets the access permission to allow execute
1527 * operations; if <code>false</code> to disallow execute operations
1528 *
1529 * @param ownerOnly
1530 * If <code>true</code>, the execute permission applies only to the
1531 * owner's execute permission; otherwise, it applies to everybody.
1532 * If the underlying file system can not distinguish the owner's
1533 * execute permission from that of others, then the permission will
1534 * apply to everybody, regardless of this value.
1535 *
1536 * @return <code>true</code> if and only if the operation succeeded. The
1537 * operation will fail if the user does not have permission to
1538 * change the access permissions of this abstract pathname. If
1539 * <code>executable</code> is <code>false</code> and the underlying
1540 * file system does not implement an execute permission, then the
1541 * operation will fail.
1542 *
1543 * @throws SecurityException
1544 * If a security manager exists and its <code>{@link
1545 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1546 * method denies write access to the file
1547 *
1548 * @since 1.6
1549 */
1550 public boolean setExecutable(boolean executable, boolean ownerOnly) {
1551 SecurityManager security = System.getSecurityManager();
1552 if (security != null) {
1553 security.checkWrite(path);
1554 }
1555 return fs.setPermission(this, FileSystem.ACCESS_EXECUTE, executable, ownerOnly);
1556 }
1557
1558 /**
1559 * A convenience method to set the owner's execute permission for this abstract
1560 * pathname.
1561 *
1562 * <p>An invocation of this method of the form <tt>file.setExcutable(arg)</tt>
1563 * behaves in exactly the same way as the invocation
1564 *
1565 * <pre>
1566 * file.setExecutable(arg, true) </pre>
1567 *
1568 * @param executable
1569 * If <code>true</code>, sets the access permission to allow execute
1570 * operations; if <code>false</code> to disallow execute operations
1571 *
1572 * @return <code>true</code> if and only if the operation succeeded. The
1573 * operation will fail if the user does not have permission to
1574 * change the access permissions of this abstract pathname. If
1575 * <code>executable</code> is <code>false</code> and the underlying
1576 * file system does not implement an excute permission, then the
1577 * operation will fail.
1578 *
1579 * @throws SecurityException
1580 * If a security manager exists and its <code>{@link
1581 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1582 * method denies write access to the file
1583 *
1584 * @since 1.6
1585 */
1586 public boolean setExecutable(boolean executable) {
1587 return setExecutable(executable, true);
1588 }
1589
1590 /**
1591 * Tests whether the application can execute the file denoted by this
1592 * abstract pathname.
1593 *
1594 * @return <code>true</code> if and only if the abstract pathname exists
1595 * <em>and</em> the application is allowed to execute the file
1596 *
1597 * @throws SecurityException
1598 * If a security manager exists and its <code>{@link
1599 * java.lang.SecurityManager#checkExec(java.lang.String)}</code>
1600 * method denies execute access to the file
1601 *
1602 * @since 1.6
1603 */
1604 public boolean canExecute() {
1605 SecurityManager security = System.getSecurityManager();
1606 if (security != null) {
1607 security.checkExec(path);
1608 }
1609 return fs.checkAccess(this, FileSystem.ACCESS_EXECUTE);
1610 }
1611
1612
1613 /* -- Filesystem interface -- */
1614
1615 /**
1616 * List the available filesystem roots.
1617 *
1618 * <p> A particular Java platform may support zero or more
1619 * hierarchically-organized file systems. Each file system has a
1620 * {@code root} directory from which all other files in that file system
1621 * can be reached. Windows platforms, for example, have a root directory
1622 * for each active drive; UNIX platforms have a single root directory,
1623 * namely {@code "/"}. The set of available filesystem roots is affected
1624 * by various system-level operations such as the insertion or ejection of
1625 * removable media and the disconnecting or unmounting of physical or
1626 * virtual disk drives.
1627 *
1628 * <p> This method returns an array of {@code File} objects that denote the
1629 * root directories of the available filesystem roots. It is guaranteed
1630 * that the canonical pathname of any file physically present on the local
1631 * machine will begin with one of the roots returned by this method.
1632 *
1633 * <p> The canonical pathname of a file that resides on some other machine
1634 * and is accessed via a remote-filesystem protocol such as SMB or NFS may
1635 * or may not begin with one of the roots returned by this method. If the
1636 * pathname of a remote file is syntactically indistinguishable from the
1637 * pathname of a local file then it will begin with one of the roots
1638 * returned by this method. Thus, for example, {@code File} objects
1639 * denoting the root directories of the mapped network drives of a Windows
1640 * platform will be returned by this method, while {@code File} objects
1641 * containing UNC pathnames will not be returned by this method.
1642 *
1643 * <p> Unlike most methods in this class, this method does not throw
1644 * security exceptions. If a security manager exists and its {@link
1645 * SecurityManager#checkRead(String)} method denies read access to a
1646 * particular root directory, then that directory will not appear in the
1647 * result.
1648 *
1649 * @return An array of {@code File} objects denoting the available
1650 * filesystem roots, or {@code null} if the set of roots could not
1651 * be determined. The array will be empty if there are no
1652 * filesystem roots.
1653 *
1654 * @since 1.2
1655 * @see java.nio.file.FileStore
1656 */
1657 public static File[] listRoots() {
1658 return fs.listRoots();
1659 }
1660
1661
1662 /* -- Disk usage -- */
1663
1664 /**
1665 * Returns the size of the partition <a href="#partName">named</a> by this
1666 * abstract pathname.
1667 *
1668 * @return The size, in bytes, of the partition or <tt>0L</tt> if this
1669 * abstract pathname does not name a partition
1670 *
1671 * @throws SecurityException
1672 * If a security manager has been installed and it denies
1673 * {@link RuntimePermission}<tt>("getFileSystemAttributes")</tt>
1674 * or its {@link SecurityManager#checkRead(String)} method denies
1675 * read access to the file named by this abstract pathname
1676 *
1677 * @since 1.6
1678 */
1679 public long getTotalSpace() {
1680 SecurityManager sm = System.getSecurityManager();
1681 if (sm != null) {
1682 sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
1683 sm.checkRead(path);
1684 }
1685 return fs.getSpace(this, FileSystem.SPACE_TOTAL);
1686 }
1687
1688 /**
1689 * Returns the number of unallocated bytes in the partition <a
1690 * href="#partName">named</a> by this abstract path name.
1691 *
1692 * <p> The returned number of unallocated bytes is a hint, but not
1693 * a guarantee, that it is possible to use most or any of these
1694 * bytes. The number of unallocated bytes is most likely to be
1695 * accurate immediately after this call. It is likely to be made
1696 * inaccurate by any external I/O operations including those made
1697 * on the system outside of this virtual machine. This method
1698 * makes no guarantee that write operations to this file system
1699 * will succeed.
1700 *
1701 * @return The number of unallocated bytes on the partition <tt>0L</tt>
1702 * if the abstract pathname does not name a partition. This
1703 * value will be less than or equal to the total file system size
1704 * returned by {@link #getTotalSpace}.
1705 *
1706 * @throws SecurityException
1707 * If a security manager has been installed and it denies
1708 * {@link RuntimePermission}<tt>("getFileSystemAttributes")</tt>
1709 * or its {@link SecurityManager#checkRead(String)} method denies
1710 * read access to the file named by this abstract pathname
1711 *
1712 * @since 1.6
1713 */
1714 public long getFreeSpace() {
1715 SecurityManager sm = System.getSecurityManager();
1716 if (sm != null) {
1717 sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
1718 sm.checkRead(path);
1719 }
1720 return fs.getSpace(this, FileSystem.SPACE_FREE);
1721 }
1722
1723 /**
1724 * Returns the number of bytes available to this virtual machine on the
1725 * partition <a href="#partName">named</a> by this abstract pathname. When
1726 * possible, this method checks for write permissions and other operating
1727 * system restrictions and will therefore usually provide a more accurate
1728 * estimate of how much new data can actually be written than {@link
1729 * #getFreeSpace}.
1730 *
1731 * <p> The returned number of available bytes is a hint, but not a
1732 * guarantee, that it is possible to use most or any of these bytes. The
1733 * number of unallocated bytes is most likely to be accurate immediately
1734 * after this call. It is likely to be made inaccurate by any external
1735 * I/O operations including those made on the system outside of this
1736 * virtual machine. This method makes no guarantee that write operations
1737 * to this file system will succeed.
1738 *
1739 * @return The number of available bytes on the partition or <tt>0L</tt>
1740 * if the abstract pathname does not name a partition. On
1741 * systems where this information is not available, this method
1742 * will be equivalent to a call to {@link #getFreeSpace}.
1743 *
1744 * @throws SecurityException
1745 * If a security manager has been installed and it denies
1746 * {@link RuntimePermission}<tt>("getFileSystemAttributes")</tt>
1747 * or its {@link SecurityManager#checkRead(String)} method denies
1748 * read access to the file named by this abstract pathname
1749 *
1750 * @since 1.6
1751 */
1752 public long getUsableSpace() {
1753 SecurityManager sm = System.getSecurityManager();
1754 if (sm != null) {
1755 sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
1756 sm.checkRead(path);
1757 }
1758 return fs.getSpace(this, FileSystem.SPACE_USABLE);
1759 }
1760
1761 /* -- Temporary files -- */
1762
1763 private static class TempDirectory {
1764 private TempDirectory() { }
1765
1766 // temporary directory location
1767 private static final File tmpdir = new File(fs.normalize(AccessController
1768 .doPrivileged(new GetPropertyAction("java.io.tmpdir"))));
1769 static File location() {
1770 return tmpdir;
1771 }
1772
1773 // file name generation
1774 private static final SecureRandom random = new SecureRandom();
1775 static File generateFile(String prefix, String suffix, File dir) {
1776 long n = random.nextLong();
1777 if (n == Long.MIN_VALUE) {
1778 n = 0; // corner case
1779 } else {
1780 n = Math.abs(n);
1781 }
1782 return new File(dir, prefix + Long.toString(n) + suffix);
1783 }
1784 }
1785
1786 /**
1787 * <p> Creates a new empty file in the specified directory, using the
1788 * given prefix and suffix strings to generate its name. If this method
1789 * returns successfully then it is guaranteed that:
1790 *
1791 * <ol>
1792 * <li> The file denoted by the returned abstract pathname did not exist
1793 * before this method was invoked, and
1794 * <li> Neither this method nor any of its variants will return the same
1795 * abstract pathname again in the current invocation of the virtual
1796 * machine.
1797 * </ol>
1798 *
1799 * This method provides only part of a temporary-file facility. To arrange
1800 * for a file created by this method to be deleted automatically, use the
1801 * <code>{@link #deleteOnExit}</code> method.
1802 *
1803 * <p> The <code>prefix</code> argument must be at least three characters
1804 * long. It is recommended that the prefix be a short, meaningful string
1805 * such as <code>"hjb"</code> or <code>"mail"</code>. The
1806 * <code>suffix</code> argument may be <code>null</code>, in which case the
1807 * suffix <code>".tmp"</code> will be used.
1808 *
1809 * <p> To create the new file, the prefix and the suffix may first be
1810 * adjusted to fit the limitations of the underlying platform. If the
1811 * prefix is too long then it will be truncated, but its first three
1812 * characters will always be preserved. If the suffix is too long then it
1813 * too will be truncated, but if it begins with a period character
1814 * (<code>'.'</code>) then the period and the first three characters
1815 * following it will always be preserved. Once these adjustments have been
1816 * made the name of the new file will be generated by concatenating the
1817 * prefix, five or more internally-generated characters, and the suffix.
1818 *
1819 * <p> If the <code>directory</code> argument is <code>null</code> then the
1820 * system-dependent default temporary-file directory will be used. The
1821 * default temporary-file directory is specified by the system property
1822 * <code>java.io.tmpdir</code>. On UNIX systems the default value of this
1823 * property is typically <code>"/tmp"</code> or <code>"/var/tmp"</code>; on
1824 * Microsoft Windows systems it is typically <code>"C:\\WINNT\\TEMP"</code>. A different
1825 * value may be given to this system property when the Java virtual machine
1826 * is invoked, but programmatic changes to this property are not guaranteed
1827 * to have any effect upon the temporary directory used by this method.
1828 *
1829 * @param prefix The prefix string to be used in generating the file's
1830 * name; must be at least three characters long
1831 *
1832 * @param suffix The suffix string to be used in generating the file's
1833 * name; may be <code>null</code>, in which case the
1834 * suffix <code>".tmp"</code> will be used
1835 *
1836 * @param directory The directory in which the file is to be created, or
1837 * <code>null</code> if the default temporary-file
1838 * directory is to be used
1839 *
1840 * @return An abstract pathname denoting a newly-created empty file
1841 *
1842 * @throws IllegalArgumentException
1843 * If the <code>prefix</code> argument contains fewer than three
1844 * characters
1845 *
1846 * @throws IOException If a file could not be created
1847 *
1848 * @throws SecurityException
1849 * If a security manager exists and its <code>{@link
1850 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1851 * method does not allow a file to be created
1852 *
1853 * @since 1.2
1854 */
1855 public static File createTempFile(String prefix, String suffix,
1856 File directory)
1857 throws IOException
1858 {
1859 if (prefix.length() < 3)
1860 throw new IllegalArgumentException("Prefix string too short");
1861 if (suffix == null)
1862 suffix = ".tmp";
1863
1864 File tmpdir = (directory != null) ? directory : TempDirectory.location();
1865 SecurityManager sm = System.getSecurityManager();
1866 File f;
1867 do {
1868 f = TempDirectory.generateFile(prefix, suffix, tmpdir);
1869 if (sm != null) {
1870 try {
1871 sm.checkWrite(f.getPath());
1872 } catch (SecurityException se) {
1873 // don't reveal temporary directory location
1874 if (directory == null)
1875 throw new SecurityException("Unable to create temporary file");
1876 throw se;
1877 }
1878 }
1879 } while (!fs.createFileExclusively(f.getPath()));
1880 return f;
1881 }
1882
1883 /**
1884 * Creates an empty file in the default temporary-file directory, using
1885 * the given prefix and suffix to generate its name. Invoking this method
1886 * is equivalent to invoking <code>{@link #createTempFile(java.lang.String,
1887 * java.lang.String, java.io.File)
1888 * createTempFile(prefix,&nbsp;suffix,&nbsp;null)}</code>.
1889 *
1890 * <p> The {@link
1891 * java.nio.file.Files#createTempFile(String,String,java.nio.file.attribute.FileAttribute[])
1892 * Files.createTempFile} method provides an alternative method to create an
1893 * empty file in the temporary-file directory. Files created by that method
1894 * may have more restrictive access permissions to files created by this
1895 * method and so may be more suited to security-sensitive applications.
1896 *
1897 * @param prefix The prefix string to be used in generating the file's
1898 * name; must be at least three characters long
1899 *
1900 * @param suffix The suffix string to be used in generating the file's
1901 * name; may be <code>null</code>, in which case the
1902 * suffix <code>".tmp"</code> will be used
1903 *
1904 * @return An abstract pathname denoting a newly-created empty file
1905 *
1906 * @throws IllegalArgumentException
1907 * If the <code>prefix</code> argument contains fewer than three
1908 * characters
1909 *
1910 * @throws IOException If a file could not be created
1911 *
1912 * @throws SecurityException
1913 * If a security manager exists and its <code>{@link
1914 * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
1915 * method does not allow a file to be created
1916 *
1917 * @since 1.2
1918 * @see java.nio.file.Files#createTempDirectory(String,FileAttribute[])
1919 */
1920 public static File createTempFile(String prefix, String suffix)
1921 throws IOException
1922 {
1923 return createTempFile(prefix, suffix, null);
1924 }
1925
1926 /* -- Basic infrastructure -- */
1927
1928 /**
1929 * Compares two abstract pathnames lexicographically. The ordering
1930 * defined by this method depends upon the underlying system. On UNIX
1931 * systems, alphabetic case is significant in comparing pathnames; on Microsoft Windows
1932 * systems it is not.
1933 *
1934 * @param pathname The abstract pathname to be compared to this abstract
1935 * pathname
1936 *
1937 * @return Zero if the argument is equal to this abstract pathname, a
1938 * value less than zero if this abstract pathname is
1939 * lexicographically less than the argument, or a value greater
1940 * than zero if this abstract pathname is lexicographically
1941 * greater than the argument
1942 *
1943 * @since 1.2
1944 */
1945 public int compareTo(File pathname) {
1946 return fs.compare(this, pathname);
1947 }
1948
1949 /**
1950 * Tests this abstract pathname for equality with the given object.
1951 * Returns <code>true</code> if and only if the argument is not
1952 * <code>null</code> and is an abstract pathname that denotes the same file
1953 * or directory as this abstract pathname. Whether or not two abstract
1954 * pathnames are equal depends upon the underlying system. On UNIX
1955 * systems, alphabetic case is significant in comparing pathnames; on Microsoft Windows
1956 * systems it is not.
1957 *
1958 * @param obj The object to be compared with this abstract pathname
1959 *
1960 * @return <code>true</code> if and only if the objects are the same;
1961 * <code>false</code> otherwise
1962 */
1963 public boolean equals(Object obj) {
1964 if ((obj != null) && (obj instanceof File)) {
1965 return compareTo((File)obj) == 0;
1966 }
1967 return false;
1968 }
1969
1970 /**
1971 * Computes a hash code for this abstract pathname. Because equality of
1972 * abstract pathnames is inherently system-dependent, so is the computation
1973 * of their hash codes. On UNIX systems, the hash code of an abstract
1974 * pathname is equal to the exclusive <em>or</em> of the hash code
1975 * of its pathname string and the decimal value
1976 * <code>1234321</code>. On Microsoft Windows systems, the hash
1977 * code is equal to the exclusive <em>or</em> of the hash code of
1978 * its pathname string converted to lower case and the decimal
1979 * value <code>1234321</code>. Locale is not taken into account on
1980 * lowercasing the pathname string.
1981 *
1982 * @return A hash code for this abstract pathname
1983 */
1984 public int hashCode() {
1985 return fs.hashCode(this);
1986 }
1987
1988 /**
1989 * Returns the pathname string of this abstract pathname. This is just the
1990 * string returned by the <code>{@link #getPath}</code> method.
1991 *
1992 * @return The string form of this abstract pathname
1993 */
1994 public String toString() {
1995 return getPath();
1996 }
1997
1998 /**
1999 * WriteObject is called to save this filename.
2000 * The separator character is saved also so it can be replaced
2001 * in case the path is reconstituted on a different host type.
2002 * <p>
2003 * @serialData Default fields followed by separator character.
2004 */
2005 private synchronized void writeObject(java.io.ObjectOutputStream s)
2006 throws IOException
2007 {
2008 s.defaultWriteObject();
2009 s.writeChar(this.separatorChar); // Add the separator character
2010 }
2011
2012 /**
2013 * readObject is called to restore this filename.
2014 * The original separator character is read. If it is different
2015 * than the separator character on this system, then the old separator
2016 * is replaced by the local separator.
2017 */
2018 private synchronized void readObject(java.io.ObjectInputStream s)
2019 throws IOException, ClassNotFoundException
2020 {
2021 ObjectInputStream.GetField fields = s.readFields();
2022 String pathField = (String)fields.get("path", null);
2023 char sep = s.readChar(); // read the previous separator char
2024 if (sep != separatorChar)
2025 pathField = pathField.replace(sep, separatorChar);
2026 this.path = fs.normalize(pathField);
2027 this.prefixLength = fs.prefixLength(this.path);
2028 }
2029
2030 /** use serialVersionUID from JDK 1.0.2 for interoperability */
2031 private static final long serialVersionUID = 301077366599181567L;
2032
2033 // -- Integration with java.nio.file --
2034
2035 private volatile transient Path filePath;
2036
2037 /**
2038 * Returns a {@link Path java.nio.file.Path} object constructed from the
2039 * this abstract path. The resulting {@code Path} is associated with the
2040 * {@link java.nio.file.FileSystems#getDefault default-filesystem}.
2041 *
2042 * <p> The first invocation of this method works as if invoking it were
2043 * equivalent to evaluating the expression:
2044 * <blockquote><pre>
2045 * {@link java.nio.file.FileSystems#getDefault FileSystems.getDefault}().{@link
2046 * java.nio.file.FileSystem#getPath getPath}(this.{@link #getPath getPath}());
2047 * </pre></blockquote>
2048 * Subsequent invocations of this method return the same {@code Path}.
2049 *
2050 * <p> If this abstract pathname is the empty abstract pathname then this
2051 * method returns a {@code Path} that may be used to access the current
2052 * user directory.
2053 *
2054 * @return a {@code Path} constructed from this abstract path
2055 *
2056 * @throws java.nio.file.InvalidPathException
2057 * if a {@code Path} object cannot be constructed from the abstract
2058 * path (see {@link java.nio.file.FileSystem#getPath FileSystem.getPath})
2059 *
2060 * @since 1.7
2061 * @see Path#toFile
2062 */
2063 public Path toPath() {
2064 Path result = filePath;
2065 if (result == null) {
2066 synchronized (this) {
2067 result = filePath;
2068 if (result == null) {
2069 result = FileSystems.getDefault().getPath(path);
2070 filePath = result;
2071 }
2072 }
2073 }
2074 return result;
2075 }
2076}
java/pkg/java/io/FileFilter.class+0−0

Binary file not shown.

java/pkg/java/io/FileFilter.java+50−0
@@ -0,0 +1,50 @@
1/*
2 * Copyright (c) 1998, 2002, 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
26package java.io;
27
28
29/**
30 * A filter for abstract pathnames.
31 *
32 * <p> Instances of this interface may be passed to the <code>{@link
33 * File#listFiles(java.io.FileFilter) listFiles(FileFilter)}</code> method
34 * of the <code>{@link java.io.File}</code> class.
35 *
36 * @since 1.2
37 */
38public interface FileFilter {
39
40 /**
41 * Tests whether or not the specified abstract pathname should be
42 * included in a pathname list.
43 *
44 * @param pathname The abstract pathname to be tested
45 * @return <code>true</code> if and only if <code>pathname</code>
46 * should be included
47 */
48 boolean accept(File pathname);
49
50}
java/pkg/java/io/FileInputStream.class+0−0

Binary file not shown.

java/pkg/java/io/FileInputStream.java+408−0
@@ -0,0 +1,408 @@
1/*
2 * Copyright (c) 1994, 2011, 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
26package java.io;
27
28import java.nio.channels.FileChannel;
29import sun.nio.ch.FileChannelImpl;
30
31
32/**
33 * A <code>FileInputStream</code> obtains input bytes
34 * from a file in a file system. What files
35 * are available depends on the host environment.
36 *
37 * <p><code>FileInputStream</code> is meant for reading streams of raw bytes
38 * such as image data. For reading streams of characters, consider using
39 * <code>FileReader</code>.
40 *
41 * @author Arthur van Hoff
42 * @see java.io.File
43 * @see java.io.FileDescriptor
44 * @see java.io.FileOutputStream
45 * @see java.nio.file.Files#newInputStream
46 * @since JDK1.0
47 */
48public
49class FileInputStream extends InputStream
50{
51 /* File Descriptor - handle to the open file */
52 private final FileDescriptor fd;
53
54 private FileChannel channel = null;
55
56 private final Object closeLock = new Object();
57 private volatile boolean closed = false;
58
59 private static final ThreadLocal<Boolean> runningFinalize =
60 new ThreadLocal<>();
61
62 private static boolean isRunningFinalize() {
63 Boolean val;
64 if ((val = runningFinalize.get()) != null)
65 return val.booleanValue();
66 return false;
67 }
68
69 /**
70 * Creates a <code>FileInputStream</code> by
71 * opening a connection to an actual file,
72 * the file named by the path name <code>name</code>
73 * in the file system. A new <code>FileDescriptor</code>
74 * object is created to represent this file
75 * connection.
76 * <p>
77 * First, if there is a security
78 * manager, its <code>checkRead</code> method
79 * is called with the <code>name</code> argument
80 * as its argument.
81 * <p>
82 * If the named file does not exist, is a directory rather than a regular
83 * file, or for some other reason cannot be opened for reading then a
84 * <code>FileNotFoundException</code> is thrown.
85 *
86 * @param name the system-dependent file name.
87 * @exception FileNotFoundException if the file does not exist,
88 * is a directory rather than a regular file,
89 * or for some other reason cannot be opened for
90 * reading.
91 * @exception SecurityException if a security manager exists and its
92 * <code>checkRead</code> method denies read access
93 * to the file.
94 * @see java.lang.SecurityManager#checkRead(java.lang.String)
95 */
96 public FileInputStream(String name) throws FileNotFoundException {
97 this(name != null ? new File(name) : null);
98 }
99
100 /**
101 * Creates a <code>FileInputStream</code> by
102 * opening a connection to an actual file,
103 * the file named by the <code>File</code>
104 * object <code>file</code> in the file system.
105 * A new <code>FileDescriptor</code> object
106 * is created to represent this file connection.
107 * <p>
108 * First, if there is a security manager,
109 * its <code>checkRead</code> method is called
110 * with the path represented by the <code>file</code>
111 * argument as its argument.
112 * <p>
113 * If the named file does not exist, is a directory rather than a regular
114 * file, or for some other reason cannot be opened for reading then a
115 * <code>FileNotFoundException</code> is thrown.
116 *
117 * @param file the file to be opened for reading.
118 * @exception FileNotFoundException if the file does not exist,
119 * is a directory rather than a regular file,
120 * or for some other reason cannot be opened for
121 * reading.
122 * @exception SecurityException if a security manager exists and its
123 * <code>checkRead</code> method denies read access to the file.
124 * @see java.io.File#getPath()
125 * @see java.lang.SecurityManager#checkRead(java.lang.String)
126 */
127 public FileInputStream(File file) throws FileNotFoundException {
128 String name = (file != null ? file.getPath() : null);
129 SecurityManager security = System.getSecurityManager();
130 if (security != null) {
131 security.checkRead(name);
132 }
133 if (name == null) {
134 throw new NullPointerException();
135 }
136 fd = new FileDescriptor();
137 fd.incrementAndGetUseCount();
138 open(name);
139 }
140
141 /**
142 * Creates a <code>FileInputStream</code> by using the file descriptor
143 * <code>fdObj</code>, which represents an existing connection to an
144 * actual file in the file system.
145 * <p>
146 * If there is a security manager, its <code>checkRead</code> method is
147 * called with the file descriptor <code>fdObj</code> as its argument to
148 * see if it's ok to read the file descriptor. If read access is denied
149 * to the file descriptor a <code>SecurityException</code> is thrown.
150 * <p>
151 * If <code>fdObj</code> is null then a <code>NullPointerException</code>
152 * is thrown.
153 * <p>
154 * This constructor does not throw an exception if <code>fdObj</code>
155 * is {@link java.io.FileDescriptor#valid() invalid}.
156 * However, if the methods are invoked on the resulting stream to attempt
157 * I/O on the stream, an <code>IOException</code> is thrown.
158 *
159 * @param fdObj the file descriptor to be opened for reading.
160 * @throws SecurityException if a security manager exists and its
161 * <code>checkRead</code> method denies read access to the
162 * file descriptor.
163 * @see SecurityManager#checkRead(java.io.FileDescriptor)
164 */
165 public FileInputStream(FileDescriptor fdObj) {
166 SecurityManager security = System.getSecurityManager();
167 if (fdObj == null) {
168 throw new NullPointerException();
169 }
170 if (security != null) {
171 security.checkRead(fdObj);
172 }
173 fd = fdObj;
174
175 /*
176 * FileDescriptor is being shared by streams.
177 * Ensure that it's GC'ed only when all the streams/channels are done
178 * using it.
179 */
180 fd.incrementAndGetUseCount();
181 }
182
183 /**
184 * Opens the specified file for reading.
185 * @param name the name of the file
186 */
187 private native void open(String name) throws FileNotFoundException;
188
189 /**
190 * Reads a byte of data from this input stream. This method blocks
191 * if no input is yet available.
192 *
193 * @return the next byte of data, or <code>-1</code> if the end of the
194 * file is reached.
195 * @exception IOException if an I/O error occurs.
196 */
197 public native int read() throws IOException;
198
199 /**
200 * Reads a subarray as a sequence of bytes.
201 * @param b the data to be written
202 * @param off the start offset in the data
203 * @param len the number of bytes that are written
204 * @exception IOException If an I/O error has occurred.
205 */
206 private native int readBytes(byte b[], int off, int len) throws IOException;
207
208 /**
209 * Reads up to <code>b.length</code> bytes of data from this input
210 * stream into an array of bytes. This method blocks until some input
211 * is available.
212 *
213 * @param b the buffer into which the data is read.
214 * @return the total number of bytes read into the buffer, or
215 * <code>-1</code> if there is no more data because the end of
216 * the file has been reached.
217 * @exception IOException if an I/O error occurs.
218 */
219 public int read(byte b[]) throws IOException {
220 return readBytes(b, 0, b.length);
221 }
222
223 /**
224 * Reads up to <code>len</code> bytes of data from this input stream
225 * into an array of bytes. If <code>len</code> is not zero, the method
226 * blocks until some input is available; otherwise, no
227 * bytes are read and <code>0</code> is returned.
228 *
229 * @param b the buffer into which the data is read.
230 * @param off the start offset in the destination array <code>b</code>
231 * @param len the maximum number of bytes read.
232 * @return the total number of bytes read into the buffer, or
233 * <code>-1</code> if there is no more data because the end of
234 * the file has been reached.
235 * @exception NullPointerException If <code>b</code> is <code>null</code>.
236 * @exception IndexOutOfBoundsException If <code>off</code> is negative,
237 * <code>len</code> is negative, or <code>len</code> is greater than
238 * <code>b.length - off</code>
239 * @exception IOException if an I/O error occurs.
240 */
241 public int read(byte b[], int off, int len) throws IOException {
242 return readBytes(b, off, len);
243 }
244
245 /**
246 * Skips over and discards <code>n</code> bytes of data from the
247 * input stream.
248 *
249 * <p>The <code>skip</code> method may, for a variety of
250 * reasons, end up skipping over some smaller number of bytes,
251 * possibly <code>0</code>. If <code>n</code> is negative, an
252 * <code>IOException</code> is thrown, even though the <code>skip</code>
253 * method of the {@link InputStream} superclass does nothing in this case.
254 * The actual number of bytes skipped is returned.
255 *
256 * <p>This method may skip more bytes than are remaining in the backing
257 * file. This produces no exception and the number of bytes skipped
258 * may include some number of bytes that were beyond the EOF of the
259 * backing file. Attempting to read from the stream after skipping past
260 * the end will result in -1 indicating the end of the file.
261 *
262 * @param n the number of bytes to be skipped.
263 * @return the actual number of bytes skipped.
264 * @exception IOException if n is negative, if the stream does not
265 * support seek, or if an I/O error occurs.
266 */
267 public native long skip(long n) throws IOException;
268
269 /**
270 * Returns an estimate of the number of remaining bytes that can be read (or
271 * skipped over) from this input stream without blocking by the next
272 * invocation of a method for this input stream. The next invocation might be
273 * the same thread or another thread. A single read or skip of this
274 * many bytes will not block, but may read or skip fewer bytes.
275 *
276 * <p> In some cases, a non-blocking read (or skip) may appear to be
277 * blocked when it is merely slow, for example when reading large
278 * files over slow networks.
279 *
280 * @return an estimate of the number of remaining bytes that can be read
281 * (or skipped over) from this input stream without blocking.
282 * @exception IOException if this file input stream has been closed by calling
283 * {@code close} or an I/O error occurs.
284 */
285 public native int available() throws IOException;
286
287 /**
288 * Closes this file input stream and releases any system resources
289 * associated with the stream.
290 *
291 * <p> If this stream has an associated channel then the channel is closed
292 * as well.
293 *
294 * @exception IOException if an I/O error occurs.
295 *
296 * @revised 1.4
297 * @spec JSR-51
298 */
299 public void close() throws IOException {
300 synchronized (closeLock) {
301 if (closed) {
302 return;
303 }
304 closed = true;
305 }
306 if (channel != null) {
307 /*
308 * Decrement the FD use count associated with the channel
309 * The use count is incremented whenever a new channel
310 * is obtained from this stream.
311 */
312 fd.decrementAndGetUseCount();
313 channel.close();
314 }
315
316 /*
317 * Decrement the FD use count associated with this stream
318 */
319 int useCount = fd.decrementAndGetUseCount();
320
321 /*
322 * If FileDescriptor is still in use by another stream, the finalizer
323 * will not close it.
324 */
325 if ((useCount <= 0) || !isRunningFinalize()) {
326 close0();
327 }
328 }
329
330 /**
331 * Returns the <code>FileDescriptor</code>
332 * object that represents the connection to
333 * the actual file in the file system being
334 * used by this <code>FileInputStream</code>.
335 *
336 * @return the file descriptor object associated with this stream.
337 * @exception IOException if an I/O error occurs.
338 * @see java.io.FileDescriptor
339 */
340 public final FileDescriptor getFD() throws IOException {
341 if (fd != null) return fd;
342 throw new IOException();
343 }
344
345 /**
346 * Returns the unique {@link java.nio.channels.FileChannel FileChannel}
347 * object associated with this file input stream.
348 *
349 * <p> The initial {@link java.nio.channels.FileChannel#position()
350 * </code>position<code>} of the returned channel will be equal to the
351 * number of bytes read from the file so far. Reading bytes from this
352 * stream will increment the channel's position. Changing the channel's
353 * position, either explicitly or by reading, will change this stream's
354 * file position.
355 *
356 * @return the file channel associated with this file input stream
357 *
358 * @since 1.4
359 * @spec JSR-51
360 */
361 public FileChannel getChannel() {
362 synchronized (this) {
363 if (channel == null) {
364 channel = FileChannelImpl.open(fd, true, false, this);
365
366 /*
367 * Increment fd's use count. Invoking the channel's close()
368 * method will result in decrementing the use count set for
369 * the channel.
370 */
371 fd.incrementAndGetUseCount();
372 }
373 return channel;
374 }
375 }
376
377 private static native void initIDs();
378
379 private native void close0() throws IOException;
380
381 static {
382 initIDs();
383 }
384
385 /**
386 * Ensures that the <code>close</code> method of this file input stream is
387 * called when there are no more references to it.
388 *
389 * @exception IOException if an I/O error occurs.
390 * @see java.io.FileInputStream#close()
391 */
392 protected void finalize() throws IOException {
393 if ((fd != null) && (fd != FileDescriptor.in)) {
394
395 /*
396 * Finalizer should not release the FileDescriptor if another
397 * stream is still using it. If the user directly invokes
398 * close() then the FileDescriptor is also released.
399 */
400 runningFinalize.set(Boolean.TRUE);
401 try {
402 close();
403 } finally {
404 runningFinalize.set(Boolean.FALSE);
405 }
406 }
407 }
408}
java/pkg/java/io/FileNotFoundException.class+0−0

Binary file not shown.

java/pkg/java/io/FileNotFoundException.java+82−0
@@ -0,0 +1,82 @@
1/*
2 * Copyright (c) 1994, 2008, 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
26package java.io;
27
28
29/**
30 * Signals that an attempt to open the file denoted by a specified pathname
31 * has failed.
32 *
33 * <p> This exception will be thrown by the {@link FileInputStream}, {@link
34 * FileOutputStream}, and {@link RandomAccessFile} constructors when a file
35 * with the specified pathname does not exist. It will also be thrown by these
36 * constructors if the file does exist but for some reason is inaccessible, for
37 * example when an attempt is made to open a read-only file for writing.
38 *
39 * @author unascribed
40 * @since JDK1.0
41 */
42
43public class FileNotFoundException extends IOException {
44 private static final long serialVersionUID = -897856973823710492L;
45
46 /**
47 * Constructs a <code>FileNotFoundException</code> with
48 * <code>null</code> as its error detail message.
49 */
50 public FileNotFoundException() {
51 super();
52 }
53
54 /**
55 * Constructs a <code>FileNotFoundException</code> with the
56 * specified detail message. The string <code>s</code> can be
57 * retrieved later by the
58 * <code>{@link java.lang.Throwable#getMessage}</code>
59 * method of class <code>java.lang.Throwable</code>.
60 *
61 * @param s the detail message.
62 */
63 public FileNotFoundException(String s) {
64 super(s);
65 }
66
67 /**
68 * Constructs a <code>FileNotFoundException</code> with a detail message
69 * consisting of the given pathname string followed by the given reason
70 * string. If the <code>reason</code> argument is <code>null</code> then
71 * it will be omitted. This private constructor is invoked only by native
72 * I/O methods.
73 *
74 * @since 1.2
75 */
76 private FileNotFoundException(String path, String reason) {
77 super(path + ((reason == null)
78 ? ""
79 : " (" + reason + ")"));
80 }
81
82}
java/pkg/java/io/FileOutputStream.class+0−0

Binary file not shown.

java/pkg/java/io/FileOutputStream.java+451−0
@@ -0,0 +1,451 @@
1/*
2 * Copyright (c) 1994, 2011, 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
26package java.io;
27
28import java.nio.channels.FileChannel;
29import sun.nio.ch.FileChannelImpl;
30
31
32/**
33 * A file output stream is an output stream for writing data to a
34 * <code>File</code> or to a <code>FileDescriptor</code>. Whether or not
35 * a file is available or may be created depends upon the underlying
36 * platform. Some platforms, in particular, allow a file to be opened
37 * for writing by only one <tt>FileOutputStream</tt> (or other
38 * file-writing object) at a time. In such situations the constructors in
39 * this class will fail if the file involved is already open.
40 *
41 * <p><code>FileOutputStream</code> is meant for writing streams of raw bytes
42 * such as image data. For writing streams of characters, consider using
43 * <code>FileWriter</code>.
44 *
45 * @author Arthur van Hoff
46 * @see java.io.File
47 * @see java.io.FileDescriptor
48 * @see java.io.FileInputStream
49 * @see java.nio.file.Files#newOutputStream
50 * @since JDK1.0
51 */
52public
53class FileOutputStream extends OutputStream
54{
55 /**
56 * The system dependent file descriptor.
57 */
58 private final FileDescriptor fd;
59
60 /**
61 * True if the file is opened for append.
62 */
63 private final boolean append;
64
65 /**
66 * The associated channel, initalized lazily.
67 */
68 private FileChannel channel;
69
70 private final Object closeLock = new Object();
71 private volatile boolean closed = false;
72 private static final ThreadLocal<Boolean> runningFinalize =
73 new ThreadLocal<>();
74
75 private static boolean isRunningFinalize() {
76 Boolean val;
77 if ((val = runningFinalize.get()) != null)
78 return val.booleanValue();
79 return false;
80 }
81
82 /**
83 * Creates a file output stream to write to the file with the
84 * specified name. A new <code>FileDescriptor</code> object is
85 * created to represent this file connection.
86 * <p>
87 * First, if there is a security manager, its <code>checkWrite</code>
88 * method is called with <code>name</code> as its argument.
89 * <p>
90 * If the file exists but is a directory rather than a regular file, does
91 * not exist but cannot be created, or cannot be opened for any other
92 * reason then a <code>FileNotFoundException</code> is thrown.
93 *
94 * @param name the system-dependent filename
95 * @exception FileNotFoundException if the file exists but is a directory
96 * rather than a regular file, does not exist but cannot
97 * be created, or cannot be opened for any other reason
98 * @exception SecurityException if a security manager exists and its
99 * <code>checkWrite</code> method denies write access
100 * to the file.
101 * @see java.lang.SecurityManager#checkWrite(java.lang.String)
102 */
103 public FileOutputStream(String name) throws FileNotFoundException {
104 this(name != null ? new File(name) : null, false);
105 }
106
107 /**
108 * Creates a file output stream to write to the file with the specified
109 * name. If the second argument is <code>true</code>, then
110 * bytes will be written to the end of the file rather than the beginning.
111 * A new <code>FileDescriptor</code> object is created to represent this
112 * file connection.
113 * <p>
114 * First, if there is a security manager, its <code>checkWrite</code>
115 * method is called with <code>name</code> as its argument.
116 * <p>
117 * If the file exists but is a directory rather than a regular file, does
118 * not exist but cannot be created, or cannot be opened for any other
119 * reason then a <code>FileNotFoundException</code> is thrown.
120 *
121 * @param name the system-dependent file name
122 * @param append if <code>true</code>, then bytes will be written
123 * to the end of the file rather than the beginning
124 * @exception FileNotFoundException if the file exists but is a directory
125 * rather than a regular file, does not exist but cannot
126 * be created, or cannot be opened for any other reason.
127 * @exception SecurityException if a security manager exists and its
128 * <code>checkWrite</code> method denies write access
129 * to the file.
130 * @see java.lang.SecurityManager#checkWrite(java.lang.String)
131 * @since JDK1.1
132 */
133 public FileOutputStream(String name, boolean append)
134 throws FileNotFoundException
135 {
136 this(name != null ? new File(name) : null, append);
137 }
138
139 /**
140 * Creates a file output stream to write to the file represented by
141 * the specified <code>File</code> object. A new
142 * <code>FileDescriptor</code> object is created to represent this
143 * file connection.
144 * <p>
145 * First, if there is a security manager, its <code>checkWrite</code>
146 * method is called with the path represented by the <code>file</code>
147 * argument as its argument.
148 * <p>
149 * If the file exists but is a directory rather than a regular file, does
150 * not exist but cannot be created, or cannot be opened for any other
151 * reason then a <code>FileNotFoundException</code> is thrown.
152 *
153 * @param file the file to be opened for writing.
154 * @exception FileNotFoundException if the file exists but is a directory
155 * rather than a regular file, does not exist but cannot
156 * be created, or cannot be opened for any other reason
157 * @exception SecurityException if a security manager exists and its
158 * <code>checkWrite</code> method denies write access
159 * to the file.
160 * @see java.io.File#getPath()
161 * @see java.lang.SecurityException
162 * @see java.lang.SecurityManager#checkWrite(java.lang.String)
163 */
164 public FileOutputStream(File file) throws FileNotFoundException {
165 this(file, false);
166 }
167
168 /**
169 * Creates a file output stream to write to the file represented by
170 * the specified <code>File</code> object. If the second argument is
171 * <code>true</code>, then bytes will be written to the end of the file
172 * rather than the beginning. A new <code>FileDescriptor</code> object is
173 * created to represent this file connection.
174 * <p>
175 * First, if there is a security manager, its <code>checkWrite</code>
176 * method is called with the path represented by the <code>file</code>
177 * argument as its argument.
178 * <p>
179 * If the file exists but is a directory rather than a regular file, does
180 * not exist but cannot be created, or cannot be opened for any other
181 * reason then a <code>FileNotFoundException</code> is thrown.
182 *
183 * @param file the file to be opened for writing.
184 * @param append if <code>true</code>, then bytes will be written
185 * to the end of the file rather than the beginning
186 * @exception FileNotFoundException if the file exists but is a directory
187 * rather than a regular file, does not exist but cannot
188 * be created, or cannot be opened for any other reason
189 * @exception SecurityException if a security manager exists and its
190 * <code>checkWrite</code> method denies write access
191 * to the file.
192 * @see java.io.File#getPath()
193 * @see java.lang.SecurityException
194 * @see java.lang.SecurityManager#checkWrite(java.lang.String)
195 * @since 1.4
196 */
197 public FileOutputStream(File file, boolean append)
198 throws FileNotFoundException
199 {
200 String name = (file != null ? file.getPath() : null);
201 SecurityManager security = System.getSecurityManager();
202 if (security != null) {
203 security.checkWrite(name);
204 }
205 if (name == null) {
206 throw new NullPointerException();
207 }
208 this.fd = new FileDescriptor();
209 this.append = append;
210
211 fd.incrementAndGetUseCount();
212 open(name, append);
213 }
214
215 /**
216 * Creates a file output stream to write to the specified file
217 * descriptor, which represents an existing connection to an actual
218 * file in the file system.
219 * <p>
220 * First, if there is a security manager, its <code>checkWrite</code>
221 * method is called with the file descriptor <code>fdObj</code>
222 * argument as its argument.
223 * <p>
224 * If <code>fdObj</code> is null then a <code>NullPointerException</code>
225 * is thrown.
226 * <p>
227 * This constructor does not throw an exception if <code>fdObj</code>
228 * is {@link java.io.FileDescriptor#valid() invalid}.
229 * However, if the methods are invoked on the resulting stream to attempt
230 * I/O on the stream, an <code>IOException</code> is thrown.
231 *
232 * @param fdObj the file descriptor to be opened for writing
233 * @exception SecurityException if a security manager exists and its
234 * <code>checkWrite</code> method denies
235 * write access to the file descriptor
236 * @see java.lang.SecurityManager#checkWrite(java.io.FileDescriptor)
237 */
238 public FileOutputStream(FileDescriptor fdObj) {
239 SecurityManager security = System.getSecurityManager();
240 if (fdObj == null) {
241 throw new NullPointerException();
242 }
243 if (security != null) {
244 security.checkWrite(fdObj);
245 }
246 this.fd = fdObj;
247 this.append = false;
248
249 /*
250 * FileDescriptor is being shared by streams.
251 * Ensure that it's GC'ed only when all the streams/channels are done
252 * using it.
253 */
254 fd.incrementAndGetUseCount();
255 }
256
257 /**
258 * Opens a file, with the specified name, for overwriting or appending.
259 * @param name name of file to be opened
260 * @param append whether the file is to be opened in append mode
261 */
262 private native void open(String name, boolean append)
263 throws FileNotFoundException;
264
265 /**
266 * Writes the specified byte to this file output stream.
267 *
268 * @param b the byte to be written.
269 * @param append {@code true} if the write operation first
270 * advances the position to the end of file
271 */
272 private native void write(int b, boolean append) throws IOException;
273
274 /**
275 * Writes the specified byte to this file output stream. Implements
276 * the <code>write</code> method of <code>OutputStream</code>.
277 *
278 * @param b the byte to be written.
279 * @exception IOException if an I/O error occurs.
280 */
281 public void write(int b) throws IOException {
282 write(b, append);
283 }
284
285 /**
286 * Writes a sub array as a sequence of bytes.
287 * @param b the data to be written
288 * @param off the start offset in the data
289 * @param len the number of bytes that are written
290 * @param append {@code true} to first advance the position to the
291 * end of file
292 * @exception IOException If an I/O error has occurred.
293 */
294 private native void writeBytes(byte b[], int off, int len, boolean append)
295 throws IOException;
296
297 /**
298 * Writes <code>b.length</code> bytes from the specified byte array
299 * to this file output stream.
300 *
301 * @param b the data.
302 * @exception IOException if an I/O error occurs.
303 */
304 public void write(byte b[]) throws IOException {
305 writeBytes(b, 0, b.length, append);
306 }
307
308 /**
309 * Writes <code>len</code> bytes from the specified byte array
310 * starting at offset <code>off</code> to this file output stream.
311 *
312 * @param b the data.
313 * @param off the start offset in the data.
314 * @param len the number of bytes to write.
315 * @exception IOException if an I/O error occurs.
316 */
317 public void write(byte b[], int off, int len) throws IOException {
318 writeBytes(b, off, len, append);
319 }
320
321 /**
322 * Closes this file output stream and releases any system resources
323 * associated with this stream. This file output stream may no longer
324 * be used for writing bytes.
325 *
326 * <p> If this stream has an associated channel then the channel is closed
327 * as well.
328 *
329 * @exception IOException if an I/O error occurs.
330 *
331 * @revised 1.4
332 * @spec JSR-51
333 */
334 public void close() throws IOException {
335 synchronized (closeLock) {
336 if (closed) {
337 return;
338 }
339 closed = true;
340 }
341
342 if (channel != null) {
343 /*
344 * Decrement FD use count associated with the channel
345 * The use count is incremented whenever a new channel
346 * is obtained from this stream.
347 */
348 fd.decrementAndGetUseCount();
349 channel.close();
350 }
351
352 /*
353 * Decrement FD use count associated with this stream
354 */
355 int useCount = fd.decrementAndGetUseCount();
356
357 /*
358 * If FileDescriptor is still in use by another stream, the finalizer
359 * will not close it.
360 */
361 if ((useCount <= 0) || !isRunningFinalize()) {
362 close0();
363 }
364 }
365
366 /**
367 * Returns the file descriptor associated with this stream.
368 *
369 * @return the <code>FileDescriptor</code> object that represents
370 * the connection to the file in the file system being used
371 * by this <code>FileOutputStream</code> object.
372 *
373 * @exception IOException if an I/O error occurs.
374 * @see java.io.FileDescriptor
375 */
376 public final FileDescriptor getFD() throws IOException {
377 if (fd != null) return fd;
378 throw new IOException();
379 }
380
381 /**
382 * Returns the unique {@link java.nio.channels.FileChannel FileChannel}
383 * object associated with this file output stream. </p>
384 *
385 * <p> The initial {@link java.nio.channels.FileChannel#position()
386 * </code>position<code>} of the returned channel will be equal to the
387 * number of bytes written to the file so far unless this stream is in
388 * append mode, in which case it will be equal to the size of the file.
389 * Writing bytes to this stream will increment the channel's position
390 * accordingly. Changing the channel's position, either explicitly or by
391 * writing, will change this stream's file position.
392 *
393 * @return the file channel associated with this file output stream
394 *
395 * @since 1.4
396 * @spec JSR-51
397 */
398 public FileChannel getChannel() {
399 synchronized (this) {
400 if (channel == null) {
401 channel = FileChannelImpl.open(fd, false, true, append, this);
402
403 /*
404 * Increment fd's use count. Invoking the channel's close()
405 * method will result in decrementing the use count set for
406 * the channel.
407 */
408 fd.incrementAndGetUseCount();
409 }
410 return channel;
411 }
412 }
413
414 /**
415 * Cleans up the connection to the file, and ensures that the
416 * <code>close</code> method of this file output stream is
417 * called when there are no more references to this stream.
418 *
419 * @exception IOException if an I/O error occurs.
420 * @see java.io.FileInputStream#close()
421 */
422 protected void finalize() throws IOException {
423 if (fd != null) {
424 if (fd == FileDescriptor.out || fd == FileDescriptor.err) {
425 flush();
426 } else {
427
428 /*
429 * Finalizer should not release the FileDescriptor if another
430 * stream is still using it. If the user directly invokes
431 * close() then the FileDescriptor is also released.
432 */
433 runningFinalize.set(Boolean.TRUE);
434 try {
435 close();
436 } finally {
437 runningFinalize.set(Boolean.FALSE);
438 }
439 }
440 }
441 }
442
443 private native void close0() throws IOException;
444
445 private static native void initIDs();
446
447 static {
448 initIDs();
449 }
450
451}
java/pkg/java/io/FilePermission$1.class+0−0

Binary file not shown.

java/pkg/java/io/FilePermission.class+0−0

Binary file not shown.

java/pkg/java/io/FilePermission.java+859−0
@@ -0,0 +1,859 @@
1/*
2 * Copyright (c) 1997, 2011, 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
26package java.io;
27
28import java.security.*;
29import java.util.Enumeration;
30import java.util.List;
31import java.util.ArrayList;
32import java.util.Vector;
33import java.util.Collections;
34import java.io.ObjectStreamField;
35import java.io.ObjectOutputStream;
36import java.io.ObjectInputStream;
37import java.io.IOException;
38import sun.security.util.SecurityConstants;
39
40/**
41 * This class represents access to a file or directory. A FilePermission consists
42 * of a pathname and a set of actions valid for that pathname.
43 * <P>
44 * Pathname is the pathname of the file or directory granted the specified
45 * actions. A pathname that ends in "/*" (where "/" is
46 * the file separator character, <code>File.separatorChar</code>) indicates
47 * all the files and directories contained in that directory. A pathname
48 * that ends with "/-" indicates (recursively) all files
49 * and subdirectories contained in that directory. A pathname consisting of
50 * the special token "&lt;&lt;ALL FILES&gt;&gt;" matches <b>any</b> file.
51 * <P>
52 * Note: A pathname consisting of a single "*" indicates all the files
53 * in the current directory, while a pathname consisting of a single "-"
54 * indicates all the files in the current directory and
55 * (recursively) all files and subdirectories contained in the current
56 * directory.
57 * <P>
58 * The actions to be granted are passed to the constructor in a string containing
59 * a list of one or more comma-separated keywords. The possible keywords are
60 * "read", "write", "execute", "delete", and "readlink". Their meaning is
61 * defined as follows:
62 * <P>
63 * <DL>
64 * <DT> read <DD> read permission
65 * <DT> write <DD> write permission
66 * <DT> execute
67 * <DD> execute permission. Allows <code>Runtime.exec</code> to
68 * be called. Corresponds to <code>SecurityManager.checkExec</code>.
69 * <DT> delete
70 * <DD> delete permission. Allows <code>File.delete</code> to
71 * be called. Corresponds to <code>SecurityManager.checkDelete</code>.
72 * <DT> readlink
73 * <DD> read link permission. Allows the target of a
74 * <a href="../nio/file/package-summary.html#links">symbolic link</a>
75 * to be read by invoking the {@link java.nio.file.Files#readSymbolicLink
76 * readSymbolicLink } method.
77 * </DL>
78 * <P>
79 * The actions string is converted to lowercase before processing.
80 * <P>
81 * Be careful when granting FilePermissions. Think about the implications
82 * of granting read and especially write access to various files and
83 * directories. The "&lt;&lt;ALL FILES>>" permission with write action is
84 * especially dangerous. This grants permission to write to the entire
85 * file system. One thing this effectively allows is replacement of the
86 * system binary, including the JVM runtime environment.
87 *
88 * <p>Please note: Code can always read a file from the same
89 * directory it's in (or a subdirectory of that directory); it does not
90 * need explicit permission to do so.
91 *
92 * @see java.security.Permission
93 * @see java.security.Permissions
94 * @see java.security.PermissionCollection
95 *
96 *
97 * @author Marianne Mueller
98 * @author Roland Schemers
99 * @since 1.2
100 *
101 * @serial exclude
102 */
103
104public final class FilePermission extends Permission implements Serializable {
105
106 /**
107 * Execute action.
108 */
109 private final static int EXECUTE = 0x1;
110 /**
111 * Write action.
112 */
113 private final static int WRITE = 0x2;
114 /**
115 * Read action.
116 */
117 private final static int READ = 0x4;
118 /**
119 * Delete action.
120 */
121 private final static int DELETE = 0x8;
122 /**
123 * Read link action.
124 */
125 private final static int READLINK = 0x10;
126
127 /**
128 * All actions (read,write,execute,delete,readlink)
129 */
130 private final static int ALL = READ|WRITE|EXECUTE|DELETE|READLINK;
131 /**
132 * No actions.
133 */
134 private final static int NONE = 0x0;
135
136 // the actions mask
137 private transient int mask;
138
139 // does path indicate a directory? (wildcard or recursive)
140 private transient boolean directory;
141
142 // is it a recursive directory specification?
143 private transient boolean recursive;
144
145 /**
146 * the actions string.
147 *
148 * @serial
149 */
150 private String actions; // Left null as long as possible, then
151 // created and re-used in the getAction function.
152
153 // canonicalized dir path. In the case of
154 // directories, it is the name "/blah/*" or "/blah/-" without
155 // the last character (the "*" or "-").
156
157 private transient String cpath;
158
159 // static Strings used by init(int mask)
160 private static final char RECURSIVE_CHAR = '-';
161 private static final char WILD_CHAR = '*';
162
163/*
164 public String toString()
165 {
166 StringBuffer sb = new StringBuffer();
167 sb.append("***\n");
168 sb.append("cpath = "+cpath+"\n");
169 sb.append("mask = "+mask+"\n");
170 sb.append("actions = "+getActions()+"\n");
171 sb.append("directory = "+directory+"\n");
172 sb.append("recursive = "+recursive+"\n");
173 sb.append("***\n");
174 return sb.toString();
175 }
176*/
177
178 private static final long serialVersionUID = 7930732926638008763L;
179
180 /**
181 * initialize a FilePermission object. Common to all constructors.
182 * Also called during de-serialization.
183 *
184 * @param mask the actions mask to use.
185 *
186 */
187 private void init(int mask)
188 {
189
190 if ((mask & ALL) != mask)
191 throw new IllegalArgumentException("invalid actions mask");
192
193 if (mask == NONE)
194 throw new IllegalArgumentException("invalid actions mask");
195
196 if ((cpath = getName()) == null)
197 throw new NullPointerException("name can't be null");
198
199 this.mask = mask;
200
201 if (cpath.equals("<<ALL FILES>>")) {
202 directory = true;
203 recursive = true;
204 cpath = "";
205 return;
206 }
207
208 // store only the canonical cpath if possible
209 cpath = AccessController.doPrivileged(new PrivilegedAction<String>() {
210 public String run() {
211 try {
212 String path = cpath;
213 if (cpath.endsWith("*")) {
214 // call getCanonicalPath with a path with wildcard character
215 // replaced to avoid calling it with paths that are
216 // intended to match all entries in a directory
217 path = path.substring(0, path.length()-1) + "-";
218 path = new File(path).getCanonicalPath();
219 return path.substring(0, path.length()-1) + "*";
220 } else {
221 return new File(path).getCanonicalPath();
222 }
223 } catch (IOException ioe) {
224 return cpath;
225 }
226 }
227 });
228
229 int len = cpath.length();
230 char last = ((len > 0) ? cpath.charAt(len - 1) : 0);
231
232 if (last == RECURSIVE_CHAR &&
233 cpath.charAt(len - 2) == File.separatorChar) {
234 directory = true;
235 recursive = true;
236 cpath = cpath.substring(0, --len);
237 } else if (last == WILD_CHAR &&
238 cpath.charAt(len - 2) == File.separatorChar) {
239 directory = true;
240 //recursive = false;
241 cpath = cpath.substring(0, --len);
242 } else {
243 // overkill since they are initialized to false, but
244 // commented out here to remind us...
245 //directory = false;
246 //recursive = false;
247 }
248
249 // XXX: at this point the path should be absolute. die if it isn't?
250 }
251
252 /**
253 * Creates a new FilePermission object with the specified actions.
254 * <i>path</i> is the pathname of a file or directory, and <i>actions</i>
255 * contains a comma-separated list of the desired actions granted on the
256 * file or directory. Possible actions are
257 * "read", "write", "execute", "delete", and "readlink".
258 *
259 * <p>A pathname that ends in "/*" (where "/" is
260 * the file separator character, <code>File.separatorChar</code>)
261 * indicates all the files and directories contained in that directory.
262 * A pathname that ends with "/-" indicates (recursively) all files and
263 * subdirectories contained in that directory. The special pathname
264 * "&lt;&lt;ALL FILES&gt;&gt;" matches any file.
265 *
266 * <p>A pathname consisting of a single "*" indicates all the files
267 * in the current directory, while a pathname consisting of a single "-"
268 * indicates all the files in the current directory and
269 * (recursively) all files and subdirectories contained in the current
270 * directory.
271 *
272 * <p>A pathname containing an empty string represents an empty path.
273 *
274 * @param path the pathname of the file/directory.
275 * @param actions the action string.
276 *
277 * @throws IllegalArgumentException
278 * If actions is <code>null</code>, empty or contains an action
279 * other than the specified possible actions.
280 */
281
282 public FilePermission(String path, String actions)
283 {
284 super(path);
285 init(getMask(actions));
286 }
287
288 /**
289 * Creates a new FilePermission object using an action mask.
290 * More efficient than the FilePermission(String, String) constructor.
291 * Can be used from within
292 * code that needs to create a FilePermission object to pass into the
293 * <code>implies</code> method.
294 *
295 * @param path the pathname of the file/directory.
296 * @param mask the action mask to use.
297 */
298
299 // package private for use by the FilePermissionCollection add method
300 FilePermission(String path, int mask)
301 {
302 super(path);
303 init(mask);
304 }
305
306 /**
307 * Checks if this FilePermission object "implies" the specified permission.
308 * <P>
309 * More specifically, this method returns true if:<p>
310 * <ul>
311 * <li> <i>p</i> is an instanceof FilePermission,<p>
312 * <li> <i>p</i>'s actions are a proper subset of this
313 * object's actions, and <p>
314 * <li> <i>p</i>'s pathname is implied by this object's
315 * pathname. For example, "/tmp/*" implies "/tmp/foo", since
316 * "/tmp/*" encompasses all files in the "/tmp" directory,
317 * including the one named "foo".
318 * </ul>
319 *
320 * @param p the permission to check against.
321 *
322 * @return <code>true</code> if the specified permission is not
323 * <code>null</code> and is implied by this object,
324 * <code>false</code> otherwise.
325 */
326 public boolean implies(Permission p) {
327 if (!(p instanceof FilePermission))
328 return false;
329
330 FilePermission that = (FilePermission) p;
331
332 // we get the effective mask. i.e., the "and" of this and that.
333 // They must be equal to that.mask for implies to return true.
334
335 return ((this.mask & that.mask) == that.mask) && impliesIgnoreMask(that);
336 }
337
338 /**
339 * Checks if the Permission's actions are a proper subset of the
340 * this object's actions. Returns the effective mask iff the
341 * this FilePermission's path also implies that FilePermission's path.
342 *
343 * @param that the FilePermission to check against.
344 * @param exact return immediately if the masks are not equal
345 * @return the effective mask
346 */
347 boolean impliesIgnoreMask(FilePermission that) {
348 if (this.directory) {
349 if (this.recursive) {
350 // make sure that.path is longer then path so
351 // something like /foo/- does not imply /foo
352 if (that.directory) {
353 return (that.cpath.length() >= this.cpath.length()) &&
354 that.cpath.startsWith(this.cpath);
355 } else {
356 return ((that.cpath.length() > this.cpath.length()) &&
357 that.cpath.startsWith(this.cpath));
358 }
359 } else {
360 if (that.directory) {
361 // if the permission passed in is a directory
362 // specification, make sure that a non-recursive
363 // permission (i.e., this object) can't imply a recursive
364 // permission.
365 if (that.recursive)
366 return false;
367 else
368 return (this.cpath.equals(that.cpath));
369 } else {
370 int last = that.cpath.lastIndexOf(File.separatorChar);
371 if (last == -1)
372 return false;
373 else {
374 // this.cpath.equals(that.cpath.substring(0, last+1));
375 // Use regionMatches to avoid creating new string
376 return (this.cpath.length() == (last + 1)) &&
377 this.cpath.regionMatches(0, that.cpath, 0, last+1);
378 }
379 }
380 }
381 } else if (that.directory) {
382 // if this is NOT recursive/wildcarded,
383 // do not let it imply a recursive/wildcarded permission
384 return false;
385 } else {
386 return (this.cpath.equals(that.cpath));
387 }
388 }
389
390 /**
391 * Checks two FilePermission objects for equality. Checks that <i>obj</i> is
392 * a FilePermission, and has the same pathname and actions as this object.
393 * <P>
394 * @param obj the object we are testing for equality with this object.
395 * @return <code>true</code> if obj is a FilePermission, and has the same
396 * pathname and actions as this FilePermission object,
397 * <code>false</code> otherwise.
398 */
399 public boolean equals(Object obj) {
400 if (obj == this)
401 return true;
402
403 if (! (obj instanceof FilePermission))
404 return false;
405
406 FilePermission that = (FilePermission) obj;
407
408 return (this.mask == that.mask) &&
409 this.cpath.equals(that.cpath) &&
410 (this.directory == that.directory) &&
411 (this.recursive == that.recursive);
412 }
413
414 /**
415 * Returns the hash code value for this object.
416 *
417 * @return a hash code value for this object.
418 */
419
420 public int hashCode() {
421 return this.cpath.hashCode();
422 }
423
424 /**
425 * Converts an actions String to an actions mask.
426 *
427 * @param action the action string.
428 * @return the actions mask.
429 */
430 private static int getMask(String actions) {
431
432 int mask = NONE;
433
434 // Null action valid?
435 if (actions == null) {
436 return mask;
437 }
438 // Check against use of constants (used heavily within the JDK)
439 if (actions == SecurityConstants.FILE_READ_ACTION) {
440 return READ;
441 } else if (actions == SecurityConstants.FILE_WRITE_ACTION) {
442 return WRITE;
443 } else if (actions == SecurityConstants.FILE_EXECUTE_ACTION) {
444 return EXECUTE;
445 } else if (actions == SecurityConstants.FILE_DELETE_ACTION) {
446 return DELETE;
447 } else if (actions == SecurityConstants.FILE_READLINK_ACTION) {
448 return READLINK;
449 }
450
451 char[] a = actions.toCharArray();
452
453 int i = a.length - 1;
454 if (i < 0)
455 return mask;
456
457 while (i != -1) {
458 char c;
459
460 // skip whitespace
461 while ((i!=-1) && ((c = a[i]) == ' ' ||
462 c == '\r' ||
463 c == '\n' ||
464 c == '\f' ||
465 c == '\t'))
466 i--;
467
468 // check for the known strings
469 int matchlen;
470
471 if (i >= 3 && (a[i-3] == 'r' || a[i-3] == 'R') &&
472 (a[i-2] == 'e' || a[i-2] == 'E') &&
473 (a[i-1] == 'a' || a[i-1] == 'A') &&
474 (a[i] == 'd' || a[i] == 'D'))
475 {
476 matchlen = 4;
477 mask |= READ;
478
479 } else if (i >= 4 && (a[i-4] == 'w' || a[i-4] == 'W') &&
480 (a[i-3] == 'r' || a[i-3] == 'R') &&
481 (a[i-2] == 'i' || a[i-2] == 'I') &&
482 (a[i-1] == 't' || a[i-1] == 'T') &&
483 (a[i] == 'e' || a[i] == 'E'))
484 {
485 matchlen = 5;
486 mask |= WRITE;
487
488 } else if (i >= 6 && (a[i-6] == 'e' || a[i-6] == 'E') &&
489 (a[i-5] == 'x' || a[i-5] == 'X') &&
490 (a[i-4] == 'e' || a[i-4] == 'E') &&
491 (a[i-3] == 'c' || a[i-3] == 'C') &&
492 (a[i-2] == 'u' || a[i-2] == 'U') &&
493 (a[i-1] == 't' || a[i-1] == 'T') &&
494 (a[i] == 'e' || a[i] == 'E'))
495 {
496 matchlen = 7;
497 mask |= EXECUTE;
498
499 } else if (i >= 5 && (a[i-5] == 'd' || a[i-5] == 'D') &&
500 (a[i-4] == 'e' || a[i-4] == 'E') &&
501 (a[i-3] == 'l' || a[i-3] == 'L') &&
502 (a[i-2] == 'e' || a[i-2] == 'E') &&
503 (a[i-1] == 't' || a[i-1] == 'T') &&
504 (a[i] == 'e' || a[i] == 'E'))
505 {
506 matchlen = 6;
507 mask |= DELETE;
508
509 } else if (i >= 7 && (a[i-7] == 'r' || a[i-7] == 'R') &&
510 (a[i-6] == 'e' || a[i-6] == 'E') &&
511 (a[i-5] == 'a' || a[i-5] == 'A') &&
512 (a[i-4] == 'd' || a[i-4] == 'D') &&
513 (a[i-3] == 'l' || a[i-3] == 'L') &&
514 (a[i-2] == 'i' || a[i-2] == 'I') &&
515 (a[i-1] == 'n' || a[i-1] == 'N') &&
516 (a[i] == 'k' || a[i] == 'K'))
517 {
518 matchlen = 8;
519 mask |= READLINK;
520
521 } else {
522 // parse error
523 throw new IllegalArgumentException(
524 "invalid permission: " + actions);
525 }
526
527 // make sure we didn't just match the tail of a word
528 // like "ackbarfaccept". Also, skip to the comma.
529 boolean seencomma = false;
530 while (i >= matchlen && !seencomma) {
531 switch(a[i-matchlen]) {
532 case ',':
533 seencomma = true;
534 /*FALLTHROUGH*/
535 case ' ': case '\r': case '\n':
536 case '\f': case '\t':
537 break;
538 default:
539 throw new IllegalArgumentException(
540 "invalid permission: " + actions);
541 }
542 i--;
543 }
544
545 // point i at the location of the comma minus one (or -1).
546 i -= matchlen;
547 }
548
549 return mask;
550 }
551
552 /**
553 * Return the current action mask. Used by the FilePermissionCollection.
554 *
555 * @return the actions mask.
556 */
557
558 int getMask() {
559 return mask;
560 }
561
562 /**
563 * Return the canonical string representation of the actions.
564 * Always returns present actions in the following order:
565 * read, write, execute, delete, readlink.
566 *
567 * @return the canonical string representation of the actions.
568 */
569 private static String getActions(int mask)
570 {
571 StringBuilder sb = new StringBuilder();
572 boolean comma = false;
573
574 if ((mask & READ) == READ) {
575 comma = true;
576 sb.append("read");
577 }
578
579 if ((mask & WRITE) == WRITE) {
580 if (comma) sb.append(',');
581 else comma = true;
582 sb.append("write");
583 }
584
585 if ((mask & EXECUTE) == EXECUTE) {
586 if (comma) sb.append(',');
587 else comma = true;
588 sb.append("execute");
589 }
590
591 if ((mask & DELETE) == DELETE) {
592 if (comma) sb.append(',');
593 else comma = true;
594 sb.append("delete");
595 }
596
597 if ((mask & READLINK) == READLINK) {
598 if (comma) sb.append(',');
599 else comma = true;
600 sb.append("readlink");
601 }
602
603 return sb.toString();
604 }
605
606 /**
607 * Returns the "canonical string representation" of the actions.
608 * That is, this method always returns present actions in the following order:
609 * read, write, execute, delete, readlink. For example, if this FilePermission
610 * object allows both write and read actions, a call to <code>getActions</code>
611 * will return the string "read,write".
612 *
613 * @return the canonical string representation of the actions.
614 */
615 public String getActions()
616 {
617 if (actions == null)
618 actions = getActions(this.mask);
619
620 return actions;
621 }
622
623
624 /**
625 * Returns a new PermissionCollection object for storing FilePermission
626 * objects.
627 * <p>
628 * FilePermission objects must be stored in a manner that allows them
629 * to be inserted into the collection in any order, but that also enables the
630 * PermissionCollection <code>implies</code>
631 * method to be implemented in an efficient (and consistent) manner.
632 *
633 * <p>For example, if you have two FilePermissions:
634 * <OL>
635 * <LI> <code>"/tmp/-", "read"</code>
636 * <LI> <code>"/tmp/scratch/foo", "write"</code>
637 * </OL>
638 *
639 * <p>and you are calling the <code>implies</code> method with the FilePermission:
640 *
641 * <pre>
642 * "/tmp/scratch/foo", "read,write",
643 * </pre>
644 *
645 * then the <code>implies</code> function must
646 * take into account both the "/tmp/-" and "/tmp/scratch/foo"
647 * permissions, so the effective permission is "read,write",
648 * and <code>implies</code> returns true. The "implies" semantics for
649 * FilePermissions are handled properly by the PermissionCollection object
650 * returned by this <code>newPermissionCollection</code> method.
651 *
652 * @return a new PermissionCollection object suitable for storing
653 * FilePermissions.
654 */
655
656 public PermissionCollection newPermissionCollection() {
657 return new FilePermissionCollection();
658 }
659
660 /**
661 * WriteObject is called to save the state of the FilePermission
662 * to a stream. The actions are serialized, and the superclass
663 * takes care of the name.
664 */
665 private void writeObject(ObjectOutputStream s)
666 throws IOException
667 {
668 // Write out the actions. The superclass takes care of the name
669 // call getActions to make sure actions field is initialized
670 if (actions == null)
671 getActions();
672 s.defaultWriteObject();
673 }
674
675 /**
676 * readObject is called to restore the state of the FilePermission from
677 * a stream.
678 */
679 private void readObject(ObjectInputStream s)
680 throws IOException, ClassNotFoundException
681 {
682 // Read in the actions, then restore everything else by calling init.
683 s.defaultReadObject();
684 init(getMask(actions));
685 }
686}
687
688/**
689 * A FilePermissionCollection stores a set of FilePermission permissions.
690 * FilePermission objects
691 * must be stored in a manner that allows them to be inserted in any
692 * order, but enable the implies function to evaluate the implies
693 * method.
694 * For example, if you have two FilePermissions:
695 * <OL>
696 * <LI> "/tmp/-", "read"
697 * <LI> "/tmp/scratch/foo", "write"
698 * </OL>
699 * And you are calling the implies function with the FilePermission:
700 * "/tmp/scratch/foo", "read,write", then the implies function must
701 * take into account both the /tmp/- and /tmp/scratch/foo
702 * permissions, so the effective permission is "read,write".
703 *
704 * @see java.security.Permission
705 * @see java.security.Permissions
706 * @see java.security.PermissionCollection
707 *
708 *
709 * @author Marianne Mueller
710 * @author Roland Schemers
711 *
712 * @serial include
713 *
714 */
715
716final class FilePermissionCollection extends PermissionCollection
717implements Serializable {
718
719 // Not serialized; see serialization section at end of class
720 private transient List<Permission> perms;
721
722 /**
723 * Create an empty FilePermissions object.
724 *
725 */
726
727 public FilePermissionCollection() {
728 perms = new ArrayList<>();
729 }
730
731 /**
732 * Adds a permission to the FilePermissions. The key for the hash is
733 * permission.path.
734 *
735 * @param permission the Permission object to add.
736 *
737 * @exception IllegalArgumentException - if the permission is not a
738 * FilePermission
739 *
740 * @exception SecurityException - if this FilePermissionCollection object
741 * has been marked readonly
742 */
743
744 public void add(Permission permission)
745 {
746 if (! (permission instanceof FilePermission))
747 throw new IllegalArgumentException("invalid permission: "+
748 permission);
749 if (isReadOnly())
750 throw new SecurityException(
751 "attempt to add a Permission to a readonly PermissionCollection");
752
753 synchronized (this) {
754 perms.add(permission);
755 }
756 }
757
758 /**
759 * Check and see if this set of permissions implies the permissions
760 * expressed in "permission".
761 *
762 * @param p the Permission object to compare
763 *
764 * @return true if "permission" is a proper subset of a permission in
765 * the set, false if not.
766 */
767
768 public boolean implies(Permission permission)
769 {
770 if (! (permission instanceof FilePermission))
771 return false;
772
773 FilePermission fp = (FilePermission) permission;
774
775 int desired = fp.getMask();
776 int effective = 0;
777 int needed = desired;
778
779 synchronized (this) {
780 int len = perms.size();
781 for (int i = 0; i < len; i++) {
782 FilePermission x = (FilePermission) perms.get(i);
783 if (((needed & x.getMask()) != 0) && x.impliesIgnoreMask(fp)) {
784 effective |= x.getMask();
785 if ((effective & desired) == desired)
786 return true;
787 needed = (desired ^ effective);
788 }
789 }
790 }
791 return false;
792 }
793
794 /**
795 * Returns an enumeration of all the FilePermission objects in the
796 * container.
797 *
798 * @return an enumeration of all the FilePermission objects.
799 */
800
801 public Enumeration elements() {
802 // Convert Iterator into Enumeration
803 synchronized (this) {
804 return Collections.enumeration(perms);
805 }
806 }
807
808 private static final long serialVersionUID = 2202956749081564585L;
809
810 // Need to maintain serialization interoperability with earlier releases,
811 // which had the serializable field:
812 // private Vector permissions;
813
814 /**
815 * @serialField permissions java.util.Vector
816 * A list of FilePermission objects.
817 */
818 private static final ObjectStreamField[] serialPersistentFields = {
819 new ObjectStreamField("permissions", Vector.class),
820 };
821
822 /**
823 * @serialData "permissions" field (a Vector containing the FilePermissions).
824 */
825 /*
826 * Writes the contents of the perms field out as a Vector for
827 * serialization compatibility with earlier releases.
828 */
829 private void writeObject(ObjectOutputStream out) throws IOException {
830 // Don't call out.defaultWriteObject()
831
832 // Write out Vector
833 Vector<Permission> permissions = new Vector<>(perms.size());
834 synchronized (this) {
835 permissions.addAll(perms);
836 }
837
838 ObjectOutputStream.PutField pfields = out.putFields();
839 pfields.put("permissions", permissions);
840 out.writeFields();
841 }
842
843 /*
844 * Reads in a Vector of FilePermissions and saves them in the perms field.
845 */
846 @SuppressWarnings("unchecked")
847 private void readObject(ObjectInputStream in) throws IOException,
848 ClassNotFoundException {
849 // Don't call defaultReadObject()
850
851 // Read in serialized fields
852 ObjectInputStream.GetField gfields = in.readFields();
853
854 // Get the one we want
855 Vector<Permission> permissions = (Vector<Permission>)gfields.get("permissions", null);
856 perms = new ArrayList<>(permissions.size());
857 perms.addAll(permissions);
858 }
859}
java/pkg/java/io/FilePermissionCollection.class+0−0

Binary file not shown.

java/pkg/java/io/FileReader.class+0−0

Binary file not shown.

java/pkg/java/io/FileReader.java+85−0
@@ -0,0 +1,85 @@
1/*
2 * Copyright (c) 1996, 2001, 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
26package java.io;
27
28
29/**
30 * Convenience class for reading character files. The constructors of this
31 * class assume that the default character encoding and the default byte-buffer
32 * size are appropriate. To specify these values yourself, construct an
33 * InputStreamReader on a FileInputStream.
34 *
35 * <p><code>FileReader</code> is meant for reading streams of characters.
36 * For reading streams of raw bytes, consider using a
37 * <code>FileInputStream</code>.
38 *
39 * @see InputStreamReader
40 * @see FileInputStream
41 *
42 * @author Mark Reinhold
43 * @since JDK1.1
44 */
45public class FileReader extends InputStreamReader {
46
47 /**
48 * Creates a new <tt>FileReader</tt>, given the name of the
49 * file to read from.
50 *
51 * @param fileName the name of the file to read from
52 * @exception FileNotFoundException if the named file does not exist,
53 * is a directory rather than a regular file,
54 * or for some other reason cannot be opened for
55 * reading.
56 */
57 public FileReader(String fileName) throws FileNotFoundException {
58 super(new FileInputStream(fileName));
59 }
60
61 /**
62 * Creates a new <tt>FileReader</tt>, given the <tt>File</tt>
63 * to read from.
64 *
65 * @param file the <tt>File</tt> to read from
66 * @exception FileNotFoundException if the file does not exist,
67 * is a directory rather than a regular file,
68 * or for some other reason cannot be opened for
69 * reading.
70 */
71 public FileReader(File file) throws FileNotFoundException {
72 super(new FileInputStream(file));
73 }
74
75 /**
76 * Creates a new <tt>FileReader</tt>, given the
77 * <tt>FileDescriptor</tt> to read from.
78 *
79 * @param fd the FileDescriptor to read from
80 */
81 public FileReader(FileDescriptor fd) {
82 super(new FileInputStream(fd));
83 }
84
85}
java/pkg/java/io/FileSystem.class+0−0

Binary file not shown.

java/pkg/java/io/FileSystem.java+252−0
@@ -0,0 +1,252 @@
1/*
2 * Copyright (c) 1998, 2005, 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
26package java.io;
27
28
29/**
30 * Package-private abstract class for the local filesystem abstraction.
31 */
32
33abstract class FileSystem {
34
35 /**
36 * Return the FileSystem object representing this platform's local
37 * filesystem.
38 */
39 public static native FileSystem getFileSystem();
40
41
42 /* -- Normalization and construction -- */
43
44 /**
45 * Return the local filesystem's name-separator character.
46 */
47 public abstract char getSeparator();
48
49 /**
50 * Return the local filesystem's path-separator character.
51 */
52 public abstract char getPathSeparator();
53
54 /**
55 * Convert the given pathname string to normal form. If the string is
56 * already in normal form then it is simply returned.
57 */
58 public abstract String normalize(String path);
59
60 /**
61 * Compute the length of this pathname string's prefix. The pathname
62 * string must be in normal form.
63 */
64 public abstract int prefixLength(String path);
65
66 /**
67 * Resolve the child pathname string against the parent.
68 * Both strings must be in normal form, and the result
69 * will be in normal form.
70 */
71 public abstract String resolve(String parent, String child);
72
73 /**
74 * Return the parent pathname string to be used when the parent-directory
75 * argument in one of the two-argument File constructors is the empty
76 * pathname.
77 */
78 public abstract String getDefaultParent();
79
80 /**
81 * Post-process the given URI path string if necessary. This is used on
82 * win32, e.g., to transform "/c:/foo" into "c:/foo". The path string
83 * still has slash separators; code in the File class will translate them
84 * after this method returns.
85 */
86 public abstract String fromURIPath(String path);
87
88
89 /* -- Path operations -- */
90
91 /**
92 * Tell whether or not the given abstract pathname is absolute.
93 */
94 public abstract boolean isAbsolute(File f);
95
96 /**
97 * Resolve the given abstract pathname into absolute form. Invoked by the
98 * getAbsolutePath and getCanonicalPath methods in the File class.
99 */
100 public abstract String resolve(File f);
101
102 public abstract String canonicalize(String path) throws IOException;
103
104
105 /* -- Attribute accessors -- */
106
107 /* Constants for simple boolean attributes */
108 public static final int BA_EXISTS = 0x01;
109 public static final int BA_REGULAR = 0x02;
110 public static final int BA_DIRECTORY = 0x04;
111 public static final int BA_HIDDEN = 0x08;
112
113 /**
114 * Return the simple boolean attributes for the file or directory denoted
115 * by the given abstract pathname, or zero if it does not exist or some
116 * other I/O error occurs.
117 */
118 public abstract int getBooleanAttributes(File f);
119
120 public static final int ACCESS_READ = 0x04;
121 public static final int ACCESS_WRITE = 0x02;
122 public static final int ACCESS_EXECUTE = 0x01;
123
124 /**
125 * Check whether the file or directory denoted by the given abstract
126 * pathname may be accessed by this process. The second argument specifies
127 * which access, ACCESS_READ, ACCESS_WRITE or ACCESS_EXECUTE, to check.
128 * Return false if access is denied or an I/O error occurs
129 */
130 public abstract boolean checkAccess(File f, int access);
131 /**
132 * Set on or off the access permission (to owner only or to all) to the file
133 * or directory denoted by the given abstract pathname, based on the parameters
134 * enable, access and oweronly.
135 */
136 public abstract boolean setPermission(File f, int access, boolean enable, boolean owneronly);
137
138 /**
139 * Return the time at which the file or directory denoted by the given
140 * abstract pathname was last modified, or zero if it does not exist or
141 * some other I/O error occurs.
142 */
143 public abstract long getLastModifiedTime(File f);
144
145 /**
146 * Return the length in bytes of the file denoted by the given abstract
147 * pathname, or zero if it does not exist, is a directory, or some other
148 * I/O error occurs.
149 */
150 public abstract long getLength(File f);
151
152
153 /* -- File operations -- */
154
155 /**
156 * Create a new empty file with the given pathname. Return
157 * <code>true</code> if the file was created and <code>false</code> if a
158 * file or directory with the given pathname already exists. Throw an
159 * IOException if an I/O error occurs.
160 */
161 public abstract boolean createFileExclusively(String pathname)
162 throws IOException;
163
164 /**
165 * Delete the file or directory denoted by the given abstract pathname,
166 * returning <code>true</code> if and only if the operation succeeds.
167 */
168 public abstract boolean delete(File f);
169
170 /**
171 * List the elements of the directory denoted by the given abstract
172 * pathname. Return an array of strings naming the elements of the
173 * directory if successful; otherwise, return <code>null</code>.
174 */
175 public abstract String[] list(File f);
176
177 /**
178 * Create a new directory denoted by the given abstract pathname,
179 * returning <code>true</code> if and only if the operation succeeds.
180 */
181 public abstract boolean createDirectory(File f);
182
183 /**
184 * Rename the file or directory denoted by the first abstract pathname to
185 * the second abstract pathname, returning <code>true</code> if and only if
186 * the operation succeeds.
187 */
188 public abstract boolean rename(File f1, File f2);
189
190 /**
191 * Set the last-modified time of the file or directory denoted by the
192 * given abstract pathname, returning <code>true</code> if and only if the
193 * operation succeeds.
194 */
195 public abstract boolean setLastModifiedTime(File f, long time);
196
197 /**
198 * Mark the file or directory denoted by the given abstract pathname as
199 * read-only, returning <code>true</code> if and only if the operation
200 * succeeds.
201 */
202 public abstract boolean setReadOnly(File f);
203
204
205 /* -- Filesystem interface -- */
206
207 /**
208 * List the available filesystem roots.
209 */
210 public abstract File[] listRoots();
211
212 /* -- Disk usage -- */
213 public static final int SPACE_TOTAL = 0;
214 public static final int SPACE_FREE = 1;
215 public static final int SPACE_USABLE = 2;
216
217 public abstract long getSpace(File f, int t);
218
219 /* -- Basic infrastructure -- */
220
221 /**
222 * Compare two abstract pathnames lexicographically.
223 */
224 public abstract int compare(File f1, File f2);
225
226 /**
227 * Compute the hash code of an abstract pathname.
228 */
229 public abstract int hashCode(File f);
230
231 // Flags for enabling/disabling performance optimizations for file
232 // name canonicalization
233 static boolean useCanonCaches = true;
234 static boolean useCanonPrefixCache = true;
235
236 private static boolean getBooleanProperty(String prop, boolean defaultVal) {
237 String val = System.getProperty(prop);
238 if (val == null) return defaultVal;
239 if (val.equalsIgnoreCase("true")) {
240 return true;
241 } else {
242 return false;
243 }
244 }
245
246 static {
247 useCanonCaches = getBooleanProperty("sun.io.useCanonCaches",
248 useCanonCaches);
249 useCanonPrefixCache = getBooleanProperty("sun.io.useCanonPrefixCache",
250 useCanonPrefixCache);
251 }
252}
java/pkg/java/io/FileWriter.class+0−0

Binary file not shown.

java/pkg/java/io/FileWriter.java+119−0
@@ -0,0 +1,119 @@
1/*
2 * Copyright (c) 1996, 2001, 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
26package java.io;
27
28
29/**
30 * Convenience class for writing character files. The constructors of this
31 * class assume that the default character encoding and the default byte-buffer
32 * size are acceptable. To specify these values yourself, construct an
33 * OutputStreamWriter on a FileOutputStream.
34 *
35 * <p>Whether or not a file is available or may be created depends upon the
36 * underlying platform. Some platforms, in particular, allow a file to be
37 * opened for writing by only one <tt>FileWriter</tt> (or other file-writing
38 * object) at a time. In such situations the constructors in this class
39 * will fail if the file involved is already open.
40 *
41 * <p><code>FileWriter</code> is meant for writing streams of characters.
42 * For writing streams of raw bytes, consider using a
43 * <code>FileOutputStream</code>.
44 *
45 * @see OutputStreamWriter
46 * @see FileOutputStream
47 *
48 * @author Mark Reinhold
49 * @since JDK1.1
50 */
51
52public class FileWriter extends OutputStreamWriter {
53
54 /**
55 * Constructs a FileWriter object given a file name.
56 *
57 * @param fileName String The system-dependent filename.
58 * @throws IOException if the named file exists but is a directory rather
59 * than a regular file, does not exist but cannot be
60 * created, or cannot be opened for any other reason
61 */
62 public FileWriter(String fileName) throws IOException {
63 super(new FileOutputStream(fileName));
64 }
65
66 /**
67 * Constructs a FileWriter object given a file name with a boolean
68 * indicating whether or not to append the data written.
69 *
70 * @param fileName String The system-dependent filename.
71 * @param append boolean if <code>true</code>, then data will be written
72 * to the end of the file rather than the beginning.
73 * @throws IOException if the named file exists but is a directory rather
74 * than a regular file, does not exist but cannot be
75 * created, or cannot be opened for any other reason
76 */
77 public FileWriter(String fileName, boolean append) throws IOException {
78 super(new FileOutputStream(fileName, append));
79 }
80
81 /**
82 * Constructs a FileWriter object given a File object.
83 *
84 * @param file a File object to write to.
85 * @throws IOException if the file exists but is a directory rather than
86 * a regular file, does not exist but cannot be created,
87 * or cannot be opened for any other reason
88 */
89 public FileWriter(File file) throws IOException {
90 super(new FileOutputStream(file));
91 }
92
93 /**
94 * Constructs a FileWriter object given a File object. If the second
95 * argument is <code>true</code>, then bytes will be written to the end
96 * of the file rather than the beginning.
97 *
98 * @param file a File object to write to
99 * @param append if <code>true</code>, then bytes will be written
100 * to the end of the file rather than the beginning
101 * @throws IOException if the file exists but is a directory rather than
102 * a regular file, does not exist but cannot be created,
103 * or cannot be opened for any other reason
104 * @since 1.4
105 */
106 public FileWriter(File file, boolean append) throws IOException {
107 super(new FileOutputStream(file, append));
108 }
109
110 /**
111 * Constructs a FileWriter object associated with a file descriptor.
112 *
113 * @param fd FileDescriptor object to write to.
114 */
115 public FileWriter(FileDescriptor fd) {
116 super(new FileOutputStream(fd));
117 }
118
119}
java/pkg/java/io/FilenameFilter.class+0−0

Binary file not shown.

java/pkg/java/io/FilenameFilter.java+53−0
@@ -0,0 +1,53 @@
1/*
2 * Copyright (c) 1994, 1998, 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
26package java.io;
27
28/**
29 * Instances of classes that implement this interface are used to
30 * filter filenames. These instances are used to filter directory
31 * listings in the <code>list</code> method of class
32 * <code>File</code>, and by the Abstract Window Toolkit's file
33 * dialog component.
34 *
35 * @author Arthur van Hoff
36 * @author Jonathan Payne
37 * @see java.awt.FileDialog#setFilenameFilter(java.io.FilenameFilter)
38 * @see java.io.File
39 * @see java.io.File#list(java.io.FilenameFilter)
40 * @since JDK1.0
41 */
42public
43interface FilenameFilter {
44 /**
45 * Tests if a specified file should be included in a file list.
46 *
47 * @param dir the directory in which the file was found.
48 * @param name the name of the file.
49 * @return <code>true</code> if and only if the name should be
50 * included in the file list; <code>false</code> otherwise.
51 */
52 boolean accept(File dir, String name);
53}
java/pkg/java/io/FilterInputStream.class+0−0

Binary file not shown.

java/pkg/java/io/FilterInputStream.java+245−0
@@ -0,0 +1,245 @@
1/*
2 * Copyright (c) 1994, 2010, 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
26package java.io;
27
28/**
29 * A <code>FilterInputStream</code> contains
30 * some other input stream, which it uses as
31 * its basic source of data, possibly transforming
32 * the data along the way or providing additional
33 * functionality. The class <code>FilterInputStream</code>
34 * itself simply overrides all methods of
35 * <code>InputStream</code> with versions that
36 * pass all requests to the contained input
37 * stream. Subclasses of <code>FilterInputStream</code>
38 * may further override some of these methods
39 * and may also provide additional methods
40 * and fields.
41 *
42 * @author Jonathan Payne
43 * @since JDK1.0
44 */
45public
46class FilterInputStream extends InputStream {
47 /**
48 * The input stream to be filtered.
49 */
50 protected volatile InputStream in;
51
52 /**
53 * Creates a <code>FilterInputStream</code>
54 * by assigning the argument <code>in</code>
55 * to the field <code>this.in</code> so as
56 * to remember it for later use.
57 *
58 * @param in the underlying input stream, or <code>null</code> if
59 * this instance is to be created without an underlying stream.
60 */
61 protected FilterInputStream(InputStream in) {
62 this.in = in;
63 }
64
65 /**
66 * Reads the next byte of data from this input stream. The value
67 * byte is returned as an <code>int</code> in the range
68 * <code>0</code> to <code>255</code>. If no byte is available
69 * because the end of the stream has been reached, the value
70 * <code>-1</code> is returned. This method blocks until input data
71 * is available, the end of the stream is detected, or an exception
72 * is thrown.
73 * <p>
74 * This method
75 * simply performs <code>in.read()</code> and returns the result.
76 *
77 * @return the next byte of data, or <code>-1</code> if the end of the
78 * stream is reached.
79 * @exception IOException if an I/O error occurs.
80 * @see java.io.FilterInputStream#in
81 */
82 public int read() throws IOException {
83 return in.read();
84 }
85
86 /**
87 * Reads up to <code>byte.length</code> bytes of data from this
88 * input stream into an array of bytes. This method blocks until some
89 * input is available.
90 * <p>
91 * This method simply performs the call
92 * <code>read(b, 0, b.length)</code> and returns
93 * the result. It is important that it does
94 * <i>not</i> do <code>in.read(b)</code> instead;
95 * certain subclasses of <code>FilterInputStream</code>
96 * depend on the implementation strategy actually
97 * used.
98 *
99 * @param b the buffer into which the data is read.
100 * @return the total number of bytes read into the buffer, or
101 * <code>-1</code> if there is no more data because the end of
102 * the stream has been reached.
103 * @exception IOException if an I/O error occurs.
104 * @see java.io.FilterInputStream#read(byte[], int, int)
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 an array of bytes. If <code>len</code> is not zero, the method
113 * blocks until some input is available; otherwise, no
114 * bytes are read and <code>0</code> is returned.
115 * <p>
116 * This method simply performs <code>in.read(b, off, len)</code>
117 * and returns the result.
118 *
119 * @param b the buffer into which the data is read.
120 * @param off the start offset in the destination array <code>b</code>
121 * @param len the maximum number of bytes read.
122 * @return the total number of bytes read into the buffer, or
123 * <code>-1</code> if there is no more data because the end of
124 * the stream has been reached.
125 * @exception NullPointerException If <code>b</code> is <code>null</code>.
126 * @exception IndexOutOfBoundsException If <code>off</code> is negative,
127 * <code>len</code> is negative, or <code>len</code> is greater than
128 * <code>b.length - off</code>
129 * @exception IOException if an I/O error occurs.
130 * @see java.io.FilterInputStream#in
131 */
132 public int read(byte b[], int off, int len) throws IOException {
133 return in.read(b, off, len);
134 }
135
136 /**
137 * Skips over and discards <code>n</code> bytes of data from the
138 * input stream. The <code>skip</code> method may, for a variety of
139 * reasons, end up skipping over some smaller number of bytes,
140 * possibly <code>0</code>. The actual number of bytes skipped is
141 * returned.
142 * <p>
143 * This method simply performs <code>in.skip(n)</code>.
144 *
145 * @param n the number of bytes to be skipped.
146 * @return the actual number of bytes skipped.
147 * @exception IOException if the stream does not support seek,
148 * or if some other I/O error occurs.
149 */
150 public long skip(long n) throws IOException {
151 return in.skip(n);
152 }
153
154 /**
155 * Returns an estimate of the number of bytes that can be read (or
156 * skipped over) from this input stream without blocking by the next
157 * caller of a method for this input stream. The next caller might be
158 * the same thread or another thread. A single read or skip of this
159 * many bytes will not block, but may read or skip fewer bytes.
160 * <p>
161 * This method returns the result of {@link #in in}.available().
162 *
163 * @return an estimate of the number of bytes that can be read (or skipped
164 * over) from this input stream without blocking.
165 * @exception IOException if an I/O error occurs.
166 */
167 public int available() throws IOException {
168 return in.available();
169 }
170
171 /**
172 * Closes this input stream and releases any system resources
173 * associated with the stream.
174 * This
175 * method simply performs <code>in.close()</code>.
176 *
177 * @exception IOException if an I/O error occurs.
178 * @see java.io.FilterInputStream#in
179 */
180 public void close() throws IOException {
181 in.close();
182 }
183
184 /**
185 * Marks the current position in this input stream. A subsequent
186 * call to the <code>reset</code> method repositions this stream at
187 * the last marked position so that subsequent reads re-read the same bytes.
188 * <p>
189 * The <code>readlimit</code> argument tells this input stream to
190 * allow that many bytes to be read before the mark position gets
191 * invalidated.
192 * <p>
193 * This method simply performs <code>in.mark(readlimit)</code>.
194 *
195 * @param readlimit the maximum limit of bytes that can be read before
196 * the mark position becomes invalid.
197 * @see java.io.FilterInputStream#in
198 * @see java.io.FilterInputStream#reset()
199 */
200 public synchronized void mark(int readlimit) {
201 in.mark(readlimit);
202 }
203
204 /**
205 * Repositions this stream to the position at the time the
206 * <code>mark</code> method was last called on this input stream.
207 * <p>
208 * This method
209 * simply performs <code>in.reset()</code>.
210 * <p>
211 * Stream marks are intended to be used in
212 * situations where you need to read ahead a little to see what's in
213 * the stream. Often this is most easily done by invoking some
214 * general parser. If the stream is of the type handled by the
215 * parse, it just chugs along happily. If the stream is not of
216 * that type, the parser should toss an exception when it fails.
217 * If this happens within readlimit bytes, it allows the outer
218 * code to reset the stream and try another parser.
219 *
220 * @exception IOException if the stream has not been marked or if the
221 * mark has been invalidated.
222 * @see java.io.FilterInputStream#in
223 * @see java.io.FilterInputStream#mark(int)
224 */
225 public synchronized void reset() throws IOException {
226 in.reset();
227 }
228
229 /**
230 * Tests if this input stream supports the <code>mark</code>
231 * and <code>reset</code> methods.
232 * This method
233 * simply performs <code>in.markSupported()</code>.
234 *
235 * @return <code>true</code> if this stream type supports the
236 * <code>mark</code> and <code>reset</code> method;
237 * <code>false</code> otherwise.
238 * @see java.io.FilterInputStream#in
239 * @see java.io.InputStream#mark(int)
240 * @see java.io.InputStream#reset()
241 */
242 public boolean markSupported() {
243 return in.markSupported();
244 }
245}
java/pkg/java/io/FilterOutputStream.class+0−0

Binary file not shown.

java/pkg/java/io/FilterOutputStream.java+162−0
@@ -0,0 +1,162 @@
1/*
2 * Copyright (c) 1994, 2011, 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
26package java.io;
27
28/**
29 * This class is the superclass of all classes that filter output
30 * streams. These streams sit on top of an already existing output
31 * stream (the <i>underlying</i> output stream) which it uses as its
32 * basic sink of data, but possibly transforming the data along the
33 * way or providing additional functionality.
34 * <p>
35 * The class <code>FilterOutputStream</code> itself simply overrides
36 * all methods of <code>OutputStream</code> with versions that pass
37 * all requests to the underlying output stream. Subclasses of
38 * <code>FilterOutputStream</code> may further override some of these
39 * methods as well as provide additional methods and fields.
40 *
41 * @author Jonathan Payne
42 * @since JDK1.0
43 */
44public
45class FilterOutputStream extends OutputStream {
46 /**
47 * The underlying output stream to be filtered.
48 */
49 protected OutputStream out;
50
51 /**
52 * Creates an output stream filter built on top of the specified
53 * underlying output stream.
54 *
55 * @param out the underlying output stream to be assigned to
56 * the field <tt>this.out</tt> for later use, or
57 * <code>null</code> if this instance is to be
58 * created without an underlying stream.
59 */
60 public FilterOutputStream(OutputStream out) {
61 this.out = out;
62 }
63
64 /**
65 * Writes the specified <code>byte</code> to this output stream.
66 * <p>
67 * The <code>write</code> method of <code>FilterOutputStream</code>
68 * calls the <code>write</code> method of its underlying output stream,
69 * that is, it performs <tt>out.write(b)</tt>.
70 * <p>
71 * Implements the abstract <tt>write</tt> method of <tt>OutputStream</tt>.
72 *
73 * @param b the <code>byte</code>.
74 * @exception IOException if an I/O error occurs.
75 */
76 public void write(int b) throws IOException {
77 out.write(b);
78 }
79
80 /**
81 * Writes <code>b.length</code> bytes to this output stream.
82 * <p>
83 * The <code>write</code> method of <code>FilterOutputStream</code>
84 * calls its <code>write</code> method of three arguments with the
85 * arguments <code>b</code>, <code>0</code>, and
86 * <code>b.length</code>.
87 * <p>
88 * Note that this method does not call the one-argument
89 * <code>write</code> method of its underlying stream with the single
90 * argument <code>b</code>.
91 *
92 * @param b the data to be written.
93 * @exception IOException if an I/O error occurs.
94 * @see java.io.FilterOutputStream#write(byte[], int, int)
95 */
96 public void write(byte b[]) throws IOException {
97 write(b, 0, b.length);
98 }
99
100 /**
101 * Writes <code>len</code> bytes from the specified
102 * <code>byte</code> array starting at offset <code>off</code> to
103 * this output stream.
104 * <p>
105 * The <code>write</code> method of <code>FilterOutputStream</code>
106 * calls the <code>write</code> method of one argument on each
107 * <code>byte</code> to output.
108 * <p>
109 * Note that this method does not call the <code>write</code> method
110 * of its underlying input stream with the same arguments. Subclasses
111 * of <code>FilterOutputStream</code> should provide a more efficient
112 * implementation of this method.
113 *
114 * @param b the data.
115 * @param off the start offset in the data.
116 * @param len the number of bytes to write.
117 * @exception IOException if an I/O error occurs.
118 * @see java.io.FilterOutputStream#write(int)
119 */
120 public void write(byte b[], int off, int len) throws IOException {
121 if ((off | len | (b.length - (len + off)) | (off + len)) < 0)
122 throw new IndexOutOfBoundsException();
123
124 for (int i = 0 ; i < len ; i++) {
125 write(b[off + i]);
126 }
127 }
128
129 /**
130 * Flushes this output stream and forces any buffered output bytes
131 * to be written out to the stream.
132 * <p>
133 * The <code>flush</code> method of <code>FilterOutputStream</code>
134 * calls the <code>flush</code> method of its underlying output stream.
135 *
136 * @exception IOException if an I/O error occurs.
137 * @see java.io.FilterOutputStream#out
138 */
139 public void flush() throws IOException {
140 out.flush();
141 }
142
143 /**
144 * Closes this output stream and releases any system resources
145 * associated with the stream.
146 * <p>
147 * The <code>close</code> method of <code>FilterOutputStream</code>
148 * calls its <code>flush</code> method, and then calls the
149 * <code>close</code> method of its underlying output stream.
150 *
151 * @exception IOException if an I/O error occurs.
152 * @see java.io.FilterOutputStream#flush()
153 * @see java.io.FilterOutputStream#out
154 */
155 public void close() throws IOException {
156 try {
157 flush();
158 } catch (IOException ignored) {
159 }
160 out.close();
161 }
162}
java/pkg/java/io/FilterReader.class+0−0

Binary file not shown.

java/pkg/java/io/FilterReader.java+124−0
@@ -0,0 +1,124 @@
1/*
2 * Copyright (c) 1996, 2005, 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
26package java.io;
27
28
29/**
30 * Abstract class for reading filtered character streams.
31 * The abstract class <code>FilterReader</code> itself
32 * provides default methods that pass all requests to
33 * the contained stream. Subclasses of <code>FilterReader</code>
34 * should override some of these methods and may also provide
35 * additional methods and fields.
36 *
37 * @author Mark Reinhold
38 * @since JDK1.1
39 */
40
41public abstract class FilterReader extends Reader {
42
43 /**
44 * The underlying character-input stream.
45 */
46 protected Reader in;
47
48 /**
49 * Creates a new filtered reader.
50 *
51 * @param in a Reader object providing the underlying stream.
52 * @throws NullPointerException if <code>in</code> is <code>null</code>
53 */
54 protected FilterReader(Reader in) {
55 super(in);
56 this.in = in;
57 }
58
59 /**
60 * Reads a single character.
61 *
62 * @exception IOException If an I/O error occurs
63 */
64 public int read() throws IOException {
65 return in.read();
66 }
67
68 /**
69 * Reads characters into a portion of an array.
70 *
71 * @exception IOException If an I/O error occurs
72 */
73 public int read(char cbuf[], int off, int len) throws IOException {
74 return in.read(cbuf, off, len);
75 }
76
77 /**
78 * Skips characters.
79 *
80 * @exception IOException If an I/O error occurs
81 */
82 public long skip(long n) throws IOException {
83 return in.skip(n);
84 }
85
86 /**
87 * Tells whether this stream is ready to be read.
88 *
89 * @exception IOException If an I/O error occurs
90 */
91 public boolean ready() throws IOException {
92 return in.ready();
93 }
94
95 /**
96 * Tells whether this stream supports the mark() operation.
97 */
98 public boolean markSupported() {
99 return in.markSupported();
100 }
101
102 /**
103 * Marks the present position in the stream.
104 *
105 * @exception IOException If an I/O error occurs
106 */
107 public void mark(int readAheadLimit) throws IOException {
108 in.mark(readAheadLimit);
109 }
110
111 /**
112 * Resets the stream.
113 *
114 * @exception IOException If an I/O error occurs
115 */
116 public void reset() throws IOException {
117 in.reset();
118 }
119
120 public void close() throws IOException {
121 in.close();
122 }
123
124}
java/pkg/java/io/FilterWriter.class+0−0

Binary file not shown.

java/pkg/java/io/FilterWriter.java+107−0
@@ -0,0 +1,107 @@
1/*
2 * Copyright (c) 1996, 2005, 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
26package java.io;
27
28
29/**
30 * Abstract class for writing filtered character streams.
31 * The abstract class <code>FilterWriter</code> itself
32 * provides default methods that pass all requests to the
33 * contained stream. Subclasses of <code>FilterWriter</code>
34 * should override some of these methods and may also
35 * provide additional methods and fields.
36 *
37 * @author Mark Reinhold
38 * @since JDK1.1
39 */
40
41public abstract class FilterWriter extends Writer {
42
43 /**
44 * The underlying character-output stream.
45 */
46 protected Writer out;
47
48 /**
49 * Create a new filtered writer.
50 *
51 * @param out a Writer object to provide the underlying stream.
52 * @throws NullPointerException if <code>out</code> is <code>null</code>
53 */
54 protected FilterWriter(Writer out) {
55 super(out);
56 this.out = out;
57 }
58
59 /**
60 * Writes a single character.
61 *
62 * @exception IOException If an I/O error occurs
63 */
64 public void write(int c) throws IOException {
65 out.write(c);
66 }
67
68 /**
69 * Writes a portion of an array of characters.
70 *
71 * @param cbuf Buffer of characters to be written
72 * @param off Offset from which to start reading characters
73 * @param len Number of characters to be written
74 *
75 * @exception IOException If an I/O error occurs
76 */
77 public void write(char cbuf[], int off, int len) throws IOException {
78 out.write(cbuf, off, len);
79 }
80
81 /**
82 * Writes a portion of a string.
83 *
84 * @param str String to be written
85 * @param off Offset from which to start reading characters
86 * @param len Number of characters to be written
87 *
88 * @exception IOException If an I/O error occurs
89 */
90 public void write(String str, int off, int len) throws IOException {
91 out.write(str, off, len);
92 }
93
94 /**
95 * Flushes the stream.
96 *
97 * @exception IOException If an I/O error occurs
98 */
99 public void flush() throws IOException {
100 out.flush();
101 }
102
103 public void close() throws IOException {
104 out.close();
105 }
106
107}
java/pkg/java/io/Flushable.class+0−0

Binary file not shown.

java/pkg/java/io/Flushable.java+47−0
@@ -0,0 +1,47 @@
1/*
2 * Copyright (c) 2004, 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
26package java.io;
27
28import java.io.IOException;
29
30/**
31 * A <tt>Flushable</tt> is a destination of data that can be flushed. The
32 * flush method is invoked to write any buffered output to the underlying
33 * stream.
34 *
35 * @since 1.5
36 */
37
38public interface Flushable {
39
40 /**
41 * Flushes this stream by writing any buffered output to the underlying
42 * stream.
43 *
44 * @throws IOException If an I/O error occurs
45 */
46 void flush() throws IOException;
47}
java/pkg/java/io/IOError.class+0−0

Binary file not shown.

java/pkg/java/io/IOError.java+50−0
@@ -0,0 +1,50 @@
1/*
2 * Copyright (c) 2005, 2006, 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
26package java.io;
27
28/**
29 * Thrown when a serious I/O error has occurred.
30 *
31 * @author Xueming Shen
32 * @since 1.6
33 */
34public class IOError extends Error {
35 /**
36 * Constructs a new instance of IOError with the specified cause. The
37 * IOError is created with the detail message of
38 * <tt>(cause==null ? null : cause.toString())</tt> (which typically
39 * contains the class and detail message of cause).
40 *
41 * @param cause
42 * The cause of this error, or <tt>null</tt> if the cause
43 * is not known
44 */
45 public IOError(Throwable cause) {
46 super(cause);
47 }
48
49 private static final long serialVersionUID = 67100927991680413L;
50}
java/pkg/java/io/IOException.class+0−0

Binary file not shown.

java/pkg/java/io/IOException.java+101−0
@@ -0,0 +1,101 @@
1/*
2 * Copyright (c) 1994, 2006, 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
26package java.io;
27
28/**
29 * Signals that an I/O exception of some sort has occurred. This
30 * class is the general class of exceptions produced by failed or
31 * interrupted I/O operations.
32 *
33 * @author unascribed
34 * @see java.io.InputStream
35 * @see java.io.OutputStream
36 * @since JDK1.0
37 */
38public
39class IOException extends Exception {
40 static final long serialVersionUID = 7818375828146090155L;
41
42 /**
43 * Constructs an {@code IOException} with {@code null}
44 * as its error detail message.
45 */
46 public IOException() {
47 super();
48 }
49
50 /**
51 * Constructs an {@code IOException} with the specified detail message.
52 *
53 * @param message
54 * The detail message (which is saved for later retrieval
55 * by the {@link #getMessage()} method)
56 */
57 public IOException(String message) {
58 super(message);
59 }
60
61 /**
62 * Constructs an {@code IOException} with the specified detail message
63 * and cause.
64 *
65 * <p> Note that the detail message associated with {@code cause} is
66 * <i>not</i> automatically incorporated into this exception's detail
67 * message.
68 *
69 * @param message
70 * The detail message (which is saved for later retrieval
71 * by the {@link #getMessage()} method)
72 *
73 * @param cause
74 * The cause (which is saved for later retrieval by the
75 * {@link #getCause()} method). (A null value is permitted,
76 * and indicates that the cause is nonexistent or unknown.)
77 *
78 * @since 1.6
79 */
80 public IOException(String message, Throwable cause) {
81 super(message, cause);
82 }
83
84 /**
85 * Constructs an {@code IOException} with the specified cause and a
86 * detail message of {@code (cause==null ? null : cause.toString())}
87 * (which typically contains the class and detail message of {@code cause}).
88 * This constructor is useful for IO exceptions that are little more
89 * than wrappers for other throwables.
90 *
91 * @param cause
92 * The cause (which is saved for later retrieval by the
93 * {@link #getCause()} method). (A null value is permitted,
94 * and indicates that the cause is nonexistent or unknown.)
95 *
96 * @since 1.6
97 */
98 public IOException(Throwable cause) {
99 super(cause);
100 }
101}
java/pkg/java/io/InputStream.class+0−0

Binary file not shown.

java/pkg/java/io/InputStream.java+370−0
@@ -0,0 +1,370 @@
1/*
2 * Copyright (c) 1994, 2006, 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
26package java.io;
27
28/**
29 * This abstract class is the superclass of all classes representing
30 * an input stream of bytes.
31 *
32 * <p> Applications that need to define a subclass of <code>InputStream</code>
33 * must always provide a method that returns the next byte of input.
34 *
35 * @author Arthur van Hoff
36 * @see java.io.BufferedInputStream
37 * @see java.io.ByteArrayInputStream
38 * @see java.io.DataInputStream
39 * @see java.io.FilterInputStream
40 * @see java.io.InputStream#read()
41 * @see java.io.OutputStream
42 * @see java.io.PushbackInputStream
43 * @since JDK1.0
44 */
45public abstract class InputStream implements Closeable {
46
47 // SKIP_BUFFER_SIZE is used to determine the size of skipBuffer
48 private static final int SKIP_BUFFER_SIZE = 2048;
49 // skipBuffer is initialized in skip(long), if needed.
50 private static byte[] skipBuffer;
51
52 /**
53 * Reads the next byte of data from the input stream. The value byte is
54 * returned as an <code>int</code> in the range <code>0</code> to
55 * <code>255</code>. If no byte is available because the end of the stream
56 * has been reached, the value <code>-1</code> is returned. This method
57 * blocks until input data is available, the end of the stream is detected,
58 * or an exception is thrown.
59 *
60 * <p> A subclass must provide an implementation of this method.
61 *
62 * @return the next byte of data, or <code>-1</code> if the end of the
63 * stream is reached.
64 * @exception IOException if an I/O error occurs.
65 */
66 public abstract int read() throws IOException;
67
68 /**
69 * Reads some number of bytes from the input stream and stores them into
70 * the buffer array <code>b</code>. The number of bytes actually read is
71 * returned as an integer. This method blocks until input data is
72 * available, end of file is detected, or an exception is thrown.
73 *
74 * <p> If the length of <code>b</code> is zero, then no bytes are read and
75 * <code>0</code> is returned; otherwise, there is an attempt to read at
76 * least one byte. If no byte is available because the stream is at the
77 * end of the file, the value <code>-1</code> is returned; otherwise, at
78 * least one byte is read and stored into <code>b</code>.
79 *
80 * <p> The first byte read is stored into element <code>b[0]</code>, the
81 * next one into <code>b[1]</code>, and so on. The number of bytes read is,
82 * at most, equal to the length of <code>b</code>. Let <i>k</i> be the
83 * number of bytes actually read; these bytes will be stored in elements
84 * <code>b[0]</code> through <code>b[</code><i>k</i><code>-1]</code>,
85 * leaving elements <code>b[</code><i>k</i><code>]</code> through
86 * <code>b[b.length-1]</code> unaffected.
87 *
88 * <p> The <code>read(b)</code> method for class <code>InputStream</code>
89 * has the same effect as: <pre><code> read(b, 0, b.length) </code></pre>
90 *
91 * @param b the buffer into which the data is read.
92 * @return the total number of bytes read into the buffer, or
93 * <code>-1</code> if there is no more data because the end of
94 * the stream has been reached.
95 * @exception IOException If the first byte cannot be read for any reason
96 * other than the end of the file, if the input stream has been closed, or
97 * if some other I/O error occurs.
98 * @exception NullPointerException if <code>b</code> is <code>null</code>.
99 * @see java.io.InputStream#read(byte[], int, int)
100 */
101 public int read(byte b[]) throws IOException {
102 return read(b, 0, b.length);
103 }
104
105 /**
106 * Reads up to <code>len</code> bytes of data from the input stream into
107 * an array of bytes. An attempt is made to read as many as
108 * <code>len</code> bytes, but a smaller number may be read.
109 * The number of bytes actually read is returned as an integer.
110 *
111 * <p> This method blocks until input data is available, end of file is
112 * detected, or an exception is thrown.
113 *
114 * <p> If <code>len</code> is zero, then no bytes are read and
115 * <code>0</code> is returned; otherwise, there is an attempt to read at
116 * least one byte. If no byte is available because the stream is at end of
117 * file, the value <code>-1</code> is returned; otherwise, at least one
118 * byte is read and stored into <code>b</code>.
119 *
120 * <p> The first byte read is stored into element <code>b[off]</code>, the
121 * next one into <code>b[off+1]</code>, and so on. The number of bytes read
122 * is, at most, equal to <code>len</code>. Let <i>k</i> be the number of
123 * bytes actually read; these bytes will be stored in elements
124 * <code>b[off]</code> through <code>b[off+</code><i>k</i><code>-1]</code>,
125 * leaving elements <code>b[off+</code><i>k</i><code>]</code> through
126 * <code>b[off+len-1]</code> unaffected.
127 *
128 * <p> In every case, elements <code>b[0]</code> through
129 * <code>b[off]</code> and elements <code>b[off+len]</code> through
130 * <code>b[b.length-1]</code> are unaffected.
131 *
132 * <p> The <code>read(b,</code> <code>off,</code> <code>len)</code> method
133 * for class <code>InputStream</code> simply calls the method
134 * <code>read()</code> repeatedly. If the first such call results in an
135 * <code>IOException</code>, that exception is returned from the call to
136 * the <code>read(b,</code> <code>off,</code> <code>len)</code> method. If
137 * any subsequent call to <code>read()</code> results in a
138 * <code>IOException</code>, the exception is caught and treated as if it
139 * were end of file; the bytes read up to that point are stored into
140 * <code>b</code> and the number of bytes read before the exception
141 * occurred is returned. The default implementation of this method blocks
142 * until the requested amount of input data <code>len</code> has been read,
143 * end of file is detected, or an exception is thrown. Subclasses are encouraged
144 * to provide a more efficient implementation of this method.
145 *
146 * @param b the buffer into which the data is read.
147 * @param off the start offset in array <code>b</code>
148 * at which the data is written.
149 * @param len the maximum number of bytes to read.
150 * @return the total number of bytes read into the buffer, or
151 * <code>-1</code> if there is no more data because the end of
152 * the stream has been reached.
153 * @exception IOException If the first byte cannot be read for any reason
154 * other than end of file, or if the input stream has been closed, or if
155 * some other I/O error occurs.
156 * @exception NullPointerException If <code>b</code> is <code>null</code>.
157 * @exception IndexOutOfBoundsException If <code>off</code> is negative,
158 * <code>len</code> is negative, or <code>len</code> is greater than
159 * <code>b.length - off</code>
160 * @see java.io.InputStream#read()
161 */
162 public int read(byte b[], int off, int len) throws IOException {
163 if (b == null) {
164 throw new NullPointerException();
165 } else if (off < 0 || len < 0 || len > b.length - off) {
166 throw new IndexOutOfBoundsException();
167 } else if (len == 0) {
168 return 0;
169 }
170
171 int c = read();
172 if (c == -1) {
173 return -1;
174 }
175 b[off] = (byte)c;
176
177 int i = 1;
178 try {
179 for (; i < len ; i++) {
180 c = read();
181 if (c == -1) {
182 break;
183 }
184 b[off + i] = (byte)c;
185 }
186 } catch (IOException ee) {
187 }
188 return i;
189 }
190
191 /**
192 * Skips over and discards <code>n</code> bytes of data from this input
193 * stream. The <code>skip</code> method may, for a variety of reasons, end
194 * up skipping over some smaller number of bytes, possibly <code>0</code>.
195 * This may result from any of a number of conditions; reaching end of file
196 * before <code>n</code> bytes have been skipped is only one possibility.
197 * The actual number of bytes skipped is returned. If <code>n</code> is
198 * negative, no bytes are skipped.
199 *
200 * <p> The <code>skip</code> method of this class creates a
201 * byte array and then repeatedly reads into it until <code>n</code> bytes
202 * have been read or the end of the stream has been reached. Subclasses are
203 * encouraged to provide a more efficient implementation of this method.
204 * For instance, the implementation may depend on the ability to seek.
205 *
206 * @param n the number of bytes to be skipped.
207 * @return the actual number of bytes skipped.
208 * @exception IOException if the stream does not support seek,
209 * or if some other I/O error occurs.
210 */
211 public long skip(long n) throws IOException {
212
213 long remaining = n;
214 int nr;
215 if (skipBuffer == null)
216 skipBuffer = new byte[SKIP_BUFFER_SIZE];
217
218 byte[] localSkipBuffer = skipBuffer;
219
220 if (n <= 0) {
221 return 0;
222 }
223
224 while (remaining > 0) {
225 nr = read(localSkipBuffer, 0,
226 (int) Math.min(SKIP_BUFFER_SIZE, remaining));
227 if (nr < 0) {
228 break;
229 }
230 remaining -= nr;
231 }
232
233 return n - remaining;
234 }
235
236 /**
237 * Returns an estimate of the number of bytes that can be read (or
238 * skipped over) from this input stream without blocking by the next
239 * invocation of a method for this input stream. The next invocation
240 * might be the same thread or another thread. A single read or skip of this
241 * many bytes will not block, but may read or skip fewer bytes.
242 *
243 * <p> Note that while some implementations of {@code InputStream} will return
244 * the total number of bytes in the stream, many will not. It is
245 * never correct to use the return value of this method to allocate
246 * a buffer intended to hold all data in this stream.
247 *
248 * <p> A subclass' implementation of this method may choose to throw an
249 * {@link IOException} if this input stream has been closed by
250 * invoking the {@link #close()} method.
251 *
252 * <p> The {@code available} method for class {@code InputStream} always
253 * returns {@code 0}.
254 *
255 * <p> This method should be overridden by subclasses.
256 *
257 * @return an estimate of the number of bytes that can be read (or skipped
258 * over) from this input stream without blocking or {@code 0} when
259 * it reaches the end of the input stream.
260 * @exception IOException if an I/O error occurs.
261 */
262 public int available() throws IOException {
263 return 0;
264 }
265
266 /**
267 * Closes this input stream and releases any system resources associated
268 * with the stream.
269 *
270 * <p> The <code>close</code> method of <code>InputStream</code> does
271 * nothing.
272 *
273 * @exception IOException if an I/O error occurs.
274 */
275 public void close() throws IOException {}
276
277 /**
278 * Marks the current position in this input stream. A subsequent call to
279 * the <code>reset</code> method repositions this stream at the last marked
280 * position so that subsequent reads re-read the same bytes.
281 *
282 * <p> The <code>readlimit</code> arguments tells this input stream to
283 * allow that many bytes to be read before the mark position gets
284 * invalidated.
285 *
286 * <p> The general contract of <code>mark</code> is that, if the method
287 * <code>markSupported</code> returns <code>true</code>, the stream somehow
288 * remembers all the bytes read after the call to <code>mark</code> and
289 * stands ready to supply those same bytes again if and whenever the method
290 * <code>reset</code> is called. However, the stream is not required to
291 * remember any data at all if more than <code>readlimit</code> bytes are
292 * read from the stream before <code>reset</code> is called.
293 *
294 * <p> Marking a closed stream should not have any effect on the stream.
295 *
296 * <p> The <code>mark</code> method of <code>InputStream</code> does
297 * nothing.
298 *
299 * @param readlimit the maximum limit of bytes that can be read before
300 * the mark position becomes invalid.
301 * @see java.io.InputStream#reset()
302 */
303 public synchronized void mark(int readlimit) {}
304
305 /**
306 * Repositions this stream to the position at the time the
307 * <code>mark</code> method was last called on this input stream.
308 *
309 * <p> The general contract of <code>reset</code> is:
310 *
311 * <p><ul>
312 *
313 * <li> If the method <code>markSupported</code> returns
314 * <code>true</code>, then:
315 *
316 * <ul><li> If the method <code>mark</code> has not been called since
317 * the stream was created, or the number of bytes read from the stream
318 * since <code>mark</code> was last called is larger than the argument
319 * to <code>mark</code> at that last call, then an
320 * <code>IOException</code> might be thrown.
321 *
322 * <li> If such an <code>IOException</code> is not thrown, then the
323 * stream is reset to a state such that all the bytes read since the
324 * most recent call to <code>mark</code> (or since the start of the
325 * file, if <code>mark</code> has not been called) will be resupplied
326 * to subsequent callers of the <code>read</code> method, followed by
327 * any bytes that otherwise would have been the next input data as of
328 * the time of the call to <code>reset</code>. </ul>
329 *
330 * <li> If the method <code>markSupported</code> returns
331 * <code>false</code>, then:
332 *
333 * <ul><li> The call to <code>reset</code> may throw an
334 * <code>IOException</code>.
335 *
336 * <li> If an <code>IOException</code> is not thrown, then the stream
337 * is reset to a fixed state that depends on the particular type of the
338 * input stream and how it was created. The bytes that will be supplied
339 * to subsequent callers of the <code>read</code> method depend on the
340 * particular type of the input stream. </ul></ul>
341 *
342 * <p>The method <code>reset</code> for class <code>InputStream</code>
343 * does nothing except throw an <code>IOException</code>.
344 *
345 * @exception IOException if this stream has not been marked or if the
346 * mark has been invalidated.
347 * @see java.io.InputStream#mark(int)
348 * @see java.io.IOException
349 */
350 public synchronized void reset() throws IOException {
351 throw new IOException("mark/reset not supported");
352 }
353
354 /**
355 * Tests if this input stream supports the <code>mark</code> and
356 * <code>reset</code> methods. Whether or not <code>mark</code> and
357 * <code>reset</code> are supported is an invariant property of a
358 * particular input stream instance. The <code>markSupported</code> method
359 * of <code>InputStream</code> returns <code>false</code>.
360 *
361 * @return <code>true</code> if this stream instance supports the mark
362 * and reset methods; <code>false</code> otherwise.
363 * @see java.io.InputStream#mark(int)
364 * @see java.io.InputStream#reset()
365 */
366 public boolean markSupported() {
367 return false;
368 }
369
370}
java/pkg/java/io/InputStreamReader.class+0−0

Binary file not shown.

java/pkg/java/io/InputStreamReader.java+201−0
@@ -0,0 +1,201 @@
1/*
2 * Copyright (c) 1996, 2005, 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
26package java.io;
27
28import java.nio.charset.Charset;
29import java.nio.charset.CharsetDecoder;
30import sun.nio.cs.StreamDecoder;
31
32
33/**
34 * An InputStreamReader is a bridge from byte streams to character streams: It
35 * reads bytes and decodes them into characters using a specified {@link
36 * java.nio.charset.Charset <code>charset</code>}. The charset that it uses
37 * may be specified by name or may be given explicitly, or the platform's
38 * default charset may be accepted.
39 *
40 * <p> Each invocation of one of an InputStreamReader's read() methods may
41 * cause one or more bytes to be read from the underlying byte-input stream.
42 * To enable the efficient conversion of bytes to characters, more bytes may
43 * be read ahead from the underlying stream than are necessary to satisfy the
44 * current read operation.
45 *
46 * <p> For top efficiency, consider wrapping an InputStreamReader within a
47 * BufferedReader. For example:
48 *
49 * <pre>
50 * BufferedReader in
51 * = new BufferedReader(new InputStreamReader(System.in));
52 * </pre>
53 *
54 * @see BufferedReader
55 * @see InputStream
56 * @see java.nio.charset.Charset
57 *
58 * @author Mark Reinhold
59 * @since JDK1.1
60 */
61
62public class InputStreamReader extends Reader {
63
64 private final StreamDecoder sd;
65
66 /**
67 * Creates an InputStreamReader that uses the default charset.
68 *
69 * @param in An InputStream
70 */
71 public InputStreamReader(InputStream in) {
72 super(in);
73 try {
74 sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object
75 } catch (UnsupportedEncodingException e) {
76 // The default encoding should always be available
77 throw new Error(e);
78 }
79 }
80
81 /**
82 * Creates an InputStreamReader that uses the named charset.
83 *
84 * @param in
85 * An InputStream
86 *
87 * @param charsetName
88 * The name of a supported
89 * {@link java.nio.charset.Charset </code>charset<code>}
90 *
91 * @exception UnsupportedEncodingException
92 * If the named charset is not supported
93 */
94 public InputStreamReader(InputStream in, String charsetName)
95 throws UnsupportedEncodingException
96 {
97 super(in);
98 if (charsetName == null)
99 throw new NullPointerException("charsetName");
100 sd = StreamDecoder.forInputStreamReader(in, this, charsetName);
101 }
102
103 /**
104 * Creates an InputStreamReader that uses the given charset. </p>
105 *
106 * @param in An InputStream
107 * @param cs A charset
108 *
109 * @since 1.4
110 * @spec JSR-51
111 */
112 public InputStreamReader(InputStream in, Charset cs) {
113 super(in);
114 if (cs == null)
115 throw new NullPointerException("charset");
116 sd = StreamDecoder.forInputStreamReader(in, this, cs);
117 }
118
119 /**
120 * Creates an InputStreamReader that uses the given charset decoder. </p>
121 *
122 * @param in An InputStream
123 * @param dec A charset decoder
124 *
125 * @since 1.4
126 * @spec JSR-51
127 */
128 public InputStreamReader(InputStream in, CharsetDecoder dec) {
129 super(in);
130 if (dec == null)
131 throw new NullPointerException("charset decoder");
132 sd = StreamDecoder.forInputStreamReader(in, this, dec);
133 }
134
135 /**
136 * Returns the name of the character encoding being used by this stream.
137 *
138 * <p> If the encoding has an historical name then that name is returned;
139 * otherwise the encoding's canonical name is returned.
140 *
141 * <p> If this instance was created with the {@link
142 * #InputStreamReader(InputStream, String)} constructor then the returned
143 * name, being unique for the encoding, may differ from the name passed to
144 * the constructor. This method will return <code>null</code> if the
145 * stream has been closed.
146 * </p>
147 * @return The historical name of this encoding, or
148 * <code>null</code> if the stream has been closed
149 *
150 * @see java.nio.charset.Charset
151 *
152 * @revised 1.4
153 * @spec JSR-51
154 */
155 public String getEncoding() {
156 return sd.getEncoding();
157 }
158
159 /**
160 * Reads a single character.
161 *
162 * @return The character read, or -1 if the end of the stream has been
163 * reached
164 *
165 * @exception IOException If an I/O error occurs
166 */
167 public int read() throws IOException {
168 return sd.read();
169 }
170
171 /**
172 * Reads characters into a portion of an array.
173 *
174 * @param cbuf Destination buffer
175 * @param offset Offset at which to start storing characters
176 * @param length Maximum number of characters to read
177 *
178 * @return The number of characters read, or -1 if the end of the
179 * stream has been reached
180 *
181 * @exception IOException If an I/O error occurs
182 */
183 public int read(char cbuf[], int offset, int length) throws IOException {
184 return sd.read(cbuf, offset, length);
185 }
186
187 /**
188 * Tells whether this stream is ready to be read. An InputStreamReader is
189 * ready if its input buffer is not empty, or if bytes are available to be
190 * read from the underlying byte stream.
191 *
192 * @exception IOException If an I/O error occurs
193 */
194 public boolean ready() throws IOException {
195 return sd.ready();
196 }
197
198 public void close() throws IOException {
199 sd.close();
200 }
201}
java/pkg/java/io/InterruptedIOException.class+0−0

Binary file not shown.

java/pkg/java/io/InterruptedIOException.java+74−0
@@ -0,0 +1,74 @@
1/*
2 * Copyright (c) 1995, 2008, 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
26package java.io;
27
28/**
29 * Signals that an I/O operation has been interrupted. An
30 * <code>InterruptedIOException</code> is thrown to indicate that an
31 * input or output transfer has been terminated because the thread
32 * performing it was interrupted. The field {@link #bytesTransferred}
33 * indicates how many bytes were successfully transferred before
34 * the interruption occurred.
35 *
36 * @author unascribed
37 * @see java.io.InputStream
38 * @see java.io.OutputStream
39 * @see java.lang.Thread#interrupt()
40 * @since JDK1.0
41 */
42public
43class InterruptedIOException extends IOException {
44 private static final long serialVersionUID = 4020568460727500567L;
45
46 /**
47 * Constructs an <code>InterruptedIOException</code> with
48 * <code>null</code> as its error detail message.
49 */
50 public InterruptedIOException() {
51 super();
52 }
53
54 /**
55 * Constructs an <code>InterruptedIOException</code> with the
56 * specified detail message. The string <code>s</code> can be
57 * retrieved later by the
58 * <code>{@link java.lang.Throwable#getMessage}</code>
59 * method of class <code>java.lang.Throwable</code>.
60 *
61 * @param s the detail message.
62 */
63 public InterruptedIOException(String s) {
64 super(s);
65 }
66
67 /**
68 * Reports how many bytes had been transferred as part of the I/O
69 * operation before it was interrupted.
70 *
71 * @serial
72 */
73 public int bytesTransferred = 0;
74}
java/pkg/java/io/InvalidClassException.class+0−0

Binary file not shown.

java/pkg/java/io/InvalidClassException.java+81−0
@@ -0,0 +1,81 @@
1/*
2 * Copyright (c) 1996, 2006, 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
26package java.io;
27
28/**
29 * Thrown when the Serialization runtime detects one of the following
30 * problems with a Class.
31 * <UL>
32 * <LI> The serial version of the class does not match that of the class
33 * descriptor read from the stream
34 * <LI> The class contains unknown datatypes
35 * <LI> The class does not have an accessible no-arg constructor
36 * </UL>
37 *
38 * @author unascribed
39 * @since JDK1.1
40 */
41public class InvalidClassException extends ObjectStreamException {
42
43 private static final long serialVersionUID = -4333316296251054416L;
44
45 /**
46 * Name of the invalid class.
47 *
48 * @serial Name of the invalid class.
49 */
50 public String classname;
51
52 /**
53 * Report an InvalidClassException for the reason specified.
54 *
55 * @param reason String describing the reason for the exception.
56 */
57 public InvalidClassException(String reason) {
58 super(reason);
59 }
60
61 /**
62 * Constructs an InvalidClassException object.
63 *
64 * @param cname a String naming the invalid class.
65 * @param reason a String describing the reason for the exception.
66 */
67 public InvalidClassException(String cname, String reason) {
68 super(reason);
69 classname = cname;
70 }
71
72 /**
73 * Produce the message and include the classname, if present.
74 */
75 public String getMessage() {
76 if (classname == null)
77 return super.getMessage();
78 else
79 return classname + "; " + super.getMessage();
80 }
81}
java/pkg/java/io/InvalidObjectException.class+0−0

Binary file not shown.

java/pkg/java/io/InvalidObjectException.java+51−0
@@ -0,0 +1,51 @@
1/*
2 * Copyright (c) 1996, 2005, 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
26package java.io;
27
28/**
29 * Indicates that one or more deserialized objects failed validation
30 * tests. The argument should provide the reason for the failure.
31 *
32 * @see ObjectInputValidation
33 * @since JDK1.1
34 *
35 * @author unascribed
36 * @since JDK1.1
37 */
38public class InvalidObjectException extends ObjectStreamException {
39
40 private static final long serialVersionUID = 3233174318281839583L;
41
42 /**
43 * Constructs an <code>InvalidObjectException</code>.
44 * @param reason Detailed message explaining the reason for the failure.
45 *
46 * @see ObjectInputValidation
47 */
48 public InvalidObjectException(String reason) {
49 super(reason);
50 }
51}
java/pkg/java/io/LineNumberInputStream.class+0−0

Binary file not shown.

java/pkg/java/io/LineNumberInputStream.java+292−0
@@ -0,0 +1,292 @@
1/*
2 * Copyright (c) 1995, 2004, 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
26package java.io;
27
28/**
29 * This class is an input stream filter that provides the added
30 * functionality of keeping track of the current line number.
31 * <p>
32 * A line is a sequence of bytes ending with a carriage return
33 * character (<code>'&#92;r'</code>), a newline character
34 * (<code>'&#92;n'</code>), or a carriage return character followed
35 * immediately by a linefeed character. In all three cases, the line
36 * terminating character(s) are returned as a single newline character.
37 * <p>
38 * The line number begins at <code>0</code>, and is incremented by
39 * <code>1</code> when a <code>read</code> returns a newline character.
40 *
41 * @author Arthur van Hoff
42 * @see java.io.LineNumberReader
43 * @since JDK1.0
44 * @deprecated This class incorrectly assumes that bytes adequately represent
45 * characters. As of JDK&nbsp;1.1, the preferred way to operate on
46 * character streams is via the new character-stream classes, which
47 * include a class for counting line numbers.
48 */
49@Deprecated
50public
51class LineNumberInputStream extends FilterInputStream {
52 int pushBack = -1;
53 int lineNumber;
54 int markLineNumber;
55 int markPushBack = -1;
56
57 /**
58 * Constructs a newline number input stream that reads its input
59 * from the specified input stream.
60 *
61 * @param in the underlying input stream.
62 */
63 public LineNumberInputStream(InputStream in) {
64 super(in);
65 }
66
67 /**
68 * Reads the next byte of data from this input stream. The value
69 * byte is returned as an <code>int</code> in the range
70 * <code>0</code> to <code>255</code>. If no byte is available
71 * because the end of the stream has been reached, the value
72 * <code>-1</code> is returned. This method blocks until input data
73 * is available, the end of the stream is detected, or an exception
74 * is thrown.
75 * <p>
76 * The <code>read</code> method of
77 * <code>LineNumberInputStream</code> calls the <code>read</code>
78 * method of the underlying input stream. It checks for carriage
79 * returns and newline characters in the input, and modifies the
80 * current line number as appropriate. A carriage-return character or
81 * a carriage return followed by a newline character are both
82 * converted into a single newline character.
83 *
84 * @return the next byte of data, or <code>-1</code> if the end of this
85 * stream is reached.
86 * @exception IOException if an I/O error occurs.
87 * @see java.io.FilterInputStream#in
88 * @see java.io.LineNumberInputStream#getLineNumber()
89 */
90 public int read() throws IOException {
91 int c = pushBack;
92
93 if (c != -1) {
94 pushBack = -1;
95 } else {
96 c = in.read();
97 }
98
99 switch (c) {
100 case '\r':
101 pushBack = in.read();
102 if (pushBack == '\n') {
103 pushBack = -1;
104 }
105 case '\n':
106 lineNumber++;
107 return '\n';
108 }
109 return c;
110 }
111
112 /**
113 * Reads up to <code>len</code> bytes of data from this input stream
114 * into an array of bytes. This method blocks until some input is available.
115 * <p>
116 * The <code>read</code> method of
117 * <code>LineNumberInputStream</code> repeatedly calls the
118 * <code>read</code> method of zero arguments to fill in the byte array.
119 *
120 * @param b the buffer into which the data is read.
121 * @param off the start offset of the data.
122 * @param len the maximum number of bytes read.
123 * @return the total number of bytes read into the buffer, or
124 * <code>-1</code> if there is no more data because the end of
125 * this stream has been reached.
126 * @exception IOException if an I/O error occurs.
127 * @see java.io.LineNumberInputStream#read()
128 */
129 public int read(byte b[], int off, int len) throws IOException {
130 if (b == null) {
131 throw new NullPointerException();
132 } else if ((off < 0) || (off > b.length) || (len < 0) ||
133 ((off + len) > b.length) || ((off + len) < 0)) {
134 throw new IndexOutOfBoundsException();
135 } else if (len == 0) {
136 return 0;
137 }
138
139 int c = read();
140 if (c == -1) {
141 return -1;
142 }
143 b[off] = (byte)c;
144
145 int i = 1;
146 try {
147 for (; i < len ; i++) {
148 c = read();
149 if (c == -1) {
150 break;
151 }
152 if (b != null) {
153 b[off + i] = (byte)c;
154 }
155 }
156 } catch (IOException ee) {
157 }
158 return i;
159 }
160
161 /**
162 * Skips over and discards <code>n</code> bytes of data from this
163 * input stream. The <code>skip</code> method may, for a variety of
164 * reasons, end up skipping over some smaller number of bytes,
165 * possibly <code>0</code>. The actual number of bytes skipped is
166 * returned. If <code>n</code> is negative, no bytes are skipped.
167 * <p>
168 * The <code>skip</code> method of <code>LineNumberInputStream</code> creates
169 * a byte array and then repeatedly reads into it until
170 * <code>n</code> bytes have been read or the end of the stream has
171 * been reached.
172 *
173 * @param n the number of bytes to be skipped.
174 * @return the actual number of bytes skipped.
175 * @exception IOException if an I/O error occurs.
176 * @see java.io.FilterInputStream#in
177 */
178 public long skip(long n) throws IOException {
179 int chunk = 2048;
180 long remaining = n;
181 byte data[];
182 int nr;
183
184 if (n <= 0) {
185 return 0;
186 }
187
188 data = new byte[chunk];
189 while (remaining > 0) {
190 nr = read(data, 0, (int) Math.min(chunk, remaining));
191 if (nr < 0) {
192 break;
193 }
194 remaining -= nr;
195 }
196
197 return n - remaining;
198 }
199
200 /**
201 * Sets the line number to the specified argument.
202 *
203 * @param lineNumber the new line number.
204 * @see #getLineNumber
205 */
206 public void setLineNumber(int lineNumber) {
207 this.lineNumber = lineNumber;
208 }
209
210 /**
211 * Returns the current line number.
212 *
213 * @return the current line number.
214 * @see #setLineNumber
215 */
216 public int getLineNumber() {
217 return lineNumber;
218 }
219
220
221 /**
222 * Returns the number of bytes that can be read from this input
223 * stream without blocking.
224 * <p>
225 * Note that if the underlying input stream is able to supply
226 * <i>k</i> input characters without blocking, the
227 * <code>LineNumberInputStream</code> can guarantee only to provide
228 * <i>k</i>/2 characters without blocking, because the
229 * <i>k</i> characters from the underlying input stream might
230 * consist of <i>k</i>/2 pairs of <code>'&#92;r'</code> and
231 * <code>'&#92;n'</code>, which are converted to just
232 * <i>k</i>/2 <code>'&#92;n'</code> characters.
233 *
234 * @return the number of bytes that can be read from this input stream
235 * without blocking.
236 * @exception IOException if an I/O error occurs.
237 * @see java.io.FilterInputStream#in
238 */
239 public int available() throws IOException {
240 return (pushBack == -1) ? super.available()/2 : super.available()/2 + 1;
241 }
242
243 /**
244 * Marks the current position in this input stream. A subsequent
245 * call to the <code>reset</code> method repositions this stream at
246 * the last marked position so that subsequent reads re-read the same bytes.
247 * <p>
248 * The <code>mark</code> method of
249 * <code>LineNumberInputStream</code> remembers the current line
250 * number in a private variable, and then calls the <code>mark</code>
251 * method of the underlying input stream.
252 *
253 * @param readlimit the maximum limit of bytes that can be read before
254 * the mark position becomes invalid.
255 * @see java.io.FilterInputStream#in
256 * @see java.io.LineNumberInputStream#reset()
257 */
258 public void mark(int readlimit) {
259 markLineNumber = lineNumber;
260 markPushBack = pushBack;
261 in.mark(readlimit);
262 }
263
264 /**
265 * Repositions this stream to the position at the time the
266 * <code>mark</code> method was last called on this input stream.
267 * <p>
268 * The <code>reset</code> method of
269 * <code>LineNumberInputStream</code> resets the line number to be
270 * the line number at the time the <code>mark</code> method was
271 * called, and then calls the <code>reset</code> method of the
272 * underlying input stream.
273 * <p>
274 * Stream marks are intended to be used in
275 * situations where you need to read ahead a little to see what's in
276 * the stream. Often this is most easily done by invoking some
277 * general parser. If the stream is of the type handled by the
278 * parser, it just chugs along happily. If the stream is not of
279 * that type, the parser should toss an exception when it fails,
280 * which, if it happens within readlimit bytes, allows the outer
281 * code to reset the stream and try another parser.
282 *
283 * @exception IOException if an I/O error occurs.
284 * @see java.io.FilterInputStream#in
285 * @see java.io.LineNumberInputStream#mark(int)
286 */
287 public void reset() throws IOException {
288 lineNumber = markLineNumber;
289 pushBack = markPushBack;
290 in.reset();
291 }
292}
java/pkg/java/io/LineNumberReader.class+0−0

Binary file not shown.

java/pkg/java/io/LineNumberReader.java+281−0
@@ -0,0 +1,281 @@
1/*
2 * Copyright (c) 1996, 2006, 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
26package java.io;
27
28
29/**
30 * A buffered character-input stream that keeps track of line numbers. This
31 * class defines methods {@link #setLineNumber(int)} and {@link
32 * #getLineNumber()} for setting and getting the current line number
33 * respectively.
34 *
35 * <p> By default, line numbering begins at 0. This number increments at every
36 * <a href="#lt">line terminator</a> as the data is read, and can be changed
37 * with a call to <tt>setLineNumber(int)</tt>. Note however, that
38 * <tt>setLineNumber(int)</tt> does not actually change the current position in
39 * the stream; it only changes the value that will be returned by
40 * <tt>getLineNumber()</tt>.
41 *
42 * <p> A line is considered to be <a name="lt">terminated</a> by any one of a
43 * line feed ('\n'), a carriage return ('\r'), or a carriage return followed
44 * immediately by a linefeed.
45 *
46 * @author Mark Reinhold
47 * @since JDK1.1
48 */
49
50public class LineNumberReader extends BufferedReader {
51
52 /** The current line number */
53 private int lineNumber = 0;
54
55 /** The line number of the mark, if any */
56 private int markedLineNumber; // Defaults to 0
57
58 /** If the next character is a line feed, skip it */
59 private boolean skipLF;
60
61 /** The skipLF flag when the mark was set */
62 private boolean markedSkipLF;
63
64 /**
65 * Create a new line-numbering reader, using the default input-buffer
66 * size.
67 *
68 * @param in
69 * A Reader object to provide the underlying stream
70 */
71 public LineNumberReader(Reader in) {
72 super(in);
73 }
74
75 /**
76 * Create a new line-numbering reader, reading characters into a buffer of
77 * the given size.
78 *
79 * @param in
80 * A Reader object to provide the underlying stream
81 *
82 * @param sz
83 * An int specifying the size of the buffer
84 */
85 public LineNumberReader(Reader in, int sz) {
86 super(in, sz);
87 }
88
89 /**
90 * Set the current line number.
91 *
92 * @param lineNumber
93 * An int specifying the line number
94 *
95 * @see #getLineNumber
96 */
97 public void setLineNumber(int lineNumber) {
98 this.lineNumber = lineNumber;
99 }
100
101 /**
102 * Get the current line number.
103 *
104 * @return The current line number
105 *
106 * @see #setLineNumber
107 */
108 public int getLineNumber() {
109 return lineNumber;
110 }
111
112 /**
113 * Read a single character. <a href="#lt">Line terminators</a> are
114 * compressed into single newline ('\n') characters. Whenever a line
115 * terminator is read the current line number is incremented.
116 *
117 * @return The character read, or -1 if the end of the stream has been
118 * reached
119 *
120 * @throws IOException
121 * If an I/O error occurs
122 */
123 public int read() throws IOException {
124 synchronized (lock) {
125 int c = super.read();
126 if (skipLF) {
127 if (c == '\n')
128 c = super.read();
129 skipLF = false;
130 }
131 switch (c) {
132 case '\r':
133 skipLF = true;
134 case '\n': /* Fall through */
135 lineNumber++;
136 return '\n';
137 }
138 return c;
139 }
140 }
141
142 /**
143 * Read characters into a portion of an array. Whenever a <a
144 * href="#lt">line terminator</a> is read the current line number is
145 * incremented.
146 *
147 * @param cbuf
148 * Destination buffer
149 *
150 * @param off
151 * Offset at which to start storing characters
152 *
153 * @param len
154 * Maximum number of characters to read
155 *
156 * @return The number of bytes read, or -1 if the end of the stream has
157 * already been reached
158 *
159 * @throws IOException
160 * If an I/O error occurs
161 */
162 public int read(char cbuf[], int off, int len) throws IOException {
163 synchronized (lock) {
164 int n = super.read(cbuf, off, len);
165
166 for (int i = off; i < off + n; i++) {
167 int c = cbuf[i];
168 if (skipLF) {
169 skipLF = false;
170 if (c == '\n')
171 continue;
172 }
173 switch (c) {
174 case '\r':
175 skipLF = true;
176 case '\n': /* Fall through */
177 lineNumber++;
178 break;
179 }
180 }
181
182 return n;
183 }
184 }
185
186 /**
187 * Read a line of text. Whenever a <a href="#lt">line terminator</a> is
188 * read the current line number is incremented.
189 *
190 * @return A String containing the contents of the line, not including
191 * any <a href="#lt">line termination characters</a>, or
192 * <tt>null</tt> if the end of the stream has been reached
193 *
194 * @throws IOException
195 * If an I/O error occurs
196 */
197 public String readLine() throws IOException {
198 synchronized (lock) {
199 String l = super.readLine(skipLF);
200 skipLF = false;
201 if (l != null)
202 lineNumber++;
203 return l;
204 }
205 }
206
207 /** Maximum skip-buffer size */
208 private static final int maxSkipBufferSize = 8192;
209
210 /** Skip buffer, null until allocated */
211 private char skipBuffer[] = null;
212
213 /**
214 * Skip characters.
215 *
216 * @param n
217 * The number of characters to skip
218 *
219 * @return The number of characters actually skipped
220 *
221 * @throws IOException
222 * If an I/O error occurs
223 *
224 * @throws IllegalArgumentException
225 * If <tt>n</tt> is negative
226 */
227 public long skip(long n) throws IOException {
228 if (n < 0)
229 throw new IllegalArgumentException("skip() value is negative");
230 int nn = (int) Math.min(n, maxSkipBufferSize);
231 synchronized (lock) {
232 if ((skipBuffer == null) || (skipBuffer.length < nn))
233 skipBuffer = new char[nn];
234 long r = n;
235 while (r > 0) {
236 int nc = read(skipBuffer, 0, (int) Math.min(r, nn));
237 if (nc == -1)
238 break;
239 r -= nc;
240 }
241 return n - r;
242 }
243 }
244
245 /**
246 * Mark the present position in the stream. Subsequent calls to reset()
247 * will attempt to reposition the stream to this point, and will also reset
248 * the line number appropriately.
249 *
250 * @param readAheadLimit
251 * Limit on the number of characters that may be read while still
252 * preserving the mark. After reading this many characters,
253 * attempting to reset the stream may fail.
254 *
255 * @throws IOException
256 * If an I/O error occurs
257 */
258 public void mark(int readAheadLimit) throws IOException {
259 synchronized (lock) {
260 super.mark(readAheadLimit);
261 markedLineNumber = lineNumber;
262 markedSkipLF = skipLF;
263 }
264 }
265
266 /**
267 * Reset the stream to the most recent mark.
268 *
269 * @throws IOException
270 * If the stream has not been marked, or if the mark has been
271 * invalidated
272 */
273 public void reset() throws IOException {
274 synchronized (lock) {
275 super.reset();
276 lineNumber = markedLineNumber;
277 skipLF = markedSkipLF;
278 }
279 }
280
281}
java/pkg/java/io/NotActiveException.class+0−0

Binary file not shown.

java/pkg/java/io/NotActiveException.java+53−0
@@ -0,0 +1,53 @@
1/*
2 * Copyright (c) 1996, 2005, 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
26package java.io;
27
28/**
29 * Thrown when serialization or deserialization is not active.
30 *
31 * @author unascribed
32 * @since JDK1.1
33 */
34public class NotActiveException extends ObjectStreamException {
35
36 private static final long serialVersionUID = -3893467273049808895L;
37
38 /**
39 * Constructor to create a new NotActiveException with the reason given.
40 *
41 * @param reason a String describing the reason for the exception.
42 */
43 public NotActiveException(String reason) {
44 super(reason);
45 }
46
47 /**
48 * Constructor to create a new NotActiveException without a reason.
49 */
50 public NotActiveException() {
51 super();
52 }
53}
java/pkg/java/io/NotSerializableException.class+0−0

Binary file not shown.

java/pkg/java/io/NotSerializableException.java+55−0
@@ -0,0 +1,55 @@
1/*
2 * Copyright (c) 1996, 2005, 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
26package java.io;
27
28/**
29 * Thrown when an instance is required to have a Serializable interface.
30 * The serialization runtime or the class of the instance can throw
31 * this exception. The argument should be the name of the class.
32 *
33 * @author unascribed
34 * @since JDK1.1
35 */
36public class NotSerializableException extends ObjectStreamException {
37
38 private static final long serialVersionUID = 2906642554793891381L;
39
40 /**
41 * Constructs a NotSerializableException object with message string.
42 *
43 * @param classname Class of the instance being serialized/deserialized.
44 */
45 public NotSerializableException(String classname) {
46 super(classname);
47 }
48
49 /**
50 * Constructs a NotSerializableException object.
51 */
52 public NotSerializableException() {
53 super();
54 }
55}
java/pkg/java/io/ObjectInput.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectInput.java+107−0
@@ -0,0 +1,107 @@
1/*
2 * Copyright (c) 1996, 2010, 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
26package java.io;
27
28/**
29 * ObjectInput extends the DataInput interface to include the reading of
30 * objects. DataInput includes methods for the input of primitive types,
31 * ObjectInput extends that interface to include objects, arrays, and Strings.
32 *
33 * @author unascribed
34 * @see java.io.InputStream
35 * @see java.io.ObjectOutputStream
36 * @see java.io.ObjectInputStream
37 * @since JDK1.1
38 */
39public interface ObjectInput extends DataInput, AutoCloseable {
40 /**
41 * Read and return an object. The class that implements this interface
42 * defines where the object is "read" from.
43 *
44 * @return the object read from the stream
45 * @exception java.lang.ClassNotFoundException If the class of a serialized
46 * object cannot be found.
47 * @exception IOException If any of the usual Input/Output
48 * related exceptions occur.
49 */
50 public Object readObject()
51 throws ClassNotFoundException, IOException;
52
53 /**
54 * Reads a byte of data. This method will block if no input is
55 * available.
56 * @return the byte read, or -1 if the end of the
57 * stream is reached.
58 * @exception IOException If an I/O error has occurred.
59 */
60 public int read() throws IOException;
61
62 /**
63 * Reads into an array of bytes. This method will
64 * block until some input is available.
65 * @param b the buffer into which the data is read
66 * @return the actual number of bytes read, -1 is
67 * returned when the end of the stream is reached.
68 * @exception IOException If an I/O error has occurred.
69 */
70 public int read(byte b[]) throws IOException;
71
72 /**
73 * Reads into an array of bytes. This method will
74 * block until some input is available.
75 * @param b the buffer into which the data is read
76 * @param off the start offset of the data
77 * @param len the maximum number of bytes read
78 * @return the actual number of bytes read, -1 is
79 * returned when the end of the stream is reached.
80 * @exception IOException If an I/O error has occurred.
81 */
82 public int read(byte b[], int off, int len) throws IOException;
83
84 /**
85 * Skips n bytes of input.
86 * @param n the number of bytes to be skipped
87 * @return the actual number of bytes skipped.
88 * @exception IOException If an I/O error has occurred.
89 */
90 public long skip(long n) throws IOException;
91
92 /**
93 * Returns the number of bytes that can be read
94 * without blocking.
95 * @return the number of available bytes.
96 * @exception IOException If an I/O error has occurred.
97 */
98 public int available() throws IOException;
99
100 /**
101 * Closes the input stream. Must be called
102 * to release any resources associated with
103 * the stream.
104 * @exception IOException If an I/O error has occurred.
105 */
106 public void close() throws IOException;
107}
java/pkg/java/io/ObjectInputStream$1.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectInputStream$BlockDataInputStream.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectInputStream$Caches.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectInputStream$GetField.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectInputStream$GetFieldImpl.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectInputStream$HandleTable$HandleList.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectInputStream$HandleTable.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectInputStream$PeekInputStream.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectInputStream$ValidationList$1.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectInputStream$ValidationList$Callback.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectInputStream$ValidationList.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectInputStream.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectInputStream.java+3508−0
@@ -0,0 +1,3508 @@
1/*
2 * Copyright (c) 1996, 2010, 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
26package java.io;
27
28import java.io.ObjectStreamClass.WeakClassKey;
29import java.lang.ref.ReferenceQueue;
30import java.lang.reflect.Array;
31import java.lang.reflect.Modifier;
32import java.lang.reflect.Proxy;
33import java.security.AccessControlContext;
34import java.security.AccessController;
35import java.security.PrivilegedAction;
36import java.security.PrivilegedActionException;
37import java.security.PrivilegedExceptionAction;
38import java.util.Arrays;
39import java.util.HashMap;
40import java.util.concurrent.ConcurrentHashMap;
41import java.util.concurrent.ConcurrentMap;
42import java.util.concurrent.atomic.AtomicBoolean;
43import static java.io.ObjectStreamClass.processQueue;
44
45/**
46 * An ObjectInputStream deserializes primitive data and objects previously
47 * written using an ObjectOutputStream.
48 *
49 * <p>ObjectOutputStream and ObjectInputStream can provide an application with
50 * persistent storage for graphs of objects when used with a FileOutputStream
51 * and FileInputStream respectively. ObjectInputStream is used to recover
52 * those objects previously serialized. Other uses include passing objects
53 * between hosts using a socket stream or for marshaling and unmarshaling
54 * arguments and parameters in a remote communication system.
55 *
56 * <p>ObjectInputStream ensures that the types of all objects in the graph
57 * created from the stream match the classes present in the Java Virtual
58 * Machine. Classes are loaded as required using the standard mechanisms.
59 *
60 * <p>Only objects that support the java.io.Serializable or
61 * java.io.Externalizable interface can be read from streams.
62 *
63 * <p>The method <code>readObject</code> is used to read an object from the
64 * stream. Java's safe casting should be used to get the desired type. In
65 * Java, strings and arrays are objects and are treated as objects during
66 * serialization. When read they need to be cast to the expected type.
67 *
68 * <p>Primitive data types can be read from the stream using the appropriate
69 * method on DataInput.
70 *
71 * <p>The default deserialization mechanism for objects restores the contents
72 * of each field to the value and type it had when it was written. Fields
73 * declared as transient or static are ignored by the deserialization process.
74 * References to other objects cause those objects to be read from the stream
75 * as necessary. Graphs of objects are restored correctly using a reference
76 * sharing mechanism. New objects are always allocated when deserializing,
77 * which prevents existing objects from being overwritten.
78 *
79 * <p>Reading an object is analogous to running the constructors of a new
80 * object. Memory is allocated for the object and initialized to zero (NULL).
81 * No-arg constructors are invoked for the non-serializable classes and then
82 * the fields of the serializable classes are restored from the stream starting
83 * with the serializable class closest to java.lang.object and finishing with
84 * the object's most specific class.
85 *
86 * <p>For example to read from a stream as written by the example in
87 * ObjectOutputStream:
88 * <br>
89 * <pre>
90 * FileInputStream fis = new FileInputStream("t.tmp");
91 * ObjectInputStream ois = new ObjectInputStream(fis);
92 *
93 * int i = ois.readInt();
94 * String today = (String) ois.readObject();
95 * Date date = (Date) ois.readObject();
96 *
97 * ois.close();
98 * </pre>
99 *
100 * <p>Classes control how they are serialized by implementing either the
101 * java.io.Serializable or java.io.Externalizable interfaces.
102 *
103 * <p>Implementing the Serializable interface allows object serialization to
104 * save and restore the entire state of the object and it allows classes to
105 * evolve between the time the stream is written and the time it is read. It
106 * automatically traverses references between objects, saving and restoring
107 * entire graphs.
108 *
109 * <p>Serializable classes that require special handling during the
110 * serialization and deserialization process should implement the following
111 * methods:<p>
112 *
113 * <pre>
114 * private void writeObject(java.io.ObjectOutputStream stream)
115 * throws IOException;
116 * private void readObject(java.io.ObjectInputStream stream)
117 * throws IOException, ClassNotFoundException;
118 * private void readObjectNoData()
119 * throws ObjectStreamException;
120 * </pre>
121 *
122 * <p>The readObject method is responsible for reading and restoring the state
123 * of the object for its particular class using data written to the stream by
124 * the corresponding writeObject method. The method does not need to concern
125 * itself with the state belonging to its superclasses or subclasses. State is
126 * restored by reading data from the ObjectInputStream for the individual
127 * fields and making assignments to the appropriate fields of the object.
128 * Reading primitive data types is supported by DataInput.
129 *
130 * <p>Any attempt to read object data which exceeds the boundaries of the
131 * custom data written by the corresponding writeObject method will cause an
132 * OptionalDataException to be thrown with an eof field value of true.
133 * Non-object reads which exceed the end of the allotted data will reflect the
134 * end of data in the same way that they would indicate the end of the stream:
135 * bytewise reads will return -1 as the byte read or number of bytes read, and
136 * primitive reads will throw EOFExceptions. If there is no corresponding
137 * writeObject method, then the end of default serialized data marks the end of
138 * the allotted data.
139 *
140 * <p>Primitive and object read calls issued from within a readExternal method
141 * behave in the same manner--if the stream is already positioned at the end of
142 * data written by the corresponding writeExternal method, object reads will
143 * throw OptionalDataExceptions with eof set to true, bytewise reads will
144 * return -1, and primitive reads will throw EOFExceptions. Note that this
145 * behavior does not hold for streams written with the old
146 * <code>ObjectStreamConstants.PROTOCOL_VERSION_1</code> protocol, in which the
147 * end of data written by writeExternal methods is not demarcated, and hence
148 * cannot be detected.
149 *
150 * <p>The readObjectNoData method is responsible for initializing the state of
151 * the object for its particular class in the event that the serialization
152 * stream does not list the given class as a superclass of the object being
153 * deserialized. This may occur in cases where the receiving party uses a
154 * different version of the deserialized instance's class than the sending
155 * party, and the receiver's version extends classes that are not extended by
156 * the sender's version. This may also occur if the serialization stream has
157 * been tampered; hence, readObjectNoData is useful for initializing
158 * deserialized objects properly despite a "hostile" or incomplete source
159 * stream.
160 *
161 * <p>Serialization does not read or assign values to the fields of any object
162 * that does not implement the java.io.Serializable interface. Subclasses of
163 * Objects that are not serializable can be serializable. In this case the
164 * non-serializable class must have a no-arg constructor to allow its fields to
165 * be initialized. In this case it is the responsibility of the subclass to
166 * save and restore the state of the non-serializable class. It is frequently
167 * the case that the fields of that class are accessible (public, package, or
168 * protected) or that there are get and set methods that can be used to restore
169 * the state.
170 *
171 * <p>Any exception that occurs while deserializing an object will be caught by
172 * the ObjectInputStream and abort the reading process.
173 *
174 * <p>Implementing the Externalizable interface allows the object to assume
175 * complete control over the contents and format of the object's serialized
176 * form. The methods of the Externalizable interface, writeExternal and
177 * readExternal, are called to save and restore the objects state. When
178 * implemented by a class they can write and read their own state using all of
179 * the methods of ObjectOutput and ObjectInput. It is the responsibility of
180 * the objects to handle any versioning that occurs.
181 *
182 * <p>Enum constants are deserialized differently than ordinary serializable or
183 * externalizable objects. The serialized form of an enum constant consists
184 * solely of its name; field values of the constant are not transmitted. To
185 * deserialize an enum constant, ObjectInputStream reads the constant name from
186 * the stream; the deserialized constant is then obtained by calling the static
187 * method <code>Enum.valueOf(Class, String)</code> with the enum constant's
188 * base type and the received constant name as arguments. Like other
189 * serializable or externalizable objects, enum constants can function as the
190 * targets of back references appearing subsequently in the serialization
191 * stream. The process by which enum constants are deserialized cannot be
192 * customized: any class-specific readObject, readObjectNoData, and readResolve
193 * methods defined by enum types are ignored during deserialization.
194 * Similarly, any serialPersistentFields or serialVersionUID field declarations
195 * are also ignored--all enum types have a fixed serialVersionUID of 0L.
196 *
197 * @author Mike Warres
198 * @author Roger Riggs
199 * @see java.io.DataInput
200 * @see java.io.ObjectOutputStream
201 * @see java.io.Serializable
202 * @see <a href="../../../platform/serialization/spec/input.html"> Object Serialization Specification, Section 3, Object Input Classes</a>
203 * @since JDK1.1
204 */
205public class ObjectInputStream
206 extends InputStream implements ObjectInput, ObjectStreamConstants
207{
208 /** handle value representing null */
209 private static final int NULL_HANDLE = -1;
210
211 /** marker for unshared objects in internal handle table */
212 private static final Object unsharedMarker = new Object();
213
214 /** table mapping primitive type names to corresponding class objects */
215 private static final HashMap<String, Class<?>> primClasses
216 = new HashMap<>(8, 1.0F);
217 static {
218 primClasses.put("boolean", boolean.class);
219 primClasses.put("byte", byte.class);
220 primClasses.put("char", char.class);
221 primClasses.put("short", short.class);
222 primClasses.put("int", int.class);
223 primClasses.put("long", long.class);
224 primClasses.put("float", float.class);
225 primClasses.put("double", double.class);
226 primClasses.put("void", void.class);
227 }
228
229 private static class Caches {
230 /** cache of subclass security audit results */
231 static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits =
232 new ConcurrentHashMap<>();
233
234 /** queue for WeakReferences to audited subclasses */
235 static final ReferenceQueue<Class<?>> subclassAuditsQueue =
236 new ReferenceQueue<>();
237 }
238
239 /** filter stream for handling block data conversion */
240 private final BlockDataInputStream bin;
241 /** validation callback list */
242 private final ValidationList vlist;
243 /** recursion depth */
244 private int depth;
245 /** whether stream is closed */
246 private boolean closed;
247
248 /** wire handle -> obj/exception map */
249 private final HandleTable handles;
250 /** scratch field for passing handle values up/down call stack */
251 private int passHandle = NULL_HANDLE;
252 /** flag set when at end of field value block with no TC_ENDBLOCKDATA */
253 private boolean defaultDataEnd = false;
254
255 /** buffer for reading primitive field values */
256 private byte[] primVals;
257
258 /** if true, invoke readObjectOverride() instead of readObject() */
259 private final boolean enableOverride;
260 /** if true, invoke resolveObject() */
261 private boolean enableResolve;
262
263 /**
264 * Context during upcalls to class-defined readObject methods; holds
265 * object currently being deserialized and descriptor for current class.
266 * Null when not during readObject upcall.
267 */
268 private SerialCallbackContext curContext;
269
270 /**
271 * Creates an ObjectInputStream that reads from the specified InputStream.
272 * A serialization stream header is read from the stream and verified.
273 * This constructor will block until the corresponding ObjectOutputStream
274 * has written and flushed the header.
275 *
276 * <p>If a security manager is installed, this constructor will check for
277 * the "enableSubclassImplementation" SerializablePermission when invoked
278 * directly or indirectly by the constructor of a subclass which overrides
279 * the ObjectInputStream.readFields or ObjectInputStream.readUnshared
280 * methods.
281 *
282 * @param in input stream to read from
283 * @throws StreamCorruptedException if the stream header is incorrect
284 * @throws IOException if an I/O error occurs while reading stream header
285 * @throws SecurityException if untrusted subclass illegally overrides
286 * security-sensitive methods
287 * @throws NullPointerException if <code>in</code> is <code>null</code>
288 * @see ObjectInputStream#ObjectInputStream()
289 * @see ObjectInputStream#readFields()
290 * @see ObjectOutputStream#ObjectOutputStream(OutputStream)
291 */
292 public ObjectInputStream(InputStream in) throws IOException {
293 verifySubclass();
294 bin = new BlockDataInputStream(in);
295 handles = new HandleTable(10);
296 vlist = new ValidationList();
297 enableOverride = false;
298 readStreamHeader();
299 bin.setBlockDataMode(true);
300 }
301
302 /**
303 * Provide a way for subclasses that are completely reimplementing
304 * ObjectInputStream to not have to allocate private data just used by this
305 * implementation of ObjectInputStream.
306 *
307 * <p>If there is a security manager installed, this method first calls the
308 * security manager's <code>checkPermission</code> method with the
309 * <code>SerializablePermission("enableSubclassImplementation")</code>
310 * permission to ensure it's ok to enable subclassing.
311 *
312 * @throws SecurityException if a security manager exists and its
313 * <code>checkPermission</code> method denies enabling
314 * subclassing.
315 * @see SecurityManager#checkPermission
316 * @see java.io.SerializablePermission
317 */
318 protected ObjectInputStream() throws IOException, SecurityException {
319 SecurityManager sm = System.getSecurityManager();
320 if (sm != null) {
321 sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
322 }
323 bin = null;
324 handles = null;
325 vlist = null;
326 enableOverride = true;
327 }
328
329 /**
330 * Read an object from the ObjectInputStream. The class of the object, the
331 * signature of the class, and the values of the non-transient and
332 * non-static fields of the class and all of its supertypes are read.
333 * Default deserializing for a class can be overriden using the writeObject
334 * and readObject methods. Objects referenced by this object are read
335 * transitively so that a complete equivalent graph of objects is
336 * reconstructed by readObject.
337 *
338 * <p>The root object is completely restored when all of its fields and the
339 * objects it references are completely restored. At this point the object
340 * validation callbacks are executed in order based on their registered
341 * priorities. The callbacks are registered by objects (in the readObject
342 * special methods) as they are individually restored.
343 *
344 * <p>Exceptions are thrown for problems with the InputStream and for
345 * classes that should not be deserialized. All exceptions are fatal to
346 * the InputStream and leave it in an indeterminate state; it is up to the
347 * caller to ignore or recover the stream state.
348 *
349 * @throws ClassNotFoundException Class of a serialized object cannot be
350 * found.
351 * @throws InvalidClassException Something is wrong with a class used by
352 * serialization.
353 * @throws StreamCorruptedException Control information in the
354 * stream is inconsistent.
355 * @throws OptionalDataException Primitive data was found in the
356 * stream instead of objects.
357 * @throws IOException Any of the usual Input/Output related exceptions.
358 */
359 public final Object readObject()
360 throws IOException, ClassNotFoundException
361 {
362 if (enableOverride) {
363 return readObjectOverride();
364 }
365
366 // if nested read, passHandle contains handle of enclosing object
367 int outerHandle = passHandle;
368 try {
369 Object obj = readObject0(false);
370 handles.markDependency(outerHandle, passHandle);
371 ClassNotFoundException ex = handles.lookupException(passHandle);
372 if (ex != null) {
373 throw ex;
374 }
375 if (depth == 0) {
376 vlist.doCallbacks();
377 }
378 return obj;
379 } finally {
380 passHandle = outerHandle;
381 if (closed && depth == 0) {
382 clear();
383 }
384 }
385 }
386
387 /**
388 * This method is called by trusted subclasses of ObjectOutputStream that
389 * constructed ObjectOutputStream using the protected no-arg constructor.
390 * The subclass is expected to provide an override method with the modifier
391 * "final".
392 *
393 * @return the Object read from the stream.
394 * @throws ClassNotFoundException Class definition of a serialized object
395 * cannot be found.
396 * @throws OptionalDataException Primitive data was found in the stream
397 * instead of objects.
398 * @throws IOException if I/O errors occurred while reading from the
399 * underlying stream
400 * @see #ObjectInputStream()
401 * @see #readObject()
402 * @since 1.2
403 */
404 protected Object readObjectOverride()
405 throws IOException, ClassNotFoundException
406 {
407 return null;
408 }
409
410 /**
411 * Reads an "unshared" object from the ObjectInputStream. This method is
412 * identical to readObject, except that it prevents subsequent calls to
413 * readObject and readUnshared from returning additional references to the
414 * deserialized instance obtained via this call. Specifically:
415 * <ul>
416 * <li>If readUnshared is called to deserialize a back-reference (the
417 * stream representation of an object which has been written
418 * previously to the stream), an ObjectStreamException will be
419 * thrown.
420 *
421 * <li>If readUnshared returns successfully, then any subsequent attempts
422 * to deserialize back-references to the stream handle deserialized
423 * by readUnshared will cause an ObjectStreamException to be thrown.
424 * </ul>
425 * Deserializing an object via readUnshared invalidates the stream handle
426 * associated with the returned object. Note that this in itself does not
427 * always guarantee that the reference returned by readUnshared is unique;
428 * the deserialized object may define a readResolve method which returns an
429 * object visible to other parties, or readUnshared may return a Class
430 * object or enum constant obtainable elsewhere in the stream or through
431 * external means. If the deserialized object defines a readResolve method
432 * and the invocation of that method returns an array, then readUnshared
433 * returns a shallow clone of that array; this guarantees that the returned
434 * array object is unique and cannot be obtained a second time from an
435 * invocation of readObject or readUnshared on the ObjectInputStream,
436 * even if the underlying data stream has been manipulated.
437 *
438 * <p>ObjectInputStream subclasses which override this method can only be
439 * constructed in security contexts possessing the
440 * "enableSubclassImplementation" SerializablePermission; any attempt to
441 * instantiate such a subclass without this permission will cause a
442 * SecurityException to be thrown.
443 *
444 * @return reference to deserialized object
445 * @throws ClassNotFoundException if class of an object to deserialize
446 * cannot be found
447 * @throws StreamCorruptedException if control information in the stream
448 * is inconsistent
449 * @throws ObjectStreamException if object to deserialize has already
450 * appeared in stream
451 * @throws OptionalDataException if primitive data is next in stream
452 * @throws IOException if an I/O error occurs during deserialization
453 * @since 1.4
454 */
455 public Object readUnshared() throws IOException, ClassNotFoundException {
456 // if nested read, passHandle contains handle of enclosing object
457 int outerHandle = passHandle;
458 try {
459 Object obj = readObject0(true);
460 handles.markDependency(outerHandle, passHandle);
461 ClassNotFoundException ex = handles.lookupException(passHandle);
462 if (ex != null) {
463 throw ex;
464 }
465 if (depth == 0) {
466 vlist.doCallbacks();
467 }
468 return obj;
469 } finally {
470 passHandle = outerHandle;
471 if (closed && depth == 0) {
472 clear();
473 }
474 }
475 }
476
477 /**
478 * Read the non-static and non-transient fields of the current class from
479 * this stream. This may only be called from the readObject method of the
480 * class being deserialized. It will throw the NotActiveException if it is
481 * called otherwise.
482 *
483 * @throws ClassNotFoundException if the class of a serialized object
484 * could not be found.
485 * @throws IOException if an I/O error occurs.
486 * @throws NotActiveException if the stream is not currently reading
487 * objects.
488 */
489 public void defaultReadObject()
490 throws IOException, ClassNotFoundException
491 {
492 if (curContext == null) {
493 throw new NotActiveException("not in call to readObject");
494 }
495 Object curObj = curContext.getObj();
496 ObjectStreamClass curDesc = curContext.getDesc();
497 bin.setBlockDataMode(false);
498 defaultReadFields(curObj, curDesc);
499 bin.setBlockDataMode(true);
500 if (!curDesc.hasWriteObjectData()) {
501 /*
502 * Fix for 4360508: since stream does not contain terminating
503 * TC_ENDBLOCKDATA tag, set flag so that reading code elsewhere
504 * knows to simulate end-of-custom-data behavior.
505 */
506 defaultDataEnd = true;
507 }
508 ClassNotFoundException ex = handles.lookupException(passHandle);
509 if (ex != null) {
510 throw ex;
511 }
512 }
513
514 /**
515 * Reads the persistent fields from the stream and makes them available by
516 * name.
517 *
518 * @return the <code>GetField</code> object representing the persistent
519 * fields of the object being deserialized
520 * @throws ClassNotFoundException if the class of a serialized object
521 * could not be found.
522 * @throws IOException if an I/O error occurs.
523 * @throws NotActiveException if the stream is not currently reading
524 * objects.
525 * @since 1.2
526 */
527 public ObjectInputStream.GetField readFields()
528 throws IOException, ClassNotFoundException
529 {
530 if (curContext == null) {
531 throw new NotActiveException("not in call to readObject");
532 }
533 Object curObj = curContext.getObj();
534 ObjectStreamClass curDesc = curContext.getDesc();
535 bin.setBlockDataMode(false);
536 GetFieldImpl getField = new GetFieldImpl(curDesc);
537 getField.readFields();
538 bin.setBlockDataMode(true);
539 if (!curDesc.hasWriteObjectData()) {
540 /*
541 * Fix for 4360508: since stream does not contain terminating
542 * TC_ENDBLOCKDATA tag, set flag so that reading code elsewhere
543 * knows to simulate end-of-custom-data behavior.
544 */
545 defaultDataEnd = true;
546 }
547
548 return getField;
549 }
550
551 /**
552 * Register an object to be validated before the graph is returned. While
553 * similar to resolveObject these validations are called after the entire
554 * graph has been reconstituted. Typically, a readObject method will
555 * register the object with the stream so that when all of the objects are
556 * restored a final set of validations can be performed.
557 *
558 * @param obj the object to receive the validation callback.
559 * @param prio controls the order of callbacks;zero is a good default.
560 * Use higher numbers to be called back earlier, lower numbers for
561 * later callbacks. Within a priority, callbacks are processed in
562 * no particular order.
563 * @throws NotActiveException The stream is not currently reading objects
564 * so it is invalid to register a callback.
565 * @throws InvalidObjectException The validation object is null.
566 */
567 public void registerValidation(ObjectInputValidation obj, int prio)
568 throws NotActiveException, InvalidObjectException
569 {
570 if (depth == 0) {
571 throw new NotActiveException("stream inactive");
572 }
573 vlist.register(obj, prio);
574 }
575
576 /**
577 * Load the local class equivalent of the specified stream class
578 * description. Subclasses may implement this method to allow classes to
579 * be fetched from an alternate source.
580 *
581 * <p>The corresponding method in <code>ObjectOutputStream</code> is
582 * <code>annotateClass</code>. This method will be invoked only once for
583 * each unique class in the stream. This method can be implemented by
584 * subclasses to use an alternate loading mechanism but must return a
585 * <code>Class</code> object. Once returned, if the class is not an array
586 * class, its serialVersionUID is compared to the serialVersionUID of the
587 * serialized class, and if there is a mismatch, the deserialization fails
588 * and an {@link InvalidClassException} is thrown.
589 *
590 * <p>The default implementation of this method in
591 * <code>ObjectInputStream</code> returns the result of calling
592 * <pre>
593 * Class.forName(desc.getName(), false, loader)
594 * </pre>
595 * where <code>loader</code> is determined as follows: if there is a
596 * method on the current thread's stack whose declaring class was
597 * defined by a user-defined class loader (and was not a generated to
598 * implement reflective invocations), then <code>loader</code> is class
599 * loader corresponding to the closest such method to the currently
600 * executing frame; otherwise, <code>loader</code> is
601 * <code>null</code>. If this call results in a
602 * <code>ClassNotFoundException</code> and the name of the passed
603 * <code>ObjectStreamClass</code> instance is the Java language keyword
604 * for a primitive type or void, then the <code>Class</code> object
605 * representing that primitive type or void will be returned
606 * (e.g., an <code>ObjectStreamClass</code> with the name
607 * <code>"int"</code> will be resolved to <code>Integer.TYPE</code>).
608 * Otherwise, the <code>ClassNotFoundException</code> will be thrown to
609 * the caller of this method.
610 *
611 * @param desc an instance of class <code>ObjectStreamClass</code>
612 * @return a <code>Class</code> object corresponding to <code>desc</code>
613 * @throws IOException any of the usual Input/Output exceptions.
614 * @throws ClassNotFoundException if class of a serialized object cannot
615 * be found.
616 */
617 protected Class<?> resolveClass(ObjectStreamClass desc)
618 throws IOException, ClassNotFoundException
619 {
620 String name = desc.getName();
621 try {
622 return Class.forName(name, false, latestUserDefinedLoader());
623 } catch (ClassNotFoundException ex) {
624 Class<?> cl = primClasses.get(name);
625 if (cl != null) {
626 return cl;
627 } else {
628 throw ex;
629 }
630 }
631 }
632
633 /**
634 * Returns a proxy class that implements the interfaces named in a proxy
635 * class descriptor; subclasses may implement this method to read custom
636 * data from the stream along with the descriptors for dynamic proxy
637 * classes, allowing them to use an alternate loading mechanism for the
638 * interfaces and the proxy class.
639 *
640 * <p>This method is called exactly once for each unique proxy class
641 * descriptor in the stream.
642 *
643 * <p>The corresponding method in <code>ObjectOutputStream</code> is
644 * <code>annotateProxyClass</code>. For a given subclass of
645 * <code>ObjectInputStream</code> that overrides this method, the
646 * <code>annotateProxyClass</code> method in the corresponding subclass of
647 * <code>ObjectOutputStream</code> must write any data or objects read by
648 * this method.
649 *
650 * <p>The default implementation of this method in
651 * <code>ObjectInputStream</code> returns the result of calling
652 * <code>Proxy.getProxyClass</code> with the list of <code>Class</code>
653 * objects for the interfaces that are named in the <code>interfaces</code>
654 * parameter. The <code>Class</code> object for each interface name
655 * <code>i</code> is the value returned by calling
656 * <pre>
657 * Class.forName(i, false, loader)
658 * </pre>
659 * where <code>loader</code> is that of the first non-<code>null</code>
660 * class loader up the execution stack, or <code>null</code> if no
661 * non-<code>null</code> class loaders are on the stack (the same class
662 * loader choice used by the <code>resolveClass</code> method). Unless any
663 * of the resolved interfaces are non-public, this same value of
664 * <code>loader</code> is also the class loader passed to
665 * <code>Proxy.getProxyClass</code>; if non-public interfaces are present,
666 * their class loader is passed instead (if more than one non-public
667 * interface class loader is encountered, an
668 * <code>IllegalAccessError</code> is thrown).
669 * If <code>Proxy.getProxyClass</code> throws an
670 * <code>IllegalArgumentException</code>, <code>resolveProxyClass</code>
671 * will throw a <code>ClassNotFoundException</code> containing the
672 * <code>IllegalArgumentException</code>.
673 *
674 * @param interfaces the list of interface names that were
675 * deserialized in the proxy class descriptor
676 * @return a proxy class for the specified interfaces
677 * @throws IOException any exception thrown by the underlying
678 * <code>InputStream</code>
679 * @throws ClassNotFoundException if the proxy class or any of the
680 * named interfaces could not be found
681 * @see ObjectOutputStream#annotateProxyClass(Class)
682 * @since 1.3
683 */
684 protected Class<?> resolveProxyClass(String[] interfaces)
685 throws IOException, ClassNotFoundException
686 {
687 ClassLoader latestLoader = latestUserDefinedLoader();
688 ClassLoader nonPublicLoader = null;
689 boolean hasNonPublicInterface = false;
690
691 // define proxy in class loader of non-public interface(s), if any
692 Class[] classObjs = new Class[interfaces.length];
693 for (int i = 0; i < interfaces.length; i++) {
694 Class cl = Class.forName(interfaces[i], false, latestLoader);
695 if ((cl.getModifiers() & Modifier.PUBLIC) == 0) {
696 if (hasNonPublicInterface) {
697 if (nonPublicLoader != cl.getClassLoader()) {
698 throw new IllegalAccessError(
699 "conflicting non-public interface class loaders");
700 }
701 } else {
702 nonPublicLoader = cl.getClassLoader();
703 hasNonPublicInterface = true;
704 }
705 }
706 classObjs[i] = cl;
707 }
708 try {
709 return Proxy.getProxyClass(
710 hasNonPublicInterface ? nonPublicLoader : latestLoader,
711 classObjs);
712 } catch (IllegalArgumentException e) {
713 throw new ClassNotFoundException(null, e);
714 }
715 }
716
717 /**
718 * This method will allow trusted subclasses of ObjectInputStream to
719 * substitute one object for another during deserialization. Replacing
720 * objects is disabled until enableResolveObject is called. The
721 * enableResolveObject method checks that the stream requesting to resolve
722 * object can be trusted. Every reference to serializable objects is passed
723 * to resolveObject. To insure that the private state of objects is not
724 * unintentionally exposed only trusted streams may use resolveObject.
725 *
726 * <p>This method is called after an object has been read but before it is
727 * returned from readObject. The default resolveObject method just returns
728 * the same object.
729 *
730 * <p>When a subclass is replacing objects it must insure that the
731 * substituted object is compatible with every field where the reference
732 * will be stored. Objects whose type is not a subclass of the type of the
733 * field or array element abort the serialization by raising an exception
734 * and the object is not be stored.
735 *
736 * <p>This method is called only once when each object is first
737 * encountered. All subsequent references to the object will be redirected
738 * to the new object.
739 *
740 * @param obj object to be substituted
741 * @return the substituted object
742 * @throws IOException Any of the usual Input/Output exceptions.
743 */
744 protected Object resolveObject(Object obj) throws IOException {
745 return obj;
746 }
747
748 /**
749 * Enable the stream to allow objects read from the stream to be replaced.
750 * When enabled, the resolveObject method is called for every object being
751 * deserialized.
752 *
753 * <p>If <i>enable</i> is true, and there is a security manager installed,
754 * this method first calls the security manager's
755 * <code>checkPermission</code> method with the
756 * <code>SerializablePermission("enableSubstitution")</code> permission to
757 * ensure it's ok to enable the stream to allow objects read from the
758 * stream to be replaced.
759 *
760 * @param enable true for enabling use of <code>resolveObject</code> for
761 * every object being deserialized
762 * @return the previous setting before this method was invoked
763 * @throws SecurityException if a security manager exists and its
764 * <code>checkPermission</code> method denies enabling the stream
765 * to allow objects read from the stream to be replaced.
766 * @see SecurityManager#checkPermission
767 * @see java.io.SerializablePermission
768 */
769 protected boolean enableResolveObject(boolean enable)
770 throws SecurityException
771 {
772 if (enable == enableResolve) {
773 return enable;
774 }
775 if (enable) {
776 SecurityManager sm = System.getSecurityManager();
777 if (sm != null) {
778 sm.checkPermission(SUBSTITUTION_PERMISSION);
779 }
780 }
781 enableResolve = enable;
782 return !enableResolve;
783 }
784
785 /**
786 * The readStreamHeader method is provided to allow subclasses to read and
787 * verify their own stream headers. It reads and verifies the magic number
788 * and version number.
789 *
790 * @throws IOException if there are I/O errors while reading from the
791 * underlying <code>InputStream</code>
792 * @throws StreamCorruptedException if control information in the stream
793 * is inconsistent
794 */
795 protected void readStreamHeader()
796 throws IOException, StreamCorruptedException
797 {
798 short s0 = bin.readShort();
799 short s1 = bin.readShort();
800 if (s0 != STREAM_MAGIC || s1 != STREAM_VERSION) {
801 throw new StreamCorruptedException(
802 String.format("invalid stream header: %04X%04X", s0, s1));
803 }
804 }
805
806 /**
807 * Read a class descriptor from the serialization stream. This method is
808 * called when the ObjectInputStream expects a class descriptor as the next
809 * item in the serialization stream. Subclasses of ObjectInputStream may
810 * override this method to read in class descriptors that have been written
811 * in non-standard formats (by subclasses of ObjectOutputStream which have
812 * overridden the <code>writeClassDescriptor</code> method). By default,
813 * this method reads class descriptors according to the format defined in
814 * the Object Serialization specification.
815 *
816 * @return the class descriptor read
817 * @throws IOException If an I/O error has occurred.
818 * @throws ClassNotFoundException If the Class of a serialized object used
819 * in the class descriptor representation cannot be found
820 * @see java.io.ObjectOutputStream#writeClassDescriptor(java.io.ObjectStreamClass)
821 * @since 1.3
822 */
823 protected ObjectStreamClass readClassDescriptor()
824 throws IOException, ClassNotFoundException
825 {
826 ObjectStreamClass desc = new ObjectStreamClass();
827 desc.readNonProxy(this);
828 return desc;
829 }
830
831 /**
832 * Reads a byte of data. This method will block if no input is available.
833 *
834 * @return the byte read, or -1 if the end of the stream is reached.
835 * @throws IOException If an I/O error has occurred.
836 */
837 public int read() throws IOException {
838 return bin.read();
839 }
840
841 /**
842 * Reads into an array of bytes. This method will block until some input
843 * is available. Consider using java.io.DataInputStream.readFully to read
844 * exactly 'length' bytes.
845 *
846 * @param buf the buffer into which the data is read
847 * @param off the start offset of the data
848 * @param len the maximum number of bytes read
849 * @return the actual number of bytes read, -1 is returned when the end of
850 * the stream is reached.
851 * @throws IOException If an I/O error has occurred.
852 * @see java.io.DataInputStream#readFully(byte[],int,int)
853 */
854 public int read(byte[] buf, int off, int len) throws IOException {
855 if (buf == null) {
856 throw new NullPointerException();
857 }
858 int endoff = off + len;
859 if (off < 0 || len < 0 || endoff > buf.length || endoff < 0) {
860 throw new IndexOutOfBoundsException();
861 }
862 return bin.read(buf, off, len, false);
863 }
864
865 /**
866 * Returns the number of bytes that can be read without blocking.
867 *
868 * @return the number of available bytes.
869 * @throws IOException if there are I/O errors while reading from the
870 * underlying <code>InputStream</code>
871 */
872 public int available() throws IOException {
873 return bin.available();
874 }
875
876 /**
877 * Closes the input stream. Must be called to release any resources
878 * associated with the stream.
879 *
880 * @throws IOException If an I/O error has occurred.
881 */
882 public void close() throws IOException {
883 /*
884 * Even if stream already closed, propagate redundant close to
885 * underlying stream to stay consistent with previous implementations.
886 */
887 closed = true;
888 if (depth == 0) {
889 clear();
890 }
891 bin.close();
892 }
893
894 /**
895 * Reads in a boolean.
896 *
897 * @return the boolean read.
898 * @throws EOFException If end of file is reached.
899 * @throws IOException If other I/O error has occurred.
900 */
901 public boolean readBoolean() throws IOException {
902 return bin.readBoolean();
903 }
904
905 /**
906 * Reads an 8 bit byte.
907 *
908 * @return the 8 bit byte read.
909 * @throws EOFException If end of file is reached.
910 * @throws IOException If other I/O error has occurred.
911 */
912 public byte readByte() throws IOException {
913 return bin.readByte();
914 }
915
916 /**
917 * Reads an unsigned 8 bit byte.
918 *
919 * @return the 8 bit byte read.
920 * @throws EOFException If end of file is reached.
921 * @throws IOException If other I/O error has occurred.
922 */
923 public int readUnsignedByte() throws IOException {
924 return bin.readUnsignedByte();
925 }
926
927 /**
928 * Reads a 16 bit char.
929 *
930 * @return the 16 bit char read.
931 * @throws EOFException If end of file is reached.
932 * @throws IOException If other I/O error has occurred.
933 */
934 public char readChar() throws IOException {
935 return bin.readChar();
936 }
937
938 /**
939 * Reads a 16 bit short.
940 *
941 * @return the 16 bit short read.
942 * @throws EOFException If end of file is reached.
943 * @throws IOException If other I/O error has occurred.
944 */
945 public short readShort() throws IOException {
946 return bin.readShort();
947 }
948
949 /**
950 * Reads an unsigned 16 bit short.
951 *
952 * @return the 16 bit short read.
953 * @throws EOFException If end of file is reached.
954 * @throws IOException If other I/O error has occurred.
955 */
956 public int readUnsignedShort() throws IOException {
957 return bin.readUnsignedShort();
958 }
959
960 /**
961 * Reads a 32 bit int.
962 *
963 * @return the 32 bit integer read.
964 * @throws EOFException If end of file is reached.
965 * @throws IOException If other I/O error has occurred.
966 */
967 public int readInt() throws IOException {
968 return bin.readInt();
969 }
970
971 /**
972 * Reads a 64 bit long.
973 *
974 * @return the read 64 bit long.
975 * @throws EOFException If end of file is reached.
976 * @throws IOException If other I/O error has occurred.
977 */
978 public long readLong() throws IOException {
979 return bin.readLong();
980 }
981
982 /**
983 * Reads a 32 bit float.
984 *
985 * @return the 32 bit float read.
986 * @throws EOFException If end of file is reached.
987 * @throws IOException If other I/O error has occurred.
988 */
989 public float readFloat() throws IOException {
990 return bin.readFloat();
991 }
992
993 /**
994 * Reads a 64 bit double.
995 *
996 * @return the 64 bit double read.
997 * @throws EOFException If end of file is reached.
998 * @throws IOException If other I/O error has occurred.
999 */
1000 public double readDouble() throws IOException {
1001 return bin.readDouble();
1002 }
1003
1004 /**
1005 * Reads bytes, blocking until all bytes are read.
1006 *
1007 * @param buf the buffer into which the data is read
1008 * @throws EOFException If end of file is reached.
1009 * @throws IOException If other I/O error has occurred.
1010 */
1011 public void readFully(byte[] buf) throws IOException {
1012 bin.readFully(buf, 0, buf.length, false);
1013 }
1014
1015 /**
1016 * Reads bytes, blocking until all bytes are read.
1017 *
1018 * @param buf the buffer into which the data is read
1019 * @param off the start offset of the data
1020 * @param len the maximum number of bytes to read
1021 * @throws EOFException If end of file is reached.
1022 * @throws IOException If other I/O error has occurred.
1023 */
1024 public void readFully(byte[] buf, int off, int len) throws IOException {
1025 int endoff = off + len;
1026 if (off < 0 || len < 0 || endoff > buf.length || endoff < 0) {
1027 throw new IndexOutOfBoundsException();
1028 }
1029 bin.readFully(buf, off, len, false);
1030 }
1031
1032 /**
1033 * Skips bytes.
1034 *
1035 * @param len the number of bytes to be skipped
1036 * @return the actual number of bytes skipped.
1037 * @throws IOException If an I/O error has occurred.
1038 */
1039 public int skipBytes(int len) throws IOException {
1040 return bin.skipBytes(len);
1041 }
1042
1043 /**
1044 * Reads in a line that has been terminated by a \n, \r, \r\n or EOF.
1045 *
1046 * @return a String copy of the line.
1047 * @throws IOException if there are I/O errors while reading from the
1048 * underlying <code>InputStream</code>
1049 * @deprecated This method does not properly convert bytes to characters.
1050 * see DataInputStream for the details and alternatives.
1051 */
1052 @Deprecated
1053 public String readLine() throws IOException {
1054 return bin.readLine();
1055 }
1056
1057 /**
1058 * Reads a String in
1059 * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
1060 * format.
1061 *
1062 * @return the String.
1063 * @throws IOException if there are I/O errors while reading from the
1064 * underlying <code>InputStream</code>
1065 * @throws UTFDataFormatException if read bytes do not represent a valid
1066 * modified UTF-8 encoding of a string
1067 */
1068 public String readUTF() throws IOException {
1069 return bin.readUTF();
1070 }
1071
1072 /**
1073 * Provide access to the persistent fields read from the input stream.
1074 */
1075 public static abstract class GetField {
1076
1077 /**
1078 * Get the ObjectStreamClass that describes the fields in the stream.
1079 *
1080 * @return the descriptor class that describes the serializable fields
1081 */
1082 public abstract ObjectStreamClass getObjectStreamClass();
1083
1084 /**
1085 * Return true if the named field is defaulted and has no value in this
1086 * stream.
1087 *
1088 * @param name the name of the field
1089 * @return true, if and only if the named field is defaulted
1090 * @throws IOException if there are I/O errors while reading from
1091 * the underlying <code>InputStream</code>
1092 * @throws IllegalArgumentException if <code>name</code> does not
1093 * correspond to a serializable field
1094 */
1095 public abstract boolean defaulted(String name) throws IOException;
1096
1097 /**
1098 * Get the value of the named boolean field from the persistent field.
1099 *
1100 * @param name the name of the field
1101 * @param val the default value to use if <code>name</code> does not
1102 * have a value
1103 * @return the value of the named <code>boolean</code> field
1104 * @throws IOException if there are I/O errors while reading from the
1105 * underlying <code>InputStream</code>
1106 * @throws IllegalArgumentException if type of <code>name</code> is
1107 * not serializable or if the field type is incorrect
1108 */
1109 public abstract boolean get(String name, boolean val)
1110 throws IOException;
1111
1112 /**
1113 * Get the value of the named byte field from the persistent field.
1114 *
1115 * @param name the name of the field
1116 * @param val the default value to use if <code>name</code> does not
1117 * have a value
1118 * @return the value of the named <code>byte</code> field
1119 * @throws IOException if there are I/O errors while reading from the
1120 * underlying <code>InputStream</code>
1121 * @throws IllegalArgumentException if type of <code>name</code> is
1122 * not serializable or if the field type is incorrect
1123 */
1124 public abstract byte get(String name, byte val) throws IOException;
1125
1126 /**
1127 * Get the value of the named char field from the persistent field.
1128 *
1129 * @param name the name of the field
1130 * @param val the default value to use if <code>name</code> does not
1131 * have a value
1132 * @return the value of the named <code>char</code> field
1133 * @throws IOException if there are I/O errors while reading from the
1134 * underlying <code>InputStream</code>
1135 * @throws IllegalArgumentException if type of <code>name</code> is
1136 * not serializable or if the field type is incorrect
1137 */
1138 public abstract char get(String name, char val) throws IOException;
1139
1140 /**
1141 * Get the value of the named short field from the persistent field.
1142 *
1143 * @param name the name of the field
1144 * @param val the default value to use if <code>name</code> does not
1145 * have a value
1146 * @return the value of the named <code>short</code> field
1147 * @throws IOException if there are I/O errors while reading from the
1148 * underlying <code>InputStream</code>
1149 * @throws IllegalArgumentException if type of <code>name</code> is
1150 * not serializable or if the field type is incorrect
1151 */
1152 public abstract short get(String name, short val) throws IOException;
1153
1154 /**
1155 * Get the value of the named int field from the persistent field.
1156 *
1157 * @param name the name of the field
1158 * @param val the default value to use if <code>name</code> does not
1159 * have a value
1160 * @return the value of the named <code>int</code> field
1161 * @throws IOException if there are I/O errors while reading from the
1162 * underlying <code>InputStream</code>
1163 * @throws IllegalArgumentException if type of <code>name</code> is
1164 * not serializable or if the field type is incorrect
1165 */
1166 public abstract int get(String name, int val) throws IOException;
1167
1168 /**
1169 * Get the value of the named long field from the persistent field.
1170 *
1171 * @param name the name of the field
1172 * @param val the default value to use if <code>name</code> does not
1173 * have a value
1174 * @return the value of the named <code>long</code> field
1175 * @throws IOException if there are I/O errors while reading from the
1176 * underlying <code>InputStream</code>
1177 * @throws IllegalArgumentException if type of <code>name</code> is
1178 * not serializable or if the field type is incorrect
1179 */
1180 public abstract long get(String name, long val) throws IOException;
1181
1182 /**
1183 * Get the value of the named float field from the persistent field.
1184 *
1185 * @param name the name of the field
1186 * @param val the default value to use if <code>name</code> does not
1187 * have a value
1188 * @return the value of the named <code>float</code> field
1189 * @throws IOException if there are I/O errors while reading from the
1190 * underlying <code>InputStream</code>
1191 * @throws IllegalArgumentException if type of <code>name</code> is
1192 * not serializable or if the field type is incorrect
1193 */
1194 public abstract float get(String name, float val) throws IOException;
1195
1196 /**
1197 * Get the value of the named double field from the persistent field.
1198 *
1199 * @param name the name of the field
1200 * @param val the default value to use if <code>name</code> does not
1201 * have a value
1202 * @return the value of the named <code>double</code> field
1203 * @throws IOException if there are I/O errors while reading from the
1204 * underlying <code>InputStream</code>
1205 * @throws IllegalArgumentException if type of <code>name</code> is
1206 * not serializable or if the field type is incorrect
1207 */
1208 public abstract double get(String name, double val) throws IOException;
1209
1210 /**
1211 * Get the value of the named Object field from the persistent field.
1212 *
1213 * @param name the name of the field
1214 * @param val the default value to use if <code>name</code> does not
1215 * have a value
1216 * @return the value of the named <code>Object</code> field
1217 * @throws IOException if there are I/O errors while reading from the
1218 * underlying <code>InputStream</code>
1219 * @throws IllegalArgumentException if type of <code>name</code> is
1220 * not serializable or if the field type is incorrect
1221 */
1222 public abstract Object get(String name, Object val) throws IOException;
1223 }
1224
1225 /**
1226 * Verifies that this (possibly subclass) instance can be constructed
1227 * without violating security constraints: the subclass must not override
1228 * security-sensitive non-final methods, or else the
1229 * "enableSubclassImplementation" SerializablePermission is checked.
1230 */
1231 private void verifySubclass() {
1232 Class cl = getClass();
1233 if (cl == ObjectInputStream.class) {
1234 return;
1235 }
1236 SecurityManager sm = System.getSecurityManager();
1237 if (sm == null) {
1238 return;
1239 }
1240 processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
1241 WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
1242 Boolean result = Caches.subclassAudits.get(key);
1243 if (result == null) {
1244 result = Boolean.valueOf(auditSubclass(cl));
1245 Caches.subclassAudits.putIfAbsent(key, result);
1246 }
1247 if (result.booleanValue()) {
1248 return;
1249 }
1250 sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
1251 }
1252
1253 /**
1254 * Performs reflective checks on given subclass to verify that it doesn't
1255 * override security-sensitive non-final methods. Returns true if subclass
1256 * is "safe", false otherwise.
1257 */
1258 private static boolean auditSubclass(final Class<?> subcl) {
1259 Boolean result = AccessController.doPrivileged(
1260 new PrivilegedAction<Boolean>() {
1261 public Boolean run() {
1262 for (Class<?> cl = subcl;
1263 cl != ObjectInputStream.class;
1264 cl = cl.getSuperclass())
1265 {
1266 try {
1267 cl.getDeclaredMethod(
1268 "readUnshared", (Class[]) null);
1269 return Boolean.FALSE;
1270 } catch (NoSuchMethodException ex) {
1271 }
1272 try {
1273 cl.getDeclaredMethod("readFields", (Class[]) null);
1274 return Boolean.FALSE;
1275 } catch (NoSuchMethodException ex) {
1276 }
1277 }
1278 return Boolean.TRUE;
1279 }
1280 }
1281 );
1282 return result.booleanValue();
1283 }
1284
1285 /**
1286 * Clears internal data structures.
1287 */
1288 private void clear() {
1289 handles.clear();
1290 vlist.clear();
1291 }
1292
1293 /**
1294 * Underlying readObject implementation.
1295 */
1296 private Object readObject0(boolean unshared) throws IOException {
1297 boolean oldMode = bin.getBlockDataMode();
1298 if (oldMode) {
1299 int remain = bin.currentBlockRemaining();
1300 if (remain > 0) {
1301 throw new OptionalDataException(remain);
1302 } else if (defaultDataEnd) {
1303 /*
1304 * Fix for 4360508: stream is currently at the end of a field
1305 * value block written via default serialization; since there
1306 * is no terminating TC_ENDBLOCKDATA tag, simulate
1307 * end-of-custom-data behavior explicitly.
1308 */
1309 throw new OptionalDataException(true);
1310 }
1311 bin.setBlockDataMode(false);
1312 }
1313
1314 byte tc;
1315 while ((tc = bin.peekByte()) == TC_RESET) {
1316 bin.readByte();
1317 handleReset();
1318 }
1319
1320 depth++;
1321 try {
1322 switch (tc) {
1323 case TC_NULL:
1324 return readNull();
1325
1326 case TC_REFERENCE:
1327 return readHandle(unshared);
1328
1329 case TC_CLASS:
1330 return readClass(unshared);
1331
1332 case TC_CLASSDESC:
1333 case TC_PROXYCLASSDESC:
1334 return readClassDesc(unshared);
1335
1336 case TC_STRING:
1337 case TC_LONGSTRING:
1338 return checkResolve(readString(unshared));
1339
1340 case TC_ARRAY:
1341 return checkResolve(readArray(unshared));
1342
1343 case TC_ENUM:
1344 return checkResolve(readEnum(unshared));
1345
1346 case TC_OBJECT:
1347 return checkResolve(readOrdinaryObject(unshared));
1348
1349 case TC_EXCEPTION:
1350 IOException ex = readFatalException();
1351 throw new WriteAbortedException("writing aborted", ex);
1352
1353 case TC_BLOCKDATA:
1354 case TC_BLOCKDATALONG:
1355 if (oldMode) {
1356 bin.setBlockDataMode(true);
1357 bin.peek(); // force header read
1358 throw new OptionalDataException(
1359 bin.currentBlockRemaining());
1360 } else {
1361 throw new StreamCorruptedException(
1362 "unexpected block data");
1363 }
1364
1365 case TC_ENDBLOCKDATA:
1366 if (oldMode) {
1367 throw new OptionalDataException(true);
1368 } else {
1369 throw new StreamCorruptedException(
1370 "unexpected end of block data");
1371 }
1372
1373 default:
1374 throw new StreamCorruptedException(
1375 String.format("invalid type code: %02X", tc));
1376 }
1377 } finally {
1378 depth--;
1379 bin.setBlockDataMode(oldMode);
1380 }
1381 }
1382
1383 /**
1384 * If resolveObject has been enabled and given object does not have an
1385 * exception associated with it, calls resolveObject to determine
1386 * replacement for object, and updates handle table accordingly. Returns
1387 * replacement object, or echoes provided object if no replacement
1388 * occurred. Expects that passHandle is set to given object's handle prior
1389 * to calling this method.
1390 */
1391 private Object checkResolve(Object obj) throws IOException {
1392 if (!enableResolve || handles.lookupException(passHandle) != null) {
1393 return obj;
1394 }
1395 Object rep = resolveObject(obj);
1396 if (rep != obj) {
1397 handles.setObject(passHandle, rep);
1398 }
1399 return rep;
1400 }
1401
1402 /**
1403 * Reads string without allowing it to be replaced in stream. Called from
1404 * within ObjectStreamClass.read().
1405 */
1406 String readTypeString() throws IOException {
1407 int oldHandle = passHandle;
1408 try {
1409 byte tc = bin.peekByte();
1410 switch (tc) {
1411 case TC_NULL:
1412 return (String) readNull();
1413
1414 case TC_REFERENCE:
1415 return (String) readHandle(false);
1416
1417 case TC_STRING:
1418 case TC_LONGSTRING:
1419 return readString(false);
1420
1421 default:
1422 throw new StreamCorruptedException(
1423 String.format("invalid type code: %02X", tc));
1424 }
1425 } finally {
1426 passHandle = oldHandle;
1427 }
1428 }
1429
1430 /**
1431 * Reads in null code, sets passHandle to NULL_HANDLE and returns null.
1432 */
1433 private Object readNull() throws IOException {
1434 if (bin.readByte() != TC_NULL) {
1435 throw new InternalError();
1436 }
1437 passHandle = NULL_HANDLE;
1438 return null;
1439 }
1440
1441 /**
1442 * Reads in object handle, sets passHandle to the read handle, and returns
1443 * object associated with the handle.
1444 */
1445 private Object readHandle(boolean unshared) throws IOException {
1446 if (bin.readByte() != TC_REFERENCE) {
1447 throw new InternalError();
1448 }
1449 passHandle = bin.readInt() - baseWireHandle;
1450 if (passHandle < 0 || passHandle >= handles.size()) {
1451 throw new StreamCorruptedException(
1452 String.format("invalid handle value: %08X", passHandle +
1453 baseWireHandle));
1454 }
1455 if (unshared) {
1456 // REMIND: what type of exception to throw here?
1457 throw new InvalidObjectException(
1458 "cannot read back reference as unshared");
1459 }
1460
1461 Object obj = handles.lookupObject(passHandle);
1462 if (obj == unsharedMarker) {
1463 // REMIND: what type of exception to throw here?
1464 throw new InvalidObjectException(
1465 "cannot read back reference to unshared object");
1466 }
1467 return obj;
1468 }
1469
1470 /**
1471 * Reads in and returns class object. Sets passHandle to class object's
1472 * assigned handle. Returns null if class is unresolvable (in which case a
1473 * ClassNotFoundException will be associated with the class' handle in the
1474 * handle table).
1475 */
1476 private Class readClass(boolean unshared) throws IOException {
1477 if (bin.readByte() != TC_CLASS) {
1478 throw new InternalError();
1479 }
1480 ObjectStreamClass desc = readClassDesc(false);
1481 Class cl = desc.forClass();
1482 passHandle = handles.assign(unshared ? unsharedMarker : cl);
1483
1484 ClassNotFoundException resolveEx = desc.getResolveException();
1485 if (resolveEx != null) {
1486 handles.markException(passHandle, resolveEx);
1487 }
1488
1489 handles.finish(passHandle);
1490 return cl;
1491 }
1492
1493 /**
1494 * Reads in and returns (possibly null) class descriptor. Sets passHandle
1495 * to class descriptor's assigned handle. If class descriptor cannot be
1496 * resolved to a class in the local VM, a ClassNotFoundException is
1497 * associated with the class descriptor's handle.
1498 */
1499 private ObjectStreamClass readClassDesc(boolean unshared)
1500 throws IOException
1501 {
1502 byte tc = bin.peekByte();
1503 switch (tc) {
1504 case TC_NULL:
1505 return (ObjectStreamClass) readNull();
1506
1507 case TC_REFERENCE:
1508 return (ObjectStreamClass) readHandle(unshared);
1509
1510 case TC_PROXYCLASSDESC:
1511 return readProxyDesc(unshared);
1512
1513 case TC_CLASSDESC:
1514 return readNonProxyDesc(unshared);
1515
1516 default:
1517 throw new StreamCorruptedException(
1518 String.format("invalid type code: %02X", tc));
1519 }
1520 }
1521
1522 /**
1523 * Reads in and returns class descriptor for a dynamic proxy class. Sets
1524 * passHandle to proxy class descriptor's assigned handle. If proxy class
1525 * descriptor cannot be resolved to a class in the local VM, a
1526 * ClassNotFoundException is associated with the descriptor's handle.
1527 */
1528 private ObjectStreamClass readProxyDesc(boolean unshared)
1529 throws IOException
1530 {
1531 if (bin.readByte() != TC_PROXYCLASSDESC) {
1532 throw new InternalError();
1533 }
1534
1535 ObjectStreamClass desc = new ObjectStreamClass();
1536 int descHandle = handles.assign(unshared ? unsharedMarker : desc);
1537 passHandle = NULL_HANDLE;
1538
1539 int numIfaces = bin.readInt();
1540 String[] ifaces = new String[numIfaces];
1541 for (int i = 0; i < numIfaces; i++) {
1542 ifaces[i] = bin.readUTF();
1543 }
1544
1545 Class cl = null;
1546 ClassNotFoundException resolveEx = null;
1547 bin.setBlockDataMode(true);
1548 try {
1549 if ((cl = resolveProxyClass(ifaces)) == null) {
1550 resolveEx = new ClassNotFoundException("null class");
1551 }
1552 } catch (ClassNotFoundException ex) {
1553 resolveEx = ex;
1554 }
1555 skipCustomData();
1556
1557 desc.initProxy(cl, resolveEx, readClassDesc(false));
1558
1559 handles.finish(descHandle);
1560 passHandle = descHandle;
1561 return desc;
1562 }
1563
1564 /**
1565 * Reads in and returns class descriptor for a class that is not a dynamic
1566 * proxy class. Sets passHandle to class descriptor's assigned handle. If
1567 * class descriptor cannot be resolved to a class in the local VM, a
1568 * ClassNotFoundException is associated with the descriptor's handle.
1569 */
1570 private ObjectStreamClass readNonProxyDesc(boolean unshared)
1571 throws IOException
1572 {
1573 if (bin.readByte() != TC_CLASSDESC) {
1574 throw new InternalError();
1575 }
1576
1577 ObjectStreamClass desc = new ObjectStreamClass();
1578 int descHandle = handles.assign(unshared ? unsharedMarker : desc);
1579 passHandle = NULL_HANDLE;
1580
1581 ObjectStreamClass readDesc = null;
1582 try {
1583 readDesc = readClassDescriptor();
1584 } catch (ClassNotFoundException ex) {
1585 throw (IOException) new InvalidClassException(
1586 "failed to read class descriptor").initCause(ex);
1587 }
1588
1589 Class cl = null;
1590 ClassNotFoundException resolveEx = null;
1591 bin.setBlockDataMode(true);
1592 try {
1593 if ((cl = resolveClass(readDesc)) == null) {
1594 resolveEx = new ClassNotFoundException("null class");
1595 }
1596 } catch (ClassNotFoundException ex) {
1597 resolveEx = ex;
1598 }
1599 skipCustomData();
1600
1601 desc.initNonProxy(readDesc, cl, resolveEx, readClassDesc(false));
1602
1603 handles.finish(descHandle);
1604 passHandle = descHandle;
1605 return desc;
1606 }
1607
1608 /**
1609 * Reads in and returns new string. Sets passHandle to new string's
1610 * assigned handle.
1611 */
1612 private String readString(boolean unshared) throws IOException {
1613 String str;
1614 byte tc = bin.readByte();
1615 switch (tc) {
1616 case TC_STRING:
1617 str = bin.readUTF();
1618 break;
1619
1620 case TC_LONGSTRING:
1621 str = bin.readLongUTF();
1622 break;
1623
1624 default:
1625 throw new StreamCorruptedException(
1626 String.format("invalid type code: %02X", tc));
1627 }
1628 passHandle = handles.assign(unshared ? unsharedMarker : str);
1629 handles.finish(passHandle);
1630 return str;
1631 }
1632
1633 /**
1634 * Reads in and returns array object, or null if array class is
1635 * unresolvable. Sets passHandle to array's assigned handle.
1636 */
1637 private Object readArray(boolean unshared) throws IOException {
1638 if (bin.readByte() != TC_ARRAY) {
1639 throw new InternalError();
1640 }
1641
1642 ObjectStreamClass desc = readClassDesc(false);
1643 int len = bin.readInt();
1644
1645 Object array = null;
1646 Class cl, ccl = null;
1647 if ((cl = desc.forClass()) != null) {
1648 ccl = cl.getComponentType();
1649 array = Array.newInstance(ccl, len);
1650 }
1651
1652 int arrayHandle = handles.assign(unshared ? unsharedMarker : array);
1653 ClassNotFoundException resolveEx = desc.getResolveException();
1654 if (resolveEx != null) {
1655 handles.markException(arrayHandle, resolveEx);
1656 }
1657
1658 if (ccl == null) {
1659 for (int i = 0; i < len; i++) {
1660 readObject0(false);
1661 }
1662 } else if (ccl.isPrimitive()) {
1663 if (ccl == Integer.TYPE) {
1664 bin.readInts((int[]) array, 0, len);
1665 } else if (ccl == Byte.TYPE) {
1666 bin.readFully((byte[]) array, 0, len, true);
1667 } else if (ccl == Long.TYPE) {
1668 bin.readLongs((long[]) array, 0, len);
1669 } else if (ccl == Float.TYPE) {
1670 bin.readFloats((float[]) array, 0, len);
1671 } else if (ccl == Double.TYPE) {
1672 bin.readDoubles((double[]) array, 0, len);
1673 } else if (ccl == Short.TYPE) {
1674 bin.readShorts((short[]) array, 0, len);
1675 } else if (ccl == Character.TYPE) {
1676 bin.readChars((char[]) array, 0, len);
1677 } else if (ccl == Boolean.TYPE) {
1678 bin.readBooleans((boolean[]) array, 0, len);
1679 } else {
1680 throw new InternalError();
1681 }
1682 } else {
1683 Object[] oa = (Object[]) array;
1684 for (int i = 0; i < len; i++) {
1685 oa[i] = readObject0(false);
1686 handles.markDependency(arrayHandle, passHandle);
1687 }
1688 }
1689
1690 handles.finish(arrayHandle);
1691 passHandle = arrayHandle;
1692 return array;
1693 }
1694
1695 /**
1696 * Reads in and returns enum constant, or null if enum type is
1697 * unresolvable. Sets passHandle to enum constant's assigned handle.
1698 */
1699 private Enum readEnum(boolean unshared) throws IOException {
1700 if (bin.readByte() != TC_ENUM) {
1701 throw new InternalError();
1702 }
1703
1704 ObjectStreamClass desc = readClassDesc(false);
1705 if (!desc.isEnum()) {
1706 throw new InvalidClassException("non-enum class: " + desc);
1707 }
1708
1709 int enumHandle = handles.assign(unshared ? unsharedMarker : null);
1710 ClassNotFoundException resolveEx = desc.getResolveException();
1711 if (resolveEx != null) {
1712 handles.markException(enumHandle, resolveEx);
1713 }
1714
1715 String name = readString(false);
1716 Enum en = null;
1717 Class cl = desc.forClass();
1718 if (cl != null) {
1719 try {
1720 en = Enum.valueOf(cl, name);
1721 } catch (IllegalArgumentException ex) {
1722 throw (IOException) new InvalidObjectException(
1723 "enum constant " + name + " does not exist in " +
1724 cl).initCause(ex);
1725 }
1726 if (!unshared) {
1727 handles.setObject(enumHandle, en);
1728 }
1729 }
1730
1731 handles.finish(enumHandle);
1732 passHandle = enumHandle;
1733 return en;
1734 }
1735
1736 /**
1737 * Reads and returns "ordinary" (i.e., not a String, Class,
1738 * ObjectStreamClass, array, or enum constant) object, or null if object's
1739 * class is unresolvable (in which case a ClassNotFoundException will be
1740 * associated with object's handle). Sets passHandle to object's assigned
1741 * handle.
1742 */
1743 private Object readOrdinaryObject(boolean unshared)
1744 throws IOException
1745 {
1746 if (bin.readByte() != TC_OBJECT) {
1747 throw new InternalError();
1748 }
1749
1750 ObjectStreamClass desc = readClassDesc(false);
1751 desc.checkDeserialize();
1752
1753 Object obj;
1754 try {
1755 obj = desc.isInstantiable() ? desc.newInstance() : null;
1756 } catch (Exception ex) {
1757 throw (IOException) new InvalidClassException(
1758 desc.forClass().getName(),
1759 "unable to create instance").initCause(ex);
1760 }
1761
1762 passHandle = handles.assign(unshared ? unsharedMarker : obj);
1763 ClassNotFoundException resolveEx = desc.getResolveException();
1764 if (resolveEx != null) {
1765 handles.markException(passHandle, resolveEx);
1766 }
1767
1768 if (desc.isExternalizable()) {
1769 readExternalData((Externalizable) obj, desc);
1770 } else {
1771 readSerialData(obj, desc);
1772 }
1773
1774 handles.finish(passHandle);
1775
1776 if (obj != null &&
1777 handles.lookupException(passHandle) == null &&
1778 desc.hasReadResolveMethod())
1779 {
1780 Object rep = desc.invokeReadResolve(obj);
1781 if (unshared && rep.getClass().isArray()) {
1782 rep = cloneArray(rep);
1783 }
1784 if (rep != obj) {
1785 handles.setObject(passHandle, obj = rep);
1786 }
1787 }
1788
1789 return obj;
1790 }
1791
1792 /**
1793 * If obj is non-null, reads externalizable data by invoking readExternal()
1794 * method of obj; otherwise, attempts to skip over externalizable data.
1795 * Expects that passHandle is set to obj's handle before this method is
1796 * called.
1797 */
1798 private void readExternalData(Externalizable obj, ObjectStreamClass desc)
1799 throws IOException
1800 {
1801 SerialCallbackContext oldContext = curContext;
1802 curContext = null;
1803 try {
1804 boolean blocked = desc.hasBlockExternalData();
1805 if (blocked) {
1806 bin.setBlockDataMode(true);
1807 }
1808 if (obj != null) {
1809 try {
1810 obj.readExternal(this);
1811 } catch (ClassNotFoundException ex) {
1812 /*
1813 * In most cases, the handle table has already propagated
1814 * a CNFException to passHandle at this point; this mark
1815 * call is included to address cases where the readExternal
1816 * method has cons'ed and thrown a new CNFException of its
1817 * own.
1818 */
1819 handles.markException(passHandle, ex);
1820 }
1821 }
1822 if (blocked) {
1823 skipCustomData();
1824 }
1825 } finally {
1826 curContext = oldContext;
1827 }
1828 /*
1829 * At this point, if the externalizable data was not written in
1830 * block-data form and either the externalizable class doesn't exist
1831 * locally (i.e., obj == null) or readExternal() just threw a
1832 * CNFException, then the stream is probably in an inconsistent state,
1833 * since some (or all) of the externalizable data may not have been
1834 * consumed. Since there's no "correct" action to take in this case,
1835 * we mimic the behavior of past serialization implementations and
1836 * blindly hope that the stream is in sync; if it isn't and additional
1837 * externalizable data remains in the stream, a subsequent read will
1838 * most likely throw a StreamCorruptedException.
1839 */
1840 }
1841
1842 /**
1843 * Reads (or attempts to skip, if obj is null or is tagged with a
1844 * ClassNotFoundException) instance data for each serializable class of
1845 * object in stream, from superclass to subclass. Expects that passHandle
1846 * is set to obj's handle before this method is called.
1847 */
1848 private void readSerialData(Object obj, ObjectStreamClass desc)
1849 throws IOException
1850 {
1851 ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout();
1852 for (int i = 0; i < slots.length; i++) {
1853 ObjectStreamClass slotDesc = slots[i].desc;
1854
1855 if (slots[i].hasData) {
1856 if (obj != null &&
1857 slotDesc.hasReadObjectMethod() &&
1858 handles.lookupException(passHandle) == null)
1859 {
1860 SerialCallbackContext oldContext = curContext;
1861
1862 try {
1863 curContext = new SerialCallbackContext(obj, slotDesc);
1864
1865 bin.setBlockDataMode(true);
1866 slotDesc.invokeReadObject(obj, this);
1867 } catch (ClassNotFoundException ex) {
1868 /*
1869 * In most cases, the handle table has already
1870 * propagated a CNFException to passHandle at this
1871 * point; this mark call is included to address cases
1872 * where the custom readObject method has cons'ed and
1873 * thrown a new CNFException of its own.
1874 */
1875 handles.markException(passHandle, ex);
1876 } finally {
1877 curContext.setUsed();
1878 curContext = oldContext;
1879 }
1880
1881 /*
1882 * defaultDataEnd may have been set indirectly by custom
1883 * readObject() method when calling defaultReadObject() or
1884 * readFields(); clear it to restore normal read behavior.
1885 */
1886 defaultDataEnd = false;
1887 } else {
1888 defaultReadFields(obj, slotDesc);
1889 }
1890 if (slotDesc.hasWriteObjectData()) {
1891 skipCustomData();
1892 } else {
1893 bin.setBlockDataMode(false);
1894 }
1895 } else {
1896 if (obj != null &&
1897 slotDesc.hasReadObjectNoDataMethod() &&
1898 handles.lookupException(passHandle) == null)
1899 {
1900 slotDesc.invokeReadObjectNoData(obj);
1901 }
1902 }
1903 }
1904 }
1905
1906 /**
1907 * Skips over all block data and objects until TC_ENDBLOCKDATA is
1908 * encountered.
1909 */
1910 private void skipCustomData() throws IOException {
1911 int oldHandle = passHandle;
1912 for (;;) {
1913 if (bin.getBlockDataMode()) {
1914 bin.skipBlockData();
1915 bin.setBlockDataMode(false);
1916 }
1917 switch (bin.peekByte()) {
1918 case TC_BLOCKDATA:
1919 case TC_BLOCKDATALONG:
1920 bin.setBlockDataMode(true);
1921 break;
1922
1923 case TC_ENDBLOCKDATA:
1924 bin.readByte();
1925 passHandle = oldHandle;
1926 return;
1927
1928 default:
1929 readObject0(false);
1930 break;
1931 }
1932 }
1933 }
1934
1935 /**
1936 * Reads in values of serializable fields declared by given class
1937 * descriptor. If obj is non-null, sets field values in obj. Expects that
1938 * passHandle is set to obj's handle before this method is called.
1939 */
1940 private void defaultReadFields(Object obj, ObjectStreamClass desc)
1941 throws IOException
1942 {
1943 // REMIND: is isInstance check necessary?
1944 Class cl = desc.forClass();
1945 if (cl != null && obj != null && !cl.isInstance(obj)) {
1946 throw new ClassCastException();
1947 }
1948
1949 int primDataSize = desc.getPrimDataSize();
1950 if (primVals == null || primVals.length < primDataSize) {
1951 primVals = new byte[primDataSize];
1952 }
1953 bin.readFully(primVals, 0, primDataSize, false);
1954 if (obj != null) {
1955 desc.setPrimFieldValues(obj, primVals);
1956 }
1957
1958 int objHandle = passHandle;
1959 ObjectStreamField[] fields = desc.getFields(false);
1960 Object[] objVals = new Object[desc.getNumObjFields()];
1961 int numPrimFields = fields.length - objVals.length;
1962 for (int i = 0; i < objVals.length; i++) {
1963 ObjectStreamField f = fields[numPrimFields + i];
1964 objVals[i] = readObject0(f.isUnshared());
1965 if (f.getField() != null) {
1966 handles.markDependency(objHandle, passHandle);
1967 }
1968 }
1969 if (obj != null) {
1970 desc.setObjFieldValues(obj, objVals);
1971 }
1972 passHandle = objHandle;
1973 }
1974
1975 /**
1976 * Reads in and returns IOException that caused serialization to abort.
1977 * All stream state is discarded prior to reading in fatal exception. Sets
1978 * passHandle to fatal exception's handle.
1979 */
1980 private IOException readFatalException() throws IOException {
1981 if (bin.readByte() != TC_EXCEPTION) {
1982 throw new InternalError();
1983 }
1984 clear();
1985 return (IOException) readObject0(false);
1986 }
1987
1988 /**
1989 * If recursion depth is 0, clears internal data structures; otherwise,
1990 * throws a StreamCorruptedException. This method is called when a
1991 * TC_RESET typecode is encountered.
1992 */
1993 private void handleReset() throws StreamCorruptedException {
1994 if (depth > 0) {
1995 throw new StreamCorruptedException(
1996 "unexpected reset; recursion depth: " + depth);
1997 }
1998 clear();
1999 }
2000
2001 /**
2002 * Converts specified span of bytes into float values.
2003 */
2004 // REMIND: remove once hotspot inlines Float.intBitsToFloat
2005 private static native void bytesToFloats(byte[] src, int srcpos,
2006 float[] dst, int dstpos,
2007 int nfloats);
2008
2009 /**
2010 * Converts specified span of bytes into double values.
2011 */
2012 // REMIND: remove once hotspot inlines Double.longBitsToDouble
2013 private static native void bytesToDoubles(byte[] src, int srcpos,
2014 double[] dst, int dstpos,
2015 int ndoubles);
2016
2017 /**
2018 * Returns the first non-null class loader (not counting class loaders of
2019 * generated reflection implementation classes) up the execution stack, or
2020 * null if only code from the null class loader is on the stack. This
2021 * method is also called via reflection by the following RMI-IIOP class:
2022 *
2023 * com.sun.corba.se.internal.util.JDKClassLoader
2024 *
2025 * This method should not be removed or its signature changed without
2026 * corresponding modifications to the above class.
2027 */
2028 // REMIND: change name to something more accurate?
2029 private static native ClassLoader latestUserDefinedLoader();
2030
2031 /**
2032 * Default GetField implementation.
2033 */
2034 private class GetFieldImpl extends GetField {
2035
2036 /** class descriptor describing serializable fields */
2037 private final ObjectStreamClass desc;
2038 /** primitive field values */
2039 private final byte[] primVals;
2040 /** object field values */
2041 private final Object[] objVals;
2042 /** object field value handles */
2043 private final int[] objHandles;
2044
2045 /**
2046 * Creates GetFieldImpl object for reading fields defined in given
2047 * class descriptor.
2048 */
2049 GetFieldImpl(ObjectStreamClass desc) {
2050 this.desc = desc;
2051 primVals = new byte[desc.getPrimDataSize()];
2052 objVals = new Object[desc.getNumObjFields()];
2053 objHandles = new int[objVals.length];
2054 }
2055
2056 public ObjectStreamClass getObjectStreamClass() {
2057 return desc;
2058 }
2059
2060 public boolean defaulted(String name) throws IOException {
2061 return (getFieldOffset(name, null) < 0);
2062 }
2063
2064 public boolean get(String name, boolean val) throws IOException {
2065 int off = getFieldOffset(name, Boolean.TYPE);
2066 return (off >= 0) ? Bits.getBoolean(primVals, off) : val;
2067 }
2068
2069 public byte get(String name, byte val) throws IOException {
2070 int off = getFieldOffset(name, Byte.TYPE);
2071 return (off >= 0) ? primVals[off] : val;
2072 }
2073
2074 public char get(String name, char val) throws IOException {
2075 int off = getFieldOffset(name, Character.TYPE);
2076 return (off >= 0) ? Bits.getChar(primVals, off) : val;
2077 }
2078
2079 public short get(String name, short val) throws IOException {
2080 int off = getFieldOffset(name, Short.TYPE);
2081 return (off >= 0) ? Bits.getShort(primVals, off) : val;
2082 }
2083
2084 public int get(String name, int val) throws IOException {
2085 int off = getFieldOffset(name, Integer.TYPE);
2086 return (off >= 0) ? Bits.getInt(primVals, off) : val;
2087 }
2088
2089 public float get(String name, float val) throws IOException {
2090 int off = getFieldOffset(name, Float.TYPE);
2091 return (off >= 0) ? Bits.getFloat(primVals, off) : val;
2092 }
2093
2094 public long get(String name, long val) throws IOException {
2095 int off = getFieldOffset(name, Long.TYPE);
2096 return (off >= 0) ? Bits.getLong(primVals, off) : val;
2097 }
2098
2099 public double get(String name, double val) throws IOException {
2100 int off = getFieldOffset(name, Double.TYPE);
2101 return (off >= 0) ? Bits.getDouble(primVals, off) : val;
2102 }
2103
2104 public Object get(String name, Object val) throws IOException {
2105 int off = getFieldOffset(name, Object.class);
2106 if (off >= 0) {
2107 int objHandle = objHandles[off];
2108 handles.markDependency(passHandle, objHandle);
2109 return (handles.lookupException(objHandle) == null) ?
2110 objVals[off] : null;
2111 } else {
2112 return val;
2113 }
2114 }
2115
2116 /**
2117 * Reads primitive and object field values from stream.
2118 */
2119 void readFields() throws IOException {
2120 bin.readFully(primVals, 0, primVals.length, false);
2121
2122 int oldHandle = passHandle;
2123 ObjectStreamField[] fields = desc.getFields(false);
2124 int numPrimFields = fields.length - objVals.length;
2125 for (int i = 0; i < objVals.length; i++) {
2126 objVals[i] =
2127 readObject0(fields[numPrimFields + i].isUnshared());
2128 objHandles[i] = passHandle;
2129 }
2130 passHandle = oldHandle;
2131 }
2132
2133 /**
2134 * Returns offset of field with given name and type. A specified type
2135 * of null matches all types, Object.class matches all non-primitive
2136 * types, and any other non-null type matches assignable types only.
2137 * If no matching field is found in the (incoming) class
2138 * descriptor but a matching field is present in the associated local
2139 * class descriptor, returns -1. Throws IllegalArgumentException if
2140 * neither incoming nor local class descriptor contains a match.
2141 */
2142 private int getFieldOffset(String name, Class type) {
2143 ObjectStreamField field = desc.getField(name, type);
2144 if (field != null) {
2145 return field.getOffset();
2146 } else if (desc.getLocalDesc().getField(name, type) != null) {
2147 return -1;
2148 } else {
2149 throw new IllegalArgumentException("no such field " + name +
2150 " with type " + type);
2151 }
2152 }
2153 }
2154
2155 /**
2156 * Prioritized list of callbacks to be performed once object graph has been
2157 * completely deserialized.
2158 */
2159 private static class ValidationList {
2160
2161 private static class Callback {
2162 final ObjectInputValidation obj;
2163 final int priority;
2164 Callback next;
2165 final AccessControlContext acc;
2166
2167 Callback(ObjectInputValidation obj, int priority, Callback next,
2168 AccessControlContext acc)
2169 {
2170 this.obj = obj;
2171 this.priority = priority;
2172 this.next = next;
2173 this.acc = acc;
2174 }
2175 }
2176
2177 /** linked list of callbacks */
2178 private Callback list;
2179
2180 /**
2181 * Creates new (empty) ValidationList.
2182 */
2183 ValidationList() {
2184 }
2185
2186 /**
2187 * Registers callback. Throws InvalidObjectException if callback
2188 * object is null.
2189 */
2190 void register(ObjectInputValidation obj, int priority)
2191 throws InvalidObjectException
2192 {
2193 if (obj == null) {
2194 throw new InvalidObjectException("null callback");
2195 }
2196
2197 Callback prev = null, cur = list;
2198 while (cur != null && priority < cur.priority) {
2199 prev = cur;
2200 cur = cur.next;
2201 }
2202 AccessControlContext acc = AccessController.getContext();
2203 if (prev != null) {
2204 prev.next = new Callback(obj, priority, cur, acc);
2205 } else {
2206 list = new Callback(obj, priority, list, acc);
2207 }
2208 }
2209
2210 /**
2211 * Invokes all registered callbacks and clears the callback list.
2212 * Callbacks with higher priorities are called first; those with equal
2213 * priorities may be called in any order. If any of the callbacks
2214 * throws an InvalidObjectException, the callback process is terminated
2215 * and the exception propagated upwards.
2216 */
2217 void doCallbacks() throws InvalidObjectException {
2218 try {
2219 while (list != null) {
2220 AccessController.doPrivileged(
2221 new PrivilegedExceptionAction<Void>()
2222 {
2223 public Void run() throws InvalidObjectException {
2224 list.obj.validateObject();
2225 return null;
2226 }
2227 }, list.acc);
2228 list = list.next;
2229 }
2230 } catch (PrivilegedActionException ex) {
2231 list = null;
2232 throw (InvalidObjectException) ex.getException();
2233 }
2234 }
2235
2236 /**
2237 * Resets the callback list to its initial (empty) state.
2238 */
2239 public void clear() {
2240 list = null;
2241 }
2242 }
2243
2244 /**
2245 * Input stream supporting single-byte peek operations.
2246 */
2247 private static class PeekInputStream extends InputStream {
2248
2249 /** underlying stream */
2250 private final InputStream in;
2251 /** peeked byte */
2252 private int peekb = -1;
2253
2254 /**
2255 * Creates new PeekInputStream on top of given underlying stream.
2256 */
2257 PeekInputStream(InputStream in) {
2258 this.in = in;
2259 }
2260
2261 /**
2262 * Peeks at next byte value in stream. Similar to read(), except
2263 * that it does not consume the read value.
2264 */
2265 int peek() throws IOException {
2266 return (peekb >= 0) ? peekb : (peekb = in.read());
2267 }
2268
2269 public int read() throws IOException {
2270 if (peekb >= 0) {
2271 int v = peekb;
2272 peekb = -1;
2273 return v;
2274 } else {
2275 return in.read();
2276 }
2277 }
2278
2279 public int read(byte[] b, int off, int len) throws IOException {
2280 if (len == 0) {
2281 return 0;
2282 } else if (peekb < 0) {
2283 return in.read(b, off, len);
2284 } else {
2285 b[off++] = (byte) peekb;
2286 len--;
2287 peekb = -1;
2288 int n = in.read(b, off, len);
2289 return (n >= 0) ? (n + 1) : 1;
2290 }
2291 }
2292
2293 void readFully(byte[] b, int off, int len) throws IOException {
2294 int n = 0;
2295 while (n < len) {
2296 int count = read(b, off + n, len - n);
2297 if (count < 0) {
2298 throw new EOFException();
2299 }
2300 n += count;
2301 }
2302 }
2303
2304 public long skip(long n) throws IOException {
2305 if (n <= 0) {
2306 return 0;
2307 }
2308 int skipped = 0;
2309 if (peekb >= 0) {
2310 peekb = -1;
2311 skipped++;
2312 n--;
2313 }
2314 return skipped + skip(n);
2315 }
2316
2317 public int available() throws IOException {
2318 return in.available() + ((peekb >= 0) ? 1 : 0);
2319 }
2320
2321 public void close() throws IOException {
2322 in.close();
2323 }
2324 }
2325
2326 /**
2327 * Input stream with two modes: in default mode, inputs data written in the
2328 * same format as DataOutputStream; in "block data" mode, inputs data
2329 * bracketed by block data markers (see object serialization specification
2330 * for details). Buffering depends on block data mode: when in default
2331 * mode, no data is buffered in advance; when in block data mode, all data
2332 * for the current data block is read in at once (and buffered).
2333 */
2334 private class BlockDataInputStream
2335 extends InputStream implements DataInput
2336 {
2337 /** maximum data block length */
2338 private static final int MAX_BLOCK_SIZE = 1024;
2339 /** maximum data block header length */
2340 private static final int MAX_HEADER_SIZE = 5;
2341 /** (tunable) length of char buffer (for reading strings) */
2342 private static final int CHAR_BUF_SIZE = 256;
2343 /** readBlockHeader() return value indicating header read may block */
2344 private static final int HEADER_BLOCKED = -2;
2345
2346 /** buffer for reading general/block data */
2347 private final byte[] buf = new byte[MAX_BLOCK_SIZE];
2348 /** buffer for reading block data headers */
2349 private final byte[] hbuf = new byte[MAX_HEADER_SIZE];
2350 /** char buffer for fast string reads */
2351 private final char[] cbuf = new char[CHAR_BUF_SIZE];
2352
2353 /** block data mode */
2354 private boolean blkmode = false;
2355
2356 // block data state fields; values meaningful only when blkmode true
2357 /** current offset into buf */
2358 private int pos = 0;
2359 /** end offset of valid data in buf, or -1 if no more block data */
2360 private int end = -1;
2361 /** number of bytes in current block yet to be read from stream */
2362 private int unread = 0;
2363
2364 /** underlying stream (wrapped in peekable filter stream) */
2365 private final PeekInputStream in;
2366 /** loopback stream (for data reads that span data blocks) */
2367 private final DataInputStream din;
2368
2369 /**
2370 * Creates new BlockDataInputStream on top of given underlying stream.
2371 * Block data mode is turned off by default.
2372 */
2373 BlockDataInputStream(InputStream in) {
2374 this.in = new PeekInputStream(in);
2375 din = new DataInputStream(this);
2376 }
2377
2378 /**
2379 * Sets block data mode to the given mode (true == on, false == off)
2380 * and returns the previous mode value. If the new mode is the same as
2381 * the old mode, no action is taken. Throws IllegalStateException if
2382 * block data mode is being switched from on to off while unconsumed
2383 * block data is still present in the stream.
2384 */
2385 boolean setBlockDataMode(boolean newmode) throws IOException {
2386 if (blkmode == newmode) {
2387 return blkmode;
2388 }
2389 if (newmode) {
2390 pos = 0;
2391 end = 0;
2392 unread = 0;
2393 } else if (pos < end) {
2394 throw new IllegalStateException("unread block data");
2395 }
2396 blkmode = newmode;
2397 return !blkmode;
2398 }
2399
2400 /**
2401 * Returns true if the stream is currently in block data mode, false
2402 * otherwise.
2403 */
2404 boolean getBlockDataMode() {
2405 return blkmode;
2406 }
2407
2408 /**
2409 * If in block data mode, skips to the end of the current group of data
2410 * blocks (but does not unset block data mode). If not in block data
2411 * mode, throws an IllegalStateException.
2412 */
2413 void skipBlockData() throws IOException {
2414 if (!blkmode) {
2415 throw new IllegalStateException("not in block data mode");
2416 }
2417 while (end >= 0) {
2418 refill();
2419 }
2420 }
2421
2422 /**
2423 * Attempts to read in the next block data header (if any). If
2424 * canBlock is false and a full header cannot be read without possibly
2425 * blocking, returns HEADER_BLOCKED, else if the next element in the
2426 * stream is a block data header, returns the block data length
2427 * specified by the header, else returns -1.
2428 */
2429 private int readBlockHeader(boolean canBlock) throws IOException {
2430 if (defaultDataEnd) {
2431 /*
2432 * Fix for 4360508: stream is currently at the end of a field
2433 * value block written via default serialization; since there
2434 * is no terminating TC_ENDBLOCKDATA tag, simulate
2435 * end-of-custom-data behavior explicitly.
2436 */
2437 return -1;
2438 }
2439 try {
2440 for (;;) {
2441 int avail = canBlock ? Integer.MAX_VALUE : in.available();
2442 if (avail == 0) {
2443 return HEADER_BLOCKED;
2444 }
2445
2446 int tc = in.peek();
2447 switch (tc) {
2448 case TC_BLOCKDATA:
2449 if (avail < 2) {
2450 return HEADER_BLOCKED;
2451 }
2452 in.readFully(hbuf, 0, 2);
2453 return hbuf[1] & 0xFF;
2454
2455 case TC_BLOCKDATALONG:
2456 if (avail < 5) {
2457 return HEADER_BLOCKED;
2458 }
2459 in.readFully(hbuf, 0, 5);
2460 int len = Bits.getInt(hbuf, 1);
2461 if (len < 0) {
2462 throw new StreamCorruptedException(
2463 "illegal block data header length: " +
2464 len);
2465 }
2466 return len;
2467
2468 /*
2469 * TC_RESETs may occur in between data blocks.
2470 * Unfortunately, this case must be parsed at a lower
2471 * level than other typecodes, since primitive data
2472 * reads may span data blocks separated by a TC_RESET.
2473 */
2474 case TC_RESET:
2475 in.read();
2476 handleReset();
2477 break;
2478
2479 default:
2480 if (tc >= 0 && (tc < TC_BASE || tc > TC_MAX)) {
2481 throw new StreamCorruptedException(
2482 String.format("invalid type code: %02X",
2483 tc));
2484 }
2485 return -1;
2486 }
2487 }
2488 } catch (EOFException ex) {
2489 throw new StreamCorruptedException(
2490 "unexpected EOF while reading block data header");
2491 }
2492 }
2493
2494 /**
2495 * Refills internal buffer buf with block data. Any data in buf at the
2496 * time of the call is considered consumed. Sets the pos, end, and
2497 * unread fields to reflect the new amount of available block data; if
2498 * the next element in the stream is not a data block, sets pos and
2499 * unread to 0 and end to -1.
2500 */
2501 private void refill() throws IOException {
2502 try {
2503 do {
2504 pos = 0;
2505 if (unread > 0) {
2506 int n =
2507 in.read(buf, 0, Math.min(unread, MAX_BLOCK_SIZE));
2508 if (n >= 0) {
2509 end = n;
2510 unread -= n;
2511 } else {
2512 throw new StreamCorruptedException(
2513 "unexpected EOF in middle of data block");
2514 }
2515 } else {
2516 int n = readBlockHeader(true);
2517 if (n >= 0) {
2518 end = 0;
2519 unread = n;
2520 } else {
2521 end = -1;
2522 unread = 0;
2523 }
2524 }
2525 } while (pos == end);
2526 } catch (IOException ex) {
2527 pos = 0;
2528 end = -1;
2529 unread = 0;
2530 throw ex;
2531 }
2532 }
2533
2534 /**
2535 * If in block data mode, returns the number of unconsumed bytes
2536 * remaining in the current data block. If not in block data mode,
2537 * throws an IllegalStateException.
2538 */
2539 int currentBlockRemaining() {
2540 if (blkmode) {
2541 return (end >= 0) ? (end - pos) + unread : 0;
2542 } else {
2543 throw new IllegalStateException();
2544 }
2545 }
2546
2547 /**
2548 * Peeks at (but does not consume) and returns the next byte value in
2549 * the stream, or -1 if the end of the stream/block data (if in block
2550 * data mode) has been reached.
2551 */
2552 int peek() throws IOException {
2553 if (blkmode) {
2554 if (pos == end) {
2555 refill();
2556 }
2557 return (end >= 0) ? (buf[pos] & 0xFF) : -1;
2558 } else {
2559 return in.peek();
2560 }
2561 }
2562
2563 /**
2564 * Peeks at (but does not consume) and returns the next byte value in
2565 * the stream, or throws EOFException if end of stream/block data has
2566 * been reached.
2567 */
2568 byte peekByte() throws IOException {
2569 int val = peek();
2570 if (val < 0) {
2571 throw new EOFException();
2572 }
2573 return (byte) val;
2574 }
2575
2576
2577 /* ----------------- generic input stream methods ------------------ */
2578 /*
2579 * The following methods are equivalent to their counterparts in
2580 * InputStream, except that they interpret data block boundaries and
2581 * read the requested data from within data blocks when in block data
2582 * mode.
2583 */
2584
2585 public int read() throws IOException {
2586 if (blkmode) {
2587 if (pos == end) {
2588 refill();
2589 }
2590 return (end >= 0) ? (buf[pos++] & 0xFF) : -1;
2591 } else {
2592 return in.read();
2593 }
2594 }
2595
2596 public int read(byte[] b, int off, int len) throws IOException {
2597 return read(b, off, len, false);
2598 }
2599
2600 public long skip(long len) throws IOException {
2601 long remain = len;
2602 while (remain > 0) {
2603 if (blkmode) {
2604 if (pos == end) {
2605 refill();
2606 }
2607 if (end < 0) {
2608 break;
2609 }
2610 int nread = (int) Math.min(remain, end - pos);
2611 remain -= nread;
2612 pos += nread;
2613 } else {
2614 int nread = (int) Math.min(remain, MAX_BLOCK_SIZE);
2615 if ((nread = in.read(buf, 0, nread)) < 0) {
2616 break;
2617 }
2618 remain -= nread;
2619 }
2620 }
2621 return len - remain;
2622 }
2623
2624 public int available() throws IOException {
2625 if (blkmode) {
2626 if ((pos == end) && (unread == 0)) {
2627 int n;
2628 while ((n = readBlockHeader(false)) == 0) ;
2629 switch (n) {
2630 case HEADER_BLOCKED:
2631 break;
2632
2633 case -1:
2634 pos = 0;
2635 end = -1;
2636 break;
2637
2638 default:
2639 pos = 0;
2640 end = 0;
2641 unread = n;
2642 break;
2643 }
2644 }
2645 // avoid unnecessary call to in.available() if possible
2646 int unreadAvail = (unread > 0) ?
2647 Math.min(in.available(), unread) : 0;
2648 return (end >= 0) ? (end - pos) + unreadAvail : 0;
2649 } else {
2650 return in.available();
2651 }
2652 }
2653
2654 public void close() throws IOException {
2655 if (blkmode) {
2656 pos = 0;
2657 end = -1;
2658 unread = 0;
2659 }
2660 in.close();
2661 }
2662
2663 /**
2664 * Attempts to read len bytes into byte array b at offset off. Returns
2665 * the number of bytes read, or -1 if the end of stream/block data has
2666 * been reached. If copy is true, reads values into an intermediate
2667 * buffer before copying them to b (to avoid exposing a reference to
2668 * b).
2669 */
2670 int read(byte[] b, int off, int len, boolean copy) throws IOException {
2671 if (len == 0) {
2672 return 0;
2673 } else if (blkmode) {
2674 if (pos == end) {
2675 refill();
2676 }
2677 if (end < 0) {
2678 return -1;
2679 }
2680 int nread = Math.min(len, end - pos);
2681 System.arraycopy(buf, pos, b, off, nread);
2682 pos += nread;
2683 return nread;
2684 } else if (copy) {
2685 int nread = in.read(buf, 0, Math.min(len, MAX_BLOCK_SIZE));
2686 if (nread > 0) {
2687 System.arraycopy(buf, 0, b, off, nread);
2688 }
2689 return nread;
2690 } else {
2691 return in.read(b, off, len);
2692 }
2693 }
2694
2695 /* ----------------- primitive data input methods ------------------ */
2696 /*
2697 * The following methods are equivalent to their counterparts in
2698 * DataInputStream, except that they interpret data block boundaries
2699 * and read the requested data from within data blocks when in block
2700 * data mode.
2701 */
2702
2703 public void readFully(byte[] b) throws IOException {
2704 readFully(b, 0, b.length, false);
2705 }
2706
2707 public void readFully(byte[] b, int off, int len) throws IOException {
2708 readFully(b, off, len, false);
2709 }
2710
2711 public void readFully(byte[] b, int off, int len, boolean copy)
2712 throws IOException
2713 {
2714 while (len > 0) {
2715 int n = read(b, off, len, copy);
2716 if (n < 0) {
2717 throw new EOFException();
2718 }
2719 off += n;
2720 len -= n;
2721 }
2722 }
2723
2724 public int skipBytes(int n) throws IOException {
2725 return din.skipBytes(n);
2726 }
2727
2728 public boolean readBoolean() throws IOException {
2729 int v = read();
2730 if (v < 0) {
2731 throw new EOFException();
2732 }
2733 return (v != 0);
2734 }
2735
2736 public byte readByte() throws IOException {
2737 int v = read();
2738 if (v < 0) {
2739 throw new EOFException();
2740 }
2741 return (byte) v;
2742 }
2743
2744 public int readUnsignedByte() throws IOException {
2745 int v = read();
2746 if (v < 0) {
2747 throw new EOFException();
2748 }
2749 return v;
2750 }
2751
2752 public char readChar() throws IOException {
2753 if (!blkmode) {
2754 pos = 0;
2755 in.readFully(buf, 0, 2);
2756 } else if (end - pos < 2) {
2757 return din.readChar();
2758 }
2759 char v = Bits.getChar(buf, pos);
2760 pos += 2;
2761 return v;
2762 }
2763
2764 public short readShort() throws IOException {
2765 if (!blkmode) {
2766 pos = 0;
2767 in.readFully(buf, 0, 2);
2768 } else if (end - pos < 2) {
2769 return din.readShort();
2770 }
2771 short v = Bits.getShort(buf, pos);
2772 pos += 2;
2773 return v;
2774 }
2775
2776 public int readUnsignedShort() throws IOException {
2777 if (!blkmode) {
2778 pos = 0;
2779 in.readFully(buf, 0, 2);
2780 } else if (end - pos < 2) {
2781 return din.readUnsignedShort();
2782 }
2783 int v = Bits.getShort(buf, pos) & 0xFFFF;
2784 pos += 2;
2785 return v;
2786 }
2787
2788 public int readInt() throws IOException {
2789 if (!blkmode) {
2790 pos = 0;
2791 in.readFully(buf, 0, 4);
2792 } else if (end - pos < 4) {
2793 return din.readInt();
2794 }
2795 int v = Bits.getInt(buf, pos);
2796 pos += 4;
2797 return v;
2798 }
2799
2800 public float readFloat() throws IOException {
2801 if (!blkmode) {
2802 pos = 0;
2803 in.readFully(buf, 0, 4);
2804 } else if (end - pos < 4) {
2805 return din.readFloat();
2806 }
2807 float v = Bits.getFloat(buf, pos);
2808 pos += 4;
2809 return v;
2810 }
2811
2812 public long readLong() throws IOException {
2813 if (!blkmode) {
2814 pos = 0;
2815 in.readFully(buf, 0, 8);
2816 } else if (end - pos < 8) {
2817 return din.readLong();
2818 }
2819 long v = Bits.getLong(buf, pos);
2820 pos += 8;
2821 return v;
2822 }
2823
2824 public double readDouble() throws IOException {
2825 if (!blkmode) {
2826 pos = 0;
2827 in.readFully(buf, 0, 8);
2828 } else if (end - pos < 8) {
2829 return din.readDouble();
2830 }
2831 double v = Bits.getDouble(buf, pos);
2832 pos += 8;
2833 return v;
2834 }
2835
2836 public String readUTF() throws IOException {
2837 return readUTFBody(readUnsignedShort());
2838 }
2839
2840 public String readLine() throws IOException {
2841 return din.readLine(); // deprecated, not worth optimizing
2842 }
2843
2844 /* -------------- primitive data array input methods --------------- */
2845 /*
2846 * The following methods read in spans of primitive data values.
2847 * Though equivalent to calling the corresponding primitive read
2848 * methods repeatedly, these methods are optimized for reading groups
2849 * of primitive data values more efficiently.
2850 */
2851
2852 void readBooleans(boolean[] v, int off, int len) throws IOException {
2853 int stop, endoff = off + len;
2854 while (off < endoff) {
2855 if (!blkmode) {
2856 int span = Math.min(endoff - off, MAX_BLOCK_SIZE);
2857 in.readFully(buf, 0, span);
2858 stop = off + span;
2859 pos = 0;
2860 } else if (end - pos < 1) {
2861 v[off++] = din.readBoolean();
2862 continue;
2863 } else {
2864 stop = Math.min(endoff, off + end - pos);
2865 }
2866
2867 while (off < stop) {
2868 v[off++] = Bits.getBoolean(buf, pos++);
2869 }
2870 }
2871 }
2872
2873 void readChars(char[] v, int off, int len) throws IOException {
2874 int stop, endoff = off + len;
2875 while (off < endoff) {
2876 if (!blkmode) {
2877 int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 1);
2878 in.readFully(buf, 0, span << 1);
2879 stop = off + span;
2880 pos = 0;
2881 } else if (end - pos < 2) {
2882 v[off++] = din.readChar();
2883 continue;
2884 } else {
2885 stop = Math.min(endoff, off + ((end - pos) >> 1));
2886 }
2887
2888 while (off < stop) {
2889 v[off++] = Bits.getChar(buf, pos);
2890 pos += 2;
2891 }
2892 }
2893 }
2894
2895 void readShorts(short[] v, int off, int len) throws IOException {
2896 int stop, endoff = off + len;
2897 while (off < endoff) {
2898 if (!blkmode) {
2899 int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 1);
2900 in.readFully(buf, 0, span << 1);
2901 stop = off + span;
2902 pos = 0;
2903 } else if (end - pos < 2) {
2904 v[off++] = din.readShort();
2905 continue;
2906 } else {
2907 stop = Math.min(endoff, off + ((end - pos) >> 1));
2908 }
2909
2910 while (off < stop) {
2911 v[off++] = Bits.getShort(buf, pos);
2912 pos += 2;
2913 }
2914 }
2915 }
2916
2917 void readInts(int[] v, int off, int len) throws IOException {
2918 int stop, endoff = off + len;
2919 while (off < endoff) {
2920 if (!blkmode) {
2921 int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 2);
2922 in.readFully(buf, 0, span << 2);
2923 stop = off + span;
2924 pos = 0;
2925 } else if (end - pos < 4) {
2926 v[off++] = din.readInt();
2927 continue;
2928 } else {
2929 stop = Math.min(endoff, off + ((end - pos) >> 2));
2930 }
2931
2932 while (off < stop) {
2933 v[off++] = Bits.getInt(buf, pos);
2934 pos += 4;
2935 }
2936 }
2937 }
2938
2939 void readFloats(float[] v, int off, int len) throws IOException {
2940 int span, endoff = off + len;
2941 while (off < endoff) {
2942 if (!blkmode) {
2943 span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 2);
2944 in.readFully(buf, 0, span << 2);
2945 pos = 0;
2946 } else if (end - pos < 4) {
2947 v[off++] = din.readFloat();
2948 continue;
2949 } else {
2950 span = Math.min(endoff - off, ((end - pos) >> 2));
2951 }
2952
2953 bytesToFloats(buf, pos, v, off, span);
2954 off += span;
2955 pos += span << 2;
2956 }
2957 }
2958
2959 void readLongs(long[] v, int off, int len) throws IOException {
2960 int stop, endoff = off + len;
2961 while (off < endoff) {
2962 if (!blkmode) {
2963 int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 3);
2964 in.readFully(buf, 0, span << 3);
2965 stop = off + span;
2966 pos = 0;
2967 } else if (end - pos < 8) {
2968 v[off++] = din.readLong();
2969 continue;
2970 } else {
2971 stop = Math.min(endoff, off + ((end - pos) >> 3));
2972 }
2973
2974 while (off < stop) {
2975 v[off++] = Bits.getLong(buf, pos);
2976 pos += 8;
2977 }
2978 }
2979 }
2980
2981 void readDoubles(double[] v, int off, int len) throws IOException {
2982 int span, endoff = off + len;
2983 while (off < endoff) {
2984 if (!blkmode) {
2985 span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 3);
2986 in.readFully(buf, 0, span << 3);
2987 pos = 0;
2988 } else if (end - pos < 8) {
2989 v[off++] = din.readDouble();
2990 continue;
2991 } else {
2992 span = Math.min(endoff - off, ((end - pos) >> 3));
2993 }
2994
2995 bytesToDoubles(buf, pos, v, off, span);
2996 off += span;
2997 pos += span << 3;
2998 }
2999 }
3000
3001 /**
3002 * Reads in string written in "long" UTF format. "Long" UTF format is
3003 * identical to standard UTF, except that it uses an 8 byte header
3004 * (instead of the standard 2 bytes) to convey the UTF encoding length.
3005 */
3006 String readLongUTF() throws IOException {
3007 return readUTFBody(readLong());
3008 }
3009
3010 /**
3011 * Reads in the "body" (i.e., the UTF representation minus the 2-byte
3012 * or 8-byte length header) of a UTF encoding, which occupies the next
3013 * utflen bytes.
3014 */
3015 private String readUTFBody(long utflen) throws IOException {
3016 StringBuilder sbuf = new StringBuilder();
3017 if (!blkmode) {
3018 end = pos = 0;
3019 }
3020
3021 while (utflen > 0) {
3022 int avail = end - pos;
3023 if (avail >= 3 || (long) avail == utflen) {
3024 utflen -= readUTFSpan(sbuf, utflen);
3025 } else {
3026 if (blkmode) {
3027 // near block boundary, read one byte at a time
3028 utflen -= readUTFChar(sbuf, utflen);
3029 } else {
3030 // shift and refill buffer manually
3031 if (avail > 0) {
3032 System.arraycopy(buf, pos, buf, 0, avail);
3033 }
3034 pos = 0;
3035 end = (int) Math.min(MAX_BLOCK_SIZE, utflen);
3036 in.readFully(buf, avail, end - avail);
3037 }
3038 }
3039 }
3040
3041 return sbuf.toString();
3042 }
3043
3044 /**
3045 * Reads span of UTF-encoded characters out of internal buffer
3046 * (starting at offset pos and ending at or before offset end),
3047 * consuming no more than utflen bytes. Appends read characters to
3048 * sbuf. Returns the number of bytes consumed.
3049 */
3050 private long readUTFSpan(StringBuilder sbuf, long utflen)
3051 throws IOException
3052 {
3053 int cpos = 0;
3054 int start = pos;
3055 int avail = Math.min(end - pos, CHAR_BUF_SIZE);
3056 // stop short of last char unless all of utf bytes in buffer
3057 int stop = pos + ((utflen > avail) ? avail - 2 : (int) utflen);
3058 boolean outOfBounds = false;
3059
3060 try {
3061 while (pos < stop) {
3062 int b1, b2, b3;
3063 b1 = buf[pos++] & 0xFF;
3064 switch (b1 >> 4) {
3065 case 0:
3066 case 1:
3067 case 2:
3068 case 3:
3069 case 4:
3070 case 5:
3071 case 6:
3072 case 7: // 1 byte format: 0xxxxxxx
3073 cbuf[cpos++] = (char) b1;
3074 break;
3075
3076 case 12:
3077 case 13: // 2 byte format: 110xxxxx 10xxxxxx
3078 b2 = buf[pos++];
3079 if ((b2 & 0xC0) != 0x80) {
3080 throw new UTFDataFormatException();
3081 }
3082 cbuf[cpos++] = (char) (((b1 & 0x1F) << 6) |
3083 ((b2 & 0x3F) << 0));
3084 break;
3085
3086 case 14: // 3 byte format: 1110xxxx 10xxxxxx 10xxxxxx
3087 b3 = buf[pos + 1];
3088 b2 = buf[pos + 0];
3089 pos += 2;
3090 if ((b2 & 0xC0) != 0x80 || (b3 & 0xC0) != 0x80) {
3091 throw new UTFDataFormatException();
3092 }
3093 cbuf[cpos++] = (char) (((b1 & 0x0F) << 12) |
3094 ((b2 & 0x3F) << 6) |
3095 ((b3 & 0x3F) << 0));
3096 break;
3097
3098 default: // 10xx xxxx, 1111 xxxx
3099 throw new UTFDataFormatException();
3100 }
3101 }
3102 } catch (ArrayIndexOutOfBoundsException ex) {
3103 outOfBounds = true;
3104 } finally {
3105 if (outOfBounds || (pos - start) > utflen) {
3106 /*
3107 * Fix for 4450867: if a malformed utf char causes the
3108 * conversion loop to scan past the expected end of the utf
3109 * string, only consume the expected number of utf bytes.
3110 */
3111 pos = start + (int) utflen;
3112 throw new UTFDataFormatException();
3113 }
3114 }
3115
3116 sbuf.append(cbuf, 0, cpos);
3117 return pos - start;
3118 }
3119
3120 /**
3121 * Reads in single UTF-encoded character one byte at a time, appends
3122 * the character to sbuf, and returns the number of bytes consumed.
3123 * This method is used when reading in UTF strings written in block
3124 * data mode to handle UTF-encoded characters which (potentially)
3125 * straddle block-data boundaries.
3126 */
3127 private int readUTFChar(StringBuilder sbuf, long utflen)
3128 throws IOException
3129 {
3130 int b1, b2, b3;
3131 b1 = readByte() & 0xFF;
3132 switch (b1 >> 4) {
3133 case 0:
3134 case 1:
3135 case 2:
3136 case 3:
3137 case 4:
3138 case 5:
3139 case 6:
3140 case 7: // 1 byte format: 0xxxxxxx
3141 sbuf.append((char) b1);
3142 return 1;
3143
3144 case 12:
3145 case 13: // 2 byte format: 110xxxxx 10xxxxxx
3146 if (utflen < 2) {
3147 throw new UTFDataFormatException();
3148 }
3149 b2 = readByte();
3150 if ((b2 & 0xC0) != 0x80) {
3151 throw new UTFDataFormatException();
3152 }
3153 sbuf.append((char) (((b1 & 0x1F) << 6) |
3154 ((b2 & 0x3F) << 0)));
3155 return 2;
3156
3157 case 14: // 3 byte format: 1110xxxx 10xxxxxx 10xxxxxx
3158 if (utflen < 3) {
3159 if (utflen == 2) {
3160 readByte(); // consume remaining byte
3161 }
3162 throw new UTFDataFormatException();
3163 }
3164 b2 = readByte();
3165 b3 = readByte();
3166 if ((b2 & 0xC0) != 0x80 || (b3 & 0xC0) != 0x80) {
3167 throw new UTFDataFormatException();
3168 }
3169 sbuf.append((char) (((b1 & 0x0F) << 12) |
3170 ((b2 & 0x3F) << 6) |
3171 ((b3 & 0x3F) << 0)));
3172 return 3;
3173
3174 default: // 10xx xxxx, 1111 xxxx
3175 throw new UTFDataFormatException();
3176 }
3177 }
3178 }
3179
3180 /**
3181 * Unsynchronized table which tracks wire handle to object mappings, as
3182 * well as ClassNotFoundExceptions associated with deserialized objects.
3183 * This class implements an exception-propagation algorithm for
3184 * determining which objects should have ClassNotFoundExceptions associated
3185 * with them, taking into account cycles and discontinuities (e.g., skipped
3186 * fields) in the object graph.
3187 *
3188 * <p>General use of the table is as follows: during deserialization, a
3189 * given object is first assigned a handle by calling the assign method.
3190 * This method leaves the assigned handle in an "open" state, wherein
3191 * dependencies on the exception status of other handles can be registered
3192 * by calling the markDependency method, or an exception can be directly
3193 * associated with the handle by calling markException. When a handle is
3194 * tagged with an exception, the HandleTable assumes responsibility for
3195 * propagating the exception to any other objects which depend
3196 * (transitively) on the exception-tagged object.
3197 *
3198 * <p>Once all exception information/dependencies for the handle have been
3199 * registered, the handle should be "closed" by calling the finish method
3200 * on it. The act of finishing a handle allows the exception propagation
3201 * algorithm to aggressively prune dependency links, lessening the
3202 * performance/memory impact of exception tracking.
3203 *
3204 * <p>Note that the exception propagation algorithm used depends on handles
3205 * being assigned/finished in LIFO order; however, for simplicity as well
3206 * as memory conservation, it does not enforce this constraint.
3207 */
3208 // REMIND: add full description of exception propagation algorithm?
3209 private static class HandleTable {
3210
3211 /* status codes indicating whether object has associated exception */
3212 private static final byte STATUS_OK = 1;
3213 private static final byte STATUS_UNKNOWN = 2;
3214 private static final byte STATUS_EXCEPTION = 3;
3215
3216 /** array mapping handle -> object status */
3217 byte[] status;
3218 /** array mapping handle -> object/exception (depending on status) */
3219 Object[] entries;
3220 /** array mapping handle -> list of dependent handles (if any) */
3221 HandleList[] deps;
3222 /** lowest unresolved dependency */
3223 int lowDep = -1;
3224 /** number of handles in table */
3225 int size = 0;
3226
3227 /**
3228 * Creates handle table with the given initial capacity.
3229 */
3230 HandleTable(int initialCapacity) {
3231 status = new byte[initialCapacity];
3232 entries = new Object[initialCapacity];
3233 deps = new HandleList[initialCapacity];
3234 }
3235
3236 /**
3237 * Assigns next available handle to given object, and returns assigned
3238 * handle. Once object has been completely deserialized (and all
3239 * dependencies on other objects identified), the handle should be
3240 * "closed" by passing it to finish().
3241 */
3242 int assign(Object obj) {
3243 if (size >= entries.length) {
3244 grow();
3245 }
3246 status[size] = STATUS_UNKNOWN;
3247 entries[size] = obj;
3248 return size++;
3249 }
3250
3251 /**
3252 * Registers a dependency (in exception status) of one handle on
3253 * another. The dependent handle must be "open" (i.e., assigned, but
3254 * not finished yet). No action is taken if either dependent or target
3255 * handle is NULL_HANDLE.
3256 */
3257 void markDependency(int dependent, int target) {
3258 if (dependent == NULL_HANDLE || target == NULL_HANDLE) {
3259 return;
3260 }
3261 switch (status[dependent]) {
3262
3263 case STATUS_UNKNOWN:
3264 switch (status[target]) {
3265 case STATUS_OK:
3266 // ignore dependencies on objs with no exception
3267 break;
3268
3269 case STATUS_EXCEPTION:
3270 // eagerly propagate exception
3271 markException(dependent,
3272 (ClassNotFoundException) entries[target]);
3273 break;
3274
3275 case STATUS_UNKNOWN:
3276 // add to dependency list of target
3277 if (deps[target] == null) {
3278 deps[target] = new HandleList();
3279 }
3280 deps[target].add(dependent);
3281
3282 // remember lowest unresolved target seen
3283 if (lowDep < 0 || lowDep > target) {
3284 lowDep = target;
3285 }
3286 break;
3287
3288 default:
3289 throw new InternalError();
3290 }
3291 break;
3292
3293 case STATUS_EXCEPTION:
3294 break;
3295
3296 default:
3297 throw new InternalError();
3298 }
3299 }
3300
3301 /**
3302 * Associates a ClassNotFoundException (if one not already associated)
3303 * with the currently active handle and propagates it to other
3304 * referencing objects as appropriate. The specified handle must be
3305 * "open" (i.e., assigned, but not finished yet).
3306 */
3307 void markException(int handle, ClassNotFoundException ex) {
3308 switch (status[handle]) {
3309 case STATUS_UNKNOWN:
3310 status[handle] = STATUS_EXCEPTION;
3311 entries[handle] = ex;
3312
3313 // propagate exception to dependents
3314 HandleList dlist = deps[handle];
3315 if (dlist != null) {
3316 int ndeps = dlist.size();
3317 for (int i = 0; i < ndeps; i++) {
3318 markException(dlist.get(i), ex);
3319 }
3320 deps[handle] = null;
3321 }
3322 break;
3323
3324 case STATUS_EXCEPTION:
3325 break;
3326
3327 default:
3328 throw new InternalError();
3329 }
3330 }
3331
3332 /**
3333 * Marks given handle as finished, meaning that no new dependencies
3334 * will be marked for handle. Calls to the assign and finish methods
3335 * must occur in LIFO order.
3336 */
3337 void finish(int handle) {
3338 int end;
3339 if (lowDep < 0) {
3340 // no pending unknowns, only resolve current handle
3341 end = handle + 1;
3342 } else if (lowDep >= handle) {
3343 // pending unknowns now clearable, resolve all upward handles
3344 end = size;
3345 lowDep = -1;
3346 } else {
3347 // unresolved backrefs present, can't resolve anything yet
3348 return;
3349 }
3350
3351 // change STATUS_UNKNOWN -> STATUS_OK in selected span of handles
3352 for (int i = handle; i < end; i++) {
3353 switch (status[i]) {
3354 case STATUS_UNKNOWN:
3355 status[i] = STATUS_OK;
3356 deps[i] = null;
3357 break;
3358
3359 case STATUS_OK:
3360 case STATUS_EXCEPTION:
3361 break;
3362
3363 default:
3364 throw new InternalError();
3365 }
3366 }
3367 }
3368
3369 /**
3370 * Assigns a new object to the given handle. The object previously
3371 * associated with the handle is forgotten. This method has no effect
3372 * if the given handle already has an exception associated with it.
3373 * This method may be called at any time after the handle is assigned.
3374 */
3375 void setObject(int handle, Object obj) {
3376 switch (status[handle]) {
3377 case STATUS_UNKNOWN:
3378 case STATUS_OK:
3379 entries[handle] = obj;
3380 break;
3381
3382 case STATUS_EXCEPTION:
3383 break;
3384
3385 default:
3386 throw new InternalError();
3387 }
3388 }
3389
3390 /**
3391 * Looks up and returns object associated with the given handle.
3392 * Returns null if the given handle is NULL_HANDLE, or if it has an
3393 * associated ClassNotFoundException.
3394 */
3395 Object lookupObject(int handle) {
3396 return (handle != NULL_HANDLE &&
3397 status[handle] != STATUS_EXCEPTION) ?
3398 entries[handle] : null;
3399 }
3400
3401 /**
3402 * Looks up and returns ClassNotFoundException associated with the
3403 * given handle. Returns null if the given handle is NULL_HANDLE, or
3404 * if there is no ClassNotFoundException associated with the handle.
3405 */
3406 ClassNotFoundException lookupException(int handle) {
3407 return (handle != NULL_HANDLE &&
3408 status[handle] == STATUS_EXCEPTION) ?
3409 (ClassNotFoundException) entries[handle] : null;
3410 }
3411
3412 /**
3413 * Resets table to its initial state.
3414 */
3415 void clear() {
3416 Arrays.fill(status, 0, size, (byte) 0);
3417 Arrays.fill(entries, 0, size, null);
3418 Arrays.fill(deps, 0, size, null);
3419 lowDep = -1;
3420 size = 0;
3421 }
3422
3423 /**
3424 * Returns number of handles registered in table.
3425 */
3426 int size() {
3427 return size;
3428 }
3429
3430 /**
3431 * Expands capacity of internal arrays.
3432 */
3433 private void grow() {
3434 int newCapacity = (entries.length << 1) + 1;
3435
3436 byte[] newStatus = new byte[newCapacity];
3437 Object[] newEntries = new Object[newCapacity];
3438 HandleList[] newDeps = new HandleList[newCapacity];
3439
3440 System.arraycopy(status, 0, newStatus, 0, size);
3441 System.arraycopy(entries, 0, newEntries, 0, size);
3442 System.arraycopy(deps, 0, newDeps, 0, size);
3443
3444 status = newStatus;
3445 entries = newEntries;
3446 deps = newDeps;
3447 }
3448
3449 /**
3450 * Simple growable list of (integer) handles.
3451 */
3452 private static class HandleList {
3453 private int[] list = new int[4];
3454 private int size = 0;
3455
3456 public HandleList() {
3457 }
3458
3459 public void add(int handle) {
3460 if (size >= list.length) {
3461 int[] newList = new int[list.length << 1];
3462 System.arraycopy(list, 0, newList, 0, list.length);
3463 list = newList;
3464 }
3465 list[size++] = handle;
3466 }
3467
3468 public int get(int index) {
3469 if (index >= size) {
3470 throw new ArrayIndexOutOfBoundsException();
3471 }
3472 return list[index];
3473 }
3474
3475 public int size() {
3476 return size;
3477 }
3478 }
3479 }
3480
3481 /**
3482 * Method for cloning arrays in case of using unsharing reading
3483 */
3484 private static Object cloneArray(Object array) {
3485 if (array instanceof Object[]) {
3486 return ((Object[]) array).clone();
3487 } else if (array instanceof boolean[]) {
3488 return ((boolean[]) array).clone();
3489 } else if (array instanceof byte[]) {
3490 return ((byte[]) array).clone();
3491 } else if (array instanceof char[]) {
3492 return ((char[]) array).clone();
3493 } else if (array instanceof double[]) {
3494 return ((double[]) array).clone();
3495 } else if (array instanceof float[]) {
3496 return ((float[]) array).clone();
3497 } else if (array instanceof int[]) {
3498 return ((int[]) array).clone();
3499 } else if (array instanceof long[]) {
3500 return ((long[]) array).clone();
3501 } else if (array instanceof short[]) {
3502 return ((short[]) array).clone();
3503 } else {
3504 throw new AssertionError();
3505 }
3506 }
3507
3508}
java/pkg/java/io/ObjectInputValidation.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectInputValidation.java+45−0
@@ -0,0 +1,45 @@
1/*
2 * Copyright (c) 1996, 1999, 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
26package java.io;
27
28/**
29 * Callback interface to allow validation of objects within a graph.
30 * Allows an object to be called when a complete graph of objects has
31 * been deserialized.
32 *
33 * @author unascribed
34 * @see ObjectInputStream
35 * @see ObjectInputStream#registerValidation(java.io.ObjectInputValidation, int)
36 * @since JDK1.1
37 */
38public interface ObjectInputValidation {
39 /**
40 * Validates the object.
41 *
42 * @exception InvalidObjectException If the object cannot validate itself.
43 */
44 public void validateObject() throws InvalidObjectException;
45}
java/pkg/java/io/ObjectOutput.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectOutput.java+90−0
@@ -0,0 +1,90 @@
1/*
2 * Copyright (c) 1996, 2010, 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
26package java.io;
27
28/**
29 * ObjectOutput extends the DataOutput interface to include writing of objects.
30 * DataOutput includes methods for output of primitive types, ObjectOutput
31 * extends that interface to include objects, arrays, and Strings.
32 *
33 * @author unascribed
34 * @see java.io.InputStream
35 * @see java.io.ObjectOutputStream
36 * @see java.io.ObjectInputStream
37 * @since JDK1.1
38 */
39public interface ObjectOutput extends DataOutput, AutoCloseable {
40 /**
41 * Write an object to the underlying storage or stream. The
42 * class that implements this interface defines how the object is
43 * written.
44 *
45 * @param obj the object to be written
46 * @exception IOException Any of the usual Input/Output related exceptions.
47 */
48 public void writeObject(Object obj)
49 throws IOException;
50
51 /**
52 * Writes a byte. This method will block until the byte is actually
53 * written.
54 * @param b the byte
55 * @exception IOException If an I/O error has occurred.
56 */
57 public void write(int b) throws IOException;
58
59 /**
60 * Writes an array of bytes. This method will block until the bytes
61 * are actually written.
62 * @param b the data to be written
63 * @exception IOException If an I/O error has occurred.
64 */
65 public void write(byte b[]) throws IOException;
66
67 /**
68 * Writes a sub array of bytes.
69 * @param b the data to be written
70 * @param off the start offset in the data
71 * @param len the number of bytes that are written
72 * @exception IOException If an I/O error has occurred.
73 */
74 public void write(byte b[], int off, int len) throws IOException;
75
76 /**
77 * Flushes the stream. This will write any buffered
78 * output bytes.
79 * @exception IOException If an I/O error has occurred.
80 */
81 public void flush() throws IOException;
82
83 /**
84 * Closes the stream. This method must be called
85 * to release any resources associated with the
86 * stream.
87 * @exception IOException If an I/O error has occurred.
88 */
89 public void close() throws IOException;
90}
java/pkg/java/io/ObjectOutputStream$1.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectOutputStream$BlockDataOutputStream.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectOutputStream$Caches.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectOutputStream$DebugTraceInfoStack.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectOutputStream$HandleTable.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectOutputStream$PutField.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectOutputStream$PutFieldImpl.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectOutputStream$ReplaceTable.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectOutputStream.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectOutputStream.java+2454−0
@@ -0,0 +1,2454 @@
1/*
2 * Copyright (c) 1996, 2010, 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
26package java.io;
27
28import java.io.ObjectStreamClass.WeakClassKey;
29import java.lang.ref.ReferenceQueue;
30import java.security.AccessController;
31import java.security.PrivilegedAction;
32import java.util.ArrayList;
33import java.util.Arrays;
34import java.util.List;
35import java.util.concurrent.ConcurrentHashMap;
36import java.util.concurrent.ConcurrentMap;
37import static java.io.ObjectStreamClass.processQueue;
38import java.io.SerialCallbackContext;
39
40/**
41 * An ObjectOutputStream writes primitive data types and graphs of Java objects
42 * to an OutputStream. The objects can be read (reconstituted) using an
43 * ObjectInputStream. Persistent storage of objects can be accomplished by
44 * using a file for the stream. If the stream is a network socket stream, the
45 * objects can be reconstituted on another host or in another process.
46 *
47 * <p>Only objects that support the java.io.Serializable interface can be
48 * written to streams. The class of each serializable object is encoded
49 * including the class name and signature of the class, the values of the
50 * object's fields and arrays, and the closure of any other objects referenced
51 * from the initial objects.
52 *
53 * <p>The method writeObject is used to write an object to the stream. Any
54 * object, including Strings and arrays, is written with writeObject. Multiple
55 * objects or primitives can be written to the stream. The objects must be
56 * read back from the corresponding ObjectInputstream with the same types and
57 * in the same order as they were written.
58 *
59 * <p>Primitive data types can also be written to the stream using the
60 * appropriate methods from DataOutput. Strings can also be written using the
61 * writeUTF method.
62 *
63 * <p>The default serialization mechanism for an object writes the class of the
64 * object, the class signature, and the values of all non-transient and
65 * non-static fields. References to other objects (except in transient or
66 * static fields) cause those objects to be written also. Multiple references
67 * to a single object are encoded using a reference sharing mechanism so that
68 * graphs of objects can be restored to the same shape as when the original was
69 * written.
70 *
71 * <p>For example to write an object that can be read by the example in
72 * ObjectInputStream:
73 * <br>
74 * <pre>
75 * FileOutputStream fos = new FileOutputStream("t.tmp");
76 * ObjectOutputStream oos = new ObjectOutputStream(fos);
77 *
78 * oos.writeInt(12345);
79 * oos.writeObject("Today");
80 * oos.writeObject(new Date());
81 *
82 * oos.close();
83 * </pre>
84 *
85 * <p>Classes that require special handling during the serialization and
86 * deserialization process must implement special methods with these exact
87 * signatures:
88 * <br>
89 * <pre>
90 * private void readObject(java.io.ObjectInputStream stream)
91 * throws IOException, ClassNotFoundException;
92 * private void writeObject(java.io.ObjectOutputStream stream)
93 * throws IOException
94 * private void readObjectNoData()
95 * throws ObjectStreamException;
96 * </pre>
97 *
98 * <p>The writeObject method is responsible for writing the state of the object
99 * for its particular class so that the corresponding readObject method can
100 * restore it. The method does not need to concern itself with the state
101 * belonging to the object's superclasses or subclasses. State is saved by
102 * writing the individual fields to the ObjectOutputStream using the
103 * writeObject method or by using the methods for primitive data types
104 * supported by DataOutput.
105 *
106 * <p>Serialization does not write out the fields of any object that does not
107 * implement the java.io.Serializable interface. Subclasses of Objects that
108 * are not serializable can be serializable. In this case the non-serializable
109 * class must have a no-arg constructor to allow its fields to be initialized.
110 * In this case it is the responsibility of the subclass to save and restore
111 * the state of the non-serializable class. It is frequently the case that the
112 * fields of that class are accessible (public, package, or protected) or that
113 * there are get and set methods that can be used to restore the state.
114 *
115 * <p>Serialization of an object can be prevented by implementing writeObject
116 * and readObject methods that throw the NotSerializableException. The
117 * exception will be caught by the ObjectOutputStream and abort the
118 * serialization process.
119 *
120 * <p>Implementing the Externalizable interface allows the object to assume
121 * complete control over the contents and format of the object's serialized
122 * form. The methods of the Externalizable interface, writeExternal and
123 * readExternal, are called to save and restore the objects state. When
124 * implemented by a class they can write and read their own state using all of
125 * the methods of ObjectOutput and ObjectInput. It is the responsibility of
126 * the objects to handle any versioning that occurs.
127 *
128 * <p>Enum constants are serialized differently than ordinary serializable or
129 * externalizable objects. The serialized form of an enum constant consists
130 * solely of its name; field values of the constant are not transmitted. To
131 * serialize an enum constant, ObjectOutputStream writes the string returned by
132 * the constant's name method. Like other serializable or externalizable
133 * objects, enum constants can function as the targets of back references
134 * appearing subsequently in the serialization stream. The process by which
135 * enum constants are serialized cannot be customized; any class-specific
136 * writeObject and writeReplace methods defined by enum types are ignored
137 * during serialization. Similarly, any serialPersistentFields or
138 * serialVersionUID field declarations are also ignored--all enum types have a
139 * fixed serialVersionUID of 0L.
140 *
141 * <p>Primitive data, excluding serializable fields and externalizable data, is
142 * written to the ObjectOutputStream in block-data records. A block data record
143 * is composed of a header and data. The block data header consists of a marker
144 * and the number of bytes to follow the header. Consecutive primitive data
145 * writes are merged into one block-data record. The blocking factor used for
146 * a block-data record will be 1024 bytes. Each block-data record will be
147 * filled up to 1024 bytes, or be written whenever there is a termination of
148 * block-data mode. Calls to the ObjectOutputStream methods writeObject,
149 * defaultWriteObject and writeFields initially terminate any existing
150 * block-data record.
151 *
152 * @author Mike Warres
153 * @author Roger Riggs
154 * @see java.io.DataOutput
155 * @see java.io.ObjectInputStream
156 * @see java.io.Serializable
157 * @see java.io.Externalizable
158 * @see <a href="../../../platform/serialization/spec/output.html">Object Serialization Specification, Section 2, Object Output Classes</a>
159 * @since JDK1.1
160 */
161public class ObjectOutputStream
162 extends OutputStream implements ObjectOutput, ObjectStreamConstants
163{
164
165 private static class Caches {
166 /** cache of subclass security audit results */
167 static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits =
168 new ConcurrentHashMap<>();
169
170 /** queue for WeakReferences to audited subclasses */
171 static final ReferenceQueue<Class<?>> subclassAuditsQueue =
172 new ReferenceQueue<>();
173 }
174
175 /** filter stream for handling block data conversion */
176 private final BlockDataOutputStream bout;
177 /** obj -> wire handle map */
178 private final HandleTable handles;
179 /** obj -> replacement obj map */
180 private final ReplaceTable subs;
181 /** stream protocol version */
182 private int protocol = PROTOCOL_VERSION_2;
183 /** recursion depth */
184 private int depth;
185
186 /** buffer for writing primitive field values */
187 private byte[] primVals;
188
189 /** if true, invoke writeObjectOverride() instead of writeObject() */
190 private final boolean enableOverride;
191 /** if true, invoke replaceObject() */
192 private boolean enableReplace;
193
194 // values below valid only during upcalls to writeObject()/writeExternal()
195 /**
196 * Context during upcalls to class-defined writeObject methods; holds
197 * object currently being serialized and descriptor for current class.
198 * Null when not during writeObject upcall.
199 */
200 private SerialCallbackContext curContext;
201 /** current PutField object */
202 private PutFieldImpl curPut;
203
204 /** custom storage for debug trace info */
205 private final DebugTraceInfoStack debugInfoStack;
206
207 /**
208 * value of "sun.io.serialization.extendedDebugInfo" property,
209 * as true or false for extended information about exception's place
210 */
211 private static final boolean extendedDebugInfo =
212 java.security.AccessController.doPrivileged(
213 new sun.security.action.GetBooleanAction(
214 "sun.io.serialization.extendedDebugInfo")).booleanValue();
215
216 /**
217 * Creates an ObjectOutputStream that writes to the specified OutputStream.
218 * This constructor writes the serialization stream header to the
219 * underlying stream; callers may wish to flush the stream immediately to
220 * ensure that constructors for receiving ObjectInputStreams will not block
221 * when reading the header.
222 *
223 * <p>If a security manager is installed, this constructor will check for
224 * the "enableSubclassImplementation" SerializablePermission when invoked
225 * directly or indirectly by the constructor of a subclass which overrides
226 * the ObjectOutputStream.putFields or ObjectOutputStream.writeUnshared
227 * methods.
228 *
229 * @param out output stream to write to
230 * @throws IOException if an I/O error occurs while writing stream header
231 * @throws SecurityException if untrusted subclass illegally overrides
232 * security-sensitive methods
233 * @throws NullPointerException if <code>out</code> is <code>null</code>
234 * @since 1.4
235 * @see ObjectOutputStream#ObjectOutputStream()
236 * @see ObjectOutputStream#putFields()
237 * @see ObjectInputStream#ObjectInputStream(InputStream)
238 */
239 public ObjectOutputStream(OutputStream out) throws IOException {
240 verifySubclass();
241 bout = new BlockDataOutputStream(out);
242 handles = new HandleTable(10, (float) 3.00);
243 subs = new ReplaceTable(10, (float) 3.00);
244 enableOverride = false;
245 writeStreamHeader();
246 bout.setBlockDataMode(true);
247 if (extendedDebugInfo) {
248 debugInfoStack = new DebugTraceInfoStack();
249 } else {
250 debugInfoStack = null;
251 }
252 }
253
254 /**
255 * Provide a way for subclasses that are completely reimplementing
256 * ObjectOutputStream to not have to allocate private data just used by
257 * this implementation of ObjectOutputStream.
258 *
259 * <p>If there is a security manager installed, this method first calls the
260 * security manager's <code>checkPermission</code> method with a
261 * <code>SerializablePermission("enableSubclassImplementation")</code>
262 * permission to ensure it's ok to enable subclassing.
263 *
264 * @throws SecurityException if a security manager exists and its
265 * <code>checkPermission</code> method denies enabling
266 * subclassing.
267 * @see SecurityManager#checkPermission
268 * @see java.io.SerializablePermission
269 */
270 protected ObjectOutputStream() throws IOException, SecurityException {
271 SecurityManager sm = System.getSecurityManager();
272 if (sm != null) {
273 sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
274 }
275 bout = null;
276 handles = null;
277 subs = null;
278 enableOverride = true;
279 debugInfoStack = null;
280 }
281
282 /**
283 * Specify stream protocol version to use when writing the stream.
284 *
285 * <p>This routine provides a hook to enable the current version of
286 * Serialization to write in a format that is backwards compatible to a
287 * previous version of the stream format.
288 *
289 * <p>Every effort will be made to avoid introducing additional
290 * backwards incompatibilities; however, sometimes there is no
291 * other alternative.
292 *
293 * @param version use ProtocolVersion from java.io.ObjectStreamConstants.
294 * @throws IllegalStateException if called after any objects
295 * have been serialized.
296 * @throws IllegalArgumentException if invalid version is passed in.
297 * @throws IOException if I/O errors occur
298 * @see java.io.ObjectStreamConstants#PROTOCOL_VERSION_1
299 * @see java.io.ObjectStreamConstants#PROTOCOL_VERSION_2
300 * @since 1.2
301 */
302 public void useProtocolVersion(int version) throws IOException {
303 if (handles.size() != 0) {
304 // REMIND: implement better check for pristine stream?
305 throw new IllegalStateException("stream non-empty");
306 }
307 switch (version) {
308 case PROTOCOL_VERSION_1:
309 case PROTOCOL_VERSION_2:
310 protocol = version;
311 break;
312
313 default:
314 throw new IllegalArgumentException(
315 "unknown version: " + version);
316 }
317 }
318
319 /**
320 * Write the specified object to the ObjectOutputStream. The class of the
321 * object, the signature of the class, and the values of the non-transient
322 * and non-static fields of the class and all of its supertypes are
323 * written. Default serialization for a class can be overridden using the
324 * writeObject and the readObject methods. Objects referenced by this
325 * object are written transitively so that a complete equivalent graph of
326 * objects can be reconstructed by an ObjectInputStream.
327 *
328 * <p>Exceptions are thrown for problems with the OutputStream and for
329 * classes that should not be serialized. All exceptions are fatal to the
330 * OutputStream, which is left in an indeterminate state, and it is up to
331 * the caller to ignore or recover the stream state.
332 *
333 * @throws InvalidClassException Something is wrong with a class used by
334 * serialization.
335 * @throws NotSerializableException Some object to be serialized does not
336 * implement the java.io.Serializable interface.
337 * @throws IOException Any exception thrown by the underlying
338 * OutputStream.
339 */
340 public final void writeObject(Object obj) throws IOException {
341 if (enableOverride) {
342 writeObjectOverride(obj);
343 return;
344 }
345 try {
346 writeObject0(obj, false);
347 } catch (IOException ex) {
348 if (depth == 0) {
349 writeFatalException(ex);
350 }
351 throw ex;
352 }
353 }
354
355 /**
356 * Method used by subclasses to override the default writeObject method.
357 * This method is called by trusted subclasses of ObjectInputStream that
358 * constructed ObjectInputStream using the protected no-arg constructor.
359 * The subclass is expected to provide an override method with the modifier
360 * "final".
361 *
362 * @param obj object to be written to the underlying stream
363 * @throws IOException if there are I/O errors while writing to the
364 * underlying stream
365 * @see #ObjectOutputStream()
366 * @see #writeObject(Object)
367 * @since 1.2
368 */
369 protected void writeObjectOverride(Object obj) throws IOException {
370 }
371
372 /**
373 * Writes an "unshared" object to the ObjectOutputStream. This method is
374 * identical to writeObject, except that it always writes the given object
375 * as a new, unique object in the stream (as opposed to a back-reference
376 * pointing to a previously serialized instance). Specifically:
377 * <ul>
378 * <li>An object written via writeUnshared is always serialized in the
379 * same manner as a newly appearing object (an object that has not
380 * been written to the stream yet), regardless of whether or not the
381 * object has been written previously.
382 *
383 * <li>If writeObject is used to write an object that has been previously
384 * written with writeUnshared, the previous writeUnshared operation
385 * is treated as if it were a write of a separate object. In other
386 * words, ObjectOutputStream will never generate back-references to
387 * object data written by calls to writeUnshared.
388 * </ul>
389 * While writing an object via writeUnshared does not in itself guarantee a
390 * unique reference to the object when it is deserialized, it allows a
391 * single object to be defined multiple times in a stream, so that multiple
392 * calls to readUnshared by the receiver will not conflict. Note that the
393 * rules described above only apply to the base-level object written with
394 * writeUnshared, and not to any transitively referenced sub-objects in the
395 * object graph to be serialized.
396 *
397 * <p>ObjectOutputStream subclasses which override this method can only be
398 * constructed in security contexts possessing the
399 * "enableSubclassImplementation" SerializablePermission; any attempt to
400 * instantiate such a subclass without this permission will cause a
401 * SecurityException to be thrown.
402 *
403 * @param obj object to write to stream
404 * @throws NotSerializableException if an object in the graph to be
405 * serialized does not implement the Serializable interface
406 * @throws InvalidClassException if a problem exists with the class of an
407 * object to be serialized
408 * @throws IOException if an I/O error occurs during serialization
409 * @since 1.4
410 */
411 public void writeUnshared(Object obj) throws IOException {
412 try {
413 writeObject0(obj, true);
414 } catch (IOException ex) {
415 if (depth == 0) {
416 writeFatalException(ex);
417 }
418 throw ex;
419 }
420 }
421
422 /**
423 * Write the non-static and non-transient fields of the current class to
424 * this stream. This may only be called from the writeObject method of the
425 * class being serialized. It will throw the NotActiveException if it is
426 * called otherwise.
427 *
428 * @throws IOException if I/O errors occur while writing to the underlying
429 * <code>OutputStream</code>
430 */
431 public void defaultWriteObject() throws IOException {
432 if ( curContext == null ) {
433 throw new NotActiveException("not in call to writeObject");
434 }
435 Object curObj = curContext.getObj();
436 ObjectStreamClass curDesc = curContext.getDesc();
437 bout.setBlockDataMode(false);
438 defaultWriteFields(curObj, curDesc);
439 bout.setBlockDataMode(true);
440 }
441
442 /**
443 * Retrieve the object used to buffer persistent fields to be written to
444 * the stream. The fields will be written to the stream when writeFields
445 * method is called.
446 *
447 * @return an instance of the class Putfield that holds the serializable
448 * fields
449 * @throws IOException if I/O errors occur
450 * @since 1.2
451 */
452 public ObjectOutputStream.PutField putFields() throws IOException {
453 if (curPut == null) {
454 if (curContext == null) {
455 throw new NotActiveException("not in call to writeObject");
456 }
457 Object curObj = curContext.getObj();
458 ObjectStreamClass curDesc = curContext.getDesc();
459 curPut = new PutFieldImpl(curDesc);
460 }
461 return curPut;
462 }
463
464 /**
465 * Write the buffered fields to the stream.
466 *
467 * @throws IOException if I/O errors occur while writing to the underlying
468 * stream
469 * @throws NotActiveException Called when a classes writeObject method was
470 * not called to write the state of the object.
471 * @since 1.2
472 */
473 public void writeFields() throws IOException {
474 if (curPut == null) {
475 throw new NotActiveException("no current PutField object");
476 }
477 bout.setBlockDataMode(false);
478 curPut.writeFields();
479 bout.setBlockDataMode(true);
480 }
481
482 /**
483 * Reset will disregard the state of any objects already written to the
484 * stream. The state is reset to be the same as a new ObjectOutputStream.
485 * The current point in the stream is marked as reset so the corresponding
486 * ObjectInputStream will be reset at the same point. Objects previously
487 * written to the stream will not be refered to as already being in the
488 * stream. They will be written to the stream again.
489 *
490 * @throws IOException if reset() is invoked while serializing an object.
491 */
492 public void reset() throws IOException {
493 if (depth != 0) {
494 throw new IOException("stream active");
495 }
496 bout.setBlockDataMode(false);
497 bout.writeByte(TC_RESET);
498 clear();
499 bout.setBlockDataMode(true);
500 }
501
502 /**
503 * Subclasses may implement this method to allow class data to be stored in
504 * the stream. By default this method does nothing. The corresponding
505 * method in ObjectInputStream is resolveClass. This method is called
506 * exactly once for each unique class in the stream. The class name and
507 * signature will have already been written to the stream. This method may
508 * make free use of the ObjectOutputStream to save any representation of
509 * the class it deems suitable (for example, the bytes of the class file).
510 * The resolveClass method in the corresponding subclass of
511 * ObjectInputStream must read and use any data or objects written by
512 * annotateClass.
513 *
514 * @param cl the class to annotate custom data for
515 * @throws IOException Any exception thrown by the underlying
516 * OutputStream.
517 */
518 protected void annotateClass(Class<?> cl) throws IOException {
519 }
520
521 /**
522 * Subclasses may implement this method to store custom data in the stream
523 * along with descriptors for dynamic proxy classes.
524 *
525 * <p>This method is called exactly once for each unique proxy class
526 * descriptor in the stream. The default implementation of this method in
527 * <code>ObjectOutputStream</code> does nothing.
528 *
529 * <p>The corresponding method in <code>ObjectInputStream</code> is
530 * <code>resolveProxyClass</code>. For a given subclass of
531 * <code>ObjectOutputStream</code> that overrides this method, the
532 * <code>resolveProxyClass</code> method in the corresponding subclass of
533 * <code>ObjectInputStream</code> must read any data or objects written by
534 * <code>annotateProxyClass</code>.
535 *
536 * @param cl the proxy class to annotate custom data for
537 * @throws IOException any exception thrown by the underlying
538 * <code>OutputStream</code>
539 * @see ObjectInputStream#resolveProxyClass(String[])
540 * @since 1.3
541 */
542 protected void annotateProxyClass(Class<?> cl) throws IOException {
543 }
544
545 /**
546 * This method will allow trusted subclasses of ObjectOutputStream to
547 * substitute one object for another during serialization. Replacing
548 * objects is disabled until enableReplaceObject is called. The
549 * enableReplaceObject method checks that the stream requesting to do
550 * replacement can be trusted. The first occurrence of each object written
551 * into the serialization stream is passed to replaceObject. Subsequent
552 * references to the object are replaced by the object returned by the
553 * original call to replaceObject. To ensure that the private state of
554 * objects is not unintentionally exposed, only trusted streams may use
555 * replaceObject.
556 *
557 * <p>The ObjectOutputStream.writeObject method takes a parameter of type
558 * Object (as opposed to type Serializable) to allow for cases where
559 * non-serializable objects are replaced by serializable ones.
560 *
561 * <p>When a subclass is replacing objects it must insure that either a
562 * complementary substitution must be made during deserialization or that
563 * the substituted object is compatible with every field where the
564 * reference will be stored. Objects whose type is not a subclass of the
565 * type of the field or array element abort the serialization by raising an
566 * exception and the object is not be stored.
567 *
568 * <p>This method is called only once when each object is first
569 * encountered. All subsequent references to the object will be redirected
570 * to the new object. This method should return the object to be
571 * substituted or the original object.
572 *
573 * <p>Null can be returned as the object to be substituted, but may cause
574 * NullReferenceException in classes that contain references to the
575 * original object since they may be expecting an object instead of
576 * null.
577 *
578 * @param obj the object to be replaced
579 * @return the alternate object that replaced the specified one
580 * @throws IOException Any exception thrown by the underlying
581 * OutputStream.
582 */
583 protected Object replaceObject(Object obj) throws IOException {
584 return obj;
585 }
586
587 /**
588 * Enable the stream to do replacement of objects in the stream. When
589 * enabled, the replaceObject method is called for every object being
590 * serialized.
591 *
592 * <p>If <code>enable</code> is true, and there is a security manager
593 * installed, this method first calls the security manager's
594 * <code>checkPermission</code> method with a
595 * <code>SerializablePermission("enableSubstitution")</code> permission to
596 * ensure it's ok to enable the stream to do replacement of objects in the
597 * stream.
598 *
599 * @param enable boolean parameter to enable replacement of objects
600 * @return the previous setting before this method was invoked
601 * @throws SecurityException if a security manager exists and its
602 * <code>checkPermission</code> method denies enabling the stream
603 * to do replacement of objects in the stream.
604 * @see SecurityManager#checkPermission
605 * @see java.io.SerializablePermission
606 */
607 protected boolean enableReplaceObject(boolean enable)
608 throws SecurityException
609 {
610 if (enable == enableReplace) {
611 return enable;
612 }
613 if (enable) {
614 SecurityManager sm = System.getSecurityManager();
615 if (sm != null) {
616 sm.checkPermission(SUBSTITUTION_PERMISSION);
617 }
618 }
619 enableReplace = enable;
620 return !enableReplace;
621 }
622
623 /**
624 * The writeStreamHeader method is provided so subclasses can append or
625 * prepend their own header to the stream. It writes the magic number and
626 * version to the stream.
627 *
628 * @throws IOException if I/O errors occur while writing to the underlying
629 * stream
630 */
631 protected void writeStreamHeader() throws IOException {
632 bout.writeShort(STREAM_MAGIC);
633 bout.writeShort(STREAM_VERSION);
634 }
635
636 /**
637 * Write the specified class descriptor to the ObjectOutputStream. Class
638 * descriptors are used to identify the classes of objects written to the
639 * stream. Subclasses of ObjectOutputStream may override this method to
640 * customize the way in which class descriptors are written to the
641 * serialization stream. The corresponding method in ObjectInputStream,
642 * <code>readClassDescriptor</code>, should then be overridden to
643 * reconstitute the class descriptor from its custom stream representation.
644 * By default, this method writes class descriptors according to the format
645 * defined in the Object Serialization specification.
646 *
647 * <p>Note that this method will only be called if the ObjectOutputStream
648 * is not using the old serialization stream format (set by calling
649 * ObjectOutputStream's <code>useProtocolVersion</code> method). If this
650 * serialization stream is using the old format
651 * (<code>PROTOCOL_VERSION_1</code>), the class descriptor will be written
652 * internally in a manner that cannot be overridden or customized.
653 *
654 * @param desc class descriptor to write to the stream
655 * @throws IOException If an I/O error has occurred.
656 * @see java.io.ObjectInputStream#readClassDescriptor()
657 * @see #useProtocolVersion(int)
658 * @see java.io.ObjectStreamConstants#PROTOCOL_VERSION_1
659 * @since 1.3
660 */
661 protected void writeClassDescriptor(ObjectStreamClass desc)
662 throws IOException
663 {
664 desc.writeNonProxy(this);
665 }
666
667 /**
668 * Writes a byte. This method will block until the byte is actually
669 * written.
670 *
671 * @param val the byte to be written to the stream
672 * @throws IOException If an I/O error has occurred.
673 */
674 public void write(int val) throws IOException {
675 bout.write(val);
676 }
677
678 /**
679 * Writes an array of bytes. This method will block until the bytes are
680 * actually written.
681 *
682 * @param buf the data to be written
683 * @throws IOException If an I/O error has occurred.
684 */
685 public void write(byte[] buf) throws IOException {
686 bout.write(buf, 0, buf.length, false);
687 }
688
689 /**
690 * Writes a sub array of bytes.
691 *
692 * @param buf the data to be written
693 * @param off the start offset in the data
694 * @param len the number of bytes that are written
695 * @throws IOException If an I/O error has occurred.
696 */
697 public void write(byte[] buf, int off, int len) throws IOException {
698 if (buf == null) {
699 throw new NullPointerException();
700 }
701 int endoff = off + len;
702 if (off < 0 || len < 0 || endoff > buf.length || endoff < 0) {
703 throw new IndexOutOfBoundsException();
704 }
705 bout.write(buf, off, len, false);
706 }
707
708 /**
709 * Flushes the stream. This will write any buffered output bytes and flush
710 * through to the underlying stream.
711 *
712 * @throws IOException If an I/O error has occurred.
713 */
714 public void flush() throws IOException {
715 bout.flush();
716 }
717
718 /**
719 * Drain any buffered data in ObjectOutputStream. Similar to flush but
720 * does not propagate the flush to the underlying stream.
721 *
722 * @throws IOException if I/O errors occur while writing to the underlying
723 * stream
724 */
725 protected void drain() throws IOException {
726 bout.drain();
727 }
728
729 /**
730 * Closes the stream. This method must be called to release any resources
731 * associated with the stream.
732 *
733 * @throws IOException If an I/O error has occurred.
734 */
735 public void close() throws IOException {
736 flush();
737 clear();
738 bout.close();
739 }
740
741 /**
742 * Writes a boolean.
743 *
744 * @param val the boolean to be written
745 * @throws IOException if I/O errors occur while writing to the underlying
746 * stream
747 */
748 public void writeBoolean(boolean val) throws IOException {
749 bout.writeBoolean(val);
750 }
751
752 /**
753 * Writes an 8 bit byte.
754 *
755 * @param val the byte value to be written
756 * @throws IOException if I/O errors occur while writing to the underlying
757 * stream
758 */
759 public void writeByte(int val) throws IOException {
760 bout.writeByte(val);
761 }
762
763 /**
764 * Writes a 16 bit short.
765 *
766 * @param val the short value to be written
767 * @throws IOException if I/O errors occur while writing to the underlying
768 * stream
769 */
770 public void writeShort(int val) throws IOException {
771 bout.writeShort(val);
772 }
773
774 /**
775 * Writes a 16 bit char.
776 *
777 * @param val the char value to be written
778 * @throws IOException if I/O errors occur while writing to the underlying
779 * stream
780 */
781 public void writeChar(int val) throws IOException {
782 bout.writeChar(val);
783 }
784
785 /**
786 * Writes a 32 bit int.
787 *
788 * @param val the integer value to be written
789 * @throws IOException if I/O errors occur while writing to the underlying
790 * stream
791 */
792 public void writeInt(int val) throws IOException {
793 bout.writeInt(val);
794 }
795
796 /**
797 * Writes a 64 bit long.
798 *
799 * @param val the long value to be written
800 * @throws IOException if I/O errors occur while writing to the underlying
801 * stream
802 */
803 public void writeLong(long val) throws IOException {
804 bout.writeLong(val);
805 }
806
807 /**
808 * Writes a 32 bit float.
809 *
810 * @param val the float value to be written
811 * @throws IOException if I/O errors occur while writing to the underlying
812 * stream
813 */
814 public void writeFloat(float val) throws IOException {
815 bout.writeFloat(val);
816 }
817
818 /**
819 * Writes a 64 bit double.
820 *
821 * @param val the double value to be written
822 * @throws IOException if I/O errors occur while writing to the underlying
823 * stream
824 */
825 public void writeDouble(double val) throws IOException {
826 bout.writeDouble(val);
827 }
828
829 /**
830 * Writes a String as a sequence of bytes.
831 *
832 * @param str the String of bytes to be written
833 * @throws IOException if I/O errors occur while writing to the underlying
834 * stream
835 */
836 public void writeBytes(String str) throws IOException {
837 bout.writeBytes(str);
838 }
839
840 /**
841 * Writes a String as a sequence of chars.
842 *
843 * @param str the String of chars to be written
844 * @throws IOException if I/O errors occur while writing to the underlying
845 * stream
846 */
847 public void writeChars(String str) throws IOException {
848 bout.writeChars(str);
849 }
850
851 /**
852 * Primitive data write of this String in
853 * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
854 * format. Note that there is a
855 * significant difference between writing a String into the stream as
856 * primitive data or as an Object. A String instance written by writeObject
857 * is written into the stream as a String initially. Future writeObject()
858 * calls write references to the string into the stream.
859 *
860 * @param str the String to be written
861 * @throws IOException if I/O errors occur while writing to the underlying
862 * stream
863 */
864 public void writeUTF(String str) throws IOException {
865 bout.writeUTF(str);
866 }
867
868 /**
869 * Provide programmatic access to the persistent fields to be written
870 * to ObjectOutput.
871 *
872 * @since 1.2
873 */
874 public static abstract class PutField {
875
876 /**
877 * Put the value of the named boolean field into the persistent field.
878 *
879 * @param name the name of the serializable field
880 * @param val the value to assign to the field
881 * @throws IllegalArgumentException if <code>name</code> does not
882 * match the name of a serializable field for the class whose fields
883 * are being written, or if the type of the named field is not
884 * <code>boolean</code>
885 */
886 public abstract void put(String name, boolean val);
887
888 /**
889 * Put the value of the named byte field into the persistent field.
890 *
891 * @param name the name of the serializable field
892 * @param val the value to assign to the field
893 * @throws IllegalArgumentException if <code>name</code> does not
894 * match the name of a serializable field for the class whose fields
895 * are being written, or if the type of the named field is not
896 * <code>byte</code>
897 */
898 public abstract void put(String name, byte val);
899
900 /**
901 * Put the value of the named char field into the persistent field.
902 *
903 * @param name the name of the serializable field
904 * @param val the value to assign to the field
905 * @throws IllegalArgumentException if <code>name</code> does not
906 * match the name of a serializable field for the class whose fields
907 * are being written, or if the type of the named field is not
908 * <code>char</code>
909 */
910 public abstract void put(String name, char val);
911
912 /**
913 * Put the value of the named short field into the persistent field.
914 *
915 * @param name the name of the serializable field
916 * @param val the value to assign to the field
917 * @throws IllegalArgumentException if <code>name</code> does not
918 * match the name of a serializable field for the class whose fields
919 * are being written, or if the type of the named field is not
920 * <code>short</code>
921 */
922 public abstract void put(String name, short val);
923
924 /**
925 * Put the value of the named int field into the persistent field.
926 *
927 * @param name the name of the serializable field
928 * @param val the value to assign to the field
929 * @throws IllegalArgumentException if <code>name</code> does not
930 * match the name of a serializable field for the class whose fields
931 * are being written, or if the type of the named field is not
932 * <code>int</code>
933 */
934 public abstract void put(String name, int val);
935
936 /**
937 * Put the value of the named long field into the persistent field.
938 *
939 * @param name the name of the serializable field
940 * @param val the value to assign to the field
941 * @throws IllegalArgumentException if <code>name</code> does not
942 * match the name of a serializable field for the class whose fields
943 * are being written, or if the type of the named field is not
944 * <code>long</code>
945 */
946 public abstract void put(String name, long val);
947
948 /**
949 * Put the value of the named float field into the persistent field.
950 *
951 * @param name the name of the serializable field
952 * @param val the value to assign to the field
953 * @throws IllegalArgumentException if <code>name</code> does not
954 * match the name of a serializable field for the class whose fields
955 * are being written, or if the type of the named field is not
956 * <code>float</code>
957 */
958 public abstract void put(String name, float val);
959
960 /**
961 * Put the value of the named double field into the persistent field.
962 *
963 * @param name the name of the serializable field
964 * @param val the value to assign to the field
965 * @throws IllegalArgumentException if <code>name</code> does not
966 * match the name of a serializable field for the class whose fields
967 * are being written, or if the type of the named field is not
968 * <code>double</code>
969 */
970 public abstract void put(String name, double val);
971
972 /**
973 * Put the value of the named Object field into the persistent field.
974 *
975 * @param name the name of the serializable field
976 * @param val the value to assign to the field
977 * (which may be <code>null</code>)
978 * @throws IllegalArgumentException if <code>name</code> does not
979 * match the name of a serializable field for the class whose fields
980 * are being written, or if the type of the named field is not a
981 * reference type
982 */
983 public abstract void put(String name, Object val);
984
985 /**
986 * Write the data and fields to the specified ObjectOutput stream,
987 * which must be the same stream that produced this
988 * <code>PutField</code> object.
989 *
990 * @param out the stream to write the data and fields to
991 * @throws IOException if I/O errors occur while writing to the
992 * underlying stream
993 * @throws IllegalArgumentException if the specified stream is not
994 * the same stream that produced this <code>PutField</code>
995 * object
996 * @deprecated This method does not write the values contained by this
997 * <code>PutField</code> object in a proper format, and may
998 * result in corruption of the serialization stream. The
999 * correct way to write <code>PutField</code> data is by
1000 * calling the {@link java.io.ObjectOutputStream#writeFields()}
1001 * method.
1002 */
1003 @Deprecated
1004 public abstract void write(ObjectOutput out) throws IOException;
1005 }
1006
1007
1008 /**
1009 * Returns protocol version in use.
1010 */
1011 int getProtocolVersion() {
1012 return protocol;
1013 }
1014
1015 /**
1016 * Writes string without allowing it to be replaced in stream. Used by
1017 * ObjectStreamClass to write class descriptor type strings.
1018 */
1019 void writeTypeString(String str) throws IOException {
1020 int handle;
1021 if (str == null) {
1022 writeNull();
1023 } else if ((handle = handles.lookup(str)) != -1) {
1024 writeHandle(handle);
1025 } else {
1026 writeString(str, false);
1027 }
1028 }
1029
1030 /**
1031 * Verifies that this (possibly subclass) instance can be constructed
1032 * without violating security constraints: the subclass must not override
1033 * security-sensitive non-final methods, or else the
1034 * "enableSubclassImplementation" SerializablePermission is checked.
1035 */
1036 private void verifySubclass() {
1037 Class cl = getClass();
1038 if (cl == ObjectOutputStream.class) {
1039 return;
1040 }
1041 SecurityManager sm = System.getSecurityManager();
1042 if (sm == null) {
1043 return;
1044 }
1045 processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
1046 WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
1047 Boolean result = Caches.subclassAudits.get(key);
1048 if (result == null) {
1049 result = Boolean.valueOf(auditSubclass(cl));
1050 Caches.subclassAudits.putIfAbsent(key, result);
1051 }
1052 if (result.booleanValue()) {
1053 return;
1054 }
1055 sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
1056 }
1057
1058 /**
1059 * Performs reflective checks on given subclass to verify that it doesn't
1060 * override security-sensitive non-final methods. Returns true if subclass
1061 * is "safe", false otherwise.
1062 */
1063 private static boolean auditSubclass(final Class subcl) {
1064 Boolean result = AccessController.doPrivileged(
1065 new PrivilegedAction<Boolean>() {
1066 public Boolean run() {
1067 for (Class cl = subcl;
1068 cl != ObjectOutputStream.class;
1069 cl = cl.getSuperclass())
1070 {
1071 try {
1072 cl.getDeclaredMethod(
1073 "writeUnshared", new Class[] { Object.class });
1074 return Boolean.FALSE;
1075 } catch (NoSuchMethodException ex) {
1076 }
1077 try {
1078 cl.getDeclaredMethod("putFields", (Class[]) null);
1079 return Boolean.FALSE;
1080 } catch (NoSuchMethodException ex) {
1081 }
1082 }
1083 return Boolean.TRUE;
1084 }
1085 }
1086 );
1087 return result.booleanValue();
1088 }
1089
1090 /**
1091 * Clears internal data structures.
1092 */
1093 private void clear() {
1094 subs.clear();
1095 handles.clear();
1096 }
1097
1098 /**
1099 * Underlying writeObject/writeUnshared implementation.
1100 */
1101 private void writeObject0(Object obj, boolean unshared)
1102 throws IOException
1103 {
1104 boolean oldMode = bout.setBlockDataMode(false);
1105 depth++;
1106 try {
1107 // handle previously written and non-replaceable objects
1108 int h;
1109 if ((obj = subs.lookup(obj)) == null) {
1110 writeNull();
1111 return;
1112 } else if (!unshared && (h = handles.lookup(obj)) != -1) {
1113 writeHandle(h);
1114 return;
1115 } else if (obj instanceof Class) {
1116 writeClass((Class) obj, unshared);
1117 return;
1118 } else if (obj instanceof ObjectStreamClass) {
1119 writeClassDesc((ObjectStreamClass) obj, unshared);
1120 return;
1121 }
1122
1123 // check for replacement object
1124 Object orig = obj;
1125 Class cl = obj.getClass();
1126 ObjectStreamClass desc;
1127 for (;;) {
1128 // REMIND: skip this check for strings/arrays?
1129 Class repCl;
1130 desc = ObjectStreamClass.lookup(cl, true);
1131 if (!desc.hasWriteReplaceMethod() ||
1132 (obj = desc.invokeWriteReplace(obj)) == null ||
1133 (repCl = obj.getClass()) == cl)
1134 {
1135 break;
1136 }
1137 cl = repCl;
1138 }
1139 if (enableReplace) {
1140 Object rep = replaceObject(obj);
1141 if (rep != obj && rep != null) {
1142 cl = rep.getClass();
1143 desc = ObjectStreamClass.lookup(cl, true);
1144 }
1145 obj = rep;
1146 }
1147
1148 // if object replaced, run through original checks a second time
1149 if (obj != orig) {
1150 subs.assign(orig, obj);
1151 if (obj == null) {
1152 writeNull();
1153 return;
1154 } else if (!unshared && (h = handles.lookup(obj)) != -1) {
1155 writeHandle(h);
1156 return;
1157 } else if (obj instanceof Class) {
1158 writeClass((Class) obj, unshared);
1159 return;
1160 } else if (obj instanceof ObjectStreamClass) {
1161 writeClassDesc((ObjectStreamClass) obj, unshared);
1162 return;
1163 }
1164 }
1165
1166 // remaining cases
1167 if (obj instanceof String) {
1168 writeString((String) obj, unshared);
1169 } else if (cl.isArray()) {
1170 writeArray(obj, desc, unshared);
1171 } else if (obj instanceof Enum) {
1172 writeEnum((Enum) obj, desc, unshared);
1173 } else if (obj instanceof Serializable) {
1174 writeOrdinaryObject(obj, desc, unshared);
1175 } else {
1176 if (extendedDebugInfo) {
1177 throw new NotSerializableException(
1178 cl.getName() + "\n" + debugInfoStack.toString());
1179 } else {
1180 throw new NotSerializableException(cl.getName());
1181 }
1182 }
1183 } finally {
1184 depth--;
1185 bout.setBlockDataMode(oldMode);
1186 }
1187 }
1188
1189 /**
1190 * Writes null code to stream.
1191 */
1192 private void writeNull() throws IOException {
1193 bout.writeByte(TC_NULL);
1194 }
1195
1196 /**
1197 * Writes given object handle to stream.
1198 */
1199 private void writeHandle(int handle) throws IOException {
1200 bout.writeByte(TC_REFERENCE);
1201 bout.writeInt(baseWireHandle + handle);
1202 }
1203
1204 /**
1205 * Writes representation of given class to stream.
1206 */
1207 private void writeClass(Class cl, boolean unshared) throws IOException {
1208 bout.writeByte(TC_CLASS);
1209 writeClassDesc(ObjectStreamClass.lookup(cl, true), false);
1210 handles.assign(unshared ? null : cl);
1211 }
1212
1213 /**
1214 * Writes representation of given class descriptor to stream.
1215 */
1216 private void writeClassDesc(ObjectStreamClass desc, boolean unshared)
1217 throws IOException
1218 {
1219 int handle;
1220 if (desc == null) {
1221 writeNull();
1222 } else if (!unshared && (handle = handles.lookup(desc)) != -1) {
1223 writeHandle(handle);
1224 } else if (desc.isProxy()) {
1225 writeProxyDesc(desc, unshared);
1226 } else {
1227 writeNonProxyDesc(desc, unshared);
1228 }
1229 }
1230
1231 /**
1232 * Writes class descriptor representing a dynamic proxy class to stream.
1233 */
1234 private void writeProxyDesc(ObjectStreamClass desc, boolean unshared)
1235 throws IOException
1236 {
1237 bout.writeByte(TC_PROXYCLASSDESC);
1238 handles.assign(unshared ? null : desc);
1239
1240 Class cl = desc.forClass();
1241 Class[] ifaces = cl.getInterfaces();
1242 bout.writeInt(ifaces.length);
1243 for (int i = 0; i < ifaces.length; i++) {
1244 bout.writeUTF(ifaces[i].getName());
1245 }
1246
1247 bout.setBlockDataMode(true);
1248 annotateProxyClass(cl);
1249 bout.setBlockDataMode(false);
1250 bout.writeByte(TC_ENDBLOCKDATA);
1251
1252 writeClassDesc(desc.getSuperDesc(), false);
1253 }
1254
1255 /**
1256 * Writes class descriptor representing a standard (i.e., not a dynamic
1257 * proxy) class to stream.
1258 */
1259 private void writeNonProxyDesc(ObjectStreamClass desc, boolean unshared)
1260 throws IOException
1261 {
1262 bout.writeByte(TC_CLASSDESC);
1263 handles.assign(unshared ? null : desc);
1264
1265 if (protocol == PROTOCOL_VERSION_1) {
1266 // do not invoke class descriptor write hook with old protocol
1267 desc.writeNonProxy(this);
1268 } else {
1269 writeClassDescriptor(desc);
1270 }
1271
1272 Class cl = desc.forClass();
1273 bout.setBlockDataMode(true);
1274 annotateClass(cl);
1275 bout.setBlockDataMode(false);
1276 bout.writeByte(TC_ENDBLOCKDATA);
1277
1278 writeClassDesc(desc.getSuperDesc(), false);
1279 }
1280
1281 /**
1282 * Writes given string to stream, using standard or long UTF format
1283 * depending on string length.
1284 */
1285 private void writeString(String str, boolean unshared) throws IOException {
1286 handles.assign(unshared ? null : str);
1287 long utflen = bout.getUTFLength(str);
1288 if (utflen <= 0xFFFF) {
1289 bout.writeByte(TC_STRING);
1290 bout.writeUTF(str, utflen);
1291 } else {
1292 bout.writeByte(TC_LONGSTRING);
1293 bout.writeLongUTF(str, utflen);
1294 }
1295 }
1296
1297 /**
1298 * Writes given array object to stream.
1299 */
1300 private void writeArray(Object array,
1301 ObjectStreamClass desc,
1302 boolean unshared)
1303 throws IOException
1304 {
1305 bout.writeByte(TC_ARRAY);
1306 writeClassDesc(desc, false);
1307 handles.assign(unshared ? null : array);
1308
1309 Class ccl = desc.forClass().getComponentType();
1310 if (ccl.isPrimitive()) {
1311 if (ccl == Integer.TYPE) {
1312 int[] ia = (int[]) array;
1313 bout.writeInt(ia.length);
1314 bout.writeInts(ia, 0, ia.length);
1315 } else if (ccl == Byte.TYPE) {
1316 byte[] ba = (byte[]) array;
1317 bout.writeInt(ba.length);
1318 bout.write(ba, 0, ba.length, true);
1319 } else if (ccl == Long.TYPE) {
1320 long[] ja = (long[]) array;
1321 bout.writeInt(ja.length);
1322 bout.writeLongs(ja, 0, ja.length);
1323 } else if (ccl == Float.TYPE) {
1324 float[] fa = (float[]) array;
1325 bout.writeInt(fa.length);
1326 bout.writeFloats(fa, 0, fa.length);
1327 } else if (ccl == Double.TYPE) {
1328 double[] da = (double[]) array;
1329 bout.writeInt(da.length);
1330 bout.writeDoubles(da, 0, da.length);
1331 } else if (ccl == Short.TYPE) {
1332 short[] sa = (short[]) array;
1333 bout.writeInt(sa.length);
1334 bout.writeShorts(sa, 0, sa.length);
1335 } else if (ccl == Character.TYPE) {
1336 char[] ca = (char[]) array;
1337 bout.writeInt(ca.length);
1338 bout.writeChars(ca, 0, ca.length);
1339 } else if (ccl == Boolean.TYPE) {
1340 boolean[] za = (boolean[]) array;
1341 bout.writeInt(za.length);
1342 bout.writeBooleans(za, 0, za.length);
1343 } else {
1344 throw new InternalError();
1345 }
1346 } else {
1347 Object[] objs = (Object[]) array;
1348 int len = objs.length;
1349 bout.writeInt(len);
1350 if (extendedDebugInfo) {
1351 debugInfoStack.push(
1352 "array (class \"" + array.getClass().getName() +
1353 "\", size: " + len + ")");
1354 }
1355 try {
1356 for (int i = 0; i < len; i++) {
1357 if (extendedDebugInfo) {
1358 debugInfoStack.push(
1359 "element of array (index: " + i + ")");
1360 }
1361 try {
1362 writeObject0(objs[i], false);
1363 } finally {
1364 if (extendedDebugInfo) {
1365 debugInfoStack.pop();
1366 }
1367 }
1368 }
1369 } finally {
1370 if (extendedDebugInfo) {
1371 debugInfoStack.pop();
1372 }
1373 }
1374 }
1375 }
1376
1377 /**
1378 * Writes given enum constant to stream.
1379 */
1380 private void writeEnum(Enum en,
1381 ObjectStreamClass desc,
1382 boolean unshared)
1383 throws IOException
1384 {
1385 bout.writeByte(TC_ENUM);
1386 ObjectStreamClass sdesc = desc.getSuperDesc();
1387 writeClassDesc((sdesc.forClass() == Enum.class) ? desc : sdesc, false);
1388 handles.assign(unshared ? null : en);
1389 writeString(en.name(), false);
1390 }
1391
1392 /**
1393 * Writes representation of a "ordinary" (i.e., not a String, Class,
1394 * ObjectStreamClass, array, or enum constant) serializable object to the
1395 * stream.
1396 */
1397 private void writeOrdinaryObject(Object obj,
1398 ObjectStreamClass desc,
1399 boolean unshared)
1400 throws IOException
1401 {
1402 if (extendedDebugInfo) {
1403 debugInfoStack.push(
1404 (depth == 1 ? "root " : "") + "object (class \"" +
1405 obj.getClass().getName() + "\", " + obj.toString() + ")");
1406 }
1407 try {
1408 desc.checkSerialize();
1409
1410 bout.writeByte(TC_OBJECT);
1411 writeClassDesc(desc, false);
1412 handles.assign(unshared ? null : obj);
1413 if (desc.isExternalizable() && !desc.isProxy()) {
1414 writeExternalData((Externalizable) obj);
1415 } else {
1416 writeSerialData(obj, desc);
1417 }
1418 } finally {
1419 if (extendedDebugInfo) {
1420 debugInfoStack.pop();
1421 }
1422 }
1423 }
1424
1425 /**
1426 * Writes externalizable data of given object by invoking its
1427 * writeExternal() method.
1428 */
1429 private void writeExternalData(Externalizable obj) throws IOException {
1430 PutFieldImpl oldPut = curPut;
1431 curPut = null;
1432
1433 if (extendedDebugInfo) {
1434 debugInfoStack.push("writeExternal data");
1435 }
1436 SerialCallbackContext oldContext = curContext;
1437 try {
1438 curContext = null;
1439 if (protocol == PROTOCOL_VERSION_1) {
1440 obj.writeExternal(this);
1441 } else {
1442 bout.setBlockDataMode(true);
1443 obj.writeExternal(this);
1444 bout.setBlockDataMode(false);
1445 bout.writeByte(TC_ENDBLOCKDATA);
1446 }
1447 } finally {
1448 curContext = oldContext;
1449 if (extendedDebugInfo) {
1450 debugInfoStack.pop();
1451 }
1452 }
1453
1454 curPut = oldPut;
1455 }
1456
1457 /**
1458 * Writes instance data for each serializable class of given object, from
1459 * superclass to subclass.
1460 */
1461 private void writeSerialData(Object obj, ObjectStreamClass desc)
1462 throws IOException
1463 {
1464 ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout();
1465 for (int i = 0; i < slots.length; i++) {
1466 ObjectStreamClass slotDesc = slots[i].desc;
1467 if (slotDesc.hasWriteObjectMethod()) {
1468 PutFieldImpl oldPut = curPut;
1469 curPut = null;
1470 SerialCallbackContext oldContext = curContext;
1471
1472 if (extendedDebugInfo) {
1473 debugInfoStack.push(
1474 "custom writeObject data (class \"" +
1475 slotDesc.getName() + "\")");
1476 }
1477 try {
1478 curContext = new SerialCallbackContext(obj, slotDesc);
1479 bout.setBlockDataMode(true);
1480 slotDesc.invokeWriteObject(obj, this);
1481 bout.setBlockDataMode(false);
1482 bout.writeByte(TC_ENDBLOCKDATA);
1483 } finally {
1484 curContext.setUsed();
1485 curContext = oldContext;
1486 if (extendedDebugInfo) {
1487 debugInfoStack.pop();
1488 }
1489 }
1490
1491 curPut = oldPut;
1492 } else {
1493 defaultWriteFields(obj, slotDesc);
1494 }
1495 }
1496 }
1497
1498 /**
1499 * Fetches and writes values of serializable fields of given object to
1500 * stream. The given class descriptor specifies which field values to
1501 * write, and in which order they should be written.
1502 */
1503 private void defaultWriteFields(Object obj, ObjectStreamClass desc)
1504 throws IOException
1505 {
1506 // REMIND: perform conservative isInstance check here?
1507 desc.checkDefaultSerialize();
1508
1509 int primDataSize = desc.getPrimDataSize();
1510 if (primVals == null || primVals.length < primDataSize) {
1511 primVals = new byte[primDataSize];
1512 }
1513 desc.getPrimFieldValues(obj, primVals);
1514 bout.write(primVals, 0, primDataSize, false);
1515
1516 ObjectStreamField[] fields = desc.getFields(false);
1517 Object[] objVals = new Object[desc.getNumObjFields()];
1518 int numPrimFields = fields.length - objVals.length;
1519 desc.getObjFieldValues(obj, objVals);
1520 for (int i = 0; i < objVals.length; i++) {
1521 if (extendedDebugInfo) {
1522 debugInfoStack.push(
1523 "field (class \"" + desc.getName() + "\", name: \"" +
1524 fields[numPrimFields + i].getName() + "\", type: \"" +
1525 fields[numPrimFields + i].getType() + "\")");
1526 }
1527 try {
1528 writeObject0(objVals[i],
1529 fields[numPrimFields + i].isUnshared());
1530 } finally {
1531 if (extendedDebugInfo) {
1532 debugInfoStack.pop();
1533 }
1534 }
1535 }
1536 }
1537
1538 /**
1539 * Attempts to write to stream fatal IOException that has caused
1540 * serialization to abort.
1541 */
1542 private void writeFatalException(IOException ex) throws IOException {
1543 /*
1544 * Note: the serialization specification states that if a second
1545 * IOException occurs while attempting to serialize the original fatal
1546 * exception to the stream, then a StreamCorruptedException should be
1547 * thrown (section 2.1). However, due to a bug in previous
1548 * implementations of serialization, StreamCorruptedExceptions were
1549 * rarely (if ever) actually thrown--the "root" exceptions from
1550 * underlying streams were thrown instead. This historical behavior is
1551 * followed here for consistency.
1552 */
1553 clear();
1554 boolean oldMode = bout.setBlockDataMode(false);
1555 try {
1556 bout.writeByte(TC_EXCEPTION);
1557 writeObject0(ex, false);
1558 clear();
1559 } finally {
1560 bout.setBlockDataMode(oldMode);
1561 }
1562 }
1563
1564 /**
1565 * Converts specified span of float values into byte values.
1566 */
1567 // REMIND: remove once hotspot inlines Float.floatToIntBits
1568 private static native void floatsToBytes(float[] src, int srcpos,
1569 byte[] dst, int dstpos,
1570 int nfloats);
1571
1572 /**
1573 * Converts specified span of double values into byte values.
1574 */
1575 // REMIND: remove once hotspot inlines Double.doubleToLongBits
1576 private static native void doublesToBytes(double[] src, int srcpos,
1577 byte[] dst, int dstpos,
1578 int ndoubles);
1579
1580 /**
1581 * Default PutField implementation.
1582 */
1583 private class PutFieldImpl extends PutField {
1584
1585 /** class descriptor describing serializable fields */
1586 private final ObjectStreamClass desc;
1587 /** primitive field values */
1588 private final byte[] primVals;
1589 /** object field values */
1590 private final Object[] objVals;
1591
1592 /**
1593 * Creates PutFieldImpl object for writing fields defined in given
1594 * class descriptor.
1595 */
1596 PutFieldImpl(ObjectStreamClass desc) {
1597 this.desc = desc;
1598 primVals = new byte[desc.getPrimDataSize()];
1599 objVals = new Object[desc.getNumObjFields()];
1600 }
1601
1602 public void put(String name, boolean val) {
1603 Bits.putBoolean(primVals, getFieldOffset(name, Boolean.TYPE), val);
1604 }
1605
1606 public void put(String name, byte val) {
1607 primVals[getFieldOffset(name, Byte.TYPE)] = val;
1608 }
1609
1610 public void put(String name, char val) {
1611 Bits.putChar(primVals, getFieldOffset(name, Character.TYPE), val);
1612 }
1613
1614 public void put(String name, short val) {
1615 Bits.putShort(primVals, getFieldOffset(name, Short.TYPE), val);
1616 }
1617
1618 public void put(String name, int val) {
1619 Bits.putInt(primVals, getFieldOffset(name, Integer.TYPE), val);
1620 }
1621
1622 public void put(String name, float val) {
1623 Bits.putFloat(primVals, getFieldOffset(name, Float.TYPE), val);
1624 }
1625
1626 public void put(String name, long val) {
1627 Bits.putLong(primVals, getFieldOffset(name, Long.TYPE), val);
1628 }
1629
1630 public void put(String name, double val) {
1631 Bits.putDouble(primVals, getFieldOffset(name, Double.TYPE), val);
1632 }
1633
1634 public void put(String name, Object val) {
1635 objVals[getFieldOffset(name, Object.class)] = val;
1636 }
1637
1638 // deprecated in ObjectOutputStream.PutField
1639 public void write(ObjectOutput out) throws IOException {
1640 /*
1641 * Applications should *not* use this method to write PutField
1642 * data, as it will lead to stream corruption if the PutField
1643 * object writes any primitive data (since block data mode is not
1644 * unset/set properly, as is done in OOS.writeFields()). This
1645 * broken implementation is being retained solely for behavioral
1646 * compatibility, in order to support applications which use
1647 * OOS.PutField.write() for writing only non-primitive data.
1648 *
1649 * Serialization of unshared objects is not implemented here since
1650 * it is not necessary for backwards compatibility; also, unshared
1651 * semantics may not be supported by the given ObjectOutput
1652 * instance. Applications which write unshared objects using the
1653 * PutField API must use OOS.writeFields().
1654 */
1655 if (ObjectOutputStream.this != out) {
1656 throw new IllegalArgumentException("wrong stream");
1657 }
1658 out.write(primVals, 0, primVals.length);
1659
1660 ObjectStreamField[] fields = desc.getFields(false);
1661 int numPrimFields = fields.length - objVals.length;
1662 // REMIND: warn if numPrimFields > 0?
1663 for (int i = 0; i < objVals.length; i++) {
1664 if (fields[numPrimFields + i].isUnshared()) {
1665 throw new IOException("cannot write unshared object");
1666 }
1667 out.writeObject(objVals[i]);
1668 }
1669 }
1670
1671 /**
1672 * Writes buffered primitive data and object fields to stream.
1673 */
1674 void writeFields() throws IOException {
1675 bout.write(primVals, 0, primVals.length, false);
1676
1677 ObjectStreamField[] fields = desc.getFields(false);
1678 int numPrimFields = fields.length - objVals.length;
1679 for (int i = 0; i < objVals.length; i++) {
1680 if (extendedDebugInfo) {
1681 debugInfoStack.push(
1682 "field (class \"" + desc.getName() + "\", name: \"" +
1683 fields[numPrimFields + i].getName() + "\", type: \"" +
1684 fields[numPrimFields + i].getType() + "\")");
1685 }
1686 try {
1687 writeObject0(objVals[i],
1688 fields[numPrimFields + i].isUnshared());
1689 } finally {
1690 if (extendedDebugInfo) {
1691 debugInfoStack.pop();
1692 }
1693 }
1694 }
1695 }
1696
1697 /**
1698 * Returns offset of field with given name and type. A specified type
1699 * of null matches all types, Object.class matches all non-primitive
1700 * types, and any other non-null type matches assignable types only.
1701 * Throws IllegalArgumentException if no matching field found.
1702 */
1703 private int getFieldOffset(String name, Class type) {
1704 ObjectStreamField field = desc.getField(name, type);
1705 if (field == null) {
1706 throw new IllegalArgumentException("no such field " + name +
1707 " with type " + type);
1708 }
1709 return field.getOffset();
1710 }
1711 }
1712
1713 /**
1714 * Buffered output stream with two modes: in default mode, outputs data in
1715 * same format as DataOutputStream; in "block data" mode, outputs data
1716 * bracketed by block data markers (see object serialization specification
1717 * for details).
1718 */
1719 private static class BlockDataOutputStream
1720 extends OutputStream implements DataOutput
1721 {
1722 /** maximum data block length */
1723 private static final int MAX_BLOCK_SIZE = 1024;
1724 /** maximum data block header length */
1725 private static final int MAX_HEADER_SIZE = 5;
1726 /** (tunable) length of char buffer (for writing strings) */
1727 private static final int CHAR_BUF_SIZE = 256;
1728
1729 /** buffer for writing general/block data */
1730 private final byte[] buf = new byte[MAX_BLOCK_SIZE];
1731 /** buffer for writing block data headers */
1732 private final byte[] hbuf = new byte[MAX_HEADER_SIZE];
1733 /** char buffer for fast string writes */
1734 private final char[] cbuf = new char[CHAR_BUF_SIZE];
1735
1736 /** block data mode */
1737 private boolean blkmode = false;
1738 /** current offset into buf */
1739 private int pos = 0;
1740
1741 /** underlying output stream */
1742 private final OutputStream out;
1743 /** loopback stream (for data writes that span data blocks) */
1744 private final DataOutputStream dout;
1745
1746 /**
1747 * Creates new BlockDataOutputStream on top of given underlying stream.
1748 * Block data mode is turned off by default.
1749 */
1750 BlockDataOutputStream(OutputStream out) {
1751 this.out = out;
1752 dout = new DataOutputStream(this);
1753 }
1754
1755 /**
1756 * Sets block data mode to the given mode (true == on, false == off)
1757 * and returns the previous mode value. If the new mode is the same as
1758 * the old mode, no action is taken. If the new mode differs from the
1759 * old mode, any buffered data is flushed before switching to the new
1760 * mode.
1761 */
1762 boolean setBlockDataMode(boolean mode) throws IOException {
1763 if (blkmode == mode) {
1764 return blkmode;
1765 }
1766 drain();
1767 blkmode = mode;
1768 return !blkmode;
1769 }
1770
1771 /**
1772 * Returns true if the stream is currently in block data mode, false
1773 * otherwise.
1774 */
1775 boolean getBlockDataMode() {
1776 return blkmode;
1777 }
1778
1779 /* ----------------- generic output stream methods ----------------- */
1780 /*
1781 * The following methods are equivalent to their counterparts in
1782 * OutputStream, except that they partition written data into data
1783 * blocks when in block data mode.
1784 */
1785
1786 public void write(int b) throws IOException {
1787 if (pos >= MAX_BLOCK_SIZE) {
1788 drain();
1789 }
1790 buf[pos++] = (byte) b;
1791 }
1792
1793 public void write(byte[] b) throws IOException {
1794 write(b, 0, b.length, false);
1795 }
1796
1797 public void write(byte[] b, int off, int len) throws IOException {
1798 write(b, off, len, false);
1799 }
1800
1801 public void flush() throws IOException {
1802 drain();
1803 out.flush();
1804 }
1805
1806 public void close() throws IOException {
1807 flush();
1808 out.close();
1809 }
1810
1811 /**
1812 * Writes specified span of byte values from given array. If copy is
1813 * true, copies the values to an intermediate buffer before writing
1814 * them to underlying stream (to avoid exposing a reference to the
1815 * original byte array).
1816 */
1817 void write(byte[] b, int off, int len, boolean copy)
1818 throws IOException
1819 {
1820 if (!(copy || blkmode)) { // write directly
1821 drain();
1822 out.write(b, off, len);
1823 return;
1824 }
1825
1826 while (len > 0) {
1827 if (pos >= MAX_BLOCK_SIZE) {
1828 drain();
1829 }
1830 if (len >= MAX_BLOCK_SIZE && !copy && pos == 0) {
1831 // avoid unnecessary copy
1832 writeBlockHeader(MAX_BLOCK_SIZE);
1833 out.write(b, off, MAX_BLOCK_SIZE);
1834 off += MAX_BLOCK_SIZE;
1835 len -= MAX_BLOCK_SIZE;
1836 } else {
1837 int wlen = Math.min(len, MAX_BLOCK_SIZE - pos);
1838 System.arraycopy(b, off, buf, pos, wlen);
1839 pos += wlen;
1840 off += wlen;
1841 len -= wlen;
1842 }
1843 }
1844 }
1845
1846 /**
1847 * Writes all buffered data from this stream to the underlying stream,
1848 * but does not flush underlying stream.
1849 */
1850 void drain() throws IOException {
1851 if (pos == 0) {
1852 return;
1853 }
1854 if (blkmode) {
1855 writeBlockHeader(pos);
1856 }
1857 out.write(buf, 0, pos);
1858 pos = 0;
1859 }
1860
1861 /**
1862 * Writes block data header. Data blocks shorter than 256 bytes are
1863 * prefixed with a 2-byte header; all others start with a 5-byte
1864 * header.
1865 */
1866 private void writeBlockHeader(int len) throws IOException {
1867 if (len <= 0xFF) {
1868 hbuf[0] = TC_BLOCKDATA;
1869 hbuf[1] = (byte) len;
1870 out.write(hbuf, 0, 2);
1871 } else {
1872 hbuf[0] = TC_BLOCKDATALONG;
1873 Bits.putInt(hbuf, 1, len);
1874 out.write(hbuf, 0, 5);
1875 }
1876 }
1877
1878
1879 /* ----------------- primitive data output methods ----------------- */
1880 /*
1881 * The following methods are equivalent to their counterparts in
1882 * DataOutputStream, except that they partition written data into data
1883 * blocks when in block data mode.
1884 */
1885
1886 public void writeBoolean(boolean v) throws IOException {
1887 if (pos >= MAX_BLOCK_SIZE) {
1888 drain();
1889 }
1890 Bits.putBoolean(buf, pos++, v);
1891 }
1892
1893 public void writeByte(int v) throws IOException {
1894 if (pos >= MAX_BLOCK_SIZE) {
1895 drain();
1896 }
1897 buf[pos++] = (byte) v;
1898 }
1899
1900 public void writeChar(int v) throws IOException {
1901 if (pos + 2 <= MAX_BLOCK_SIZE) {
1902 Bits.putChar(buf, pos, (char) v);
1903 pos += 2;
1904 } else {
1905 dout.writeChar(v);
1906 }
1907 }
1908
1909 public void writeShort(int v) throws IOException {
1910 if (pos + 2 <= MAX_BLOCK_SIZE) {
1911 Bits.putShort(buf, pos, (short) v);
1912 pos += 2;
1913 } else {
1914 dout.writeShort(v);
1915 }
1916 }
1917
1918 public void writeInt(int v) throws IOException {
1919 if (pos + 4 <= MAX_BLOCK_SIZE) {
1920 Bits.putInt(buf, pos, v);
1921 pos += 4;
1922 } else {
1923 dout.writeInt(v);
1924 }
1925 }
1926
1927 public void writeFloat(float v) throws IOException {
1928 if (pos + 4 <= MAX_BLOCK_SIZE) {
1929 Bits.putFloat(buf, pos, v);
1930 pos += 4;
1931 } else {
1932 dout.writeFloat(v);
1933 }
1934 }
1935
1936 public void writeLong(long v) throws IOException {
1937 if (pos + 8 <= MAX_BLOCK_SIZE) {
1938 Bits.putLong(buf, pos, v);
1939 pos += 8;
1940 } else {
1941 dout.writeLong(v);
1942 }
1943 }
1944
1945 public void writeDouble(double v) throws IOException {
1946 if (pos + 8 <= MAX_BLOCK_SIZE) {
1947 Bits.putDouble(buf, pos, v);
1948 pos += 8;
1949 } else {
1950 dout.writeDouble(v);
1951 }
1952 }
1953
1954 public void writeBytes(String s) throws IOException {
1955 int endoff = s.length();
1956 int cpos = 0;
1957 int csize = 0;
1958 for (int off = 0; off < endoff; ) {
1959 if (cpos >= csize) {
1960 cpos = 0;
1961 csize = Math.min(endoff - off, CHAR_BUF_SIZE);
1962 s.getChars(off, off + csize, cbuf, 0);
1963 }
1964 if (pos >= MAX_BLOCK_SIZE) {
1965 drain();
1966 }
1967 int n = Math.min(csize - cpos, MAX_BLOCK_SIZE - pos);
1968 int stop = pos + n;
1969 while (pos < stop) {
1970 buf[pos++] = (byte) cbuf[cpos++];
1971 }
1972 off += n;
1973 }
1974 }
1975
1976 public void writeChars(String s) throws IOException {
1977 int endoff = s.length();
1978 for (int off = 0; off < endoff; ) {
1979 int csize = Math.min(endoff - off, CHAR_BUF_SIZE);
1980 s.getChars(off, off + csize, cbuf, 0);
1981 writeChars(cbuf, 0, csize);
1982 off += csize;
1983 }
1984 }
1985
1986 public void writeUTF(String s) throws IOException {
1987 writeUTF(s, getUTFLength(s));
1988 }
1989
1990
1991 /* -------------- primitive data array output methods -------------- */
1992 /*
1993 * The following methods write out spans of primitive data values.
1994 * Though equivalent to calling the corresponding primitive write
1995 * methods repeatedly, these methods are optimized for writing groups
1996 * of primitive data values more efficiently.
1997 */
1998
1999 void writeBooleans(boolean[] v, int off, int len) throws IOException {
2000 int endoff = off + len;
2001 while (off < endoff) {
2002 if (pos >= MAX_BLOCK_SIZE) {
2003 drain();
2004 }
2005 int stop = Math.min(endoff, off + (MAX_BLOCK_SIZE - pos));
2006 while (off < stop) {
2007 Bits.putBoolean(buf, pos++, v[off++]);
2008 }
2009 }
2010 }
2011
2012 void writeChars(char[] v, int off, int len) throws IOException {
2013 int limit = MAX_BLOCK_SIZE - 2;
2014 int endoff = off + len;
2015 while (off < endoff) {
2016 if (pos <= limit) {
2017 int avail = (MAX_BLOCK_SIZE - pos) >> 1;
2018 int stop = Math.min(endoff, off + avail);
2019 while (off < stop) {
2020 Bits.putChar(buf, pos, v[off++]);
2021 pos += 2;
2022 }
2023 } else {
2024 dout.writeChar(v[off++]);
2025 }
2026 }
2027 }
2028
2029 void writeShorts(short[] v, int off, int len) throws IOException {
2030 int limit = MAX_BLOCK_SIZE - 2;
2031 int endoff = off + len;
2032 while (off < endoff) {
2033 if (pos <= limit) {
2034 int avail = (MAX_BLOCK_SIZE - pos) >> 1;
2035 int stop = Math.min(endoff, off + avail);
2036 while (off < stop) {
2037 Bits.putShort(buf, pos, v[off++]);
2038 pos += 2;
2039 }
2040 } else {
2041 dout.writeShort(v[off++]);
2042 }
2043 }
2044 }
2045
2046 void writeInts(int[] v, int off, int len) throws IOException {
2047 int limit = MAX_BLOCK_SIZE - 4;
2048 int endoff = off + len;
2049 while (off < endoff) {
2050 if (pos <= limit) {
2051 int avail = (MAX_BLOCK_SIZE - pos) >> 2;
2052 int stop = Math.min(endoff, off + avail);
2053 while (off < stop) {
2054 Bits.putInt(buf, pos, v[off++]);
2055 pos += 4;
2056 }
2057 } else {
2058 dout.writeInt(v[off++]);
2059 }
2060 }
2061 }
2062
2063 void writeFloats(float[] v, int off, int len) throws IOException {
2064 int limit = MAX_BLOCK_SIZE - 4;
2065 int endoff = off + len;
2066 while (off < endoff) {
2067 if (pos <= limit) {
2068 int avail = (MAX_BLOCK_SIZE - pos) >> 2;
2069 int chunklen = Math.min(endoff - off, avail);
2070 floatsToBytes(v, off, buf, pos, chunklen);
2071 off += chunklen;
2072 pos += chunklen << 2;
2073 } else {
2074 dout.writeFloat(v[off++]);
2075 }
2076 }
2077 }
2078
2079 void writeLongs(long[] v, int off, int len) throws IOException {
2080 int limit = MAX_BLOCK_SIZE - 8;
2081 int endoff = off + len;
2082 while (off < endoff) {
2083 if (pos <= limit) {
2084 int avail = (MAX_BLOCK_SIZE - pos) >> 3;
2085 int stop = Math.min(endoff, off + avail);
2086 while (off < stop) {
2087 Bits.putLong(buf, pos, v[off++]);
2088 pos += 8;
2089 }
2090 } else {
2091 dout.writeLong(v[off++]);
2092 }
2093 }
2094 }
2095
2096 void writeDoubles(double[] v, int off, int len) throws IOException {
2097 int limit = MAX_BLOCK_SIZE - 8;
2098 int endoff = off + len;
2099 while (off < endoff) {
2100 if (pos <= limit) {
2101 int avail = (MAX_BLOCK_SIZE - pos) >> 3;
2102 int chunklen = Math.min(endoff - off, avail);
2103 doublesToBytes(v, off, buf, pos, chunklen);
2104 off += chunklen;
2105 pos += chunklen << 3;
2106 } else {
2107 dout.writeDouble(v[off++]);
2108 }
2109 }
2110 }
2111
2112 /**
2113 * Returns the length in bytes of the UTF encoding of the given string.
2114 */
2115 long getUTFLength(String s) {
2116 int len = s.length();
2117 long utflen = 0;
2118 for (int off = 0; off < len; ) {
2119 int csize = Math.min(len - off, CHAR_BUF_SIZE);
2120 s.getChars(off, off + csize, cbuf, 0);
2121 for (int cpos = 0; cpos < csize; cpos++) {
2122 char c = cbuf[cpos];
2123 if (c >= 0x0001 && c <= 0x007F) {
2124 utflen++;
2125 } else if (c > 0x07FF) {
2126 utflen += 3;
2127 } else {
2128 utflen += 2;
2129 }
2130 }
2131 off += csize;
2132 }
2133 return utflen;
2134 }
2135
2136 /**
2137 * Writes the given string in UTF format. This method is used in
2138 * situations where the UTF encoding length of the string is already
2139 * known; specifying it explicitly avoids a prescan of the string to
2140 * determine its UTF length.
2141 */
2142 void writeUTF(String s, long utflen) throws IOException {
2143 if (utflen > 0xFFFFL) {
2144 throw new UTFDataFormatException();
2145 }
2146 writeShort((int) utflen);
2147 if (utflen == (long) s.length()) {
2148 writeBytes(s);
2149 } else {
2150 writeUTFBody(s);
2151 }
2152 }
2153
2154 /**
2155 * Writes given string in "long" UTF format. "Long" UTF format is
2156 * identical to standard UTF, except that it uses an 8 byte header
2157 * (instead of the standard 2 bytes) to convey the UTF encoding length.
2158 */
2159 void writeLongUTF(String s) throws IOException {
2160 writeLongUTF(s, getUTFLength(s));
2161 }
2162
2163 /**
2164 * Writes given string in "long" UTF format, where the UTF encoding
2165 * length of the string is already known.
2166 */
2167 void writeLongUTF(String s, long utflen) throws IOException {
2168 writeLong(utflen);
2169 if (utflen == (long) s.length()) {
2170 writeBytes(s);
2171 } else {
2172 writeUTFBody(s);
2173 }
2174 }
2175
2176 /**
2177 * Writes the "body" (i.e., the UTF representation minus the 2-byte or
2178 * 8-byte length header) of the UTF encoding for the given string.
2179 */
2180 private void writeUTFBody(String s) throws IOException {
2181 int limit = MAX_BLOCK_SIZE - 3;
2182 int len = s.length();
2183 for (int off = 0; off < len; ) {
2184 int csize = Math.min(len - off, CHAR_BUF_SIZE);
2185 s.getChars(off, off + csize, cbuf, 0);
2186 for (int cpos = 0; cpos < csize; cpos++) {
2187 char c = cbuf[cpos];
2188 if (pos <= limit) {
2189 if (c <= 0x007F && c != 0) {
2190 buf[pos++] = (byte) c;
2191 } else if (c > 0x07FF) {
2192 buf[pos + 2] = (byte) (0x80 | ((c >> 0) & 0x3F));
2193 buf[pos + 1] = (byte) (0x80 | ((c >> 6) & 0x3F));
2194 buf[pos + 0] = (byte) (0xE0 | ((c >> 12) & 0x0F));
2195 pos += 3;
2196 } else {
2197 buf[pos + 1] = (byte) (0x80 | ((c >> 0) & 0x3F));
2198 buf[pos + 0] = (byte) (0xC0 | ((c >> 6) & 0x1F));
2199 pos += 2;
2200 }
2201 } else { // write one byte at a time to normalize block
2202 if (c <= 0x007F && c != 0) {
2203 write(c);
2204 } else if (c > 0x07FF) {
2205 write(0xE0 | ((c >> 12) & 0x0F));
2206 write(0x80 | ((c >> 6) & 0x3F));
2207 write(0x80 | ((c >> 0) & 0x3F));
2208 } else {
2209 write(0xC0 | ((c >> 6) & 0x1F));
2210 write(0x80 | ((c >> 0) & 0x3F));
2211 }
2212 }
2213 }
2214 off += csize;
2215 }
2216 }
2217 }
2218
2219 /**
2220 * Lightweight identity hash table which maps objects to integer handles,
2221 * assigned in ascending order.
2222 */
2223 private static class HandleTable {
2224
2225 /* number of mappings in table/next available handle */
2226 private int size;
2227 /* size threshold determining when to expand hash spine */
2228 private int threshold;
2229 /* factor for computing size threshold */
2230 private final float loadFactor;
2231 /* maps hash value -> candidate handle value */
2232 private int[] spine;
2233 /* maps handle value -> next candidate handle value */
2234 private int[] next;
2235 /* maps handle value -> associated object */
2236 private Object[] objs;
2237
2238 /**
2239 * Creates new HandleTable with given capacity and load factor.
2240 */
2241 HandleTable(int initialCapacity, float loadFactor) {
2242 this.loadFactor = loadFactor;
2243 spine = new int[initialCapacity];
2244 next = new int[initialCapacity];
2245 objs = new Object[initialCapacity];
2246 threshold = (int) (initialCapacity * loadFactor);
2247 clear();
2248 }
2249
2250 /**
2251 * Assigns next available handle to given object, and returns handle
2252 * value. Handles are assigned in ascending order starting at 0.
2253 */
2254 int assign(Object obj) {
2255 if (size >= next.length) {
2256 growEntries();
2257 }
2258 if (size >= threshold) {
2259 growSpine();
2260 }
2261 insert(obj, size);
2262 return size++;
2263 }
2264
2265 /**
2266 * Looks up and returns handle associated with given object, or -1 if
2267 * no mapping found.
2268 */
2269 int lookup(Object obj) {
2270 if (size == 0) {
2271 return -1;
2272 }
2273 int index = hash(obj) % spine.length;
2274 for (int i = spine[index]; i >= 0; i = next[i]) {
2275 if (objs[i] == obj) {
2276 return i;
2277 }
2278 }
2279 return -1;
2280 }
2281
2282 /**
2283 * Resets table to its initial (empty) state.
2284 */
2285 void clear() {
2286 Arrays.fill(spine, -1);
2287 Arrays.fill(objs, 0, size, null);
2288 size = 0;
2289 }
2290
2291 /**
2292 * Returns the number of mappings currently in table.
2293 */
2294 int size() {
2295 return size;
2296 }
2297
2298 /**
2299 * Inserts mapping object -> handle mapping into table. Assumes table
2300 * is large enough to accommodate new mapping.
2301 */
2302 private void insert(Object obj, int handle) {
2303 int index = hash(obj) % spine.length;
2304 objs[handle] = obj;
2305 next[handle] = spine[index];
2306 spine[index] = handle;
2307 }
2308
2309 /**
2310 * Expands the hash "spine" -- equivalent to increasing the number of
2311 * buckets in a conventional hash table.
2312 */
2313 private void growSpine() {
2314 spine = new int[(spine.length << 1) + 1];
2315 threshold = (int) (spine.length * loadFactor);
2316 Arrays.fill(spine, -1);
2317 for (int i = 0; i < size; i++) {
2318 insert(objs[i], i);
2319 }
2320 }
2321
2322 /**
2323 * Increases hash table capacity by lengthening entry arrays.
2324 */
2325 private void growEntries() {
2326 int newLength = (next.length << 1) + 1;
2327 int[] newNext = new int[newLength];
2328 System.arraycopy(next, 0, newNext, 0, size);
2329 next = newNext;
2330
2331 Object[] newObjs = new Object[newLength];
2332 System.arraycopy(objs, 0, newObjs, 0, size);
2333 objs = newObjs;
2334 }
2335
2336 /**
2337 * Returns hash value for given object.
2338 */
2339 private int hash(Object obj) {
2340 return System.identityHashCode(obj) & 0x7FFFFFFF;
2341 }
2342 }
2343
2344 /**
2345 * Lightweight identity hash table which maps objects to replacement
2346 * objects.
2347 */
2348 private static class ReplaceTable {
2349
2350 /* maps object -> index */
2351 private final HandleTable htab;
2352 /* maps index -> replacement object */
2353 private Object[] reps;
2354
2355 /**
2356 * Creates new ReplaceTable with given capacity and load factor.
2357 */
2358 ReplaceTable(int initialCapacity, float loadFactor) {
2359 htab = new HandleTable(initialCapacity, loadFactor);
2360 reps = new Object[initialCapacity];
2361 }
2362
2363 /**
2364 * Enters mapping from object to replacement object.
2365 */
2366 void assign(Object obj, Object rep) {
2367 int index = htab.assign(obj);
2368 while (index >= reps.length) {
2369 grow();
2370 }
2371 reps[index] = rep;
2372 }
2373
2374 /**
2375 * Looks up and returns replacement for given object. If no
2376 * replacement is found, returns the lookup object itself.
2377 */
2378 Object lookup(Object obj) {
2379 int index = htab.lookup(obj);
2380 return (index >= 0) ? reps[index] : obj;
2381 }
2382
2383 /**
2384 * Resets table to its initial (empty) state.
2385 */
2386 void clear() {
2387 Arrays.fill(reps, 0, htab.size(), null);
2388 htab.clear();
2389 }
2390
2391 /**
2392 * Returns the number of mappings currently in table.
2393 */
2394 int size() {
2395 return htab.size();
2396 }
2397
2398 /**
2399 * Increases table capacity.
2400 */
2401 private void grow() {
2402 Object[] newReps = new Object[(reps.length << 1) + 1];
2403 System.arraycopy(reps, 0, newReps, 0, reps.length);
2404 reps = newReps;
2405 }
2406 }
2407
2408 /**
2409 * Stack to keep debug information about the state of the
2410 * serialization process, for embedding in exception messages.
2411 */
2412 private static class DebugTraceInfoStack {
2413 private final List<String> stack;
2414
2415 DebugTraceInfoStack() {
2416 stack = new ArrayList<>();
2417 }
2418
2419 /**
2420 * Removes all of the elements from enclosed list.
2421 */
2422 void clear() {
2423 stack.clear();
2424 }
2425
2426 /**
2427 * Removes the object at the top of enclosed list.
2428 */
2429 void pop() {
2430 stack.remove(stack.size()-1);
2431 }
2432
2433 /**
2434 * Pushes a String onto the top of enclosed list.
2435 */
2436 void push(String entry) {
2437 stack.add("\t- " + entry);
2438 }
2439
2440 /**
2441 * Returns a string representation of this object
2442 */
2443 public String toString() {
2444 StringBuilder buffer = new StringBuilder();
2445 if (!stack.isEmpty()) {
2446 for(int i = stack.size(); i > 0; i-- ) {
2447 buffer.append(stack.get(i-1) + ((i != 1) ? "\n" : ""));
2448 }
2449 }
2450 return buffer.toString();
2451 }
2452 }
2453
2454}
java/pkg/java/io/ObjectStreamClass$1.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectStreamClass$2.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectStreamClass$3.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectStreamClass$4.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectStreamClass$5.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectStreamClass$Caches.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectStreamClass$ClassDataSlot.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectStreamClass$EntryFuture$1.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectStreamClass$EntryFuture.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectStreamClass$FieldReflector.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectStreamClass$FieldReflectorKey.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectStreamClass$MemberSignature.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectStreamClass$WeakClassKey.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectStreamClass.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectStreamClass.java+2304−0
@@ -0,0 +1,2304 @@
1/*
2 * Copyright (c) 1996, 2011, 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
26package java.io;
27
28import java.lang.ref.Reference;
29import java.lang.ref.ReferenceQueue;
30import java.lang.ref.SoftReference;
31import java.lang.ref.WeakReference;
32import java.lang.reflect.Constructor;
33import java.lang.reflect.Field;
34import java.lang.reflect.InvocationTargetException;
35import java.lang.reflect.Member;
36import java.lang.reflect.Method;
37import java.lang.reflect.Modifier;
38import java.lang.reflect.Proxy;
39import java.security.AccessController;
40import java.security.MessageDigest;
41import java.security.NoSuchAlgorithmException;
42import java.security.PrivilegedAction;
43import java.util.ArrayList;
44import java.util.Arrays;
45import java.util.Collections;
46import java.util.Comparator;
47import java.util.HashSet;
48import java.util.Set;
49import java.util.concurrent.ConcurrentHashMap;
50import java.util.concurrent.ConcurrentMap;
51import sun.misc.Unsafe;
52import sun.reflect.ReflectionFactory;
53
54/**
55 * Serialization's descriptor for classes. It contains the name and
56 * serialVersionUID of the class. The ObjectStreamClass for a specific class
57 * loaded in this Java VM can be found/created using the lookup method.
58 *
59 * <p>The algorithm to compute the SerialVersionUID is described in
60 * <a href="../../../platform/serialization/spec/class.html#4100">Object
61 * Serialization Specification, Section 4.6, Stream Unique Identifiers</a>.
62 *
63 * @author Mike Warres
64 * @author Roger Riggs
65 * @see ObjectStreamField
66 * @see <a href="../../../platform/serialization/spec/class.html">Object Serialization Specification, Section 4, Class Descriptors</a>
67 * @since JDK1.1
68 */
69public class ObjectStreamClass implements Serializable {
70
71 /** serialPersistentFields value indicating no serializable fields */
72 public static final ObjectStreamField[] NO_FIELDS =
73 new ObjectStreamField[0];
74
75 private static final long serialVersionUID = -6120832682080437368L;
76 private static final ObjectStreamField[] serialPersistentFields =
77 NO_FIELDS;
78
79 /** reflection factory for obtaining serialization constructors */
80 private static final ReflectionFactory reflFactory =
81 AccessController.doPrivileged(
82 new ReflectionFactory.GetReflectionFactoryAction());
83
84 private static class Caches {
85 /** cache mapping local classes -> descriptors */
86 static final ConcurrentMap<WeakClassKey,Reference<?>> localDescs =
87 new ConcurrentHashMap<>();
88
89 /** cache mapping field group/local desc pairs -> field reflectors */
90 static final ConcurrentMap<FieldReflectorKey,Reference<?>> reflectors =
91 new ConcurrentHashMap<>();
92
93 /** queue for WeakReferences to local classes */
94 private static final ReferenceQueue<Class<?>> localDescsQueue =
95 new ReferenceQueue<>();
96 /** queue for WeakReferences to field reflectors keys */
97 private static final ReferenceQueue<Class<?>> reflectorsQueue =
98 new ReferenceQueue<>();
99 }
100
101 /** class associated with this descriptor (if any) */
102 private Class<?> cl;
103 /** name of class represented by this descriptor */
104 private String name;
105 /** serialVersionUID of represented class (null if not computed yet) */
106 private volatile Long suid;
107
108 /** true if represents dynamic proxy class */
109 private boolean isProxy;
110 /** true if represents enum type */
111 private boolean isEnum;
112 /** true if represented class implements Serializable */
113 private boolean serializable;
114 /** true if represented class implements Externalizable */
115 private boolean externalizable;
116 /** true if desc has data written by class-defined writeObject method */
117 private boolean hasWriteObjectData;
118 /**
119 * true if desc has externalizable data written in block data format; this
120 * must be true by default to accommodate ObjectInputStream subclasses which
121 * override readClassDescriptor() to return class descriptors obtained from
122 * ObjectStreamClass.lookup() (see 4461737)
123 */
124 private boolean hasBlockExternalData = true;
125
126 /** exception (if any) thrown while attempting to resolve class */
127 private ClassNotFoundException resolveEx;
128 /** exception (if any) to throw if non-enum deserialization attempted */
129 private InvalidClassException deserializeEx;
130 /** exception (if any) to throw if non-enum serialization attempted */
131 private InvalidClassException serializeEx;
132 /** exception (if any) to throw if default serialization attempted */
133 private InvalidClassException defaultSerializeEx;
134
135 /** serializable fields */
136 private ObjectStreamField[] fields;
137 /** aggregate marshalled size of primitive fields */
138 private int primDataSize;
139 /** number of non-primitive fields */
140 private int numObjFields;
141 /** reflector for setting/getting serializable field values */
142 private FieldReflector fieldRefl;
143 /** data layout of serialized objects described by this class desc */
144 private volatile ClassDataSlot[] dataLayout;
145
146 /** serialization-appropriate constructor, or null if none */
147 private Constructor cons;
148 /** class-defined writeObject method, or null if none */
149 private Method writeObjectMethod;
150 /** class-defined readObject method, or null if none */
151 private Method readObjectMethod;
152 /** class-defined readObjectNoData method, or null if none */
153 private Method readObjectNoDataMethod;
154 /** class-defined writeReplace method, or null if none */
155 private Method writeReplaceMethod;
156 /** class-defined readResolve method, or null if none */
157 private Method readResolveMethod;
158
159 /** local class descriptor for represented class (may point to self) */
160 private ObjectStreamClass localDesc;
161 /** superclass descriptor appearing in stream */
162 private ObjectStreamClass superDesc;
163
164 /**
165 * Initializes native code.
166 */
167 private static native void initNative();
168 static {
169 initNative();
170 }
171
172 /**
173 * Find the descriptor for a class that can be serialized. Creates an
174 * ObjectStreamClass instance if one does not exist yet for class. Null is
175 * returned if the specified class does not implement java.io.Serializable
176 * or java.io.Externalizable.
177 *
178 * @param cl class for which to get the descriptor
179 * @return the class descriptor for the specified class
180 */
181 public static ObjectStreamClass lookup(Class<?> cl) {
182 return lookup(cl, false);
183 }
184
185 /**
186 * Returns the descriptor for any class, regardless of whether it
187 * implements {@link Serializable}.
188 *
189 * @param cl class for which to get the descriptor
190 * @return the class descriptor for the specified class
191 * @since 1.6
192 */
193 public static ObjectStreamClass lookupAny(Class<?> cl) {
194 return lookup(cl, true);
195 }
196
197 /**
198 * Returns the name of the class described by this descriptor.
199 * This method returns the name of the class in the format that
200 * is used by the {@link Class#getName} method.
201 *
202 * @return a string representing the name of the class
203 */
204 public String getName() {
205 return name;
206 }
207
208 /**
209 * Return the serialVersionUID for this class. The serialVersionUID
210 * defines a set of classes all with the same name that have evolved from a
211 * common root class and agree to be serialized and deserialized using a
212 * common format. NonSerializable classes have a serialVersionUID of 0L.
213 *
214 * @return the SUID of the class described by this descriptor
215 */
216 public long getSerialVersionUID() {
217 // REMIND: synchronize instead of relying on volatile?
218 if (suid == null) {
219 suid = AccessController.doPrivileged(
220 new PrivilegedAction<Long>() {
221 public Long run() {
222 return computeDefaultSUID(cl);
223 }
224 }
225 );
226 }
227 return suid.longValue();
228 }
229
230 /**
231 * Return the class in the local VM that this version is mapped to. Null
232 * is returned if there is no corresponding local class.
233 *
234 * @return the <code>Class</code> instance that this descriptor represents
235 */
236 public Class<?> forClass() {
237 return cl;
238 }
239
240 /**
241 * Return an array of the fields of this serializable class.
242 *
243 * @return an array containing an element for each persistent field of
244 * this class. Returns an array of length zero if there are no
245 * fields.
246 * @since 1.2
247 */
248 public ObjectStreamField[] getFields() {
249 return getFields(true);
250 }
251
252 /**
253 * Get the field of this class by name.
254 *
255 * @param name the name of the data field to look for
256 * @return The ObjectStreamField object of the named field or null if
257 * there is no such named field.
258 */
259 public ObjectStreamField getField(String name) {
260 return getField(name, null);
261 }
262
263 /**
264 * Return a string describing this ObjectStreamClass.
265 */
266 public String toString() {
267 return name + ": static final long serialVersionUID = " +
268 getSerialVersionUID() + "L;";
269 }
270
271 /**
272 * Looks up and returns class descriptor for given class, or null if class
273 * is non-serializable and "all" is set to false.
274 *
275 * @param cl class to look up
276 * @param all if true, return descriptors for all classes; if false, only
277 * return descriptors for serializable classes
278 */
279 static ObjectStreamClass lookup(Class<?> cl, boolean all) {
280 if (!(all || Serializable.class.isAssignableFrom(cl))) {
281 return null;
282 }
283 processQueue(Caches.localDescsQueue, Caches.localDescs);
284 WeakClassKey key = new WeakClassKey(cl, Caches.localDescsQueue);
285 Reference<?> ref = Caches.localDescs.get(key);
286 Object entry = null;
287 if (ref != null) {
288 entry = ref.get();
289 }
290 EntryFuture future = null;
291 if (entry == null) {
292 EntryFuture newEntry = new EntryFuture();
293 Reference<?> newRef = new SoftReference<>(newEntry);
294 do {
295 if (ref != null) {
296 Caches.localDescs.remove(key, ref);
297 }
298 ref = Caches.localDescs.putIfAbsent(key, newRef);
299 if (ref != null) {
300 entry = ref.get();
301 }
302 } while (ref != null && entry == null);
303 if (entry == null) {
304 future = newEntry;
305 }
306 }
307
308 if (entry instanceof ObjectStreamClass) { // check common case first
309 return (ObjectStreamClass) entry;
310 }
311 if (entry instanceof EntryFuture) {
312 future = (EntryFuture) entry;
313 if (future.getOwner() == Thread.currentThread()) {
314 /*
315 * Handle nested call situation described by 4803747: waiting
316 * for future value to be set by a lookup() call further up the
317 * stack will result in deadlock, so calculate and set the
318 * future value here instead.
319 */
320 entry = null;
321 } else {
322 entry = future.get();
323 }
324 }
325 if (entry == null) {
326 try {
327 entry = new ObjectStreamClass(cl);
328 } catch (Throwable th) {
329 entry = th;
330 }
331 if (future.set(entry)) {
332 Caches.localDescs.put(key, new SoftReference<Object>(entry));
333 } else {
334 // nested lookup call already set future
335 entry = future.get();
336 }
337 }
338
339 if (entry instanceof ObjectStreamClass) {
340 return (ObjectStreamClass) entry;
341 } else if (entry instanceof RuntimeException) {
342 throw (RuntimeException) entry;
343 } else if (entry instanceof Error) {
344 throw (Error) entry;
345 } else {
346 throw new InternalError("unexpected entry: " + entry);
347 }
348 }
349
350 /**
351 * Placeholder used in class descriptor and field reflector lookup tables
352 * for an entry in the process of being initialized. (Internal) callers
353 * which receive an EntryFuture belonging to another thread as the result
354 * of a lookup should call the get() method of the EntryFuture; this will
355 * return the actual entry once it is ready for use and has been set(). To
356 * conserve objects, EntryFutures synchronize on themselves.
357 */
358 private static class EntryFuture {
359
360 private static final Object unset = new Object();
361 private final Thread owner = Thread.currentThread();
362 private Object entry = unset;
363
364 /**
365 * Attempts to set the value contained by this EntryFuture. If the
366 * EntryFuture's value has not been set already, then the value is
367 * saved, any callers blocked in the get() method are notified, and
368 * true is returned. If the value has already been set, then no saving
369 * or notification occurs, and false is returned.
370 */
371 synchronized boolean set(Object entry) {
372 if (this.entry != unset) {
373 return false;
374 }
375 this.entry = entry;
376 notifyAll();
377 return true;
378 }
379
380 /**
381 * Returns the value contained by this EntryFuture, blocking if
382 * necessary until a value is set.
383 */
384 synchronized Object get() {
385 boolean interrupted = false;
386 while (entry == unset) {
387 try {
388 wait();
389 } catch (InterruptedException ex) {
390 interrupted = true;
391 }
392 }
393 if (interrupted) {
394 AccessController.doPrivileged(
395 new PrivilegedAction<Void>() {
396 public Void run() {
397 Thread.currentThread().interrupt();
398 return null;
399 }
400 }
401 );
402 }
403 return entry;
404 }
405
406 /**
407 * Returns the thread that created this EntryFuture.
408 */
409 Thread getOwner() {
410 return owner;
411 }
412 }
413
414 /**
415 * Creates local class descriptor representing given class.
416 */
417 private ObjectStreamClass(final Class<?> cl) {
418 this.cl = cl;
419 name = cl.getName();
420 isProxy = Proxy.isProxyClass(cl);
421 isEnum = Enum.class.isAssignableFrom(cl);
422 serializable = Serializable.class.isAssignableFrom(cl);
423 externalizable = Externalizable.class.isAssignableFrom(cl);
424
425 Class<?> superCl = cl.getSuperclass();
426 superDesc = (superCl != null) ? lookup(superCl, false) : null;
427 localDesc = this;
428
429 if (serializable) {
430 AccessController.doPrivileged(new PrivilegedAction<Void>() {
431 public Void run() {
432 if (isEnum) {
433 suid = Long.valueOf(0);
434 fields = NO_FIELDS;
435 return null;
436 }
437 if (cl.isArray()) {
438 fields = NO_FIELDS;
439 return null;
440 }
441
442 suid = getDeclaredSUID(cl);
443 try {
444 fields = getSerialFields(cl);
445 computeFieldOffsets();
446 } catch (InvalidClassException e) {
447 serializeEx = deserializeEx = e;
448 fields = NO_FIELDS;
449 }
450
451 if (externalizable) {
452 cons = getExternalizableConstructor(cl);
453 } else {
454 cons = getSerializableConstructor(cl);
455 writeObjectMethod = getPrivateMethod(cl, "writeObject",
456 new Class<?>[] { ObjectOutputStream.class },
457 Void.TYPE);
458 readObjectMethod = getPrivateMethod(cl, "readObject",
459 new Class<?>[] { ObjectInputStream.class },
460 Void.TYPE);
461 readObjectNoDataMethod = getPrivateMethod(
462 cl, "readObjectNoData", null, Void.TYPE);
463 hasWriteObjectData = (writeObjectMethod != null);
464 }
465 writeReplaceMethod = getInheritableMethod(
466 cl, "writeReplace", null, Object.class);
467 readResolveMethod = getInheritableMethod(
468 cl, "readResolve", null, Object.class);
469 return null;
470 }
471 });
472 } else {
473 suid = Long.valueOf(0);
474 fields = NO_FIELDS;
475 }
476
477 try {
478 fieldRefl = getReflector(fields, this);
479 } catch (InvalidClassException ex) {
480 // field mismatches impossible when matching local fields vs. self
481 throw new InternalError();
482 }
483
484 if (deserializeEx == null) {
485 if (isEnum) {
486 deserializeEx = new InvalidClassException(name, "enum type");
487 } else if (cons == null) {
488 deserializeEx = new InvalidClassException(
489 name, "no valid constructor");
490 }
491 }
492 for (int i = 0; i < fields.length; i++) {
493 if (fields[i].getField() == null) {
494 defaultSerializeEx = new InvalidClassException(
495 name, "unmatched serializable field(s) declared");
496 }
497 }
498 }
499
500 /**
501 * Creates blank class descriptor which should be initialized via a
502 * subsequent call to initProxy(), initNonProxy() or readNonProxy().
503 */
504 ObjectStreamClass() {
505 }
506
507 /**
508 * Initializes class descriptor representing a proxy class.
509 */
510 void initProxy(Class<?> cl,
511 ClassNotFoundException resolveEx,
512 ObjectStreamClass superDesc)
513 throws InvalidClassException
514 {
515 this.cl = cl;
516 this.resolveEx = resolveEx;
517 this.superDesc = superDesc;
518 isProxy = true;
519 serializable = true;
520 suid = Long.valueOf(0);
521 fields = NO_FIELDS;
522
523 if (cl != null) {
524 localDesc = lookup(cl, true);
525 if (!localDesc.isProxy) {
526 throw new InvalidClassException(
527 "cannot bind proxy descriptor to a non-proxy class");
528 }
529 name = localDesc.name;
530 externalizable = localDesc.externalizable;
531 cons = localDesc.cons;
532 writeReplaceMethod = localDesc.writeReplaceMethod;
533 readResolveMethod = localDesc.readResolveMethod;
534 deserializeEx = localDesc.deserializeEx;
535 }
536 fieldRefl = getReflector(fields, localDesc);
537 }
538
539 /**
540 * Initializes class descriptor representing a non-proxy class.
541 */
542 void initNonProxy(ObjectStreamClass model,
543 Class<?> cl,
544 ClassNotFoundException resolveEx,
545 ObjectStreamClass superDesc)
546 throws InvalidClassException
547 {
548 this.cl = cl;
549 this.resolveEx = resolveEx;
550 this.superDesc = superDesc;
551 name = model.name;
552 suid = Long.valueOf(model.getSerialVersionUID());
553 isProxy = false;
554 isEnum = model.isEnum;
555 serializable = model.serializable;
556 externalizable = model.externalizable;
557 hasBlockExternalData = model.hasBlockExternalData;
558 hasWriteObjectData = model.hasWriteObjectData;
559 fields = model.fields;
560 primDataSize = model.primDataSize;
561 numObjFields = model.numObjFields;
562
563 if (cl != null) {
564 localDesc = lookup(cl, true);
565 if (localDesc.isProxy) {
566 throw new InvalidClassException(
567 "cannot bind non-proxy descriptor to a proxy class");
568 }
569 if (isEnum != localDesc.isEnum) {
570 throw new InvalidClassException(isEnum ?
571 "cannot bind enum descriptor to a non-enum class" :
572 "cannot bind non-enum descriptor to an enum class");
573 }
574
575 if (serializable == localDesc.serializable &&
576 !cl.isArray() &&
577 suid.longValue() != localDesc.getSerialVersionUID())
578 {
579 throw new InvalidClassException(localDesc.name,
580 "local class incompatible: " +
581 "stream classdesc serialVersionUID = " + suid +
582 ", local class serialVersionUID = " +
583 localDesc.getSerialVersionUID());
584 }
585
586 if (!classNamesEqual(name, localDesc.name)) {
587 throw new InvalidClassException(localDesc.name,
588 "local class name incompatible with stream class " +
589 "name \"" + name + "\"");
590 }
591
592 if (!isEnum) {
593 if ((serializable == localDesc.serializable) &&
594 (externalizable != localDesc.externalizable))
595 {
596 throw new InvalidClassException(localDesc.name,
597 "Serializable incompatible with Externalizable");
598 }
599
600 if ((serializable != localDesc.serializable) ||
601 (externalizable != localDesc.externalizable) ||
602 !(serializable || externalizable))
603 {
604 deserializeEx = new InvalidClassException(localDesc.name,
605 "class invalid for deserialization");
606 }
607 }
608
609 cons = localDesc.cons;
610 writeObjectMethod = localDesc.writeObjectMethod;
611 readObjectMethod = localDesc.readObjectMethod;
612 readObjectNoDataMethod = localDesc.readObjectNoDataMethod;
613 writeReplaceMethod = localDesc.writeReplaceMethod;
614 readResolveMethod = localDesc.readResolveMethod;
615 if (deserializeEx == null) {
616 deserializeEx = localDesc.deserializeEx;
617 }
618 }
619 fieldRefl = getReflector(fields, localDesc);
620 // reassign to matched fields so as to reflect local unshared settings
621 fields = fieldRefl.getFields();
622 }
623
624 /**
625 * Reads non-proxy class descriptor information from given input stream.
626 * The resulting class descriptor is not fully functional; it can only be
627 * used as input to the ObjectInputStream.resolveClass() and
628 * ObjectStreamClass.initNonProxy() methods.
629 */
630 void readNonProxy(ObjectInputStream in)
631 throws IOException, ClassNotFoundException
632 {
633 name = in.readUTF();
634 suid = Long.valueOf(in.readLong());
635 isProxy = false;
636
637 byte flags = in.readByte();
638 hasWriteObjectData =
639 ((flags & ObjectStreamConstants.SC_WRITE_METHOD) != 0);
640 hasBlockExternalData =
641 ((flags & ObjectStreamConstants.SC_BLOCK_DATA) != 0);
642 externalizable =
643 ((flags & ObjectStreamConstants.SC_EXTERNALIZABLE) != 0);
644 boolean sflag =
645 ((flags & ObjectStreamConstants.SC_SERIALIZABLE) != 0);
646 if (externalizable && sflag) {
647 throw new InvalidClassException(
648 name, "serializable and externalizable flags conflict");
649 }
650 serializable = externalizable || sflag;
651 isEnum = ((flags & ObjectStreamConstants.SC_ENUM) != 0);
652 if (isEnum && suid.longValue() != 0L) {
653 throw new InvalidClassException(name,
654 "enum descriptor has non-zero serialVersionUID: " + suid);
655 }
656
657 int numFields = in.readShort();
658 if (isEnum && numFields != 0) {
659 throw new InvalidClassException(name,
660 "enum descriptor has non-zero field count: " + numFields);
661 }
662 fields = (numFields > 0) ?
663 new ObjectStreamField[numFields] : NO_FIELDS;
664 for (int i = 0; i < numFields; i++) {
665 char tcode = (char) in.readByte();
666 String fname = in.readUTF();
667 String signature = ((tcode == 'L') || (tcode == '[')) ?
668 in.readTypeString() : new String(new char[] { tcode });
669 try {
670 fields[i] = new ObjectStreamField(fname, signature, false);
671 } catch (RuntimeException e) {
672 throw (IOException) new InvalidClassException(name,
673 "invalid descriptor for field " + fname).initCause(e);
674 }
675 }
676 computeFieldOffsets();
677 }
678
679 /**
680 * Writes non-proxy class descriptor information to given output stream.
681 */
682 void writeNonProxy(ObjectOutputStream out) throws IOException {
683 out.writeUTF(name);
684 out.writeLong(getSerialVersionUID());
685
686 byte flags = 0;
687 if (externalizable) {
688 flags |= ObjectStreamConstants.SC_EXTERNALIZABLE;
689 int protocol = out.getProtocolVersion();
690 if (protocol != ObjectStreamConstants.PROTOCOL_VERSION_1) {
691 flags |= ObjectStreamConstants.SC_BLOCK_DATA;
692 }
693 } else if (serializable) {
694 flags |= ObjectStreamConstants.SC_SERIALIZABLE;
695 }
696 if (hasWriteObjectData) {
697 flags |= ObjectStreamConstants.SC_WRITE_METHOD;
698 }
699 if (isEnum) {
700 flags |= ObjectStreamConstants.SC_ENUM;
701 }
702 out.writeByte(flags);
703
704 out.writeShort(fields.length);
705 for (int i = 0; i < fields.length; i++) {
706 ObjectStreamField f = fields[i];
707 out.writeByte(f.getTypeCode());
708 out.writeUTF(f.getName());
709 if (!f.isPrimitive()) {
710 out.writeTypeString(f.getTypeString());
711 }
712 }
713 }
714
715 /**
716 * Returns ClassNotFoundException (if any) thrown while attempting to
717 * resolve local class corresponding to this class descriptor.
718 */
719 ClassNotFoundException getResolveException() {
720 return resolveEx;
721 }
722
723 /**
724 * Throws an InvalidClassException if object instances referencing this
725 * class descriptor should not be allowed to deserialize. This method does
726 * not apply to deserialization of enum constants.
727 */
728 void checkDeserialize() throws InvalidClassException {
729 if (deserializeEx != null) {
730 InvalidClassException ice =
731 new InvalidClassException(deserializeEx.classname,
732 deserializeEx.getMessage());
733 ice.initCause(deserializeEx);
734 throw ice;
735 }
736 }
737
738 /**
739 * Throws an InvalidClassException if objects whose class is represented by
740 * this descriptor should not be allowed to serialize. This method does
741 * not apply to serialization of enum constants.
742 */
743 void checkSerialize() throws InvalidClassException {
744 if (serializeEx != null) {
745 InvalidClassException ice =
746 new InvalidClassException(serializeEx.classname,
747 serializeEx.getMessage());
748 ice.initCause(serializeEx);
749 throw ice;
750 }
751 }
752
753 /**
754 * Throws an InvalidClassException if objects whose class is represented by
755 * this descriptor should not be permitted to use default serialization
756 * (e.g., if the class declares serializable fields that do not correspond
757 * to actual fields, and hence must use the GetField API). This method
758 * does not apply to deserialization of enum constants.
759 */
760 void checkDefaultSerialize() throws InvalidClassException {
761 if (defaultSerializeEx != null) {
762 InvalidClassException ice =
763 new InvalidClassException(defaultSerializeEx.classname,
764 defaultSerializeEx.getMessage());
765 ice.initCause(defaultSerializeEx);
766 throw ice;
767 }
768 }
769
770 /**
771 * Returns superclass descriptor. Note that on the receiving side, the
772 * superclass descriptor may be bound to a class that is not a superclass
773 * of the subclass descriptor's bound class.
774 */
775 ObjectStreamClass getSuperDesc() {
776 return superDesc;
777 }
778
779 /**
780 * Returns the "local" class descriptor for the class associated with this
781 * class descriptor (i.e., the result of
782 * ObjectStreamClass.lookup(this.forClass())) or null if there is no class
783 * associated with this descriptor.
784 */
785 ObjectStreamClass getLocalDesc() {
786 return localDesc;
787 }
788
789 /**
790 * Returns arrays of ObjectStreamFields representing the serializable
791 * fields of the represented class. If copy is true, a clone of this class
792 * descriptor's field array is returned, otherwise the array itself is
793 * returned.
794 */
795 ObjectStreamField[] getFields(boolean copy) {
796 return copy ? fields.clone() : fields;
797 }
798
799 /**
800 * Looks up a serializable field of the represented class by name and type.
801 * A specified type of null matches all types, Object.class matches all
802 * non-primitive types, and any other non-null type matches assignable
803 * types only. Returns matching field, or null if no match found.
804 */
805 ObjectStreamField getField(String name, Class<?> type) {
806 for (int i = 0; i < fields.length; i++) {
807 ObjectStreamField f = fields[i];
808 if (f.getName().equals(name)) {
809 if (type == null ||
810 (type == Object.class && !f.isPrimitive()))
811 {
812 return f;
813 }
814 Class<?> ftype = f.getType();
815 if (ftype != null && type.isAssignableFrom(ftype)) {
816 return f;
817 }
818 }
819 }
820 return null;
821 }
822
823 /**
824 * Returns true if class descriptor represents a dynamic proxy class, false
825 * otherwise.
826 */
827 boolean isProxy() {
828 return isProxy;
829 }
830
831 /**
832 * Returns true if class descriptor represents an enum type, false
833 * otherwise.
834 */
835 boolean isEnum() {
836 return isEnum;
837 }
838
839 /**
840 * Returns true if represented class implements Externalizable, false
841 * otherwise.
842 */
843 boolean isExternalizable() {
844 return externalizable;
845 }
846
847 /**
848 * Returns true if represented class implements Serializable, false
849 * otherwise.
850 */
851 boolean isSerializable() {
852 return serializable;
853 }
854
855 /**
856 * Returns true if class descriptor represents externalizable class that
857 * has written its data in 1.2 (block data) format, false otherwise.
858 */
859 boolean hasBlockExternalData() {
860 return hasBlockExternalData;
861 }
862
863 /**
864 * Returns true if class descriptor represents serializable (but not
865 * externalizable) class which has written its data via a custom
866 * writeObject() method, false otherwise.
867 */
868 boolean hasWriteObjectData() {
869 return hasWriteObjectData;
870 }
871
872 /**
873 * Returns true if represented class is serializable/externalizable and can
874 * be instantiated by the serialization runtime--i.e., if it is
875 * externalizable and defines a public no-arg constructor, or if it is
876 * non-externalizable and its first non-serializable superclass defines an
877 * accessible no-arg constructor. Otherwise, returns false.
878 */
879 boolean isInstantiable() {
880 return (cons != null);
881 }
882
883 /**
884 * Returns true if represented class is serializable (but not
885 * externalizable) and defines a conformant writeObject method. Otherwise,
886 * returns false.
887 */
888 boolean hasWriteObjectMethod() {
889 return (writeObjectMethod != null);
890 }
891
892 /**
893 * Returns true if represented class is serializable (but not
894 * externalizable) and defines a conformant readObject method. Otherwise,
895 * returns false.
896 */
897 boolean hasReadObjectMethod() {
898 return (readObjectMethod != null);
899 }
900
901 /**
902 * Returns true if represented class is serializable (but not
903 * externalizable) and defines a conformant readObjectNoData method.
904 * Otherwise, returns false.
905 */
906 boolean hasReadObjectNoDataMethod() {
907 return (readObjectNoDataMethod != null);
908 }
909
910 /**
911 * Returns true if represented class is serializable or externalizable and
912 * defines a conformant writeReplace method. Otherwise, returns false.
913 */
914 boolean hasWriteReplaceMethod() {
915 return (writeReplaceMethod != null);
916 }
917
918 /**
919 * Returns true if represented class is serializable or externalizable and
920 * defines a conformant readResolve method. Otherwise, returns false.
921 */
922 boolean hasReadResolveMethod() {
923 return (readResolveMethod != null);
924 }
925
926 /**
927 * Creates a new instance of the represented class. If the class is
928 * externalizable, invokes its public no-arg constructor; otherwise, if the
929 * class is serializable, invokes the no-arg constructor of the first
930 * non-serializable superclass. Throws UnsupportedOperationException if
931 * this class descriptor is not associated with a class, if the associated
932 * class is non-serializable or if the appropriate no-arg constructor is
933 * inaccessible/unavailable.
934 */
935 Object newInstance()
936 throws InstantiationException, InvocationTargetException,
937 UnsupportedOperationException
938 {
939 if (cons != null) {
940 try {
941 return cons.newInstance();
942 } catch (IllegalAccessException ex) {
943 // should not occur, as access checks have been suppressed
944 throw new InternalError();
945 }
946 } else {
947 throw new UnsupportedOperationException();
948 }
949 }
950
951 /**
952 * Invokes the writeObject method of the represented serializable class.
953 * Throws UnsupportedOperationException if this class descriptor is not
954 * associated with a class, or if the class is externalizable,
955 * non-serializable or does not define writeObject.
956 */
957 void invokeWriteObject(Object obj, ObjectOutputStream out)
958 throws IOException, UnsupportedOperationException
959 {
960 if (writeObjectMethod != null) {
961 try {
962 writeObjectMethod.invoke(obj, new Object[]{ out });
963 } catch (InvocationTargetException ex) {
964 Throwable th = ex.getTargetException();
965 if (th instanceof IOException) {
966 throw (IOException) th;
967 } else {
968 throwMiscException(th);
969 }
970 } catch (IllegalAccessException ex) {
971 // should not occur, as access checks have been suppressed
972 throw new InternalError();
973 }
974 } else {
975 throw new UnsupportedOperationException();
976 }
977 }
978
979 /**
980 * Invokes the readObject method of the represented serializable class.
981 * Throws UnsupportedOperationException if this class descriptor is not
982 * associated with a class, or if the class is externalizable,
983 * non-serializable or does not define readObject.
984 */
985 void invokeReadObject(Object obj, ObjectInputStream in)
986 throws ClassNotFoundException, IOException,
987 UnsupportedOperationException
988 {
989 if (readObjectMethod != null) {
990 try {
991 readObjectMethod.invoke(obj, new Object[]{ in });
992 } catch (InvocationTargetException ex) {
993 Throwable th = ex.getTargetException();
994 if (th instanceof ClassNotFoundException) {
995 throw (ClassNotFoundException) th;
996 } else if (th instanceof IOException) {
997 throw (IOException) th;
998 } else {
999 throwMiscException(th);
1000 }
1001 } catch (IllegalAccessException ex) {
1002 // should not occur, as access checks have been suppressed
1003 throw new InternalError();
1004 }
1005 } else {
1006 throw new UnsupportedOperationException();
1007 }
1008 }
1009
1010 /**
1011 * Invokes the readObjectNoData method of the represented serializable
1012 * class. Throws UnsupportedOperationException if this class descriptor is
1013 * not associated with a class, or if the class is externalizable,
1014 * non-serializable or does not define readObjectNoData.
1015 */
1016 void invokeReadObjectNoData(Object obj)
1017 throws IOException, UnsupportedOperationException
1018 {
1019 if (readObjectNoDataMethod != null) {
1020 try {
1021 readObjectNoDataMethod.invoke(obj, (Object[]) null);
1022 } catch (InvocationTargetException ex) {
1023 Throwable th = ex.getTargetException();
1024 if (th instanceof ObjectStreamException) {
1025 throw (ObjectStreamException) th;
1026 } else {
1027 throwMiscException(th);
1028 }
1029 } catch (IllegalAccessException ex) {
1030 // should not occur, as access checks have been suppressed
1031 throw new InternalError();
1032 }
1033 } else {
1034 throw new UnsupportedOperationException();
1035 }
1036 }
1037
1038 /**
1039 * Invokes the writeReplace method of the represented serializable class and
1040 * returns the result. Throws UnsupportedOperationException if this class
1041 * descriptor is not associated with a class, or if the class is
1042 * non-serializable or does not define writeReplace.
1043 */
1044 Object invokeWriteReplace(Object obj)
1045 throws IOException, UnsupportedOperationException
1046 {
1047 if (writeReplaceMethod != null) {
1048 try {
1049 return writeReplaceMethod.invoke(obj, (Object[]) null);
1050 } catch (InvocationTargetException ex) {
1051 Throwable th = ex.getTargetException();
1052 if (th instanceof ObjectStreamException) {
1053 throw (ObjectStreamException) th;
1054 } else {
1055 throwMiscException(th);
1056 throw new InternalError(); // never reached
1057 }
1058 } catch (IllegalAccessException ex) {
1059 // should not occur, as access checks have been suppressed
1060 throw new InternalError();
1061 }
1062 } else {
1063 throw new UnsupportedOperationException();
1064 }
1065 }
1066
1067 /**
1068 * Invokes the readResolve method of the represented serializable class and
1069 * returns the result. Throws UnsupportedOperationException if this class
1070 * descriptor is not associated with a class, or if the class is
1071 * non-serializable or does not define readResolve.
1072 */
1073 Object invokeReadResolve(Object obj)
1074 throws IOException, UnsupportedOperationException
1075 {
1076 if (readResolveMethod != null) {
1077 try {
1078 return readResolveMethod.invoke(obj, (Object[]) null);
1079 } catch (InvocationTargetException ex) {
1080 Throwable th = ex.getTargetException();
1081 if (th instanceof ObjectStreamException) {
1082 throw (ObjectStreamException) th;
1083 } else {
1084 throwMiscException(th);
1085 throw new InternalError(); // never reached
1086 }
1087 } catch (IllegalAccessException ex) {
1088 // should not occur, as access checks have been suppressed
1089 throw new InternalError();
1090 }
1091 } else {
1092 throw new UnsupportedOperationException();
1093 }
1094 }
1095
1096 /**
1097 * Class representing the portion of an object's serialized form allotted
1098 * to data described by a given class descriptor. If "hasData" is false,
1099 * the object's serialized form does not contain data associated with the
1100 * class descriptor.
1101 */
1102 static class ClassDataSlot {
1103
1104 /** class descriptor "occupying" this slot */
1105 final ObjectStreamClass desc;
1106 /** true if serialized form includes data for this slot's descriptor */
1107 final boolean hasData;
1108
1109 ClassDataSlot(ObjectStreamClass desc, boolean hasData) {
1110 this.desc = desc;
1111 this.hasData = hasData;
1112 }
1113 }
1114
1115 /**
1116 * Returns array of ClassDataSlot instances representing the data layout
1117 * (including superclass data) for serialized objects described by this
1118 * class descriptor. ClassDataSlots are ordered by inheritance with those
1119 * containing "higher" superclasses appearing first. The final
1120 * ClassDataSlot contains a reference to this descriptor.
1121 */
1122 ClassDataSlot[] getClassDataLayout() throws InvalidClassException {
1123 // REMIND: synchronize instead of relying on volatile?
1124 if (dataLayout == null) {
1125 dataLayout = getClassDataLayout0();
1126 }
1127 return dataLayout;
1128 }
1129
1130 private ClassDataSlot[] getClassDataLayout0()
1131 throws InvalidClassException
1132 {
1133 ArrayList<ClassDataSlot> slots = new ArrayList<>();
1134 Class<?> start = cl, end = cl;
1135
1136 // locate closest non-serializable superclass
1137 while (end != null && Serializable.class.isAssignableFrom(end)) {
1138 end = end.getSuperclass();
1139 }
1140
1141 for (ObjectStreamClass d = this; d != null; d = d.superDesc) {
1142
1143 // search up inheritance hierarchy for class with matching name
1144 String searchName = (d.cl != null) ? d.cl.getName() : d.name;
1145 Class<?> match = null;
1146 for (Class<?> c = start; c != end; c = c.getSuperclass()) {
1147 if (searchName.equals(c.getName())) {
1148 match = c;
1149 break;
1150 }
1151 }
1152
1153 // add "no data" slot for each unmatched class below match
1154 if (match != null) {
1155 for (Class<?> c = start; c != match; c = c.getSuperclass()) {
1156 slots.add(new ClassDataSlot(
1157 ObjectStreamClass.lookup(c, true), false));
1158 }
1159 start = match.getSuperclass();
1160 }
1161
1162 // record descriptor/class pairing
1163 slots.add(new ClassDataSlot(d.getVariantFor(match), true));
1164 }
1165
1166 // add "no data" slot for any leftover unmatched classes
1167 for (Class<?> c = start; c != end; c = c.getSuperclass()) {
1168 slots.add(new ClassDataSlot(
1169 ObjectStreamClass.lookup(c, true), false));
1170 }
1171
1172 // order slots from superclass -> subclass
1173 Collections.reverse(slots);
1174 return slots.toArray(new ClassDataSlot[slots.size()]);
1175 }
1176
1177 /**
1178 * Returns aggregate size (in bytes) of marshalled primitive field values
1179 * for represented class.
1180 */
1181 int getPrimDataSize() {
1182 return primDataSize;
1183 }
1184
1185 /**
1186 * Returns number of non-primitive serializable fields of represented
1187 * class.
1188 */
1189 int getNumObjFields() {
1190 return numObjFields;
1191 }
1192
1193 /**
1194 * Fetches the serializable primitive field values of object obj and
1195 * marshals them into byte array buf starting at offset 0. It is the
1196 * responsibility of the caller to ensure that obj is of the proper type if
1197 * non-null.
1198 */
1199 void getPrimFieldValues(Object obj, byte[] buf) {
1200 fieldRefl.getPrimFieldValues(obj, buf);
1201 }
1202
1203 /**
1204 * Sets the serializable primitive fields of object obj using values
1205 * unmarshalled from byte array buf starting at offset 0. It is the
1206 * responsibility of the caller to ensure that obj is of the proper type if
1207 * non-null.
1208 */
1209 void setPrimFieldValues(Object obj, byte[] buf) {
1210 fieldRefl.setPrimFieldValues(obj, buf);
1211 }
1212
1213 /**
1214 * Fetches the serializable object field values of object obj and stores
1215 * them in array vals starting at offset 0. It is the responsibility of
1216 * the caller to ensure that obj is of the proper type if non-null.
1217 */
1218 void getObjFieldValues(Object obj, Object[] vals) {
1219 fieldRefl.getObjFieldValues(obj, vals);
1220 }
1221
1222 /**
1223 * Sets the serializable object fields of object obj using values from
1224 * array vals starting at offset 0. It is the responsibility of the caller
1225 * to ensure that obj is of the proper type if non-null.
1226 */
1227 void setObjFieldValues(Object obj, Object[] vals) {
1228 fieldRefl.setObjFieldValues(obj, vals);
1229 }
1230
1231 /**
1232 * Calculates and sets serializable field offsets, as well as primitive
1233 * data size and object field count totals. Throws InvalidClassException
1234 * if fields are illegally ordered.
1235 */
1236 private void computeFieldOffsets() throws InvalidClassException {
1237 primDataSize = 0;
1238 numObjFields = 0;
1239 int firstObjIndex = -1;
1240
1241 for (int i = 0; i < fields.length; i++) {
1242 ObjectStreamField f = fields[i];
1243 switch (f.getTypeCode()) {
1244 case 'Z':
1245 case 'B':
1246 f.setOffset(primDataSize++);
1247 break;
1248
1249 case 'C':
1250 case 'S':
1251 f.setOffset(primDataSize);
1252 primDataSize += 2;
1253 break;
1254
1255 case 'I':
1256 case 'F':
1257 f.setOffset(primDataSize);
1258 primDataSize += 4;
1259 break;
1260
1261 case 'J':
1262 case 'D':
1263 f.setOffset(primDataSize);
1264 primDataSize += 8;
1265 break;
1266
1267 case '[':
1268 case 'L':
1269 f.setOffset(numObjFields++);
1270 if (firstObjIndex == -1) {
1271 firstObjIndex = i;
1272 }
1273 break;
1274
1275 default:
1276 throw new InternalError();
1277 }
1278 }
1279 if (firstObjIndex != -1 &&
1280 firstObjIndex + numObjFields != fields.length)
1281 {
1282 throw new InvalidClassException(name, "illegal field order");
1283 }
1284 }
1285
1286 /**
1287 * If given class is the same as the class associated with this class
1288 * descriptor, returns reference to this class descriptor. Otherwise,
1289 * returns variant of this class descriptor bound to given class.
1290 */
1291 private ObjectStreamClass getVariantFor(Class<?> cl)
1292 throws InvalidClassException
1293 {

1011 more lines aren’t shown here.

java/pkg/java/io/ObjectStreamConstants.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectStreamConstants.java+235−0

This diff is large: its 236 lines aren’t shown here.

java/pkg/java/io/ObjectStreamException.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectStreamException.java+53−0

This diff is large: its 54 lines aren’t shown here.

java/pkg/java/io/ObjectStreamField.class+0−0

Binary file not shown.

java/pkg/java/io/ObjectStreamField.java+314−0

This diff is large: its 315 lines aren’t shown here.

java/pkg/java/io/OptionalDataException.class+0−0

Binary file not shown.

java/pkg/java/io/OptionalDataException.java+83−0

This diff is large: its 84 lines aren’t shown here.

java/pkg/java/io/OutputStream.class+0−0

Binary file not shown.

java/pkg/java/io/OutputStream.java+154−0

This diff is large: its 155 lines aren’t shown here.

java/pkg/java/io/OutputStreamWriter.class+0−0

Binary file not shown.

java/pkg/java/io/OutputStreamWriter.java+235−0

This diff is large: its 236 lines aren’t shown here.

java/pkg/java/io/PipedInputStream.class+0−0

Binary file not shown.

java/pkg/java/io/PipedInputStream.java+450−0

This diff is large: its 451 lines aren’t shown here.

java/pkg/java/io/PipedOutputStream.class+0−0

Binary file not shown.

java/pkg/java/io/PipedOutputStream.java+179−0

This diff is large: its 180 lines aren’t shown here.

java/pkg/java/io/PipedReader.class+0−0

Binary file not shown.

java/pkg/java/io/PipedReader.java+363−0

This diff is large: its 364 lines aren’t shown here.

java/pkg/java/io/PipedWriter.class+0−0

Binary file not shown.

java/pkg/java/io/PipedWriter.java+184−0

This diff is large: its 185 lines aren’t shown here.

java/pkg/java/io/PrintStream.class+0−0

Binary file not shown.

java/pkg/java/io/PrintStream.java+1129−0

This diff is large: its 1130 lines aren’t shown here.

java/pkg/java/io/PrintWriter.class+0−0

Binary file not shown.

java/pkg/java/io/PrintWriter.java+1066−0

This diff is large: its 1067 lines aren’t shown here.

java/pkg/java/io/PushbackInputStream.class+0−0

Binary file not shown.

java/pkg/java/io/PushbackInputStream.java+383−0

This diff is large: its 384 lines aren’t shown here.

java/pkg/java/io/PushbackReader.class+0−0

Binary file not shown.

java/pkg/java/io/PushbackReader.java+281−0

This diff is large: its 282 lines aren’t shown here.

java/pkg/java/io/RandomAccessFile.class+0−0

Binary file not shown.

java/pkg/java/io/RandomAccessFile.java+1125−0

This diff is large: its 1126 lines aren’t shown here.

java/pkg/java/io/Reader.class+0−0

Binary file not shown.

java/pkg/java/io/Reader.java+262−0

This diff is large: its 263 lines aren’t shown here.

java/pkg/java/io/SequenceInputStream.class+0−0

Binary file not shown.

java/pkg/java/io/SequenceInputStream.java+235−0

This diff is large: its 236 lines aren’t shown here.

java/pkg/java/io/SerialCallbackContext.class+0−0

Binary file not shown.

java/pkg/java/io/SerialCallbackContext.java+54−0

This diff is large: its 55 lines aren’t shown here.

java/pkg/java/io/Serializable.class+0−0

Binary file not shown.

java/pkg/java/io/Serializable.java+170−0

This diff is large: its 171 lines aren’t shown here.

java/pkg/java/io/SerializablePermission.class+0−0

Binary file not shown.

java/pkg/java/io/SerializablePermission.java+132−0

This diff is large: its 133 lines aren’t shown here.

java/pkg/java/io/StreamCorruptedException.class+0−0

Binary file not shown.

java/pkg/java/io/StreamCorruptedException.java+54−0

This diff is large: its 55 lines aren’t shown here.

java/pkg/java/io/StreamTokenizer.class+0−0

Binary file not shown.

java/pkg/java/io/StreamTokenizer.java+834−0

This diff is large: its 835 lines aren’t shown here.

java/pkg/java/io/StringBufferInputStream.class+0−0

Binary file not shown.

java/pkg/java/io/StringBufferInputStream.java+172−0

This diff is large: its 173 lines aren’t shown here.

java/pkg/java/io/StringReader.class+0−0

Binary file not shown.

java/pkg/java/io/StringReader.java+201−0

This diff is large: its 202 lines aren’t shown here.

java/pkg/java/io/StringWriter.class+0−0

Binary file not shown.

java/pkg/java/io/StringWriter.java+236−0

This diff is large: its 237 lines aren’t shown here.

java/pkg/java/io/SyncFailedException.class+0−0

Binary file not shown.

java/pkg/java/io/SyncFailedException.java+48−0

This diff is large: its 49 lines aren’t shown here.

java/pkg/java/io/UTFDataFormatException.class+0−0

Binary file not shown.

java/pkg/java/io/UTFDataFormatException.java+69−0

This diff is large: its 70 lines aren’t shown here.

java/pkg/java/io/UnsupportedEncodingException.class+0−0

Binary file not shown.

java/pkg/java/io/UnsupportedEncodingException.java+52−0

This diff is large: its 53 lines aren’t shown here.

java/pkg/java/io/WriteAbortedException.class+0−0

Binary file not shown.

java/pkg/java/io/WriteAbortedException.java+93−0

This diff is large: its 94 lines aren’t shown here.

java/pkg/java/io/Writer.class+0−0

Binary file not shown.

java/pkg/java/io/Writer.java+325−0

This diff is large: its 326 lines aren’t shown here.

java/pkg/java/io/mkfile+89−0

This diff is large: its 90 lines aren’t shown here.

java/pkg/java/io/package.html+52−0

This diff is large: its 53 lines aren’t shown here.