OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [gnu/] [java/] [nio/] [channels/] [FileChannelImpl.java] - Blame information for rev 756

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 756 jeremybenn
/* FileChannelImpl.java --
2
   Copyright (C) 2002, 2004, 2005, 2006  Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package gnu.java.nio.channels;
40
 
41
import gnu.classpath.Configuration;
42
import gnu.java.nio.FileLockImpl;
43
 
44
import java.io.File;
45
import java.io.FileNotFoundException;
46
import java.io.IOException;
47
import java.nio.ByteBuffer;
48
import java.nio.MappedByteBuffer;
49
import java.nio.channels.ClosedChannelException;
50
import java.nio.channels.FileChannel;
51
import java.nio.channels.FileLock;
52
import java.nio.channels.NonReadableChannelException;
53
import java.nio.channels.NonWritableChannelException;
54
import java.nio.channels.ReadableByteChannel;
55
import java.nio.channels.WritableByteChannel;
56
 
57
/**
58
 * This file is not user visible !
59
 * But alas, Java does not have a concept of friendly packages
60
 * so this class is public.
61
 * Instances of this class are created by invoking getChannel
62
 * Upon a Input/Output/RandomAccessFile object.
63
 */
64
public final class FileChannelImpl extends FileChannel
65
{
66
  // These are mode values for open().
67
  public static final int READ   = 1;
68
  public static final int WRITE  = 2;
69
  public static final int APPEND = 4;
70
 
71
  // EXCL is used only when making a temp file.
72
  public static final int EXCL   = 8;
73
  public static final int SYNC   = 16;
74
  public static final int DSYNC  = 32;
75
 
76
  private static native void init();
77
 
78
  static
79
  {
80
    if (Configuration.INIT_LOAD_LIBRARY)
81
      {
82
        System.loadLibrary("javanio");
83
      }
84
 
85
    init();
86
  }
87
 
88
  /**
89
   * This is the actual native file descriptor value
90
   */
91
  // System's notion of file descriptor.  It might seem redundant to
92
  // initialize this given that it is reassigned in the constructors.
93
  // However, this is necessary because if open() throws an exception
94
  // we want to make sure this has the value -1.  This is the most
95
  // efficient way to accomplish that.
96
  private int fd = -1;
97
 
98
  private long pos;
99
  private int mode;
100
 
101
  public FileChannelImpl ()
102
  {
103
  }
104
 
105
  /* Open a file.  MODE is a combination of the above mode flags. */
106
  /* This is a static factory method, so that VM implementors can decide
107
   * substitute subclasses of FileChannelImpl. */
108
  public static FileChannelImpl create(File file, int mode)
109
    throws FileNotFoundException
110
  {
111
    return new FileChannelImpl(file, mode);
112
  }
113
 
114
  /* Open a file.  MODE is a combination of the above mode flags. */
115
  private FileChannelImpl (File file, int mode) throws FileNotFoundException
116
  {
117
    final String path = file.getPath();
118
    fd = open (path, mode);
119
    this.mode = mode;
120
 
121
    // First open the file and then check if it is a a directory
122
    // to avoid race condition.
123
    if (file.isDirectory())
124
      {
125
        try
126
          {
127
              close();
128
          }
129
        catch (IOException e)
130
          {
131
              /* ignore it */
132
          }
133
 
134
        throw new FileNotFoundException(path + " is a directory");
135
      }
136
  }
137
 
138
  /* Used by init() (native code) */
139
  FileChannelImpl (int fd, int mode)
140
  {
141
    this.fd = fd;
142
    this.mode = mode;
143
  }
144
 
145
  public static FileChannelImpl in;
146
  public static FileChannelImpl out;
147
  public static FileChannelImpl err;
148
 
149
  private native int open (String path, int mode) throws FileNotFoundException;
150
 
151
  public native int available () throws IOException;
152
  private native long implPosition () throws IOException;
153
  private native void seek (long newPosition) throws IOException;
154
  private native void implTruncate (long size) throws IOException;
155
 
156
  public native void unlock (long pos, long len) throws IOException;
157
 
158
  public native long size () throws IOException;
159
 
160
  protected native void implCloseChannel() throws IOException;
161
 
162
  /**
163
   * Makes sure the Channel is properly closed.
164
   */
165
  protected void finalize() throws IOException
166
  {
167
    this.close();
168
  }
169
 
170
  public int read (ByteBuffer dst) throws IOException
171
  {
172
    int result;
173
    byte[] buffer = new byte [dst.remaining ()];
174
 
175
    result = read (buffer, 0, buffer.length);
176
 
177
    if (result > 0)
178
      dst.put (buffer, 0, result);
179
 
180
    return result;
181
  }
182
 
183
  public int read (ByteBuffer dst, long position)
184
    throws IOException
185
  {
186
    if (position < 0)
187
      throw new IllegalArgumentException ();
188
    long oldPosition = implPosition ();
189
    position (position);
190
    int result = read(dst);
191
    position (oldPosition);
192
 
193
    return result;
194
  }
195
 
196
  public native int read ()
197
    throws IOException;
198
 
199
  public native int read (byte[] buffer, int offset, int length)
200
    throws IOException;
201
 
202
  public long read (ByteBuffer[] dsts, int offset, int length)
203
    throws IOException
204
  {
205
    long result = 0;
206
 
207
    for (int i = offset; i < offset + length; i++)
208
      {
209
        result += read (dsts [i]);
210
      }
211
 
212
    return result;
213
  }
214
 
215
  public int write (ByteBuffer src) throws IOException
216
  {
217
    int len = src.remaining ();
218
    if (src.hasArray())
219
      {
220
        byte[] buffer = src.array();
221
        write(buffer, src.arrayOffset() + src.position(), len);
222
        src.position(src.position() + len);
223
      }
224
    else
225
      {
226
        // Use a more efficient native method! FIXME!
227
        byte[] buffer = new byte [len];
228
        src.get (buffer, 0, len);
229
        write (buffer, 0, len);
230
      }
231
    return len;
232
  }
233
 
234
  public int write (ByteBuffer src, long position)
235
    throws IOException
236
  {
237
    if (position < 0)
238
      throw new IllegalArgumentException ();
239
 
240
    if (!isOpen ())
241
      throw new ClosedChannelException ();
242
 
243
    if ((mode & WRITE) == 0)
244
       throw new NonWritableChannelException ();
245
 
246
    int result;
247
    long oldPosition;
248
 
249
    oldPosition = implPosition ();
250
    seek (position);
251
    result = write(src);
252
    seek (oldPosition);
253
 
254
    return result;
255
  }
256
 
257
  public native void write (byte[] buffer, int offset, int length)
258
    throws IOException;
259
 
260
  public native void write (int b) throws IOException;
261
 
262
  public long write(ByteBuffer[] srcs, int offset, int length)
263
    throws IOException
264
  {
265
    long result = 0;
266
 
267
    for (int i = offset;i < offset + length;i++)
268
      {
269
        result += write (srcs[i]);
270
      }
271
 
272
    return result;
273
  }
274
 
275
  public native MappedByteBuffer mapImpl (char mode, long position, int size)
276
    throws IOException;
277
 
278
  public MappedByteBuffer map (FileChannel.MapMode mode,
279
                               long position, long size)
280
    throws IOException
281
  {
282
    char nmode = 0;
283
    if (mode == MapMode.READ_ONLY)
284
      {
285
        nmode = 'r';
286
        if ((this.mode & READ) == 0)
287
          throw new NonReadableChannelException();
288
      }
289
    else if (mode == MapMode.READ_WRITE || mode == MapMode.PRIVATE)
290
      {
291
        nmode = mode == MapMode.READ_WRITE ? '+' : 'c';
292
        if ((this.mode & (READ|WRITE)) != (READ|WRITE))
293
          throw new NonWritableChannelException();
294
      }
295
    else
296
      throw new IllegalArgumentException ();
297
 
298
    if (position < 0 || size < 0 || size > Integer.MAX_VALUE)
299
      throw new IllegalArgumentException ();
300
    return mapImpl(nmode, position, (int) size);
301
  }
302
 
303
  /**
304
   * msync with the disk
305
   */
306
  public void force (boolean metaData) throws IOException
307
  {
308
    if (!isOpen ())
309
      throw new ClosedChannelException ();
310
  }
311
 
312
  // like transferTo, but with a count of less than 2Gbytes
313
  private int smallTransferTo (long position, int count,
314
                               WritableByteChannel target)
315
    throws IOException
316
  {
317
    ByteBuffer buffer;
318
    try
319
      {
320
        // Try to use a mapped buffer if we can.  If this fails for
321
        // any reason we'll fall back to using a ByteBuffer.
322
        buffer = map (MapMode.READ_ONLY, position, count);
323
      }
324
    catch (IOException e)
325
      {
326
        buffer = ByteBuffer.allocate (count);
327
        read (buffer, position);
328
        buffer.flip();
329
      }
330
 
331
    return target.write (buffer);
332
  }
333
 
334
  public long transferTo (long position, long count,
335
                          WritableByteChannel target)
336
    throws IOException
337
  {
338
    if (position < 0
339
        || count < 0)
340
      throw new IllegalArgumentException ();
341
 
342
    if (!isOpen ())
343
      throw new ClosedChannelException ();
344
 
345
    if ((mode & READ) == 0)
346
       throw new NonReadableChannelException ();
347
 
348
    final int pageSize = 65536;
349
    long total = 0;
350
 
351
    while (count > 0)
352
      {
353
        int transferred
354
          = smallTransferTo (position, (int)Math.min (count, pageSize),
355
                             target);
356
        if (transferred < 0)
357
          break;
358
        total += transferred;
359
        position += transferred;
360
        count -= transferred;
361
      }
362
 
363
    return total;
364
  }
365
 
366
  // like transferFrom, but with a count of less than 2Gbytes
367
  private int smallTransferFrom (ReadableByteChannel src, long position,
368
                                 int count)
369
    throws IOException
370
  {
371
    ByteBuffer buffer = null;
372
 
373
    if (src instanceof FileChannel)
374
      {
375
        try
376
          {
377
            // Try to use a mapped buffer if we can.  If this fails
378
            // for any reason we'll fall back to using a ByteBuffer.
379
            buffer = ((FileChannel)src).map (MapMode.READ_ONLY, position,
380
                                             count);
381
          }
382
        catch (IOException e)
383
          {
384
          }
385
      }
386
 
387
    if (buffer == null)
388
      {
389
        buffer = ByteBuffer.allocate ((int) count);
390
        src.read (buffer);
391
        buffer.flip();
392
      }
393
 
394
    return write (buffer, position);
395
  }
396
 
397
  public long transferFrom (ReadableByteChannel src, long position,
398
                            long count)
399
    throws IOException
400
  {
401
    if (position < 0
402
        || count < 0)
403
      throw new IllegalArgumentException ();
404
 
405
    if (!isOpen ())
406
      throw new ClosedChannelException ();
407
 
408
    if ((mode & WRITE) == 0)
409
       throw new NonWritableChannelException ();
410
 
411
    final int pageSize = 65536;
412
    long total = 0;
413
 
414
    while (count > 0)
415
      {
416
        int transferred = smallTransferFrom (src, position,
417
                                             (int)Math.min (count, pageSize));
418
        if (transferred < 0)
419
          break;
420
        total += transferred;
421
        position += transferred;
422
        count -= transferred;
423
      }
424
 
425
    return total;
426
  }
427
 
428
  public FileLock tryLock (long position, long size, boolean shared)
429
    throws IOException
430
  {
431
    if (position < 0
432
        || size < 0)
433
      throw new IllegalArgumentException ();
434
 
435
    if (!isOpen ())
436
      throw new ClosedChannelException ();
437
 
438
    if (shared && (mode & READ) == 0)
439
      throw new NonReadableChannelException ();
440
 
441
    if (!shared && (mode & WRITE) == 0)
442
      throw new NonWritableChannelException ();
443
 
444
    boolean completed = false;
445
 
446
    try
447
      {
448
        begin();
449
        boolean lockable = lock(position, size, shared, false);
450
        completed = true;
451
        return (lockable
452
                ? new FileLockImpl(this, position, size, shared)
453
                : null);
454
      }
455
    finally
456
      {
457
        end(completed);
458
      }
459
  }
460
 
461
  /** Try to acquire a lock at the given position and size.
462
   * On success return true.
463
   * If wait as specified, block until we can get it.
464
   * Otherwise return false.
465
   */
466
  private native boolean lock(long position, long size,
467
                              boolean shared, boolean wait) throws IOException;
468
 
469
  public FileLock lock (long position, long size, boolean shared)
470
    throws IOException
471
  {
472
    if (position < 0
473
        || size < 0)
474
      throw new IllegalArgumentException ();
475
 
476
    if (!isOpen ())
477
      throw new ClosedChannelException ();
478
 
479
    boolean completed = false;
480
 
481
    try
482
      {
483
        boolean lockable = lock(position, size, shared, true);
484
        completed = true;
485
        return (lockable
486
                ? new FileLockImpl(this, position, size, shared)
487
                : null);
488
      }
489
    finally
490
      {
491
        end(completed);
492
      }
493
  }
494
 
495
  public long position ()
496
    throws IOException
497
  {
498
    if (!isOpen ())
499
      throw new ClosedChannelException ();
500
 
501
    return implPosition ();
502
  }
503
 
504
  public FileChannel position (long newPosition)
505
    throws IOException
506
  {
507
    if (newPosition < 0)
508
      throw new IllegalArgumentException ();
509
 
510
    if (!isOpen ())
511
      throw new ClosedChannelException ();
512
 
513
    // FIXME note semantics if seeking beyond eof.
514
    // We should seek lazily - only on a write.
515
    seek (newPosition);
516
    return this;
517
  }
518
 
519
  public FileChannel truncate (long size)
520
    throws IOException
521
  {
522
    if (size < 0)
523
      throw new IllegalArgumentException ();
524
 
525
    if (!isOpen ())
526
      throw new ClosedChannelException ();
527
 
528
    if ((mode & WRITE) == 0)
529
       throw new NonWritableChannelException ();
530
 
531
    if (size < size ())
532
      implTruncate (size);
533
 
534
    return this;
535
  }
536
 
537
  /**
538
   * @return The native file descriptor.
539
   */
540
  public int getNativeFD()
541
  {
542
    return fd;
543
  }
544
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.