-
Notifications
You must be signed in to change notification settings - Fork 227
Expand file tree
/
Copy pathIOBase.java
More file actions
237 lines (214 loc) · 5.59 KB
/
IOBase.java
File metadata and controls
237 lines (214 loc) · 5.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
/* Copyright (c) 2007-2012 Jython Developers */
package org.python.core.io;
import jnr.constants.platform.Errno;
import java.io.InputStream;
import java.io.OutputStream;
import org.python.core.Py;
import org.python.core.PyException;
/**
* Base class for all I/O classes.
*
* IOBase and its descendents in org.python.core.io are based off Python 3's new io module (PEP
* 3116).
*
* This does not define read(), readinto() and write(), nor readline() and friends, since their
* signatures vary per layer.
*
* @author Philip Jenvey
*/
public abstract class IOBase {
/** The default size of generic buffers */
public static final int DEFAULT_BUFFER_SIZE = 8192;
/** Byte representation of the Line Feed character */
protected static final byte LF_BYTE = 10;
/** true if the file has been closed */
private boolean closed = false;
/**
* Seek to byte offset pos relative to the start of the stream.
*
* Returns the new absolute position.
*
* @param pos
* a long position value
* @return a long position value seeked to
*/
public long seek(long pos) {
return seek(pos, 0);
}
/**
* Seek to byte offset {@code pos} relative to position indicated by {@code whence}.
* <table>
* <caption> Semantics</caption>
* <tr>
* <th>{@code whence}</th>
* <th align="left">Seek to</th>
* <th>{@code pos}</th>
* </tr>
* <tr>
* <th>0</th>
* <td>Start of stream (the default).</td><td>Should be ≥0.</td>
* </tr>
* <tr>
* <th>1</th>
* <td>Current position + {@code pos} </td><td>Either sign.</td>
* </tr>
* <tr>
* <th>2</th>
* <td>End of stream + {@code pos} </td><td>Usually ≤0.</td>
* </tr>
* </table>
* Returns the new absolute position.
*
* @param pos a long position value
* @param whence an int whence value
* @return a long position value seeked to
*/
public long seek(long pos, int whence) {
unsupported("seek");
return -1;
}
/**
* Return the current stream position.
*
* @return a long position value
*/
public long tell() {
return seek(0, 1);
}
/**
* Truncate file to size in bytes.
*
* Returns the new size.
*
* @param size
* a long size to truncate to
* @return a long size value the file was truncated to
*/
public long truncate(long size) {
unsupported("truncate");
return -1;
}
/**
* Flushes write buffers, if applicable.
*
* This is a no-op for read-only and non-blocking streams.
*
*/
public void flush() {}
/**
* Flushes and closes the IO object.
*
* This must be idempotent. It should also set a flag for the 'closed' property (see below) to
* test.
*/
public void close() {
if (closed()) {
return;
}
try {
flush();
} catch (PyException pye) {
if (!pye.match(Py.IOError)) {
throw pye;
}
// If flush() fails, just give up
}
closed = true;
}
/**
* Returns underlying file descriptor if one exists.
*
* Raises IOError if the IO object does not use a file descriptor.
*
* @return a file descriptor
*/
public RawIOBase fileno() {
unsupported("fileno");
return null;
}
/**
* Returns whether this is an 'interactive' stream.
*
* Returns False if we don't know.
*
* @return a boolean, true if an 'interactive' stream
*/
public boolean isatty() {
checkClosed();
return false;
}
/**
* Return whether this file was opened for reading.
*
* @return true if the file was opened for reading
*/
public boolean readable() {
return false;
}
/**
* Raise an IOError if the file is not readable.
*
*/
public void checkReadable() {
if (!readable()) {
throw Py.IOError(Errno.EBADF);
}
}
/**
* Return whether this file was opened for writing.
*
* @return true if the file was opened for writing
*/
public boolean writable() {
return false;
}
/**
* Raise an IOError if the file is not writable.
*
*/
public void checkWritable() {
if (!writable()) {
throw Py.IOError(Errno.EBADF);
}
}
/**
* Return whether this file has been closed.
*
* @return true if the file has been closed
*/
public boolean closed() {
return closed;
}
/**
* Raise a ValueError if the file is closed.
*
*/
public void checkClosed() {
if (closed()) {
throw Py.ValueError("I/O operation on closed file");
}
}
/**
* Coerce this into an OutputStream if possible, or return null.
*/
public OutputStream asOutputStream() {
return null;
}
/**
* Coerce this into an InputStream if possible, or return null.
*/
public InputStream asInputStream() {
return null;
}
/**
* Raise a TypeError indicating the specified operation is not supported.
*
* @param methodName
* the String name of the operation
*/
protected void unsupported(String methodName) {
String qualifiedName = getClass().getName();
String className = qualifiedName.substring(qualifiedName.lastIndexOf('.') + 1);
throw Py.IOError(String.format("%s.%s() not supported", className, methodName));
}
}