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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [gnu/] [java/] [nio/] [channels/] [FileChannelImpl.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* FileChannelImpl.java --
2
   Copyright (C) 2002, 2004, 2005  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
  public FileChannelImpl (File file, int mode) throws FileNotFoundException
107
  {
108
    final String path = file.getPath();
109
    fd = open (path, mode);
110
    this.mode = mode;
111
 
112
    // First open the file and then check if it is a a directory
113
    // to avoid race condition.
114
    if (file.isDirectory())
115
      {
116
        try
117
          {
118
              close();
119
          }
120
        catch (IOException e)
121
          {
122
              /* ignore it */
123
          }
124
 
125
        throw new FileNotFoundException(path + " is a directory");
126
      }
127
  }
128
 
129
  /* Used by init() (native code) */
130
  FileChannelImpl (int fd, int mode)
131
  {
132
    this.fd = fd;
133
    this.mode = mode;
134
  }
135
 
136
  public static FileChannelImpl in;
137
  public static FileChannelImpl out;
138
  public static FileChannelImpl err;
139
 
140
  private native int open (String path, int mode) throws FileNotFoundException;
141
 
142
  public native int available () throws IOException;
143
  private native long implPosition () throws IOException;
144
  private native void seek (long newPosition) throws IOException;
145
  private native void implTruncate (long size) throws IOException;
146
 
147
  public native void unlock (long pos, long len) throws IOException;
148
 
149
  public native long size () throws IOException;
150
 
151
  protected native void implCloseChannel() throws IOException;
152
 
153
  /**
154
   * Makes sure the Channel is properly closed.
155
   */
156
  protected void finalize() throws IOException
157
  {
158
    this.close();
159
  }
160
 
161
  public int read (ByteBuffer dst) throws IOException
162
  {
163
    int result;
164
    byte[] buffer = new byte [dst.remaining ()];
165
 
166
    result = read (buffer, 0, buffer.length);
167
 
168
    if (result > 0)
169
      dst.put (buffer, 0, result);
170
 
171
    return result;
172
  }
173
 
174
  public int read (ByteBuffer dst, long position)
175
    throws IOException
176
  {
177
    if (position < 0)
178
      throw new IllegalArgumentException ();
179
    long oldPosition = implPosition ();
180
    position (position);
181
    int result = read(dst);
182
    position (oldPosition);
183
 
184
    return result;
185
  }
186
 
187
  public native int read ()
188
    throws IOException;
189
 
190
  public native int read (byte[] buffer, int offset, int length)
191
    throws IOException;
192
 
193
  public long read (ByteBuffer[] dsts, int offset, int length)
194
    throws IOException
195
  {
196
    long result = 0;
197
 
198
    for (int i = offset; i < offset + length; i++)
199
      {
200
        result += read (dsts [i]);
201
      }
202
 
203
    return result;
204
  }
205
 
206
  public int write (ByteBuffer src) throws IOException
207
  {
208
    int len = src.remaining ();
209
    if (src.hasArray())
210
      {
211
        byte[] buffer = src.array();
212
        write(buffer, src.arrayOffset() + src.position(), len);
213
        src.position(src.position() + len);
214
      }
215
    else
216
      {
217
        // Use a more efficient native method! FIXME!
218
        byte[] buffer = new byte [len];
219
        src.get (buffer, 0, len);
220
        write (buffer, 0, len);
221
      }
222
    return len;
223
  }
224
 
225
  public int write (ByteBuffer src, long position)
226
    throws IOException
227
  {
228
    if (position < 0)
229
      throw new IllegalArgumentException ();
230
 
231
    if (!isOpen ())
232
      throw new ClosedChannelException ();
233
 
234
    if ((mode & WRITE) == 0)
235
       throw new NonWritableChannelException ();
236
 
237
    int result;
238
    long oldPosition;
239
 
240
    oldPosition = implPosition ();
241
    seek (position);
242
    result = write(src);
243
    seek (oldPosition);
244
 
245
    return result;
246
  }
247
 
248
  public native void write (byte[] buffer, int offset, int length)
249
    throws IOException;
250
 
251
  public native void write (int b) throws IOException;
252
 
253
  public long write(ByteBuffer[] srcs, int offset, int length)
254
    throws IOException
255
  {
256
    long result = 0;
257
 
258
    for (int i = offset;i < offset + length;i++)
259
      {
260
        result += write (srcs[i]);
261
      }
262
 
263
    return result;
264
  }
265
 
266
  public native MappedByteBuffer mapImpl (char mode, long position, int size)
267
    throws IOException;
268
 
269
  public MappedByteBuffer map (FileChannel.MapMode mode,
270
                               long position, long size)
271
    throws IOException
272
  {
273
    char nmode = 0;
274
    if (mode == MapMode.READ_ONLY)
275
      {
276
        nmode = 'r';
277
        if ((this.mode & READ) == 0)
278
          throw new NonReadableChannelException();
279
      }
280
    else if (mode == MapMode.READ_WRITE || mode == MapMode.PRIVATE)
281
      {
282
        nmode = mode == MapMode.READ_WRITE ? '+' : 'c';
283
        if ((this.mode & (READ|WRITE)) != (READ|WRITE))
284
          throw new NonWritableChannelException();
285
      }
286
    else
287
      throw new IllegalArgumentException ();
288
 
289
    if (position < 0 || size < 0 || size > Integer.MAX_VALUE)
290
      throw new IllegalArgumentException ();
291
    return mapImpl(nmode, position, (int) size);
292
  }
293
 
294
  /**
295
   * msync with the disk
296
   */
297
  public void force (boolean metaData) throws IOException
298
  {
299
    if (!isOpen ())
300
      throw new ClosedChannelException ();
301
  }
302
 
303
  // like transferTo, but with a count of less than 2Gbytes
304
  private int smallTransferTo (long position, int count,
305
                               WritableByteChannel target)
306
    throws IOException
307
  {
308
    ByteBuffer buffer;
309
    try
310
      {
311
        // Try to use a mapped buffer if we can.  If this fails for
312
        // any reason we'll fall back to using a ByteBuffer.
313
        buffer = map (MapMode.READ_ONLY, position, count);
314
      }
315
    catch (IOException e)
316
      {
317
        buffer = ByteBuffer.allocate (count);
318
        read (buffer, position);
319
        buffer.flip();
320
      }
321
 
322
    return target.write (buffer);
323
  }
324
 
325
  public long transferTo (long position, long count,
326
                          WritableByteChannel target)
327
    throws IOException
328
  {
329
    if (position < 0
330
        || count < 0)
331
      throw new IllegalArgumentException ();
332
 
333
    if (!isOpen ())
334
      throw new ClosedChannelException ();
335
 
336
    if ((mode & READ) == 0)
337
       throw new NonReadableChannelException ();
338
 
339
    final int pageSize = 65536;
340
    long total = 0;
341
 
342
    while (count > 0)
343
      {
344
        int transferred
345
          = smallTransferTo (position, (int)Math.min (count, pageSize),
346
                             target);
347
        if (transferred < 0)
348
          break;
349
        total += transferred;
350
        position += transferred;
351
        count -= transferred;
352
      }
353
 
354
    return total;
355
  }
356
 
357
  // like transferFrom, but with a count of less than 2Gbytes
358
  private int smallTransferFrom (ReadableByteChannel src, long position,
359
                                 int count)
360
    throws IOException
361
  {
362
    ByteBuffer buffer = null;
363
 
364
    if (src instanceof FileChannel)
365
      {
366
        try
367
          {
368
            // Try to use a mapped buffer if we can.  If this fails
369
            // for any reason we'll fall back to using a ByteBuffer.
370
            buffer = ((FileChannel)src).map (MapMode.READ_ONLY, position,
371
                                             count);
372
          }
373
        catch (IOException e)
374
          {
375
          }
376
      }
377
 
378
    if (buffer == null)
379
      {
380
        buffer = ByteBuffer.allocate ((int) count);
381
        src.read (buffer);
382
        buffer.flip();
383
      }
384
 
385
    return write (buffer, position);
386
  }
387
 
388
  public long transferFrom (ReadableByteChannel src, long position,
389
                            long count)
390
    throws IOException
391
  {
392
    if (position < 0
393
        || count < 0)
394
      throw new IllegalArgumentException ();
395
 
396
    if (!isOpen ())
397
      throw new ClosedChannelException ();
398
 
399
    if ((mode & WRITE) == 0)
400
       throw new NonWritableChannelException ();
401
 
402
    final int pageSize = 65536;
403
    long total = 0;
404
 
405
    while (count > 0)
406
      {
407
        int transferred = smallTransferFrom (src, position,
408
                                             (int)Math.min (count, pageSize));
409
        if (transferred < 0)
410
          break;
411
        total += transferred;
412
        position += transferred;
413
        count -= transferred;
414
      }
415
 
416
    return total;
417
  }
418
 
419
  public FileLock tryLock (long position, long size, boolean shared)
420
    throws IOException
421
  {
422
    if (position < 0
423
        || size < 0)
424
      throw new IllegalArgumentException ();
425
 
426
    if (!isOpen ())
427
      throw new ClosedChannelException ();
428
 
429
    if (shared && (mode & READ) == 0)
430
      throw new NonReadableChannelException ();
431
 
432
    if (!shared && (mode & WRITE) == 0)
433
      throw new NonWritableChannelException ();
434
 
435
    boolean completed = false;
436
 
437
    try
438
      {
439
        begin();
440
        boolean lockable = lock(position, size, shared, false);
441
        completed = true;
442
        return (lockable
443
                ? new FileLockImpl(this, position, size, shared)
444
                : null);
445
      }
446
    finally
447
      {
448
        end(completed);
449
      }
450
  }
451
 
452
  /** Try to acquire a lock at the given position and size.
453
   * On success return true.
454
   * If wait as specified, block until we can get it.
455
   * Otherwise return false.
456
   */
457
  private native boolean lock(long position, long size,
458
                              boolean shared, boolean wait) throws IOException;
459
 
460
  public FileLock lock (long position, long size, boolean shared)
461
    throws IOException
462
  {
463
    if (position < 0
464
        || size < 0)
465
      throw new IllegalArgumentException ();
466
 
467
    if (!isOpen ())
468
      throw new ClosedChannelException ();
469
 
470
    boolean completed = false;
471
 
472
    try
473
      {
474
        boolean lockable = lock(position, size, shared, true);
475
        completed = true;
476
        return (lockable
477
                ? new FileLockImpl(this, position, size, shared)
478
                : null);
479
      }
480
    finally
481
      {
482
        end(completed);
483
      }
484
  }
485
 
486
  public long position ()
487
    throws IOException
488
  {
489
    if (!isOpen ())
490
      throw new ClosedChannelException ();
491
 
492
    return implPosition ();
493
  }
494
 
495
  public FileChannel position (long newPosition)
496
    throws IOException
497
  {
498
    if (newPosition < 0)
499
      throw new IllegalArgumentException ();
500
 
501
    if (!isOpen ())
502
      throw new ClosedChannelException ();
503
 
504
    // FIXME note semantics if seeking beyond eof.
505
    // We should seek lazily - only on a write.
506
    seek (newPosition);
507
    return this;
508
  }
509
 
510
  public FileChannel truncate (long size)
511
    throws IOException
512
  {
513
    if (size < 0)
514
      throw new IllegalArgumentException ();
515
 
516
    if (!isOpen ())
517
      throw new ClosedChannelException ();
518
 
519
    if ((mode & WRITE) == 0)
520
       throw new NonWritableChannelException ();
521
 
522
    if (size < size ())
523
      implTruncate (size);
524
 
525
    return this;
526
  }
527
}

powered by: WebSVN 2.1.0

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