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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 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;
40
 
41
import gnu.classpath.Configuration;
42
import gnu.java.nio.FileLockImpl;
43
import gnu.java.nio.VMChannel;
44
 
45
import java.io.File;
46
import java.io.FileNotFoundException;
47
import java.io.IOException;
48
import java.nio.ByteBuffer;
49
import java.nio.MappedByteBuffer;
50
import java.nio.channels.ClosedChannelException;
51
import java.nio.channels.FileChannel;
52
import java.nio.channels.FileLock;
53
import java.nio.channels.NonReadableChannelException;
54
import java.nio.channels.NonWritableChannelException;
55
import java.nio.channels.ReadableByteChannel;
56
import java.nio.channels.WritableByteChannel;
57
 
58
/**
59
 * This file is not user visible !
60
 * But alas, Java does not have a concept of friendly packages
61
 * so this class is public.
62
 * Instances of this class are created by invoking getChannel
63
 * Upon a Input/Output/RandomAccessFile object.
64
 */
65
public final class FileChannelImpl extends FileChannel
66
{
67
  // These are mode values for open().
68
  public static final int READ   = 1;
69
  public static final int WRITE  = 2;
70
  public static final int APPEND = 4;
71
 
72
  // EXCL is used only when making a temp file.
73
  public static final int EXCL   = 8;
74
  public static final int SYNC   = 16;
75
  public static final int DSYNC  = 32;
76
 
77
  public static final FileChannelImpl in;
78
  public static final FileChannelImpl out;
79
  public static final FileChannelImpl err;
80
 
81
  //private static native void init();
82
 
83
  static
84
  {
85
    if (Configuration.INIT_LOAD_LIBRARY)
86
      {
87
        System.loadLibrary("javanio");
88
      }
89
 
90
    //init();
91
 
92
    FileChannelImpl ch = null;
93
    try
94
      {
95
        ch = new FileChannelImpl(VMChannel.getStdin(), READ);
96
      }
97
    catch (IOException ioe)
98
      {
99
        throw new Error(ioe);
100
      }
101
    in = ch;
102
 
103
    ch = null;
104
    try
105
      {
106
        ch = new FileChannelImpl(VMChannel.getStdout(), WRITE);
107
      }
108
    catch (IOException ioe)
109
      {
110
        throw new Error(ioe);
111
      }
112
    out = ch;
113
 
114
    ch = null;
115
    try
116
      {
117
        ch = new FileChannelImpl(VMChannel.getStderr(), WRITE);
118
      }
119
    catch (IOException ioe)
120
      {
121
        throw new Error(ioe);
122
      }
123
    err = ch;
124
  }
125
 
126
  /**
127
   * This is the actual native file descriptor value
128
   */
129
  private VMChannel ch;
130
 
131
  private int mode;
132
 
133
  final String description;
134
 
135
  /* Open a file.  MODE is a combination of the above mode flags. */
136
  /* This is a static factory method, so that VM implementors can decide
137
   * substitute subclasses of FileChannelImpl. */
138
  public static FileChannelImpl create(File file, int mode)
139
    throws IOException
140
  {
141
    return new FileChannelImpl(file, mode);
142
  }
143
 
144
  private FileChannelImpl(File file, int mode)
145
    throws IOException
146
  {
147
    String path = file.getPath();
148
    description = path;
149
    this.mode = mode;
150
    this.ch = new VMChannel();
151
    ch.openFile(path, mode);
152
 
153
    // First open the file and then check if it is a a directory
154
    // to avoid race condition.
155
    if (file.isDirectory())
156
      {
157
        try
158
          {
159
            close();
160
          }
161
        catch (IOException e)
162
          {
163
            /* ignore it */
164
          }
165
 
166
        throw new FileNotFoundException(description + " is a directory");
167
      }
168
  }
169
 
170
  /**
171
   * Constructor for default channels in, out and err.
172
   *
173
   * Used by init() (native code).
174
   *
175
   * @param fd the file descriptor (0, 1, 2 for stdin, stdout, stderr).
176
   *
177
   * @param mode READ or WRITE
178
   */
179
  FileChannelImpl (VMChannel ch, int mode)
180
  {
181
    this.mode = mode;
182
    this.description = "descriptor(" + ch.getState() + ")";
183
    this.ch = ch;
184
  }
185
 
186
  public int available() throws IOException
187
  {
188
    return ch.available();
189
  }
190
 
191
  private long implPosition() throws IOException
192
  {
193
    return ch.position();
194
  }
195
 
196
  private void seek(long newPosition) throws IOException
197
  {
198
    ch.seek(newPosition);
199
  }
200
 
201
  private void implTruncate(long size) throws IOException
202
  {
203
    ch.truncate(size);
204
  }
205
 
206
  public void unlock(long pos, long len) throws IOException
207
  {
208
    ch.unlock(pos, len);
209
  }
210
 
211
  public long size () throws IOException
212
  {
213
    return ch.size();
214
  }
215
 
216
  protected void implCloseChannel() throws IOException
217
  {
218
    ch.close();
219
  }
220
 
221
  /**
222
   * Makes sure the Channel is properly closed.
223
   */
224
  protected void finalize() throws IOException
225
  {
226
    if (ch.getState().isValid())
227
      close();
228
  }
229
 
230
  public int read (ByteBuffer dst) throws IOException
231
  {
232
    return ch.read(dst);
233
  }
234
 
235
  public int read (ByteBuffer dst, long position)
236
    throws IOException
237
  {
238
    if (position < 0)
239
      throw new IllegalArgumentException ("position: " + position);
240
    long oldPosition = implPosition ();
241
    position (position);
242
    int result = read(dst);
243
    position (oldPosition);
244
 
245
    return result;
246
  }
247
 
248
  public int read() throws IOException
249
  {
250
    return ch.read();
251
  }
252
 
253
  public long read (ByteBuffer[] dsts, int offset, int length)
254
    throws IOException
255
  {
256
    return ch.readScattering(dsts, offset, length);
257
  }
258
 
259
  public int write (ByteBuffer src) throws IOException
260
  {
261
    return ch.write(src);
262
  }
263
 
264
  public int write (ByteBuffer src, long position)
265
    throws IOException
266
  {
267
    if (position < 0)
268
      throw new IllegalArgumentException ("position: " + position);
269
 
270
    if (!isOpen ())
271
      throw new ClosedChannelException ();
272
 
273
    if ((mode & WRITE) == 0)
274
       throw new NonWritableChannelException ();
275
 
276
    int result;
277
    long oldPosition;
278
 
279
    oldPosition = implPosition ();
280
    seek (position);
281
    result = write(src);
282
    seek (oldPosition);
283
 
284
    return result;
285
  }
286
 
287
  public void write (int b) throws IOException
288
  {
289
    ch.write(b);
290
  }
291
 
292
  public long write(ByteBuffer[] srcs, int offset, int length)
293
    throws IOException
294
  {
295
    return ch.writeGathering(srcs, offset, length);
296
  }
297
 
298
  public MappedByteBuffer map (FileChannel.MapMode mode,
299
                               long position, long size)
300
    throws IOException
301
  {
302
    char nmode = 0;
303
    if (mode == MapMode.READ_ONLY)
304
      {
305
        nmode = 'r';
306
        if ((this.mode & READ) == 0)
307
          throw new NonReadableChannelException();
308
      }
309
    else if (mode == MapMode.READ_WRITE || mode == MapMode.PRIVATE)
310
      {
311
        nmode = mode == MapMode.READ_WRITE ? '+' : 'c';
312
        if ((this.mode & WRITE) != WRITE)
313
          throw new NonWritableChannelException();
314
        if ((this.mode & READ) != READ)
315
          throw new NonReadableChannelException();
316
      }
317
    else
318
      throw new IllegalArgumentException ("mode: " + mode);
319
 
320
    if (position < 0 || size < 0 || size > Integer.MAX_VALUE)
321
      throw new IllegalArgumentException ("position: " + position
322
                                          + ", size: " + size);
323
    return ch.map(nmode, position, (int) size);
324
  }
325
 
326
  /**
327
   * msync with the disk
328
   */
329
  public void force (boolean metaData) throws IOException
330
  {
331
    if (!isOpen ())
332
      throw new ClosedChannelException ();
333
 
334
    ch.flush(metaData);
335
  }
336
 
337
  // like transferTo, but with a count of less than 2Gbytes
338
  private int smallTransferTo (long position, int count,
339
                               WritableByteChannel target)
340
    throws IOException
341
  {
342
    ByteBuffer buffer;
343
    try
344
      {
345
        // Try to use a mapped buffer if we can.  If this fails for
346
        // any reason we'll fall back to using a ByteBuffer.
347
        buffer = map (MapMode.READ_ONLY, position, count);
348
      }
349
    catch (IOException e)
350
      {
351
        buffer = ByteBuffer.allocate (count);
352
        read (buffer, position);
353
        buffer.flip();
354
      }
355
 
356
    return target.write (buffer);
357
  }
358
 
359
  public long transferTo (long position, long count,
360
                          WritableByteChannel target)
361
    throws IOException
362
  {
363
    if (position < 0
364
        || count < 0)
365
      throw new IllegalArgumentException ("position: " + position
366
                                          + ", count: " + count);
367
 
368
    if (!isOpen ())
369
      throw new ClosedChannelException ();
370
 
371
    if ((mode & READ) == 0)
372
       throw new NonReadableChannelException ();
373
 
374
    final int pageSize = 65536;
375
    long total = 0;
376
 
377
    while (count > 0)
378
      {
379
        int transferred
380
          = smallTransferTo (position, (int)Math.min (count, pageSize),
381
                             target);
382
        if (transferred < 0)
383
          break;
384
        total += transferred;
385
        position += transferred;
386
        count -= transferred;
387
      }
388
 
389
    return total;
390
  }
391
 
392
  // like transferFrom, but with a count of less than 2Gbytes
393
  private int smallTransferFrom (ReadableByteChannel src, long position,
394
                                 int count)
395
    throws IOException
396
  {
397
    ByteBuffer buffer = null;
398
 
399
    if (src instanceof FileChannel)
400
      {
401
        try
402
          {
403
            // Try to use a mapped buffer if we can.  If this fails
404
            // for any reason we'll fall back to using a ByteBuffer.
405
            buffer = ((FileChannel)src).map (MapMode.READ_ONLY, position,
406
                                             count);
407
          }
408
        catch (IOException e)
409
          {
410
          }
411
      }
412
 
413
    if (buffer == null)
414
      {
415
        buffer = ByteBuffer.allocate (count);
416
        src.read (buffer);
417
        buffer.flip();
418
      }
419
 
420
    return write (buffer, position);
421
  }
422
 
423
  public long transferFrom (ReadableByteChannel src, long position,
424
                            long count)
425
    throws IOException
426
  {
427
    if (position < 0
428
        || count < 0)
429
      throw new IllegalArgumentException ("position: " + position
430
                                          + ", count: " + count);
431
 
432
    if (!isOpen ())
433
      throw new ClosedChannelException ();
434
 
435
    if ((mode & WRITE) == 0)
436
       throw new NonWritableChannelException ();
437
 
438
    final int pageSize = 65536;
439
    long total = 0;
440
 
441
    while (count > 0)
442
      {
443
        int transferred = smallTransferFrom (src, position,
444
                                             (int)Math.min (count, pageSize));
445
        if (transferred < 0)
446
          break;
447
        total += transferred;
448
        position += transferred;
449
        count -= transferred;
450
      }
451
 
452
    return total;
453
  }
454
 
455
  // Shared sanity checks between lock and tryLock methods.
456
  private void lockCheck(long position, long size, boolean shared)
457
    throws IOException
458
  {
459
    if (position < 0
460
        || size < 0)
461
      throw new IllegalArgumentException ("position: " + position
462
                                          + ", size: " + size);
463
 
464
    if (!isOpen ())
465
      throw new ClosedChannelException();
466
 
467
    if (shared && ((mode & READ) == 0))
468
      throw new NonReadableChannelException();
469
 
470
    if (!shared && ((mode & WRITE) == 0))
471
      throw new NonWritableChannelException();
472
  }
473
 
474
  public FileLock tryLock (long position, long size, boolean shared)
475
    throws IOException
476
  {
477
    lockCheck(position, size, shared);
478
 
479
    boolean completed = false;
480
    try
481
      {
482
        begin();
483
        boolean lockable = ch.lock(position, size, shared, false);
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 FileLock lock (long position, long size, boolean shared)
496
    throws IOException
497
  {
498
    lockCheck(position, size, shared);
499
 
500
    boolean completed = false;
501
    try
502
      {
503
        boolean lockable = ch.lock(position, size, shared, true);
504
        completed = true;
505
        return (lockable
506
                ? new FileLockImpl(this, position, size, shared)
507
                : null);
508
      }
509
    finally
510
      {
511
        end(completed);
512
      }
513
  }
514
 
515
  public long position ()
516
    throws IOException
517
  {
518
    if (!isOpen ())
519
      throw new ClosedChannelException ();
520
 
521
    return implPosition ();
522
  }
523
 
524
  public FileChannel position (long newPosition)
525
    throws IOException
526
  {
527
    if (newPosition < 0)
528
      throw new IllegalArgumentException ("newPosition: " + newPosition);
529
 
530
    if (!isOpen ())
531
      throw new ClosedChannelException ();
532
 
533
    // FIXME note semantics if seeking beyond eof.
534
    // We should seek lazily - only on a write.
535
    seek (newPosition);
536
    return this;
537
  }
538
 
539
  public FileChannel truncate (long size)
540
    throws IOException
541
  {
542
    if (size < 0)
543
      throw new IllegalArgumentException ("size: " + size);
544
 
545
    if (!isOpen ())
546
      throw new ClosedChannelException ();
547
 
548
    if ((mode & WRITE) == 0)
549
       throw new NonWritableChannelException ();
550
 
551
    if (size < size ())
552
      implTruncate (size);
553
 
554
    return this;
555
  }
556
 
557
  public String toString()
558
  {
559
    return (super.toString()
560
            + "[ fd: " + ch.getState()
561
            + "; mode: " + Integer.toOctalString(mode)
562
            + "; " + description + " ]");
563
  }
564
 
565
  /**
566
   * @return The native file descriptor.
567
   * /
568
  public int getNativeFD()
569
  {
570
    return fd;
571
  }*/
572
}

powered by: WebSVN 2.1.0

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