38 |
package gnu.java.nio; |
package gnu.java.nio; |
39 |
|
|
40 |
import java.io.EOFException; |
import java.io.EOFException; |
41 |
|
import java.io.FileDescriptor; |
42 |
import java.io.FileInputStream; |
import java.io.FileInputStream; |
43 |
import java.io.FileOutputStream; |
import java.io.FileOutputStream; |
44 |
import java.io.IOException; |
import java.io.IOException; |
45 |
import java.io.RandomAccessFile; |
import java.io.RandomAccessFile; |
46 |
import java.nio.ByteBuffer; |
import java.nio.ByteBuffer; |
47 |
import java.nio.MappedByteBuffer; |
import java.nio.MappedByteBuffer; |
48 |
|
import java.nio.channels.ClosedChannelException; |
49 |
import java.nio.channels.FileChannel; |
import java.nio.channels.FileChannel; |
50 |
import java.nio.channels.FileLock; |
import java.nio.channels.FileLock; |
51 |
|
import java.nio.channels.NonReadableChannelException; |
52 |
|
import java.nio.channels.NonWritableChannelException; |
53 |
import java.nio.channels.ReadableByteChannel; |
import java.nio.channels.ReadableByteChannel; |
54 |
import java.nio.channels.WritableByteChannel; |
import java.nio.channels.WritableByteChannel; |
55 |
|
import gnu.classpath.RawData; |
56 |
|
|
57 |
/** |
/** |
58 |
* This file is not user visible ! |
* This file is not user visible ! |
64 |
|
|
65 |
public class FileChannelImpl extends FileChannel |
public class FileChannelImpl extends FileChannel |
66 |
{ |
{ |
67 |
public long address; |
RawData map_address; |
68 |
public int length; |
|
69 |
public int fd; |
int length; |
70 |
public MappedByteBuffer buf; |
FileDescriptor fd; |
71 |
public Object file_obj; // just to keep it live... |
MappedByteBuffer buf; |
72 |
|
Object file_obj; // just to keep it live... |
73 |
|
|
74 |
|
public FileChannelImpl (FileDescriptor fd, boolean write, Object obj) |
75 |
|
{ |
76 |
|
if (!(obj instanceof RandomAccessFile) |
77 |
|
&& !(obj instanceof FileInputStream) |
78 |
|
&& !(obj instanceof FileOutputStream)) |
79 |
|
throw new InternalError (); |
80 |
|
|
|
/** |
|
|
* This method came from java.io.RandomAccessFile |
|
|
* It is private there so we will repeat it here. |
|
|
*/ |
|
|
private native long lengthInternal (int native_fd) throws IOException; |
|
|
|
|
|
public FileChannelImpl (int fd, Object obj) |
|
|
{ |
|
81 |
this.fd = fd; |
this.fd = fd; |
82 |
this.file_obj = obj; |
this.file_obj = obj; |
83 |
} |
} |
84 |
|
|
85 |
public long size () throws IOException |
public FileChannelImpl () |
86 |
{ |
{ |
87 |
return lengthInternal (fd); |
this (new FileDescriptor (), true, null); |
88 |
} |
} |
89 |
|
|
90 |
|
private native long implPosition (); |
91 |
|
private native FileChannel implPosition (long newPosition); |
92 |
|
private native FileChannel implTruncate (long size); |
93 |
|
|
94 |
|
private native RawData nio_mmap_file (long pos, long size, int mode); |
95 |
|
private native void nio_unmmap_file (RawData map_address, int size); |
96 |
|
private native void nio_msync (RawData map_address, int length); |
97 |
|
|
98 |
|
public native long size () throws IOException; |
99 |
|
|
100 |
protected void implCloseChannel() throws IOException |
protected void implCloseChannel() throws IOException |
101 |
{ |
{ |
102 |
if (address != 0) |
if (map_address != null) |
103 |
{ |
{ |
104 |
nio_unmmap_file (fd, address, (int) length); |
nio_unmmap_file (map_address, (int) length); |
105 |
} |
map_address = null; |
106 |
|
} |
|
// FIXME |
|
|
fd = 0; |
|
107 |
|
|
108 |
if (file_obj instanceof RandomAccessFile) |
if (file_obj instanceof RandomAccessFile) |
109 |
{ |
{ |
110 |
RandomAccessFile o = (RandomAccessFile) file_obj; |
RandomAccessFile o = (RandomAccessFile) file_obj; |
111 |
o.close(); |
o.close(); |
112 |
} |
} |
113 |
else if (file_obj instanceof FileInputStream) |
else if (file_obj instanceof FileInputStream) |
114 |
{ |
{ |
115 |
FileInputStream o = (FileInputStream) file_obj; |
FileInputStream o = (FileInputStream) file_obj; |
116 |
o.close(); |
o.close(); |
117 |
} |
} |
118 |
else if (file_obj instanceof FileOutputStream) |
else if (file_obj instanceof FileOutputStream) |
119 |
{ |
{ |
120 |
FileOutputStream o = (FileOutputStream) file_obj; |
FileOutputStream o = (FileOutputStream) file_obj; |
121 |
o.close(); |
o.close(); |
122 |
} |
} |
123 |
} |
} |
124 |
|
|
125 |
public int read (ByteBuffer dst) throws IOException |
public int read (ByteBuffer dst) throws IOException |
126 |
{ |
{ |
|
int w = 0; |
|
127 |
int s = (int)size(); |
int s = (int)size(); |
128 |
|
|
129 |
if (buf == null) |
if (buf == null) |
130 |
{ |
{ |
131 |
throw new EOFException("file not mapped"); |
throw new EOFException("file not mapped"); |
132 |
} |
} |
133 |
|
|
134 |
for (int i=0; i<s; i++) |
for (int i = 0; i < s; i++) |
135 |
{ |
{ |
136 |
dst.put( buf.get() ); |
dst.put (buf.get()); |
137 |
} |
} |
138 |
|
|
139 |
return s; |
return s; |
140 |
} |
} |
141 |
|
|
142 |
|
public int read (ByteBuffer dst, long position) |
143 |
|
throws IOException |
144 |
|
{ |
145 |
|
if (position < 0) |
146 |
|
throw new IllegalArgumentException (); |
147 |
|
|
148 |
|
if (!isOpen ()) |
149 |
|
throw new ClosedChannelException (); |
150 |
|
|
151 |
|
// FIXME: check for NonReadableChannelException |
152 |
|
|
153 |
|
throw new Error ("Not implemented"); |
154 |
|
} |
155 |
|
|
156 |
public long read (ByteBuffer[] dsts, int offset, int length) |
public long read (ByteBuffer[] dsts, int offset, int length) |
157 |
throws IOException |
throws IOException |
158 |
{ |
{ |
159 |
long result = 0; |
long result = 0; |
160 |
|
|
161 |
for (int i = offset; i < offset + length; i++) |
for (int i = offset; i < offset + length; i++) |
162 |
{ |
{ |
163 |
result += write (dsts[i]); |
result += write (dsts [i]); |
164 |
} |
} |
165 |
|
|
166 |
return result; |
return result; |
167 |
} |
} |
168 |
|
|
|
public int read (ByteBuffer src, long position) throws IOException |
|
|
{ |
|
|
return 0; |
|
|
} |
|
|
|
|
169 |
public int write (ByteBuffer src) throws IOException |
public int write (ByteBuffer src) throws IOException |
170 |
{ |
{ |
171 |
int w = 0; |
int w = 0; |
172 |
|
|
173 |
if (buf == null) |
if (buf == null) |
174 |
{ |
{ |
175 |
throw new EOFException ("file not mapped"); |
throw new EOFException ("file not mapped"); |
176 |
} |
} |
177 |
|
|
178 |
while (src.hasRemaining ()) |
while (src.hasRemaining ()) |
179 |
{ |
{ |
180 |
buf.put (src.get ()); |
buf.put (src.get ()); |
181 |
w++; |
w++; |
182 |
} |
} |
183 |
|
|
184 |
return w; |
return w; |
185 |
} |
} |
186 |
|
|
187 |
public long write(ByteBuffer[] srcs, int offset, int length) |
public int write (ByteBuffer src, long position) |
188 |
throws IOException |
throws IOException |
189 |
{ |
{ |
190 |
long res = 0; |
if (position < 0) |
191 |
|
throw new IllegalArgumentException (); |
192 |
|
|
193 |
for (int i = offset;i < offset + length;i++) |
if (!isOpen ()) |
194 |
{ |
throw new ClosedChannelException (); |
195 |
res += write (srcs[i]); |
|
196 |
} |
// FIXME: check for NonWritableChannelException |
|
return res; |
|
|
} |
|
197 |
|
|
198 |
public int write (ByteBuffer src, long position) throws IOException |
throw new Error ("Not implemented"); |
199 |
|
} |
200 |
|
|
201 |
|
public long write(ByteBuffer[] srcs, int offset, int length) |
202 |
|
throws IOException |
203 |
{ |
{ |
204 |
return 0; |
long result = 0; |
205 |
|
|
206 |
|
for (int i = offset;i < offset + length;i++) |
207 |
|
{ |
208 |
|
result += write (srcs[i]); |
209 |
|
} |
210 |
|
|
211 |
|
return result; |
212 |
} |
} |
213 |
|
|
214 |
public MappedByteBuffer map (FileChannel.MapMode mode, long position, |
public MappedByteBuffer map (FileChannel.MapMode mode, long position, |
223 |
return null; |
return null; |
224 |
} |
} |
225 |
|
|
226 |
static MappedByteBuffer create_direct_mapped_buffer (long address, |
static MappedByteBuffer create_direct_mapped_buffer (RawData map_address, |
227 |
long length) |
long length) |
228 |
|
throws IOException |
229 |
{ |
{ |
230 |
FileChannelImpl ch = new FileChannelImpl (-1, null); |
FileChannelImpl ch = new FileChannelImpl (); |
231 |
ch.address = address; |
ch.map_address = map_address; |
232 |
ch.length = (int) length; |
ch.length = (int) length; |
233 |
ch.buf = new MappedByteFileBuffer (ch); |
ch.buf = new MappedByteFileBuffer (ch); |
234 |
return ch.buf; |
return ch.buf; |
243 |
/** |
/** |
244 |
* msync with the disk |
* msync with the disk |
245 |
*/ |
*/ |
246 |
public void force (boolean metaData) |
public void force (boolean metaData) throws IOException |
247 |
{ |
{ |
248 |
nio_msync (fd, address, length); |
if (!isOpen ()) |
249 |
} |
throw new ClosedChannelException (); |
250 |
|
|
251 |
static native long nio_mmap_file (int fd, long pos, int size, int mode); |
// FIXME: What to do with metaData ? |
252 |
|
|
253 |
|
nio_msync (map_address, length); |
254 |
|
} |
255 |
|
|
256 |
static native void nio_unmmap_file (int fd, long address, int size); |
public long transferTo (long position, long count, WritableByteChannel target) |
257 |
|
throws IOException |
258 |
|
{ |
259 |
|
if (position < 0 |
260 |
|
|| count < 0) |
261 |
|
throw new IllegalArgumentException (); |
262 |
|
|
263 |
static native void nio_msync (int fd, long address, int length); |
if (!isOpen ()) |
264 |
|
throw new ClosedChannelException (); |
265 |
|
|
266 |
public FileLock lock (long position, long size, boolean shared) throws IOException |
// FIXME: check for NonReadableChannelException |
267 |
{ |
// FIXME: check for NonWritableChannelException |
268 |
return null; |
|
269 |
|
throw new Error ("Not implemented"); |
270 |
} |
} |
271 |
|
|
272 |
public FileLock tryLock (long position, long size, boolean shared) throws IOException |
public long transferFrom (ReadableByteChannel src, long position, long count) |
273 |
|
throws IOException |
274 |
{ |
{ |
275 |
return null; |
if (position < 0 |
276 |
} |
|| count < 0) |
277 |
|
throw new IllegalArgumentException (); |
278 |
|
|
279 |
public long position () throws IOException |
if (!isOpen ()) |
280 |
{ |
throw new ClosedChannelException (); |
281 |
return 0; |
|
282 |
|
// FIXME: check for NonReadableChannelException |
283 |
|
// FIXME: check for NonWritableChannelException |
284 |
|
|
285 |
|
throw new Error ("Not implemented"); |
286 |
} |
} |
287 |
|
|
288 |
public FileChannel position (long newPosition) throws IOException |
public FileLock lock (long position, long size, boolean shared) |
289 |
|
throws IOException |
290 |
{ |
{ |
291 |
return this; |
if (position < 0 |
292 |
} |
|| size < 0) |
293 |
|
throw new IllegalArgumentException (); |
294 |
|
|
295 |
public long transferTo (long position, long count, WritableByteChannel target) |
if (!isOpen ()) |
296 |
|
throw new ClosedChannelException (); |
297 |
|
|
298 |
|
// FIXME: check for NonReadableChannelException |
299 |
|
// FIXME: check for NonWritableChannelException |
300 |
|
|
301 |
|
throw new Error ("Not implemented"); |
302 |
|
} |
303 |
|
|
304 |
|
public FileLock tryLock (long position, long size, boolean shared) |
305 |
throws IOException |
throws IOException |
306 |
{ |
{ |
307 |
return 0; |
if (position < 0 |
308 |
|
|| size < 0) |
309 |
|
throw new IllegalArgumentException (); |
310 |
|
|
311 |
|
if (!isOpen ()) |
312 |
|
throw new ClosedChannelException (); |
313 |
|
|
314 |
|
throw new Error ("Not implemented"); |
315 |
} |
} |
316 |
|
|
317 |
public long transferFrom (ReadableByteChannel src, long position, long count) |
public long position () |
318 |
throws IOException |
throws IOException |
319 |
{ |
{ |
320 |
return 0; |
if (!isOpen ()) |
321 |
|
throw new ClosedChannelException (); |
322 |
|
|
323 |
|
return implPosition (); |
324 |
} |
} |
325 |
|
|
326 |
|
public FileChannel position (long newPosition) |
327 |
|
throws IOException |
328 |
|
{ |
329 |
|
if (newPosition < 0) |
330 |
|
throw new IllegalArgumentException (); |
331 |
|
|
332 |
|
if (!isOpen ()) |
333 |
|
throw new ClosedChannelException (); |
334 |
|
|
335 |
public FileChannel truncate (long size) throws IOException |
return implPosition (newPosition); |
336 |
|
} |
337 |
|
|
338 |
|
public FileChannel truncate (long size) |
339 |
|
throws IOException |
340 |
{ |
{ |
341 |
return null; |
if (size < 0) |
342 |
|
throw new IllegalArgumentException (); |
343 |
|
|
344 |
|
if (!isOpen ()) |
345 |
|
throw new ClosedChannelException (); |
346 |
|
|
347 |
|
// FIXME: check for NonWritableChannelException |
348 |
|
|
349 |
|
return implTruncate (size); |
350 |
} |
} |
351 |
} |
} |