Automatic sources dropoff on 2020-06-10 18:32:38.095721
The change is generated with prebuilt drop tool.
Change-Id: I24cbf6ba6db262a1ae1445db1427a08fee35b3b4
diff --git a/java/nio/Bits.java b/java/nio/Bits.java
new file mode 100644
index 0000000..56cb80b
--- /dev/null
+++ b/java/nio/Bits.java
@@ -0,0 +1,881 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio;
+
+import java.security.AccessController;
+
+import sun.misc.Unsafe;
+import sun.misc.VM;
+
+/**
+ * Access to bits, native and otherwise.
+ */
+
+class Bits { // package-private
+
+ private Bits() { }
+
+
+ // -- Swapping --
+
+ static short swap(short x) {
+ return Short.reverseBytes(x);
+ }
+
+ static char swap(char x) {
+ return Character.reverseBytes(x);
+ }
+
+ static int swap(int x) {
+ return Integer.reverseBytes(x);
+ }
+
+ static long swap(long x) {
+ return Long.reverseBytes(x);
+ }
+
+
+ // -- get/put char --
+
+ static private char makeChar(byte b1, byte b0) {
+ return (char)((b1 << 8) | (b0 & 0xff));
+ }
+
+ static char getCharL(ByteBuffer bb, int bi) {
+ return makeChar(bb._get(bi + 1),
+ bb._get(bi ));
+ }
+
+ static char getCharL(long a) {
+ return makeChar(_get(a + 1),
+ _get(a ));
+ }
+
+ static char getCharB(ByteBuffer bb, int bi) {
+ return makeChar(bb._get(bi ),
+ bb._get(bi + 1));
+ }
+
+ static char getCharB(long a) {
+ return makeChar(_get(a ),
+ _get(a + 1));
+ }
+
+ static char getChar(ByteBuffer bb, int bi, boolean bigEndian) {
+ return bigEndian ? getCharB(bb, bi) : getCharL(bb, bi);
+ }
+
+ static char getChar(long a, boolean bigEndian) {
+ return bigEndian ? getCharB(a) : getCharL(a);
+ }
+
+ private static byte char1(char x) { return (byte)(x >> 8); }
+ private static byte char0(char x) { return (byte)(x ); }
+
+ static void putCharL(ByteBuffer bb, int bi, char x) {
+ bb._put(bi , char0(x));
+ bb._put(bi + 1, char1(x));
+ }
+
+ static void putCharL(long a, char x) {
+ _put(a , char0(x));
+ _put(a + 1, char1(x));
+ }
+
+ static void putCharB(ByteBuffer bb, int bi, char x) {
+ bb._put(bi , char1(x));
+ bb._put(bi + 1, char0(x));
+ }
+
+ static void putCharB(long a, char x) {
+ _put(a , char1(x));
+ _put(a + 1, char0(x));
+ }
+
+ static void putChar(ByteBuffer bb, int bi, char x, boolean bigEndian) {
+ if (bigEndian)
+ putCharB(bb, bi, x);
+ else
+ putCharL(bb, bi, x);
+ }
+
+ static void putChar(long a, char x, boolean bigEndian) {
+ if (bigEndian)
+ putCharB(a, x);
+ else
+ putCharL(a, x);
+ }
+
+
+ // -- get/put short --
+
+ static private short makeShort(byte b1, byte b0) {
+ return (short)((b1 << 8) | (b0 & 0xff));
+ }
+
+ static short getShortL(ByteBuffer bb, int bi) {
+ return makeShort(bb._get(bi + 1),
+ bb._get(bi ));
+ }
+
+ static short getShortL(long a) {
+ return makeShort(_get(a + 1),
+ _get(a ));
+ }
+
+ static short getShortB(ByteBuffer bb, int bi) {
+ return makeShort(bb._get(bi ),
+ bb._get(bi + 1));
+ }
+
+ static short getShortB(long a) {
+ return makeShort(_get(a ),
+ _get(a + 1));
+ }
+
+ static short getShort(ByteBuffer bb, int bi, boolean bigEndian) {
+ return bigEndian ? getShortB(bb, bi) : getShortL(bb, bi);
+ }
+
+ static short getShort(long a, boolean bigEndian) {
+ return bigEndian ? getShortB(a) : getShortL(a);
+ }
+
+ private static byte short1(short x) { return (byte)(x >> 8); }
+ private static byte short0(short x) { return (byte)(x ); }
+
+ static void putShortL(ByteBuffer bb, int bi, short x) {
+ bb._put(bi , short0(x));
+ bb._put(bi + 1, short1(x));
+ }
+
+ static void putShortL(long a, short x) {
+ _put(a , short0(x));
+ _put(a + 1, short1(x));
+ }
+
+ static void putShortB(ByteBuffer bb, int bi, short x) {
+ bb._put(bi , short1(x));
+ bb._put(bi + 1, short0(x));
+ }
+
+ static void putShortB(long a, short x) {
+ _put(a , short1(x));
+ _put(a + 1, short0(x));
+ }
+
+ static void putShort(ByteBuffer bb, int bi, short x, boolean bigEndian) {
+ if (bigEndian)
+ putShortB(bb, bi, x);
+ else
+ putShortL(bb, bi, x);
+ }
+
+ static void putShort(long a, short x, boolean bigEndian) {
+ if (bigEndian)
+ putShortB(a, x);
+ else
+ putShortL(a, x);
+ }
+
+
+ // -- get/put int --
+
+ static private int makeInt(byte b3, byte b2, byte b1, byte b0) {
+ return (((b3 ) << 24) |
+ ((b2 & 0xff) << 16) |
+ ((b1 & 0xff) << 8) |
+ ((b0 & 0xff) ));
+ }
+
+ static int getIntL(ByteBuffer bb, int bi) {
+ return makeInt(bb._get(bi + 3),
+ bb._get(bi + 2),
+ bb._get(bi + 1),
+ bb._get(bi ));
+ }
+
+ static int getIntL(long a) {
+ return makeInt(_get(a + 3),
+ _get(a + 2),
+ _get(a + 1),
+ _get(a ));
+ }
+
+ static int getIntB(ByteBuffer bb, int bi) {
+ return makeInt(bb._get(bi ),
+ bb._get(bi + 1),
+ bb._get(bi + 2),
+ bb._get(bi + 3));
+ }
+
+ static int getIntB(long a) {
+ return makeInt(_get(a ),
+ _get(a + 1),
+ _get(a + 2),
+ _get(a + 3));
+ }
+
+ static int getInt(ByteBuffer bb, int bi, boolean bigEndian) {
+ return bigEndian ? getIntB(bb, bi) : getIntL(bb, bi) ;
+ }
+
+ static int getInt(long a, boolean bigEndian) {
+ return bigEndian ? getIntB(a) : getIntL(a) ;
+ }
+
+ private static byte int3(int x) { return (byte)(x >> 24); }
+ private static byte int2(int x) { return (byte)(x >> 16); }
+ private static byte int1(int x) { return (byte)(x >> 8); }
+ private static byte int0(int x) { return (byte)(x ); }
+
+ static void putIntL(ByteBuffer bb, int bi, int x) {
+ bb._put(bi + 3, int3(x));
+ bb._put(bi + 2, int2(x));
+ bb._put(bi + 1, int1(x));
+ bb._put(bi , int0(x));
+ }
+
+ static void putIntL(long a, int x) {
+ _put(a + 3, int3(x));
+ _put(a + 2, int2(x));
+ _put(a + 1, int1(x));
+ _put(a , int0(x));
+ }
+
+ static void putIntB(ByteBuffer bb, int bi, int x) {
+ bb._put(bi , int3(x));
+ bb._put(bi + 1, int2(x));
+ bb._put(bi + 2, int1(x));
+ bb._put(bi + 3, int0(x));
+ }
+
+ static void putIntB(long a, int x) {
+ _put(a , int3(x));
+ _put(a + 1, int2(x));
+ _put(a + 2, int1(x));
+ _put(a + 3, int0(x));
+ }
+
+ static void putInt(ByteBuffer bb, int bi, int x, boolean bigEndian) {
+ if (bigEndian)
+ putIntB(bb, bi, x);
+ else
+ putIntL(bb, bi, x);
+ }
+
+ static void putInt(long a, int x, boolean bigEndian) {
+ if (bigEndian)
+ putIntB(a, x);
+ else
+ putIntL(a, x);
+ }
+
+
+ // -- get/put long --
+
+ static private long makeLong(byte b7, byte b6, byte b5, byte b4,
+ byte b3, byte b2, byte b1, byte b0)
+ {
+ return ((((long)b7 ) << 56) |
+ (((long)b6 & 0xff) << 48) |
+ (((long)b5 & 0xff) << 40) |
+ (((long)b4 & 0xff) << 32) |
+ (((long)b3 & 0xff) << 24) |
+ (((long)b2 & 0xff) << 16) |
+ (((long)b1 & 0xff) << 8) |
+ (((long)b0 & 0xff) ));
+ }
+
+ static long getLongL(ByteBuffer bb, int bi) {
+ return makeLong(bb._get(bi + 7),
+ bb._get(bi + 6),
+ bb._get(bi + 5),
+ bb._get(bi + 4),
+ bb._get(bi + 3),
+ bb._get(bi + 2),
+ bb._get(bi + 1),
+ bb._get(bi ));
+ }
+
+ static long getLongL(long a) {
+ return makeLong(_get(a + 7),
+ _get(a + 6),
+ _get(a + 5),
+ _get(a + 4),
+ _get(a + 3),
+ _get(a + 2),
+ _get(a + 1),
+ _get(a ));
+ }
+
+ static long getLongB(ByteBuffer bb, int bi) {
+ return makeLong(bb._get(bi ),
+ bb._get(bi + 1),
+ bb._get(bi + 2),
+ bb._get(bi + 3),
+ bb._get(bi + 4),
+ bb._get(bi + 5),
+ bb._get(bi + 6),
+ bb._get(bi + 7));
+ }
+
+ static long getLongB(long a) {
+ return makeLong(_get(a ),
+ _get(a + 1),
+ _get(a + 2),
+ _get(a + 3),
+ _get(a + 4),
+ _get(a + 5),
+ _get(a + 6),
+ _get(a + 7));
+ }
+
+ static long getLong(ByteBuffer bb, int bi, boolean bigEndian) {
+ return bigEndian ? getLongB(bb, bi) : getLongL(bb, bi);
+ }
+
+ static long getLong(long a, boolean bigEndian) {
+ return bigEndian ? getLongB(a) : getLongL(a);
+ }
+
+ private static byte long7(long x) { return (byte)(x >> 56); }
+ private static byte long6(long x) { return (byte)(x >> 48); }
+ private static byte long5(long x) { return (byte)(x >> 40); }
+ private static byte long4(long x) { return (byte)(x >> 32); }
+ private static byte long3(long x) { return (byte)(x >> 24); }
+ private static byte long2(long x) { return (byte)(x >> 16); }
+ private static byte long1(long x) { return (byte)(x >> 8); }
+ private static byte long0(long x) { return (byte)(x ); }
+
+ static void putLongL(ByteBuffer bb, int bi, long x) {
+ bb._put(bi + 7, long7(x));
+ bb._put(bi + 6, long6(x));
+ bb._put(bi + 5, long5(x));
+ bb._put(bi + 4, long4(x));
+ bb._put(bi + 3, long3(x));
+ bb._put(bi + 2, long2(x));
+ bb._put(bi + 1, long1(x));
+ bb._put(bi , long0(x));
+ }
+
+ static void putLongL(long a, long x) {
+ _put(a + 7, long7(x));
+ _put(a + 6, long6(x));
+ _put(a + 5, long5(x));
+ _put(a + 4, long4(x));
+ _put(a + 3, long3(x));
+ _put(a + 2, long2(x));
+ _put(a + 1, long1(x));
+ _put(a , long0(x));
+ }
+
+ static void putLongB(ByteBuffer bb, int bi, long x) {
+ bb._put(bi , long7(x));
+ bb._put(bi + 1, long6(x));
+ bb._put(bi + 2, long5(x));
+ bb._put(bi + 3, long4(x));
+ bb._put(bi + 4, long3(x));
+ bb._put(bi + 5, long2(x));
+ bb._put(bi + 6, long1(x));
+ bb._put(bi + 7, long0(x));
+ }
+
+ static void putLongB(long a, long x) {
+ _put(a , long7(x));
+ _put(a + 1, long6(x));
+ _put(a + 2, long5(x));
+ _put(a + 3, long4(x));
+ _put(a + 4, long3(x));
+ _put(a + 5, long2(x));
+ _put(a + 6, long1(x));
+ _put(a + 7, long0(x));
+ }
+
+ static void putLong(ByteBuffer bb, int bi, long x, boolean bigEndian) {
+ if (bigEndian)
+ putLongB(bb, bi, x);
+ else
+ putLongL(bb, bi, x);
+ }
+
+ static void putLong(long a, long x, boolean bigEndian) {
+ if (bigEndian)
+ putLongB(a, x);
+ else
+ putLongL(a, x);
+ }
+
+
+ // -- get/put float --
+
+ static float getFloatL(ByteBuffer bb, int bi) {
+ return Float.intBitsToFloat(getIntL(bb, bi));
+ }
+
+ static float getFloatL(long a) {
+ return Float.intBitsToFloat(getIntL(a));
+ }
+
+ static float getFloatB(ByteBuffer bb, int bi) {
+ return Float.intBitsToFloat(getIntB(bb, bi));
+ }
+
+ static float getFloatB(long a) {
+ return Float.intBitsToFloat(getIntB(a));
+ }
+
+ static float getFloat(ByteBuffer bb, int bi, boolean bigEndian) {
+ return bigEndian ? getFloatB(bb, bi) : getFloatL(bb, bi);
+ }
+
+ static float getFloat(long a, boolean bigEndian) {
+ return bigEndian ? getFloatB(a) : getFloatL(a);
+ }
+
+ static void putFloatL(ByteBuffer bb, int bi, float x) {
+ putIntL(bb, bi, Float.floatToRawIntBits(x));
+ }
+
+ static void putFloatL(long a, float x) {
+ putIntL(a, Float.floatToRawIntBits(x));
+ }
+
+ static void putFloatB(ByteBuffer bb, int bi, float x) {
+ putIntB(bb, bi, Float.floatToRawIntBits(x));
+ }
+
+ static void putFloatB(long a, float x) {
+ putIntB(a, Float.floatToRawIntBits(x));
+ }
+
+ static void putFloat(ByteBuffer bb, int bi, float x, boolean bigEndian) {
+ if (bigEndian)
+ putFloatB(bb, bi, x);
+ else
+ putFloatL(bb, bi, x);
+ }
+
+ static void putFloat(long a, float x, boolean bigEndian) {
+ if (bigEndian)
+ putFloatB(a, x);
+ else
+ putFloatL(a, x);
+ }
+
+
+ // -- get/put double --
+
+ static double getDoubleL(ByteBuffer bb, int bi) {
+ return Double.longBitsToDouble(getLongL(bb, bi));
+ }
+
+ static double getDoubleL(long a) {
+ return Double.longBitsToDouble(getLongL(a));
+ }
+
+ static double getDoubleB(ByteBuffer bb, int bi) {
+ return Double.longBitsToDouble(getLongB(bb, bi));
+ }
+
+ static double getDoubleB(long a) {
+ return Double.longBitsToDouble(getLongB(a));
+ }
+
+ static double getDouble(ByteBuffer bb, int bi, boolean bigEndian) {
+ return bigEndian ? getDoubleB(bb, bi) : getDoubleL(bb, bi);
+ }
+
+ static double getDouble(long a, boolean bigEndian) {
+ return bigEndian ? getDoubleB(a) : getDoubleL(a);
+ }
+
+ static void putDoubleL(ByteBuffer bb, int bi, double x) {
+ putLongL(bb, bi, Double.doubleToRawLongBits(x));
+ }
+
+ static void putDoubleL(long a, double x) {
+ putLongL(a, Double.doubleToRawLongBits(x));
+ }
+
+ static void putDoubleB(ByteBuffer bb, int bi, double x) {
+ putLongB(bb, bi, Double.doubleToRawLongBits(x));
+ }
+
+ static void putDoubleB(long a, double x) {
+ putLongB(a, Double.doubleToRawLongBits(x));
+ }
+
+ static void putDouble(ByteBuffer bb, int bi, double x, boolean bigEndian) {
+ if (bigEndian)
+ putDoubleB(bb, bi, x);
+ else
+ putDoubleL(bb, bi, x);
+ }
+
+ static void putDouble(long a, double x, boolean bigEndian) {
+ if (bigEndian)
+ putDoubleB(a, x);
+ else
+ putDoubleL(a, x);
+ }
+
+
+ // -- Unsafe access --
+
+ private static final Unsafe unsafe = Unsafe.getUnsafe();
+
+ private static byte _get(long a) {
+ return unsafe.getByte(a);
+ }
+
+ private static void _put(long a, byte b) {
+ unsafe.putByte(a, b);
+ }
+
+ static Unsafe unsafe() {
+ return unsafe;
+ }
+
+
+ // -- Processor and memory-system properties --
+
+ private static final ByteOrder byteOrder;
+
+ static ByteOrder byteOrder() {
+ // Android-removed: Android is always little-endian.
+ /*
+ if (byteOrder == null)
+ throw new Error("Unknown byte order");
+ */
+ return byteOrder;
+ }
+
+ static {
+ // BEGIN Android-changed: Android is always little-endian.
+ /*
+ long a = unsafe.allocateMemory(8);
+ try {
+ unsafe.putLong(a, 0x0102030405060708L);
+ byte b = unsafe.getByte(a);
+ switch (b) {
+ case 0x01: byteOrder = ByteOrder.BIG_ENDIAN; break;
+ case 0x08: byteOrder = ByteOrder.LITTLE_ENDIAN; break;
+ default:
+ assert false;
+ byteOrder = null;
+ }
+ } finally {
+ unsafe.freeMemory(a);
+ }
+ */
+ byteOrder = ByteOrder.LITTLE_ENDIAN;
+ // END Android-changed: Android is always little-endian.
+ }
+
+
+ private static int pageSize = -1;
+
+ static int pageSize() {
+ if (pageSize == -1)
+ pageSize = unsafe().pageSize();
+ return pageSize;
+ }
+
+ static int pageCount(long size) {
+ return (int)(size + (long)pageSize() - 1L) / pageSize();
+ }
+
+ private static boolean unaligned;
+ private static boolean unalignedKnown = false;
+
+ static boolean unaligned() {
+ if (unalignedKnown)
+ return unaligned;
+ String arch = AccessController.doPrivileged(
+ new sun.security.action.GetPropertyAction("os.arch"));
+ unaligned = arch.equals("i386") || arch.equals("x86")
+ || arch.equals("amd64") || arch.equals("x86_64");
+ unalignedKnown = true;
+ return unaligned;
+ }
+
+
+ // -- Direct memory management --
+
+ // BEGIN Android-removed: Direct memory management unused on Android.
+ /*
+ // A user-settable upper limit on the maximum amount of allocatable
+ // direct buffer memory. This value may be changed during VM
+ // initialization if it is launched with "-XX:MaxDirectMemorySize=<size>".
+ private static volatile long maxMemory = VM.maxDirectMemory();
+ private static final AtomicLong reservedMemory = new AtomicLong();
+ private static final AtomicLong totalCapacity = new AtomicLong();
+ private static final AtomicLong count = new AtomicLong();
+ private static volatile boolean memoryLimitSet = false;
+ // max. number of sleeps during try-reserving with exponentially
+ // increasing delay before throwing OutOfMemoryError:
+ // 1, 2, 4, 8, 16, 32, 64, 128, 256 (total 511 ms ~ 0.5 s)
+ // which means that OOME will be thrown after 0.5 s of trying
+ private static final int MAX_SLEEPS = 9;
+
+ // These methods should be called whenever direct memory is allocated or
+ // freed. They allow the user to control the amount of direct memory
+ // which a process may access. All sizes are specified in bytes.
+ static void reserveMemory(long size, int cap) {
+
+ if (!memoryLimitSet && VM.isBooted()) {
+ maxMemory = VM.maxDirectMemory();
+ memoryLimitSet = true;
+ }
+
+ // optimist!
+ if (tryReserveMemory(size, cap)) {
+ return;
+ }
+
+ final JavaLangRefAccess jlra = SharedSecrets.getJavaLangRefAccess();
+
+ // retry while helping enqueue pending Reference objects
+ // which includes executing pending Cleaner(s) which includes
+ // Cleaner(s) that free direct buffer memory
+ while (jlra.tryHandlePendingReference()) {
+ if (tryReserveMemory(size, cap)) {
+ return;
+ }
+ }
+
+ // trigger VM's Reference processing
+ System.gc();
+
+ // a retry loop with exponential back-off delays
+ // (this gives VM some time to do it's job)
+ boolean interrupted = false;
+ try {
+ long sleepTime = 1;
+ int sleeps = 0;
+ while (true) {
+ if (tryReserveMemory(size, cap)) {
+ return;
+ }
+ if (sleeps >= MAX_SLEEPS) {
+ break;
+ }
+ if (!jlra.tryHandlePendingReference()) {
+ try {
+ Thread.sleep(sleepTime);
+ sleepTime <<= 1;
+ sleeps++;
+ } catch (InterruptedException e) {
+ interrupted = true;
+ }
+ }
+ }
+
+ // no luck
+ throw new OutOfMemoryError("Direct buffer memory");
+
+ } finally {
+ if (interrupted) {
+ // don't swallow interrupts
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+
+ private static boolean tryReserveMemory(long size, int cap) {
+
+ // -XX:MaxDirectMemorySize limits the total capacity rather than the
+ // actual memory usage, which will differ when buffers are page
+ // aligned.
+ long totalCap;
+ while (cap <= maxMemory - (totalCap = totalCapacity.get())) {
+ if (totalCapacity.compareAndSet(totalCap, totalCap + cap)) {
+ reservedMemory.addAndGet(size);
+ count.incrementAndGet();
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+
+ static void unreserveMemory(long size, int cap) {
+ long cnt = count.decrementAndGet();
+ long reservedMem = reservedMemory.addAndGet(-size);
+ long totalCap = totalCapacity.addAndGet(-cap);
+ assert cnt >= 0 && reservedMem >= 0 && totalCap >= 0;
+ }
+ */
+ // END Android-removed: Direct memory management unused on Android.
+
+ // -- Monitoring of direct buffer usage --
+
+ // BEGIN Android-removed: Remove support for java.lang.management.
+ /*
+ static {
+ // setup access to this package in SharedSecrets
+ sun.misc.SharedSecrets.setJavaNioAccess(
+ new sun.misc.JavaNioAccess() {
+ @Override
+ public sun.misc.JavaNioAccess.BufferPool getDirectBufferPool() {
+ return new sun.misc.JavaNioAccess.BufferPool() {
+ @Override
+ public String getName() {
+ return "direct";
+ }
+ @Override
+ public long getCount() {
+ return Bits.count.get();
+ }
+ @Override
+ public long getTotalCapacity() {
+ return Bits.totalCapacity.get();
+ }
+ @Override
+ public long getMemoryUsed() {
+ return Bits.reservedMemory.get();
+ }
+ };
+ }
+ @Override
+ public ByteBuffer newDirectByteBuffer(long addr, int cap, Object ob) {
+ return new DirectByteBuffer(addr, cap, ob);
+ }
+ @Override
+ public void truncate(Buffer buf) {
+ buf.truncate();
+ }
+ });
+ }
+ */
+ // END Android-removed: Remove support for java.lang.management.
+
+ // BEGIN Android-removed: Bulk get/put methods are unused on Android.
+ /*
+
+ // -- Bulk get/put acceleration --
+
+ // These numbers represent the point at which we have empirically
+ // determined that the average cost of a JNI call exceeds the expense
+ // of an element by element copy. These numbers may change over time.
+ static final int JNI_COPY_TO_ARRAY_THRESHOLD = 6;
+ static final int JNI_COPY_FROM_ARRAY_THRESHOLD = 6;
+
+ // This number limits the number of bytes to copy per call to Unsafe's
+ // copyMemory method. A limit is imposed to allow for safepoint polling
+ // during a large copy
+ static final long UNSAFE_COPY_THRESHOLD = 1024L * 1024L;
+
+ // These methods do no bounds checking. Verification that the copy will not
+ // result in memory corruption should be done prior to invocation.
+ // All positions and lengths are specified in bytes.
+
+ /**
+ * Copy from given source array to destination address.
+ *
+ * @param src
+ * source array
+ * @param srcBaseOffset
+ * offset of first element of storage in source array
+ * @param srcPos
+ * offset within source array of the first element to read
+ * @param dstAddr
+ * destination address
+ * @param length
+ * number of bytes to copy
+ *
+ static void copyFromArray(Object src, long srcBaseOffset, long srcPos,
+ long dstAddr, long length)
+ {
+ long offset = srcBaseOffset + srcPos;
+ while (length > 0) {
+ long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length;
+ unsafe.copyMemory(src, offset, null, dstAddr, size);
+ length -= size;
+ offset += size;
+ dstAddr += size;
+ }
+ }
+
+ /**
+ * Copy from source address into given destination array.
+ *
+ * @param srcAddr
+ * source address
+ * @param dst
+ * destination array
+ * @param dstBaseOffset
+ * offset of first element of storage in destination array
+ * @param dstPos
+ * offset within destination array of the first element to write
+ * @param length
+ * number of bytes to copy
+ *
+ static void copyToArray(long srcAddr, Object dst, long dstBaseOffset, long dstPos,
+ long length)
+ {
+ long offset = dstBaseOffset + dstPos;
+ while (length > 0) {
+ long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length;
+ unsafe.copyMemory(null, srcAddr, dst, offset, size);
+ length -= size;
+ srcAddr += size;
+ offset += size;
+ }
+ }
+
+ static void copyFromCharArray(Object src, long srcPos, long dstAddr,
+ long length)
+ {
+ copyFromShortArray(src, srcPos, dstAddr, length);
+ }
+
+ static void copyToCharArray(long srcAddr, Object dst, long dstPos,
+ long length)
+ {
+ copyToShortArray(srcAddr, dst, dstPos, length);
+ }
+
+ static native void copyFromShortArray(Object src, long srcPos, long dstAddr,
+ long length);
+ static native void copyToShortArray(long srcAddr, Object dst, long dstPos,
+ long length);
+
+ static native void copyFromIntArray(Object src, long srcPos, long dstAddr,
+ long length);
+ static native void copyToIntArray(long srcAddr, Object dst, long dstPos,
+ long length);
+
+ static native void copyFromLongArray(Object src, long srcPos, long dstAddr,
+ long length);
+ static native void copyToLongArray(long srcAddr, Object dst, long dstPos,
+ long length);
+ */
+ // END Android-removed: Bulk get/put methods are unused on Android.
+}
diff --git a/java/nio/Buffer.java b/java/nio/Buffer.java
new file mode 100644
index 0000000..e517560
--- /dev/null
+++ b/java/nio/Buffer.java
@@ -0,0 +1,601 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio;
+
+import java.util.Spliterator;
+
+/**
+ * A container for data of a specific primitive type.
+ *
+ * <p> A buffer is a linear, finite sequence of elements of a specific
+ * primitive type. Aside from its content, the essential properties of a
+ * buffer are its capacity, limit, and position: </p>
+ *
+ * <blockquote>
+ *
+ * <p> A buffer's <i>capacity</i> is the number of elements it contains. The
+ * capacity of a buffer is never negative and never changes. </p>
+ *
+ * <p> A buffer's <i>limit</i> is the index of the first element that should
+ * not be read or written. A buffer's limit is never negative and is never
+ * greater than its capacity. </p>
+ *
+ * <p> A buffer's <i>position</i> is the index of the next element to be
+ * read or written. A buffer's position is never negative and is never
+ * greater than its limit. </p>
+ *
+ * </blockquote>
+ *
+ * <p> There is one subclass of this class for each non-boolean primitive type.
+ *
+ *
+ * <h2> Transferring data </h2>
+ *
+ * <p> Each subclass of this class defines two categories of <i>get</i> and
+ * <i>put</i> operations: </p>
+ *
+ * <blockquote>
+ *
+ * <p> <i>Relative</i> operations read or write one or more elements starting
+ * at the current position and then increment the position by the number of
+ * elements transferred. If the requested transfer exceeds the limit then a
+ * relative <i>get</i> operation throws a {@link BufferUnderflowException}
+ * and a relative <i>put</i> operation throws a {@link
+ * BufferOverflowException}; in either case, no data is transferred. </p>
+ *
+ * <p> <i>Absolute</i> operations take an explicit element index and do not
+ * affect the position. Absolute <i>get</i> and <i>put</i> operations throw
+ * an {@link IndexOutOfBoundsException} if the index argument exceeds the
+ * limit. </p>
+ *
+ * </blockquote>
+ *
+ * <p> Data may also, of course, be transferred in to or out of a buffer by the
+ * I/O operations of an appropriate channel, which are always relative to the
+ * current position.
+ *
+ *
+ * <h2> Marking and resetting </h2>
+ *
+ * <p> A buffer's <i>mark</i> is the index to which its position will be reset
+ * when the {@link #reset reset} method is invoked. The mark is not always
+ * defined, but when it is defined it is never negative and is never greater
+ * than the position. If the mark is defined then it is discarded when the
+ * position or the limit is adjusted to a value smaller than the mark. If the
+ * mark is not defined then invoking the {@link #reset reset} method causes an
+ * {@link InvalidMarkException} to be thrown.
+ *
+ *
+ * <h2> Invariants </h2>
+ *
+ * <p> The following invariant holds for the mark, position, limit, and
+ * capacity values:
+ *
+ * <blockquote>
+ * <tt>0</tt> <tt><=</tt>
+ * <i>mark</i> <tt><=</tt>
+ * <i>position</i> <tt><=</tt>
+ * <i>limit</i> <tt><=</tt>
+ * <i>capacity</i>
+ * </blockquote>
+ *
+ * <p> A newly-created buffer always has a position of zero and a mark that is
+ * undefined. The initial limit may be zero, or it may be some other value
+ * that depends upon the type of the buffer and the manner in which it is
+ * constructed. Each element of a newly-allocated buffer is initialized
+ * to zero.
+ *
+ *
+ * <h2> Clearing, flipping, and rewinding </h2>
+ *
+ * <p> In addition to methods for accessing the position, limit, and capacity
+ * values and for marking and resetting, this class also defines the following
+ * operations upon buffers:
+ *
+ * <ul>
+ *
+ * <li><p> {@link #clear} makes a buffer ready for a new sequence of
+ * channel-read or relative <i>put</i> operations: It sets the limit to the
+ * capacity and the position to zero. </p></li>
+ *
+ * <li><p> {@link #flip} makes a buffer ready for a new sequence of
+ * channel-write or relative <i>get</i> operations: It sets the limit to the
+ * current position and then sets the position to zero. </p></li>
+ *
+ * <li><p> {@link #rewind} makes a buffer ready for re-reading the data that
+ * it already contains: It leaves the limit unchanged and sets the position
+ * to zero. </p></li>
+ *
+ * </ul>
+ *
+ *
+ * <h2> Read-only buffers </h2>
+ *
+ * <p> Every buffer is readable, but not every buffer is writable. The
+ * mutation methods of each buffer class are specified as <i>optional
+ * operations</i> that will throw a {@link ReadOnlyBufferException} when
+ * invoked upon a read-only buffer. A read-only buffer does not allow its
+ * content to be changed, but its mark, position, and limit values are mutable.
+ * Whether or not a buffer is read-only may be determined by invoking its
+ * {@link #isReadOnly isReadOnly} method.
+ *
+ *
+ * <h2> Thread safety </h2>
+ *
+ * <p> Buffers are not safe for use by multiple concurrent threads. If a
+ * buffer is to be used by more than one thread then access to the buffer
+ * should be controlled by appropriate synchronization.
+ *
+ *
+ * <h2> Invocation chaining </h2>
+ *
+ * <p> Methods in this class that do not otherwise have a value to return are
+ * specified to return the buffer upon which they are invoked. This allows
+ * method invocations to be chained; for example, the sequence of statements
+ *
+ * <blockquote><pre>
+ * b.flip();
+ * b.position(23);
+ * b.limit(42);</pre></blockquote>
+ *
+ * can be replaced by the single, more compact statement
+ *
+ * <blockquote><pre>
+ * b.flip().position(23).limit(42);</pre></blockquote>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class Buffer {
+
+ /**
+ * The characteristics of Spliterators that traverse and split elements
+ * maintained in Buffers.
+ */
+ static final int SPLITERATOR_CHARACTERISTICS =
+ Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED;
+
+ // Invariants: mark <= position <= limit <= capacity
+ private int mark = -1;
+ // Android-changed: position field non-private for use by Android's nio implementation classes.
+ int position = 0;
+ private int limit;
+ private int capacity;
+
+ // Used only by direct buffers
+ // NOTE: hoisted here for speed in JNI GetDirectBufferAddress
+ long address;
+
+ // Android-added: _elementSizeShift field for NIOAccess class and framework native code.
+ /**
+ * The log base 2 of the element size of this buffer. Each typed subclass
+ * (ByteBuffer, CharBuffer, etc.) is responsible for initializing this
+ * value. The value is used by JNI code in frameworks/base/ to avoid the
+ * need for costly 'instanceof' tests.
+ */
+ final int _elementSizeShift;
+
+ // Creates a new buffer with the given mark, position, limit, and capacity,
+ // after checking invariants.
+ //
+ // Android-added: _elementSizeShift field for NIOAccess class and framework native code.
+ Buffer(int mark, int pos, int lim, int cap, int elementSizeShift) { // package-private
+ if (cap < 0)
+ throw new IllegalArgumentException("Negative capacity: " + cap);
+ this.capacity = cap;
+ limit(lim);
+ position(pos);
+ if (mark >= 0) {
+ if (mark > pos)
+ throw new IllegalArgumentException("mark > position: ("
+ + mark + " > " + pos + ")");
+ this.mark = mark;
+ }
+ // Android-added: _elementSizeShift field for NIOAccess class and framework native code.
+ _elementSizeShift = elementSizeShift;
+ }
+
+ /**
+ * Returns this buffer's capacity.
+ *
+ * @return The capacity of this buffer
+ */
+ public final int capacity() {
+ return capacity;
+ }
+
+ /**
+ * Returns this buffer's position.
+ *
+ * @return The position of this buffer
+ */
+ public final int position() {
+ return position;
+ }
+
+ /**
+ * Sets this buffer's position. If the mark is defined and larger than the
+ * new position then it is discarded.
+ *
+ * @param newPosition
+ * The new position value; must be non-negative
+ * and no larger than the current limit
+ *
+ * @return This buffer
+ *
+ * @throws IllegalArgumentException
+ * If the preconditions on <tt>newPosition</tt> do not hold
+ */
+ public Buffer position(int newPosition) {
+ if ((newPosition > limit) || (newPosition < 0))
+ // Android-changed: Improved error message.
+ throw new IllegalArgumentException("Bad position " + newPosition + "/" + limit);
+ position = newPosition;
+ if (mark > position) mark = -1;
+ return this;
+ }
+
+ /**
+ * Returns this buffer's limit.
+ *
+ * @return The limit of this buffer
+ */
+ public final int limit() {
+ return limit;
+ }
+
+ /**
+ * Sets this buffer's limit. If the position is larger than the new limit
+ * then it is set to the new limit. If the mark is defined and larger than
+ * the new limit then it is discarded.
+ *
+ * @param newLimit
+ * The new limit value; must be non-negative
+ * and no larger than this buffer's capacity
+ *
+ * @return This buffer
+ *
+ * @throws IllegalArgumentException
+ * If the preconditions on <tt>newLimit</tt> do not hold
+ */
+ public Buffer limit(int newLimit) {
+ if ((newLimit > capacity) || (newLimit < 0))
+ throw new IllegalArgumentException();
+ limit = newLimit;
+ if (position > limit) position = limit;
+ if (mark > limit) mark = -1;
+ return this;
+ }
+
+ /**
+ * Sets this buffer's mark at its position.
+ *
+ * @return This buffer
+ */
+ public Buffer mark() {
+ mark = position;
+ return this;
+ }
+
+ /**
+ * Resets this buffer's position to the previously-marked position.
+ *
+ * <p> Invoking this method neither changes nor discards the mark's
+ * value. </p>
+ *
+ * @return This buffer
+ *
+ * @throws InvalidMarkException
+ * If the mark has not been set
+ */
+ public Buffer reset() {
+ int m = mark;
+ if (m < 0)
+ throw new InvalidMarkException();
+ position = m;
+ return this;
+ }
+
+ /**
+ * Clears this buffer. The position is set to zero, the limit is set to
+ * the capacity, and the mark is discarded.
+ *
+ * <p> Invoke this method before using a sequence of channel-read or
+ * <i>put</i> operations to fill this buffer. For example:
+ *
+ * <blockquote><pre>
+ * buf.clear(); // Prepare buffer for reading
+ * in.read(buf); // Read data</pre></blockquote>
+ *
+ * <p> This method does not actually erase the data in the buffer, but it
+ * is named as if it did because it will most often be used in situations
+ * in which that might as well be the case. </p>
+ *
+ * @return This buffer
+ */
+ public Buffer clear() {
+ position = 0;
+ limit = capacity;
+ mark = -1;
+ return this;
+ }
+
+ /**
+ * Flips this buffer. The limit is set to the current position and then
+ * the position is set to zero. If the mark is defined then it is
+ * discarded.
+ *
+ * <p> After a sequence of channel-read or <i>put</i> operations, invoke
+ * this method to prepare for a sequence of channel-write or relative
+ * <i>get</i> operations. For example:
+ *
+ * <blockquote><pre>
+ * buf.put(magic); // Prepend header
+ * in.read(buf); // Read data into rest of buffer
+ * buf.flip(); // Flip buffer
+ * out.write(buf); // Write header + data to channel</pre></blockquote>
+ *
+ * <p> This method is often used in conjunction with the {@link
+ * java.nio.ByteBuffer#compact compact} method when transferring data from
+ * one place to another. </p>
+ *
+ * @return This buffer
+ */
+ public Buffer flip() {
+ limit = position;
+ position = 0;
+ mark = -1;
+ return this;
+ }
+
+ /**
+ * Rewinds this buffer. The position is set to zero and the mark is
+ * discarded.
+ *
+ * <p> Invoke this method before a sequence of channel-write or <i>get</i>
+ * operations, assuming that the limit has already been set
+ * appropriately. For example:
+ *
+ * <blockquote><pre>
+ * out.write(buf); // Write remaining data
+ * buf.rewind(); // Rewind buffer
+ * buf.get(array); // Copy data into array</pre></blockquote>
+ *
+ * @return This buffer
+ */
+ public Buffer rewind() {
+ position = 0;
+ mark = -1;
+ return this;
+ }
+
+ /**
+ * Returns the number of elements between the current position and the
+ * limit.
+ *
+ * @return The number of elements remaining in this buffer
+ */
+ public final int remaining() {
+ return limit - position;
+ }
+
+ /**
+ * Tells whether there are any elements between the current position and
+ * the limit.
+ *
+ * @return <tt>true</tt> if, and only if, there is at least one element
+ * remaining in this buffer
+ */
+ public final boolean hasRemaining() {
+ return position < limit;
+ }
+
+ /**
+ * Tells whether or not this buffer is read-only.
+ *
+ * @return <tt>true</tt> if, and only if, this buffer is read-only
+ */
+ public abstract boolean isReadOnly();
+
+ /**
+ * Tells whether or not this buffer is backed by an accessible
+ * array.
+ *
+ * <p> If this method returns <tt>true</tt> then the {@link #array() array}
+ * and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
+ * </p>
+ *
+ * @return <tt>true</tt> if, and only if, this buffer
+ * is backed by an array and is not read-only
+ *
+ * @since 1.6
+ */
+ public abstract boolean hasArray();
+
+ /**
+ * Returns the array that backs this
+ * buffer <i>(optional operation)</i>.
+ *
+ * <p> This method is intended to allow array-backed buffers to be
+ * passed to native code more efficiently. Concrete subclasses
+ * provide more strongly-typed return values for this method.
+ *
+ * <p> Modifications to this buffer's content will cause the returned
+ * array's content to be modified, and vice versa.
+ *
+ * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+ * method in order to ensure that this buffer has an accessible backing
+ * array. </p>
+ *
+ * @return The array that backs this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
+ *
+ * @since 1.6
+ */
+ public abstract Object array();
+
+ /**
+ * Returns the offset within this buffer's backing array of the first
+ * element of the buffer <i>(optional operation)</i>.
+ *
+ * <p> If this buffer is backed by an array then buffer position <i>p</i>
+ * corresponds to array index <i>p</i> + <tt>arrayOffset()</tt>.
+ *
+ * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+ * method in order to ensure that this buffer has an accessible backing
+ * array. </p>
+ *
+ * @return The offset within this buffer's array
+ * of the first element of the buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
+ *
+ * @since 1.6
+ */
+ public abstract int arrayOffset();
+
+ /**
+ * Tells whether or not this buffer is
+ * <a href="ByteBuffer.html#direct"><i>direct</i></a>.
+ *
+ * @return <tt>true</tt> if, and only if, this buffer is direct
+ *
+ * @since 1.6
+ */
+ public abstract boolean isDirect();
+
+
+ // -- Package-private methods for bounds checking, etc. --
+
+ /**
+ * Checks the current position against the limit, throwing a {@link
+ * BufferUnderflowException} if it is not smaller than the limit, and then
+ * increments the position.
+ *
+ * @return The current position value, before it is incremented
+ */
+ final int nextGetIndex() { // package-private
+ if (position >= limit)
+ throw new BufferUnderflowException();
+ return position++;
+ }
+
+ final int nextGetIndex(int nb) { // package-private
+ if (limit - position < nb)
+ throw new BufferUnderflowException();
+ int p = position;
+ position += nb;
+ return p;
+ }
+
+ /**
+ * Checks the current position against the limit, throwing a {@link
+ * BufferOverflowException} if it is not smaller than the limit, and then
+ * increments the position.
+ *
+ * @return The current position value, before it is incremented
+ */
+ final int nextPutIndex() { // package-private
+ if (position >= limit)
+ throw new BufferOverflowException();
+ return position++;
+ }
+
+ final int nextPutIndex(int nb) { // package-private
+ if (limit - position < nb)
+ throw new BufferOverflowException();
+ int p = position;
+ position += nb;
+ return p;
+ }
+
+ /**
+ * Checks the given index against the limit, throwing an {@link
+ * IndexOutOfBoundsException} if it is not smaller than the limit
+ * or is smaller than zero.
+ */
+ final int checkIndex(int i) { // package-private
+ if ((i < 0) || (i >= limit))
+ // Android-changed: Add bounds details to exception.
+ throw new IndexOutOfBoundsException(
+ "index=" + i + " out of bounds (limit=" + limit + ")");
+ return i;
+ }
+
+ final int checkIndex(int i, int nb) { // package-private
+ if ((i < 0) || (nb > limit - i))
+ // Android-changed: Add bounds details to exception.
+ throw new IndexOutOfBoundsException(
+ "index=" + i + " out of bounds (limit=" + limit + ", nb=" + nb + ")");
+ return i;
+ }
+
+ final int markValue() { // package-private
+ return mark;
+ }
+
+ final void truncate() { // package-private
+ mark = -1;
+ position = 0;
+ limit = 0;
+ capacity = 0;
+ }
+
+ final void discardMark() { // package-private
+ mark = -1;
+ }
+
+ static void checkBounds(int off, int len, int size) { // package-private
+ if ((off | len | (off + len) | (size - (off + len))) < 0)
+ // Android-changed: Add bounds details to exception.
+ throw new IndexOutOfBoundsException(
+ "off=" + off + ", len=" + len + " out of bounds (size=" + size + ")");
+ }
+
+ // Android-added: getElementSizeShift() method for testing.
+ /**
+ * For testing only. This field is accessed directly via JNI from frameworks code.
+ *
+ * @hide
+ */
+ public int getElementSizeShift() {
+ return _elementSizeShift;
+ }
+
+}
diff --git a/java/nio/BufferOverflowException.java b/java/nio/BufferOverflowException.java
new file mode 100644
index 0000000..d141a82
--- /dev/null
+++ b/java/nio/BufferOverflowException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio;
+
+
+/**
+ * Unchecked exception thrown when a relative <i>put</i> operation reaches
+ * the target buffer's limit.
+ *
+ * @since 1.4
+ */
+
+public class BufferOverflowException
+ extends RuntimeException
+{
+
+ private static final long serialVersionUID = -5484897634319144535L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public BufferOverflowException() { }
+
+}
diff --git a/java/nio/BufferUnderflowException.java b/java/nio/BufferUnderflowException.java
new file mode 100644
index 0000000..d7a062a
--- /dev/null
+++ b/java/nio/BufferUnderflowException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio;
+
+
+/**
+ * Unchecked exception thrown when a relative <i>get</i> operation reaches
+ * the source buffer's limit.
+ *
+ * @since 1.4
+ */
+
+public class BufferUnderflowException
+ extends RuntimeException
+{
+
+ private static final long serialVersionUID = -1713313658691622206L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public BufferUnderflowException() { }
+
+}
diff --git a/java/nio/ByteBuffer.annotated.java b/java/nio/ByteBuffer.annotated.java
new file mode 100644
index 0000000..d0caba2
--- /dev/null
+++ b/java/nio/ByteBuffer.annotated.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+
+package java.nio;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class ByteBuffer extends java.nio.Buffer implements java.lang.Comparable<java.nio.ByteBuffer> {
+
+ByteBuffer(int mark, int pos, int lim, int cap) { super(0, 0, 0, 0, 0); throw new RuntimeException("Stub!"); }
+
+public static java.nio.ByteBuffer allocateDirect(int capacity) { throw new RuntimeException("Stub!"); }
+
+public static java.nio.ByteBuffer allocate(int capacity) { throw new RuntimeException("Stub!"); }
+
+public static java.nio.ByteBuffer wrap(byte[] array, int offset, int length) { throw new RuntimeException("Stub!"); }
+
+public static java.nio.ByteBuffer wrap(byte[] array) { throw new RuntimeException("Stub!"); }
+
+public abstract java.nio.ByteBuffer slice();
+
+public abstract java.nio.ByteBuffer duplicate();
+
+public abstract java.nio.ByteBuffer asReadOnlyBuffer();
+
+public abstract byte get();
+
+public abstract java.nio.ByteBuffer put(byte b);
+
+public abstract byte get(int index);
+
+public abstract java.nio.ByteBuffer put(int index, byte b);
+
+public java.nio.ByteBuffer get(byte[] dst, int offset, int length) { throw new RuntimeException("Stub!"); }
+
+public java.nio.ByteBuffer get(byte[] dst) { throw new RuntimeException("Stub!"); }
+
+public java.nio.ByteBuffer put(java.nio.ByteBuffer src) { throw new RuntimeException("Stub!"); }
+
+public java.nio.ByteBuffer put(byte[] src, int offset, int length) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer put(byte[] src) { throw new RuntimeException("Stub!"); }
+
+public final boolean hasArray() { throw new RuntimeException("Stub!"); }
+
+public final byte[] array() { throw new RuntimeException("Stub!"); }
+
+public final int arrayOffset() { throw new RuntimeException("Stub!"); }
+
+public abstract java.nio.ByteBuffer compact();
+
+public abstract boolean isDirect();
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(java.lang.Object ob) { throw new RuntimeException("Stub!"); }
+
+public int compareTo(java.nio.ByteBuffer that) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteOrder order() { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer order(java.nio.ByteOrder bo) { throw new RuntimeException("Stub!"); }
+
+public abstract char getChar();
+
+public abstract java.nio.ByteBuffer putChar(char value);
+
+public abstract char getChar(int index);
+
+public abstract java.nio.ByteBuffer putChar(int index, char value);
+
+public abstract java.nio.CharBuffer asCharBuffer();
+
+public abstract short getShort();
+
+public abstract java.nio.ByteBuffer putShort(short value);
+
+public abstract short getShort(int index);
+
+public abstract java.nio.ByteBuffer putShort(int index, short value);
+
+public abstract java.nio.ShortBuffer asShortBuffer();
+
+public abstract int getInt();
+
+public abstract java.nio.ByteBuffer putInt(int value);
+
+public abstract int getInt(int index);
+
+public abstract java.nio.ByteBuffer putInt(int index, int value);
+
+public abstract java.nio.IntBuffer asIntBuffer();
+
+public abstract long getLong();
+
+public abstract java.nio.ByteBuffer putLong(long value);
+
+public abstract long getLong(int index);
+
+public abstract java.nio.ByteBuffer putLong(int index, long value);
+
+public abstract java.nio.LongBuffer asLongBuffer();
+
+public abstract float getFloat();
+
+public abstract java.nio.ByteBuffer putFloat(float value);
+
+public abstract float getFloat(int index);
+
+public abstract java.nio.ByteBuffer putFloat(int index, float value);
+
+public abstract java.nio.FloatBuffer asFloatBuffer();
+
+public abstract double getDouble();
+
+public abstract java.nio.ByteBuffer putDouble(double value);
+
+public abstract double getDouble(int index);
+
+public abstract java.nio.ByteBuffer putDouble(int index, double value);
+
+public abstract java.nio.DoubleBuffer asDoubleBuffer();
+
+public boolean isAccessible() { throw new RuntimeException("Stub!"); }
+
[email protected]
+public void setAccessible(boolean value) { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/java/nio/ByteBuffer.java b/java/nio/ByteBuffer.java
new file mode 100644
index 0000000..b286cbd
--- /dev/null
+++ b/java/nio/ByteBuffer.java
@@ -0,0 +1,1746 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio;
+
+import libcore.io.Memory;
+
+import dalvik.annotation.codegen.CovariantReturnType;
+
+/**
+ * A byte buffer.
+ *
+ * <p> This class defines six categories of operations upon
+ * byte buffers:
+ *
+ * <ul>
+ *
+ * <li><p> Absolute and relative {@link #get() <i>get</i>} and
+ * {@link #put(byte) <i>put</i>} methods that read and write
+ * single bytes; </p></li>
+ *
+ * <li><p> Relative {@link #get(byte[]) <i>bulk get</i>}
+ * methods that transfer contiguous sequences of bytes from this buffer
+ * into an array; </p></li>
+ *
+ * <li><p> Relative {@link #put(byte[]) <i>bulk put</i>}
+ * methods that transfer contiguous sequences of bytes from a
+ * byte array or some other byte
+ * buffer into this buffer; </p></li>
+ *
+ *
+ * <li><p> Absolute and relative {@link #getChar() <i>get</i>}
+ * and {@link #putChar(char) <i>put</i>} methods that read and
+ * write values of other primitive types, translating them to and from
+ * sequences of bytes in a particular byte order; </p></li>
+ *
+ * <li><p> Methods for creating <i><a href="#views">view buffers</a></i>,
+ * which allow a byte buffer to be viewed as a buffer containing values of
+ * some other primitive type; and </p></li>
+ *
+ *
+ * <li><p> Methods for {@link #compact compacting}, {@link
+ * #duplicate duplicating}, and {@link #slice slicing}
+ * a byte buffer. </p></li>
+ *
+ * </ul>
+ *
+ * <p> Byte buffers can be created either by {@link #allocate
+ * <i>allocation</i>}, which allocates space for the buffer's
+ *
+ *
+ * content, or by {@link #wrap(byte[]) <i>wrapping</i>} an
+ * existing byte array into a buffer.
+ *
+ *
+ *
+ * <a name="direct"></a>
+ * <h2> Direct <i>vs.</i> non-direct buffers </h2>
+ *
+ * <p> A byte buffer is either <i>direct</i> or <i>non-direct</i>. Given a
+ * direct byte buffer, the Java virtual machine will make a best effort to
+ * perform native I/O operations directly upon it. That is, it will attempt to
+ * avoid copying the buffer's content to (or from) an intermediate buffer
+ * before (or after) each invocation of one of the underlying operating
+ * system's native I/O operations.
+ *
+ * <p> A direct byte buffer may be created by invoking the {@link
+ * #allocateDirect(int) allocateDirect} factory method of this class. The
+ * buffers returned by this method typically have somewhat higher allocation
+ * and deallocation costs than non-direct buffers. The contents of direct
+ * buffers may reside outside of the normal garbage-collected heap, and so
+ * their impact upon the memory footprint of an application might not be
+ * obvious. It is therefore recommended that direct buffers be allocated
+ * primarily for large, long-lived buffers that are subject to the underlying
+ * system's native I/O operations. In general it is best to allocate direct
+ * buffers only when they yield a measureable gain in program performance.
+ *
+ * <p> A direct byte buffer may also be created by {@link
+ * java.nio.channels.FileChannel#map mapping} a region of a file
+ * directly into memory. An implementation of the Java platform may optionally
+ * support the creation of direct byte buffers from native code via JNI. If an
+ * instance of one of these kinds of buffers refers to an inaccessible region
+ * of memory then an attempt to access that region will not change the buffer's
+ * content and will cause an unspecified exception to be thrown either at the
+ * time of the access or at some later time.
+ *
+ * <p> Whether a byte buffer is direct or non-direct may be determined by
+ * invoking its {@link #isDirect isDirect} method. This method is provided so
+ * that explicit buffer management can be done in performance-critical code.
+ *
+ *
+ * <a name="bin"></a>
+ * <h2> Access to binary data </h2>
+ *
+ * <p> This class defines methods for reading and writing values of all other
+ * primitive types, except <tt>boolean</tt>. Primitive values are translated
+ * to (or from) sequences of bytes according to the buffer's current byte
+ * order, which may be retrieved and modified via the {@link #order order}
+ * methods. Specific byte orders are represented by instances of the {@link
+ * ByteOrder} class. The initial order of a byte buffer is always {@link
+ * ByteOrder#BIG_ENDIAN BIG_ENDIAN}.
+ *
+ * <p> For access to heterogeneous binary data, that is, sequences of values of
+ * different types, this class defines a family of absolute and relative
+ * <i>get</i> and <i>put</i> methods for each type. For 32-bit floating-point
+ * values, for example, this class defines:
+ *
+ * <blockquote><pre>
+ * float {@link #getFloat()}
+ * float {@link #getFloat(int) getFloat(int index)}
+ * void {@link #putFloat(float) putFloat(float f)}
+ * void {@link #putFloat(int,float) putFloat(int index, float f)}</pre></blockquote>
+ *
+ * <p> Corresponding methods are defined for the types <tt>char</tt>,
+ * <tt>short</tt>, <tt>int</tt>, <tt>long</tt>, and <tt>double</tt>. The index
+ * parameters of the absolute <i>get</i> and <i>put</i> methods are in terms of
+ * bytes rather than of the type being read or written.
+ *
+ * <a name="views"></a>
+ *
+ * <p> For access to homogeneous binary data, that is, sequences of values of
+ * the same type, this class defines methods that can create <i>views</i> of a
+ * given byte buffer. A <i>view buffer</i> is simply another buffer whose
+ * content is backed by the byte buffer. Changes to the byte buffer's content
+ * will be visible in the view buffer, and vice versa; the two buffers'
+ * position, limit, and mark values are independent. The {@link
+ * #asFloatBuffer() asFloatBuffer} method, for example, creates an instance of
+ * the {@link FloatBuffer} class that is backed by the byte buffer upon which
+ * the method is invoked. Corresponding view-creation methods are defined for
+ * the types <tt>char</tt>, <tt>short</tt>, <tt>int</tt>, <tt>long</tt>, and
+ * <tt>double</tt>.
+ *
+ * <p> View buffers have three important advantages over the families of
+ * type-specific <i>get</i> and <i>put</i> methods described above:
+ *
+ * <ul>
+ *
+ * <li><p> A view buffer is indexed not in terms of bytes but rather in terms
+ * of the type-specific size of its values; </p></li>
+ *
+ * <li><p> A view buffer provides relative bulk <i>get</i> and <i>put</i>
+ * methods that can transfer contiguous sequences of values between a buffer
+ * and an array or some other buffer of the same type; and </p></li>
+ *
+ * <li><p> A view buffer is potentially much more efficient because it will
+ * be direct if, and only if, its backing byte buffer is direct. </p></li>
+ *
+ * </ul>
+ *
+ * <p> The byte order of a view buffer is fixed to be that of its byte buffer
+ * at the time that the view is created. </p>
+ *
+*
+*
+ *
+ * <h2> Invocation chaining </h2>
+ *
+ * <p> Methods in this class that do not otherwise have a value to return are
+ * specified to return the buffer upon which they are invoked. This allows
+ * method invocations to be chained.
+ *
+ *
+ * The sequence of statements
+ *
+ * <blockquote><pre>
+ * bb.putInt(0xCAFEBABE);
+ * bb.putShort(3);
+ * bb.putShort(45);</pre></blockquote>
+ *
+ * can, for example, be replaced by the single statement
+ *
+ * <blockquote><pre>
+ * bb.putInt(0xCAFEBABE).putShort(3).putShort(45);</pre></blockquote>
+ *
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class ByteBuffer
+ extends Buffer
+ implements Comparable<ByteBuffer>
+{
+
+ // These fields are declared here rather than in Heap-X-Buffer in order to
+ // reduce the number of virtual method invocations needed to access these
+ // values, which is especially costly when coding small buffers.
+ //
+ final byte[] hb; // Non-null only for heap buffers
+ final int offset;
+ boolean isReadOnly; // Valid only for heap buffers
+
+ // Creates a new buffer with the given mark, position, limit, capacity,
+ // backing array, and array offset
+ //
+ ByteBuffer(int mark, int pos, int lim, int cap, // package-private
+ byte[] hb, int offset)
+ {
+ // Android-added: elementSizeShift parameter (log2 of element size).
+ super(mark, pos, lim, cap, 0 /* elementSizeShift */);
+ this.hb = hb;
+ this.offset = offset;
+ }
+
+ // Creates a new buffer with the given mark, position, limit, and capacity
+ //
+ ByteBuffer(int mark, int pos, int lim, int cap) { // package-private
+ this(mark, pos, lim, cap, null, 0);
+ }
+
+
+ /**
+ * Allocates a new direct byte buffer.
+ *
+ * <p> The new buffer's position will be zero, its limit will be its
+ * capacity, its mark will be undefined, and each of its elements will be
+ * initialized to zero. Whether or not it has a
+ * {@link #hasArray backing array} is unspecified.
+ *
+ * @param capacity
+ * The new buffer's capacity, in bytes
+ *
+ * @return The new byte buffer
+ *
+ * @throws IllegalArgumentException
+ * If the <tt>capacity</tt> is a negative integer
+ */
+ public static ByteBuffer allocateDirect(int capacity) {
+ // Android-changed: Android's DirectByteBuffers carry a MemoryRef.
+ // return new DirectByteBuffer(capacity);
+ DirectByteBuffer.MemoryRef memoryRef = new DirectByteBuffer.MemoryRef(capacity);
+ return new DirectByteBuffer(capacity, memoryRef);
+ }
+
+
+ /**
+ * Allocates a new byte buffer.
+ *
+ * <p> The new buffer's position will be zero, its limit will be its
+ * capacity, its mark will be undefined, and each of its elements will be
+ * initialized to zero. It will have a {@link #array backing array},
+ * and its {@link #arrayOffset array offset} will be zero.
+ *
+ * @param capacity
+ * The new buffer's capacity, in bytes
+ *
+ * @return The new byte buffer
+ *
+ * @throws IllegalArgumentException
+ * If the <tt>capacity</tt> is a negative integer
+ */
+ public static ByteBuffer allocate(int capacity) {
+ if (capacity < 0)
+ throw new IllegalArgumentException();
+ return new HeapByteBuffer(capacity, capacity);
+ }
+
+ /**
+ * Wraps a byte array into a buffer.
+ *
+ * <p> The new buffer will be backed by the given byte array;
+ * that is, modifications to the buffer will cause the array to be modified
+ * and vice versa. The new buffer's capacity will be
+ * <tt>array.length</tt>, its position will be <tt>offset</tt>, its limit
+ * will be <tt>offset + length</tt>, and its mark will be undefined. Its
+ * {@link #array backing array} will be the given array, and
+ * its {@link #arrayOffset array offset} will be zero. </p>
+ *
+ * @param array
+ * The array that will back the new buffer
+ *
+ * @param offset
+ * The offset of the subarray to be used; must be non-negative and
+ * no larger than <tt>array.length</tt>. The new buffer's position
+ * will be set to this value.
+ *
+ * @param length
+ * The length of the subarray to be used;
+ * must be non-negative and no larger than
+ * <tt>array.length - offset</tt>.
+ * The new buffer's limit will be set to <tt>offset + length</tt>.
+ *
+ * @return The new byte buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ */
+ public static ByteBuffer wrap(byte[] array,
+ int offset, int length)
+ {
+ try {
+ return new HeapByteBuffer(array, offset, length);
+ } catch (IllegalArgumentException x) {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+
+ /**
+ * Wraps a byte array into a buffer.
+ *
+ * <p> The new buffer will be backed by the given byte array;
+ * that is, modifications to the buffer will cause the array to be modified
+ * and vice versa. The new buffer's capacity and limit will be
+ * <tt>array.length</tt>, its position will be zero, and its mark will be
+ * undefined. Its {@link #array backing array} will be the
+ * given array, and its {@link #arrayOffset array offset>} will
+ * be zero. </p>
+ *
+ * @param array
+ * The array that will back this buffer
+ *
+ * @return The new byte buffer
+ */
+ public static ByteBuffer wrap(byte[] array) {
+ return wrap(array, 0, array.length);
+ }
+
+
+ /**
+ * Creates a new byte buffer whose content is a shared subsequence of
+ * this buffer's content.
+ *
+ * <p> The content of the new buffer will start at this buffer's current
+ * position. Changes to this buffer's content will be visible in the new
+ * buffer, and vice versa; the two buffers' position, limit, and mark
+ * values will be independent.
+ *
+ * <p> The new buffer's position will be zero, its capacity and its limit
+ * will be the number of bytes remaining in this buffer, and its mark
+ * will be undefined. The new buffer will be direct if, and only if, this
+ * buffer is direct, and it will be read-only if, and only if, this buffer
+ * is read-only. </p>
+ *
+ * @return The new byte buffer
+ */
+ public abstract ByteBuffer slice();
+
+ /**
+ * Creates a new byte buffer that shares this buffer's content.
+ *
+ * <p> The content of the new buffer will be that of this buffer. Changes
+ * to this buffer's content will be visible in the new buffer, and vice
+ * versa; the two buffers' position, limit, and mark values will be
+ * independent.
+ *
+ * <p> The new buffer's capacity, limit, position, and mark values will be
+ * identical to those of this buffer. The new buffer will be direct if,
+ * and only if, this buffer is direct, and it will be read-only if, and
+ * only if, this buffer is read-only. </p>
+ *
+ * @return The new byte buffer
+ */
+ public abstract ByteBuffer duplicate();
+
+ /**
+ * Creates a new, read-only byte buffer that shares this buffer's
+ * content.
+ *
+ * <p> The content of the new buffer will be that of this buffer. Changes
+ * to this buffer's content will be visible in the new buffer; the new
+ * buffer itself, however, will be read-only and will not allow the shared
+ * content to be modified. The two buffers' position, limit, and mark
+ * values will be independent.
+ *
+ * <p> The new buffer's capacity, limit, position, and mark values will be
+ * identical to those of this buffer.
+ *
+ * <p> If this buffer is itself read-only then this method behaves in
+ * exactly the same way as the {@link #duplicate duplicate} method. </p>
+ *
+ * @return The new, read-only byte buffer
+ */
+ public abstract ByteBuffer asReadOnlyBuffer();
+
+
+ // -- Singleton get/put methods --
+
+ /**
+ * Relative <i>get</i> method. Reads the byte at this buffer's
+ * current position, and then increments the position.
+ *
+ * @return The byte at the buffer's current position
+ *
+ * @throws BufferUnderflowException
+ * If the buffer's current position is not smaller than its limit
+ */
+ public abstract byte get();
+
+ /**
+ * Relative <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> Writes the given byte into this buffer at the current
+ * position, and then increments the position. </p>
+ *
+ * @param b
+ * The byte to be written
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If this buffer's current position is not smaller than its limit
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract ByteBuffer put(byte b);
+
+ /**
+ * Absolute <i>get</i> method. Reads the byte at the given
+ * index.
+ *
+ * @param index
+ * The index from which the byte will be read
+ *
+ * @return The byte at the given index
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
+ */
+ public abstract byte get(int index);
+
+ /**
+ * Absolute <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> Writes the given byte into this buffer at the given
+ * index. </p>
+ *
+ * @param index
+ * The index at which the byte will be written
+ *
+ * @param b
+ * The byte value to be written
+ *
+ * @return This buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract ByteBuffer put(int index, byte b);
+
+
+ // -- Bulk get operations --
+
+ /**
+ * Relative bulk <i>get</i> method.
+ *
+ * <p> This method transfers bytes from this buffer into the given
+ * destination array. If there are fewer bytes remaining in the
+ * buffer than are required to satisfy the request, that is, if
+ * <tt>length</tt> <tt>></tt> <tt>remaining()</tt>, then no
+ * bytes are transferred and a {@link BufferUnderflowException} is
+ * thrown.
+ *
+ * <p> Otherwise, this method copies <tt>length</tt> bytes from this
+ * buffer into the given array, starting at the current position of this
+ * buffer and at the given offset in the array. The position of this
+ * buffer is then incremented by <tt>length</tt>.
+ *
+ * <p> In other words, an invocation of this method of the form
+ * <tt>src.get(dst, off, len)</tt> has exactly the same effect as
+ * the loop
+ *
+ * <pre>{@code
+ * for (int i = off; i < off + len; i++)
+ * dst[i] = src.get();
+ * }</pre>
+ *
+ * except that it first checks that there are sufficient bytes in
+ * this buffer and it is potentially much more efficient.
+ *
+ * @param dst
+ * The array into which bytes are to be written
+ *
+ * @param offset
+ * The offset within the array of the first byte to be
+ * written; must be non-negative and no larger than
+ * <tt>dst.length</tt>
+ *
+ * @param length
+ * The maximum number of bytes to be written to the given
+ * array; must be non-negative and no larger than
+ * <tt>dst.length - offset</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than <tt>length</tt> bytes
+ * remaining in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ */
+ public ByteBuffer get(byte[] dst, int offset, int length) {
+ checkBounds(offset, length, dst.length);
+ if (length > remaining())
+ throw new BufferUnderflowException();
+ int end = offset + length;
+ for (int i = offset; i < end; i++)
+ dst[i] = get();
+ return this;
+ }
+
+ /**
+ * Relative bulk <i>get</i> method.
+ *
+ * <p> This method transfers bytes from this buffer into the given
+ * destination array. An invocation of this method of the form
+ * <tt>src.get(a)</tt> behaves in exactly the same way as the invocation
+ *
+ * <pre>
+ * src.get(a, 0, a.length) </pre>
+ *
+ * @param dst
+ * The destination array
+ *
+ * @return This buffer
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than <tt>length</tt> bytes
+ * remaining in this buffer
+ */
+ public ByteBuffer get(byte[] dst) {
+ return get(dst, 0, dst.length);
+ }
+
+
+ // -- Bulk put operations --
+
+ /**
+ * Relative bulk <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> This method transfers the bytes remaining in the given source
+ * buffer into this buffer. If there are more bytes remaining in the
+ * source buffer than in this buffer, that is, if
+ * <tt>src.remaining()</tt> <tt>></tt> <tt>remaining()</tt>,
+ * then no bytes are transferred and a {@link
+ * BufferOverflowException} is thrown.
+ *
+ * <p> Otherwise, this method copies
+ * <i>n</i> = <tt>src.remaining()</tt> bytes from the given
+ * buffer into this buffer, starting at each buffer's current position.
+ * The positions of both buffers are then incremented by <i>n</i>.
+ *
+ * <p> In other words, an invocation of this method of the form
+ * <tt>dst.put(src)</tt> has exactly the same effect as the loop
+ *
+ * <pre>
+ * while (src.hasRemaining())
+ * dst.put(src.get()); </pre>
+ *
+ * except that it first checks that there is sufficient space in this
+ * buffer and it is potentially much more efficient.
+ *
+ * @param src
+ * The source buffer from which bytes are to be read;
+ * must not be this buffer
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ * for the remaining bytes in the source buffer
+ *
+ * @throws IllegalArgumentException
+ * If the source buffer is this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public ByteBuffer put(ByteBuffer src) {
+ if (src == this)
+ throw new IllegalArgumentException();
+ if (isReadOnly())
+ throw new ReadOnlyBufferException();
+ int n = src.remaining();
+ if (n > remaining())
+ throw new BufferOverflowException();
+
+ // Android-changed: improve ByteBuffer.put(ByteBuffer) performance through bulk copy.
+ /*
+ for (int i = 0; i < n; i++)
+ put(src.get());
+ */
+ // Note that we use offset instead of arrayOffset because arrayOffset is specified to
+ // throw for read only buffers. Our use of arrayOffset here is provably safe, we only
+ // use it to read *from* readOnly buffers.
+ if (this.hb != null && src.hb != null) {
+ // System.arraycopy is intrinsified by ART and therefore tiny bit faster than memmove
+ System.arraycopy(src.hb, src.position() + src.offset, hb, position() + offset, n);
+ } else {
+ // Use the buffer object (and the raw memory address) if it's a direct buffer. Note that
+ // isDirect() doesn't imply !hasArray(), ByteBuffer.allocateDirect allocated buffer will
+ // have a backing, non-gc-movable byte array. JNI allocated direct byte buffers WILL NOT
+ // have a backing array.
+ final Object srcObject = src.isDirect() ? src : src.hb;
+ int srcOffset = src.position();
+ if (!src.isDirect()) {
+ srcOffset += src.offset;
+ }
+
+ final ByteBuffer dst = this;
+ final Object dstObject = dst.isDirect() ? dst : dst.hb;
+ int dstOffset = dst.position();
+ if (!dst.isDirect()) {
+ dstOffset += dst.offset;
+ }
+ Memory.memmove(dstObject, dstOffset, srcObject, srcOffset, n);
+ }
+ src.position(src.limit());
+ this.position(this.position() + n);
+ return this;
+ }
+
+ /**
+ * Relative bulk <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> This method transfers bytes into this buffer from the given
+ * source array. If there are more bytes to be copied from the array
+ * than remain in this buffer, that is, if
+ * <tt>length</tt> <tt>></tt> <tt>remaining()</tt>, then no
+ * bytes are transferred and a {@link BufferOverflowException} is
+ * thrown.
+ *
+ * <p> Otherwise, this method copies <tt>length</tt> bytes from the
+ * given array into this buffer, starting at the given offset in the array
+ * and at the current position of this buffer. The position of this buffer
+ * is then incremented by <tt>length</tt>.
+ *
+ * <p> In other words, an invocation of this method of the form
+ * <tt>dst.put(src, off, len)</tt> has exactly the same effect as
+ * the loop
+ *
+ * <pre>{@code
+ * for (int i = off; i < off + len; i++)
+ * dst.put(a[i]);
+ * }</pre>
+ *
+ * except that it first checks that there is sufficient space in this
+ * buffer and it is potentially much more efficient.
+ *
+ * @param src
+ * The array from which bytes are to be read
+ *
+ * @param offset
+ * The offset within the array of the first byte to be read;
+ * must be non-negative and no larger than <tt>array.length</tt>
+ *
+ * @param length
+ * The number of bytes to be read from the given array;
+ * must be non-negative and no larger than
+ * <tt>array.length - offset</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public ByteBuffer put(byte[] src, int offset, int length) {
+ checkBounds(offset, length, src.length);
+ if (length > remaining())
+ throw new BufferOverflowException();
+ int end = offset + length;
+ for (int i = offset; i < end; i++)
+ this.put(src[i]);
+ return this;
+ }
+
+ /**
+ * Relative bulk <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> This method transfers the entire content of the given source
+ * byte array into this buffer. An invocation of this method of the
+ * form <tt>dst.put(a)</tt> behaves in exactly the same way as the
+ * invocation
+ *
+ * <pre>
+ * dst.put(a, 0, a.length) </pre>
+ *
+ * @param src
+ * The source array
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public final ByteBuffer put(byte[] src) {
+ return put(src, 0, src.length);
+ }
+
+
+ // -- Other stuff --
+
+ /**
+ * Tells whether or not this buffer is backed by an accessible byte
+ * array.
+ *
+ * <p> If this method returns <tt>true</tt> then the {@link #array() array}
+ * and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
+ * </p>
+ *
+ * @return <tt>true</tt> if, and only if, this buffer
+ * is backed by an array and is not read-only
+ */
+ public final boolean hasArray() {
+ return (hb != null) && !isReadOnly;
+ }
+
+ /**
+ * Returns the byte array that backs this
+ * buffer <i>(optional operation)</i>.
+ *
+ * <p> Modifications to this buffer's content will cause the returned
+ * array's content to be modified, and vice versa.
+ *
+ * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+ * method in order to ensure that this buffer has an accessible backing
+ * array. </p>
+ *
+ * @return The array that backs this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
+ */
+ public final byte[] array() {
+ if (hb == null)
+ throw new UnsupportedOperationException();
+ if (isReadOnly)
+ throw new ReadOnlyBufferException();
+ return hb;
+ }
+
+ /**
+ * Returns the offset within this buffer's backing array of the first
+ * element of the buffer <i>(optional operation)</i>.
+ *
+ * <p> If this buffer is backed by an array then buffer position <i>p</i>
+ * corresponds to array index <i>p</i> + <tt>arrayOffset()</tt>.
+ *
+ * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+ * method in order to ensure that this buffer has an accessible backing
+ * array. </p>
+ *
+ * @return The offset within this buffer's array
+ * of the first element of the buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
+ */
+ public final int arrayOffset() {
+ if (hb == null)
+ throw new UnsupportedOperationException();
+ if (isReadOnly)
+ throw new ReadOnlyBufferException();
+ return offset;
+ }
+
+ // BEGIN Android-added: covariant overloads of *Buffer methods that return this.
+ @CovariantReturnType(returnType = ByteBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer position(int newPosition) {
+ return super.position(newPosition);
+ }
+
+ @CovariantReturnType(returnType = ByteBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer limit(int newLimit) {
+ return super.limit(newLimit);
+ }
+
+ @CovariantReturnType(returnType = ByteBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer mark() {
+ return super.mark();
+ }
+
+ @CovariantReturnType(returnType = ByteBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer reset() {
+ return super.reset();
+ }
+
+ @CovariantReturnType(returnType = ByteBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer clear() {
+ return super.clear();
+ }
+
+ @CovariantReturnType(returnType = ByteBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer flip() {
+ return super.flip();
+ }
+
+ @CovariantReturnType(returnType = ByteBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer rewind() {
+ return super.rewind();
+ }
+ // END Android-added: covariant overloads of *Buffer methods that return this.
+
+ /**
+ * Compacts this buffer <i>(optional operation)</i>.
+ *
+ * <p> The bytes between the buffer's current position and its limit,
+ * if any, are copied to the beginning of the buffer. That is, the
+ * byte at index <i>p</i> = <tt>position()</tt> is copied
+ * to index zero, the byte at index <i>p</i> + 1 is copied
+ * to index one, and so forth until the byte at index
+ * <tt>limit()</tt> - 1 is copied to index
+ * <i>n</i> = <tt>limit()</tt> - <tt>1</tt> - <i>p</i>.
+ * The buffer's position is then set to <i>n+1</i> and its limit is set to
+ * its capacity. The mark, if defined, is discarded.
+ *
+ * <p> The buffer's position is set to the number of bytes copied,
+ * rather than to zero, so that an invocation of this method can be
+ * followed immediately by an invocation of another relative <i>put</i>
+ * method. </p>
+ *
+
+ *
+ * <p> Invoke this method after writing data from a buffer in case the
+ * write was incomplete. The following loop, for example, copies bytes
+ * from one channel to another via the buffer <tt>buf</tt>:
+ *
+ * <blockquote><pre>{@code
+ * buf.clear(); // Prepare buffer for use
+ * while (in.read(buf) >= 0 || buf.position != 0) {
+ * buf.flip();
+ * out.write(buf);
+ * buf.compact(); // In case of partial write
+ * }
+ * }</pre></blockquote>
+ *
+
+ *
+ * @return This buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract ByteBuffer compact();
+
+ /**
+ * Tells whether or not this byte buffer is direct.
+ *
+ * @return <tt>true</tt> if, and only if, this buffer is direct
+ */
+ public abstract boolean isDirect();
+
+
+ /**
+ * Returns a string summarizing the state of this buffer.
+ *
+ * @return A summary string
+ */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(getClass().getName());
+ sb.append("[pos=");
+ sb.append(position());
+ sb.append(" lim=");
+ sb.append(limit());
+ sb.append(" cap=");
+ sb.append(capacity());
+ sb.append("]");
+ return sb.toString();
+ }
+
+
+ /**
+ * Returns the current hash code of this buffer.
+ *
+ * <p> The hash code of a byte buffer depends only upon its remaining
+ * elements; that is, upon the elements from <tt>position()</tt> up to, and
+ * including, the element at <tt>limit()</tt> - <tt>1</tt>.
+ *
+ * <p> Because buffer hash codes are content-dependent, it is inadvisable
+ * to use buffers as keys in hash maps or similar data structures unless it
+ * is known that their contents will not change. </p>
+ *
+ * @return The current hash code of this buffer
+ */
+ public int hashCode() {
+ int h = 1;
+ int p = position();
+ for (int i = limit() - 1; i >= p; i--)
+ h = 31 * h + (int)get(i);
+ return h;
+ }
+
+ /**
+ * Tells whether or not this buffer is equal to another object.
+ *
+ * <p> Two byte buffers are equal if, and only if,
+ *
+ * <ol>
+ *
+ * <li><p> They have the same element type, </p></li>
+ *
+ * <li><p> They have the same number of remaining elements, and
+ * </p></li>
+ *
+ * <li><p> The two sequences of remaining elements, considered
+ * independently of their starting positions, are pointwise equal.
+
+ * </p></li>
+ *
+ * </ol>
+ *
+ * <p> A byte buffer is not equal to any other type of object. </p>
+ *
+ * @param ob The object to which this buffer is to be compared
+ *
+ * @return <tt>true</tt> if, and only if, this buffer is equal to the
+ * given object
+ */
+ public boolean equals(Object ob) {
+ if (this == ob)
+ return true;
+ if (!(ob instanceof ByteBuffer))
+ return false;
+ ByteBuffer that = (ByteBuffer)ob;
+ if (this.remaining() != that.remaining())
+ return false;
+ int p = this.position();
+ for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--)
+ if (!equals(this.get(i), that.get(j)))
+ return false;
+ return true;
+ }
+
+ private static boolean equals(byte x, byte y) {
+
+
+ return x == y;
+
+ }
+
+ /**
+ * Compares this buffer to another.
+ *
+ * <p> Two byte buffers are compared by comparing their sequences of
+ * remaining elements lexicographically, without regard to the starting
+ * position of each sequence within its corresponding buffer.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * Pairs of {@code byte} elements are compared as if by invoking
+ * {@link Byte#compare(byte,byte)}.
+
+ *
+ * <p> A byte buffer is not comparable to any other type of object.
+ *
+ * @return A negative integer, zero, or a positive integer as this buffer
+ * is less than, equal to, or greater than the given buffer
+ */
+ public int compareTo(ByteBuffer that) {
+ int n = this.position() + Math.min(this.remaining(), that.remaining());
+ for (int i = this.position(), j = that.position(); i < n; i++, j++) {
+ int cmp = compare(this.get(i), that.get(j));
+ if (cmp != 0)
+ return cmp;
+ }
+ return this.remaining() - that.remaining();
+ }
+
+ private static int compare(byte x, byte y) {
+
+
+ return Byte.compare(x, y);
+
+ }
+
+ // -- Other char stuff --
+
+
+ // -- Other byte stuff: Access to binary data --
+
+
+ boolean bigEndian // package-private
+ = true;
+ boolean nativeByteOrder // package-private
+ = (Bits.byteOrder() == ByteOrder.BIG_ENDIAN);
+
+ /**
+ * Retrieves this buffer's byte order.
+ *
+ * <p> The byte order is used when reading or writing multibyte values, and
+ * when creating buffers that are views of this byte buffer. The order of
+ * a newly-created byte buffer is always {@link ByteOrder#BIG_ENDIAN
+ * BIG_ENDIAN}. </p>
+ *
+ * @return This buffer's byte order
+ */
+ public final ByteOrder order() {
+ return bigEndian ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
+ }
+
+ /**
+ * Modifies this buffer's byte order.
+ *
+ * @param bo
+ * The new byte order,
+ * either {@link ByteOrder#BIG_ENDIAN BIG_ENDIAN}
+ * or {@link ByteOrder#LITTLE_ENDIAN LITTLE_ENDIAN}
+ *
+ * @return This buffer
+ */
+ public final ByteBuffer order(ByteOrder bo) {
+ bigEndian = (bo == ByteOrder.BIG_ENDIAN);
+ nativeByteOrder =
+ (bigEndian == (Bits.byteOrder() == ByteOrder.BIG_ENDIAN));
+ return this;
+ }
+
+ // Unchecked accessors, for use by ByteBufferAs-X-Buffer classes
+ //
+ abstract byte _get(int i); // package-private
+ abstract void _put(int i, byte b); // package-private
+
+
+ /**
+ * Relative <i>get</i> method for reading a char value.
+ *
+ * <p> Reads the next two bytes at this buffer's current position,
+ * composing them into a char value according to the current byte order,
+ * and then increments the position by two. </p>
+ *
+ * @return The char value at the buffer's current position
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than two bytes
+ * remaining in this buffer
+ */
+ public abstract char getChar();
+
+ /**
+ * Relative <i>put</i> method for writing a char
+ * value <i>(optional operation)</i>.
+ *
+ * <p> Writes two bytes containing the given char value, in the
+ * current byte order, into this buffer at the current position, and then
+ * increments the position by two. </p>
+ *
+ * @param value
+ * The char value to be written
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there are fewer than two bytes
+ * remaining in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract ByteBuffer putChar(char value);
+
+ /**
+ * Absolute <i>get</i> method for reading a char value.
+ *
+ * <p> Reads two bytes at the given index, composing them into a
+ * char value according to the current byte order. </p>
+ *
+ * @param index
+ * The index from which the bytes will be read
+ *
+ * @return The char value at the given index
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit,
+ * minus one
+ */
+ public abstract char getChar(int index);
+
+ // BEGIN Android-added: {get,put}*Unchecked() accessors.
+ abstract char getCharUnchecked(int index);
+ abstract void getUnchecked(int pos, char[] dst, int dstOffset, int length);
+ // END Android-added: {get,put}*Unchecked() accessors.
+
+ /**
+ * Absolute <i>put</i> method for writing a char
+ * value <i>(optional operation)</i>.
+ *
+ * <p> Writes two bytes containing the given char value, in the
+ * current byte order, into this buffer at the given index. </p>
+ *
+ * @param index
+ * The index at which the bytes will be written
+ *
+ * @param value
+ * The char value to be written
+ *
+ * @return This buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit,
+ * minus one
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract ByteBuffer putChar(int index, char value);
+
+ // BEGIN Android-added: {get,put}*Unchecked() accessors.
+ abstract void putCharUnchecked(int index, char value);
+ abstract void putUnchecked(int pos, char[] dst, int srcOffset, int length);
+ // END Android-added: {get,put}*Unchecked() accessors.
+
+ /**
+ * Creates a view of this byte buffer as a char buffer.
+ *
+ * <p> The content of the new buffer will start at this buffer's current
+ * position. Changes to this buffer's content will be visible in the new
+ * buffer, and vice versa; the two buffers' position, limit, and mark
+ * values will be independent.
+ *
+ * <p> The new buffer's position will be zero, its capacity and its limit
+ * will be the number of bytes remaining in this buffer divided by
+ * two, and its mark will be undefined. The new buffer will be direct
+ * if, and only if, this buffer is direct, and it will be read-only if, and
+ * only if, this buffer is read-only. </p>
+ *
+ * @return A new char buffer
+ */
+ public abstract CharBuffer asCharBuffer();
+
+
+ /**
+ * Relative <i>get</i> method for reading a short value.
+ *
+ * <p> Reads the next two bytes at this buffer's current position,
+ * composing them into a short value according to the current byte order,
+ * and then increments the position by two. </p>
+ *
+ * @return The short value at the buffer's current position
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than two bytes
+ * remaining in this buffer
+ */
+ public abstract short getShort();
+
+ /**
+ * Relative <i>put</i> method for writing a short
+ * value <i>(optional operation)</i>.
+ *
+ * <p> Writes two bytes containing the given short value, in the
+ * current byte order, into this buffer at the current position, and then
+ * increments the position by two. </p>
+ *
+ * @param value
+ * The short value to be written
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there are fewer than two bytes
+ * remaining in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract ByteBuffer putShort(short value);
+
+ /**
+ * Absolute <i>get</i> method for reading a short value.
+ *
+ * <p> Reads two bytes at the given index, composing them into a
+ * short value according to the current byte order. </p>
+ *
+ * @param index
+ * The index from which the bytes will be read
+ *
+ * @return The short value at the given index
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit,
+ * minus one
+ */
+ public abstract short getShort(int index);
+
+ // BEGIN Android-added: {get,put}*Unchecked() accessors.
+ abstract short getShortUnchecked(int index);
+ abstract void getUnchecked(int pos, short[] dst, int dstOffset, int length);
+ // END Android-added: {get,put}*Unchecked() accessors.
+
+ /**
+ * Absolute <i>put</i> method for writing a short
+ * value <i>(optional operation)</i>.
+ *
+ * <p> Writes two bytes containing the given short value, in the
+ * current byte order, into this buffer at the given index. </p>
+ *
+ * @param index
+ * The index at which the bytes will be written
+ *
+ * @param value
+ * The short value to be written
+ *
+ * @return This buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit,
+ * minus one
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract ByteBuffer putShort(int index, short value);
+
+ // BEGIN Android-added: {get,put}*Unchecked() accessors.
+ abstract void putShortUnchecked(int index, short value);
+ abstract void putUnchecked(int pos, short[] dst, int srcOffset, int length);
+ // END Android-added: {get,put}*Unchecked() accessors.
+
+ /**
+ * Creates a view of this byte buffer as a short buffer.
+ *
+ * <p> The content of the new buffer will start at this buffer's current
+ * position. Changes to this buffer's content will be visible in the new
+ * buffer, and vice versa; the two buffers' position, limit, and mark
+ * values will be independent.
+ *
+ * <p> The new buffer's position will be zero, its capacity and its limit
+ * will be the number of bytes remaining in this buffer divided by
+ * two, and its mark will be undefined. The new buffer will be direct
+ * if, and only if, this buffer is direct, and it will be read-only if, and
+ * only if, this buffer is read-only. </p>
+ *
+ * @return A new short buffer
+ */
+ public abstract ShortBuffer asShortBuffer();
+
+
+ /**
+ * Relative <i>get</i> method for reading an int value.
+ *
+ * <p> Reads the next four bytes at this buffer's current position,
+ * composing them into an int value according to the current byte order,
+ * and then increments the position by four. </p>
+ *
+ * @return The int value at the buffer's current position
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than four bytes
+ * remaining in this buffer
+ */
+ public abstract int getInt();
+
+ /**
+ * Relative <i>put</i> method for writing an int
+ * value <i>(optional operation)</i>.
+ *
+ * <p> Writes four bytes containing the given int value, in the
+ * current byte order, into this buffer at the current position, and then
+ * increments the position by four. </p>
+ *
+ * @param value
+ * The int value to be written
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there are fewer than four bytes
+ * remaining in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract ByteBuffer putInt(int value);
+
+ /**
+ * Absolute <i>get</i> method for reading an int value.
+ *
+ * <p> Reads four bytes at the given index, composing them into a
+ * int value according to the current byte order. </p>
+ *
+ * @param index
+ * The index from which the bytes will be read
+ *
+ * @return The int value at the given index
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit,
+ * minus three
+ */
+ public abstract int getInt(int index);
+
+ // BEGIN Android-added: {get,put}*Unchecked() accessors.
+ abstract int getIntUnchecked(int index);
+ abstract void getUnchecked(int pos, int[] dst, int dstOffset, int length);
+ // END Android-added: {get,put}*Unchecked() accessors.
+
+ /**
+ * Absolute <i>put</i> method for writing an int
+ * value <i>(optional operation)</i>.
+ *
+ * <p> Writes four bytes containing the given int value, in the
+ * current byte order, into this buffer at the given index. </p>
+ *
+ * @param index
+ * The index at which the bytes will be written
+ *
+ * @param value
+ * The int value to be written
+ *
+ * @return This buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit,
+ * minus three
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract ByteBuffer putInt(int index, int value);
+
+ // BEGIN Android-added: {get,put}*Unchecked() accessors.
+ abstract void putIntUnchecked(int index, int value);
+ abstract void putUnchecked(int pos, int[] dst, int srcOffset, int length);
+ // END Android-added: {get,put}*Unchecked() accessors.
+
+ /**
+ * Creates a view of this byte buffer as an int buffer.
+ *
+ * <p> The content of the new buffer will start at this buffer's current
+ * position. Changes to this buffer's content will be visible in the new
+ * buffer, and vice versa; the two buffers' position, limit, and mark
+ * values will be independent.
+ *
+ * <p> The new buffer's position will be zero, its capacity and its limit
+ * will be the number of bytes remaining in this buffer divided by
+ * four, and its mark will be undefined. The new buffer will be direct
+ * if, and only if, this buffer is direct, and it will be read-only if, and
+ * only if, this buffer is read-only. </p>
+ *
+ * @return A new int buffer
+ */
+ public abstract IntBuffer asIntBuffer();
+
+
+ /**
+ * Relative <i>get</i> method for reading a long value.
+ *
+ * <p> Reads the next eight bytes at this buffer's current position,
+ * composing them into a long value according to the current byte order,
+ * and then increments the position by eight. </p>
+ *
+ * @return The long value at the buffer's current position
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than eight bytes
+ * remaining in this buffer
+ */
+ public abstract long getLong();
+
+ /**
+ * Relative <i>put</i> method for writing a long
+ * value <i>(optional operation)</i>.
+ *
+ * <p> Writes eight bytes containing the given long value, in the
+ * current byte order, into this buffer at the current position, and then
+ * increments the position by eight. </p>
+ *
+ * @param value
+ * The long value to be written
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there are fewer than eight bytes
+ * remaining in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract ByteBuffer putLong(long value);
+
+ /**
+ * Absolute <i>get</i> method for reading a long value.
+ *
+ * <p> Reads eight bytes at the given index, composing them into a
+ * long value according to the current byte order. </p>
+ *
+ * @param index
+ * The index from which the bytes will be read
+ *
+ * @return The long value at the given index
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit,
+ * minus seven
+ */
+ public abstract long getLong(int index);
+
+ // BEGIN Android-added: {get,put}*Unchecked() accessors.
+ abstract long getLongUnchecked(int index);
+ abstract void getUnchecked(int pos, long[] dst, int dstOffset, int length);
+ // END Android-added: {get,put}*Unchecked() accessors.
+
+ /**
+ * Absolute <i>put</i> method for writing a long
+ * value <i>(optional operation)</i>.
+ *
+ * <p> Writes eight bytes containing the given long value, in the
+ * current byte order, into this buffer at the given index. </p>
+ *
+ * @param index
+ * The index at which the bytes will be written
+ *
+ * @param value
+ * The long value to be written
+ *
+ * @return This buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit,
+ * minus seven
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract ByteBuffer putLong(int index, long value);
+
+ // BEGIN Android-added: {get,put}*Unchecked() accessors.
+ abstract void putLongUnchecked(int index, long value);
+ abstract void putUnchecked(int pos, long[] dst, int srcOffset, int length);
+ // END Android-added: {get,put}*Unchecked() accessors.
+
+ /**
+ * Creates a view of this byte buffer as a long buffer.
+ *
+ * <p> The content of the new buffer will start at this buffer's current
+ * position. Changes to this buffer's content will be visible in the new
+ * buffer, and vice versa; the two buffers' position, limit, and mark
+ * values will be independent.
+ *
+ * <p> The new buffer's position will be zero, its capacity and its limit
+ * will be the number of bytes remaining in this buffer divided by
+ * eight, and its mark will be undefined. The new buffer will be direct
+ * if, and only if, this buffer is direct, and it will be read-only if, and
+ * only if, this buffer is read-only. </p>
+ *
+ * @return A new long buffer
+ */
+ public abstract LongBuffer asLongBuffer();
+
+
+ /**
+ * Relative <i>get</i> method for reading a float value.
+ *
+ * <p> Reads the next four bytes at this buffer's current position,
+ * composing them into a float value according to the current byte order,
+ * and then increments the position by four. </p>
+ *
+ * @return The float value at the buffer's current position
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than four bytes
+ * remaining in this buffer
+ */
+ public abstract float getFloat();
+
+ /**
+ * Relative <i>put</i> method for writing a float
+ * value <i>(optional operation)</i>.
+ *
+ * <p> Writes four bytes containing the given float value, in the
+ * current byte order, into this buffer at the current position, and then
+ * increments the position by four. </p>
+ *
+ * @param value
+ * The float value to be written
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there are fewer than four bytes
+ * remaining in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract ByteBuffer putFloat(float value);
+
+ /**
+ * Absolute <i>get</i> method for reading a float value.
+ *
+ * <p> Reads four bytes at the given index, composing them into a
+ * float value according to the current byte order. </p>
+ *
+ * @param index
+ * The index from which the bytes will be read
+ *
+ * @return The float value at the given index
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit,
+ * minus three
+ */
+ public abstract float getFloat(int index);
+
+ // BEGIN Android-added: {get,put}*Unchecked() accessors.
+ abstract float getFloatUnchecked(int index);
+ abstract void getUnchecked(int pos, float[] dst, int dstOffset, int length);
+ // END Android-added: {get,put}*Unchecked() accessors.
+
+ /**
+ * Absolute <i>put</i> method for writing a float
+ * value <i>(optional operation)</i>.
+ *
+ * <p> Writes four bytes containing the given float value, in the
+ * current byte order, into this buffer at the given index. </p>
+ *
+ * @param index
+ * The index at which the bytes will be written
+ *
+ * @param value
+ * The float value to be written
+ *
+ * @return This buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit,
+ * minus three
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract ByteBuffer putFloat(int index, float value);
+
+ // BEGIN Android-added: {get,put}*Unchecked() accessors.
+ abstract void putFloatUnchecked(int index, float value);
+ abstract void putUnchecked(int pos, float[] dst, int srcOffset, int length);
+ // END Android-added: {get,put}*Unchecked() accessors.
+
+ /**
+ * Creates a view of this byte buffer as a float buffer.
+ *
+ * <p> The content of the new buffer will start at this buffer's current
+ * position. Changes to this buffer's content will be visible in the new
+ * buffer, and vice versa; the two buffers' position, limit, and mark
+ * values will be independent.
+ *
+ * <p> The new buffer's position will be zero, its capacity and its limit
+ * will be the number of bytes remaining in this buffer divided by
+ * four, and its mark will be undefined. The new buffer will be direct
+ * if, and only if, this buffer is direct, and it will be read-only if, and
+ * only if, this buffer is read-only. </p>
+ *
+ * @return A new float buffer
+ */
+ public abstract FloatBuffer asFloatBuffer();
+
+
+ /**
+ * Relative <i>get</i> method for reading a double value.
+ *
+ * <p> Reads the next eight bytes at this buffer's current position,
+ * composing them into a double value according to the current byte order,
+ * and then increments the position by eight. </p>
+ *
+ * @return The double value at the buffer's current position
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than eight bytes
+ * remaining in this buffer
+ */
+ public abstract double getDouble();
+
+ /**
+ * Relative <i>put</i> method for writing a double
+ * value <i>(optional operation)</i>.
+ *
+ * <p> Writes eight bytes containing the given double value, in the
+ * current byte order, into this buffer at the current position, and then
+ * increments the position by eight. </p>
+ *
+ * @param value
+ * The double value to be written
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there are fewer than eight bytes
+ * remaining in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract ByteBuffer putDouble(double value);
+
+ /**
+ * Absolute <i>get</i> method for reading a double value.
+ *
+ * <p> Reads eight bytes at the given index, composing them into a
+ * double value according to the current byte order. </p>
+ *
+ * @param index
+ * The index from which the bytes will be read
+ *
+ * @return The double value at the given index
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit,
+ * minus seven
+ */
+ public abstract double getDouble(int index);
+
+ // BEGIN Android-added: {get,put}*Unchecked() accessors.
+ abstract double getDoubleUnchecked(int index);
+ abstract void getUnchecked(int pos, double[] dst, int dstOffset, int length);
+ // END Android-added: {get,put}*Unchecked() accessors.
+
+ /**
+ * Absolute <i>put</i> method for writing a double
+ * value <i>(optional operation)</i>.
+ *
+ * <p> Writes eight bytes containing the given double value, in the
+ * current byte order, into this buffer at the given index. </p>
+ *
+ * @param index
+ * The index at which the bytes will be written
+ *
+ * @param value
+ * The double value to be written
+ *
+ * @return This buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit,
+ * minus seven
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract ByteBuffer putDouble(int index, double value);
+
+ // BEGIN Android-added: {get,put}*Unchecked() accessors.
+ abstract void putDoubleUnchecked(int index, double value);
+ abstract void putUnchecked(int pos, double[] dst, int srcOffset, int length);
+ // END Android-added: {get,put}*Unchecked() accessors.
+
+ /**
+ * Creates a view of this byte buffer as a double buffer.
+ *
+ * <p> The content of the new buffer will start at this buffer's current
+ * position. Changes to this buffer's content will be visible in the new
+ * buffer, and vice versa; the two buffers' position, limit, and mark
+ * values will be independent.
+ *
+ * <p> The new buffer's position will be zero, its capacity and its limit
+ * will be the number of bytes remaining in this buffer divided by
+ * eight, and its mark will be undefined. The new buffer will be direct
+ * if, and only if, this buffer is direct, and it will be read-only if, and
+ * only if, this buffer is read-only. </p>
+ *
+ * @return A new double buffer
+ */
+ public abstract DoubleBuffer asDoubleBuffer();
+
+ // BEGIN Android-added: isAccessible(), setAccessible(), for use by frameworks (MediaCodec).
+ /**
+ * @hide
+ */
+ public boolean isAccessible() {
+ return true;
+ }
+
+ /**
+ * @hide
+ */
+ public void setAccessible(boolean value) {
+ throw new UnsupportedOperationException();
+ }
+ // END Android-added: isAccessible(), setAccessible(), for use by frameworks (MediaCodec).
+}
diff --git a/java/nio/ByteBufferAsCharBuffer.java b/java/nio/ByteBufferAsCharBuffer.java
new file mode 100644
index 0000000..9dbb8a6
--- /dev/null
+++ b/java/nio/ByteBufferAsCharBuffer.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio;
+
+import libcore.io.Memory;
+
+class ByteBufferAsCharBuffer extends CharBuffer { // package-private
+
+ protected final ByteBuffer bb;
+ protected final int offset;
+ private final ByteOrder order;
+
+ ByteBufferAsCharBuffer(ByteBuffer bb,
+ int mark, int pos, int lim, int cap,
+ int off, ByteOrder order) {
+ super(mark, pos, lim, cap);
+ this.bb = bb.duplicate();
+ this.isReadOnly = bb.isReadOnly;
+ // There are only two possibilities for the type of ByteBuffer "bb", viz, DirectByteBuffer and
+ // HeapByteBuffer. We only have to initialize the field when bb is an instance of
+ // DirectByteBuffer.
+ // The address field is used by NIOAccess#getBasePointer and GetDirectBufferAddress method
+ // in art which return the address of the first usable byte of the underlying memory, i.e,
+ // the position of parent buffer. Therefore, value of "off" will be equal to parent buffer's
+ // position when the method is called from either HeapByteBuffer or DirectByteBuffer.
+ if (bb instanceof DirectByteBuffer) {
+ this.address = bb.address + off;
+ }
+ this.bb.order(order);
+ this.order = order;
+ offset = off;
+ }
+
+ public CharBuffer slice() {
+ int pos = this.position();
+ int lim = this.limit();
+ assert (pos <= lim);
+ int rem = (pos <= lim ? lim - pos : 0);
+ int off = (pos << 1) + offset;
+ assert (off >= 0);
+ return new ByteBufferAsCharBuffer(bb, -1, 0, rem, rem, off, order);
+ }
+
+ public CharBuffer duplicate() {
+ return new ByteBufferAsCharBuffer(bb,
+ markValue(),
+ position(),
+ limit(),
+ capacity(),
+ offset,
+ order);
+ }
+
+ public CharBuffer asReadOnlyBuffer() {
+ return new ByteBufferAsCharBuffer(bb.asReadOnlyBuffer(),
+ markValue(),
+ position(),
+ limit(),
+ capacity(),
+ offset,
+ order);
+ }
+
+ protected int ix(int i) {
+ return (i << 1) + offset;
+ }
+
+ public char get() {
+ return get(nextGetIndex());
+ }
+
+ public char get(int i) {
+ return bb.getCharUnchecked(ix(checkIndex(i)));
+ }
+
+ public CharBuffer get(char[] dst, int offset, int length) {
+ checkBounds(offset, length, dst.length);
+ if (length > remaining())
+ throw new BufferUnderflowException();
+ bb.getUnchecked(ix(position), dst, offset, length);
+ position += length;
+ return this;
+ }
+
+ char getUnchecked(int i) {
+ return bb.getCharUnchecked(ix(i));
+ }
+
+ public CharBuffer put(char x) {
+ put(nextPutIndex(), x);
+ return this;
+ }
+
+ public CharBuffer put(int i, char x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ bb.putCharUnchecked(ix(checkIndex(i)), x);
+ return this;
+ }
+
+ public CharBuffer put(char[] src, int offset, int length) {
+ checkBounds(offset, length, src.length);
+ if (length > remaining())
+ throw new BufferOverflowException();
+ bb.putUnchecked(ix(position), src, offset, length);
+ position += length;
+ return this;
+ }
+
+ public CharBuffer compact() {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ int pos = position();
+ int lim = limit();
+ assert (pos <= lim);
+ int rem = (pos <= lim ? lim - pos : 0);
+ if (!(bb instanceof DirectByteBuffer)) {
+ System.arraycopy(bb.array(), ix(pos), bb.array(), ix(0), rem << 1);
+ } else {
+ Memory.memmove(this, ix(0), this, ix(pos), rem << 1);
+ }
+ position(rem);
+ limit(capacity());
+ discardMark();
+ return this;
+ }
+
+ public boolean isDirect() {
+ return bb.isDirect();
+ }
+
+ public boolean isReadOnly() {
+ return isReadOnly;
+ }
+
+ public String toString(int start, int end) {
+ if ((end > limit()) || (start > end))
+ throw new IndexOutOfBoundsException();
+ try {
+ int len = end - start;
+ char[] ca = new char[len];
+ CharBuffer cb = CharBuffer.wrap(ca);
+ CharBuffer db = this.duplicate();
+ db.position(start);
+ db.limit(end);
+ cb.put(db);
+ return new String(ca);
+ } catch (StringIndexOutOfBoundsException x) {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+
+ // --- Methods to support CharSequence ---
+
+ public CharBuffer subSequence(int start, int end) {
+ int pos = position();
+ int lim = limit();
+ assert (pos <= lim);
+ pos = (pos <= lim ? pos : lim);
+ int len = lim - pos;
+
+ if ((start < 0) || (end > len) || (start > end))
+ throw new IndexOutOfBoundsException();
+ return new ByteBufferAsCharBuffer(bb,
+ -1,
+ pos + start,
+ pos + end,
+ capacity(),
+ offset,
+ order);
+ }
+
+ public ByteOrder order() {
+ return order;
+ }
+}
diff --git a/java/nio/ByteBufferAsDoubleBuffer.java b/java/nio/ByteBufferAsDoubleBuffer.java
new file mode 100644
index 0000000..ff4a6bf
--- /dev/null
+++ b/java/nio/ByteBufferAsDoubleBuffer.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio;
+
+import libcore.io.Memory;
+
+class ByteBufferAsDoubleBuffer
+ extends DoubleBuffer { // package-private
+
+ protected final ByteBuffer bb;
+ protected final int offset;
+ private final ByteOrder order;
+
+ ByteBufferAsDoubleBuffer(ByteBuffer bb,
+ int mark, int pos, int lim, int cap,
+ int off, ByteOrder order) {
+ super(mark, pos, lim, cap);
+ this.bb = bb.duplicate();
+ this.isReadOnly = bb.isReadOnly;
+ // There are only two possibilities for the type of ByteBuffer "bb", viz, DirectByteBuffer and
+ // HeapByteBuffer. We only have to initialize the field when bb is an instance of
+ // DirectByteBuffer.
+ // The address field is used by NIOAccess#getBasePointer and GetDirectBufferAddress method
+ // in art which return the address of the first usable byte of the underlying memory, i.e,
+ // the position of parent buffer. Therefore, value of "off" will be equal to parent buffer's
+ // position when the method is called from either HeapByteBuffer or DirectByteBuffer.
+ if (bb instanceof DirectByteBuffer) {
+ this.address = bb.address + off;
+ }
+ this.bb.order(order);
+ this.order = order;
+ offset = off;
+ }
+
+ public DoubleBuffer slice() {
+ int pos = this.position();
+ int lim = this.limit();
+ assert (pos <= lim);
+ int rem = (pos <= lim ? lim - pos : 0);
+ int off = (pos << 3) + offset;
+ assert (off >= 0);
+ return new ByteBufferAsDoubleBuffer(bb, -1, 0, rem, rem, off, order);
+ }
+
+ public DoubleBuffer duplicate() {
+ return new ByteBufferAsDoubleBuffer(bb,
+ markValue(),
+ position(),
+ limit(),
+ capacity(),
+ offset,
+ order);
+ }
+
+ public DoubleBuffer asReadOnlyBuffer() {
+ return new ByteBufferAsDoubleBuffer(bb.asReadOnlyBuffer(),
+ markValue(),
+ position(),
+ limit(),
+ capacity(),
+ offset,
+ order);
+ }
+
+ protected int ix(int i) {
+ return (i << 3) + offset;
+ }
+
+ public double get() {
+ return get(nextGetIndex());
+ }
+
+ public double get(int i) {
+ return bb.getDoubleUnchecked(ix(checkIndex(i)));
+ }
+
+ public DoubleBuffer get(double[] dst, int offset, int length) {
+ checkBounds(offset, length, dst.length);
+ if (length > remaining())
+ throw new BufferUnderflowException();
+ bb.getUnchecked(ix(position), dst, offset, length);
+ position += length;
+ return this;
+ }
+
+ public DoubleBuffer put(double x) {
+ put(nextPutIndex(), x);
+ return this;
+ }
+
+ public DoubleBuffer put(int i, double x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ bb.putDoubleUnchecked(ix(checkIndex(i)), x);
+ return this;
+ }
+
+ public DoubleBuffer put(double[] src, int offset, int length) {
+ checkBounds(offset, length, src.length);
+ if (length > remaining())
+ throw new BufferOverflowException();
+ bb.putUnchecked(ix(position), src, offset, length);
+ position += length;
+ return this;
+ }
+
+ public DoubleBuffer compact() {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ int pos = position();
+ int lim = limit();
+ assert (pos <= lim);
+ int rem = (pos <= lim ? lim - pos : 0);
+ if (!(bb instanceof DirectByteBuffer)) {
+ System.arraycopy(bb.array(), ix(pos), bb.array(), ix(0), rem << 3);
+ } else {
+ Memory.memmove(this, ix(0), this, ix(pos), rem << 3);
+ }
+ position(rem);
+ limit(capacity());
+ discardMark();
+ return this;
+ }
+
+ public boolean isDirect() {
+ return bb.isDirect();
+ }
+
+ public boolean isReadOnly() {
+ return isReadOnly;
+ }
+
+ public ByteOrder order() {
+ return order;
+ }
+}
diff --git a/java/nio/ByteBufferAsFloatBuffer.java b/java/nio/ByteBufferAsFloatBuffer.java
new file mode 100644
index 0000000..8e4e2e8
--- /dev/null
+++ b/java/nio/ByteBufferAsFloatBuffer.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio;
+
+import libcore.io.Memory;
+
+class ByteBufferAsFloatBuffer extends FloatBuffer { // package-private
+
+ protected final ByteBuffer bb;
+ protected final int offset;
+ private final ByteOrder order;
+
+ ByteBufferAsFloatBuffer(ByteBuffer bb,
+ int mark, int pos, int lim, int cap,
+ int off, ByteOrder order) {
+ super(mark, pos, lim, cap);
+ this.bb = bb.duplicate();
+ this.isReadOnly = bb.isReadOnly;
+ // There are only two possibilities for the type of ByteBuffer "bb", viz, DirectByteBuffer and
+ // HeapByteBuffer. We only have to initialize the field when bb is an instance of
+ // DirectByteBuffer.
+ // The address field is used by NIOAccess#getBasePointer and GetDirectBufferAddress method
+ // in art which return the address of the first usable byte of the underlying memory, i.e,
+ // the position of parent buffer. Therefore, value of "off" will be equal to parent buffer's
+ // position when the method is called from either HeapByteBuffer or DirectByteBuffer.
+ if (bb instanceof DirectByteBuffer) {
+ this.address = bb.address + off;
+ }
+ this.bb.order(order);
+ this.order = order;
+ offset = off;
+ }
+
+ public FloatBuffer slice() {
+ int pos = this.position();
+ int lim = this.limit();
+ assert (pos <= lim);
+ int rem = (pos <= lim ? lim - pos : 0);
+ int off = (pos << 2) + offset;
+ assert (off >= 0);
+ return new ByteBufferAsFloatBuffer(bb, -1, 0, rem, rem, off, order);
+ }
+
+ public FloatBuffer duplicate() {
+ return new ByteBufferAsFloatBuffer(bb,
+ markValue(),
+ position(),
+ limit(),
+ capacity(),
+ offset,
+ order);
+ }
+
+ public FloatBuffer asReadOnlyBuffer() {
+ return new ByteBufferAsFloatBuffer(bb.asReadOnlyBuffer(),
+ markValue(),
+ position(),
+ limit(),
+ capacity(),
+ offset,
+ order);
+ }
+
+ protected int ix(int i) {
+ return (i << 2) + offset;
+ }
+
+ public float get() {
+ return get(nextGetIndex());
+ }
+
+ public float get(int i) {
+ return bb.getFloatUnchecked(ix(checkIndex(i)));
+ }
+
+ public FloatBuffer get(float[] dst, int offset, int length) {
+ checkBounds(offset, length, dst.length);
+ if (length > remaining())
+ throw new BufferUnderflowException();
+ bb.getUnchecked(ix(position), dst, offset, length);
+ position += length;
+ return this;
+ }
+
+ public FloatBuffer put(float x) {
+ put(nextPutIndex(), x);
+ return this;
+ }
+
+ public FloatBuffer put(int i, float x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ bb.putFloatUnchecked(ix(checkIndex(i)), x);
+ return this;
+ }
+
+ public FloatBuffer put(float[] src, int offset, int length) {
+ checkBounds(offset, length, src.length);
+ if (length > remaining())
+ throw new BufferOverflowException();
+ bb.putUnchecked(ix(position), src, offset, length);
+ position += length;
+ return this;
+ }
+
+ public FloatBuffer compact() {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ int pos = position();
+ int lim = limit();
+ assert (pos <= lim);
+ int rem = (pos <= lim ? lim - pos : 0);
+ if (!(bb instanceof DirectByteBuffer)) {
+ System.arraycopy(bb.array(), ix(pos), bb.array(), ix(0), rem << 2);
+ } else {
+ Memory.memmove(this, ix(0), this, ix(pos), rem << 2);
+ }
+ position(rem);
+ limit(capacity());
+ discardMark();
+ return this;
+ }
+
+ public boolean isDirect() {
+ return bb.isDirect();
+ }
+
+ public boolean isReadOnly() {
+ return isReadOnly;
+ }
+
+ public ByteOrder order() {
+ return order;
+ }
+}
diff --git a/java/nio/ByteBufferAsIntBuffer.java b/java/nio/ByteBufferAsIntBuffer.java
new file mode 100644
index 0000000..e340426
--- /dev/null
+++ b/java/nio/ByteBufferAsIntBuffer.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio;
+
+import libcore.io.Memory;
+
+class ByteBufferAsIntBuffer extends IntBuffer { // package-private
+
+ protected final ByteBuffer bb;
+ protected final int offset;
+ private final ByteOrder order;
+
+ ByteBufferAsIntBuffer(ByteBuffer bb,
+ int mark, int pos, int lim, int cap,
+ int off, ByteOrder order) {
+ super(mark, pos, lim, cap);
+ this.bb = bb.duplicate();
+ this.isReadOnly = bb.isReadOnly;
+ // There are only two possibilities for the type of ByteBuffer "bb", viz, DirectByteBuffer and
+ // HeapByteBuffer. We only have to initialize the field when bb is an instance of
+ // DirectByteBuffer.
+ // The address field is used by NIOAccess#getBasePointer and GetDirectBufferAddress method
+ // in art which return the address of the first usable byte of the underlying memory, i.e,
+ // the position of parent buffer. Therefore, value of "off" will be equal to parent buffer's
+ // position when the method is called from either HeapByteBuffer or DirectByteBuffer.
+ if (bb instanceof DirectByteBuffer) {
+ this.address = bb.address + off;
+ }
+ this.bb.order(order);
+ this.order = order;
+ offset = off;
+ }
+
+ public IntBuffer slice() {
+ int pos = this.position();
+ int lim = this.limit();
+ assert (pos <= lim);
+ int rem = (pos <= lim ? lim - pos : 0);
+ int off = (pos << 2) + offset;
+ assert (off >= 0);
+ return new ByteBufferAsIntBuffer(bb, -1, 0, rem, rem, off, order);
+ }
+
+ public IntBuffer duplicate() {
+ return new ByteBufferAsIntBuffer(bb,
+ markValue(),
+ position(),
+ limit(),
+ capacity(),
+ offset,
+ order);
+ }
+
+ public IntBuffer asReadOnlyBuffer() {
+ return new ByteBufferAsIntBuffer(bb.asReadOnlyBuffer(),
+ markValue(),
+ position(),
+ limit(),
+ capacity(),
+ offset,
+ order);
+ }
+
+ protected int ix(int i) {
+ return (i << 2) + offset;
+ }
+
+ public int get() {
+ return get(nextGetIndex());
+ }
+
+ public int get(int i) {
+ return bb.getIntUnchecked(ix(checkIndex(i)));
+ }
+
+ public IntBuffer get(int[] dst, int offset, int length) {
+ checkBounds(offset, length, dst.length);
+ if (length > remaining())
+ throw new BufferUnderflowException();
+ bb.getUnchecked(ix(position), dst, offset, length);
+ position += length;
+ return this;
+ }
+
+ public IntBuffer put(int x) {
+ put(nextPutIndex(), x);
+ return this;
+ }
+
+ public IntBuffer put(int i, int x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ bb.putIntUnchecked(ix(checkIndex(i)), x);
+ return this;
+ }
+
+ public IntBuffer put(int[] src, int offset, int length) {
+ checkBounds(offset, length, src.length);
+ if (length > remaining())
+ throw new BufferOverflowException();
+ bb.putUnchecked(ix(position), src, offset, length);
+ position += length;
+ return this;
+ }
+
+ public IntBuffer compact() {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ int pos = position();
+ int lim = limit();
+ assert (pos <= lim);
+ int rem = (pos <= lim ? lim - pos : 0);
+ if (!(bb instanceof DirectByteBuffer)) {
+ System.arraycopy(bb.array(), ix(pos), bb.array(), ix(0), rem << 2);
+ } else {
+ Memory.memmove(this, ix(0), this, ix(pos), rem << 2);
+ }
+ position(rem);
+ limit(capacity());
+ discardMark();
+ return this;
+ }
+
+ public boolean isDirect() {
+ return bb.isDirect();
+ }
+
+ public boolean isReadOnly() {
+ return isReadOnly;
+ }
+
+ public ByteOrder order() {
+ return order;
+ }
+}
diff --git a/java/nio/ByteBufferAsLongBuffer.java b/java/nio/ByteBufferAsLongBuffer.java
new file mode 100644
index 0000000..70f59c9
--- /dev/null
+++ b/java/nio/ByteBufferAsLongBuffer.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio;
+
+import libcore.io.Memory;
+
+class ByteBufferAsLongBuffer extends LongBuffer { // package-private
+
+ protected final ByteBuffer bb;
+ protected final int offset;
+ private final ByteOrder order;
+
+ ByteBufferAsLongBuffer(ByteBuffer bb,
+ int mark, int pos, int lim, int cap,
+ int off, ByteOrder order) {
+ super(mark, pos, lim, cap);
+ this.bb = bb.duplicate();
+ this.isReadOnly = bb.isReadOnly;
+ // There are only two possibilities for the type of ByteBuffer "bb", viz, DirectByteBuffer and
+ // HeapByteBuffer. We only have to initialize the field when bb is an instance of
+ // DirectByteBuffer.
+ // The address field is used by NIOAccess#getBasePointer and GetDirectBufferAddress method
+ // in art which return the address of the first usable byte of the underlying memory, i.e,
+ // the position of parent buffer. Therefore, value of "off" will be equal to parent buffer's
+ // position when the method is called from either HeapByteBuffer or DirectByteBuffer.
+ if (bb instanceof DirectByteBuffer) {
+ this.address = bb.address + off;
+ }
+ this.bb.order(order);
+ this.order = order;
+ offset = off;
+ }
+
+ public LongBuffer slice() {
+ int pos = this.position();
+ int lim = this.limit();
+ assert (pos <= lim);
+ int rem = (pos <= lim ? lim - pos : 0);
+ int off = (pos << 3) + offset;
+ assert (off >= 0);
+ return new ByteBufferAsLongBuffer(bb, -1, 0, rem, rem, off, order);
+ }
+
+ public LongBuffer duplicate() {
+ return new ByteBufferAsLongBuffer(bb,
+ this.markValue(),
+ this.position(),
+ this.limit(),
+ this.capacity(),
+ offset,
+ order);
+ }
+
+ public LongBuffer asReadOnlyBuffer() {
+ return new ByteBufferAsLongBuffer(bb.asReadOnlyBuffer(),
+ this.markValue(),
+ this.position(),
+ this.limit(),
+ this.capacity(),
+ offset,
+ order);
+ }
+
+ protected int ix(int i) {
+ return (i << 3) + offset;
+ }
+
+ public long get() {
+ return get(nextGetIndex());
+ }
+
+ public long get(int i) {
+ return bb.getLongUnchecked(ix(checkIndex(i)));
+ }
+
+ public LongBuffer get(long[] dst, int offset, int length) {
+ checkBounds(offset, length, dst.length);
+ if (length > remaining())
+ throw new BufferUnderflowException();
+ bb.getUnchecked(ix(position), dst, offset, length);
+ position += length;
+ return this;
+ }
+
+ public LongBuffer put(long x) {
+ put(nextPutIndex(), x);
+ return this;
+ }
+
+ public LongBuffer put(int i, long x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ bb.putLongUnchecked(ix(checkIndex(i)), x);
+ return this;
+ }
+
+ public LongBuffer put(long[] src, int offset, int length) {
+ checkBounds(offset, length, src.length);
+ if (length > remaining())
+ throw new BufferOverflowException();
+ bb.putUnchecked(ix(position), src, offset, length);
+ position += length;
+ return this;
+ }
+
+ public LongBuffer compact() {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ int pos = position();
+ int lim = limit();
+ assert (pos <= lim);
+ int rem = (pos <= lim ? lim - pos : 0);
+ if (!(bb instanceof DirectByteBuffer)) {
+ System.arraycopy(bb.array(), ix(pos), bb.array(), ix(0), rem << 3);
+ } else {
+ Memory.memmove(this, ix(0), this, ix(pos), rem << 3);
+ }
+ position(rem);
+ limit(capacity());
+ discardMark();
+ return this;
+ }
+
+ public boolean isDirect() {
+ return bb.isDirect();
+ }
+
+ public boolean isReadOnly() {
+ return isReadOnly;
+ }
+
+ public ByteOrder order() {
+ return order;
+ }
+}
diff --git a/java/nio/ByteBufferAsShortBuffer.java b/java/nio/ByteBufferAsShortBuffer.java
new file mode 100644
index 0000000..5178a7e
--- /dev/null
+++ b/java/nio/ByteBufferAsShortBuffer.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio;
+
+import libcore.io.Memory;
+
+class ByteBufferAsShortBuffer extends ShortBuffer { // package-private
+
+ protected final ByteBuffer bb;
+ protected final int offset;
+ private final ByteOrder order;
+
+ ByteBufferAsShortBuffer(ByteBuffer bb,
+ int mark, int pos, int lim, int cap,
+ int off, ByteOrder order) {
+ super(mark, pos, lim, cap);
+ this.bb = bb.duplicate();
+ this.isReadOnly = bb.isReadOnly;
+ // There are only two possibilities for the type of ByteBuffer "bb", viz, DirectByteBuffer and
+ // HeapByteBuffer. We only have to initialize the field when bb is an instance of
+ // DirectByteBuffer.
+ // The address field is use by NIOAccess#getBasePointer and GetDirectBufferAddress method
+ // in art which return the address of the first usable byte of the underlying memory, i.e,
+ // the position of parent buffer. Therefore, value of "off" will be equal to parent buffer's
+ // position when the method is called from either HeapByteBuffer or DirectByteBuffer.
+ if (bb instanceof DirectByteBuffer) {
+ this.address = bb.address + off;
+ }
+ this.bb.order(order);
+ this.order = order;
+ offset = off;
+ }
+
+ public ShortBuffer slice() {
+ int pos = this.position();
+ int lim = this.limit();
+ assert (pos <= lim);
+ int rem = (pos <= lim ? lim - pos : 0);
+ int off = (pos << 1) + offset;
+ assert (off >= 0);
+ return new ByteBufferAsShortBuffer(bb, -1, 0, rem, rem, off, order);
+ }
+
+ public ShortBuffer duplicate() {
+ return new ByteBufferAsShortBuffer(bb,
+ this.markValue(),
+ this.position(),
+ this.limit(),
+ this.capacity(),
+ offset, order);
+ }
+
+ public ShortBuffer asReadOnlyBuffer() {
+ return new ByteBufferAsShortBuffer(bb.asReadOnlyBuffer(),
+ this.markValue(),
+ this.position(),
+ this.limit(),
+ this.capacity(),
+ offset, order);
+ }
+
+ protected int ix(int i) {
+ return (i << 1) + offset;
+ }
+
+ public short get() {
+ return get(nextGetIndex());
+ }
+
+ public short get(int i) {
+ return bb.getShortUnchecked(ix(checkIndex(i)));
+
+ }
+
+ public ShortBuffer get(short[] dst, int offset, int length) {
+ checkBounds(offset, length, dst.length);
+ if (length > remaining())
+ throw new BufferUnderflowException();
+ bb.getUnchecked(ix(position), dst, offset, length);
+ position += length;
+ return this;
+ }
+
+ public ShortBuffer put(short x) {
+ put(nextPutIndex(), x);
+ return this;
+ }
+
+ public ShortBuffer put(int i, short x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ bb.putShortUnchecked(ix(checkIndex(i)), x);
+ return this;
+ }
+
+ public ShortBuffer put(short[] src, int offset, int length) {
+ checkBounds(offset, length, src.length);
+ if (length > remaining())
+ throw new BufferOverflowException();
+ bb.putUnchecked(ix(position), src, offset, length);
+ position += length;
+ return this;
+ }
+
+ public ShortBuffer compact() {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ int pos = position();
+ int lim = limit();
+ assert (pos <= lim);
+ int rem = (pos <= lim ? lim - pos : 0);
+ if (!(bb instanceof DirectByteBuffer)) {
+ System.arraycopy(bb.array(), ix(pos), bb.array(), ix(0), rem << 1);
+ } else {
+ Memory.memmove(this, ix(0), this, ix(pos), rem << 1);
+ }
+ position(rem);
+ limit(capacity());
+ discardMark();
+ return this;
+ }
+
+ public boolean isDirect() {
+ return bb.isDirect();
+ }
+
+ public boolean isReadOnly() {
+ return isReadOnly;
+ }
+
+ public ByteOrder order() {
+ return order;
+ }
+}
diff --git a/java/nio/ByteOrder.java b/java/nio/ByteOrder.java
new file mode 100644
index 0000000..a20cacc
--- /dev/null
+++ b/java/nio/ByteOrder.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio;
+
+
+/**
+ * A typesafe enumeration for byte orders.
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public final class ByteOrder {
+
+ private String name;
+
+ private ByteOrder(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Constant denoting big-endian byte order. In this order, the bytes of a
+ * multibyte value are ordered from most significant to least significant.
+ */
+ public static final ByteOrder BIG_ENDIAN
+ = new ByteOrder("BIG_ENDIAN");
+
+ /**
+ * Constant denoting little-endian byte order. In this order, the bytes of
+ * a multibyte value are ordered from least significant to most
+ * significant.
+ */
+ public static final ByteOrder LITTLE_ENDIAN
+ = new ByteOrder("LITTLE_ENDIAN");
+
+ /**
+ * Retrieves the native byte order of the underlying platform.
+ *
+ * <p> This method is defined so that performance-sensitive Java code can
+ * allocate direct buffers with the same byte order as the hardware.
+ * Native code libraries are often more efficient when such buffers are
+ * used. </p>
+ *
+ * @return The native byte order of the hardware upon which this Java
+ * virtual machine is running
+ */
+ public static ByteOrder nativeOrder() {
+ return Bits.byteOrder();
+ }
+
+ /**
+ * Constructs a string describing this object.
+ *
+ * <p> This method returns the string <tt>"BIG_ENDIAN"</tt> for {@link
+ * #BIG_ENDIAN} and <tt>"LITTLE_ENDIAN"</tt> for {@link #LITTLE_ENDIAN}.
+ * </p>
+ *
+ * @return The specified string
+ */
+ public String toString() {
+ return name;
+ }
+
+}
diff --git a/java/nio/CharBuffer.java b/java/nio/CharBuffer.java
new file mode 100644
index 0000000..6d73448
--- /dev/null
+++ b/java/nio/CharBuffer.java
@@ -0,0 +1,1274 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio;
+
+
+import java.io.IOException;
+import java.util.Spliterator;
+import java.util.stream.StreamSupport;
+import java.util.stream.IntStream;
+
+import dalvik.annotation.codegen.CovariantReturnType;
+
+
+/**
+ * A char buffer.
+ *
+ * <p> This class defines four categories of operations upon
+ * char buffers:
+ *
+ * <ul>
+ *
+ * <li><p> Absolute and relative {@link #get() <i>get</i>} and
+ * {@link #put(char) <i>put</i>} methods that read and write
+ * single chars; </p></li>
+ *
+ * <li><p> Relative {@link #get(char[]) <i>bulk get</i>}
+ * methods that transfer contiguous sequences of chars from this buffer
+ * into an array; and</p></li>
+ *
+ * <li><p> Relative {@link #put(char[]) <i>bulk put</i>}
+ * methods that transfer contiguous sequences of chars from a
+ * char array, a string, or some other char
+ * buffer into this buffer; and </p></li>
+ *
+ *
+ * <li><p> Methods for {@link #compact compacting}, {@link
+ * #duplicate duplicating}, and {@link #slice slicing}
+ * a char buffer. </p></li>
+ *
+ * </ul>
+ *
+ * <p> Char buffers can be created either by {@link #allocate
+ * <i>allocation</i>}, which allocates space for the buffer's
+ *
+ *
+ * content, by {@link #wrap(char[]) <i>wrapping</i>} an existing
+ * char array or string into a buffer, or by creating a
+ * <a href="ByteBuffer.html#views"><i>view</i></a> of an existing byte buffer.
+ *
+ *
+*
+ *
+ * <p> Like a byte buffer, a char buffer is either <a
+ * href="ByteBuffer.html#direct"><i>direct</i> or <i>non-direct</i></a>. A
+ * char buffer created via the <tt>wrap</tt> methods of this class will
+ * be non-direct. A char buffer created as a view of a byte buffer will
+ * be direct if, and only if, the byte buffer itself is direct. Whether or not
+ * a char buffer is direct may be determined by invoking the {@link
+ * #isDirect isDirect} method. </p>
+ *
+*
+ *
+ * <p> This class implements the {@link CharSequence} interface so that
+ * character buffers may be used wherever character sequences are accepted, for
+ * example in the regular-expression package <tt>{@link java.util.regex}</tt>.
+ * </p>
+ *
+ *
+ *
+ * <p> Methods in this class that do not otherwise have a value to return are
+ * specified to return the buffer upon which they are invoked. This allows
+ * method invocations to be chained.
+ *
+ *
+ * The sequence of statements
+ *
+ * <blockquote><pre>
+ * cb.put("text/");
+ * cb.put(subtype);
+ * cb.put("; charset=");
+ * cb.put(enc);</pre></blockquote>
+ *
+ * can, for example, be replaced by the single statement
+ *
+ * <blockquote><pre>
+ * cb.put("text/").put(subtype).put("; charset=").put(enc);</pre></blockquote>
+ *
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class CharBuffer
+ extends Buffer
+ implements Comparable<CharBuffer>, Appendable, CharSequence, Readable
+{
+
+ // These fields are declared here rather than in Heap-X-Buffer in order to
+ // reduce the number of virtual method invocations needed to access these
+ // values, which is especially costly when coding small buffers.
+ //
+ final char[] hb; // Non-null only for heap buffers
+ final int offset;
+ boolean isReadOnly; // Valid only for heap buffers
+
+ // Creates a new buffer with the given mark, position, limit, capacity,
+ // backing array, and array offset
+ //
+ CharBuffer(int mark, int pos, int lim, int cap, // package-private
+ char[] hb, int offset)
+ {
+ // Android-added: elementSizeShift parameter (log2 of element size).
+ super(mark, pos, lim, cap, 1 /* elementSizeShift */);
+ this.hb = hb;
+ this.offset = offset;
+ }
+
+ // Creates a new buffer with the given mark, position, limit, and capacity
+ //
+ CharBuffer(int mark, int pos, int lim, int cap) { // package-private
+ this(mark, pos, lim, cap, null, 0);
+ }
+
+
+ /**
+ * Allocates a new char buffer.
+ *
+ * <p> The new buffer's position will be zero, its limit will be its
+ * capacity, its mark will be undefined, and each of its elements will be
+ * initialized to zero. It will have a {@link #array backing array},
+ * and its {@link #arrayOffset array offset} will be zero.
+ *
+ * @param capacity
+ * The new buffer's capacity, in chars
+ *
+ * @return The new char buffer
+ *
+ * @throws IllegalArgumentException
+ * If the <tt>capacity</tt> is a negative integer
+ */
+ public static CharBuffer allocate(int capacity) {
+ if (capacity < 0)
+ throw new IllegalArgumentException();
+ return new HeapCharBuffer(capacity, capacity);
+ }
+
+ /**
+ * Wraps a char array into a buffer.
+ *
+ * <p> The new buffer will be backed by the given char array;
+ * that is, modifications to the buffer will cause the array to be modified
+ * and vice versa. The new buffer's capacity will be
+ * <tt>array.length</tt>, its position will be <tt>offset</tt>, its limit
+ * will be <tt>offset + length</tt>, and its mark will be undefined. Its
+ * {@link #array backing array} will be the given array, and
+ * its {@link #arrayOffset array offset} will be zero. </p>
+ *
+ * @param array
+ * The array that will back the new buffer
+ *
+ * @param offset
+ * The offset of the subarray to be used; must be non-negative and
+ * no larger than <tt>array.length</tt>. The new buffer's position
+ * will be set to this value.
+ *
+ * @param length
+ * The length of the subarray to be used;
+ * must be non-negative and no larger than
+ * <tt>array.length - offset</tt>.
+ * The new buffer's limit will be set to <tt>offset + length</tt>.
+ *
+ * @return The new char buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ */
+ public static CharBuffer wrap(char[] array,
+ int offset, int length)
+ {
+ try {
+ return new HeapCharBuffer(array, offset, length);
+ } catch (IllegalArgumentException x) {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+
+ /**
+ * Wraps a char array into a buffer.
+ *
+ * <p> The new buffer will be backed by the given char array;
+ * that is, modifications to the buffer will cause the array to be modified
+ * and vice versa. The new buffer's capacity and limit will be
+ * <tt>array.length</tt>, its position will be zero, and its mark will be
+ * undefined. Its {@link #array backing array} will be the
+ * given array, and its {@link #arrayOffset array offset>} will
+ * be zero. </p>
+ *
+ * @param array
+ * The array that will back this buffer
+ *
+ * @return The new char buffer
+ */
+ public static CharBuffer wrap(char[] array) {
+ return wrap(array, 0, array.length);
+ }
+
+
+ /**
+ * Attempts to read characters into the specified character buffer.
+ * The buffer is used as a repository of characters as-is: the only
+ * changes made are the results of a put operation. No flipping or
+ * rewinding of the buffer is performed.
+ *
+ * @param target the buffer to read characters into
+ * @return The number of characters added to the buffer, or
+ * -1 if this source of characters is at its end
+ * @throws IOException if an I/O error occurs
+ * @throws NullPointerException if target is null
+ * @throws ReadOnlyBufferException if target is a read only buffer
+ * @since 1.5
+ */
+ public int read(CharBuffer target) throws IOException {
+ // Determine the number of bytes n that can be transferred
+ int targetRemaining = target.remaining();
+ int remaining = remaining();
+ if (remaining == 0)
+ return -1;
+ int n = Math.min(remaining, targetRemaining);
+ int limit = limit();
+ // Set source limit to prevent target overflow
+ if (targetRemaining < remaining)
+ limit(position() + n);
+ try {
+ if (n > 0)
+ target.put(this);
+ } finally {
+ limit(limit); // restore real limit
+ }
+ return n;
+ }
+
+ /**
+ * Wraps a character sequence into a buffer.
+ *
+ * <p> The content of the new, read-only buffer will be the content of the
+ * given character sequence. The buffer's capacity will be
+ * <tt>csq.length()</tt>, its position will be <tt>start</tt>, its limit
+ * will be <tt>end</tt>, and its mark will be undefined. </p>
+ *
+ * @param csq
+ * The character sequence from which the new character buffer is to
+ * be created
+ *
+ * @param start
+ * The index of the first character to be used;
+ * must be non-negative and no larger than <tt>csq.length()</tt>.
+ * The new buffer's position will be set to this value.
+ *
+ * @param end
+ * The index of the character following the last character to be
+ * used; must be no smaller than <tt>start</tt> and no larger
+ * than <tt>csq.length()</tt>.
+ * The new buffer's limit will be set to this value.
+ *
+ * @return The new character buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>start</tt> and <tt>end</tt>
+ * parameters do not hold
+ */
+ public static CharBuffer wrap(CharSequence csq, int start, int end) {
+ try {
+ return new StringCharBuffer(csq, start, end);
+ } catch (IllegalArgumentException x) {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+
+ /**
+ * Wraps a character sequence into a buffer.
+ *
+ * <p> The content of the new, read-only buffer will be the content of the
+ * given character sequence. The new buffer's capacity and limit will be
+ * <tt>csq.length()</tt>, its position will be zero, and its mark will be
+ * undefined. </p>
+ *
+ * @param csq
+ * The character sequence from which the new character buffer is to
+ * be created
+ *
+ * @return The new character buffer
+ */
+ public static CharBuffer wrap(CharSequence csq) {
+ return wrap(csq, 0, csq.length());
+ }
+
+
+ /**
+ * Creates a new char buffer whose content is a shared subsequence of
+ * this buffer's content.
+ *
+ * <p> The content of the new buffer will start at this buffer's current
+ * position. Changes to this buffer's content will be visible in the new
+ * buffer, and vice versa; the two buffers' position, limit, and mark
+ * values will be independent.
+ *
+ * <p> The new buffer's position will be zero, its capacity and its limit
+ * will be the number of chars remaining in this buffer, and its mark
+ * will be undefined. The new buffer will be direct if, and only if, this
+ * buffer is direct, and it will be read-only if, and only if, this buffer
+ * is read-only. </p>
+ *
+ * @return The new char buffer
+ */
+ public abstract CharBuffer slice();
+
+ /**
+ * Creates a new char buffer that shares this buffer's content.
+ *
+ * <p> The content of the new buffer will be that of this buffer. Changes
+ * to this buffer's content will be visible in the new buffer, and vice
+ * versa; the two buffers' position, limit, and mark values will be
+ * independent.
+ *
+ * <p> The new buffer's capacity, limit, position, and mark values will be
+ * identical to those of this buffer. The new buffer will be direct if,
+ * and only if, this buffer is direct, and it will be read-only if, and
+ * only if, this buffer is read-only. </p>
+ *
+ * @return The new char buffer
+ */
+ public abstract CharBuffer duplicate();
+
+ /**
+ * Creates a new, read-only char buffer that shares this buffer's
+ * content.
+ *
+ * <p> The content of the new buffer will be that of this buffer. Changes
+ * to this buffer's content will be visible in the new buffer; the new
+ * buffer itself, however, will be read-only and will not allow the shared
+ * content to be modified. The two buffers' position, limit, and mark
+ * values will be independent.
+ *
+ * <p> The new buffer's capacity, limit, position, and mark values will be
+ * identical to those of this buffer.
+ *
+ * <p> If this buffer is itself read-only then this method behaves in
+ * exactly the same way as the {@link #duplicate duplicate} method. </p>
+ *
+ * @return The new, read-only char buffer
+ */
+ public abstract CharBuffer asReadOnlyBuffer();
+
+
+ // -- Singleton get/put methods --
+
+ /**
+ * Relative <i>get</i> method. Reads the char at this buffer's
+ * current position, and then increments the position.
+ *
+ * @return The char at the buffer's current position
+ *
+ * @throws BufferUnderflowException
+ * If the buffer's current position is not smaller than its limit
+ */
+ public abstract char get();
+
+ /**
+ * Relative <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> Writes the given char into this buffer at the current
+ * position, and then increments the position. </p>
+ *
+ * @param c
+ * The char to be written
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If this buffer's current position is not smaller than its limit
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract CharBuffer put(char c);
+
+ /**
+ * Absolute <i>get</i> method. Reads the char at the given
+ * index.
+ *
+ * @param index
+ * The index from which the char will be read
+ *
+ * @return The char at the given index
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
+ */
+ public abstract char get(int index);
+
+ /**
+ * Absolute <i>get</i> method. Reads the char at the given
+ * index without any validation of the index.
+ *
+ * @param index
+ * The index from which the char will be read
+ *
+ * @return The char at the given index
+ */
+ abstract char getUnchecked(int index); // package-private
+
+ /**
+ * Absolute <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> Writes the given char into this buffer at the given
+ * index. </p>
+ *
+ * @param index
+ * The index at which the char will be written
+ *
+ * @param c
+ * The char value to be written
+ *
+ * @return This buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract CharBuffer put(int index, char c);
+
+
+ // -- Bulk get operations --
+
+ /**
+ * Relative bulk <i>get</i> method.
+ *
+ * <p> This method transfers chars from this buffer into the given
+ * destination array. If there are fewer chars remaining in the
+ * buffer than are required to satisfy the request, that is, if
+ * <tt>length</tt> <tt>></tt> <tt>remaining()</tt>, then no
+ * chars are transferred and a {@link BufferUnderflowException} is
+ * thrown.
+ *
+ * <p> Otherwise, this method copies <tt>length</tt> chars from this
+ * buffer into the given array, starting at the current position of this
+ * buffer and at the given offset in the array. The position of this
+ * buffer is then incremented by <tt>length</tt>.
+ *
+ * <p> In other words, an invocation of this method of the form
+ * <tt>src.get(dst, off, len)</tt> has exactly the same effect as
+ * the loop
+ *
+ * <pre>{@code
+ * for (int i = off; i < off + len; i++)
+ * dst[i] = src.get();
+ * }</pre>
+ *
+ * except that it first checks that there are sufficient chars in
+ * this buffer and it is potentially much more efficient.
+ *
+ * @param dst
+ * The array into which chars are to be written
+ *
+ * @param offset
+ * The offset within the array of the first char to be
+ * written; must be non-negative and no larger than
+ * <tt>dst.length</tt>
+ *
+ * @param length
+ * The maximum number of chars to be written to the given
+ * array; must be non-negative and no larger than
+ * <tt>dst.length - offset</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than <tt>length</tt> chars
+ * remaining in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ */
+ public CharBuffer get(char[] dst, int offset, int length) {
+ checkBounds(offset, length, dst.length);
+ if (length > remaining())
+ throw new BufferUnderflowException();
+ int end = offset + length;
+ for (int i = offset; i < end; i++)
+ dst[i] = get();
+ return this;
+ }
+
+ /**
+ * Relative bulk <i>get</i> method.
+ *
+ * <p> This method transfers chars from this buffer into the given
+ * destination array. An invocation of this method of the form
+ * <tt>src.get(a)</tt> behaves in exactly the same way as the invocation
+ *
+ * <pre>
+ * src.get(a, 0, a.length) </pre>
+ *
+ * @param dst
+ * The destination array
+ *
+ * @return This buffer
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than <tt>length</tt> chars
+ * remaining in this buffer
+ */
+ public CharBuffer get(char[] dst) {
+ return get(dst, 0, dst.length);
+ }
+
+
+ // -- Bulk put operations --
+
+ /**
+ * Relative bulk <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> This method transfers the chars remaining in the given source
+ * buffer into this buffer. If there are more chars remaining in the
+ * source buffer than in this buffer, that is, if
+ * <tt>src.remaining()</tt> <tt>></tt> <tt>remaining()</tt>,
+ * then no chars are transferred and a {@link
+ * BufferOverflowException} is thrown.
+ *
+ * <p> Otherwise, this method copies
+ * <i>n</i> = <tt>src.remaining()</tt> chars from the given
+ * buffer into this buffer, starting at each buffer's current position.
+ * The positions of both buffers are then incremented by <i>n</i>.
+ *
+ * <p> In other words, an invocation of this method of the form
+ * <tt>dst.put(src)</tt> has exactly the same effect as the loop
+ *
+ * <pre>
+ * while (src.hasRemaining())
+ * dst.put(src.get()); </pre>
+ *
+ * except that it first checks that there is sufficient space in this
+ * buffer and it is potentially much more efficient.
+ *
+ * @param src
+ * The source buffer from which chars are to be read;
+ * must not be this buffer
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ * for the remaining chars in the source buffer
+ *
+ * @throws IllegalArgumentException
+ * If the source buffer is this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public CharBuffer put(CharBuffer src) {
+ if (src == this)
+ throw new IllegalArgumentException();
+ if (isReadOnly())
+ throw new ReadOnlyBufferException();
+ int n = src.remaining();
+ if (n > remaining())
+ throw new BufferOverflowException();
+ for (int i = 0; i < n; i++)
+ put(src.get());
+ return this;
+ }
+
+ /**
+ * Relative bulk <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> This method transfers chars into this buffer from the given
+ * source array. If there are more chars to be copied from the array
+ * than remain in this buffer, that is, if
+ * <tt>length</tt> <tt>></tt> <tt>remaining()</tt>, then no
+ * chars are transferred and a {@link BufferOverflowException} is
+ * thrown.
+ *
+ * <p> Otherwise, this method copies <tt>length</tt> chars from the
+ * given array into this buffer, starting at the given offset in the array
+ * and at the current position of this buffer. The position of this buffer
+ * is then incremented by <tt>length</tt>.
+ *
+ * <p> In other words, an invocation of this method of the form
+ * <tt>dst.put(src, off, len)</tt> has exactly the same effect as
+ * the loop
+ *
+ * <pre>{@code
+ * for (int i = off; i < off + len; i++)
+ * dst.put(a[i]);
+ * }</pre>
+ *
+ * except that it first checks that there is sufficient space in this
+ * buffer and it is potentially much more efficient.
+ *
+ * @param src
+ * The array from which chars are to be read
+ *
+ * @param offset
+ * The offset within the array of the first char to be read;
+ * must be non-negative and no larger than <tt>array.length</tt>
+ *
+ * @param length
+ * The number of chars to be read from the given array;
+ * must be non-negative and no larger than
+ * <tt>array.length - offset</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public CharBuffer put(char[] src, int offset, int length) {
+ checkBounds(offset, length, src.length);
+ if (length > remaining())
+ throw new BufferOverflowException();
+ int end = offset + length;
+ for (int i = offset; i < end; i++)
+ this.put(src[i]);
+ return this;
+ }
+
+ /**
+ * Relative bulk <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> This method transfers the entire content of the given source
+ * char array into this buffer. An invocation of this method of the
+ * form <tt>dst.put(a)</tt> behaves in exactly the same way as the
+ * invocation
+ *
+ * <pre>
+ * dst.put(a, 0, a.length) </pre>
+ *
+ * @param src
+ * The source array
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public final CharBuffer put(char[] src) {
+ return put(src, 0, src.length);
+ }
+
+
+ /**
+ * Relative bulk <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> This method transfers chars from the given string into this
+ * buffer. If there are more chars to be copied from the string than
+ * remain in this buffer, that is, if
+ * <tt>end - start</tt> <tt>></tt> <tt>remaining()</tt>,
+ * then no chars are transferred and a {@link
+ * BufferOverflowException} is thrown.
+ *
+ * <p> Otherwise, this method copies
+ * <i>n</i> = <tt>end</tt> - <tt>start</tt> chars
+ * from the given string into this buffer, starting at the given
+ * <tt>start</tt> index and at the current position of this buffer. The
+ * position of this buffer is then incremented by <i>n</i>.
+ *
+ * <p> In other words, an invocation of this method of the form
+ * <tt>dst.put(src, start, end)</tt> has exactly the same effect
+ * as the loop
+ *
+ * <pre>{@code
+ * for (int i = start; i < end; i++)
+ * dst.put(src.charAt(i));
+ * }</pre>
+ *
+ * except that it first checks that there is sufficient space in this
+ * buffer and it is potentially much more efficient.
+ *
+ * @param src
+ * The string from which chars are to be read
+ *
+ * @param start
+ * The offset within the string of the first char to be read;
+ * must be non-negative and no larger than
+ * <tt>string.length()</tt>
+ *
+ * @param end
+ * The offset within the string of the last char to be read,
+ * plus one; must be non-negative and no larger than
+ * <tt>string.length()</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>start</tt> and <tt>end</tt>
+ * parameters do not hold
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public CharBuffer put(String src, int start, int end) {
+ checkBounds(start, end - start, src.length());
+
+ // BEGIN Android-added: Don't check readonly/overflow if there's nothing to write.
+ // This is questionable behaviour but code expects it.
+ if (start == end) {
+ return this;
+ }
+ // END Android-added: Don't check readonly/overflow if there's nothing to write.
+
+ if (isReadOnly())
+ throw new ReadOnlyBufferException();
+ if (end - start > remaining())
+ throw new BufferOverflowException();
+ for (int i = start; i < end; i++)
+ this.put(src.charAt(i));
+ return this;
+ }
+
+ /**
+ * Relative bulk <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> This method transfers the entire content of the given source string
+ * into this buffer. An invocation of this method of the form
+ * <tt>dst.put(s)</tt> behaves in exactly the same way as the invocation
+ *
+ * <pre>
+ * dst.put(s, 0, s.length()) </pre>
+ *
+ * @param src
+ * The source string
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public final CharBuffer put(String src) {
+ return put(src, 0, src.length());
+ }
+
+
+ // -- Other stuff --
+
+ /**
+ * Tells whether or not this buffer is backed by an accessible char
+ * array.
+ *
+ * <p> If this method returns <tt>true</tt> then the {@link #array() array}
+ * and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
+ * </p>
+ *
+ * @return <tt>true</tt> if, and only if, this buffer
+ * is backed by an array and is not read-only
+ */
+ public final boolean hasArray() {
+ return (hb != null) && !isReadOnly;
+ }
+
+ /**
+ * Returns the char array that backs this
+ * buffer <i>(optional operation)</i>.
+ *
+ * <p> Modifications to this buffer's content will cause the returned
+ * array's content to be modified, and vice versa.
+ *
+ * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+ * method in order to ensure that this buffer has an accessible backing
+ * array. </p>
+ *
+ * @return The array that backs this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
+ */
+ public final char[] array() {
+ if (hb == null)
+ throw new UnsupportedOperationException();
+ if (isReadOnly)
+ throw new ReadOnlyBufferException();
+ return hb;
+ }
+
+ /**
+ * Returns the offset within this buffer's backing array of the first
+ * element of the buffer <i>(optional operation)</i>.
+ *
+ * <p> If this buffer is backed by an array then buffer position <i>p</i>
+ * corresponds to array index <i>p</i> + <tt>arrayOffset()</tt>.
+ *
+ * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+ * method in order to ensure that this buffer has an accessible backing
+ * array. </p>
+ *
+ * @return The offset within this buffer's array
+ * of the first element of the buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
+ */
+ public final int arrayOffset() {
+ if (hb == null)
+ throw new UnsupportedOperationException();
+ if (isReadOnly)
+ throw new ReadOnlyBufferException();
+ return offset;
+ }
+
+ // BEGIN Android-added: covariant overloads of *Buffer methods that return this.
+ @CovariantReturnType(returnType = CharBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer position(int newPosition) {
+ return super.position(newPosition);
+ }
+
+ @CovariantReturnType(returnType = CharBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer limit(int newLimit) {
+ return super.limit(newLimit);
+ }
+
+ @CovariantReturnType(returnType = CharBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer mark() {
+ return super.mark();
+ }
+
+ @CovariantReturnType(returnType = CharBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer reset() {
+ return super.reset();
+ }
+
+ @CovariantReturnType(returnType = CharBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer clear() {
+ return super.clear();
+ }
+
+ @CovariantReturnType(returnType = CharBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer flip() {
+ return super.flip();
+ }
+
+ @CovariantReturnType(returnType = CharBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer rewind() {
+ return super.rewind();
+ }
+ // END Android-added: covariant overloads of *Buffer methods that return this.
+
+ /**
+ * Compacts this buffer <i>(optional operation)</i>.
+ *
+ * <p> The chars between the buffer's current position and its limit,
+ * if any, are copied to the beginning of the buffer. That is, the
+ * char at index <i>p</i> = <tt>position()</tt> is copied
+ * to index zero, the char at index <i>p</i> + 1 is copied
+ * to index one, and so forth until the char at index
+ * <tt>limit()</tt> - 1 is copied to index
+ * <i>n</i> = <tt>limit()</tt> - <tt>1</tt> - <i>p</i>.
+ * The buffer's position is then set to <i>n+1</i> and its limit is set to
+ * its capacity. The mark, if defined, is discarded.
+ *
+ * <p> The buffer's position is set to the number of chars copied,
+ * rather than to zero, so that an invocation of this method can be
+ * followed immediately by an invocation of another relative <i>put</i>
+ * method. </p>
+ *
+
+ *
+ * @return This buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract CharBuffer compact();
+
+ /**
+ * Tells whether or not this char buffer is direct.
+ *
+ * @return <tt>true</tt> if, and only if, this buffer is direct
+ */
+ public abstract boolean isDirect();
+
+
+ /**
+ * Returns the current hash code of this buffer.
+ *
+ * <p> The hash code of a char buffer depends only upon its remaining
+ * elements; that is, upon the elements from <tt>position()</tt> up to, and
+ * including, the element at <tt>limit()</tt> - <tt>1</tt>.
+ *
+ * <p> Because buffer hash codes are content-dependent, it is inadvisable
+ * to use buffers as keys in hash maps or similar data structures unless it
+ * is known that their contents will not change. </p>
+ *
+ * @return The current hash code of this buffer
+ */
+ public int hashCode() {
+ int h = 1;
+ int p = position();
+ for (int i = limit() - 1; i >= p; i--)
+ h = 31 * h + (int) get(i);
+ return h;
+ }
+
+ /**
+ * Tells whether or not this buffer is equal to another object.
+ *
+ * <p> Two char buffers are equal if, and only if,
+ *
+ * <ol>
+ *
+ * <li><p> They have the same element type, </p></li>
+ *
+ * <li><p> They have the same number of remaining elements, and
+ * </p></li>
+ *
+ * <li><p> The two sequences of remaining elements, considered
+ * independently of their starting positions, are pointwise equal.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * </p></li>
+ *
+ * </ol>
+ *
+ * <p> A char buffer is not equal to any other type of object. </p>
+ *
+ * @param ob The object to which this buffer is to be compared
+ *
+ * @return <tt>true</tt> if, and only if, this buffer is equal to the
+ * given object
+ */
+ public boolean equals(Object ob) {
+ if (this == ob)
+ return true;
+ if (!(ob instanceof CharBuffer))
+ return false;
+ CharBuffer that = (CharBuffer)ob;
+ if (this.remaining() != that.remaining())
+ return false;
+ int p = this.position();
+ for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--)
+ if (!equals(this.get(i), that.get(j)))
+ return false;
+ return true;
+ }
+
+ private static boolean equals(char x, char y) {
+
+
+ return x == y;
+
+ }
+
+ /**
+ * Compares this buffer to another.
+ *
+ * <p> Two char buffers are compared by comparing their sequences of
+ * remaining elements lexicographically, without regard to the starting
+ * position of each sequence within its corresponding buffer.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * Pairs of {@code char} elements are compared as if by invoking
+ * {@link Character#compare(char,char)}.
+
+ *
+ * <p> A char buffer is not comparable to any other type of object.
+ *
+ * @return A negative integer, zero, or a positive integer as this buffer
+ * is less than, equal to, or greater than the given buffer
+ */
+ public int compareTo(CharBuffer that) {
+ int n = this.position() + Math.min(this.remaining(), that.remaining());
+ for (int i = this.position(), j = that.position(); i < n; i++, j++) {
+ int cmp = compare(this.get(i), that.get(j));
+ if (cmp != 0)
+ return cmp;
+ }
+ return this.remaining() - that.remaining();
+ }
+
+ private static int compare(char x, char y) {
+
+
+ return Character.compare(x, y);
+
+ }
+
+ // -- Other char stuff --
+
+
+ /**
+ * Returns a string containing the characters in this buffer.
+ *
+ * <p> The first character of the resulting string will be the character at
+ * this buffer's position, while the last character will be the character
+ * at index <tt>limit()</tt> - 1. Invoking this method does not
+ * change the buffer's position. </p>
+ *
+ * @return The specified string
+ */
+ public String toString() {
+ return toString(position(), limit());
+ }
+
+ abstract String toString(int start, int end); // package-private
+
+
+ // --- Methods to support CharSequence ---
+
+ /**
+ * Returns the length of this character buffer.
+ *
+ * <p> When viewed as a character sequence, the length of a character
+ * buffer is simply the number of characters between the position
+ * (inclusive) and the limit (exclusive); that is, it is equivalent to
+ * <tt>remaining()</tt>. </p>
+ *
+ * @return The length of this character buffer
+ */
+ public final int length() {
+ return remaining();
+ }
+
+ /**
+ * Reads the character at the given index relative to the current
+ * position.
+ *
+ * @param index
+ * The index of the character to be read, relative to the position;
+ * must be non-negative and smaller than <tt>remaining()</tt>
+ *
+ * @return The character at index
+ * <tt>position() + index</tt>
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on <tt>index</tt> do not hold
+ */
+ public final char charAt(int index) {
+ return get(position() + checkIndex(index, 1));
+ }
+
+ /**
+ * Creates a new character buffer that represents the specified subsequence
+ * of this buffer, relative to the current position.
+ *
+ * <p> The new buffer will share this buffer's content; that is, if the
+ * content of this buffer is mutable then modifications to one buffer will
+ * cause the other to be modified. The new buffer's capacity will be that
+ * of this buffer, its position will be
+ * <tt>position()</tt> + <tt>start</tt>, and its limit will be
+ * <tt>position()</tt> + <tt>end</tt>. The new buffer will be
+ * direct if, and only if, this buffer is direct, and it will be read-only
+ * if, and only if, this buffer is read-only. </p>
+ *
+ * @param start
+ * The index, relative to the current position, of the first
+ * character in the subsequence; must be non-negative and no larger
+ * than <tt>remaining()</tt>
+ *
+ * @param end
+ * The index, relative to the current position, of the character
+ * following the last character in the subsequence; must be no
+ * smaller than <tt>start</tt> and no larger than
+ * <tt>remaining()</tt>
+ *
+ * @return The new character buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on <tt>start</tt> and <tt>end</tt>
+ * do not hold
+ */
+ public abstract CharBuffer subSequence(int start, int end);
+
+
+ // --- Methods to support Appendable ---
+
+ /**
+ * Appends the specified character sequence to this
+ * buffer <i>(optional operation)</i>.
+ *
+ * <p> An invocation of this method of the form <tt>dst.append(csq)</tt>
+ * behaves in exactly the same way as the invocation
+ *
+ * <pre>
+ * dst.put(csq.toString()) </pre>
+ *
+ * <p> Depending on the specification of <tt>toString</tt> for the
+ * character sequence <tt>csq</tt>, the entire sequence may not be
+ * appended. For instance, invoking the {@link CharBuffer#toString()
+ * toString} method of a character buffer will return a subsequence whose
+ * content depends upon the buffer's position and limit.
+ *
+ * @param csq
+ * The character sequence to append. If <tt>csq</tt> is
+ * <tt>null</tt>, then the four characters <tt>"null"</tt> are
+ * appended to this character buffer.
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ *
+ * @since 1.5
+ */
+ public CharBuffer append(CharSequence csq) {
+ if (csq == null)
+ return put("null");
+ else
+ return put(csq.toString());
+ }
+
+ /**
+ * Appends a subsequence of the specified character sequence to this
+ * buffer <i>(optional operation)</i>.
+ *
+ * <p> An invocation of this method of the form <tt>dst.append(csq, start,
+ * end)</tt> when <tt>csq</tt> is not <tt>null</tt>, behaves in exactly the
+ * same way as the invocation
+ *
+ * <pre>
+ * dst.put(csq.subSequence(start, end).toString()) </pre>
+ *
+ * @param csq
+ * The character sequence from which a subsequence will be
+ * appended. If <tt>csq</tt> is <tt>null</tt>, then characters
+ * will be appended as if <tt>csq</tt> contained the four
+ * characters <tt>"null"</tt>.
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>start</tt> or <tt>end</tt> are negative, <tt>start</tt>
+ * is greater than <tt>end</tt>, or <tt>end</tt> is greater than
+ * <tt>csq.length()</tt>
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ *
+ * @since 1.5
+ */
+ public CharBuffer append(CharSequence csq, int start, int end) {
+ CharSequence cs = (csq == null ? "null" : csq);
+ return put(cs.subSequence(start, end).toString());
+ }
+
+ /**
+ * Appends the specified char to this
+ * buffer <i>(optional operation)</i>.
+ *
+ * <p> An invocation of this method of the form <tt>dst.append(c)</tt>
+ * behaves in exactly the same way as the invocation
+ *
+ * <pre>
+ * dst.put(c) </pre>
+ *
+ * @param c
+ * The 16-bit char to append
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ *
+ * @since 1.5
+ */
+ public CharBuffer append(char c) {
+ return put(c);
+ }
+
+
+ // -- Other byte stuff: Access to binary data --
+
+
+ /**
+ * Retrieves this buffer's byte order.
+ *
+ * <p> The byte order of a char buffer created by allocation or by
+ * wrapping an existing <tt>char</tt> array is the {@link
+ * ByteOrder#nativeOrder native order} of the underlying
+ * hardware. The byte order of a char buffer created as a <a
+ * href="ByteBuffer.html#views">view</a> of a byte buffer is that of the
+ * byte buffer at the moment that the view is created. </p>
+ *
+ * @return This buffer's byte order
+ */
+ public abstract ByteOrder order();
+
+ @Override
+ public IntStream chars() {
+ return StreamSupport.intStream(() -> new CharBufferSpliterator(this),
+ Buffer.SPLITERATOR_CHARACTERISTICS, false);
+ }
+}
diff --git a/java/nio/CharBufferSpliterator.java b/java/nio/CharBufferSpliterator.java
new file mode 100644
index 0000000..5b3977a
--- /dev/null
+++ b/java/nio/CharBufferSpliterator.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio;
+
+import java.util.Comparator;
+import java.util.Spliterator;
+import java.util.function.IntConsumer;
+
+/**
+ * A Spliterator.OfInt for sources that traverse and split elements
+ * maintained in a CharBuffer.
+ *
+ * @implNote
+ * The implementation is based on the code for the Array-based spliterators.
+ */
+class CharBufferSpliterator implements Spliterator.OfInt {
+ private final CharBuffer buffer;
+ private int index; // current index, modified on advance/split
+ private final int limit;
+
+ CharBufferSpliterator(CharBuffer buffer) {
+ this(buffer, buffer.position(), buffer.limit());
+ }
+
+ CharBufferSpliterator(CharBuffer buffer, int origin, int limit) {
+ assert origin <= limit;
+ this.buffer = buffer;
+ this.index = (origin <= limit) ? origin : limit;
+ this.limit = limit;
+ }
+
+ @Override
+ public OfInt trySplit() {
+ int lo = index, mid = (lo + limit) >>> 1;
+ return (lo >= mid)
+ ? null
+ : new CharBufferSpliterator(buffer, lo, index = mid);
+ }
+
+ @Override
+ public void forEachRemaining(IntConsumer action) {
+ if (action == null)
+ throw new NullPointerException();
+ CharBuffer cb = buffer;
+ int i = index;
+ int hi = limit;
+ index = hi;
+ while (i < hi) {
+ action.accept(cb.getUnchecked(i++));
+ }
+ }
+
+ @Override
+ public boolean tryAdvance(IntConsumer action) {
+ if (action == null)
+ throw new NullPointerException();
+ if (index >= 0 && index < limit) {
+ action.accept(buffer.getUnchecked(index++));
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public long estimateSize() {
+ return (long)(limit - index);
+ }
+
+ @Override
+ public int characteristics() {
+ return Buffer.SPLITERATOR_CHARACTERISTICS;
+ }
+}
diff --git a/java/nio/DirectByteBuffer.annotated.java b/java/nio/DirectByteBuffer.annotated.java
new file mode 100644
index 0000000..51e0e9c
--- /dev/null
+++ b/java/nio/DirectByteBuffer.annotated.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.nio;
+
+
[email protected]
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class DirectByteBuffer extends java.nio.MappedByteBuffer implements sun.nio.ch.DirectBuffer {
+
[email protected]
+public DirectByteBuffer(int cap, long addr, java.io.FileDescriptor fd, java.lang.Runnable unmapper, boolean isReadOnly) { super(0, 0, 0, 0); throw new RuntimeException("Stub!"); }
+
+public final java.lang.Object attachment() { throw new RuntimeException("Stub!"); }
+
+public final sun.misc.Cleaner cleaner() { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer slice() { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer duplicate() { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer asReadOnlyBuffer() { throw new RuntimeException("Stub!"); }
+
[email protected]
+public final long address() { throw new RuntimeException("Stub!"); }
+
+public final byte get() { throw new RuntimeException("Stub!"); }
+
+public final byte get(int i) { throw new RuntimeException("Stub!"); }
+
+public java.nio.ByteBuffer get(byte[] dst, int dstOffset, int length) { throw new RuntimeException("Stub!"); }
+
+public java.nio.ByteBuffer put(java.nio.ByteBuffer src) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer put(byte x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer put(int i, byte x) { throw new RuntimeException("Stub!"); }
+
+public java.nio.ByteBuffer put(byte[] src, int srcOffset, int length) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer compact() { throw new RuntimeException("Stub!"); }
+
+public final boolean isDirect() { throw new RuntimeException("Stub!"); }
+
+public final boolean isReadOnly() { throw new RuntimeException("Stub!"); }
+
+public final char getChar() { throw new RuntimeException("Stub!"); }
+
+public final char getChar(int i) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putChar(char x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putChar(int i, char x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.CharBuffer asCharBuffer() { throw new RuntimeException("Stub!"); }
+
+public final short getShort() { throw new RuntimeException("Stub!"); }
+
+public final short getShort(int i) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putShort(short x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putShort(int i, short x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ShortBuffer asShortBuffer() { throw new RuntimeException("Stub!"); }
+
+public int getInt() { throw new RuntimeException("Stub!"); }
+
+public int getInt(int i) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putInt(int x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putInt(int i, int x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.IntBuffer asIntBuffer() { throw new RuntimeException("Stub!"); }
+
+public final long getLong() { throw new RuntimeException("Stub!"); }
+
+public final long getLong(int i) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putLong(long x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putLong(int i, long x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.LongBuffer asLongBuffer() { throw new RuntimeException("Stub!"); }
+
+public final float getFloat() { throw new RuntimeException("Stub!"); }
+
+public final float getFloat(int i) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putFloat(float x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putFloat(int i, float x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.FloatBuffer asFloatBuffer() { throw new RuntimeException("Stub!"); }
+
+public final double getDouble() { throw new RuntimeException("Stub!"); }
+
+public final double getDouble(int i) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putDouble(double x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putDouble(int i, double x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.DoubleBuffer asDoubleBuffer() { throw new RuntimeException("Stub!"); }
+
+public final boolean isAccessible() { throw new RuntimeException("Stub!"); }
+
+public final void setAccessible(boolean value) { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/java/nio/DirectByteBuffer.java b/java/nio/DirectByteBuffer.java
new file mode 100644
index 0000000..3e06011
--- /dev/null
+++ b/java/nio/DirectByteBuffer.java
@@ -0,0 +1,975 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio;
+
+import java.io.FileDescriptor;
+
+import dalvik.system.VMRuntime;
+import libcore.io.Memory;
+import sun.misc.Cleaner;
+import sun.nio.ch.DirectBuffer;
+
+// Not final because it is extended in tests.
+/** @hide */
+public class DirectByteBuffer extends MappedByteBuffer implements DirectBuffer {
+
+ /**
+ * Stores the details of the memory backing a DirectByteBuffer. This could be a pointer
+ * (passed through from JNI or resulting from a mapping) or a non-movable byte array allocated
+ * from Java. Each MemoryRef also has an isAccessible associated with it, which determines
+ * whether the underlying memory is "accessible". The notion of "accessibility" is usually
+ * defined by the allocator of the reference, and is separate from the accessibility of the
+ * memory as defined by the underlying system.
+ *
+ * A single MemoryRef instance is shared across all slices and duplicates of a given buffer.
+ */
+ final static class MemoryRef {
+ byte[] buffer;
+ long allocatedAddress;
+ final int offset;
+ boolean isAccessible;
+ boolean isFreed;
+
+
+ // Reference to original DirectByteBuffer that held this MemoryRef. The field is set
+ // only for the MemoryRef created through JNI NewDirectByteBuffer(void*, long) function.
+ // This allows users of JNI NewDirectByteBuffer to create a PhantomReference on the
+ // DirectByteBuffer instance that will only be put in the associated ReferenceQueue when
+ // the underlying memory is not referenced by any DirectByteBuffer instance. The
+ // MemoryRef can outlive the original DirectByteBuffer instance if, for example, slice()
+ // or asReadOnlyBuffer() are called and all strong references to the original DirectByteBuffer
+ // are discarded.
+ final Object originalBufferObject;
+
+ MemoryRef(int capacity) {
+ VMRuntime runtime = VMRuntime.getRuntime();
+ buffer = (byte[]) runtime.newNonMovableArray(byte.class, capacity + 7);
+ allocatedAddress = runtime.addressOf(buffer);
+ // Offset is set to handle the alignment: http://b/16449607
+ offset = (int) (((allocatedAddress + 7) & ~(long) 7) - allocatedAddress);
+ isAccessible = true;
+ isFreed = false;
+ originalBufferObject = null;
+ }
+
+ MemoryRef(long allocatedAddress, Object originalBufferObject) {
+ buffer = null;
+ this.allocatedAddress = allocatedAddress;
+ this.offset = 0;
+ this.originalBufferObject = originalBufferObject;
+ isAccessible = true;
+ }
+
+ void free() {
+ buffer = null;
+ allocatedAddress = 0;
+ isAccessible = false;
+ isFreed = true;
+ }
+ }
+
+ final Cleaner cleaner;
+ final MemoryRef memoryRef;
+
+ DirectByteBuffer(int capacity, MemoryRef memoryRef) {
+ super(-1, 0, capacity, capacity, memoryRef.buffer, memoryRef.offset);
+ // Only have references to java objects, no need for a cleaner since the GC will do all
+ // the work.
+ this.memoryRef = memoryRef;
+ this.address = memoryRef.allocatedAddress + memoryRef.offset;
+ cleaner = null;
+ this.isReadOnly = false;
+ }
+
+ // Invoked only by JNI: NewDirectByteBuffer(void*, long)
+ @SuppressWarnings("unused")
+ private DirectByteBuffer(long addr, int cap) {
+ super(-1, 0, cap, cap);
+ memoryRef = new MemoryRef(addr, this);
+ address = addr;
+ cleaner = null;
+ }
+
+ /** @hide */
+ public DirectByteBuffer(int cap, long addr,
+ FileDescriptor fd,
+ Runnable unmapper,
+ boolean isReadOnly) {
+ super(-1, 0, cap, cap, fd);
+ this.isReadOnly = isReadOnly;
+ memoryRef = new MemoryRef(addr, null);
+ address = addr;
+ cleaner = Cleaner.create(memoryRef, unmapper);
+ }
+
+ // For duplicates and slices
+ DirectByteBuffer(MemoryRef memoryRef, // package-private
+ int mark, int pos, int lim, int cap,
+ int off) {
+ this(memoryRef, mark, pos, lim, cap, off, false);
+ }
+
+ DirectByteBuffer(MemoryRef memoryRef, // package-private
+ int mark, int pos, int lim, int cap,
+ int off, boolean isReadOnly) {
+ super(mark, pos, lim, cap, memoryRef.buffer, off);
+ this.isReadOnly = isReadOnly;
+ this.memoryRef = memoryRef;
+ address = memoryRef.allocatedAddress + off;
+ cleaner = null;
+ }
+
+ @Override
+ public final Object attachment() {
+ return memoryRef;
+ }
+
+ @Override
+ public final Cleaner cleaner() {
+ return cleaner;
+ }
+
+ @Override
+ public final ByteBuffer slice() {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ int pos = position();
+ int lim = limit();
+ assert (pos <= lim);
+ int rem = (pos <= lim ? lim - pos : 0);
+ int off = pos + offset;
+ assert (off >= 0);
+ return new DirectByteBuffer(memoryRef, -1, 0, rem, rem, off, isReadOnly);
+ }
+
+ @Override
+ public final ByteBuffer duplicate() {
+ if (memoryRef.isFreed) {
+ throw new IllegalStateException("buffer has been freed");
+ }
+ return new DirectByteBuffer(memoryRef,
+ this.markValue(),
+ this.position(),
+ this.limit(),
+ this.capacity(),
+ offset,
+ isReadOnly);
+ }
+
+ @Override
+ public final ByteBuffer asReadOnlyBuffer() {
+ if (memoryRef.isFreed) {
+ throw new IllegalStateException("buffer has been freed");
+ }
+ return new DirectByteBuffer(memoryRef,
+ this.markValue(),
+ this.position(),
+ this.limit(),
+ this.capacity(),
+ offset,
+ true);
+ }
+
+ @Override
+ public final long address() {
+ return address;
+ }
+
+ private long ix(int i) {
+ return address + i;
+ }
+
+ private byte get(long a) {
+ return Memory.peekByte(a);
+ }
+
+ @Override
+ public final byte get() {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ return get(ix(nextGetIndex()));
+ }
+
+ @Override
+ public final byte get(int i) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ return get(ix(checkIndex(i)));
+ }
+
+ // This method is not declared final because it is overridden in tests.
+ @Override
+ public ByteBuffer get(byte[] dst, int dstOffset, int length) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ checkBounds(dstOffset, length, dst.length);
+ int pos = position();
+ int lim = limit();
+ assert (pos <= lim);
+ int rem = (pos <= lim ? lim - pos : 0);
+ if (length > rem)
+ throw new BufferUnderflowException();
+ Memory.peekByteArray(ix(pos),
+ dst, dstOffset, length);
+ position = pos + length;
+ return this;
+ }
+
+ private ByteBuffer put(long a, byte x) {
+ Memory.pokeByte(a, x);
+ return this;
+ }
+
+ @Override
+ public ByteBuffer put(ByteBuffer src) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ return super.put(src);
+ }
+
+ @Override
+ public final ByteBuffer put(byte x) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ put(ix(nextPutIndex()), x);
+ return this;
+ }
+
+ @Override
+ public final ByteBuffer put(int i, byte x) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ put(ix(checkIndex(i)), x);
+ return this;
+ }
+
+ // This method is not declared final because it is overridden in tests.
+ @Override
+ public ByteBuffer put(byte[] src, int srcOffset, int length) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ checkBounds(srcOffset, length, src.length);
+ int pos = position();
+ int lim = limit();
+ assert (pos <= lim);
+ int rem = (pos <= lim ? lim - pos : 0);
+ if (length > rem)
+ throw new BufferOverflowException();
+ Memory.pokeByteArray(ix(pos),
+ src, srcOffset, length);
+ position = pos + length;
+ return this;
+ }
+
+ @Override
+ public final ByteBuffer compact() {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ int pos = position();
+ int lim = limit();
+ assert (pos <= lim);
+ int rem = (pos <= lim ? lim - pos : 0);
+ System.arraycopy(hb, position + offset, hb, offset, remaining());
+ position(rem);
+ limit(capacity());
+ discardMark();
+ return this;
+ }
+
+ @Override
+ public final boolean isDirect() {
+ return true;
+ }
+
+ @Override
+ public final boolean isReadOnly() {
+ return isReadOnly;
+ }
+
+ // Used by java.nio.Bits
+ @Override
+ final byte _get(int i) { // package-private
+ return get(i);
+ }
+
+ // Used by java.nio.Bits
+ @Override
+ final void _put(int i, byte b) { // package-private
+ put(i, b);
+ }
+
+ @Override
+ public final char getChar() {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ int newPosition = position + Character.BYTES;
+ if (newPosition > limit()) {
+ throw new BufferUnderflowException();
+ }
+ char x = (char) Memory.peekShort(ix(position), !nativeByteOrder);
+ position = newPosition;
+ return x;
+ }
+
+ @Override
+ public final char getChar(int i) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ checkIndex(i, Character.BYTES);
+ return (char) Memory.peekShort(ix(i), !nativeByteOrder);
+ }
+
+ @Override
+ char getCharUnchecked(int i) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ return (char) Memory.peekShort(ix(i), !nativeByteOrder);
+ }
+
+ @Override
+ void getUnchecked(int pos, char[] dst, int dstOffset, int length) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ Memory.peekCharArray(ix(pos),
+ dst, dstOffset, length, !nativeByteOrder);
+ }
+
+ private ByteBuffer putChar(long a, char x) {
+ Memory.pokeShort(a, (short) x, !nativeByteOrder);
+ return this;
+ }
+
+ @Override
+ public final ByteBuffer putChar(char x) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ putChar(ix(nextPutIndex(Character.BYTES)), x);
+ return this;
+ }
+
+ @Override
+ public final ByteBuffer putChar(int i, char x) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ putChar(ix(checkIndex(i, Character.BYTES)), x);
+ return this;
+ }
+
+ @Override
+ void putCharUnchecked(int i, char x) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ putChar(ix(i), x);
+ }
+
+ @Override
+ void putUnchecked(int pos, char[] src, int srcOffset, int length) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ Memory.pokeCharArray(ix(pos),
+ src, srcOffset, length, !nativeByteOrder);
+ }
+
+ @Override
+ public final CharBuffer asCharBuffer() {
+ if (memoryRef.isFreed) {
+ throw new IllegalStateException("buffer has been freed");
+ }
+ int off = this.position();
+ int lim = this.limit();
+ assert (off <= lim);
+ int rem = (off <= lim ? lim - off : 0);
+ int size = rem >> 1;
+ return new ByteBufferAsCharBuffer(this,
+ -1,
+ 0,
+ size,
+ size,
+ off,
+ order());
+ }
+
+ private short getShort(long a) {
+ return Memory.peekShort(a, !nativeByteOrder);
+ }
+
+ @Override
+ public final short getShort() {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ return getShort(ix(nextGetIndex(Short.BYTES)));
+ }
+
+ @Override
+ public final short getShort(int i) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ return getShort(ix(checkIndex(i, Short.BYTES)));
+ }
+
+ @Override
+ short getShortUnchecked(int i) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ return getShort(ix(i));
+ }
+
+ @Override
+ void getUnchecked(int pos, short[] dst, int dstOffset, int length) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ Memory.peekShortArray(ix(pos),
+ dst, dstOffset, length, !nativeByteOrder);
+ }
+
+ private ByteBuffer putShort(long a, short x) {
+ Memory.pokeShort(a, x, !nativeByteOrder);
+ return this;
+ }
+
+ @Override
+ public final ByteBuffer putShort(short x) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ putShort(ix(nextPutIndex(Short.BYTES)), x);
+ return this;
+ }
+
+ @Override
+ public final ByteBuffer putShort(int i, short x) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ putShort(ix(checkIndex(i, Short.BYTES)), x);
+ return this;
+ }
+
+ @Override
+ void putShortUnchecked(int i, short x) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ putShort(ix(i), x);
+ }
+
+ @Override
+ void putUnchecked(int pos, short[] src, int srcOffset, int length) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ Memory.pokeShortArray(ix(pos),
+ src, srcOffset, length, !nativeByteOrder);
+ }
+
+ @Override
+ public final ShortBuffer asShortBuffer() {
+ if (memoryRef.isFreed) {
+ throw new IllegalStateException("buffer has been freed");
+ }
+ int off = this.position();
+ int lim = this.limit();
+ assert (off <= lim);
+ int rem = (off <= lim ? lim - off : 0);
+ int size = rem >> 1;
+ return new ByteBufferAsShortBuffer(this,
+ -1,
+ 0,
+ size,
+ size,
+ off,
+ order());
+ }
+
+ private int getInt(long a) {
+ return Memory.peekInt(a, !nativeByteOrder);
+ }
+
+ @Override
+ public int getInt() {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ return getInt(ix(nextGetIndex(Integer.BYTES)));
+ }
+
+ @Override
+ public int getInt(int i) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ return getInt(ix(checkIndex(i, (Integer.BYTES))));
+ }
+
+ @Override
+ final int getIntUnchecked(int i) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ return getInt(ix(i));
+ }
+
+ @Override
+ final void getUnchecked(int pos, int[] dst, int dstOffset, int length) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ Memory.peekIntArray(ix(pos),
+ dst, dstOffset, length, !nativeByteOrder);
+ }
+
+ private ByteBuffer putInt(long a, int x) {
+ Memory.pokeInt(a, x, !nativeByteOrder);
+ return this;
+ }
+
+ @Override
+ public final ByteBuffer putInt(int x) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ putInt(ix(nextPutIndex(Integer.BYTES)), x);
+ return this;
+ }
+
+ @Override
+ public final ByteBuffer putInt(int i, int x) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ putInt(ix(checkIndex(i, Integer.BYTES)), x);
+ return this;
+ }
+
+ @Override
+ final void putIntUnchecked(int i, int x) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ putInt(ix(i), x);
+ }
+
+ @Override
+ final void putUnchecked(int pos, int[] src, int srcOffset, int length) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ Memory.pokeIntArray(ix(pos),
+ src, srcOffset, length, !nativeByteOrder);
+ }
+
+ @Override
+ public final IntBuffer asIntBuffer() {
+ if (memoryRef.isFreed) {
+ throw new IllegalStateException("buffer has been freed");
+ }
+ int off = this.position();
+ int lim = this.limit();
+ assert (off <= lim);
+ int rem = (off <= lim ? lim - off : 0);
+ int size = rem >> 2;
+ return new ByteBufferAsIntBuffer(this,
+ -1,
+ 0,
+ size,
+ size,
+ off,
+ order());
+ }
+
+ private long getLong(long a) {
+ return Memory.peekLong(a, !nativeByteOrder);
+ }
+
+ @Override
+ public final long getLong() {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ return getLong(ix(nextGetIndex(Long.BYTES)));
+ }
+
+ @Override
+ public final long getLong(int i) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ return getLong(ix(checkIndex(i, Long.BYTES)));
+ }
+
+ @Override
+ final long getLongUnchecked(int i) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ return getLong(ix(i));
+ }
+
+ @Override
+ final void getUnchecked(int pos, long[] dst, int dstOffset, int length) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ Memory.peekLongArray(ix(pos),
+ dst, dstOffset, length, !nativeByteOrder);
+ }
+
+ private ByteBuffer putLong(long a, long x) {
+ Memory.pokeLong(a, x, !nativeByteOrder);
+ return this;
+ }
+
+ @Override
+ public final ByteBuffer putLong(long x) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ putLong(ix(nextPutIndex(Long.BYTES)), x);
+ return this;
+ }
+
+ @Override
+ public final ByteBuffer putLong(int i, long x) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ putLong(ix(checkIndex(i, Long.BYTES)), x);
+ return this;
+ }
+
+ @Override
+ final void putLongUnchecked(int i, long x) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ putLong(ix(i), x);
+ }
+
+ @Override
+ final void putUnchecked(int pos, long[] src, int srcOffset, int length) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ Memory.pokeLongArray(ix(pos),
+ src, srcOffset, length, !nativeByteOrder);
+ }
+
+ @Override
+ public final LongBuffer asLongBuffer() {
+ if (memoryRef.isFreed) {
+ throw new IllegalStateException("buffer has been freed");
+ }
+ int off = this.position();
+ int lim = this.limit();
+ assert (off <= lim);
+ int rem = (off <= lim ? lim - off : 0);
+ int size = rem >> 3;
+ return new ByteBufferAsLongBuffer(this,
+ -1,
+ 0,
+ size,
+ size,
+ off,
+ order());
+ }
+
+ private float getFloat(long a) {
+ int x = Memory.peekInt(a, !nativeByteOrder);
+ return Float.intBitsToFloat(x);
+ }
+
+ @Override
+ public final float getFloat() {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ return getFloat(ix(nextGetIndex(Float.BYTES)));
+ }
+
+ @Override
+ public final float getFloat(int i) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ return getFloat(ix(checkIndex(i, Float.BYTES)));
+ }
+
+ @Override
+ final float getFloatUnchecked(int i) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ return getFloat(ix(i));
+ }
+
+ @Override
+ final void getUnchecked(int pos, float[] dst, int dstOffset, int length) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ Memory.peekFloatArray(ix(pos),
+ dst, dstOffset, length, !nativeByteOrder);
+ }
+
+ private ByteBuffer putFloat(long a, float x) {
+ int y = Float.floatToRawIntBits(x);
+ Memory.pokeInt(a, y, !nativeByteOrder);
+ return this;
+ }
+
+ @Override
+ public final ByteBuffer putFloat(float x) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ putFloat(ix(nextPutIndex(Float.BYTES)), x);
+ return this;
+ }
+
+ @Override
+ public final ByteBuffer putFloat(int i, float x) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ putFloat(ix(checkIndex(i, Float.BYTES)), x);
+ return this;
+ }
+
+ @Override
+ final void putFloatUnchecked(int i, float x) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ putFloat(ix(i), x);
+ }
+
+ @Override
+ final void putUnchecked(int pos, float[] src, int srcOffset, int length) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ Memory.pokeFloatArray(ix(pos),
+ src, srcOffset, length, !nativeByteOrder);
+ }
+
+ @Override
+ public final FloatBuffer asFloatBuffer() {
+ if (memoryRef.isFreed) {
+ throw new IllegalStateException("buffer has been freed");
+ }
+ int off = this.position();
+ int lim = this.limit();
+ assert (off <= lim);
+ int rem = (off <= lim ? lim - off : 0);
+ int size = rem >> 2;
+ return new ByteBufferAsFloatBuffer(this,
+ -1,
+ 0,
+ size,
+ size,
+ off,
+ order());
+ }
+
+ private double getDouble(long a) {
+ long x = Memory.peekLong(a, !nativeByteOrder);
+ return Double.longBitsToDouble(x);
+ }
+
+ @Override
+ public final double getDouble() {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ return getDouble(ix(nextGetIndex(Double.BYTES)));
+ }
+
+ @Override
+ public final double getDouble(int i) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ return getDouble(ix(checkIndex(i, Double.BYTES)));
+ }
+
+ @Override
+ final double getDoubleUnchecked(int i) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ return getDouble(ix(i));
+ }
+
+ @Override
+ final void getUnchecked(int pos, double[] dst, int dstOffset, int length) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ Memory.peekDoubleArray(ix(pos),
+ dst, dstOffset, length, !nativeByteOrder);
+ }
+
+ private ByteBuffer putDouble(long a, double x) {
+ long y = Double.doubleToRawLongBits(x);
+ Memory.pokeLong(a, y, !nativeByteOrder);
+ return this;
+ }
+
+ @Override
+ public final ByteBuffer putDouble(double x) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ putDouble(ix(nextPutIndex(Double.BYTES)), x);
+ return this;
+ }
+
+ @Override
+ public final ByteBuffer putDouble(int i, double x) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ putDouble(ix(checkIndex(i, Double.BYTES)), x);
+ return this;
+ }
+
+ @Override
+ final void putDoubleUnchecked(int i, double x) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ putDouble(ix(i), x);
+ }
+
+ @Override
+ final void putUnchecked(int pos, double[] src, int srcOffset, int length) {
+ if (!memoryRef.isAccessible) {
+ throw new IllegalStateException("buffer is inaccessible");
+ }
+ Memory.pokeDoubleArray(ix(pos),
+ src, srcOffset, length, !nativeByteOrder);
+ }
+
+ @Override
+ public final DoubleBuffer asDoubleBuffer() {
+ if (memoryRef.isFreed) {
+ throw new IllegalStateException("buffer has been freed");
+ }
+ int off = this.position();
+ int lim = this.limit();
+ assert (off <= lim);
+ int rem = (off <= lim ? lim - off : 0);
+
+ int size = rem >> 3;
+ return new ByteBufferAsDoubleBuffer(this,
+ -1,
+ 0,
+ size,
+ size,
+ off,
+ order());
+ }
+
+ @Override
+ public final boolean isAccessible() {
+ return memoryRef.isAccessible;
+ }
+
+ @Override
+ public final void setAccessible(boolean value) {
+ memoryRef.isAccessible = value;
+ }
+}
diff --git a/java/nio/DoubleBuffer.java b/java/nio/DoubleBuffer.java
new file mode 100644
index 0000000..bd80f4d
--- /dev/null
+++ b/java/nio/DoubleBuffer.java
@@ -0,0 +1,873 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio;
+
+
+import dalvik.annotation.codegen.CovariantReturnType;
+
+/**
+ * A double buffer.
+ *
+ * <p> This class defines four categories of operations upon
+ * double buffers:
+ *
+ * <ul>
+ *
+ * <li><p> Absolute and relative {@link #get() <i>get</i>} and
+ * {@link #put(double) <i>put</i>} methods that read and write
+ * single doubles; </p></li>
+ *
+ * <li><p> Relative {@link #get(double[]) <i>bulk get</i>}
+ * methods that transfer contiguous sequences of doubles from this buffer
+ * into an array; and</p></li>
+ *
+ * <li><p> Relative {@link #put(double[]) <i>bulk put</i>}
+ * methods that transfer contiguous sequences of doubles from a
+ * double array or some other double
+ * buffer into this buffer; and </p></li>
+ *
+ *
+ * <li><p> Methods for {@link #compact compacting}, {@link
+ * #duplicate duplicating}, and {@link #slice slicing}
+ * a double buffer. </p></li>
+ *
+ * </ul>
+ *
+ * <p> Double buffers can be created either by {@link #allocate
+ * <i>allocation</i>}, which allocates space for the buffer's
+ *
+ *
+ * content, by {@link #wrap(double[]) <i>wrapping</i>} an existing
+ * double array into a buffer, or by creating a
+ * <a href="ByteBuffer.html#views"><i>view</i></a> of an existing byte buffer.
+ *
+ *
+*
+ *
+ * <p> Like a byte buffer, a double buffer is either <a
+ * href="ByteBuffer.html#direct"><i>direct</i> or <i>non-direct</i></a>. A
+ * double buffer created via the <tt>wrap</tt> methods of this class will
+ * be non-direct. A double buffer created as a view of a byte buffer will
+ * be direct if, and only if, the byte buffer itself is direct. Whether or not
+ * a double buffer is direct may be determined by invoking the {@link
+ * #isDirect isDirect} method. </p>
+ *
+*
+ *
+ *
+ * <p> Methods in this class that do not otherwise have a value to return are
+ * specified to return the buffer upon which they are invoked. This allows
+ * method invocations to be chained.
+ *
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class DoubleBuffer
+ extends Buffer
+ implements Comparable<DoubleBuffer>
+{
+
+ // These fields are declared here rather than in Heap-X-Buffer in order to
+ // reduce the number of virtual method invocations needed to access these
+ // values, which is especially costly when coding small buffers.
+ //
+ final double[] hb; // Non-null only for heap buffers
+ final int offset;
+ boolean isReadOnly; // Valid only for heap buffers
+
+ // Creates a new buffer with the given mark, position, limit, capacity,
+ // backing array, and array offset
+ //
+ DoubleBuffer(int mark, int pos, int lim, int cap, // package-private
+ double[] hb, int offset)
+ {
+ // Android-added: elementSizeShift parameter (log2 of element size).
+ super(mark, pos, lim, cap, 3 /* elementSizeShift */);
+ this.hb = hb;
+ this.offset = offset;
+ }
+
+ // Creates a new buffer with the given mark, position, limit, and capacity
+ //
+ DoubleBuffer(int mark, int pos, int lim, int cap) { // package-private
+ this(mark, pos, lim, cap, null, 0);
+ }
+
+
+ /**
+ * Allocates a new double buffer.
+ *
+ * <p> The new buffer's position will be zero, its limit will be its
+ * capacity, its mark will be undefined, and each of its elements will be
+ * initialized to zero. It will have a {@link #array backing array},
+ * and its {@link #arrayOffset array offset} will be zero.
+ *
+ * @param capacity
+ * The new buffer's capacity, in doubles
+ *
+ * @return The new double buffer
+ *
+ * @throws IllegalArgumentException
+ * If the <tt>capacity</tt> is a negative integer
+ */
+ public static DoubleBuffer allocate(int capacity) {
+ if (capacity < 0)
+ throw new IllegalArgumentException();
+ return new HeapDoubleBuffer(capacity, capacity);
+ }
+
+ /**
+ * Wraps a double array into a buffer.
+ *
+ * <p> The new buffer will be backed by the given double array;
+ * that is, modifications to the buffer will cause the array to be modified
+ * and vice versa. The new buffer's capacity will be
+ * <tt>array.length</tt>, its position will be <tt>offset</tt>, its limit
+ * will be <tt>offset + length</tt>, and its mark will be undefined. Its
+ * {@link #array backing array} will be the given array, and
+ * its {@link #arrayOffset array offset} will be zero. </p>
+ *
+ * @param array
+ * The array that will back the new buffer
+ *
+ * @param offset
+ * The offset of the subarray to be used; must be non-negative and
+ * no larger than <tt>array.length</tt>. The new buffer's position
+ * will be set to this value.
+ *
+ * @param length
+ * The length of the subarray to be used;
+ * must be non-negative and no larger than
+ * <tt>array.length - offset</tt>.
+ * The new buffer's limit will be set to <tt>offset + length</tt>.
+ *
+ * @return The new double buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ */
+ public static DoubleBuffer wrap(double[] array,
+ int offset, int length)
+ {
+ try {
+ return new HeapDoubleBuffer(array, offset, length);
+ } catch (IllegalArgumentException x) {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+
+ /**
+ * Wraps a double array into a buffer.
+ *
+ * <p> The new buffer will be backed by the given double array;
+ * that is, modifications to the buffer will cause the array to be modified
+ * and vice versa. The new buffer's capacity and limit will be
+ * <tt>array.length</tt>, its position will be zero, and its mark will be
+ * undefined. Its {@link #array backing array} will be the
+ * given array, and its {@link #arrayOffset array offset>} will
+ * be zero. </p>
+ *
+ * @param array
+ * The array that will back this buffer
+ *
+ * @return The new double buffer
+ */
+ public static DoubleBuffer wrap(double[] array) {
+ return wrap(array, 0, array.length);
+ }
+
+
+ /**
+ * Creates a new double buffer whose content is a shared subsequence of
+ * this buffer's content.
+ *
+ * <p> The content of the new buffer will start at this buffer's current
+ * position. Changes to this buffer's content will be visible in the new
+ * buffer, and vice versa; the two buffers' position, limit, and mark
+ * values will be independent.
+ *
+ * <p> The new buffer's position will be zero, its capacity and its limit
+ * will be the number of doubles remaining in this buffer, and its mark
+ * will be undefined. The new buffer will be direct if, and only if, this
+ * buffer is direct, and it will be read-only if, and only if, this buffer
+ * is read-only. </p>
+ *
+ * @return The new double buffer
+ */
+ public abstract DoubleBuffer slice();
+
+ /**
+ * Creates a new double buffer that shares this buffer's content.
+ *
+ * <p> The content of the new buffer will be that of this buffer. Changes
+ * to this buffer's content will be visible in the new buffer, and vice
+ * versa; the two buffers' position, limit, and mark values will be
+ * independent.
+ *
+ * <p> The new buffer's capacity, limit, position, and mark values will be
+ * identical to those of this buffer. The new buffer will be direct if,
+ * and only if, this buffer is direct, and it will be read-only if, and
+ * only if, this buffer is read-only. </p>
+ *
+ * @return The new double buffer
+ */
+ public abstract DoubleBuffer duplicate();
+
+ /**
+ * Creates a new, read-only double buffer that shares this buffer's
+ * content.
+ *
+ * <p> The content of the new buffer will be that of this buffer. Changes
+ * to this buffer's content will be visible in the new buffer; the new
+ * buffer itself, however, will be read-only and will not allow the shared
+ * content to be modified. The two buffers' position, limit, and mark
+ * values will be independent.
+ *
+ * <p> The new buffer's capacity, limit, position, and mark values will be
+ * identical to those of this buffer.
+ *
+ * <p> If this buffer is itself read-only then this method behaves in
+ * exactly the same way as the {@link #duplicate duplicate} method. </p>
+ *
+ * @return The new, read-only double buffer
+ */
+ public abstract DoubleBuffer asReadOnlyBuffer();
+
+
+ // -- Singleton get/put methods --
+
+ /**
+ * Relative <i>get</i> method. Reads the double at this buffer's
+ * current position, and then increments the position.
+ *
+ * @return The double at the buffer's current position
+ *
+ * @throws BufferUnderflowException
+ * If the buffer's current position is not smaller than its limit
+ */
+ public abstract double get();
+
+ /**
+ * Relative <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> Writes the given double into this buffer at the current
+ * position, and then increments the position. </p>
+ *
+ * @param d
+ * The double to be written
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If this buffer's current position is not smaller than its limit
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract DoubleBuffer put(double d);
+
+ /**
+ * Absolute <i>get</i> method. Reads the double at the given
+ * index.
+ *
+ * @param index
+ * The index from which the double will be read
+ *
+ * @return The double at the given index
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
+ */
+ public abstract double get(int index);
+
+ /**
+ * Absolute <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> Writes the given double into this buffer at the given
+ * index. </p>
+ *
+ * @param index
+ * The index at which the double will be written
+ *
+ * @param d
+ * The double value to be written
+ *
+ * @return This buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract DoubleBuffer put(int index, double d);
+
+
+ // -- Bulk get operations --
+
+ /**
+ * Relative bulk <i>get</i> method.
+ *
+ * <p> This method transfers doubles from this buffer into the given
+ * destination array. If there are fewer doubles remaining in the
+ * buffer than are required to satisfy the request, that is, if
+ * <tt>length</tt> <tt>></tt> <tt>remaining()</tt>, then no
+ * doubles are transferred and a {@link BufferUnderflowException} is
+ * thrown.
+ *
+ * <p> Otherwise, this method copies <tt>length</tt> doubles from this
+ * buffer into the given array, starting at the current position of this
+ * buffer and at the given offset in the array. The position of this
+ * buffer is then incremented by <tt>length</tt>.
+ *
+ * <p> In other words, an invocation of this method of the form
+ * <tt>src.get(dst, off, len)</tt> has exactly the same effect as
+ * the loop
+ *
+ * <pre>{@code
+ * for (int i = off; i < off + len; i++)
+ * dst[i] = src.get();
+ * }</pre>
+ *
+ * except that it first checks that there are sufficient doubles in
+ * this buffer and it is potentially much more efficient.
+ *
+ * @param dst
+ * The array into which doubles are to be written
+ *
+ * @param offset
+ * The offset within the array of the first double to be
+ * written; must be non-negative and no larger than
+ * <tt>dst.length</tt>
+ *
+ * @param length
+ * The maximum number of doubles to be written to the given
+ * array; must be non-negative and no larger than
+ * <tt>dst.length - offset</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than <tt>length</tt> doubles
+ * remaining in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ */
+ public DoubleBuffer get(double[] dst, int offset, int length) {
+ checkBounds(offset, length, dst.length);
+ if (length > remaining())
+ throw new BufferUnderflowException();
+ int end = offset + length;
+ for (int i = offset; i < end; i++)
+ dst[i] = get();
+ return this;
+ }
+
+ /**
+ * Relative bulk <i>get</i> method.
+ *
+ * <p> This method transfers doubles from this buffer into the given
+ * destination array. An invocation of this method of the form
+ * <tt>src.get(a)</tt> behaves in exactly the same way as the invocation
+ *
+ * <pre>
+ * src.get(a, 0, a.length) </pre>
+ *
+ * @param dst
+ * The destination array
+ *
+ * @return This buffer
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than <tt>length</tt> doubles
+ * remaining in this buffer
+ */
+ public DoubleBuffer get(double[] dst) {
+ return get(dst, 0, dst.length);
+ }
+
+
+ // -- Bulk put operations --
+
+ /**
+ * Relative bulk <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> This method transfers the doubles remaining in the given source
+ * buffer into this buffer. If there are more doubles remaining in the
+ * source buffer than in this buffer, that is, if
+ * <tt>src.remaining()</tt> <tt>></tt> <tt>remaining()</tt>,
+ * then no doubles are transferred and a {@link
+ * BufferOverflowException} is thrown.
+ *
+ * <p> Otherwise, this method copies
+ * <i>n</i> = <tt>src.remaining()</tt> doubles from the given
+ * buffer into this buffer, starting at each buffer's current position.
+ * The positions of both buffers are then incremented by <i>n</i>.
+ *
+ * <p> In other words, an invocation of this method of the form
+ * <tt>dst.put(src)</tt> has exactly the same effect as the loop
+ *
+ * <pre>
+ * while (src.hasRemaining())
+ * dst.put(src.get()); </pre>
+ *
+ * except that it first checks that there is sufficient space in this
+ * buffer and it is potentially much more efficient.
+ *
+ * @param src
+ * The source buffer from which doubles are to be read;
+ * must not be this buffer
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ * for the remaining doubles in the source buffer
+ *
+ * @throws IllegalArgumentException
+ * If the source buffer is this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public DoubleBuffer put(DoubleBuffer src) {
+ if (src == this)
+ throw new IllegalArgumentException();
+ if (isReadOnly())
+ throw new ReadOnlyBufferException();
+ int n = src.remaining();
+ if (n > remaining())
+ throw new BufferOverflowException();
+ for (int i = 0; i < n; i++)
+ put(src.get());
+ return this;
+ }
+
+ /**
+ * Relative bulk <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> This method transfers doubles into this buffer from the given
+ * source array. If there are more doubles to be copied from the array
+ * than remain in this buffer, that is, if
+ * <tt>length</tt> <tt>></tt> <tt>remaining()</tt>, then no
+ * doubles are transferred and a {@link BufferOverflowException} is
+ * thrown.
+ *
+ * <p> Otherwise, this method copies <tt>length</tt> doubles from the
+ * given array into this buffer, starting at the given offset in the array
+ * and at the current position of this buffer. The position of this buffer
+ * is then incremented by <tt>length</tt>.
+ *
+ * <p> In other words, an invocation of this method of the form
+ * <tt>dst.put(src, off, len)</tt> has exactly the same effect as
+ * the loop
+ *
+ * <pre>{@code
+ * for (int i = off; i < off + len; i++)
+ * dst.put(a[i]);
+ * }</pre>
+ *
+ * except that it first checks that there is sufficient space in this
+ * buffer and it is potentially much more efficient.
+ *
+ * @param src
+ * The array from which doubles are to be read
+ *
+ * @param offset
+ * The offset within the array of the first double to be read;
+ * must be non-negative and no larger than <tt>array.length</tt>
+ *
+ * @param length
+ * The number of doubles to be read from the given array;
+ * must be non-negative and no larger than
+ * <tt>array.length - offset</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public DoubleBuffer put(double[] src, int offset, int length) {
+ checkBounds(offset, length, src.length);
+ if (length > remaining())
+ throw new BufferOverflowException();
+ int end = offset + length;
+ for (int i = offset; i < end; i++)
+ this.put(src[i]);
+ return this;
+ }
+
+ /**
+ * Relative bulk <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> This method transfers the entire content of the given source
+ * double array into this buffer. An invocation of this method of the
+ * form <tt>dst.put(a)</tt> behaves in exactly the same way as the
+ * invocation
+ *
+ * <pre>
+ * dst.put(a, 0, a.length) </pre>
+ *
+ * @param src
+ * The source array
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public final DoubleBuffer put(double[] src) {
+ return put(src, 0, src.length);
+ }
+
+
+ // -- Other stuff --
+
+ /**
+ * Tells whether or not this buffer is backed by an accessible double
+ * array.
+ *
+ * <p> If this method returns <tt>true</tt> then the {@link #array() array}
+ * and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
+ * </p>
+ *
+ * @return <tt>true</tt> if, and only if, this buffer
+ * is backed by an array and is not read-only
+ */
+ public final boolean hasArray() {
+ return (hb != null) && !isReadOnly;
+ }
+
+ /**
+ * Returns the double array that backs this
+ * buffer <i>(optional operation)</i>.
+ *
+ * <p> Modifications to this buffer's content will cause the returned
+ * array's content to be modified, and vice versa.
+ *
+ * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+ * method in order to ensure that this buffer has an accessible backing
+ * array. </p>
+ *
+ * @return The array that backs this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
+ */
+ public final double[] array() {
+ if (hb == null)
+ throw new UnsupportedOperationException();
+ if (isReadOnly)
+ throw new ReadOnlyBufferException();
+ return hb;
+ }
+
+ /**
+ * Returns the offset within this buffer's backing array of the first
+ * element of the buffer <i>(optional operation)</i>.
+ *
+ * <p> If this buffer is backed by an array then buffer position <i>p</i>
+ * corresponds to array index <i>p</i> + <tt>arrayOffset()</tt>.
+ *
+ * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+ * method in order to ensure that this buffer has an accessible backing
+ * array. </p>
+ *
+ * @return The offset within this buffer's array
+ * of the first element of the buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
+ */
+ public final int arrayOffset() {
+ if (hb == null)
+ throw new UnsupportedOperationException();
+ if (isReadOnly)
+ throw new ReadOnlyBufferException();
+ return offset;
+ }
+
+ // BEGIN Android-added: covariant overloads of *Buffer methods that return this.
+ @CovariantReturnType(returnType = DoubleBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer position(int newPosition) {
+ return super.position(newPosition);
+ }
+
+ @CovariantReturnType(returnType = DoubleBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer limit(int newLimit) {
+ return super.limit(newLimit);
+ }
+
+ @CovariantReturnType(returnType = DoubleBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer mark() {
+ return super.mark();
+ }
+
+ @CovariantReturnType(returnType = DoubleBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer reset() {
+ return super.reset();
+ }
+
+ @CovariantReturnType(returnType = DoubleBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer clear() {
+ return super.clear();
+ }
+
+ @CovariantReturnType(returnType = DoubleBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer flip() {
+ return super.flip();
+ }
+
+ @CovariantReturnType(returnType = DoubleBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer rewind() {
+ return super.rewind();
+ }
+ // END Android-added: covariant overloads of *Buffer methods that return this.
+
+ /**
+ * Compacts this buffer <i>(optional operation)</i>.
+ *
+ * <p> The doubles between the buffer's current position and its limit,
+ * if any, are copied to the beginning of the buffer. That is, the
+ * double at index <i>p</i> = <tt>position()</tt> is copied
+ * to index zero, the double at index <i>p</i> + 1 is copied
+ * to index one, and so forth until the double at index
+ * <tt>limit()</tt> - 1 is copied to index
+ * <i>n</i> = <tt>limit()</tt> - <tt>1</tt> - <i>p</i>.
+ * The buffer's position is then set to <i>n+1</i> and its limit is set to
+ * its capacity. The mark, if defined, is discarded.
+ *
+ * <p> The buffer's position is set to the number of doubles copied,
+ * rather than to zero, so that an invocation of this method can be
+ * followed immediately by an invocation of another relative <i>put</i>
+ * method. </p>
+ *
+
+ *
+ * @return This buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract DoubleBuffer compact();
+
+ /**
+ * Tells whether or not this double buffer is direct.
+ *
+ * @return <tt>true</tt> if, and only if, this buffer is direct
+ */
+ public abstract boolean isDirect();
+
+
+ /**
+ * Returns a string summarizing the state of this buffer.
+ *
+ * @return A summary string
+ */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(getClass().getName());
+ sb.append("[pos=");
+ sb.append(position());
+ sb.append(" lim=");
+ sb.append(limit());
+ sb.append(" cap=");
+ sb.append(capacity());
+ sb.append("]");
+ return sb.toString();
+ }
+
+
+ /**
+ * Returns the current hash code of this buffer.
+ *
+ * <p> The hash code of a double buffer depends only upon its remaining
+ * elements; that is, upon the elements from <tt>position()</tt> up to, and
+ * including, the element at <tt>limit()</tt> - <tt>1</tt>.
+ *
+ * <p> Because buffer hash codes are content-dependent, it is inadvisable
+ * to use buffers as keys in hash maps or similar data structures unless it
+ * is known that their contents will not change. </p>
+ *
+ * @return The current hash code of this buffer
+ */
+ public int hashCode() {
+ int h = 1;
+ int p = position();
+ for (int i = limit() - 1; i >= p; i--)
+ h = 31 * h + (int) get(i);
+ return h;
+ }
+
+ /**
+ * Tells whether or not this buffer is equal to another object.
+ *
+ * <p> Two double buffers are equal if, and only if,
+ *
+ * <ol>
+ *
+ * <li><p> They have the same element type, </p></li>
+ *
+ * <li><p> They have the same number of remaining elements, and
+ * </p></li>
+ *
+ * <li><p> The two sequences of remaining elements, considered
+ * independently of their starting positions, are pointwise equal.
+
+ * This method considers two double elements {@code a} and {@code b}
+ * to be equal if
+ * {@code (a == b) || (Double.isNaN(a) && Double.isNaN(b))}.
+ * The values {@code -0.0} and {@code +0.0} are considered to be
+ * equal, unlike {@link Double#equals(Object)}.
+
+ * </p></li>
+ *
+ * </ol>
+ *
+ * <p> A double buffer is not equal to any other type of object. </p>
+ *
+ * @param ob The object to which this buffer is to be compared
+ *
+ * @return <tt>true</tt> if, and only if, this buffer is equal to the
+ * given object
+ */
+ public boolean equals(Object ob) {
+ if (this == ob)
+ return true;
+ if (!(ob instanceof DoubleBuffer))
+ return false;
+ DoubleBuffer that = (DoubleBuffer)ob;
+ if (this.remaining() != that.remaining())
+ return false;
+ int p = this.position();
+ for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--)
+ if (!equals(this.get(i), that.get(j)))
+ return false;
+ return true;
+ }
+
+ private static boolean equals(double x, double y) {
+
+ return (x == y) || (Double.isNaN(x) && Double.isNaN(y));
+
+
+ }
+
+ /**
+ * Compares this buffer to another.
+ *
+ * <p> Two double buffers are compared by comparing their sequences of
+ * remaining elements lexicographically, without regard to the starting
+ * position of each sequence within its corresponding buffer.
+
+ * Pairs of {@code double} elements are compared as if by invoking
+ * {@link Double#compare(double,double)}, except that
+ * {@code -0.0} and {@code 0.0} are considered to be equal.
+ * {@code Double.NaN} is considered by this method to be equal
+ * to itself and greater than all other {@code double} values
+ * (including {@code Double.POSITIVE_INFINITY}).
+
+ *
+ * <p> A double buffer is not comparable to any other type of object.
+ *
+ * @return A negative integer, zero, or a positive integer as this buffer
+ * is less than, equal to, or greater than the given buffer
+ */
+ public int compareTo(DoubleBuffer that) {
+ int n = this.position() + Math.min(this.remaining(), that.remaining());
+ for (int i = this.position(), j = that.position(); i < n; i++, j++) {
+ int cmp = compare(this.get(i), that.get(j));
+ if (cmp != 0)
+ return cmp;
+ }
+ return this.remaining() - that.remaining();
+ }
+
+ private static int compare(double x, double y) {
+
+ return ((x < y) ? -1 :
+ (x > y) ? +1 :
+ (x == y) ? 0 :
+ Double.isNaN(x) ? (Double.isNaN(y) ? 0 : +1) : -1);
+
+ }
+
+ // -- Other char stuff --
+
+
+ // -- Other byte stuff: Access to binary data --
+
+
+ /**
+ * Retrieves this buffer's byte order.
+ *
+ * <p> The byte order of a double buffer created by allocation or by
+ * wrapping an existing <tt>double</tt> array is the {@link
+ * ByteOrder#nativeOrder native order} of the underlying
+ * hardware. The byte order of a double buffer created as a <a
+ * href="ByteBuffer.html#views">view</a> of a byte buffer is that of the
+ * byte buffer at the moment that the view is created. </p>
+ *
+ * @return This buffer's byte order
+ */
+ public abstract ByteOrder order();
+
+
+}
diff --git a/java/nio/FloatBuffer.java b/java/nio/FloatBuffer.java
new file mode 100644
index 0000000..3d34211
--- /dev/null
+++ b/java/nio/FloatBuffer.java
@@ -0,0 +1,874 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio;
+
+
+import dalvik.annotation.codegen.CovariantReturnType;
+
+/**
+ * A float buffer.
+ *
+ * <p> This class defines four categories of operations upon
+ * float buffers:
+ *
+ * <ul>
+ *
+ * <li><p> Absolute and relative {@link #get() <i>get</i>} and
+ * {@link #put(float) <i>put</i>} methods that read and write
+ * single floats; </p></li>
+ *
+ * <li><p> Relative {@link #get(float[]) <i>bulk get</i>}
+ * methods that transfer contiguous sequences of floats from this buffer
+ * into an array; and</p></li>
+ *
+ * <li><p> Relative {@link #put(float[]) <i>bulk put</i>}
+ * methods that transfer contiguous sequences of floats from a
+ * float array or some other float
+ * buffer into this buffer; and </p></li>
+ *
+ *
+ * <li><p> Methods for {@link #compact compacting}, {@link
+ * #duplicate duplicating}, and {@link #slice slicing}
+ * a float buffer. </p></li>
+ *
+ * </ul>
+ *
+ * <p> Float buffers can be created either by {@link #allocate
+ * <i>allocation</i>}, which allocates space for the buffer's
+ *
+ *
+ * content, by {@link #wrap(float[]) <i>wrapping</i>} an existing
+ * float array into a buffer, or by creating a
+ * <a href="ByteBuffer.html#views"><i>view</i></a> of an existing byte buffer.
+ *
+ *
+*
+ *
+ * <p> Like a byte buffer, a float buffer is either <a
+ * href="ByteBuffer.html#direct"><i>direct</i> or <i>non-direct</i></a>. A
+ * float buffer created via the <tt>wrap</tt> methods of this class will
+ * be non-direct. A float buffer created as a view of a byte buffer will
+ * be direct if, and only if, the byte buffer itself is direct. Whether or not
+ * a float buffer is direct may be determined by invoking the {@link
+ * #isDirect isDirect} method. </p>
+ *
+*
+ *
+ *
+ * <p> Methods in this class that do not otherwise have a value to return are
+ * specified to return the buffer upon which they are invoked. This allows
+ * method invocations to be chained.
+ *
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class FloatBuffer
+ extends Buffer
+ implements Comparable<FloatBuffer>
+{
+
+ // These fields are declared here rather than in Heap-X-Buffer in order to
+ // reduce the number of virtual method invocations needed to access these
+ // values, which is especially costly when coding small buffers.
+ //
+ final float[] hb; // Non-null only for heap buffers
+ final int offset;
+ boolean isReadOnly; // Valid only for heap buffers
+
+ // Creates a new buffer with the given mark, position, limit, capacity,
+ // backing array, and array offset
+ //
+ FloatBuffer(int mark, int pos, int lim, int cap, // package-private
+ float[] hb, int offset)
+ {
+ // Android-added: elementSizeShift parameter (log2 of element size).
+ super(mark, pos, lim, cap, 2 /* elementSizeShift */);
+ this.hb = hb;
+ this.offset = offset;
+ }
+
+ // Creates a new buffer with the given mark, position, limit, and capacity
+ //
+ FloatBuffer(int mark, int pos, int lim, int cap) { // package-private
+ this(mark, pos, lim, cap, null, 0);
+ }
+
+
+ /**
+ * Allocates a new float buffer.
+ *
+ * <p> The new buffer's position will be zero, its limit will be its
+ * capacity, its mark will be undefined, and each of its elements will be
+ * initialized to zero. It will have a {@link #array backing array},
+ * and its {@link #arrayOffset array offset} will be zero.
+ *
+ * @param capacity
+ * The new buffer's capacity, in floats
+ *
+ * @return The new float buffer
+ *
+ * @throws IllegalArgumentException
+ * If the <tt>capacity</tt> is a negative integer
+ */
+ public static FloatBuffer allocate(int capacity) {
+ if (capacity < 0)
+ throw new IllegalArgumentException();
+ return new HeapFloatBuffer(capacity, capacity);
+ }
+
+ /**
+ * Wraps a float array into a buffer.
+ *
+ * <p> The new buffer will be backed by the given float array;
+ * that is, modifications to the buffer will cause the array to be modified
+ * and vice versa. The new buffer's capacity will be
+ * <tt>array.length</tt>, its position will be <tt>offset</tt>, its limit
+ * will be <tt>offset + length</tt>, and its mark will be undefined. Its
+ * {@link #array backing array} will be the given array, and
+ * its {@link #arrayOffset array offset} will be zero. </p>
+ *
+ * @param array
+ * The array that will back the new buffer
+ *
+ * @param offset
+ * The offset of the subarray to be used; must be non-negative and
+ * no larger than <tt>array.length</tt>. The new buffer's position
+ * will be set to this value.
+ *
+ * @param length
+ * The length of the subarray to be used;
+ * must be non-negative and no larger than
+ * <tt>array.length - offset</tt>.
+ * The new buffer's limit will be set to <tt>offset + length</tt>.
+ *
+ * @return The new float buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ */
+ public static FloatBuffer wrap(float[] array,
+ int offset, int length)
+ {
+ try {
+ return new HeapFloatBuffer(array, offset, length);
+ } catch (IllegalArgumentException x) {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+
+ /**
+ * Wraps a float array into a buffer.
+ *
+ * <p> The new buffer will be backed by the given float array;
+ * that is, modifications to the buffer will cause the array to be modified
+ * and vice versa. The new buffer's capacity and limit will be
+ * <tt>array.length</tt>, its position will be zero, and its mark will be
+ * undefined. Its {@link #array backing array} will be the
+ * given array, and its {@link #arrayOffset array offset>} will
+ * be zero. </p>
+ *
+ * @param array
+ * The array that will back this buffer
+ *
+ * @return The new float buffer
+ */
+ public static FloatBuffer wrap(float[] array) {
+ return wrap(array, 0, array.length);
+ }
+
+
+ /**
+ * Creates a new float buffer whose content is a shared subsequence of
+ * this buffer's content.
+ *
+ * <p> The content of the new buffer will start at this buffer's current
+ * position. Changes to this buffer's content will be visible in the new
+ * buffer, and vice versa; the two buffers' position, limit, and mark
+ * values will be independent.
+ *
+ * <p> The new buffer's position will be zero, its capacity and its limit
+ * will be the number of floats remaining in this buffer, and its mark
+ * will be undefined. The new buffer will be direct if, and only if, this
+ * buffer is direct, and it will be read-only if, and only if, this buffer
+ * is read-only. </p>
+ *
+ * @return The new float buffer
+ */
+ public abstract FloatBuffer slice();
+
+ /**
+ * Creates a new float buffer that shares this buffer's content.
+ *
+ * <p> The content of the new buffer will be that of this buffer. Changes
+ * to this buffer's content will be visible in the new buffer, and vice
+ * versa; the two buffers' position, limit, and mark values will be
+ * independent.
+ *
+ * <p> The new buffer's capacity, limit, position, and mark values will be
+ * identical to those of this buffer. The new buffer will be direct if,
+ * and only if, this buffer is direct, and it will be read-only if, and
+ * only if, this buffer is read-only. </p>
+ *
+ * @return The new float buffer
+ */
+ public abstract FloatBuffer duplicate();
+
+ /**
+ * Creates a new, read-only float buffer that shares this buffer's
+ * content.
+ *
+ * <p> The content of the new buffer will be that of this buffer. Changes
+ * to this buffer's content will be visible in the new buffer; the new
+ * buffer itself, however, will be read-only and will not allow the shared
+ * content to be modified. The two buffers' position, limit, and mark
+ * values will be independent.
+ *
+ * <p> The new buffer's capacity, limit, position, and mark values will be
+ * identical to those of this buffer.
+ *
+ * <p> If this buffer is itself read-only then this method behaves in
+ * exactly the same way as the {@link #duplicate duplicate} method. </p>
+ *
+ * @return The new, read-only float buffer
+ */
+ public abstract FloatBuffer asReadOnlyBuffer();
+
+
+ // -- Singleton get/put methods --
+
+ /**
+ * Relative <i>get</i> method. Reads the float at this buffer's
+ * current position, and then increments the position.
+ *
+ * @return The float at the buffer's current position
+ *
+ * @throws BufferUnderflowException
+ * If the buffer's current position is not smaller than its limit
+ */
+ public abstract float get();
+
+ /**
+ * Relative <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> Writes the given float into this buffer at the current
+ * position, and then increments the position. </p>
+ *
+ * @param f
+ * The float to be written
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If this buffer's current position is not smaller than its limit
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract FloatBuffer put(float f);
+
+ /**
+ * Absolute <i>get</i> method. Reads the float at the given
+ * index.
+ *
+ * @param index
+ * The index from which the float will be read
+ *
+ * @return The float at the given index
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
+ */
+ public abstract float get(int index);
+
+ /**
+ * Absolute <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> Writes the given float into this buffer at the given
+ * index. </p>
+ *
+ * @param index
+ * The index at which the float will be written
+ *
+ * @param f
+ * The float value to be written
+ *
+ * @return This buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract FloatBuffer put(int index, float f);
+
+
+ // -- Bulk get operations --
+
+ /**
+ * Relative bulk <i>get</i> method.
+ *
+ * <p> This method transfers floats from this buffer into the given
+ * destination array. If there are fewer floats remaining in the
+ * buffer than are required to satisfy the request, that is, if
+ * <tt>length</tt> <tt>></tt> <tt>remaining()</tt>, then no
+ * floats are transferred and a {@link BufferUnderflowException} is
+ * thrown.
+ *
+ * <p> Otherwise, this method copies <tt>length</tt> floats from this
+ * buffer into the given array, starting at the current position of this
+ * buffer and at the given offset in the array. The position of this
+ * buffer is then incremented by <tt>length</tt>.
+ *
+ * <p> In other words, an invocation of this method of the form
+ * <tt>src.get(dst, off, len)</tt> has exactly the same effect as
+ * the loop
+ *
+ * <pre>{@code
+ * for (int i = off; i < off + len; i++)
+ * dst[i] = src.get();
+ * }</pre>
+ *
+ * except that it first checks that there are sufficient floats in
+ * this buffer and it is potentially much more efficient.
+ *
+ * @param dst
+ * The array into which floats are to be written
+ *
+ * @param offset
+ * The offset within the array of the first float to be
+ * written; must be non-negative and no larger than
+ * <tt>dst.length</tt>
+ *
+ * @param length
+ * The maximum number of floats to be written to the given
+ * array; must be non-negative and no larger than
+ * <tt>dst.length - offset</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than <tt>length</tt> floats
+ * remaining in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ */
+ public FloatBuffer get(float[] dst, int offset, int length) {
+ checkBounds(offset, length, dst.length);
+ if (length > remaining())
+ throw new BufferUnderflowException();
+ int end = offset + length;
+ for (int i = offset; i < end; i++)
+ dst[i] = get();
+ return this;
+ }
+
+ /**
+ * Relative bulk <i>get</i> method.
+ *
+ * <p> This method transfers floats from this buffer into the given
+ * destination array. An invocation of this method of the form
+ * <tt>src.get(a)</tt> behaves in exactly the same way as the invocation
+ *
+ * <pre>
+ * src.get(a, 0, a.length) </pre>
+ *
+ * @param dst
+ * The destination array
+ *
+ * @return This buffer
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than <tt>length</tt> floats
+ * remaining in this buffer
+ */
+ public FloatBuffer get(float[] dst) {
+ return get(dst, 0, dst.length);
+ }
+
+
+ // -- Bulk put operations --
+
+ /**
+ * Relative bulk <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> This method transfers the floats remaining in the given source
+ * buffer into this buffer. If there are more floats remaining in the
+ * source buffer than in this buffer, that is, if
+ * <tt>src.remaining()</tt> <tt>></tt> <tt>remaining()</tt>,
+ * then no floats are transferred and a {@link
+ * BufferOverflowException} is thrown.
+ *
+ * <p> Otherwise, this method copies
+ * <i>n</i> = <tt>src.remaining()</tt> floats from the given
+ * buffer into this buffer, starting at each buffer's current position.
+ * The positions of both buffers are then incremented by <i>n</i>.
+ *
+ * <p> In other words, an invocation of this method of the form
+ * <tt>dst.put(src)</tt> has exactly the same effect as the loop
+ *
+ * <pre>
+ * while (src.hasRemaining())
+ * dst.put(src.get()); </pre>
+ *
+ * except that it first checks that there is sufficient space in this
+ * buffer and it is potentially much more efficient.
+ *
+ * @param src
+ * The source buffer from which floats are to be read;
+ * must not be this buffer
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ * for the remaining floats in the source buffer
+ *
+ * @throws IllegalArgumentException
+ * If the source buffer is this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public FloatBuffer put(FloatBuffer src) {
+ if (src == this)
+ throw new IllegalArgumentException();
+ if (isReadOnly())
+ throw new ReadOnlyBufferException();
+ int n = src.remaining();
+ if (n > remaining())
+ throw new BufferOverflowException();
+ for (int i = 0; i < n; i++)
+ put(src.get());
+ return this;
+ }
+
+ /**
+ * Relative bulk <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> This method transfers floats into this buffer from the given
+ * source array. If there are more floats to be copied from the array
+ * than remain in this buffer, that is, if
+ * <tt>length</tt> <tt>></tt> <tt>remaining()</tt>, then no
+ * floats are transferred and a {@link BufferOverflowException} is
+ * thrown.
+ *
+ * <p> Otherwise, this method copies <tt>length</tt> floats from the
+ * given array into this buffer, starting at the given offset in the array
+ * and at the current position of this buffer. The position of this buffer
+ * is then incremented by <tt>length</tt>.
+ *
+ * <p> In other words, an invocation of this method of the form
+ * <tt>dst.put(src, off, len)</tt> has exactly the same effect as
+ * the loop
+ *
+ * <pre>{@code
+ * for (int i = off; i < off + len; i++)
+ * dst.put(a[i]);
+ * }</pre>
+ *
+ * except that it first checks that there is sufficient space in this
+ * buffer and it is potentially much more efficient.
+ *
+ * @param src
+ * The array from which floats are to be read
+ *
+ * @param offset
+ * The offset within the array of the first float to be read;
+ * must be non-negative and no larger than <tt>array.length</tt>
+ *
+ * @param length
+ * The number of floats to be read from the given array;
+ * must be non-negative and no larger than
+ * <tt>array.length - offset</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public FloatBuffer put(float[] src, int offset, int length) {
+ checkBounds(offset, length, src.length);
+ if (length > remaining())
+ throw new BufferOverflowException();
+ int end = offset + length;
+ for (int i = offset; i < end; i++)
+ this.put(src[i]);
+ return this;
+ }
+
+ /**
+ * Relative bulk <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> This method transfers the entire content of the given source
+ * float array into this buffer. An invocation of this method of the
+ * form <tt>dst.put(a)</tt> behaves in exactly the same way as the
+ * invocation
+ *
+ * <pre>
+ * dst.put(a, 0, a.length) </pre>
+ *
+ * @param src
+ * The source array
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public final FloatBuffer put(float[] src) {
+ return put(src, 0, src.length);
+ }
+
+
+ // -- Other stuff --
+
+ /**
+ * Tells whether or not this buffer is backed by an accessible float
+ * array.
+ *
+ * <p> If this method returns <tt>true</tt> then the {@link #array() array}
+ * and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
+ * </p>
+ *
+ * @return <tt>true</tt> if, and only if, this buffer
+ * is backed by an array and is not read-only
+ */
+ public final boolean hasArray() {
+ return (hb != null) && !isReadOnly;
+ }
+
+ /**
+ * Returns the float array that backs this
+ * buffer <i>(optional operation)</i>.
+ *
+ * <p> Modifications to this buffer's content will cause the returned
+ * array's content to be modified, and vice versa.
+ *
+ * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+ * method in order to ensure that this buffer has an accessible backing
+ * array. </p>
+ *
+ * @return The array that backs this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
+ */
+ public final float[] array() {
+ if (hb == null)
+ throw new UnsupportedOperationException();
+ if (isReadOnly)
+ throw new ReadOnlyBufferException();
+ return hb;
+ }
+
+ /**
+ * Returns the offset within this buffer's backing array of the first
+ * element of the buffer <i>(optional operation)</i>.
+ *
+ * <p> If this buffer is backed by an array then buffer position <i>p</i>
+ * corresponds to array index <i>p</i> + <tt>arrayOffset()</tt>.
+ *
+ * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+ * method in order to ensure that this buffer has an accessible backing
+ * array. </p>
+ *
+ * @return The offset within this buffer's array
+ * of the first element of the buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
+ */
+ public final int arrayOffset() {
+ if (hb == null)
+ throw new UnsupportedOperationException();
+ if (isReadOnly)
+ throw new ReadOnlyBufferException();
+ return offset;
+ }
+
+ // BEGIN Android-added: covariant overloads of *Buffer methods that return this.
+ @CovariantReturnType(returnType = FloatBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer position(int newPosition) {
+ return super.position(newPosition);
+ }
+
+ @CovariantReturnType(returnType = FloatBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer limit(int newLimit) {
+ return super.limit(newLimit);
+ }
+
+ @CovariantReturnType(returnType = FloatBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer mark() {
+ return super.mark();
+ }
+
+ @CovariantReturnType(returnType = FloatBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer reset() {
+ return super.reset();
+ }
+
+ @CovariantReturnType(returnType = FloatBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer clear() {
+ return super.clear();
+ }
+
+ @CovariantReturnType(returnType = FloatBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer flip() {
+ return super.flip();
+ }
+
+ @CovariantReturnType(returnType = FloatBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer rewind() {
+ return super.rewind();
+ }
+ // END Android-added: covariant overloads of *Buffer methods that return this.
+
+ /**
+ * Compacts this buffer <i>(optional operation)</i>.
+ *
+ * <p> The floats between the buffer's current position and its limit,
+ * if any, are copied to the beginning of the buffer. That is, the
+ * float at index <i>p</i> = <tt>position()</tt> is copied
+ * to index zero, the float at index <i>p</i> + 1 is copied
+ * to index one, and so forth until the float at index
+ * <tt>limit()</tt> - 1 is copied to index
+ * <i>n</i> = <tt>limit()</tt> - <tt>1</tt> - <i>p</i>.
+ * The buffer's position is then set to <i>n+1</i> and its limit is set to
+ * its capacity. The mark, if defined, is discarded.
+ *
+ * <p> The buffer's position is set to the number of floats copied,
+ * rather than to zero, so that an invocation of this method can be
+ * followed immediately by an invocation of another relative <i>put</i>
+ * method. </p>
+ *
+
+ *
+ * @return This buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract FloatBuffer compact();
+
+ /**
+ * Tells whether or not this float buffer is direct.
+ *
+ * @return <tt>true</tt> if, and only if, this buffer is direct
+ */
+ public abstract boolean isDirect();
+
+
+ /**
+ * Returns a string summarizing the state of this buffer.
+ *
+ * @return A summary string
+ */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(getClass().getName());
+ sb.append("[pos=");
+ sb.append(position());
+ sb.append(" lim=");
+ sb.append(limit());
+ sb.append(" cap=");
+ sb.append(capacity());
+ sb.append("]");
+ return sb.toString();
+ }
+
+
+ /**
+ * Returns the current hash code of this buffer.
+ *
+ * <p> The hash code of a float buffer depends only upon its remaining
+ * elements; that is, upon the elements from <tt>position()</tt> up to, and
+ * including, the element at <tt>limit()</tt> - <tt>1</tt>.
+ *
+ * <p> Because buffer hash codes are content-dependent, it is inadvisable
+ * to use buffers as keys in hash maps or similar data structures unless it
+ * is known that their contents will not change. </p>
+ *
+ * @return The current hash code of this buffer
+ */
+ public int hashCode() {
+ int h = 1;
+ int p = position();
+ for (int i = limit() - 1; i >= p; i--)
+ h = 31 * h + (int) get(i);
+ return h;
+ }
+
+ /**
+ * Tells whether or not this buffer is equal to another object.
+ *
+ * <p> Two float buffers are equal if, and only if,
+ *
+ * <ol>
+ *
+ * <li><p> They have the same element type, </p></li>
+ *
+ * <li><p> They have the same number of remaining elements, and
+ * </p></li>
+ *
+ * <li><p> The two sequences of remaining elements, considered
+ * independently of their starting positions, are pointwise equal.
+
+ * This method considers two float elements {@code a} and {@code b}
+ * to be equal if
+ * {@code (a == b) || (Float.isNaN(a) && Float.isNaN(b))}.
+ * The values {@code -0.0} and {@code +0.0} are considered to be
+ * equal, unlike {@link Float#equals(Object)}.
+
+ * </p></li>
+ *
+ * </ol>
+ *
+ * <p> A float buffer is not equal to any other type of object. </p>
+ *
+ * @param ob The object to which this buffer is to be compared
+ *
+ * @return <tt>true</tt> if, and only if, this buffer is equal to the
+ * given object
+ */
+ public boolean equals(Object ob) {
+ if (this == ob)
+ return true;
+ if (!(ob instanceof FloatBuffer))
+ return false;
+ FloatBuffer that = (FloatBuffer)ob;
+ if (this.remaining() != that.remaining())
+ return false;
+ int p = this.position();
+ for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--)
+ if (!equals(this.get(i), that.get(j)))
+ return false;
+ return true;
+ }
+
+ private static boolean equals(float x, float y) {
+
+ return (x == y) || (Float.isNaN(x) && Float.isNaN(y));
+
+
+ }
+
+ /**
+ * Compares this buffer to another.
+ *
+ * <p> Two float buffers are compared by comparing their sequences of
+ * remaining elements lexicographically, without regard to the starting
+ * position of each sequence within its corresponding buffer.
+
+ * Pairs of {@code float} elements are compared as if by invoking
+ * {@link Float#compare(float,float)}, except that
+ * {@code -0.0} and {@code 0.0} are considered to be equal.
+ * {@code Float.NaN} is considered by this method to be equal
+ * to itself and greater than all other {@code float} values
+ * (including {@code Float.POSITIVE_INFINITY}).
+ *
+ *
+ *
+ *
+ *
+ * <p> A float buffer is not comparable to any other type of object.
+ *
+ * @return A negative integer, zero, or a positive integer as this buffer
+ * is less than, equal to, or greater than the given buffer
+ */
+ public int compareTo(FloatBuffer that) {
+ int n = this.position() + Math.min(this.remaining(), that.remaining());
+ for (int i = this.position(), j = that.position(); i < n; i++, j++) {
+ int cmp = compare(this.get(i), that.get(j));
+ if (cmp != 0)
+ return cmp;
+ }
+ return this.remaining() - that.remaining();
+ }
+
+ private static int compare(float x, float y) {
+
+ return ((x < y) ? -1 :
+ (x > y) ? +1 :
+ (x == y) ? 0 :
+ Float.isNaN(x) ? (Float.isNaN(y) ? 0 : +1) : -1);
+
+ }
+
+ // -- Other char stuff --
+
+ // -- Other byte stuff: Access to binary data --
+
+ /**
+ * Retrieves this buffer's byte order.
+ *
+ * <p> The byte order of a float buffer created by allocation or by
+ * wrapping an existing <tt>float</tt> array is the {@link
+ * ByteOrder#nativeOrder native order} of the underlying
+ * hardware. The byte order of a float buffer created as a <a
+ * href="ByteBuffer.html#views">view</a> of a byte buffer is that of the
+ * byte buffer at the moment that the view is created. </p>
+ *
+ * @return This buffer's byte order
+ */
+ public abstract ByteOrder order();
+
+
+}
diff --git a/java/nio/HeapByteBuffer.java b/java/nio/HeapByteBuffer.java
new file mode 100644
index 0000000..4666638
--- /dev/null
+++ b/java/nio/HeapByteBuffer.java
@@ -0,0 +1,561 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.nio;
+
+
+import libcore.io.Memory;
+
+/**
+ * A read/write HeapByteBuffer.
+ */
+
+final class HeapByteBuffer extends ByteBuffer {
+
+ // For speed these fields are actually declared in X-Buffer;
+ // these declarations are here as documentation
+ /*
+
+ protected final byte[] hb;
+ protected final int offset;
+
+ */
+
+ HeapByteBuffer(int cap, int lim) { // packag-private
+ this(cap, lim, false);
+ }
+
+
+ private HeapByteBuffer(int cap, int lim, boolean isReadOnly) {
+ super(-1, 0, lim, cap, new byte[cap], 0);
+ this.isReadOnly = isReadOnly;
+ }
+
+ HeapByteBuffer(byte[] buf, int off, int len) { // package-private
+ this(buf, off, len, false);
+ }
+
+ private HeapByteBuffer(byte[] buf, int off, int len, boolean isReadOnly) {
+ super(-1, off, off + len, buf.length, buf, 0);
+ this.isReadOnly = isReadOnly;
+ }
+
+ private HeapByteBuffer(byte[] buf, int mark, int pos, int lim, int cap, int off,
+ boolean isReadOnly) {
+ super(mark, pos, lim, cap, buf, off);
+ this.isReadOnly = isReadOnly;
+ }
+
+ @Override
+ public ByteBuffer slice() {
+ return new HeapByteBuffer(hb,
+ -1,
+ 0,
+ remaining(),
+ remaining(),
+ position() + offset,
+ isReadOnly);
+ }
+
+ @Override
+ public ByteBuffer duplicate() {
+ return new HeapByteBuffer(hb,
+ markValue(),
+ position(),
+ limit(),
+ capacity(),
+ offset,
+ isReadOnly);
+ }
+
+ @Override
+ public ByteBuffer asReadOnlyBuffer() {
+ return new HeapByteBuffer(hb,
+ this.markValue(),
+ this.position(),
+ this.limit(),
+ this.capacity(),
+ offset, true);
+ }
+
+ protected int ix(int i) {
+ return i + offset;
+ }
+
+ @Override
+ public byte get() {
+ return hb[ix(nextGetIndex())];
+ }
+
+ @Override
+ public byte get(int i) {
+ return hb[ix(checkIndex(i))];
+ }
+
+ @Override
+ public ByteBuffer get(byte[] dst, int offset, int length) {
+ checkBounds(offset, length, dst.length);
+ if (length > remaining())
+ throw new BufferUnderflowException();
+ System.arraycopy(hb, ix(position()), dst, offset, length);
+ position(position() + length);
+ return this;
+ }
+
+ @Override
+ public boolean isDirect() {
+ return false;
+ }
+
+ @Override
+ public boolean isReadOnly() {
+ return isReadOnly;
+ }
+
+ @Override
+ public ByteBuffer put(byte x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ hb[ix(nextPutIndex())] = x;
+ return this;
+ }
+
+ @Override
+ public ByteBuffer put(int i, byte x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ hb[ix(checkIndex(i))] = x;
+ return this;
+ }
+
+ @Override
+ public ByteBuffer put(byte[] src, int offset, int length) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ checkBounds(offset, length, src.length);
+ if (length > remaining())
+ throw new BufferOverflowException();
+ System.arraycopy(src, offset, hb, ix(position()), length);
+ position(position() + length);
+ return this;
+ }
+
+ @Override
+ public ByteBuffer compact() {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
+ position(remaining());
+ limit(capacity());
+ discardMark();
+ return this;
+ }
+
+ @Override
+ byte _get(int i) { // package-private
+ return hb[i];
+ }
+
+ @Override
+ void _put(int i, byte b) { // package-private
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ hb[i] = b;
+ }
+
+ @Override
+ public char getChar() {
+ return Bits.getChar(this, ix(nextGetIndex(2)), bigEndian);
+ }
+
+ @Override
+ public char getChar(int i) {
+ return Bits.getChar(this, ix(checkIndex(i, 2)), bigEndian);
+ }
+
+ @Override
+ char getCharUnchecked(int i) {
+ return Bits.getChar(this, ix(i), bigEndian);
+ }
+
+ @Override
+ void getUnchecked(int pos, char[] dst, int dstOffset, int length) {
+ Memory.unsafeBulkGet(dst, dstOffset, length * 2, hb, ix(pos), 2, !nativeByteOrder);
+ }
+
+ @Override
+ public ByteBuffer putChar(char x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ Bits.putChar(this, ix(nextPutIndex(2)), x, bigEndian);
+ return this;
+ }
+
+ @Override
+ public ByteBuffer putChar(int i, char x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ Bits.putChar(this, ix(checkIndex(i, 2)), x, bigEndian);
+ return this;
+ }
+
+ @Override
+ void putCharUnchecked(int i, char x) {
+ Bits.putChar(this, ix(i), x, bigEndian);
+ }
+
+ @Override
+ void putUnchecked(int pos, char[] src, int srcOffset, int length) {
+ Memory.unsafeBulkPut(hb, ix(pos), length * 2, src, srcOffset, 2, !nativeByteOrder);
+ }
+
+ @Override
+ public CharBuffer asCharBuffer() {
+ int size = this.remaining() >> 1;
+ int off = position();
+ return new ByteBufferAsCharBuffer(this,
+ -1,
+ 0,
+ size,
+ size,
+ off,
+ order());
+ }
+
+ @Override
+ public short getShort() {
+ return Bits.getShort(this, ix(nextGetIndex(2)), bigEndian);
+ }
+
+ @Override
+ public short getShort(int i) {
+ return Bits.getShort(this, ix(checkIndex(i, 2)), bigEndian);
+ }
+
+ @Override
+ short getShortUnchecked(int i) {
+ return Bits.getShort(this, ix(i), bigEndian);
+ }
+
+ @Override
+ void getUnchecked(int pos, short[] dst, int dstOffset, int length) {
+ Memory.unsafeBulkGet(dst, dstOffset, length * 2, hb, ix(pos), 2, !nativeByteOrder);
+ }
+
+ @Override
+ public ByteBuffer putShort(short x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ Bits.putShort(this, ix(nextPutIndex(2)), x, bigEndian);
+ return this;
+ }
+
+ @Override
+ public ByteBuffer putShort(int i, short x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ Bits.putShort(this, ix(checkIndex(i, 2)), x, bigEndian);
+ return this;
+ }
+
+ @Override
+ void putShortUnchecked(int i, short x) {
+ Bits.putShort(this, ix(i), x, bigEndian);
+ }
+
+ @Override
+ void putUnchecked(int pos, short[] src, int srcOffset, int length) {
+ Memory.unsafeBulkPut(hb, ix(pos), length * 2, src, srcOffset, 2, !nativeByteOrder);
+ }
+
+ @Override
+ public ShortBuffer asShortBuffer() {
+ int size = this.remaining() >> 1;
+ int off = position();
+ return new ByteBufferAsShortBuffer(this,
+ -1,
+ 0,
+ size,
+ size,
+ off,
+ order());
+ }
+
+ @Override
+ public int getInt() {
+ return Bits.getInt(this, ix(nextGetIndex(4)), bigEndian);
+ }
+
+ @Override
+ public int getInt(int i) {
+ return Bits.getInt(this, ix(checkIndex(i, 4)), bigEndian);
+ }
+
+ @Override
+ int getIntUnchecked(int i) {
+ return Bits.getInt(this, ix(i), bigEndian);
+ }
+
+ @Override
+ void getUnchecked(int pos, int[] dst, int dstOffset, int length) {
+ Memory.unsafeBulkGet(dst, dstOffset, length * 4, hb, ix(pos), 4, !nativeByteOrder);
+ }
+
+ @Override
+ public ByteBuffer putInt(int x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ Bits.putInt(this, ix(nextPutIndex(4)), x, bigEndian);
+ return this;
+ }
+
+ @Override
+ public ByteBuffer putInt(int i, int x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ Bits.putInt(this, ix(checkIndex(i, 4)), x, bigEndian);
+ return this;
+ }
+
+ @Override
+ void putIntUnchecked(int i, int x) {
+ Bits.putInt(this, ix(i), x, bigEndian);
+ }
+
+ @Override
+ void putUnchecked(int pos, int[] src, int srcOffset, int length) {
+ Memory.unsafeBulkPut(hb, ix(pos), length * 4, src, srcOffset, 4, !nativeByteOrder);
+ }
+
+ @Override
+ public IntBuffer asIntBuffer() {
+ int size = this.remaining() >> 2;
+ int off = position();
+
+ return new ByteBufferAsIntBuffer(this,
+ -1,
+ 0,
+ size,
+ size,
+ off,
+ order());
+ }
+
+ @Override
+ public long getLong() {
+ return Bits.getLong(this, ix(nextGetIndex(8)), bigEndian);
+ }
+
+ @Override
+ public long getLong(int i) {
+ return Bits.getLong(this, ix(checkIndex(i, 8)), bigEndian);
+ }
+
+ @Override
+ long getLongUnchecked(int i) {
+ return Bits.getLong(this, ix(i), bigEndian);
+ }
+
+ @Override
+ void getUnchecked(int pos, long[] dst, int dstOffset, int length) {
+ Memory.unsafeBulkGet(dst, dstOffset, length * 8, hb, ix(pos), 8, !nativeByteOrder);
+ }
+
+ @Override
+ public ByteBuffer putLong(long x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ Bits.putLong(this, ix(nextPutIndex(8)), x, bigEndian);
+ return this;
+ }
+
+ @Override
+ public ByteBuffer putLong(int i, long x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ Bits.putLong(this, ix(checkIndex(i, 8)), x, bigEndian);
+ return this;
+ }
+
+ @Override
+ void putLongUnchecked(int i, long x) {
+ Bits.putLong(this, ix(i), x, bigEndian);
+ }
+
+ @Override
+ void putUnchecked(int pos, long[] src, int srcOffset, int length) {
+ Memory.unsafeBulkPut(hb, ix(pos), length * 8, src, srcOffset, 8, !nativeByteOrder);
+ }
+
+ @Override
+ public LongBuffer asLongBuffer() {
+ int size = this.remaining() >> 3;
+ int off = position();
+ return new ByteBufferAsLongBuffer(this,
+ -1,
+ 0,
+ size,
+ size,
+ off,
+ order());
+ }
+
+ @Override
+ public float getFloat() {
+ return Bits.getFloat(this, ix(nextGetIndex(4)), bigEndian);
+ }
+
+ @Override
+ public float getFloat(int i) {
+ return Bits.getFloat(this, ix(checkIndex(i, 4)), bigEndian);
+ }
+
+ @Override
+ float getFloatUnchecked(int i) {
+ return Bits.getFloat(this, ix(i), bigEndian);
+ }
+
+ @Override
+ void getUnchecked(int pos, float[] dst, int dstOffset, int length) {
+ Memory.unsafeBulkGet(dst, dstOffset, length * 4, hb, ix(pos), 4, !nativeByteOrder);
+ }
+
+ @Override
+ public ByteBuffer putFloat(float x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ Bits.putFloat(this, ix(nextPutIndex(4)), x, bigEndian);
+ return this;
+ }
+
+ @Override
+ public ByteBuffer putFloat(int i, float x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ Bits.putFloat(this, ix(checkIndex(i, 4)), x, bigEndian);
+ return this;
+ }
+
+ @Override
+ void putFloatUnchecked(int i, float x) {
+ Bits.putFloat(this, ix(i), x, bigEndian);
+ }
+
+ @Override
+ void putUnchecked(int pos, float[] src, int srcOffset, int length) {
+ Memory.unsafeBulkPut(hb, ix(pos), length * 4, src, srcOffset, 4, !nativeByteOrder);
+ }
+
+ @Override
+ public FloatBuffer asFloatBuffer() {
+ int size = this.remaining() >> 2;
+ int off = position();
+ return new ByteBufferAsFloatBuffer(this,
+ -1,
+ 0,
+ size,
+ size,
+ off,
+ order());
+ }
+
+ @Override
+ public double getDouble() {
+ return Bits.getDouble(this, ix(nextGetIndex(8)), bigEndian);
+ }
+
+ @Override
+ public double getDouble(int i) {
+ return Bits.getDouble(this, ix(checkIndex(i, 8)), bigEndian);
+ }
+
+ @Override
+ double getDoubleUnchecked(int i) {
+ return Bits.getDouble(this, ix(i), bigEndian);
+ }
+
+ @Override
+ void getUnchecked(int pos, double[] dst, int dstOffset, int length) {
+ Memory.unsafeBulkGet(dst, dstOffset, length * 8, hb, ix(pos), 8, !nativeByteOrder);
+ }
+
+ @Override
+ public ByteBuffer putDouble(double x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ Bits.putDouble(this, ix(nextPutIndex(8)), x, bigEndian);
+ return this;
+ }
+
+ @Override
+ public ByteBuffer putDouble(int i, double x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ Bits.putDouble(this, ix(checkIndex(i, 8)), x, bigEndian);
+ return this;
+ }
+
+ @Override
+ void putDoubleUnchecked(int i, double x) {
+ Bits.putDouble(this, ix(i), x, bigEndian);
+ }
+
+ @Override
+ void putUnchecked(int pos, double[] src, int srcOffset, int length) {
+ Memory.unsafeBulkPut(hb, ix(pos), length * 8, src, srcOffset, 8, !nativeByteOrder);
+ }
+
+ @Override
+ public DoubleBuffer asDoubleBuffer() {
+ int size = this.remaining() >> 3;
+ int off = position();
+ return new ByteBufferAsDoubleBuffer(this,
+ -1,
+ 0,
+ size,
+ size,
+ off,
+ order());
+ }
+}
diff --git a/java/nio/HeapCharBuffer.java b/java/nio/HeapCharBuffer.java
new file mode 100644
index 0000000..fad4fa6
--- /dev/null
+++ b/java/nio/HeapCharBuffer.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio;
+
+/**
+ * A read/write HeapCharBuffer.
+ */
+
+class HeapCharBuffer extends CharBuffer {
+
+ // For speed these fields are actually declared in X-Buffer;
+ // these declarations are here as documentation
+ /*
+
+ protected final char[] hb;
+ protected final int offset;
+
+ */
+
+ HeapCharBuffer(int cap, int lim) { // package-private
+ this(cap, lim, false);
+ }
+
+ HeapCharBuffer(int cap, int lim, boolean isReadOnly) { // package-private
+ super(-1, 0, lim, cap, new char[cap], 0);
+ this.isReadOnly = isReadOnly;
+ }
+
+ HeapCharBuffer(char[] buf, int off, int len) { // package-private
+ this(buf, off, len, false);
+ }
+
+ HeapCharBuffer(char[] buf, int off, int len, boolean isReadOnly) { // package-private
+ super(-1, off, off + len, buf.length, buf, 0);
+ this.isReadOnly = isReadOnly;
+ }
+
+ protected HeapCharBuffer(char[] buf,
+ int mark, int pos, int lim, int cap,
+ int off) {
+ this(buf, mark, pos, lim, cap, off, false);
+ }
+
+ protected HeapCharBuffer(char[] buf,
+ int mark, int pos, int lim, int cap,
+ int off, boolean isReadOnly) {
+ super(mark, pos, lim, cap, buf, off);
+ this.isReadOnly = isReadOnly;
+ }
+
+ public CharBuffer slice() {
+ return new HeapCharBuffer(hb,
+ -1,
+ 0,
+ this.remaining(),
+ this.remaining(),
+ this.position() + offset,
+ isReadOnly);
+ }
+
+ public CharBuffer duplicate() {
+ return new HeapCharBuffer(hb,
+ this.markValue(),
+ this.position(),
+ this.limit(),
+ this.capacity(),
+ offset,
+ isReadOnly);
+ }
+
+ public CharBuffer asReadOnlyBuffer() {
+
+ return new HeapCharBuffer(hb,
+ this.markValue(),
+ this.position(),
+ this.limit(),
+ this.capacity(),
+ offset,
+ true);
+ }
+
+ protected int ix(int i) {
+ return i + offset;
+ }
+
+ public char get() {
+ return hb[ix(nextGetIndex())];
+ }
+
+ public char get(int i) {
+ return hb[ix(checkIndex(i))];
+ }
+
+ char getUnchecked(int i) {
+ return hb[ix(i)];
+ }
+
+ public CharBuffer get(char[] dst, int offset, int length) {
+ checkBounds(offset, length, dst.length);
+ if (length > remaining())
+ throw new BufferUnderflowException();
+ System.arraycopy(hb, ix(position()), dst, offset, length);
+ position(position() + length);
+ return this;
+ }
+
+ public boolean isDirect() {
+ return false;
+ }
+
+ public boolean isReadOnly() {
+ return isReadOnly;
+ }
+
+ public CharBuffer put(char x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ hb[ix(nextPutIndex())] = x;
+ return this;
+ }
+
+ public CharBuffer put(int i, char x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ hb[ix(checkIndex(i))] = x;
+ return this;
+ }
+
+ public CharBuffer put(char[] src, int offset, int length) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ checkBounds(offset, length, src.length);
+ if (length > remaining())
+ throw new BufferOverflowException();
+ System.arraycopy(src, offset, hb, ix(position()), length);
+ position(position() + length);
+ return this;
+ }
+
+ public CharBuffer put(CharBuffer src) {
+ if (src == this) {
+ throw new IllegalArgumentException();
+ }
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ if (src instanceof HeapCharBuffer) {
+ HeapCharBuffer sb = (HeapCharBuffer) src;
+ int n = sb.remaining();
+ if (n > remaining())
+ throw new BufferOverflowException();
+ System.arraycopy(sb.hb, sb.ix(sb.position()),
+ hb, ix(position()), n);
+ sb.position(sb.position() + n);
+ position(position() + n);
+ } else if (src.isDirect()) {
+ int n = src.remaining();
+ if (n > remaining())
+ throw new BufferOverflowException();
+ src.get(hb, ix(position()), n);
+ position(position() + n);
+ } else {
+ super.put(src);
+ }
+ return this;
+ }
+
+ public CharBuffer compact() {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
+ position(remaining());
+ limit(capacity());
+ discardMark();
+ return this;
+ }
+
+ String toString(int start, int end) { // package-private
+ try {
+ return new String(hb, start + offset, end - start);
+ } catch (StringIndexOutOfBoundsException x) {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+
+ public CharBuffer subSequence(int start, int end) {
+ if ((start < 0)
+ || (end > length())
+ || (start > end))
+ throw new IndexOutOfBoundsException();
+ int pos = position();
+ return new HeapCharBuffer(hb,
+ -1,
+ pos + start,
+ pos + end,
+ capacity(),
+ offset, isReadOnly);
+ }
+
+ public ByteOrder order() {
+ return ByteOrder.nativeOrder();
+ }
+}
diff --git a/java/nio/HeapDoubleBuffer.java b/java/nio/HeapDoubleBuffer.java
new file mode 100644
index 0000000..02634dd
--- /dev/null
+++ b/java/nio/HeapDoubleBuffer.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio;
+
+/**
+ * A read/write HeapDoubleBuffer.
+ */
+
+class HeapDoubleBuffer extends DoubleBuffer {
+
+ // For speed these fields are actually declared in X-Buffer;
+ // these declarations are here as documentation
+ /*
+
+ protected final double[] hb;
+ protected final int offset;
+
+ */
+
+ HeapDoubleBuffer(int cap, int lim) { // package-private
+ this(cap, lim, false);
+ }
+
+ HeapDoubleBuffer(double[] buf, int off, int len) { // package-private
+ this(buf, off, len, false);
+ }
+
+ protected HeapDoubleBuffer(double[] buf,
+ int mark, int pos, int lim, int cap,
+ int off) {
+ this(buf, mark, pos, lim, cap, off, false);
+ }
+
+ HeapDoubleBuffer(int cap, int lim, boolean isReadOnly) { // package-private
+ super(-1, 0, lim, cap, new double[cap], 0);
+ this.isReadOnly = isReadOnly;
+ }
+
+ HeapDoubleBuffer(double[] buf, int off, int len, boolean isReadOnly) { // package-private
+ super(-1, off, off + len, buf.length, buf, 0);
+ this.isReadOnly = isReadOnly;
+ }
+
+ protected HeapDoubleBuffer(double[] buf,
+ int mark, int pos, int lim, int cap,
+ int off, boolean isReadOnly) {
+ super(mark, pos, lim, cap, buf, off);
+ this.isReadOnly = isReadOnly;
+ }
+
+
+ public DoubleBuffer slice() {
+ return new HeapDoubleBuffer(hb,
+ -1,
+ 0,
+ this.remaining(),
+ this.remaining(),
+ this.position() + offset,
+ isReadOnly);
+ }
+
+ public DoubleBuffer duplicate() {
+ return new HeapDoubleBuffer(hb,
+ this.markValue(),
+ this.position(),
+ this.limit(),
+ this.capacity(),
+ offset,
+ isReadOnly);
+ }
+
+ public DoubleBuffer asReadOnlyBuffer() {
+ return new HeapDoubleBuffer(hb,
+ this.markValue(),
+ this.position(),
+ this.limit(),
+ this.capacity(),
+ offset, true);
+ }
+
+ protected int ix(int i) {
+ return i + offset;
+ }
+
+ public double get() {
+ return hb[ix(nextGetIndex())];
+ }
+
+ public double get(int i) {
+ return hb[ix(checkIndex(i))];
+ }
+
+ public DoubleBuffer get(double[] dst, int offset, int length) {
+ checkBounds(offset, length, dst.length);
+ if (length > remaining())
+ throw new BufferUnderflowException();
+ System.arraycopy(hb, ix(position()), dst, offset, length);
+ position(position() + length);
+ return this;
+ }
+
+ public boolean isDirect() {
+ return false;
+ }
+
+ public boolean isReadOnly() {
+ return isReadOnly;
+ }
+
+ public DoubleBuffer put(double x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ hb[ix(nextPutIndex())] = x;
+ return this;
+ }
+
+ public DoubleBuffer put(int i, double x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ hb[ix(checkIndex(i))] = x;
+ return this;
+ }
+
+ public DoubleBuffer put(double[] src, int offset, int length) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ checkBounds(offset, length, src.length);
+ if (length > remaining())
+ throw new BufferOverflowException();
+ System.arraycopy(src, offset, hb, ix(position()), length);
+ position(position() + length);
+ return this;
+ }
+
+ public DoubleBuffer put(DoubleBuffer src) {
+ if (src == this) {
+ throw new IllegalArgumentException();
+ }
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ if (src instanceof HeapDoubleBuffer) {
+ HeapDoubleBuffer sb = (HeapDoubleBuffer)src;
+ int n = sb.remaining();
+ if (n > remaining())
+ throw new BufferOverflowException();
+ System.arraycopy(sb.hb, sb.ix(sb.position()),
+ hb, ix(position()), n);
+ sb.position(sb.position() + n);
+ position(position() + n);
+ } else if (src.isDirect()) {
+ int n = src.remaining();
+ if (n > remaining())
+ throw new BufferOverflowException();
+ src.get(hb, ix(position()), n);
+ position(position() + n);
+ } else {
+ super.put(src);
+ }
+ return this;
+ }
+
+ public DoubleBuffer compact() {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
+ position(remaining());
+ limit(capacity());
+ discardMark();
+ return this;
+ }
+
+ public ByteOrder order() {
+ return ByteOrder.nativeOrder();
+ }
+}
diff --git a/java/nio/HeapFloatBuffer.java b/java/nio/HeapFloatBuffer.java
new file mode 100644
index 0000000..42dd8ce
--- /dev/null
+++ b/java/nio/HeapFloatBuffer.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio;
+
+/**
+ * A read/write HeapFloatBuffer.
+ */
+
+class HeapFloatBuffer extends FloatBuffer {
+
+ // For speed these fields are actually declared in X-Buffer;
+ // these declarations are here as documentation
+ /*
+
+ protected final float[] hb;
+ protected final int offset;
+
+ */
+
+ HeapFloatBuffer(int cap, int lim) { // package-private
+ this(cap, lim, false);
+ }
+
+ HeapFloatBuffer(int cap, int lim, boolean isReadOnly) { // package-private
+ super(-1, 0, lim, cap, new float[cap], 0);
+ this.isReadOnly = isReadOnly;
+ }
+
+ HeapFloatBuffer(float[] buf, int off, int len) { // package-private
+ this(buf, off, len, false);
+ }
+
+ HeapFloatBuffer(float[] buf, int off, int len, boolean isReadOnly) { // package-private
+ super(-1, off, off + len, buf.length, buf, 0);
+ this.isReadOnly = isReadOnly;
+ }
+
+ protected HeapFloatBuffer(float[] buf,
+ int mark, int pos, int lim, int cap,
+ int off) {
+ this(buf, mark, pos, lim, cap, off, false);
+ }
+
+ protected HeapFloatBuffer(float[] buf,
+ int mark, int pos, int lim, int cap,
+ int off, boolean isReadOnly) {
+ super(mark, pos, lim, cap, buf, off);
+ this.isReadOnly = isReadOnly;
+ }
+
+ public FloatBuffer slice() {
+ return new HeapFloatBuffer(hb,
+ -1,
+ 0,
+ this.remaining(),
+ this.remaining(),
+ this.position() + offset,
+ isReadOnly);
+ }
+
+ public FloatBuffer duplicate() {
+ return new HeapFloatBuffer(hb,
+ this.markValue(),
+ this.position(),
+ this.limit(),
+ this.capacity(),
+ offset,
+ isReadOnly);
+ }
+
+ public FloatBuffer asReadOnlyBuffer() {
+ return new HeapFloatBuffer(hb,
+ this.markValue(),
+ this.position(),
+ this.limit(),
+ this.capacity(),
+ offset, true);
+ }
+
+ protected int ix(int i) {
+ return i + offset;
+ }
+
+ public float get() {
+ return hb[ix(nextGetIndex())];
+ }
+
+ public float get(int i) {
+ return hb[ix(checkIndex(i))];
+ }
+
+ public FloatBuffer get(float[] dst, int offset, int length) {
+ checkBounds(offset, length, dst.length);
+ if (length > remaining())
+ throw new BufferUnderflowException();
+ System.arraycopy(hb, ix(position()), dst, offset, length);
+ position(position() + length);
+ return this;
+ }
+
+ public boolean isDirect() {
+ return false;
+ }
+
+ public boolean isReadOnly() {
+ return isReadOnly;
+ }
+
+ public FloatBuffer put(float x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ hb[ix(nextPutIndex())] = x;
+ return this;
+ }
+
+ public FloatBuffer put(int i, float x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ hb[ix(checkIndex(i))] = x;
+ return this;
+ }
+
+ public FloatBuffer put(float[] src, int offset, int length) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ checkBounds(offset, length, src.length);
+ if (length > remaining())
+ throw new BufferOverflowException();
+ System.arraycopy(src, offset, hb, ix(position()), length);
+ position(position() + length);
+ return this;
+ }
+
+ public FloatBuffer put(FloatBuffer src) {
+ if (src == this) {
+ throw new IllegalArgumentException();
+ }
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ if (src instanceof HeapFloatBuffer) {
+ HeapFloatBuffer sb = (HeapFloatBuffer) src;
+ int n = sb.remaining();
+ if (n > remaining())
+ throw new BufferOverflowException();
+ System.arraycopy(sb.hb, sb.ix(sb.position()),
+ hb, ix(position()), n);
+ sb.position(sb.position() + n);
+ position(position() + n);
+ } else if (src.isDirect()) {
+ int n = src.remaining();
+ if (n > remaining())
+ throw new BufferOverflowException();
+ src.get(hb, ix(position()), n);
+ position(position() + n);
+ } else {
+ super.put(src);
+ }
+ return this;
+ }
+
+ public FloatBuffer compact() {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
+ position(remaining());
+ limit(capacity());
+ discardMark();
+ return this;
+ }
+
+ public ByteOrder order() {
+ return ByteOrder.nativeOrder();
+ }
+}
diff --git a/java/nio/HeapIntBuffer.java b/java/nio/HeapIntBuffer.java
new file mode 100644
index 0000000..b4f3bf7
--- /dev/null
+++ b/java/nio/HeapIntBuffer.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio;
+
+/**
+ * A read/write HeapIntBuffer.
+ */
+
+class HeapIntBuffer extends IntBuffer {
+
+ // For speed these fields are actually declared in X-Buffer;
+ // these declarations are here as documentation
+ /*
+
+ protected final int[] hb;
+ protected final int offset;
+
+ */
+
+ HeapIntBuffer(int cap, int lim) { // package-private
+ this(cap, lim, false);
+ }
+
+ HeapIntBuffer(int cap, int lim, boolean isReadOnly) { // package-private
+ super(-1, 0, lim, cap, new int[cap], 0);
+ this.isReadOnly = isReadOnly;
+ }
+
+ HeapIntBuffer(int[] buf, int off, int len) { // package-private
+ this(buf, off, len, false);
+ }
+
+ HeapIntBuffer(int[] buf, int off, int len, boolean isReadOnly) { // package-private
+ super(-1, off, off + len, buf.length, buf, 0);
+ this.isReadOnly = isReadOnly;
+ }
+
+ protected HeapIntBuffer(int[] buf,
+ int mark, int pos, int lim, int cap,
+ int off) {
+ this(buf, mark, pos, lim, cap, off, false);
+ }
+
+ protected HeapIntBuffer(int[] buf,
+ int mark, int pos, int lim, int cap,
+ int off, boolean isReadOnly) {
+ super(mark, pos, lim, cap, buf, off);
+ this.isReadOnly = isReadOnly;
+ }
+
+ public IntBuffer slice() {
+ return new HeapIntBuffer(hb,
+ -1,
+ 0,
+ this.remaining(),
+ this.remaining(),
+ this.position() + offset,
+ isReadOnly);
+ }
+
+ public IntBuffer duplicate() {
+ return new HeapIntBuffer(hb,
+ this.markValue(),
+ this.position(),
+ this.limit(),
+ this.capacity(),
+ offset,
+ isReadOnly);
+ }
+
+ public IntBuffer asReadOnlyBuffer() {
+
+ return new HeapIntBuffer(hb,
+ this.markValue(),
+ this.position(),
+ this.limit(),
+ this.capacity(),
+ offset, true);
+ }
+
+ protected int ix(int i) {
+ return i + offset;
+ }
+
+ public int get() {
+ return hb[ix(nextGetIndex())];
+ }
+
+ public int get(int i) {
+ return hb[ix(checkIndex(i))];
+ }
+
+ public IntBuffer get(int[] dst, int offset, int length) {
+ checkBounds(offset, length, dst.length);
+ if (length > remaining())
+ throw new BufferUnderflowException();
+ System.arraycopy(hb, ix(position()), dst, offset, length);
+ position(position() + length);
+ return this;
+ }
+
+ public boolean isDirect() {
+ return false;
+ }
+
+ public boolean isReadOnly() {
+ return isReadOnly;
+ }
+
+ public IntBuffer put(int x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ hb[ix(nextPutIndex())] = x;
+ return this;
+ }
+
+ public IntBuffer put(int i, int x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ hb[ix(checkIndex(i))] = x;
+ return this;
+ }
+
+ public IntBuffer put(int[] src, int offset, int length) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ checkBounds(offset, length, src.length);
+ if (length > remaining())
+ throw new BufferOverflowException();
+ System.arraycopy(src, offset, hb, ix(position()), length);
+ position(position() + length);
+ return this;
+ }
+
+ public IntBuffer put(IntBuffer src) {
+ if (src == this) {
+ throw new IllegalArgumentException();
+ }
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ if (src instanceof HeapIntBuffer) {
+ HeapIntBuffer sb = (HeapIntBuffer) src;
+ int n = sb.remaining();
+ if (n > remaining())
+ throw new BufferOverflowException();
+ System.arraycopy(sb.hb, sb.ix(sb.position()),
+ hb, ix(position()), n);
+ sb.position(sb.position() + n);
+ position(position() + n);
+ } else if (src.isDirect()) {
+ int n = src.remaining();
+ if (n > remaining())
+ throw new BufferOverflowException();
+ src.get(hb, ix(position()), n);
+ position(position() + n);
+ } else {
+ super.put(src);
+ }
+ return this;
+ }
+
+ public IntBuffer compact() {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
+ position(remaining());
+ limit(capacity());
+ discardMark();
+ return this;
+ }
+
+ public ByteOrder order() {
+ return ByteOrder.nativeOrder();
+ }
+}
diff --git a/java/nio/HeapLongBuffer.java b/java/nio/HeapLongBuffer.java
new file mode 100644
index 0000000..c0678b3
--- /dev/null
+++ b/java/nio/HeapLongBuffer.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio;
+
+/**
+ * A read/write HeapLongBuffer.
+ */
+
+class HeapLongBuffer
+ extends LongBuffer {
+
+ // For speed these fields are actually declared in X-Buffer;
+ // these declarations are here as documentation
+ /*
+
+ protected final long[] hb;
+ protected final int offset;
+
+ */
+
+ HeapLongBuffer(int cap, int lim) { // package-private
+ this(cap, lim, false);
+ }
+
+ HeapLongBuffer(int cap, int lim, boolean isReadOnly) { // package-private
+ super(-1, 0, lim, cap, new long[cap], 0);
+ this.isReadOnly = isReadOnly;
+ }
+
+ HeapLongBuffer(long[] buf, int off, int len) { // package-private
+ this(buf, off, len, false);
+ }
+
+ HeapLongBuffer(long[] buf, int off, int len, boolean isReadOnly) { // package-private
+ super(-1, off, off + len, buf.length, buf, 0);
+ this.isReadOnly = isReadOnly;
+ }
+
+ protected HeapLongBuffer(long[] buf,
+ int mark, int pos, int lim, int cap,
+ int off) {
+ this(buf, mark, pos, lim, cap, off, false);
+ }
+
+ protected HeapLongBuffer(long[] buf,
+ int mark, int pos, int lim, int cap,
+ int off, boolean isReadOnly) {
+ super(mark, pos, lim, cap, buf, off);
+ this.isReadOnly = isReadOnly;
+ }
+
+ public LongBuffer slice() {
+ return new HeapLongBuffer(hb,
+ -1,
+ 0,
+ this.remaining(),
+ this.remaining(),
+ this.position() + offset,
+ isReadOnly);
+ }
+
+ public LongBuffer duplicate() {
+ return new HeapLongBuffer(hb,
+ this.markValue(),
+ this.position(),
+ this.limit(),
+ this.capacity(),
+ offset,
+ isReadOnly);
+ }
+
+ public LongBuffer asReadOnlyBuffer() {
+ return new HeapLongBuffer(hb,
+ this.markValue(),
+ this.position(),
+ this.limit(),
+ this.capacity(),
+ offset, true);
+ }
+
+
+ protected int ix(int i) {
+ return i + offset;
+ }
+
+ public long get() {
+ return hb[ix(nextGetIndex())];
+ }
+
+ public long get(int i) {
+ return hb[ix(checkIndex(i))];
+ }
+
+ public LongBuffer get(long[] dst, int offset, int length) {
+ checkBounds(offset, length, dst.length);
+ if (length > remaining())
+ throw new BufferUnderflowException();
+ System.arraycopy(hb, ix(position()), dst, offset, length);
+ position(position() + length);
+ return this;
+ }
+
+ public boolean isDirect() {
+ return false;
+ }
+
+ public boolean isReadOnly() {
+ return isReadOnly;
+ }
+
+ public LongBuffer put(long x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ hb[ix(nextPutIndex())] = x;
+ return this;
+ }
+
+ public LongBuffer put(int i, long x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ hb[ix(checkIndex(i))] = x;
+ return this;
+ }
+
+ public LongBuffer put(long[] src, int offset, int length) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ checkBounds(offset, length, src.length);
+ if (length > remaining())
+ throw new BufferOverflowException();
+ System.arraycopy(src, offset, hb, ix(position()), length);
+ position(position() + length);
+ return this;
+ }
+
+ public LongBuffer put(LongBuffer src) {
+ if (src == this) {
+ throw new IllegalArgumentException();
+ }
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ if (src instanceof HeapLongBuffer) {
+ HeapLongBuffer sb = (HeapLongBuffer) src;
+ int n = sb.remaining();
+ if (n > remaining())
+ throw new BufferOverflowException();
+ System.arraycopy(sb.hb, sb.ix(sb.position()),
+ hb, ix(position()), n);
+ sb.position(sb.position() + n);
+ position(position() + n);
+ } else if (src.isDirect()) {
+ int n = src.remaining();
+ if (n > remaining())
+ throw new BufferOverflowException();
+ src.get(hb, ix(position()), n);
+ position(position() + n);
+ } else {
+ super.put(src);
+ }
+ return this;
+ }
+
+ public LongBuffer compact() {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
+ position(remaining());
+ limit(capacity());
+ discardMark();
+ return this;
+ }
+
+ public ByteOrder order() {
+ return ByteOrder.nativeOrder();
+ }
+}
diff --git a/java/nio/HeapShortBuffer.java b/java/nio/HeapShortBuffer.java
new file mode 100644
index 0000000..af39261
--- /dev/null
+++ b/java/nio/HeapShortBuffer.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio;
+
+/**
+ * A read/write HeapShortBuffer.
+ */
+
+class HeapShortBuffer extends ShortBuffer {
+
+ // For speed these fields are actually declared in X-Buffer;
+ // these declarations are here as documentation
+ /*
+
+ protected final short[] hb;
+ protected final int offset;
+
+ */
+
+ HeapShortBuffer(int cap, int lim) { // package-private
+ this(cap, lim, false);
+ }
+
+ HeapShortBuffer(int cap, int lim, boolean isReadOnly) { // package-private
+ super(-1, 0, lim, cap, new short[cap], 0);
+ this.isReadOnly = isReadOnly;
+ }
+
+ HeapShortBuffer(short[] buf, int off, int len) { // package-private
+ this(buf, off, len, false);
+ }
+
+ HeapShortBuffer(short[] buf, int off, int len, boolean isReadOnly) { // package-private
+ super(-1, off, off + len, buf.length, buf, 0);
+ this.isReadOnly = isReadOnly;
+ }
+
+ protected HeapShortBuffer(short[] buf,
+ int mark, int pos, int lim, int cap,
+ int off) {
+ this(buf, mark, pos, lim, cap, off, false);
+ }
+
+ protected HeapShortBuffer(short[] buf,
+ int mark, int pos, int lim, int cap,
+ int off, boolean isReadOnly) {
+ super(mark, pos, lim, cap, buf, off);
+ this.isReadOnly = isReadOnly;
+ }
+
+ public ShortBuffer slice() {
+ return new HeapShortBuffer(hb,
+ -1,
+ 0,
+ this.remaining(),
+ this.remaining(),
+ this.position() + offset,
+ isReadOnly);
+ }
+
+ public ShortBuffer duplicate() {
+ return new HeapShortBuffer(hb,
+ this.markValue(),
+ this.position(),
+ this.limit(),
+ this.capacity(),
+ offset,
+ isReadOnly);
+ }
+
+ public ShortBuffer asReadOnlyBuffer() {
+
+ return new HeapShortBuffer(hb,
+ this.markValue(),
+ this.position(),
+ this.limit(),
+ this.capacity(),
+ offset, true);
+ }
+
+ protected int ix(int i) {
+ return i + offset;
+ }
+
+ public short get() {
+ return hb[ix(nextGetIndex())];
+ }
+
+ public short get(int i) {
+ return hb[ix(checkIndex(i))];
+ }
+
+ public ShortBuffer get(short[] dst, int offset, int length) {
+ checkBounds(offset, length, dst.length);
+ if (length > remaining())
+ throw new BufferUnderflowException();
+ System.arraycopy(hb, ix(position()), dst, offset, length);
+ position(position() + length);
+ return this;
+ }
+
+ public boolean isDirect() {
+ return false;
+ }
+
+ public boolean isReadOnly() {
+ return isReadOnly;
+ }
+
+ public ShortBuffer put(short x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ hb[ix(nextPutIndex())] = x;
+ return this;
+ }
+
+ public ShortBuffer put(int i, short x) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ hb[ix(checkIndex(i))] = x;
+ return this;
+ }
+
+ public ShortBuffer put(short[] src, int offset, int length) {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ checkBounds(offset, length, src.length);
+ if (length > remaining())
+ throw new BufferOverflowException();
+ System.arraycopy(src, offset, hb, ix(position()), length);
+ position(position() + length);
+ return this;
+ }
+
+ public ShortBuffer put(ShortBuffer src) {
+ if (src == this) {
+ throw new IllegalArgumentException();
+ }
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ if (src instanceof HeapShortBuffer) {
+ HeapShortBuffer sb = (HeapShortBuffer)src;
+ int n = sb.remaining();
+ if (n > remaining())
+ throw new BufferOverflowException();
+ System.arraycopy(sb.hb, sb.ix(sb.position()),
+ hb, ix(position()), n);
+ sb.position(sb.position() + n);
+ position(position() + n);
+ } else if (src.isDirect()) {
+ int n = src.remaining();
+ if (n > remaining())
+ throw new BufferOverflowException();
+ src.get(hb, ix(position()), n);
+ position(position() + n);
+ } else {
+ super.put(src);
+ }
+ return this;
+ }
+
+ public ShortBuffer compact() {
+ if (isReadOnly) {
+ throw new ReadOnlyBufferException();
+ }
+ System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
+ position(remaining());
+ limit(capacity());
+ discardMark();
+ return this;
+ }
+
+ public ByteOrder order() {
+ return ByteOrder.nativeOrder();
+ }
+}
diff --git a/java/nio/IntBuffer.java b/java/nio/IntBuffer.java
new file mode 100644
index 0000000..7e34229
--- /dev/null
+++ b/java/nio/IntBuffer.java
@@ -0,0 +1,875 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio;
+
+
+import dalvik.annotation.codegen.CovariantReturnType;
+
+/**
+ * An int buffer.
+ *
+ * <p> This class defines four categories of operations upon
+ * int buffers:
+ *
+ * <ul>
+ *
+ * <li><p> Absolute and relative {@link #get() <i>get</i>} and
+ * {@link #put(int) <i>put</i>} methods that read and write
+ * single ints; </p></li>
+ *
+ * <li><p> Relative {@link #get(int[]) <i>bulk get</i>}
+ * methods that transfer contiguous sequences of ints from this buffer
+ * into an array; and</p></li>
+ *
+ * <li><p> Relative {@link #put(int[]) <i>bulk put</i>}
+ * methods that transfer contiguous sequences of ints from an
+ * int array or some other int
+ * buffer into this buffer; and </p></li>
+ *
+ *
+ * <li><p> Methods for {@link #compact compacting}, {@link
+ * #duplicate duplicating}, and {@link #slice slicing}
+ * an int buffer. </p></li>
+ *
+ * </ul>
+ *
+ * <p> Int buffers can be created either by {@link #allocate
+ * <i>allocation</i>}, which allocates space for the buffer's
+ *
+ *
+ * content, by {@link #wrap(int[]) <i>wrapping</i>} an existing
+ * int array into a buffer, or by creating a
+ * <a href="ByteBuffer.html#views"><i>view</i></a> of an existing byte buffer.
+ *
+ *
+*
+ *
+ * <p> Like a byte buffer, an int buffer is either <a
+ * href="ByteBuffer.html#direct"><i>direct</i> or <i>non-direct</i></a>. A
+ * int buffer created via the <tt>wrap</tt> methods of this class will
+ * be non-direct. An int buffer created as a view of a byte buffer will
+ * be direct if, and only if, the byte buffer itself is direct. Whether or not
+ * an int buffer is direct may be determined by invoking the {@link
+ * #isDirect isDirect} method. </p>
+ *
+*
+ *
+ *
+ * <p> Methods in this class that do not otherwise have a value to return are
+ * specified to return the buffer upon which they are invoked. This allows
+ * method invocations to be chained.
+ *
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class IntBuffer
+ extends Buffer
+ implements Comparable<IntBuffer>
+{
+
+ // These fields are declared here rather than in Heap-X-Buffer in order to
+ // reduce the number of virtual method invocations needed to access these
+ // values, which is especially costly when coding small buffers.
+ //
+ final int[] hb; // Non-null only for heap buffers
+ final int offset;
+ boolean isReadOnly; // Valid only for heap buffers
+
+ // Creates a new buffer with the given mark, position, limit, capacity,
+ // backing array, and array offset
+ //
+ IntBuffer(int mark, int pos, int lim, int cap, // package-private
+ int[] hb, int offset)
+ {
+ // Android-added: elementSizeShift parameter (log2 of element size).
+ super(mark, pos, lim, cap, 2 /* elementSizeShift */);
+ this.hb = hb;
+ this.offset = offset;
+ }
+
+ // Creates a new buffer with the given mark, position, limit, and capacity
+ //
+ IntBuffer(int mark, int pos, int lim, int cap) { // package-private
+ this(mark, pos, lim, cap, null, 0);
+ }
+
+
+ /**
+ * Allocates a new int buffer.
+ *
+ * <p> The new buffer's position will be zero, its limit will be its
+ * capacity, its mark will be undefined, and each of its elements will be
+ * initialized to zero. It will have a {@link #array backing array},
+ * and its {@link #arrayOffset array offset} will be zero.
+ *
+ * @param capacity
+ * The new buffer's capacity, in ints
+ *
+ * @return The new int buffer
+ *
+ * @throws IllegalArgumentException
+ * If the <tt>capacity</tt> is a negative integer
+ */
+ public static IntBuffer allocate(int capacity) {
+ if (capacity < 0)
+ throw new IllegalArgumentException();
+ return new HeapIntBuffer(capacity, capacity);
+ }
+
+ /**
+ * Wraps an int array into a buffer.
+ *
+ * <p> The new buffer will be backed by the given int array;
+ * that is, modifications to the buffer will cause the array to be modified
+ * and vice versa. The new buffer's capacity will be
+ * <tt>array.length</tt>, its position will be <tt>offset</tt>, its limit
+ * will be <tt>offset + length</tt>, and its mark will be undefined. Its
+ * {@link #array backing array} will be the given array, and
+ * its {@link #arrayOffset array offset} will be zero. </p>
+ *
+ * @param array
+ * The array that will back the new buffer
+ *
+ * @param offset
+ * The offset of the subarray to be used; must be non-negative and
+ * no larger than <tt>array.length</tt>. The new buffer's position
+ * will be set to this value.
+ *
+ * @param length
+ * The length of the subarray to be used;
+ * must be non-negative and no larger than
+ * <tt>array.length - offset</tt>.
+ * The new buffer's limit will be set to <tt>offset + length</tt>.
+ *
+ * @return The new int buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ */
+ public static IntBuffer wrap(int[] array,
+ int offset, int length)
+ {
+ try {
+ return new HeapIntBuffer(array, offset, length);
+ } catch (IllegalArgumentException x) {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+
+ /**
+ * Wraps an int array into a buffer.
+ *
+ * <p> The new buffer will be backed by the given int array;
+ * that is, modifications to the buffer will cause the array to be modified
+ * and vice versa. The new buffer's capacity and limit will be
+ * <tt>array.length</tt>, its position will be zero, and its mark will be
+ * undefined. Its {@link #array backing array} will be the
+ * given array, and its {@link #arrayOffset array offset>} will
+ * be zero. </p>
+ *
+ * @param array
+ * The array that will back this buffer
+ *
+ * @return The new int buffer
+ */
+ public static IntBuffer wrap(int[] array) {
+ return wrap(array, 0, array.length);
+ }
+
+
+ /**
+ * Creates a new int buffer whose content is a shared subsequence of
+ * this buffer's content.
+ *
+ * <p> The content of the new buffer will start at this buffer's current
+ * position. Changes to this buffer's content will be visible in the new
+ * buffer, and vice versa; the two buffers' position, limit, and mark
+ * values will be independent.
+ *
+ * <p> The new buffer's position will be zero, its capacity and its limit
+ * will be the number of ints remaining in this buffer, and its mark
+ * will be undefined. The new buffer will be direct if, and only if, this
+ * buffer is direct, and it will be read-only if, and only if, this buffer
+ * is read-only. </p>
+ *
+ * @return The new int buffer
+ */
+ public abstract IntBuffer slice();
+
+ /**
+ * Creates a new int buffer that shares this buffer's content.
+ *
+ * <p> The content of the new buffer will be that of this buffer. Changes
+ * to this buffer's content will be visible in the new buffer, and vice
+ * versa; the two buffers' position, limit, and mark values will be
+ * independent.
+ *
+ * <p> The new buffer's capacity, limit, position, and mark values will be
+ * identical to those of this buffer. The new buffer will be direct if,
+ * and only if, this buffer is direct, and it will be read-only if, and
+ * only if, this buffer is read-only. </p>
+ *
+ * @return The new int buffer
+ */
+ public abstract IntBuffer duplicate();
+
+ /**
+ * Creates a new, read-only int buffer that shares this buffer's
+ * content.
+ *
+ * <p> The content of the new buffer will be that of this buffer. Changes
+ * to this buffer's content will be visible in the new buffer; the new
+ * buffer itself, however, will be read-only and will not allow the shared
+ * content to be modified. The two buffers' position, limit, and mark
+ * values will be independent.
+ *
+ * <p> The new buffer's capacity, limit, position, and mark values will be
+ * identical to those of this buffer.
+ *
+ * <p> If this buffer is itself read-only then this method behaves in
+ * exactly the same way as the {@link #duplicate duplicate} method. </p>
+ *
+ * @return The new, read-only int buffer
+ */
+ public abstract IntBuffer asReadOnlyBuffer();
+
+
+ // -- Singleton get/put methods --
+
+ /**
+ * Relative <i>get</i> method. Reads the int at this buffer's
+ * current position, and then increments the position.
+ *
+ * @return The int at the buffer's current position
+ *
+ * @throws BufferUnderflowException
+ * If the buffer's current position is not smaller than its limit
+ */
+ public abstract int get();
+
+ /**
+ * Relative <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> Writes the given int into this buffer at the current
+ * position, and then increments the position. </p>
+ *
+ * @param i
+ * The int to be written
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If this buffer's current position is not smaller than its limit
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract IntBuffer put(int i);
+
+ /**
+ * Absolute <i>get</i> method. Reads the int at the given
+ * index.
+ *
+ * @param index
+ * The index from which the int will be read
+ *
+ * @return The int at the given index
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
+ */
+ public abstract int get(int index);
+
+ /**
+ * Absolute <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> Writes the given int into this buffer at the given
+ * index. </p>
+ *
+ * @param index
+ * The index at which the int will be written
+ *
+ * @param i
+ * The int value to be written
+ *
+ * @return This buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract IntBuffer put(int index, int i);
+
+
+ // -- Bulk get operations --
+
+ /**
+ * Relative bulk <i>get</i> method.
+ *
+ * <p> This method transfers ints from this buffer into the given
+ * destination array. If there are fewer ints remaining in the
+ * buffer than are required to satisfy the request, that is, if
+ * <tt>length</tt> <tt>></tt> <tt>remaining()</tt>, then no
+ * ints are transferred and a {@link BufferUnderflowException} is
+ * thrown.
+ *
+ * <p> Otherwise, this method copies <tt>length</tt> ints from this
+ * buffer into the given array, starting at the current position of this
+ * buffer and at the given offset in the array. The position of this
+ * buffer is then incremented by <tt>length</tt>.
+ *
+ * <p> In other words, an invocation of this method of the form
+ * <tt>src.get(dst, off, len)</tt> has exactly the same effect as
+ * the loop
+ *
+ * <pre>{@code
+ * for (int i = off; i < off + len; i++)
+ * dst[i] = src.get();
+ * }</pre>
+ *
+ * except that it first checks that there are sufficient ints in
+ * this buffer and it is potentially much more efficient.
+ *
+ * @param dst
+ * The array into which ints are to be written
+ *
+ * @param offset
+ * The offset within the array of the first int to be
+ * written; must be non-negative and no larger than
+ * <tt>dst.length</tt>
+ *
+ * @param length
+ * The maximum number of ints to be written to the given
+ * array; must be non-negative and no larger than
+ * <tt>dst.length - offset</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than <tt>length</tt> ints
+ * remaining in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ */
+ public IntBuffer get(int[] dst, int offset, int length) {
+ checkBounds(offset, length, dst.length);
+ if (length > remaining())
+ throw new BufferUnderflowException();
+ int end = offset + length;
+ for (int i = offset; i < end; i++)
+ dst[i] = get();
+ return this;
+ }
+
+ /**
+ * Relative bulk <i>get</i> method.
+ *
+ * <p> This method transfers ints from this buffer into the given
+ * destination array. An invocation of this method of the form
+ * <tt>src.get(a)</tt> behaves in exactly the same way as the invocation
+ *
+ * <pre>
+ * src.get(a, 0, a.length) </pre>
+ *
+ * @param dst
+ * The destination array
+ *
+ * @return This buffer
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than <tt>length</tt> ints
+ * remaining in this buffer
+ */
+ public IntBuffer get(int[] dst) {
+ return get(dst, 0, dst.length);
+ }
+
+
+ // -- Bulk put operations --
+
+ /**
+ * Relative bulk <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> This method transfers the ints remaining in the given source
+ * buffer into this buffer. If there are more ints remaining in the
+ * source buffer than in this buffer, that is, if
+ * <tt>src.remaining()</tt> <tt>></tt> <tt>remaining()</tt>,
+ * then no ints are transferred and a {@link
+ * BufferOverflowException} is thrown.
+ *
+ * <p> Otherwise, this method copies
+ * <i>n</i> = <tt>src.remaining()</tt> ints from the given
+ * buffer into this buffer, starting at each buffer's current position.
+ * The positions of both buffers are then incremented by <i>n</i>.
+ *
+ * <p> In other words, an invocation of this method of the form
+ * <tt>dst.put(src)</tt> has exactly the same effect as the loop
+ *
+ * <pre>
+ * while (src.hasRemaining())
+ * dst.put(src.get()); </pre>
+ *
+ * except that it first checks that there is sufficient space in this
+ * buffer and it is potentially much more efficient.
+ *
+ * @param src
+ * The source buffer from which ints are to be read;
+ * must not be this buffer
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ * for the remaining ints in the source buffer
+ *
+ * @throws IllegalArgumentException
+ * If the source buffer is this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public IntBuffer put(IntBuffer src) {
+ if (src == this)
+ throw new IllegalArgumentException();
+ if (isReadOnly())
+ throw new ReadOnlyBufferException();
+ int n = src.remaining();
+ if (n > remaining())
+ throw new BufferOverflowException();
+ for (int i = 0; i < n; i++)
+ put(src.get());
+ return this;
+ }
+
+ /**
+ * Relative bulk <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> This method transfers ints into this buffer from the given
+ * source array. If there are more ints to be copied from the array
+ * than remain in this buffer, that is, if
+ * <tt>length</tt> <tt>></tt> <tt>remaining()</tt>, then no
+ * ints are transferred and a {@link BufferOverflowException} is
+ * thrown.
+ *
+ * <p> Otherwise, this method copies <tt>length</tt> ints from the
+ * given array into this buffer, starting at the given offset in the array
+ * and at the current position of this buffer. The position of this buffer
+ * is then incremented by <tt>length</tt>.
+ *
+ * <p> In other words, an invocation of this method of the form
+ * <tt>dst.put(src, off, len)</tt> has exactly the same effect as
+ * the loop
+ *
+ * <pre>{@code
+ * for (int i = off; i < off + len; i++)
+ * dst.put(a[i]);
+ * }</pre>
+ *
+ * except that it first checks that there is sufficient space in this
+ * buffer and it is potentially much more efficient.
+ *
+ * @param src
+ * The array from which ints are to be read
+ *
+ * @param offset
+ * The offset within the array of the first int to be read;
+ * must be non-negative and no larger than <tt>array.length</tt>
+ *
+ * @param length
+ * The number of ints to be read from the given array;
+ * must be non-negative and no larger than
+ * <tt>array.length - offset</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public IntBuffer put(int[] src, int offset, int length) {
+ checkBounds(offset, length, src.length);
+ if (length > remaining())
+ throw new BufferOverflowException();
+ int end = offset + length;
+ for (int i = offset; i < end; i++)
+ this.put(src[i]);
+ return this;
+ }
+
+ /**
+ * Relative bulk <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> This method transfers the entire content of the given source
+ * int array into this buffer. An invocation of this method of the
+ * form <tt>dst.put(a)</tt> behaves in exactly the same way as the
+ * invocation
+ *
+ * <pre>
+ * dst.put(a, 0, a.length) </pre>
+ *
+ * @param src
+ * The source array
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public final IntBuffer put(int[] src) {
+ return put(src, 0, src.length);
+ }
+
+
+ // -- Other stuff --
+
+ /**
+ * Tells whether or not this buffer is backed by an accessible int
+ * array.
+ *
+ * <p> If this method returns <tt>true</tt> then the {@link #array() array}
+ * and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
+ * </p>
+ *
+ * @return <tt>true</tt> if, and only if, this buffer
+ * is backed by an array and is not read-only
+ */
+ public final boolean hasArray() {
+ return (hb != null) && !isReadOnly;
+ }
+
+ /**
+ * Returns the int array that backs this
+ * buffer <i>(optional operation)</i>.
+ *
+ * <p> Modifications to this buffer's content will cause the returned
+ * array's content to be modified, and vice versa.
+ *
+ * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+ * method in order to ensure that this buffer has an accessible backing
+ * array. </p>
+ *
+ * @return The array that backs this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
+ */
+ public final int[] array() {
+ if (hb == null)
+ throw new UnsupportedOperationException();
+ if (isReadOnly)
+ throw new ReadOnlyBufferException();
+ return hb;
+ }
+
+ /**
+ * Returns the offset within this buffer's backing array of the first
+ * element of the buffer <i>(optional operation)</i>.
+ *
+ * <p> If this buffer is backed by an array then buffer position <i>p</i>
+ * corresponds to array index <i>p</i> + <tt>arrayOffset()</tt>.
+ *
+ * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+ * method in order to ensure that this buffer has an accessible backing
+ * array. </p>
+ *
+ * @return The offset within this buffer's array
+ * of the first element of the buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
+ */
+ public final int arrayOffset() {
+ if (hb == null)
+ throw new UnsupportedOperationException();
+ if (isReadOnly)
+ throw new ReadOnlyBufferException();
+ return offset;
+ }
+
+ // BEGIN Android-added: covariant overloads of *Buffer methods that return this.
+ @CovariantReturnType(returnType = IntBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer position(int newPosition) {
+ return super.position(newPosition);
+ }
+
+ @CovariantReturnType(returnType = IntBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer limit(int newLimit) {
+ return super.limit(newLimit);
+ }
+
+ @CovariantReturnType(returnType = IntBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer mark() {
+ return super.mark();
+ }
+
+ @CovariantReturnType(returnType = IntBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer reset() {
+ return super.reset();
+ }
+
+ @CovariantReturnType(returnType = IntBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer clear() {
+ return super.clear();
+ }
+
+ @CovariantReturnType(returnType = IntBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer flip() {
+ return super.flip();
+ }
+
+ @CovariantReturnType(returnType = IntBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer rewind() {
+ return super.rewind();
+ }
+ // END Android-added: covariant overloads of *Buffer methods that return this.
+
+ /**
+ * Compacts this buffer <i>(optional operation)</i>.
+ *
+ * <p> The ints between the buffer's current position and its limit,
+ * if any, are copied to the beginning of the buffer. That is, the
+ * int at index <i>p</i> = <tt>position()</tt> is copied
+ * to index zero, the int at index <i>p</i> + 1 is copied
+ * to index one, and so forth until the int at index
+ * <tt>limit()</tt> - 1 is copied to index
+ * <i>n</i> = <tt>limit()</tt> - <tt>1</tt> - <i>p</i>.
+ * The buffer's position is then set to <i>n+1</i> and its limit is set to
+ * its capacity. The mark, if defined, is discarded.
+ *
+ * <p> The buffer's position is set to the number of ints copied,
+ * rather than to zero, so that an invocation of this method can be
+ * followed immediately by an invocation of another relative <i>put</i>
+ * method. </p>
+ *
+
+ *
+ * @return This buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract IntBuffer compact();
+
+ /**
+ * Tells whether or not this int buffer is direct.
+ *
+ * @return <tt>true</tt> if, and only if, this buffer is direct
+ */
+ public abstract boolean isDirect();
+
+
+ /**
+ * Returns a string summarizing the state of this buffer.
+ *
+ * @return A summary string
+ */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(getClass().getName());
+ sb.append("[pos=");
+ sb.append(position());
+ sb.append(" lim=");
+ sb.append(limit());
+ sb.append(" cap=");
+ sb.append(capacity());
+ sb.append("]");
+ return sb.toString();
+ }
+
+
+ /**
+ * Returns the current hash code of this buffer.
+ *
+ * <p> The hash code of a int buffer depends only upon its remaining
+ * elements; that is, upon the elements from <tt>position()</tt> up to, and
+ * including, the element at <tt>limit()</tt> - <tt>1</tt>.
+ *
+ * <p> Because buffer hash codes are content-dependent, it is inadvisable
+ * to use buffers as keys in hash maps or similar data structures unless it
+ * is known that their contents will not change. </p>
+ *
+ * @return The current hash code of this buffer
+ */
+ public int hashCode() {
+ int h = 1;
+ int p = position();
+ for (int i = limit() - 1; i >= p; i--)
+ h = 31 * h + (int) get(i);
+ return h;
+ }
+
+ /**
+ * Tells whether or not this buffer is equal to another object.
+ *
+ * <p> Two int buffers are equal if, and only if,
+ *
+ * <ol>
+ *
+ * <li><p> They have the same element type, </p></li>
+ *
+ * <li><p> They have the same number of remaining elements, and
+ * </p></li>
+ *
+ * <li><p> The two sequences of remaining elements, considered
+ * independently of their starting positions, are pointwise equal.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * </p></li>
+ *
+ * </ol>
+ *
+ * <p> A int buffer is not equal to any other type of object. </p>
+ *
+ * @param ob The object to which this buffer is to be compared
+ *
+ * @return <tt>true</tt> if, and only if, this buffer is equal to the
+ * given object
+ */
+ public boolean equals(Object ob) {
+ if (this == ob)
+ return true;
+ if (!(ob instanceof IntBuffer))
+ return false;
+ IntBuffer that = (IntBuffer)ob;
+ if (this.remaining() != that.remaining())
+ return false;
+ int p = this.position();
+ for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--)
+ if (!equals(this.get(i), that.get(j)))
+ return false;
+ return true;
+ }
+
+ private static boolean equals(int x, int y) {
+
+
+ return x == y;
+
+ }
+
+ /**
+ * Compares this buffer to another.
+ *
+ * <p> Two int buffers are compared by comparing their sequences of
+ * remaining elements lexicographically, without regard to the starting
+ * position of each sequence within its corresponding buffer.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * Pairs of {@code int} elements are compared as if by invoking
+ * {@link Integer#compare(int,int)}.
+
+ *
+ * <p> A int buffer is not comparable to any other type of object.
+ *
+ * @return A negative integer, zero, or a positive integer as this buffer
+ * is less than, equal to, or greater than the given buffer
+ */
+ public int compareTo(IntBuffer that) {
+ int n = this.position() + Math.min(this.remaining(), that.remaining());
+ for (int i = this.position(), j = that.position(); i < n; i++, j++) {
+ int cmp = compare(this.get(i), that.get(j));
+ if (cmp != 0)
+ return cmp;
+ }
+ return this.remaining() - that.remaining();
+ }
+
+ private static int compare(int x, int y) {
+
+
+ return Integer.compare(x, y);
+
+ }
+
+ // -- Other char stuff --
+
+
+ // -- Other byte stuff: Access to binary data --
+
+
+ /**
+ * Retrieves this buffer's byte order.
+ *
+ * <p> The byte order of an int buffer created by allocation or by
+ * wrapping an existing <tt>int</tt> array is the {@link
+ * ByteOrder#nativeOrder native order} of the underlying
+ * hardware. The byte order of an int buffer created as a <a
+ * href="ByteBuffer.html#views">view</a> of a byte buffer is that of the
+ * byte buffer at the moment that the view is created. </p>
+ *
+ * @return This buffer's byte order
+ */
+ public abstract ByteOrder order();
+
+
+}
diff --git a/java/nio/InvalidMarkException.java b/java/nio/InvalidMarkException.java
new file mode 100644
index 0000000..ed1a059
--- /dev/null
+++ b/java/nio/InvalidMarkException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to reset a buffer
+ * when its mark is not defined.
+ *
+ * @since 1.4
+ */
+
+public class InvalidMarkException
+ extends IllegalStateException
+{
+
+ private static final long serialVersionUID = 1698329710438510774L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public InvalidMarkException() { }
+
+}
diff --git a/java/nio/LongBuffer.java b/java/nio/LongBuffer.java
new file mode 100644
index 0000000..5e5fa18
--- /dev/null
+++ b/java/nio/LongBuffer.java
@@ -0,0 +1,868 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio;
+
+
+import dalvik.annotation.codegen.CovariantReturnType;
+
+/**
+ * A long buffer.
+ *
+ * <p> This class defines four categories of operations upon
+ * long buffers:
+ *
+ * <ul>
+ *
+ * <li><p> Absolute and relative {@link #get() <i>get</i>} and
+ * {@link #put(long) <i>put</i>} methods that read and write
+ * single longs; </p></li>
+ *
+ * <li><p> Relative {@link #get(long[]) <i>bulk get</i>}
+ * methods that transfer contiguous sequences of longs from this buffer
+ * into an array; and</p></li>
+ *
+ * <li><p> Relative {@link #put(long[]) <i>bulk put</i>}
+ * methods that transfer contiguous sequences of longs from a
+ * long array or some other long
+ * buffer into this buffer; and </p></li>
+ *
+ *
+ * <li><p> Methods for {@link #compact compacting}, {@link
+ * #duplicate duplicating}, and {@link #slice slicing}
+ * a long buffer. </p></li>
+ *
+ * </ul>
+ *
+ * <p> Long buffers can be created either by {@link #allocate
+ * <i>allocation</i>}, which allocates space for the buffer's
+ *
+ *
+ * content, by {@link #wrap(long[]) <i>wrapping</i>} an existing
+ * long array into a buffer, or by creating a
+ * <a href="ByteBuffer.html#views"><i>view</i></a> of an existing byte buffer.
+ *
+ *
+*
+ *
+ * <p> Like a byte buffer, a long buffer is either <a
+ * href="ByteBuffer.html#direct"><i>direct</i> or <i>non-direct</i></a>. A
+ * long buffer created via the <tt>wrap</tt> methods of this class will
+ * be non-direct. A long buffer created as a view of a byte buffer will
+ * be direct if, and only if, the byte buffer itself is direct. Whether or not
+ * a long buffer is direct may be determined by invoking the {@link
+ * #isDirect isDirect} method. </p>
+ *
+*
+ *
+ *
+ * <p> Methods in this class that do not otherwise have a value to return are
+ * specified to return the buffer upon which they are invoked. This allows
+ * method invocations to be chained.
+ *
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class LongBuffer
+ extends Buffer
+ implements Comparable<LongBuffer>
+{
+
+ // These fields are declared here rather than in Heap-X-Buffer in order to
+ // reduce the number of virtual method invocations needed to access these
+ // values, which is especially costly when coding small buffers.
+ //
+ final long[] hb; // Non-null only for heap buffers
+ final int offset;
+ boolean isReadOnly; // Valid only for heap buffers
+
+ // Creates a new buffer with the given mark, position, limit, capacity,
+ // backing array, and array offset
+ //
+ LongBuffer(int mark, int pos, int lim, int cap, // package-private
+ long[] hb, int offset)
+ {
+ // Android-added: elementSizeShift parameter (log2 of element size).
+ super(mark, pos, lim, cap, 3 /* elementSizeShift */);
+ this.hb = hb;
+ this.offset = offset;
+ }
+
+ // Creates a new buffer with the given mark, position, limit, and capacity
+ //
+ LongBuffer(int mark, int pos, int lim, int cap) { // package-private
+ this(mark, pos, lim, cap, null, 0);
+ }
+
+
+ /**
+ * Allocates a new long buffer.
+ *
+ * <p> The new buffer's position will be zero, its limit will be its
+ * capacity, its mark will be undefined, and each of its elements will be
+ * initialized to zero. It will have a {@link #array backing array},
+ * and its {@link #arrayOffset array offset} will be zero.
+ *
+ * @param capacity
+ * The new buffer's capacity, in longs
+ *
+ * @return The new long buffer
+ *
+ * @throws IllegalArgumentException
+ * If the <tt>capacity</tt> is a negative integer
+ */
+ public static LongBuffer allocate(int capacity) {
+ if (capacity < 0)
+ throw new IllegalArgumentException();
+ return new HeapLongBuffer(capacity, capacity);
+ }
+
+ /**
+ * Wraps a long array into a buffer.
+ *
+ * <p> The new buffer will be backed by the given long array;
+ * that is, modifications to the buffer will cause the array to be modified
+ * and vice versa. The new buffer's capacity will be
+ * <tt>array.length</tt>, its position will be <tt>offset</tt>, its limit
+ * will be <tt>offset + length</tt>, and its mark will be undefined. Its
+ * {@link #array backing array} will be the given array, and
+ * its {@link #arrayOffset array offset} will be zero. </p>
+ *
+ * @param array
+ * The array that will back the new buffer
+ *
+ * @param offset
+ * The offset of the subarray to be used; must be non-negative and
+ * no larger than <tt>array.length</tt>. The new buffer's position
+ * will be set to this value.
+ *
+ * @param length
+ * The length of the subarray to be used;
+ * must be non-negative and no larger than
+ * <tt>array.length - offset</tt>.
+ * The new buffer's limit will be set to <tt>offset + length</tt>.
+ *
+ * @return The new long buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ */
+ public static LongBuffer wrap(long[] array,
+ int offset, int length)
+ {
+ try {
+ return new HeapLongBuffer(array, offset, length);
+ } catch (IllegalArgumentException x) {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+
+ /**
+ * Wraps a long array into a buffer.
+ *
+ * <p> The new buffer will be backed by the given long array;
+ * that is, modifications to the buffer will cause the array to be modified
+ * and vice versa. The new buffer's capacity and limit will be
+ * <tt>array.length</tt>, its position will be zero, and its mark will be
+ * undefined. Its {@link #array backing array} will be the
+ * given array, and its {@link #arrayOffset array offset>} will
+ * be zero. </p>
+ *
+ * @param array
+ * The array that will back this buffer
+ *
+ * @return The new long buffer
+ */
+ public static LongBuffer wrap(long[] array) {
+ return wrap(array, 0, array.length);
+ }
+
+
+ /**
+ * Creates a new long buffer whose content is a shared subsequence of
+ * this buffer's content.
+ *
+ * <p> The content of the new buffer will start at this buffer's current
+ * position. Changes to this buffer's content will be visible in the new
+ * buffer, and vice versa; the two buffers' position, limit, and mark
+ * values will be independent.
+ *
+ * <p> The new buffer's position will be zero, its capacity and its limit
+ * will be the number of longs remaining in this buffer, and its mark
+ * will be undefined. The new buffer will be direct if, and only if, this
+ * buffer is direct, and it will be read-only if, and only if, this buffer
+ * is read-only. </p>
+ *
+ * @return The new long buffer
+ */
+ public abstract LongBuffer slice();
+
+ /**
+ * Creates a new long buffer that shares this buffer's content.
+ *
+ * <p> The content of the new buffer will be that of this buffer. Changes
+ * to this buffer's content will be visible in the new buffer, and vice
+ * versa; the two buffers' position, limit, and mark values will be
+ * independent.
+ *
+ * <p> The new buffer's capacity, limit, position, and mark values will be
+ * identical to those of this buffer. The new buffer will be direct if,
+ * and only if, this buffer is direct, and it will be read-only if, and
+ * only if, this buffer is read-only. </p>
+ *
+ * @return The new long buffer
+ */
+ public abstract LongBuffer duplicate();
+
+ /**
+ * Creates a new, read-only long buffer that shares this buffer's
+ * content.
+ *
+ * <p> The content of the new buffer will be that of this buffer. Changes
+ * to this buffer's content will be visible in the new buffer; the new
+ * buffer itself, however, will be read-only and will not allow the shared
+ * content to be modified. The two buffers' position, limit, and mark
+ * values will be independent.
+ *
+ * <p> The new buffer's capacity, limit, position, and mark values will be
+ * identical to those of this buffer.
+ *
+ * <p> If this buffer is itself read-only then this method behaves in
+ * exactly the same way as the {@link #duplicate duplicate} method. </p>
+ *
+ * @return The new, read-only long buffer
+ */
+ public abstract LongBuffer asReadOnlyBuffer();
+
+
+ // -- Singleton get/put methods --
+
+ /**
+ * Relative <i>get</i> method. Reads the long at this buffer's
+ * current position, and then increments the position.
+ *
+ * @return The long at the buffer's current position
+ *
+ * @throws BufferUnderflowException
+ * If the buffer's current position is not smaller than its limit
+ */
+ public abstract long get();
+
+ /**
+ * Relative <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> Writes the given long into this buffer at the current
+ * position, and then increments the position. </p>
+ *
+ * @param l
+ * The long to be written
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If this buffer's current position is not smaller than its limit
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract LongBuffer put(long l);
+
+ /**
+ * Absolute <i>get</i> method. Reads the long at the given
+ * index.
+ *
+ * @param index
+ * The index from which the long will be read
+ *
+ * @return The long at the given index
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
+ */
+ public abstract long get(int index);
+
+ /**
+ * Absolute <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> Writes the given long into this buffer at the given
+ * index. </p>
+ *
+ * @param index
+ * The index at which the long will be written
+ *
+ * @param l
+ * The long value to be written
+ *
+ * @return This buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract LongBuffer put(int index, long l);
+
+
+ // -- Bulk get operations --
+
+ /**
+ * Relative bulk <i>get</i> method.
+ *
+ * <p> This method transfers longs from this buffer into the given
+ * destination array. If there are fewer longs remaining in the
+ * buffer than are required to satisfy the request, that is, if
+ * <tt>length</tt> <tt>></tt> <tt>remaining()</tt>, then no
+ * longs are transferred and a {@link BufferUnderflowException} is
+ * thrown.
+ *
+ * <p> Otherwise, this method copies <tt>length</tt> longs from this
+ * buffer into the given array, starting at the current position of this
+ * buffer and at the given offset in the array. The position of this
+ * buffer is then incremented by <tt>length</tt>.
+ *
+ * <p> In other words, an invocation of this method of the form
+ * <tt>src.get(dst, off, len)</tt> has exactly the same effect as
+ * the loop
+ *
+ * <pre>{@code
+ * for (int i = off; i < off + len; i++)
+ * dst[i] = src.get();
+ * }</pre>
+ *
+ * except that it first checks that there are sufficient longs in
+ * this buffer and it is potentially much more efficient.
+ *
+ * @param dst
+ * The array into which longs are to be written
+ *
+ * @param offset
+ * The offset within the array of the first long to be
+ * written; must be non-negative and no larger than
+ * <tt>dst.length</tt>
+ *
+ * @param length
+ * The maximum number of longs to be written to the given
+ * array; must be non-negative and no larger than
+ * <tt>dst.length - offset</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than <tt>length</tt> longs
+ * remaining in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ */
+ public LongBuffer get(long[] dst, int offset, int length) {
+ checkBounds(offset, length, dst.length);
+ if (length > remaining())
+ throw new BufferUnderflowException();
+ int end = offset + length;
+ for (int i = offset; i < end; i++)
+ dst[i] = get();
+ return this;
+ }
+
+ /**
+ * Relative bulk <i>get</i> method.
+ *
+ * <p> This method transfers longs from this buffer into the given
+ * destination array. An invocation of this method of the form
+ * <tt>src.get(a)</tt> behaves in exactly the same way as the invocation
+ *
+ * <pre>
+ * src.get(a, 0, a.length) </pre>
+ *
+ * @param dst
+ * The destination array
+ *
+ * @return This buffer
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than <tt>length</tt> longs
+ * remaining in this buffer
+ */
+ public LongBuffer get(long[] dst) {
+ return get(dst, 0, dst.length);
+ }
+
+
+ // -- Bulk put operations --
+
+ /**
+ * Relative bulk <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> This method transfers the longs remaining in the given source
+ * buffer into this buffer. If there are more longs remaining in the
+ * source buffer than in this buffer, that is, if
+ * <tt>src.remaining()</tt> <tt>></tt> <tt>remaining()</tt>,
+ * then no longs are transferred and a {@link
+ * BufferOverflowException} is thrown.
+ *
+ * <p> Otherwise, this method copies
+ * <i>n</i> = <tt>src.remaining()</tt> longs from the given
+ * buffer into this buffer, starting at each buffer's current position.
+ * The positions of both buffers are then incremented by <i>n</i>.
+ *
+ * <p> In other words, an invocation of this method of the form
+ * <tt>dst.put(src)</tt> has exactly the same effect as the loop
+ *
+ * <pre>
+ * while (src.hasRemaining())
+ * dst.put(src.get()); </pre>
+ *
+ * except that it first checks that there is sufficient space in this
+ * buffer and it is potentially much more efficient.
+ *
+ * @param src
+ * The source buffer from which longs are to be read;
+ * must not be this buffer
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ * for the remaining longs in the source buffer
+ *
+ * @throws IllegalArgumentException
+ * If the source buffer is this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public LongBuffer put(LongBuffer src) {
+ if (src == this)
+ throw new IllegalArgumentException();
+ if (isReadOnly())
+ throw new ReadOnlyBufferException();
+ int n = src.remaining();
+ if (n > remaining())
+ throw new BufferOverflowException();
+ for (int i = 0; i < n; i++)
+ put(src.get());
+ return this;
+ }
+
+ /**
+ * Relative bulk <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> This method transfers longs into this buffer from the given
+ * source array. If there are more longs to be copied from the array
+ * than remain in this buffer, that is, if
+ * <tt>length</tt> <tt>></tt> <tt>remaining()</tt>, then no
+ * longs are transferred and a {@link BufferOverflowException} is
+ * thrown.
+ *
+ * <p> Otherwise, this method copies <tt>length</tt> longs from the
+ * given array into this buffer, starting at the given offset in the array
+ * and at the current position of this buffer. The position of this buffer
+ * is then incremented by <tt>length</tt>.
+ *
+ * <p> In other words, an invocation of this method of the form
+ * <tt>dst.put(src, off, len)</tt> has exactly the same effect as
+ * the loop
+ *
+ * <pre>{@code
+ * for (int i = off; i < off + len; i++)
+ * dst.put(a[i]);
+ * }</pre>
+ *
+ * except that it first checks that there is sufficient space in this
+ * buffer and it is potentially much more efficient.
+ *
+ * @param src
+ * The array from which longs are to be read
+ *
+ * @param offset
+ * The offset within the array of the first long to be read;
+ * must be non-negative and no larger than <tt>array.length</tt>
+ *
+ * @param length
+ * The number of longs to be read from the given array;
+ * must be non-negative and no larger than
+ * <tt>array.length - offset</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public LongBuffer put(long[] src, int offset, int length) {
+ checkBounds(offset, length, src.length);
+ if (length > remaining())
+ throw new BufferOverflowException();
+ int end = offset + length;
+ for (int i = offset; i < end; i++)
+ this.put(src[i]);
+ return this;
+ }
+
+ /**
+ * Relative bulk <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> This method transfers the entire content of the given source
+ * long array into this buffer. An invocation of this method of the
+ * form <tt>dst.put(a)</tt> behaves in exactly the same way as the
+ * invocation
+ *
+ * <pre>
+ * dst.put(a, 0, a.length) </pre>
+ *
+ * @param src
+ * The source array
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public final LongBuffer put(long[] src) {
+ return put(src, 0, src.length);
+ }
+
+
+ // -- Other stuff --
+
+ /**
+ * Tells whether or not this buffer is backed by an accessible long
+ * array.
+ *
+ * <p> If this method returns <tt>true</tt> then the {@link #array() array}
+ * and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
+ * </p>
+ *
+ * @return <tt>true</tt> if, and only if, this buffer
+ * is backed by an array and is not read-only
+ */
+ public final boolean hasArray() {
+ return (hb != null) && !isReadOnly;
+ }
+
+ /**
+ * Returns the long array that backs this
+ * buffer <i>(optional operation)</i>.
+ *
+ * <p> Modifications to this buffer's content will cause the returned
+ * array's content to be modified, and vice versa.
+ *
+ * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+ * method in order to ensure that this buffer has an accessible backing
+ * array. </p>
+ *
+ * @return The array that backs this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
+ */
+ public final long[] array() {
+ if (hb == null)
+ throw new UnsupportedOperationException();
+ if (isReadOnly)
+ throw new ReadOnlyBufferException();
+ return hb;
+ }
+
+ /**
+ * Returns the offset within this buffer's backing array of the first
+ * element of the buffer <i>(optional operation)</i>.
+ *
+ * <p> If this buffer is backed by an array then buffer position <i>p</i>
+ * corresponds to array index <i>p</i> + <tt>arrayOffset()</tt>.
+ *
+ * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+ * method in order to ensure that this buffer has an accessible backing
+ * array. </p>
+ *
+ * @return The offset within this buffer's array
+ * of the first element of the buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
+ */
+ public final int arrayOffset() {
+ if (hb == null)
+ throw new UnsupportedOperationException();
+ if (isReadOnly)
+ throw new ReadOnlyBufferException();
+ return offset;
+ }
+
+ // BEGIN Android-added: covariant overloads of *Buffer methods that return this.
+ @CovariantReturnType(returnType = LongBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer position(int newPosition) {
+ return super.position(newPosition);
+ }
+
+ @CovariantReturnType(returnType = LongBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer limit(int newLimit) {
+ return super.limit(newLimit);
+ }
+
+ @CovariantReturnType(returnType = LongBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer mark() {
+ return super.mark();
+ }
+
+ @CovariantReturnType(returnType = LongBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer reset() {
+ return super.reset();
+ }
+
+ @CovariantReturnType(returnType = LongBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer clear() {
+ return super.clear();
+ }
+
+ @CovariantReturnType(returnType = LongBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer flip() {
+ return super.flip();
+ }
+
+ @CovariantReturnType(returnType = LongBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer rewind() {
+ return super.rewind();
+ }
+ // END Android-added: covariant overloads of *Buffer methods that return this.
+
+ /**
+ * Compacts this buffer <i>(optional operation)</i>.
+ *
+ * <p> The longs between the buffer's current position and its limit,
+ * if any, are copied to the beginning of the buffer. That is, the
+ * long at index <i>p</i> = <tt>position()</tt> is copied
+ * to index zero, the long at index <i>p</i> + 1 is copied
+ * to index one, and so forth until the long at index
+ * <tt>limit()</tt> - 1 is copied to index
+ * <i>n</i> = <tt>limit()</tt> - <tt>1</tt> - <i>p</i>.
+ * The buffer's position is then set to <i>n+1</i> and its limit is set to
+ * its capacity. The mark, if defined, is discarded.
+ *
+ * <p> The buffer's position is set to the number of longs copied,
+ * rather than to zero, so that an invocation of this method can be
+ * followed immediately by an invocation of another relative <i>put</i>
+ * method. </p>
+ *
+
+ *
+ * @return This buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract LongBuffer compact();
+
+ /**
+ * Tells whether or not this long buffer is direct.
+ *
+ * @return <tt>true</tt> if, and only if, this buffer is direct
+ */
+ public abstract boolean isDirect();
+
+
+ /**
+ * Returns a string summarizing the state of this buffer.
+ *
+ * @return A summary string
+ */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(getClass().getName());
+ sb.append("[pos=");
+ sb.append(position());
+ sb.append(" lim=");
+ sb.append(limit());
+ sb.append(" cap=");
+ sb.append(capacity());
+ sb.append("]");
+ return sb.toString();
+ }
+
+
+ /**
+ * Returns the current hash code of this buffer.
+ *
+ * <p> The hash code of a long buffer depends only upon its remaining
+ * elements; that is, upon the elements from <tt>position()</tt> up to, and
+ * including, the element at <tt>limit()</tt> - <tt>1</tt>.
+ *
+ * <p> Because buffer hash codes are content-dependent, it is inadvisable
+ * to use buffers as keys in hash maps or similar data structures unless it
+ * is known that their contents will not change. </p>
+ *
+ * @return The current hash code of this buffer
+ */
+ public int hashCode() {
+ int h = 1;
+ int p = position();
+ for (int i = limit() - 1; i >= p; i--)
+ h = 31 * h + (int) get(i);
+ return h;
+ }
+
+ /**
+ * Tells whether or not this buffer is equal to another object.
+ *
+ * <p> Two long buffers are equal if, and only if,
+ *
+ * <ol>
+ *
+ * <li><p> They have the same element type, </p></li>
+ *
+ * <li><p> They have the same number of remaining elements, and
+ * </p></li>
+ *
+ * <li><p> The two sequences of remaining elements, considered
+ * independently of their starting positions, are pointwise equal.
+
+ * </p></li>
+ *
+ * </ol>
+ *
+ * <p> A long buffer is not equal to any other type of object. </p>
+ *
+ * @param ob The object to which this buffer is to be compared
+ *
+ * @return <tt>true</tt> if, and only if, this buffer is equal to the
+ * given object
+ */
+ public boolean equals(Object ob) {
+ if (this == ob)
+ return true;
+ if (!(ob instanceof LongBuffer))
+ return false;
+ LongBuffer that = (LongBuffer)ob;
+ if (this.remaining() != that.remaining())
+ return false;
+ int p = this.position();
+ for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--)
+ if (!equals(this.get(i), that.get(j)))
+ return false;
+ return true;
+ }
+
+ private static boolean equals(long x, long y) {
+
+
+ return x == y;
+
+ }
+
+ /**
+ * Compares this buffer to another.
+ *
+ * <p> Two long buffers are compared by comparing their sequences of
+ * remaining elements lexicographically, without regard to the starting
+ * position of each sequence within its corresponding buffer.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * Pairs of {@code long} elements are compared as if by invoking
+ * {@link Long#compare(long,long)}.
+
+ *
+ * <p> A long buffer is not comparable to any other type of object.
+ *
+ * @return A negative integer, zero, or a positive integer as this buffer
+ * is less than, equal to, or greater than the given buffer
+ */
+ public int compareTo(LongBuffer that) {
+ int n = this.position() + Math.min(this.remaining(), that.remaining());
+ for (int i = this.position(), j = that.position(); i < n; i++, j++) {
+ int cmp = compare(this.get(i), that.get(j));
+ if (cmp != 0)
+ return cmp;
+ }
+ return this.remaining() - that.remaining();
+ }
+
+ private static int compare(long x, long y) {
+
+
+ return Long.compare(x, y);
+
+ }
+
+ // -- Other char stuff --
+
+
+ // -- Other byte stuff: Access to binary data --
+
+
+ /**
+ * Retrieves this buffer's byte order.
+ *
+ * <p> The byte order of a long buffer created by allocation or by
+ * wrapping an existing <tt>long</tt> array is the {@link
+ * ByteOrder#nativeOrder native order} of the underlying
+ * hardware. The byte order of a long buffer created as a <a
+ * href="ByteBuffer.html#views">view</a> of a byte buffer is that of the
+ * byte buffer at the moment that the view is created. </p>
+ *
+ * @return This buffer's byte order
+ */
+ public abstract ByteOrder order();
+
+
+}
diff --git a/java/nio/MappedByteBuffer.java b/java/nio/MappedByteBuffer.java
new file mode 100644
index 0000000..2ea6cbd
--- /dev/null
+++ b/java/nio/MappedByteBuffer.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio;
+
+import java.io.FileDescriptor;
+import sun.misc.Unsafe;
+
+
+/**
+ * A direct byte buffer whose content is a memory-mapped region of a file.
+ *
+ * <p> Mapped byte buffers are created via the {@link
+ * java.nio.channels.FileChannel#map FileChannel.map} method. This class
+ * extends the {@link ByteBuffer} class with operations that are specific to
+ * memory-mapped file regions.
+ *
+ * <p> A mapped byte buffer and the file mapping that it represents remain
+ * valid until the buffer itself is garbage-collected.
+ *
+ * <p> The content of a mapped byte buffer can change at any time, for example
+ * if the content of the corresponding region of the mapped file is changed by
+ * this program or another. Whether or not such changes occur, and when they
+ * occur, is operating-system dependent and therefore unspecified.
+ *
+ * <a name="inaccess"></a><p> All or part of a mapped byte buffer may become
+ * inaccessible at any time, for example if the mapped file is truncated. An
+ * attempt to access an inaccessible region of a mapped byte buffer will not
+ * change the buffer's content and will cause an unspecified exception to be
+ * thrown either at the time of the access or at some later time. It is
+ * therefore strongly recommended that appropriate precautions be taken to
+ * avoid the manipulation of a mapped file by this program, or by a
+ * concurrently running program, except to read or write the file's content.
+ *
+ * <p> Mapped byte buffers otherwise behave no differently than ordinary direct
+ * byte buffers. </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class MappedByteBuffer
+ extends ByteBuffer
+{
+
+ // This is a little bit backwards: By rights MappedByteBuffer should be a
+ // subclass of DirectByteBuffer, but to keep the spec clear and simple, and
+ // for optimization purposes, it's easier to do it the other way around.
+ // This works because DirectByteBuffer is a package-private class.
+
+ // For mapped buffers, a FileDescriptor that may be used for mapping
+ // operations if valid; null if the buffer is not mapped.
+ private final FileDescriptor fd;
+
+ // This should only be invoked by the DirectByteBuffer constructors
+ //
+ MappedByteBuffer(int mark, int pos, int lim, int cap, // package-private
+ FileDescriptor fd)
+ {
+ super(mark, pos, lim, cap);
+ this.fd = fd;
+ }
+
+ // Android-added: Additional constructor for use by Android's DirectByteBuffer.
+ MappedByteBuffer(int mark, int pos, int lim, int cap, byte[] buf, int offset) {
+ super(mark, pos, lim, cap, buf, offset);
+ this.fd = null;
+ }
+
+ MappedByteBuffer(int mark, int pos, int lim, int cap) { // package-private
+ super(mark, pos, lim, cap);
+ this.fd = null;
+ }
+
+ private void checkMapped() {
+ if (fd == null)
+ // Can only happen if a luser explicitly casts a direct byte buffer
+ throw new UnsupportedOperationException();
+ }
+
+ // Returns the distance (in bytes) of the buffer from the page aligned address
+ // of the mapping. Computed each time to avoid storing in every direct buffer.
+ private long mappingOffset() {
+ int ps = Bits.pageSize();
+ long offset = address % ps;
+ return (offset >= 0) ? offset : (ps + offset);
+ }
+
+ private long mappingAddress(long mappingOffset) {
+ return address - mappingOffset;
+ }
+
+ private long mappingLength(long mappingOffset) {
+ return (long)capacity() + mappingOffset;
+ }
+
+ /**
+ * Tells whether or not this buffer's content is resident in physical
+ * memory.
+ *
+ * <p> A return value of <tt>true</tt> implies that it is highly likely
+ * that all of the data in this buffer is resident in physical memory and
+ * may therefore be accessed without incurring any virtual-memory page
+ * faults or I/O operations. A return value of <tt>false</tt> does not
+ * necessarily imply that the buffer's content is not resident in physical
+ * memory.
+ *
+ * <p> The returned value is a hint, rather than a guarantee, because the
+ * underlying operating system may have paged out some of the buffer's data
+ * by the time that an invocation of this method returns. </p>
+ *
+ * @return <tt>true</tt> if it is likely that this buffer's content
+ * is resident in physical memory
+ */
+ public final boolean isLoaded() {
+ checkMapped();
+ if ((address == 0) || (capacity() == 0))
+ return true;
+ long offset = mappingOffset();
+ long length = mappingLength(offset);
+ return isLoaded0(mappingAddress(offset), length, Bits.pageCount(length));
+ }
+
+ // not used, but a potential target for a store, see load() for details.
+ private static byte unused;
+
+ /**
+ * Loads this buffer's content into physical memory.
+ *
+ * <p> This method makes a best effort to ensure that, when it returns,
+ * this buffer's content is resident in physical memory. Invoking this
+ * method may cause some number of page faults and I/O operations to
+ * occur. </p>
+ *
+ * @return This buffer
+ */
+ public final MappedByteBuffer load() {
+ checkMapped();
+ if ((address == 0) || (capacity() == 0))
+ return this;
+ long offset = mappingOffset();
+ long length = mappingLength(offset);
+ load0(mappingAddress(offset), length);
+
+ // Read a byte from each page to bring it into memory. A checksum
+ // is computed as we go along to prevent the compiler from otherwise
+ // considering the loop as dead code.
+ Unsafe unsafe = Unsafe.getUnsafe();
+ int ps = Bits.pageSize();
+ int count = Bits.pageCount(length);
+ long a = mappingAddress(offset);
+ byte x = 0;
+ for (int i=0; i<count; i++) {
+ x ^= unsafe.getByte(a);
+ a += ps;
+ }
+ if (unused != 0)
+ unused = x;
+
+ return this;
+ }
+
+ /**
+ * Forces any changes made to this buffer's content to be written to the
+ * storage device containing the mapped file.
+ *
+ * <p> If the file mapped into this buffer resides on a local storage
+ * device then when this method returns it is guaranteed that all changes
+ * made to the buffer since it was created, or since this method was last
+ * invoked, will have been written to that device.
+ *
+ * <p> If the file does not reside on a local device then no such guarantee
+ * is made.
+ *
+ * <p> If this buffer was not mapped in read/write mode ({@link
+ * java.nio.channels.FileChannel.MapMode#READ_WRITE}) then invoking this
+ * method has no effect. </p>
+ *
+ * @return This buffer
+ */
+ public final MappedByteBuffer force() {
+ checkMapped();
+ if ((address != 0) && (capacity() != 0)) {
+ long offset = mappingOffset();
+ force0(fd, mappingAddress(offset), mappingLength(offset));
+ }
+ return this;
+ }
+
+ private native boolean isLoaded0(long address, long length, int pageCount);
+ private native void load0(long address, long length);
+ private native void force0(FileDescriptor fd, long address, long length);
+}
diff --git a/java/nio/NIOAccess.java b/java/nio/NIOAccess.java
new file mode 100644
index 0000000..7345379
--- /dev/null
+++ b/java/nio/NIOAccess.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.nio;
+
+import android.compat.annotation.UnsupportedAppUsage;
+
+/**
+ * This class is used via JNI by code in frameworks/base/ and
+ * by the JniConstants cache in libnativehelper/.
+ * @hide
+ */
+// @VisibleForTesting : was default
[email protected]
+public final class NIOAccess {
+
+ /**
+ * Returns the underlying native pointer to the data of the given
+ * Buffer starting at the Buffer's current position, or 0 if the
+ * Buffer is not backed by native heap storage.
+ * @hide
+ */
+ // @VisibleForTesting : was default
+ @UnsupportedAppUsage
+ public static long getBasePointer(Buffer b) {
+ long address = b.address;
+ if (address == 0L) {
+ return 0L;
+ }
+ return address + (b.position << b._elementSizeShift);
+ }
+
+ /**
+ * Returns the underlying Java array containing the data of the
+ * given Buffer, or null if the Buffer is not backed by a Java array.
+ */
+ @UnsupportedAppUsage
+ @libcore.api.CorePlatformApi
+ public static Object getBaseArray(Buffer b) {
+ return b.hasArray() ? b.array() : null;
+ }
+
+ /**
+ * Returns the offset in bytes from the start of the underlying
+ * Java array object containing the data of the given Buffer to
+ * the actual start of the data. The start of the data takes into
+ * account the Buffer's current position. This method is only
+ * meaningful if getBaseArray() returns non-null.
+ */
+ @UnsupportedAppUsage
+ @libcore.api.CorePlatformApi
+ public static int getBaseArrayOffset(Buffer b) {
+ return b.hasArray() ? ((b.arrayOffset() + b.position) << b._elementSizeShift) : 0;
+ }
+}
diff --git a/java/nio/NioUtils.java b/java/nio/NioUtils.java
new file mode 100644
index 0000000..aca91b0
--- /dev/null
+++ b/java/nio/NioUtils.java
@@ -0,0 +1,92 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.nio;
+
+import android.compat.annotation.UnsupportedAppUsage;
+
+import java.io.Closeable;
+import java.io.FileDescriptor;
+import java.nio.channels.FileChannel;
+
+import sun.nio.ch.FileChannelImpl;
+
+import static android.system.OsConstants.O_ACCMODE;
+import static android.system.OsConstants.O_APPEND;
+import static android.system.OsConstants.O_RDONLY;
+import static android.system.OsConstants.O_WRONLY;
+
+/**
+ * @hide internal use only
+ */
[email protected]
+public final class NioUtils {
+ private NioUtils() {
+ }
+
+ @UnsupportedAppUsage
+ @libcore.api.CorePlatformApi
+ public static void freeDirectBuffer(ByteBuffer buffer) {
+ if (buffer == null) {
+ return;
+ }
+
+ DirectByteBuffer dbb = (DirectByteBuffer) buffer;
+ // Run the cleaner early, if one is defined.
+ if (dbb.cleaner != null) {
+ dbb.cleaner.clean();
+ }
+
+ dbb.memoryRef.free();
+ }
+
+ /**
+ * Returns the int file descriptor from within the given FileChannel 'fc'.
+ */
+ public static FileDescriptor getFD(FileChannel fc) {
+ return ((FileChannelImpl) fc).fd;
+ }
+
+ /**
+ * Helps bridge between io and nio.
+ */
+ public static FileChannel newFileChannel(Closeable ioObject, FileDescriptor fd, int mode) {
+ boolean readable = (mode & O_ACCMODE) != O_WRONLY;
+ boolean writable = (mode & O_ACCMODE) != O_RDONLY;
+ boolean append = (mode & O_APPEND) != 0;
+ return FileChannelImpl.open(fd, null, readable, writable, append, ioObject);
+ }
+
+ /**
+ * Exposes the array backing a non-direct ByteBuffer, even if the ByteBuffer is read-only.
+ * Normally, attempting to access the array backing a read-only buffer throws.
+ */
+ @UnsupportedAppUsage
+ @libcore.api.CorePlatformApi
+ public static byte[] unsafeArray(ByteBuffer b) {
+ return b.array();
+ }
+
+ /**
+ * Exposes the array offset for the array backing a non-direct ByteBuffer,
+ * even if the ByteBuffer is read-only.
+ */
+ @UnsupportedAppUsage
+ @libcore.api.CorePlatformApi
+ public static int unsafeArrayOffset(ByteBuffer b) {
+ return b.arrayOffset();
+ }
+}
diff --git a/java/nio/ReadOnlyBufferException.java b/java/nio/ReadOnlyBufferException.java
new file mode 100644
index 0000000..5eb4b95
--- /dev/null
+++ b/java/nio/ReadOnlyBufferException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio;
+
+
+/**
+ * Unchecked exception thrown when a content-mutation method such as
+ * <tt>put</tt> or <tt>compact</tt> is invoked upon a read-only buffer.
+ *
+ * @since 1.4
+ */
+
+public class ReadOnlyBufferException
+ extends UnsupportedOperationException
+{
+
+ private static final long serialVersionUID = -1210063976496234090L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public ReadOnlyBufferException() { }
+
+}
diff --git a/java/nio/ShortBuffer.java b/java/nio/ShortBuffer.java
new file mode 100644
index 0000000..b2a479c
--- /dev/null
+++ b/java/nio/ShortBuffer.java
@@ -0,0 +1,868 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio;
+
+
+import dalvik.annotation.codegen.CovariantReturnType;
+
+/**
+ * A short buffer.
+ *
+ * <p> This class defines four categories of operations upon
+ * short buffers:
+ *
+ * <ul>
+ *
+ * <li><p> Absolute and relative {@link #get() <i>get</i>} and
+ * {@link #put(short) <i>put</i>} methods that read and write
+ * single shorts; </p></li>
+ *
+ * <li><p> Relative {@link #get(short[]) <i>bulk get</i>}
+ * methods that transfer contiguous sequences of shorts from this buffer
+ * into an array; and</p></li>
+ *
+ * <li><p> Relative {@link #put(short[]) <i>bulk put</i>}
+ * methods that transfer contiguous sequences of shorts from a
+ * short array or some other short
+ * buffer into this buffer; and </p></li>
+ *
+ *
+ * <li><p> Methods for {@link #compact compacting}, {@link
+ * #duplicate duplicating}, and {@link #slice slicing}
+ * a short buffer. </p></li>
+ *
+ * </ul>
+ *
+ * <p> Short buffers can be created either by {@link #allocate
+ * <i>allocation</i>}, which allocates space for the buffer's
+ *
+ *
+ * content, by {@link #wrap(short[]) <i>wrapping</i>} an existing
+ * short array into a buffer, or by creating a
+ * <a href="ByteBuffer.html#views"><i>view</i></a> of an existing byte buffer.
+ *
+ *
+*
+ *
+ * <p> Like a byte buffer, a short buffer is either <a
+ * href="ByteBuffer.html#direct"><i>direct</i> or <i>non-direct</i></a>. A
+ * short buffer created via the <tt>wrap</tt> methods of this class will
+ * be non-direct. A short buffer created as a view of a byte buffer will
+ * be direct if, and only if, the byte buffer itself is direct. Whether or not
+ * a short buffer is direct may be determined by invoking the {@link
+ * #isDirect isDirect} method. </p>
+ *
+*
+ *
+ *
+ * <p> Methods in this class that do not otherwise have a value to return are
+ * specified to return the buffer upon which they are invoked. This allows
+ * method invocations to be chained.
+ *
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class ShortBuffer
+ extends Buffer
+ implements Comparable<ShortBuffer>
+{
+
+ // These fields are declared here rather than in Heap-X-Buffer in order to
+ // reduce the number of virtual method invocations needed to access these
+ // values, which is especially costly when coding small buffers.
+ //
+ final short[] hb; // Non-null only for heap buffers
+ final int offset;
+ boolean isReadOnly; // Valid only for heap buffers
+
+ // Creates a new buffer with the given mark, position, limit, capacity,
+ // backing array, and array offset
+ //
+ ShortBuffer(int mark, int pos, int lim, int cap, // package-private
+ short[] hb, int offset)
+ {
+ // Android-added: elementSizeShift parameter (log2 of element size).
+ super(mark, pos, lim, cap, 1 /* elementSizeShift */);
+ this.hb = hb;
+ this.offset = offset;
+ }
+
+ // Creates a new buffer with the given mark, position, limit, and capacity
+ //
+ ShortBuffer(int mark, int pos, int lim, int cap) { // package-private
+ this(mark, pos, lim, cap, null, 0);
+ }
+
+
+ /**
+ * Allocates a new short buffer.
+ *
+ * <p> The new buffer's position will be zero, its limit will be its
+ * capacity, its mark will be undefined, and each of its elements will be
+ * initialized to zero. It will have a {@link #array backing array},
+ * and its {@link #arrayOffset array offset} will be zero.
+ *
+ * @param capacity
+ * The new buffer's capacity, in shorts
+ *
+ * @return The new short buffer
+ *
+ * @throws IllegalArgumentException
+ * If the <tt>capacity</tt> is a negative integer
+ */
+ public static ShortBuffer allocate(int capacity) {
+ if (capacity < 0)
+ throw new IllegalArgumentException();
+ return new HeapShortBuffer(capacity, capacity);
+ }
+
+ /**
+ * Wraps a short array into a buffer.
+ *
+ * <p> The new buffer will be backed by the given short array;
+ * that is, modifications to the buffer will cause the array to be modified
+ * and vice versa. The new buffer's capacity will be
+ * <tt>array.length</tt>, its position will be <tt>offset</tt>, its limit
+ * will be <tt>offset + length</tt>, and its mark will be undefined. Its
+ * {@link #array backing array} will be the given array, and
+ * its {@link #arrayOffset array offset} will be zero. </p>
+ *
+ * @param array
+ * The array that will back the new buffer
+ *
+ * @param offset
+ * The offset of the subarray to be used; must be non-negative and
+ * no larger than <tt>array.length</tt>. The new buffer's position
+ * will be set to this value.
+ *
+ * @param length
+ * The length of the subarray to be used;
+ * must be non-negative and no larger than
+ * <tt>array.length - offset</tt>.
+ * The new buffer's limit will be set to <tt>offset + length</tt>.
+ *
+ * @return The new short buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ */
+ public static ShortBuffer wrap(short[] array,
+ int offset, int length)
+ {
+ try {
+ return new HeapShortBuffer(array, offset, length);
+ } catch (IllegalArgumentException x) {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+
+ /**
+ * Wraps a short array into a buffer.
+ *
+ * <p> The new buffer will be backed by the given short array;
+ * that is, modifications to the buffer will cause the array to be modified
+ * and vice versa. The new buffer's capacity and limit will be
+ * <tt>array.length</tt>, its position will be zero, and its mark will be
+ * undefined. Its {@link #array backing array} will be the
+ * given array, and its {@link #arrayOffset array offset>} will
+ * be zero. </p>
+ *
+ * @param array
+ * The array that will back this buffer
+ *
+ * @return The new short buffer
+ */
+ public static ShortBuffer wrap(short[] array) {
+ return wrap(array, 0, array.length);
+ }
+
+
+ /**
+ * Creates a new short buffer whose content is a shared subsequence of
+ * this buffer's content.
+ *
+ * <p> The content of the new buffer will start at this buffer's current
+ * position. Changes to this buffer's content will be visible in the new
+ * buffer, and vice versa; the two buffers' position, limit, and mark
+ * values will be independent.
+ *
+ * <p> The new buffer's position will be zero, its capacity and its limit
+ * will be the number of shorts remaining in this buffer, and its mark
+ * will be undefined. The new buffer will be direct if, and only if, this
+ * buffer is direct, and it will be read-only if, and only if, this buffer
+ * is read-only. </p>
+ *
+ * @return The new short buffer
+ */
+ public abstract ShortBuffer slice();
+
+ /**
+ * Creates a new short buffer that shares this buffer's content.
+ *
+ * <p> The content of the new buffer will be that of this buffer. Changes
+ * to this buffer's content will be visible in the new buffer, and vice
+ * versa; the two buffers' position, limit, and mark values will be
+ * independent.
+ *
+ * <p> The new buffer's capacity, limit, position, and mark values will be
+ * identical to those of this buffer. The new buffer will be direct if,
+ * and only if, this buffer is direct, and it will be read-only if, and
+ * only if, this buffer is read-only. </p>
+ *
+ * @return The new short buffer
+ */
+ public abstract ShortBuffer duplicate();
+
+ /**
+ * Creates a new, read-only short buffer that shares this buffer's
+ * content.
+ *
+ * <p> The content of the new buffer will be that of this buffer. Changes
+ * to this buffer's content will be visible in the new buffer; the new
+ * buffer itself, however, will be read-only and will not allow the shared
+ * content to be modified. The two buffers' position, limit, and mark
+ * values will be independent.
+ *
+ * <p> The new buffer's capacity, limit, position, and mark values will be
+ * identical to those of this buffer.
+ *
+ * <p> If this buffer is itself read-only then this method behaves in
+ * exactly the same way as the {@link #duplicate duplicate} method. </p>
+ *
+ * @return The new, read-only short buffer
+ */
+ public abstract ShortBuffer asReadOnlyBuffer();
+
+
+ // -- Singleton get/put methods --
+
+ /**
+ * Relative <i>get</i> method. Reads the short at this buffer's
+ * current position, and then increments the position.
+ *
+ * @return The short at the buffer's current position
+ *
+ * @throws BufferUnderflowException
+ * If the buffer's current position is not smaller than its limit
+ */
+ public abstract short get();
+
+ /**
+ * Relative <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> Writes the given short into this buffer at the current
+ * position, and then increments the position. </p>
+ *
+ * @param s
+ * The short to be written
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If this buffer's current position is not smaller than its limit
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract ShortBuffer put(short s);
+
+ /**
+ * Absolute <i>get</i> method. Reads the short at the given
+ * index.
+ *
+ * @param index
+ * The index from which the short will be read
+ *
+ * @return The short at the given index
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
+ */
+ public abstract short get(int index);
+
+ /**
+ * Absolute <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> Writes the given short into this buffer at the given
+ * index. </p>
+ *
+ * @param index
+ * The index at which the short will be written
+ *
+ * @param s
+ * The short value to be written
+ *
+ * @return This buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If <tt>index</tt> is negative
+ * or not smaller than the buffer's limit
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract ShortBuffer put(int index, short s);
+
+
+ // -- Bulk get operations --
+
+ /**
+ * Relative bulk <i>get</i> method.
+ *
+ * <p> This method transfers shorts from this buffer into the given
+ * destination array. If there are fewer shorts remaining in the
+ * buffer than are required to satisfy the request, that is, if
+ * <tt>length</tt> <tt>></tt> <tt>remaining()</tt>, then no
+ * shorts are transferred and a {@link BufferUnderflowException} is
+ * thrown.
+ *
+ * <p> Otherwise, this method copies <tt>length</tt> shorts from this
+ * buffer into the given array, starting at the current position of this
+ * buffer and at the given offset in the array. The position of this
+ * buffer is then incremented by <tt>length</tt>.
+ *
+ * <p> In other words, an invocation of this method of the form
+ * <tt>src.get(dst, off, len)</tt> has exactly the same effect as
+ * the loop
+ *
+ * <pre>{@code
+ * for (int i = off; i < off + len; i++)
+ * dst[i] = src.get();
+ * }</pre>
+ *
+ * except that it first checks that there are sufficient shorts in
+ * this buffer and it is potentially much more efficient.
+ *
+ * @param dst
+ * The array into which shorts are to be written
+ *
+ * @param offset
+ * The offset within the array of the first short to be
+ * written; must be non-negative and no larger than
+ * <tt>dst.length</tt>
+ *
+ * @param length
+ * The maximum number of shorts to be written to the given
+ * array; must be non-negative and no larger than
+ * <tt>dst.length - offset</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than <tt>length</tt> shorts
+ * remaining in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ */
+ public ShortBuffer get(short[] dst, int offset, int length) {
+ checkBounds(offset, length, dst.length);
+ if (length > remaining())
+ throw new BufferUnderflowException();
+ int end = offset + length;
+ for (int i = offset; i < end; i++)
+ dst[i] = get();
+ return this;
+ }
+
+ /**
+ * Relative bulk <i>get</i> method.
+ *
+ * <p> This method transfers shorts from this buffer into the given
+ * destination array. An invocation of this method of the form
+ * <tt>src.get(a)</tt> behaves in exactly the same way as the invocation
+ *
+ * <pre>
+ * src.get(a, 0, a.length) </pre>
+ *
+ * @param dst
+ * The destination array
+ *
+ * @return This buffer
+ *
+ * @throws BufferUnderflowException
+ * If there are fewer than <tt>length</tt> shorts
+ * remaining in this buffer
+ */
+ public ShortBuffer get(short[] dst) {
+ return get(dst, 0, dst.length);
+ }
+
+
+ // -- Bulk put operations --
+
+ /**
+ * Relative bulk <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> This method transfers the shorts remaining in the given source
+ * buffer into this buffer. If there are more shorts remaining in the
+ * source buffer than in this buffer, that is, if
+ * <tt>src.remaining()</tt> <tt>></tt> <tt>remaining()</tt>,
+ * then no shorts are transferred and a {@link
+ * BufferOverflowException} is thrown.
+ *
+ * <p> Otherwise, this method copies
+ * <i>n</i> = <tt>src.remaining()</tt> shorts from the given
+ * buffer into this buffer, starting at each buffer's current position.
+ * The positions of both buffers are then incremented by <i>n</i>.
+ *
+ * <p> In other words, an invocation of this method of the form
+ * <tt>dst.put(src)</tt> has exactly the same effect as the loop
+ *
+ * <pre>
+ * while (src.hasRemaining())
+ * dst.put(src.get()); </pre>
+ *
+ * except that it first checks that there is sufficient space in this
+ * buffer and it is potentially much more efficient.
+ *
+ * @param src
+ * The source buffer from which shorts are to be read;
+ * must not be this buffer
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ * for the remaining shorts in the source buffer
+ *
+ * @throws IllegalArgumentException
+ * If the source buffer is this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public ShortBuffer put(ShortBuffer src) {
+ if (src == this)
+ throw new IllegalArgumentException();
+ if (isReadOnly())
+ throw new ReadOnlyBufferException();
+ int n = src.remaining();
+ if (n > remaining())
+ throw new BufferOverflowException();
+ for (int i = 0; i < n; i++)
+ put(src.get());
+ return this;
+ }
+
+ /**
+ * Relative bulk <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> This method transfers shorts into this buffer from the given
+ * source array. If there are more shorts to be copied from the array
+ * than remain in this buffer, that is, if
+ * <tt>length</tt> <tt>></tt> <tt>remaining()</tt>, then no
+ * shorts are transferred and a {@link BufferOverflowException} is
+ * thrown.
+ *
+ * <p> Otherwise, this method copies <tt>length</tt> shorts from the
+ * given array into this buffer, starting at the given offset in the array
+ * and at the current position of this buffer. The position of this buffer
+ * is then incremented by <tt>length</tt>.
+ *
+ * <p> In other words, an invocation of this method of the form
+ * <tt>dst.put(src, off, len)</tt> has exactly the same effect as
+ * the loop
+ *
+ * <pre>{@code
+ * for (int i = off; i < off + len; i++)
+ * dst.put(a[i]);
+ * }</pre>
+ *
+ * except that it first checks that there is sufficient space in this
+ * buffer and it is potentially much more efficient.
+ *
+ * @param src
+ * The array from which shorts are to be read
+ *
+ * @param offset
+ * The offset within the array of the first short to be read;
+ * must be non-negative and no larger than <tt>array.length</tt>
+ *
+ * @param length
+ * The number of shorts to be read from the given array;
+ * must be non-negative and no larger than
+ * <tt>array.length - offset</tt>
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public ShortBuffer put(short[] src, int offset, int length) {
+ checkBounds(offset, length, src.length);
+ if (length > remaining())
+ throw new BufferOverflowException();
+ int end = offset + length;
+ for (int i = offset; i < end; i++)
+ this.put(src[i]);
+ return this;
+ }
+
+ /**
+ * Relative bulk <i>put</i> method <i>(optional operation)</i>.
+ *
+ * <p> This method transfers the entire content of the given source
+ * short array into this buffer. An invocation of this method of the
+ * form <tt>dst.put(a)</tt> behaves in exactly the same way as the
+ * invocation
+ *
+ * <pre>
+ * dst.put(a, 0, a.length) </pre>
+ *
+ * @param src
+ * The source array
+ *
+ * @return This buffer
+ *
+ * @throws BufferOverflowException
+ * If there is insufficient space in this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public final ShortBuffer put(short[] src) {
+ return put(src, 0, src.length);
+ }
+
+
+ // -- Other stuff --
+
+ /**
+ * Tells whether or not this buffer is backed by an accessible short
+ * array.
+ *
+ * <p> If this method returns <tt>true</tt> then the {@link #array() array}
+ * and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
+ * </p>
+ *
+ * @return <tt>true</tt> if, and only if, this buffer
+ * is backed by an array and is not read-only
+ */
+ public final boolean hasArray() {
+ return (hb != null) && !isReadOnly;
+ }
+
+ /**
+ * Returns the short array that backs this
+ * buffer <i>(optional operation)</i>.
+ *
+ * <p> Modifications to this buffer's content will cause the returned
+ * array's content to be modified, and vice versa.
+ *
+ * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+ * method in order to ensure that this buffer has an accessible backing
+ * array. </p>
+ *
+ * @return The array that backs this buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
+ */
+ public final short[] array() {
+ if (hb == null)
+ throw new UnsupportedOperationException();
+ if (isReadOnly)
+ throw new ReadOnlyBufferException();
+ return hb;
+ }
+
+ /**
+ * Returns the offset within this buffer's backing array of the first
+ * element of the buffer <i>(optional operation)</i>.
+ *
+ * <p> If this buffer is backed by an array then buffer position <i>p</i>
+ * corresponds to array index <i>p</i> + <tt>arrayOffset()</tt>.
+ *
+ * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+ * method in order to ensure that this buffer has an accessible backing
+ * array. </p>
+ *
+ * @return The offset within this buffer's array
+ * of the first element of the buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is backed by an array but is read-only
+ *
+ * @throws UnsupportedOperationException
+ * If this buffer is not backed by an accessible array
+ */
+ public final int arrayOffset() {
+ if (hb == null)
+ throw new UnsupportedOperationException();
+ if (isReadOnly)
+ throw new ReadOnlyBufferException();
+ return offset;
+ }
+
+ // BEGIN Android-added: covariant overloads of *Buffer methods that return this.
+ @CovariantReturnType(returnType = ShortBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer position(int newPosition) {
+ return super.position(newPosition);
+ }
+
+ @CovariantReturnType(returnType = ShortBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer limit(int newLimit) {
+ return super.limit(newLimit);
+ }
+
+ @CovariantReturnType(returnType = ShortBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer mark() {
+ return super.mark();
+ }
+
+ @CovariantReturnType(returnType = ShortBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer reset() {
+ return super.reset();
+ }
+
+ @CovariantReturnType(returnType = ShortBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer clear() {
+ return super.clear();
+ }
+
+ @CovariantReturnType(returnType = ShortBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer flip() {
+ return super.flip();
+ }
+
+ @CovariantReturnType(returnType = ShortBuffer.class, presentAfter = 28)
+ @Override
+ public Buffer rewind() {
+ return super.rewind();
+ }
+ // END Android-added: covariant overloads of *Buffer methods that return this.
+
+ /**
+ * Compacts this buffer <i>(optional operation)</i>.
+ *
+ * <p> The shorts between the buffer's current position and its limit,
+ * if any, are copied to the beginning of the buffer. That is, the
+ * short at index <i>p</i> = <tt>position()</tt> is copied
+ * to index zero, the short at index <i>p</i> + 1 is copied
+ * to index one, and so forth until the short at index
+ * <tt>limit()</tt> - 1 is copied to index
+ * <i>n</i> = <tt>limit()</tt> - <tt>1</tt> - <i>p</i>.
+ * The buffer's position is then set to <i>n+1</i> and its limit is set to
+ * its capacity. The mark, if defined, is discarded.
+ *
+ * <p> The buffer's position is set to the number of shorts copied,
+ * rather than to zero, so that an invocation of this method can be
+ * followed immediately by an invocation of another relative <i>put</i>
+ * method. </p>
+ *
+
+ *
+ * @return This buffer
+ *
+ * @throws ReadOnlyBufferException
+ * If this buffer is read-only
+ */
+ public abstract ShortBuffer compact();
+
+ /**
+ * Tells whether or not this short buffer is direct.
+ *
+ * @return <tt>true</tt> if, and only if, this buffer is direct
+ */
+ public abstract boolean isDirect();
+
+
+ /**
+ * Returns a string summarizing the state of this buffer.
+ *
+ * @return A summary string
+ */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(getClass().getName());
+ sb.append("[pos=");
+ sb.append(position());
+ sb.append(" lim=");
+ sb.append(limit());
+ sb.append(" cap=");
+ sb.append(capacity());
+ sb.append("]");
+ return sb.toString();
+ }
+
+
+ /**
+ * Returns the current hash code of this buffer.
+ *
+ * <p> The hash code of a short buffer depends only upon its remaining
+ * elements; that is, upon the elements from <tt>position()</tt> up to, and
+ * including, the element at <tt>limit()</tt> - <tt>1</tt>.
+ *
+ * <p> Because buffer hash codes are content-dependent, it is inadvisable
+ * to use buffers as keys in hash maps or similar data structures unless it
+ * is known that their contents will not change. </p>
+ *
+ * @return The current hash code of this buffer
+ */
+ public int hashCode() {
+ int h = 1;
+ int p = position();
+ for (int i = limit() - 1; i >= p; i--)
+ h = 31 * h + (int) get(i);
+ return h;
+ }
+
+ /**
+ * Tells whether or not this buffer is equal to another object.
+ *
+ * <p> Two short buffers are equal if, and only if,
+ *
+ * <ol>
+ *
+ * <li><p> They have the same element type, </p></li>
+ *
+ * <li><p> They have the same number of remaining elements, and
+ * </p></li>
+ *
+ * <li><p> The two sequences of remaining elements, considered
+ * independently of their starting positions, are pointwise equal.
+
+ * </p></li>
+ *
+ * </ol>
+ *
+ * <p> A short buffer is not equal to any other type of object. </p>
+ *
+ * @param ob The object to which this buffer is to be compared
+ *
+ * @return <tt>true</tt> if, and only if, this buffer is equal to the
+ * given object
+ */
+ public boolean equals(Object ob) {
+ if (this == ob)
+ return true;
+ if (!(ob instanceof ShortBuffer))
+ return false;
+ ShortBuffer that = (ShortBuffer)ob;
+ if (this.remaining() != that.remaining())
+ return false;
+ int p = this.position();
+ for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--)
+ if (!equals(this.get(i), that.get(j)))
+ return false;
+ return true;
+ }
+
+ private static boolean equals(short x, short y) {
+
+
+ return x == y;
+
+ }
+
+ /**
+ * Compares this buffer to another.
+ *
+ * <p> Two short buffers are compared by comparing their sequences of
+ * remaining elements lexicographically, without regard to the starting
+ * position of each sequence within its corresponding buffer.
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * Pairs of {@code short} elements are compared as if by invoking
+ * {@link Short#compare(short,short)}.
+
+ *
+ * <p> A short buffer is not comparable to any other type of object.
+ *
+ * @return A negative integer, zero, or a positive integer as this buffer
+ * is less than, equal to, or greater than the given buffer
+ */
+ public int compareTo(ShortBuffer that) {
+ int n = this.position() + Math.min(this.remaining(), that.remaining());
+ for (int i = this.position(), j = that.position(); i < n; i++, j++) {
+ int cmp = compare(this.get(i), that.get(j));
+ if (cmp != 0)
+ return cmp;
+ }
+ return this.remaining() - that.remaining();
+ }
+
+ private static int compare(short x, short y) {
+
+
+ return Short.compare(x, y);
+
+ }
+
+ // -- Other char stuff --
+
+
+ // -- Other byte stuff: Access to binary data --
+
+
+ /**
+ * Retrieves this buffer's byte order.
+ *
+ * <p> The byte order of a short buffer created by allocation or by
+ * wrapping an existing <tt>short</tt> array is the {@link
+ * ByteOrder#nativeOrder native order} of the underlying
+ * hardware. The byte order of a short buffer created as a <a
+ * href="ByteBuffer.html#views">view</a> of a byte buffer is that of the
+ * byte buffer at the moment that the view is created. </p>
+ *
+ * @return This buffer's byte order
+ */
+ public abstract ByteOrder order();
+
+
+}
diff --git a/java/nio/StringCharBuffer.java b/java/nio/StringCharBuffer.java
new file mode 100644
index 0000000..0c20fa6
--- /dev/null
+++ b/java/nio/StringCharBuffer.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio;
+
+
+// ## If the sequence is a string, use reflection to share its array
+
+class StringCharBuffer // package-private
+ extends CharBuffer
+{
+ CharSequence str;
+
+ StringCharBuffer(CharSequence s, int start, int end) { // package-private
+ super(-1, start, end, s.length());
+ int n = s.length();
+ if ((start < 0) || (start > n) || (end < start) || (end > n))
+ throw new IndexOutOfBoundsException();
+ str = s;
+ }
+
+ public CharBuffer slice() {
+ return new StringCharBuffer(str,
+ -1,
+ 0,
+ this.remaining(),
+ this.remaining(),
+ offset + this.position());
+ }
+
+ private StringCharBuffer(CharSequence s,
+ int mark,
+ int pos,
+ int limit,
+ int cap,
+ int offset) {
+ super(mark, pos, limit, cap, null, offset);
+ str = s;
+ }
+
+ public CharBuffer duplicate() {
+ return new StringCharBuffer(str, markValue(),
+ position(), limit(), capacity(), offset);
+ }
+
+ public CharBuffer asReadOnlyBuffer() {
+ return duplicate();
+ }
+
+ public final char get() {
+ return str.charAt(nextGetIndex() + offset);
+ }
+
+ public final char get(int index) {
+ return str.charAt(checkIndex(index) + offset);
+ }
+
+ char getUnchecked(int index) {
+ return str.charAt(index + offset);
+ }
+
+ // ## Override bulk get methods for better performance
+
+ public final CharBuffer put(char c) {
+ throw new ReadOnlyBufferException();
+ }
+
+ public final CharBuffer put(int index, char c) {
+ throw new ReadOnlyBufferException();
+ }
+
+ public final CharBuffer compact() {
+ throw new ReadOnlyBufferException();
+ }
+
+ public final boolean isReadOnly() {
+ return true;
+ }
+
+ final String toString(int start, int end) {
+ return str.toString().substring(start + offset, end + offset);
+ }
+
+ public final CharBuffer subSequence(int start, int end) {
+ try {
+ int pos = position();
+ return new StringCharBuffer(str,
+ -1,
+ pos + checkIndex(start, pos),
+ pos + checkIndex(end, pos),
+ capacity(),
+ offset);
+ } catch (IllegalArgumentException x) {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+
+ public boolean isDirect() {
+ return false;
+ }
+
+ public ByteOrder order() {
+ return ByteOrder.nativeOrder();
+ }
+
+}
diff --git a/java/nio/channels/AcceptPendingException.java b/java/nio/channels/AcceptPendingException.java
new file mode 100644
index 0000000..dc357f0
--- /dev/null
+++ b/java/nio/channels/AcceptPendingException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to initiate an accept
+ * operation on a channel and a previous accept operation has not completed.
+ *
+ * @since 1.7
+ */
+
+public class AcceptPendingException
+ extends IllegalStateException
+{
+
+ private static final long serialVersionUID = 2721339977965416421L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public AcceptPendingException() { }
+
+}
diff --git a/java/nio/channels/AlreadyBoundException.java b/java/nio/channels/AlreadyBoundException.java
new file mode 100644
index 0000000..38d1033
--- /dev/null
+++ b/java/nio/channels/AlreadyBoundException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to bind the socket a
+ * network oriented channel that is already bound.
+ *
+ * @since 1.7
+ */
+
+public class AlreadyBoundException
+ extends IllegalStateException
+{
+
+ private static final long serialVersionUID = 6796072983322737592L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public AlreadyBoundException() { }
+
+}
diff --git a/java/nio/channels/AlreadyConnectedException.java b/java/nio/channels/AlreadyConnectedException.java
new file mode 100644
index 0000000..931efff
--- /dev/null
+++ b/java/nio/channels/AlreadyConnectedException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to connect a {@link
+ * SocketChannel} that is already connected.
+ *
+ * @since 1.4
+ */
+
+public class AlreadyConnectedException
+ extends IllegalStateException
+{
+
+ private static final long serialVersionUID = -7331895245053773357L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public AlreadyConnectedException() { }
+
+}
diff --git a/java/nio/channels/AsynchronousByteChannel.java b/java/nio/channels/AsynchronousByteChannel.java
new file mode 100644
index 0000000..b96a239
--- /dev/null
+++ b/java/nio/channels/AsynchronousByteChannel.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+import java.nio.ByteBuffer;
+import java.util.concurrent.Future;
+
+/**
+ * An asynchronous channel that can read and write bytes.
+ *
+ * <p> Some channels may not allow more than one read or write to be outstanding
+ * at any given time. If a thread invokes a read method before a previous read
+ * operation has completed then a {@link ReadPendingException} will be thrown.
+ * Similarly, if a write method is invoked before a previous write has completed
+ * then {@link WritePendingException} is thrown. Whether or not other kinds of
+ * I/O operations may proceed concurrently with a read operation depends upon
+ * the type of the channel.
+ *
+ * <p> Note that {@link java.nio.ByteBuffer ByteBuffers} are not safe for use by
+ * multiple concurrent threads. When a read or write operation is initiated then
+ * care must be taken to ensure that the buffer is not accessed until the
+ * operation completes.
+ *
+ * @see Channels#newInputStream(AsynchronousByteChannel)
+ * @see Channels#newOutputStream(AsynchronousByteChannel)
+ *
+ * @since 1.7
+ */
+
+public interface AsynchronousByteChannel
+ extends AsynchronousChannel
+{
+ /**
+ * Reads a sequence of bytes from this channel into the given buffer.
+ *
+ * <p> This method initiates an asynchronous read operation to read a
+ * sequence of bytes from this channel into the given buffer. The {@code
+ * handler} parameter is a completion handler that is invoked when the read
+ * operation completes (or fails). The result passed to the completion
+ * handler is the number of bytes read or {@code -1} if no bytes could be
+ * read because the channel has reached end-of-stream.
+ *
+ * <p> The read operation may read up to <i>r</i> bytes from the channel,
+ * where <i>r</i> is the number of bytes remaining in the buffer, that is,
+ * {@code dst.remaining()} at the time that the read is attempted. Where
+ * <i>r</i> is 0, the read operation completes immediately with a result of
+ * {@code 0} without initiating an I/O operation.
+ *
+ * <p> Suppose that a byte sequence of length <i>n</i> is read, where
+ * <tt>0</tt> <tt><</tt> <i>n</i> <tt><=</tt> <i>r</i>.
+ * This byte sequence will be transferred into the buffer so that the first
+ * byte in the sequence is at index <i>p</i> and the last byte is at index
+ * <i>p</i> <tt>+</tt> <i>n</i> <tt>-</tt> <tt>1</tt>,
+ * where <i>p</i> is the buffer's position at the moment the read is
+ * performed. Upon completion the buffer's position will be equal to
+ * <i>p</i> <tt>+</tt> <i>n</i>; its limit will not have changed.
+ *
+ * <p> Buffers are not safe for use by multiple concurrent threads so care
+ * should be taken to not access the buffer until the operation has
+ * completed.
+ *
+ * <p> This method may be invoked at any time. Some channel types may not
+ * allow more than one read to be outstanding at any given time. If a thread
+ * initiates a read operation before a previous read operation has
+ * completed then a {@link ReadPendingException} will be thrown.
+ *
+ * @param <A>
+ * The type of the attachment
+ * @param dst
+ * The buffer into which bytes are to be transferred
+ * @param attachment
+ * The object to attach to the I/O operation; can be {@code null}
+ * @param handler
+ * The completion handler
+ *
+ * @throws IllegalArgumentException
+ * If the buffer is read-only
+ * @throws ReadPendingException
+ * If the channel does not allow more than one read to be outstanding
+ * and a previous read has not completed
+ * @throws ShutdownChannelGroupException
+ * If the channel is associated with a {@link AsynchronousChannelGroup
+ * group} that has terminated
+ */
+ <A> void read(ByteBuffer dst,
+ A attachment,
+ CompletionHandler<Integer,? super A> handler);
+
+ /**
+ * Reads a sequence of bytes from this channel into the given buffer.
+ *
+ * <p> This method initiates an asynchronous read operation to read a
+ * sequence of bytes from this channel into the given buffer. The method
+ * behaves in exactly the same manner as the {@link
+ * #read(ByteBuffer,Object,CompletionHandler)
+ * read(ByteBuffer,Object,CompletionHandler)} method except that instead
+ * of specifying a completion handler, this method returns a {@code Future}
+ * representing the pending result. The {@code Future}'s {@link Future#get()
+ * get} method returns the number of bytes read or {@code -1} if no bytes
+ * could be read because the channel has reached end-of-stream.
+ *
+ * @param dst
+ * The buffer into which bytes are to be transferred
+ *
+ * @return A Future representing the result of the operation
+ *
+ * @throws IllegalArgumentException
+ * If the buffer is read-only
+ * @throws ReadPendingException
+ * If the channel does not allow more than one read to be outstanding
+ * and a previous read has not completed
+ */
+ Future<Integer> read(ByteBuffer dst);
+
+ /**
+ * Writes a sequence of bytes to this channel from the given buffer.
+ *
+ * <p> This method initiates an asynchronous write operation to write a
+ * sequence of bytes to this channel from the given buffer. The {@code
+ * handler} parameter is a completion handler that is invoked when the write
+ * operation completes (or fails). The result passed to the completion
+ * handler is the number of bytes written.
+ *
+ * <p> The write operation may write up to <i>r</i> bytes to the channel,
+ * where <i>r</i> is the number of bytes remaining in the buffer, that is,
+ * {@code src.remaining()} at the time that the write is attempted. Where
+ * <i>r</i> is 0, the write operation completes immediately with a result of
+ * {@code 0} without initiating an I/O operation.
+ *
+ * <p> Suppose that a byte sequence of length <i>n</i> is written, where
+ * <tt>0</tt> <tt><</tt> <i>n</i> <tt><=</tt> <i>r</i>.
+ * This byte sequence will be transferred from the buffer starting at index
+ * <i>p</i>, where <i>p</i> is the buffer's position at the moment the
+ * write is performed; the index of the last byte written will be
+ * <i>p</i> <tt>+</tt> <i>n</i> <tt>-</tt> <tt>1</tt>.
+ * Upon completion the buffer's position will be equal to
+ * <i>p</i> <tt>+</tt> <i>n</i>; its limit will not have changed.
+ *
+ * <p> Buffers are not safe for use by multiple concurrent threads so care
+ * should be taken to not access the buffer until the operation has
+ * completed.
+ *
+ * <p> This method may be invoked at any time. Some channel types may not
+ * allow more than one write to be outstanding at any given time. If a thread
+ * initiates a write operation before a previous write operation has
+ * completed then a {@link WritePendingException} will be thrown.
+ *
+ * @param <A>
+ * The type of the attachment
+ * @param src
+ * The buffer from which bytes are to be retrieved
+ * @param attachment
+ * The object to attach to the I/O operation; can be {@code null}
+ * @param handler
+ * The completion handler object
+ *
+ * @throws WritePendingException
+ * If the channel does not allow more than one write to be outstanding
+ * and a previous write has not completed
+ * @throws ShutdownChannelGroupException
+ * If the channel is associated with a {@link AsynchronousChannelGroup
+ * group} that has terminated
+ */
+ <A> void write(ByteBuffer src,
+ A attachment,
+ CompletionHandler<Integer,? super A> handler);
+
+ /**
+ * Writes a sequence of bytes to this channel from the given buffer.
+ *
+ * <p> This method initiates an asynchronous write operation to write a
+ * sequence of bytes to this channel from the given buffer. The method
+ * behaves in exactly the same manner as the {@link
+ * #write(ByteBuffer,Object,CompletionHandler)
+ * write(ByteBuffer,Object,CompletionHandler)} method except that instead
+ * of specifying a completion handler, this method returns a {@code Future}
+ * representing the pending result. The {@code Future}'s {@link Future#get()
+ * get} method returns the number of bytes written.
+ *
+ * @param src
+ * The buffer from which bytes are to be retrieved
+ *
+ * @return A Future representing the result of the operation
+ *
+ * @throws WritePendingException
+ * If the channel does not allow more than one write to be outstanding
+ * and a previous write has not completed
+ */
+ Future<Integer> write(ByteBuffer src);
+}
diff --git a/java/nio/channels/AsynchronousChannel.java b/java/nio/channels/AsynchronousChannel.java
new file mode 100644
index 0000000..4668d09
--- /dev/null
+++ b/java/nio/channels/AsynchronousChannel.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+import java.io.IOException;
+import java.util.concurrent.Future; // javadoc
+
+/**
+ * A channel that supports asynchronous I/O operations. Asynchronous I/O
+ * operations will usually take one of two forms:
+ *
+ * <ol>
+ * <li><pre>{@link Future}<V> <em>operation</em>(<em>...</em>)</pre></li>
+ * <li><pre>void <em>operation</em>(<em>...</em> A attachment, {@link
+ * CompletionHandler}<V,? super A> handler)</pre></li>
+ * </ol>
+ *
+ * where <i>operation</i> is the name of the I/O operation (read or write for
+ * example), <i>V</i> is the result type of the I/O operation, and <i>A</i> is
+ * the type of an object attached to the I/O operation to provide context when
+ * consuming the result. The attachment is important for cases where a
+ * <em>state-less</em> {@code CompletionHandler} is used to consume the result
+ * of many I/O operations.
+ *
+ * <p> In the first form, the methods defined by the {@link Future Future}
+ * interface may be used to check if the operation has completed, wait for its
+ * completion, and to retrieve the result. In the second form, a {@link
+ * CompletionHandler} is invoked to consume the result of the I/O operation when
+ * it completes or fails.
+ *
+ * <p> A channel that implements this interface is <em>asynchronously
+ * closeable</em>: If an I/O operation is outstanding on the channel and the
+ * channel's {@link #close close} method is invoked, then the I/O operation
+ * fails with the exception {@link AsynchronousCloseException}.
+ *
+ * <p> Asynchronous channels are safe for use by multiple concurrent threads.
+ * Some channel implementations may support concurrent reading and writing, but
+ * may not allow more than one read and one write operation to be outstanding at
+ * any given time.
+ *
+ * <h2>Cancellation</h2>
+ *
+ * <p> The {@code Future} interface defines the {@link Future#cancel cancel}
+ * method to cancel execution. This causes all threads waiting on the result of
+ * the I/O operation to throw {@link java.util.concurrent.CancellationException}.
+ * Whether the underlying I/O operation can be cancelled is highly implementation
+ * specific and therefore not specified. Where cancellation leaves the channel,
+ * or the entity to which it is connected, in an inconsistent state, then the
+ * channel is put into an implementation specific <em>error state</em> that
+ * prevents further attempts to initiate I/O operations that are <i>similar</i>
+ * to the operation that was cancelled. For example, if a read operation is
+ * cancelled but the implementation cannot guarantee that bytes have not been
+ * read from the channel then it puts the channel into an error state; further
+ * attempts to initiate a {@code read} operation cause an unspecified runtime
+ * exception to be thrown. Similarly, if a write operation is cancelled but the
+ * implementation cannot guarantee that bytes have not been written to the
+ * channel then subsequent attempts to initiate a {@code write} will fail with
+ * an unspecified runtime exception.
+ *
+ * <p> Where the {@link Future#cancel cancel} method is invoked with the {@code
+ * mayInterruptIfRunning} parameter set to {@code true} then the I/O operation
+ * may be interrupted by closing the channel. In that case all threads waiting
+ * on the result of the I/O operation throw {@code CancellationException} and
+ * any other I/O operations outstanding on the channel complete with the
+ * exception {@link AsynchronousCloseException}.
+ *
+ * <p> Where the {@code cancel} method is invoked to cancel read or write
+ * operations then it is recommended that all buffers used in the I/O operations
+ * be discarded or care taken to ensure that the buffers are not accessed while
+ * the channel remains open.
+ *
+ * @since 1.7
+ */
+
+public interface AsynchronousChannel
+ extends Channel
+{
+ /**
+ * Closes this channel.
+ *
+ * <p> Any outstanding asynchronous operations upon this channel will
+ * complete with the exception {@link AsynchronousCloseException}. After a
+ * channel is closed, further attempts to initiate asynchronous I/O
+ * operations complete immediately with cause {@link ClosedChannelException}.
+ *
+ * <p> This method otherwise behaves exactly as specified by the {@link
+ * Channel} interface.
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ @Override
+ void close() throws IOException;
+}
diff --git a/java/nio/channels/AsynchronousChannelGroup.java b/java/nio/channels/AsynchronousChannelGroup.java
new file mode 100644
index 0000000..92b7e66
--- /dev/null
+++ b/java/nio/channels/AsynchronousChannelGroup.java
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+import java.nio.channels.spi.AsynchronousChannelProvider;
+import java.io.IOException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A grouping of asynchronous channels for the purpose of resource sharing.
+ *
+ * <p> An asynchronous channel group encapsulates the mechanics required to
+ * handle the completion of I/O operations initiated by {@link AsynchronousChannel
+ * asynchronous channels} that are bound to the group. A group has an associated
+ * thread pool to which tasks are submitted to handle I/O events and dispatch to
+ * {@link CompletionHandler completion-handlers} that consume the result of
+ * asynchronous operations performed on channels in the group. In addition to
+ * handling I/O events, the pooled threads may also execute other tasks required
+ * to support the execution of asynchronous I/O operations.
+ *
+ * <p> An asynchronous channel group is created by invoking the {@link
+ * #withFixedThreadPool withFixedThreadPool} or {@link #withCachedThreadPool
+ * withCachedThreadPool} methods defined here. Channels are bound to a group by
+ * specifying the group when constructing the channel. The associated thread
+ * pool is <em>owned</em> by the group; termination of the group results in the
+ * shutdown of the associated thread pool.
+ *
+ * <p> In addition to groups created explicitly, the Java virtual machine
+ * maintains a system-wide <em>default group</em> that is constructed
+ * automatically. Asynchronous channels that do not specify a group at
+ * construction time are bound to the default group. The default group has an
+ * associated thread pool that creates new threads as needed. The default group
+ * may be configured by means of system properties defined in the table below.
+ * Where the {@link java.util.concurrent.ThreadFactory ThreadFactory} for the
+ * default group is not configured then the pooled threads of the default group
+ * are {@link Thread#isDaemon daemon} threads.
+ *
+ * <table border summary="System properties">
+ * <tr>
+ * <th>System property</th>
+ * <th>Description</th>
+ * </tr>
+ * <tr>
+ * <td> {@code java.nio.channels.DefaultThreadPool.threadFactory} </td>
+ * <td> The value of this property is taken to be the fully-qualified name
+ * of a concrete {@link java.util.concurrent.ThreadFactory ThreadFactory}
+ * class. The class is loaded using the system class loader and instantiated.
+ * The factory's {@link java.util.concurrent.ThreadFactory#newThread
+ * newThread} method is invoked to create each thread for the default
+ * group's thread pool. If the process to load and instantiate the value
+ * of the property fails then an unspecified error is thrown during the
+ * construction of the default group. </td>
+ * </tr>
+ * <tr>
+ * <td> {@code java.nio.channels.DefaultThreadPool.initialSize} </td>
+ * <td> The value of the {@code initialSize} parameter for the default
+ * group (see {@link #withCachedThreadPool withCachedThreadPool}).
+ * The value of the property is taken to be the {@code String}
+ * representation of an {@code Integer} that is the initial size parameter.
+ * If the value cannot be parsed as an {@code Integer} it causes an
+ * unspecified error to be thrown during the construction of the default
+ * group. </td>
+ * </tr>
+ * </table>
+ *
+ * <a name="threading"></a><h2>Threading</h2>
+ *
+ * <p> The completion handler for an I/O operation initiated on a channel bound
+ * to a group is guaranteed to be invoked by one of the pooled threads in the
+ * group. This ensures that the completion handler is run by a thread with the
+ * expected <em>identity</em>.
+ *
+ * <p> Where an I/O operation completes immediately, and the initiating thread
+ * is one of the pooled threads in the group then the completion handler may
+ * be invoked directly by the initiating thread. To avoid stack overflow, an
+ * implementation may impose a limit as to the number of activations on the
+ * thread stack. Some I/O operations may prohibit invoking the completion
+ * handler directly by the initiating thread (see {@link
+ * AsynchronousServerSocketChannel#accept(Object,CompletionHandler) accept}).
+ *
+ * <a name="shutdown"></a><h2>Shutdown and Termination</h2>
+ *
+ * <p> The {@link #shutdown() shutdown} method is used to initiate an <em>orderly
+ * shutdown</em> of a group. An orderly shutdown marks the group as shutdown;
+ * further attempts to construct a channel that binds to the group will throw
+ * {@link ShutdownChannelGroupException}. Whether or not a group is shutdown can
+ * be tested using the {@link #isShutdown() isShutdown} method. Once shutdown,
+ * the group <em>terminates</em> when all asynchronous channels that are bound to
+ * the group are closed, all actively executing completion handlers have run to
+ * completion, and resources used by the group are released. No attempt is made
+ * to stop or interrupt threads that are executing completion handlers. The
+ * {@link #isTerminated() isTerminated} method is used to test if the group has
+ * terminated, and the {@link #awaitTermination awaitTermination} method can be
+ * used to block until the group has terminated.
+ *
+ * <p> The {@link #shutdownNow() shutdownNow} method can be used to initiate a
+ * <em>forceful shutdown</em> of the group. In addition to the actions performed
+ * by an orderly shutdown, the {@code shutdownNow} method closes all open channels
+ * in the group as if by invoking the {@link AsynchronousChannel#close close}
+ * method.
+ *
+ * @since 1.7
+ *
+ * @see AsynchronousSocketChannel#open(AsynchronousChannelGroup)
+ * @see AsynchronousServerSocketChannel#open(AsynchronousChannelGroup)
+ */
+
+public abstract class AsynchronousChannelGroup {
+ private final AsynchronousChannelProvider provider;
+
+ /**
+ * Initialize a new instance of this class.
+ *
+ * @param provider
+ * The asynchronous channel provider for this group
+ */
+ protected AsynchronousChannelGroup(AsynchronousChannelProvider provider) {
+ this.provider = provider;
+ }
+
+ /**
+ * Returns the provider that created this channel group.
+ *
+ * @return The provider that created this channel group
+ */
+ public final AsynchronousChannelProvider provider() {
+ return provider;
+ }
+
+ /**
+ * Creates an asynchronous channel group with a fixed thread pool.
+ *
+ * <p> The resulting asynchronous channel group reuses a fixed number of
+ * threads. At any point, at most {@code nThreads} threads will be active
+ * processing tasks that are submitted to handle I/O events and dispatch
+ * completion results for operations initiated on asynchronous channels in
+ * the group.
+ *
+ * <p> The group is created by invoking the {@link
+ * AsynchronousChannelProvider#openAsynchronousChannelGroup(int,ThreadFactory)
+ * openAsynchronousChannelGroup(int,ThreadFactory)} method of the system-wide
+ * default {@link AsynchronousChannelProvider} object.
+ *
+ * @param nThreads
+ * The number of threads in the pool
+ * @param threadFactory
+ * The factory to use when creating new threads
+ *
+ * @return A new asynchronous channel group
+ *
+ * @throws IllegalArgumentException
+ * If {@code nThreads <= 0}
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ public static AsynchronousChannelGroup withFixedThreadPool(int nThreads,
+ ThreadFactory threadFactory)
+ throws IOException
+ {
+ return AsynchronousChannelProvider.provider()
+ .openAsynchronousChannelGroup(nThreads, threadFactory);
+ }
+
+ /**
+ * Creates an asynchronous channel group with a given thread pool that
+ * creates new threads as needed.
+ *
+ * <p> The {@code executor} parameter is an {@code ExecutorService} that
+ * creates new threads as needed to execute tasks that are submitted to
+ * handle I/O events and dispatch completion results for operations initiated
+ * on asynchronous channels in the group. It may reuse previously constructed
+ * threads when they are available.
+ *
+ * <p> The {@code initialSize} parameter may be used by the implementation
+ * as a <em>hint</em> as to the initial number of tasks it may submit. For
+ * example, it may be used to indicate the initial number of threads that
+ * wait on I/O events.
+ *
+ * <p> The executor is intended to be used exclusively by the resulting
+ * asynchronous channel group. Termination of the group results in the
+ * orderly {@link ExecutorService#shutdown shutdown} of the executor
+ * service. Shutting down the executor service by other means results in
+ * unspecified behavior.
+ *
+ * <p> The group is created by invoking the {@link
+ * AsynchronousChannelProvider#openAsynchronousChannelGroup(ExecutorService,int)
+ * openAsynchronousChannelGroup(ExecutorService,int)} method of the system-wide
+ * default {@link AsynchronousChannelProvider} object.
+ *
+ * @param executor
+ * The thread pool for the resulting group
+ * @param initialSize
+ * A value {@code >=0} or a negative value for implementation
+ * specific default
+ *
+ * @return A new asynchronous channel group
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ *
+ * @see java.util.concurrent.Executors#newCachedThreadPool
+ */
+ public static AsynchronousChannelGroup withCachedThreadPool(ExecutorService executor,
+ int initialSize)
+ throws IOException
+ {
+ return AsynchronousChannelProvider.provider()
+ .openAsynchronousChannelGroup(executor, initialSize);
+ }
+
+ /**
+ * Creates an asynchronous channel group with a given thread pool.
+ *
+ * <p> The {@code executor} parameter is an {@code ExecutorService} that
+ * executes tasks submitted to dispatch completion results for operations
+ * initiated on asynchronous channels in the group.
+ *
+ * <p> Care should be taken when configuring the executor service. It
+ * should support <em>direct handoff</em> or <em>unbounded queuing</em> of
+ * submitted tasks, and the thread that invokes the {@link
+ * ExecutorService#execute execute} method should never invoke the task
+ * directly. An implementation may mandate additional constraints.
+ *
+ * <p> The executor is intended to be used exclusively by the resulting
+ * asynchronous channel group. Termination of the group results in the
+ * orderly {@link ExecutorService#shutdown shutdown} of the executor
+ * service. Shutting down the executor service by other means results in
+ * unspecified behavior.
+ *
+ * <p> The group is created by invoking the {@link
+ * AsynchronousChannelProvider#openAsynchronousChannelGroup(ExecutorService,int)
+ * openAsynchronousChannelGroup(ExecutorService,int)} method of the system-wide
+ * default {@link AsynchronousChannelProvider} object with an {@code
+ * initialSize} of {@code 0}.
+ *
+ * @param executor
+ * The thread pool for the resulting group
+ *
+ * @return A new asynchronous channel group
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ public static AsynchronousChannelGroup withThreadPool(ExecutorService executor)
+ throws IOException
+ {
+ return AsynchronousChannelProvider.provider()
+ .openAsynchronousChannelGroup(executor, 0);
+ }
+
+ /**
+ * Tells whether or not this asynchronous channel group is shutdown.
+ *
+ * @return {@code true} if this asynchronous channel group is shutdown or
+ * has been marked for shutdown.
+ */
+ public abstract boolean isShutdown();
+
+ /**
+ * Tells whether or not this group has terminated.
+ *
+ * <p> Where this method returns {@code true}, then the associated thread
+ * pool has also {@link ExecutorService#isTerminated terminated}.
+ *
+ * @return {@code true} if this group has terminated
+ */
+ public abstract boolean isTerminated();
+
+ /**
+ * Initiates an orderly shutdown of the group.
+ *
+ * <p> This method marks the group as shutdown. Further attempts to construct
+ * channel that binds to this group will throw {@link ShutdownChannelGroupException}.
+ * The group terminates when all asynchronous channels in the group are
+ * closed, all actively executing completion handlers have run to completion,
+ * and all resources have been released. This method has no effect if the
+ * group is already shutdown.
+ */
+ public abstract void shutdown();
+
+ /**
+ * Shuts down the group and closes all open channels in the group.
+ *
+ * <p> In addition to the actions performed by the {@link #shutdown() shutdown}
+ * method, this method invokes the {@link AsynchronousChannel#close close}
+ * method on all open channels in the group. This method does not attempt to
+ * stop or interrupt threads that are executing completion handlers. The
+ * group terminates when all actively executing completion handlers have run
+ * to completion and all resources have been released. This method may be
+ * invoked at any time. If some other thread has already invoked it, then
+ * another invocation will block until the first invocation is complete,
+ * after which it will return without effect.
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ public abstract void shutdownNow() throws IOException;
+
+ /**
+ * Awaits termination of the group.
+
+ * <p> This method blocks until the group has terminated, or the timeout
+ * occurs, or the current thread is interrupted, whichever happens first.
+ *
+ * @param timeout
+ * The maximum time to wait, or zero or less to not wait
+ * @param unit
+ * The time unit of the timeout argument
+ *
+ * @return {@code true} if the group has terminated; {@code false} if the
+ * timeout elapsed before termination
+ *
+ * @throws InterruptedException
+ * If interrupted while waiting
+ */
+ public abstract boolean awaitTermination(long timeout, TimeUnit unit)
+ throws InterruptedException;
+}
diff --git a/java/nio/channels/AsynchronousCloseException.java b/java/nio/channels/AsynchronousCloseException.java
new file mode 100644
index 0000000..6fb5e57
--- /dev/null
+++ b/java/nio/channels/AsynchronousCloseException.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Checked exception received by a thread when another thread closes the
+ * channel or the part of the channel upon which it is blocked in an I/O
+ * operation.
+ *
+ * @since 1.4
+ */
+
+public class AsynchronousCloseException
+ extends ClosedChannelException
+{
+
+ private static final long serialVersionUID = 6891178312432313966L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public AsynchronousCloseException() { }
+
+}
diff --git a/java/nio/channels/AsynchronousFileChannel.java b/java/nio/channels/AsynchronousFileChannel.java
new file mode 100644
index 0000000..b985d77
--- /dev/null
+++ b/java/nio/channels/AsynchronousFileChannel.java
@@ -0,0 +1,779 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+import java.nio.file.*;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.file.spi.*;
+import java.nio.ByteBuffer;
+import java.io.IOException;
+import java.util.concurrent.Future;
+import java.util.concurrent.ExecutorService;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
+
+/**
+ * An asynchronous channel for reading, writing, and manipulating a file.
+ *
+ * <p> An asynchronous file channel is created when a file is opened by invoking
+ * one of the {@link #open open} methods defined by this class. The file contains
+ * a variable-length sequence of bytes that can be read and written and whose
+ * current size can be {@link #size() queried}. The size of the file increases
+ * when bytes are written beyond its current size; the size of the file decreases
+ * when it is {@link #truncate truncated}.
+ *
+ * <p> An asynchronous file channel does not have a <i>current position</i>
+ * within the file. Instead, the file position is specified to each read and
+ * write method that initiates asynchronous operations. A {@link CompletionHandler}
+ * is specified as a parameter and is invoked to consume the result of the I/O
+ * operation. This class also defines read and write methods that initiate
+ * asynchronous operations, returning a {@link Future} to represent the pending
+ * result of the operation. The {@code Future} may be used to check if the
+ * operation has completed, wait for its completion, and retrieve the result.
+ *
+ * <p> In addition to read and write operations, this class defines the
+ * following operations: </p>
+ *
+ * <ul>
+ *
+ * <li><p> Updates made to a file may be {@link #force <i>forced
+ * out</i>} to the underlying storage device, ensuring that data are not
+ * lost in the event of a system crash. </p></li>
+ *
+ * <li><p> A region of a file may be {@link #lock <i>locked</i>} against
+ * access by other programs. </p></li>
+ *
+ * </ul>
+ *
+ * <p> An {@code AsynchronousFileChannel} is associated with a thread pool to
+ * which tasks are submitted to handle I/O events and dispatch to completion
+ * handlers that consume the results of I/O operations on the channel. The
+ * completion handler for an I/O operation initiated on a channel is guaranteed
+ * to be invoked by one of the threads in the thread pool (This ensures that the
+ * completion handler is run by a thread with the expected <em>identity</em>).
+ * Where an I/O operation completes immediately, and the initiating thread is
+ * itself a thread in the thread pool, then the completion handler may be invoked
+ * directly by the initiating thread. When an {@code AsynchronousFileChannel} is
+ * created without specifying a thread pool then the channel is associated with
+ * a system-dependent default thread pool that may be shared with other
+ * channels. The default thread pool is configured by the system properties
+ * defined by the {@link AsynchronousChannelGroup} class.
+ *
+ * <p> Channels of this type are safe for use by multiple concurrent threads. The
+ * {@link Channel#close close} method may be invoked at any time, as specified
+ * by the {@link Channel} interface. This causes all outstanding asynchronous
+ * operations on the channel to complete with the exception {@link
+ * AsynchronousCloseException}. Multiple read and write operations may be
+ * outstanding at the same time. When multiple read and write operations are
+ * outstanding then the ordering of the I/O operations, and the order that the
+ * completion handlers are invoked, is not specified; they are not, in particular,
+ * guaranteed to execute in the order that the operations were initiated. The
+ * {@link java.nio.ByteBuffer ByteBuffers} used when reading or writing are not
+ * safe for use by multiple concurrent I/O operations. Furthermore, after an I/O
+ * operation is initiated then care should be taken to ensure that the buffer is
+ * not accessed until after the operation has completed.
+ *
+ * <p> As with {@link FileChannel}, the view of a file provided by an instance of
+ * this class is guaranteed to be consistent with other views of the same file
+ * provided by other instances in the same program. The view provided by an
+ * instance of this class may or may not, however, be consistent with the views
+ * seen by other concurrently-running programs due to caching performed by the
+ * underlying operating system and delays induced by network-filesystem protocols.
+ * This is true regardless of the language in which these other programs are
+ * written, and whether they are running on the same machine or on some other
+ * machine. The exact nature of any such inconsistencies are system-dependent
+ * and are therefore unspecified.
+ *
+ * @since 1.7
+ */
+
+public abstract class AsynchronousFileChannel
+ implements AsynchronousChannel
+{
+ /**
+ * Initializes a new instance of this class.
+ */
+ protected AsynchronousFileChannel() {
+ }
+
+ /**
+ * Opens or creates a file for reading and/or writing, returning an
+ * asynchronous file channel to access the file.
+ *
+ * <p> The {@code options} parameter determines how the file is opened.
+ * The {@link StandardOpenOption#READ READ} and {@link StandardOpenOption#WRITE
+ * WRITE} options determines if the file should be opened for reading and/or
+ * writing. If neither option is contained in the array then an existing file
+ * is opened for reading.
+ *
+ * <p> In addition to {@code READ} and {@code WRITE}, the following options
+ * may be present:
+ *
+ * <table border=1 cellpadding=5 summary="">
+ * <tr> <th>Option</th> <th>Description</th> </tr>
+ * <tr>
+ * <td> {@link StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING} </td>
+ * <td> When opening an existing file, the file is first truncated to a
+ * size of 0 bytes. This option is ignored when the file is opened only
+ * for reading.</td>
+ * </tr>
+ * <tr>
+ * <td> {@link StandardOpenOption#CREATE_NEW CREATE_NEW} </td>
+ * <td> If this option is present then a new file is created, failing if
+ * the file already exists. When creating a file the check for the
+ * existence of the file and the creation of the file if it does not exist
+ * is atomic with respect to other file system operations. This option is
+ * ignored when the file is opened only for reading. </td>
+ * </tr>
+ * <tr>
+ * <td > {@link StandardOpenOption#CREATE CREATE} </td>
+ * <td> If this option is present then an existing file is opened if it
+ * exists, otherwise a new file is created. When creating a file the check
+ * for the existence of the file and the creation of the file if it does
+ * not exist is atomic with respect to other file system operations. This
+ * option is ignored if the {@code CREATE_NEW} option is also present or
+ * the file is opened only for reading. </td>
+ * </tr>
+ * <tr>
+ * <td > {@link StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} </td>
+ * <td> When this option is present then the implementation makes a
+ * <em>best effort</em> attempt to delete the file when closed by the
+ * the {@link #close close} method. If the {@code close} method is not
+ * invoked then a <em>best effort</em> attempt is made to delete the file
+ * when the Java virtual machine terminates. </td>
+ * </tr>
+ * <tr>
+ * <td>{@link StandardOpenOption#SPARSE SPARSE} </td>
+ * <td> When creating a new file this option is a <em>hint</em> that the
+ * new file will be sparse. This option is ignored when not creating
+ * a new file. </td>
+ * </tr>
+ * <tr>
+ * <td> {@link StandardOpenOption#SYNC SYNC} </td>
+ * <td> Requires that every update to the file's content or metadata be
+ * written synchronously to the underlying storage device. (see <a
+ * href="../file/package-summary.html#integrity"> Synchronized I/O file
+ * integrity</a>). </td>
+ * </tr>
+ * <tr>
+ * <td> {@link StandardOpenOption#DSYNC DSYNC} </td>
+ * <td> Requires that every update to the file's content be written
+ * synchronously to the underlying storage device. (see <a
+ * href="../file/package-summary.html#integrity"> Synchronized I/O file
+ * integrity</a>). </td>
+ * </tr>
+ * </table>
+ *
+ * <p> An implementation may also support additional options.
+ *
+ * <p> The {@code executor} parameter is the {@link ExecutorService} to
+ * which tasks are submitted to handle I/O events and dispatch completion
+ * results for operations initiated on resulting channel.
+ * The nature of these tasks is highly implementation specific and so care
+ * should be taken when configuring the {@code Executor}. Minimally it
+ * should support an unbounded work queue and should not run tasks on the
+ * caller thread of the {@link ExecutorService#execute execute} method.
+ * Shutting down the executor service while the channel is open results in
+ * unspecified behavior.
+ *
+ * <p> The {@code attrs} parameter is an optional array of file {@link
+ * FileAttribute file-attributes} to set atomically when creating the file.
+ *
+ * <p> The new channel is created by invoking the {@link
+ * FileSystemProvider#newFileChannel newFileChannel} method on the
+ * provider that created the {@code Path}.
+ *
+ * @param file
+ * The path of the file to open or create
+ * @param options
+ * Options specifying how the file is opened
+ * @param executor
+ * The thread pool or {@code null} to associate the channel with
+ * the default thread pool
+ * @param attrs
+ * An optional list of file attributes to set atomically when
+ * creating the file
+ *
+ * @return A new asynchronous file channel
+ *
+ * @throws IllegalArgumentException
+ * If the set contains an invalid combination of options
+ * @throws UnsupportedOperationException
+ * If the {@code file} is associated with a provider that does not
+ * support creating asynchronous file channels, or an unsupported
+ * open option is specified, or the array contains an attribute that
+ * cannot be set atomically when creating the file
+ * @throws IOException
+ * If an I/O error occurs
+ * @throws SecurityException
+ * If a security manager is installed and it denies an
+ * unspecified permission required by the implementation.
+ * In the case of the default provider, the {@link
+ * SecurityManager#checkRead(String)} method is invoked to check
+ * read access if the file is opened for reading. The {@link
+ * SecurityManager#checkWrite(String)} method is invoked to check
+ * write access if the file is opened for writing
+ */
+ public static AsynchronousFileChannel open(Path file,
+ Set<? extends OpenOption> options,
+ ExecutorService executor,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ FileSystemProvider provider = file.getFileSystem().provider();
+ return provider.newAsynchronousFileChannel(file, options, executor, attrs);
+ }
+
+ @SuppressWarnings({"unchecked", "rawtypes"}) // generic array construction
+ private static final FileAttribute<?>[] NO_ATTRIBUTES = new FileAttribute[0];
+
+ /**
+ * Opens or creates a file for reading and/or writing, returning an
+ * asynchronous file channel to access the file.
+ *
+ * <p> An invocation of this method behaves in exactly the same way as the
+ * invocation
+ * <pre>
+ * ch.{@link #open(Path,Set,ExecutorService,FileAttribute[])
+ * open}(file, opts, null, new FileAttribute<?>[0]);
+ * </pre>
+ * where {@code opts} is a {@code Set} containing the options specified to
+ * this method.
+ *
+ * <p> The resulting channel is associated with default thread pool to which
+ * tasks are submitted to handle I/O events and dispatch to completion
+ * handlers that consume the result of asynchronous operations performed on
+ * the resulting channel.
+ *
+ * @param file
+ * The path of the file to open or create
+ * @param options
+ * Options specifying how the file is opened
+ *
+ * @return A new asynchronous file channel
+ *
+ * @throws IllegalArgumentException
+ * If the set contains an invalid combination of options
+ * @throws UnsupportedOperationException
+ * If the {@code file} is associated with a provider that does not
+ * support creating file channels, or an unsupported open option is
+ * specified
+ * @throws IOException
+ * If an I/O error occurs
+ * @throws SecurityException
+ * If a security manager is installed and it denies an
+ * unspecified permission required by the implementation.
+ * In the case of the default provider, the {@link
+ * SecurityManager#checkRead(String)} method is invoked to check
+ * read access if the file is opened for reading. The {@link
+ * SecurityManager#checkWrite(String)} method is invoked to check
+ * write access if the file is opened for writing
+ */
+ public static AsynchronousFileChannel open(Path file, OpenOption... options)
+ throws IOException
+ {
+ Set<OpenOption> set = new HashSet<OpenOption>(options.length);
+ Collections.addAll(set, options);
+ return open(file, set, null, NO_ATTRIBUTES);
+ }
+
+ /**
+ * Returns the current size of this channel's file.
+ *
+ * @return The current size of this channel's file, measured in bytes
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public abstract long size() throws IOException;
+
+ /**
+ * Truncates this channel's file to the given size.
+ *
+ * <p> If the given size is less than the file's current size then the file
+ * is truncated, discarding any bytes beyond the new end of the file. If
+ * the given size is greater than or equal to the file's current size then
+ * the file is not modified. </p>
+ *
+ * @param size
+ * The new size, a non-negative byte count
+ *
+ * @return This file channel
+ *
+ * @throws NonWritableChannelException
+ * If this channel was not opened for writing
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ *
+ * @throws IllegalArgumentException
+ * If the new size is negative
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public abstract AsynchronousFileChannel truncate(long size) throws IOException;
+
+ /**
+ * Forces any updates to this channel's file to be written to the storage
+ * device that contains it.
+ *
+ * <p> If this channel's file resides on a local storage device then when
+ * this method returns it is guaranteed that all changes made to the file
+ * since this channel was created, or since this method was last invoked,
+ * will have been written to that device. This is useful for ensuring that
+ * critical information is not lost in the event of a system crash.
+ *
+ * <p> If the file does not reside on a local device then no such guarantee
+ * is made.
+ *
+ * <p> The {@code metaData} parameter can be used to limit the number of
+ * I/O operations that this method is required to perform. Passing
+ * {@code false} for this parameter indicates that only updates to the
+ * file's content need be written to storage; passing {@code true}
+ * indicates that updates to both the file's content and metadata must be
+ * written, which generally requires at least one more I/O operation.
+ * Whether this parameter actually has any effect is dependent upon the
+ * underlying operating system and is therefore unspecified.
+ *
+ * <p> Invoking this method may cause an I/O operation to occur even if the
+ * channel was only opened for reading. Some operating systems, for
+ * example, maintain a last-access time as part of a file's metadata, and
+ * this time is updated whenever the file is read. Whether or not this is
+ * actually done is system-dependent and is therefore unspecified.
+ *
+ * <p> This method is only guaranteed to force changes that were made to
+ * this channel's file via the methods defined in this class.
+ *
+ * @param metaData
+ * If {@code true} then this method is required to force changes
+ * to both the file's content and metadata to be written to
+ * storage; otherwise, it need only force content changes to be
+ * written
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public abstract void force(boolean metaData) throws IOException;
+
+ /**
+ * Acquires a lock on the given region of this channel's file.
+ *
+ * <p> This method initiates an operation to acquire a lock on the given
+ * region of this channel's file. The {@code handler} parameter is a
+ * completion handler that is invoked when the lock is acquired (or the
+ * operation fails). The result passed to the completion handler is the
+ * resulting {@code FileLock}.
+ *
+ * <p> The region specified by the {@code position} and {@code size}
+ * parameters need not be contained within, or even overlap, the actual
+ * underlying file. Lock regions are fixed in size; if a locked region
+ * initially contains the end of the file and the file grows beyond the
+ * region then the new portion of the file will not be covered by the lock.
+ * If a file is expected to grow in size and a lock on the entire file is
+ * required then a region starting at zero, and no smaller than the
+ * expected maximum size of the file, should be locked. The two-argument
+ * {@link #lock(Object,CompletionHandler)} method simply locks a region
+ * of size {@link Long#MAX_VALUE}. If a lock that overlaps the requested
+ * region is already held by this Java virtual machine, or this method has
+ * been invoked to lock an overlapping region and that operation has not
+ * completed, then this method throws {@link OverlappingFileLockException}.
+ *
+ * <p> Some operating systems do not support a mechanism to acquire a file
+ * lock in an asynchronous manner. Consequently an implementation may
+ * acquire the file lock in a background thread or from a task executed by
+ * a thread in the associated thread pool. If there are many lock operations
+ * outstanding then it may consume threads in the Java virtual machine for
+ * indefinite periods.
+ *
+ * <p> Some operating systems do not support shared locks, in which case a
+ * request for a shared lock is automatically converted into a request for
+ * an exclusive lock. Whether the newly-acquired lock is shared or
+ * exclusive may be tested by invoking the resulting lock object's {@link
+ * FileLock#isShared() isShared} method.
+ *
+ * <p> File locks are held on behalf of the entire Java virtual machine.
+ * They are not suitable for controlling access to a file by multiple
+ * threads within the same virtual machine.
+ *
+ * @param <A>
+ * The type of the attachment
+ * @param position
+ * The position at which the locked region is to start; must be
+ * non-negative
+ * @param size
+ * The size of the locked region; must be non-negative, and the sum
+ * {@code position} + {@code size} must be non-negative
+ * @param shared
+ * {@code true} to request a shared lock, in which case this
+ * channel must be open for reading (and possibly writing);
+ * {@code false} to request an exclusive lock, in which case this
+ * channel must be open for writing (and possibly reading)
+ * @param attachment
+ * The object to attach to the I/O operation; can be {@code null}
+ * @param handler
+ * The handler for consuming the result
+ *
+ * @throws OverlappingFileLockException
+ * If a lock that overlaps the requested region is already held by
+ * this Java virtual machine, or there is already a pending attempt
+ * to lock an overlapping region
+ * @throws IllegalArgumentException
+ * If the preconditions on the parameters do not hold
+ * @throws NonReadableChannelException
+ * If {@code shared} is true but this channel was not opened for reading
+ * @throws NonWritableChannelException
+ * If {@code shared} is false but this channel was not opened for writing
+ */
+ public abstract <A> void lock(long position,
+ long size,
+ boolean shared,
+ A attachment,
+ CompletionHandler<FileLock,? super A> handler);
+
+ /**
+ * Acquires an exclusive lock on this channel's file.
+ *
+ * <p> This method initiates an operation to acquire a lock on the given
+ * region of this channel's file. The {@code handler} parameter is a
+ * completion handler that is invoked when the lock is acquired (or the
+ * operation fails). The result passed to the completion handler is the
+ * resulting {@code FileLock}.
+ *
+ * <p> An invocation of this method of the form {@code ch.lock(att,handler)}
+ * behaves in exactly the same way as the invocation
+ * <pre>
+ * ch.{@link #lock(long,long,boolean,Object,CompletionHandler) lock}(0L, Long.MAX_VALUE, false, att, handler)
+ * </pre>
+ *
+ * @param <A>
+ * The type of the attachment
+ * @param attachment
+ * The object to attach to the I/O operation; can be {@code null}
+ * @param handler
+ * The handler for consuming the result
+ *
+ * @throws OverlappingFileLockException
+ * If a lock is already held by this Java virtual machine, or there
+ * is already a pending attempt to lock a region
+ * @throws NonWritableChannelException
+ * If this channel was not opened for writing
+ */
+ public final <A> void lock(A attachment,
+ CompletionHandler<FileLock,? super A> handler)
+ {
+ lock(0L, Long.MAX_VALUE, false, attachment, handler);
+ }
+
+ /**
+ * Acquires a lock on the given region of this channel's file.
+ *
+ * <p> This method initiates an operation to acquire a lock on the given
+ * region of this channel's file. The method behaves in exactly the same
+ * manner as the {@link #lock(long, long, boolean, Object, CompletionHandler)}
+ * method except that instead of specifying a completion handler, this
+ * method returns a {@code Future} representing the pending result. The
+ * {@code Future}'s {@link Future#get() get} method returns the {@link
+ * FileLock} on successful completion.
+ *
+ * @param position
+ * The position at which the locked region is to start; must be
+ * non-negative
+ * @param size
+ * The size of the locked region; must be non-negative, and the sum
+ * {@code position} + {@code size} must be non-negative
+ * @param shared
+ * {@code true} to request a shared lock, in which case this
+ * channel must be open for reading (and possibly writing);
+ * {@code false} to request an exclusive lock, in which case this
+ * channel must be open for writing (and possibly reading)
+ *
+ * @return a {@code Future} object representing the pending result
+ *
+ * @throws OverlappingFileLockException
+ * If a lock is already held by this Java virtual machine, or there
+ * is already a pending attempt to lock a region
+ * @throws IllegalArgumentException
+ * If the preconditions on the parameters do not hold
+ * @throws NonReadableChannelException
+ * If {@code shared} is true but this channel was not opened for reading
+ * @throws NonWritableChannelException
+ * If {@code shared} is false but this channel was not opened for writing
+ */
+ public abstract Future<FileLock> lock(long position, long size, boolean shared);
+
+ /**
+ * Acquires an exclusive lock on this channel's file.
+ *
+ * <p> This method initiates an operation to acquire an exclusive lock on this
+ * channel's file. The method returns a {@code Future} representing the
+ * pending result of the operation. The {@code Future}'s {@link Future#get()
+ * get} method returns the {@link FileLock} on successful completion.
+ *
+ * <p> An invocation of this method behaves in exactly the same way as the
+ * invocation
+ * <pre>
+ * ch.{@link #lock(long,long,boolean) lock}(0L, Long.MAX_VALUE, false)
+ * </pre>
+ *
+ * @return a {@code Future} object representing the pending result
+ *
+ * @throws OverlappingFileLockException
+ * If a lock is already held by this Java virtual machine, or there
+ * is already a pending attempt to lock a region
+ * @throws NonWritableChannelException
+ * If this channel was not opened for writing
+ */
+ public final Future<FileLock> lock() {
+ return lock(0L, Long.MAX_VALUE, false);
+ }
+
+ /**
+ * Attempts to acquire a lock on the given region of this channel's file.
+ *
+ * <p> This method does not block. An invocation always returns immediately,
+ * either having acquired a lock on the requested region or having failed to
+ * do so. If it fails to acquire a lock because an overlapping lock is held
+ * by another program then it returns {@code null}. If it fails to acquire
+ * a lock for any other reason then an appropriate exception is thrown.
+ *
+ * @param position
+ * The position at which the locked region is to start; must be
+ * non-negative
+ *
+ * @param size
+ * The size of the locked region; must be non-negative, and the sum
+ * {@code position} + {@code size} must be non-negative
+ *
+ * @param shared
+ * {@code true} to request a shared lock,
+ * {@code false} to request an exclusive lock
+ *
+ * @return A lock object representing the newly-acquired lock,
+ * or {@code null} if the lock could not be acquired
+ * because another program holds an overlapping lock
+ *
+ * @throws IllegalArgumentException
+ * If the preconditions on the parameters do not hold
+ * @throws ClosedChannelException
+ * If this channel is closed
+ * @throws OverlappingFileLockException
+ * If a lock that overlaps the requested region is already held by
+ * this Java virtual machine, or if another thread is already
+ * blocked in this method and is attempting to lock an overlapping
+ * region of the same file
+ * @throws NonReadableChannelException
+ * If {@code shared} is true but this channel was not opened for reading
+ * @throws NonWritableChannelException
+ * If {@code shared} is false but this channel was not opened for writing
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ *
+ * @see #lock(Object,CompletionHandler)
+ * @see #lock(long,long,boolean,Object,CompletionHandler)
+ * @see #tryLock()
+ */
+ public abstract FileLock tryLock(long position, long size, boolean shared)
+ throws IOException;
+
+ /**
+ * Attempts to acquire an exclusive lock on this channel's file.
+ *
+ * <p> An invocation of this method of the form {@code ch.tryLock()}
+ * behaves in exactly the same way as the invocation
+ *
+ * <pre>
+ * ch.{@link #tryLock(long,long,boolean) tryLock}(0L, Long.MAX_VALUE, false) </pre>
+ *
+ * @return A lock object representing the newly-acquired lock,
+ * or {@code null} if the lock could not be acquired
+ * because another program holds an overlapping lock
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ * @throws OverlappingFileLockException
+ * If a lock that overlaps the requested region is already held by
+ * this Java virtual machine, or if another thread is already
+ * blocked in this method and is attempting to lock an overlapping
+ * region
+ * @throws NonWritableChannelException
+ * If {@code shared} is false but this channel was not opened for writing
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ *
+ * @see #lock(Object,CompletionHandler)
+ * @see #lock(long,long,boolean,Object,CompletionHandler)
+ * @see #tryLock(long,long,boolean)
+ */
+ public final FileLock tryLock() throws IOException {
+ return tryLock(0L, Long.MAX_VALUE, false);
+ }
+
+ /**
+ * Reads a sequence of bytes from this channel into the given buffer,
+ * starting at the given file position.
+ *
+ * <p> This method initiates the reading of a sequence of bytes from this
+ * channel into the given buffer, starting at the given file position. The
+ * result of the read is the number of bytes read or {@code -1} if the given
+ * position is greater than or equal to the file's size at the time that the
+ * read is attempted.
+ *
+ * <p> This method works in the same manner as the {@link
+ * AsynchronousByteChannel#read(ByteBuffer,Object,CompletionHandler)}
+ * method, except that bytes are read starting at the given file position.
+ * If the given file position is greater than the file's size at the time
+ * that the read is attempted then no bytes are read.
+ *
+ * @param <A>
+ * The type of the attachment
+ * @param dst
+ * The buffer into which bytes are to be transferred
+ * @param position
+ * The file position at which the transfer is to begin;
+ * must be non-negative
+ * @param attachment
+ * The object to attach to the I/O operation; can be {@code null}
+ * @param handler
+ * The handler for consuming the result
+ *
+ * @throws IllegalArgumentException
+ * If the position is negative or the buffer is read-only
+ * @throws NonReadableChannelException
+ * If this channel was not opened for reading
+ */
+ public abstract <A> void read(ByteBuffer dst,
+ long position,
+ A attachment,
+ CompletionHandler<Integer,? super A> handler);
+
+ /**
+ * Reads a sequence of bytes from this channel into the given buffer,
+ * starting at the given file position.
+ *
+ * <p> This method initiates the reading of a sequence of bytes from this
+ * channel into the given buffer, starting at the given file position. This
+ * method returns a {@code Future} representing the pending result of the
+ * operation. The {@code Future}'s {@link Future#get() get} method returns
+ * the number of bytes read or {@code -1} if the given position is greater
+ * than or equal to the file's size at the time that the read is attempted.
+ *
+ * <p> This method works in the same manner as the {@link
+ * AsynchronousByteChannel#read(ByteBuffer)} method, except that bytes are
+ * read starting at the given file position. If the given file position is
+ * greater than the file's size at the time that the read is attempted then
+ * no bytes are read.
+ *
+ * @param dst
+ * The buffer into which bytes are to be transferred
+ * @param position
+ * The file position at which the transfer is to begin;
+ * must be non-negative
+ *
+ * @return A {@code Future} object representing the pending result
+ *
+ * @throws IllegalArgumentException
+ * If the position is negative or the buffer is read-only
+ * @throws NonReadableChannelException
+ * If this channel was not opened for reading
+ */
+ public abstract Future<Integer> read(ByteBuffer dst, long position);
+
+ /**
+ * Writes a sequence of bytes to this channel from the given buffer, starting
+ * at the given file position.
+ *
+ * <p> This method works in the same manner as the {@link
+ * AsynchronousByteChannel#write(ByteBuffer,Object,CompletionHandler)}
+ * method, except that bytes are written starting at the given file position.
+ * If the given position is greater than the file's size, at the time that
+ * the write is attempted, then the file will be grown to accommodate the new
+ * bytes; the values of any bytes between the previous end-of-file and the
+ * newly-written bytes are unspecified.
+ *
+ * @param <A>
+ * The type of the attachment
+ * @param src
+ * The buffer from which bytes are to be transferred
+ * @param position
+ * The file position at which the transfer is to begin;
+ * must be non-negative
+ * @param attachment
+ * The object to attach to the I/O operation; can be {@code null}
+ * @param handler
+ * The handler for consuming the result
+ *
+ * @throws IllegalArgumentException
+ * If the position is negative
+ * @throws NonWritableChannelException
+ * If this channel was not opened for writing
+ */
+ public abstract <A> void write(ByteBuffer src,
+ long position,
+ A attachment,
+ CompletionHandler<Integer,? super A> handler);
+
+ /**
+ * Writes a sequence of bytes to this channel from the given buffer, starting
+ * at the given file position.
+ *
+ * <p> This method initiates the writing of a sequence of bytes to this
+ * channel from the given buffer, starting at the given file position. The
+ * method returns a {@code Future} representing the pending result of the
+ * write operation. The {@code Future}'s {@link Future#get() get} method
+ * returns the number of bytes written.
+ *
+ * <p> This method works in the same manner as the {@link
+ * AsynchronousByteChannel#write(ByteBuffer)} method, except that bytes are
+ * written starting at the given file position. If the given position is
+ * greater than the file's size, at the time that the write is attempted,
+ * then the file will be grown to accommodate the new bytes; the values of
+ * any bytes between the previous end-of-file and the newly-written bytes
+ * are unspecified.
+ *
+ * @param src
+ * The buffer from which bytes are to be transferred
+ * @param position
+ * The file position at which the transfer is to begin;
+ * must be non-negative
+ *
+ * @return A {@code Future} object representing the pending result
+ *
+ * @throws IllegalArgumentException
+ * If the position is negative
+ * @throws NonWritableChannelException
+ * If this channel was not opened for writing
+ */
+ public abstract Future<Integer> write(ByteBuffer src, long position);
+}
diff --git a/java/nio/channels/AsynchronousServerSocketChannel.java b/java/nio/channels/AsynchronousServerSocketChannel.java
new file mode 100644
index 0000000..29ecbd6
--- /dev/null
+++ b/java/nio/channels/AsynchronousServerSocketChannel.java
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+import java.nio.channels.spi.*;
+import java.net.SocketOption;
+import java.net.SocketAddress;
+import java.util.concurrent.Future;
+import java.io.IOException;
+
+/**
+ * An asynchronous channel for stream-oriented listening sockets.
+ *
+ * <p> An asynchronous server-socket channel is created by invoking the
+ * {@link #open open} method of this class.
+ * A newly-created asynchronous server-socket channel is open but not yet bound.
+ * It can be bound to a local address and configured to listen for connections
+ * by invoking the {@link #bind(SocketAddress,int) bind} method. Once bound,
+ * the {@link #accept(Object,CompletionHandler) accept} method
+ * is used to initiate the accepting of connections to the channel's socket.
+ * An attempt to invoke the <tt>accept</tt> method on an unbound channel will
+ * cause a {@link NotYetBoundException} to be thrown.
+ *
+ * <p> Channels of this type are safe for use by multiple concurrent threads
+ * though at most one accept operation can be outstanding at any time.
+ * If a thread initiates an accept operation before a previous accept operation
+ * has completed then an {@link AcceptPendingException} will be thrown.
+ *
+ * <p> Socket options are configured using the {@link #setOption(SocketOption,Object)
+ * setOption} method. Channels of this type support the following options:
+ * <blockquote>
+ * <table border summary="Socket options">
+ * <tr>
+ * <th>Option Name</th>
+ * <th>Description</th>
+ * </tr>
+ * <tr>
+ * <td> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </td>
+ * <td> The size of the socket receive buffer </td>
+ * </tr>
+ * <tr>
+ * <td> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </td>
+ * <td> Re-use address </td>
+ * </tr>
+ * </table>
+ * </blockquote>
+ * Additional (implementation specific) options may also be supported.
+ *
+ * <p> <b>Usage Example:</b>
+ * <pre>
+ * final AsynchronousServerSocketChannel listener =
+ * AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(5000));
+ *
+ * listener.accept(null, new CompletionHandler<AsynchronousSocketChannel,Void>() {
+ * public void completed(AsynchronousSocketChannel ch, Void att) {
+ * // accept the next connection
+ * listener.accept(null, this);
+ *
+ * // handle this connection
+ * handle(ch);
+ * }
+ * public void failed(Throwable exc, Void att) {
+ * ...
+ * }
+ * });
+ * </pre>
+ *
+ * @since 1.7
+ */
+
+public abstract class AsynchronousServerSocketChannel
+ implements AsynchronousChannel, NetworkChannel
+{
+ private final AsynchronousChannelProvider provider;
+
+ /**
+ * Initializes a new instance of this class.
+ *
+ * @param provider
+ * The provider that created this channel
+ */
+ protected AsynchronousServerSocketChannel(AsynchronousChannelProvider provider) {
+ this.provider = provider;
+ }
+
+ /**
+ * Returns the provider that created this channel.
+ *
+ * @return The provider that created this channel
+ */
+ public final AsynchronousChannelProvider provider() {
+ return provider;
+ }
+
+ /**
+ * Opens an asynchronous server-socket channel.
+ *
+ * <p> The new channel is created by invoking the {@link
+ * java.nio.channels.spi.AsynchronousChannelProvider#openAsynchronousServerSocketChannel
+ * openAsynchronousServerSocketChannel} method on the {@link
+ * java.nio.channels.spi.AsynchronousChannelProvider} object that created
+ * the given group. If the group parameter is <tt>null</tt> then the
+ * resulting channel is created by the system-wide default provider, and
+ * bound to the <em>default group</em>.
+ *
+ * @param group
+ * The group to which the newly constructed channel should be bound,
+ * or <tt>null</tt> for the default group
+ *
+ * @return A new asynchronous server socket channel
+ *
+ * @throws ShutdownChannelGroupException
+ * If the channel group is shutdown
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ public static AsynchronousServerSocketChannel open(AsynchronousChannelGroup group)
+ throws IOException
+ {
+ AsynchronousChannelProvider provider = (group == null) ?
+ AsynchronousChannelProvider.provider() : group.provider();
+ return provider.openAsynchronousServerSocketChannel(group);
+ }
+
+ /**
+ * Opens an asynchronous server-socket channel.
+ *
+ * <p> This method returns an asynchronous server socket channel that is
+ * bound to the <em>default group</em>. This method is equivalent to evaluating
+ * the expression:
+ * <blockquote><pre>
+ * open((AsynchronousChannelGroup)null);
+ * </pre></blockquote>
+ *
+ * @return A new asynchronous server socket channel
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ public static AsynchronousServerSocketChannel open()
+ throws IOException
+ {
+ return open(null);
+ }
+
+ /**
+ * Binds the channel's socket to a local address and configures the socket to
+ * listen for connections.
+ *
+ * <p> An invocation of this method is equivalent to the following:
+ * <blockquote><pre>
+ * bind(local, 0);
+ * </pre></blockquote>
+ *
+ * @param local
+ * The local address to bind the socket, or <tt>null</tt> to bind
+ * to an automatically assigned socket address
+ *
+ * @return This channel
+ *
+ * @throws AlreadyBoundException {@inheritDoc}
+ * @throws UnsupportedAddressTypeException {@inheritDoc}
+ * @throws SecurityException {@inheritDoc}
+ * @throws ClosedChannelException {@inheritDoc}
+ * @throws IOException {@inheritDoc}
+ */
+ public final AsynchronousServerSocketChannel bind(SocketAddress local)
+ throws IOException
+ {
+ return bind(local, 0);
+ }
+
+ /**
+ * Binds the channel's socket to a local address and configures the socket to
+ * listen for connections.
+ *
+ * <p> This method is used to establish an association between the socket and
+ * a local address. Once an association is established then the socket remains
+ * bound until the associated channel is closed.
+ *
+ * <p> The {@code backlog} parameter is the maximum number of pending
+ * connections on the socket. Its exact semantics are implementation specific.
+ * In particular, an implementation may impose a maximum length or may choose
+ * to ignore the parameter altogther. If the {@code backlog} parameter has
+ * the value {@code 0}, or a negative value, then an implementation specific
+ * default is used.
+ *
+ * @param local
+ * The local address to bind the socket, or {@code null} to bind
+ * to an automatically assigned socket address
+ * @param backlog
+ * The maximum number of pending connections
+ *
+ * @return This channel
+ *
+ * @throws AlreadyBoundException
+ * If the socket is already bound
+ * @throws UnsupportedAddressTypeException
+ * If the type of the given address is not supported
+ * @throws SecurityException
+ * If a security manager has been installed and its {@link
+ * SecurityManager#checkListen checkListen} method denies the operation
+ * @throws ClosedChannelException
+ * If the channel is closed
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public abstract AsynchronousServerSocketChannel bind(SocketAddress local, int backlog)
+ throws IOException;
+
+ /**
+ * @throws IllegalArgumentException {@inheritDoc}
+ * @throws ClosedChannelException {@inheritDoc}
+ * @throws IOException {@inheritDoc}
+ */
+ public abstract <T> AsynchronousServerSocketChannel setOption(SocketOption<T> name, T value)
+ throws IOException;
+
+ /**
+ * Accepts a connection.
+ *
+ * <p> This method initiates an asynchronous operation to accept a
+ * connection made to this channel's socket. The {@code handler} parameter is
+ * a completion handler that is invoked when a connection is accepted (or
+ * the operation fails). The result passed to the completion handler is
+ * the {@link AsynchronousSocketChannel} to the new connection.
+ *
+ * <p> When a new connection is accepted then the resulting {@code
+ * AsynchronousSocketChannel} will be bound to the same {@link
+ * AsynchronousChannelGroup} as this channel. If the group is {@link
+ * AsynchronousChannelGroup#isShutdown shutdown} and a connection is accepted,
+ * then the connection is closed, and the operation completes with an {@code
+ * IOException} and cause {@link ShutdownChannelGroupException}.
+ *
+ * <p> To allow for concurrent handling of new connections, the completion
+ * handler is not invoked directly by the initiating thread when a new
+ * connection is accepted immediately (see <a
+ * href="AsynchronousChannelGroup.html#threading">Threading</a>).
+ *
+ * <p> If a security manager has been installed then it verifies that the
+ * address and port number of the connection's remote endpoint are permitted
+ * by the security manager's {@link SecurityManager#checkAccept checkAccept}
+ * method. The permission check is performed with privileges that are restricted
+ * by the calling context of this method. If the permission check fails then
+ * the connection is closed and the operation completes with a {@link
+ * SecurityException}.
+ *
+ * @param <A>
+ * The type of the attachment
+ * @param attachment
+ * The object to attach to the I/O operation; can be {@code null}
+ * @param handler
+ * The handler for consuming the result
+ *
+ * @throws AcceptPendingException
+ * If an accept operation is already in progress on this channel
+ * @throws NotYetBoundException
+ * If this channel's socket has not yet been bound
+ * @throws ShutdownChannelGroupException
+ * If the channel group has terminated
+ */
+ public abstract <A> void accept(A attachment,
+ CompletionHandler<AsynchronousSocketChannel,? super A> handler);
+
+ /**
+ * Accepts a connection.
+ *
+ * <p> This method initiates an asynchronous operation to accept a
+ * connection made to this channel's socket. The method behaves in exactly
+ * the same manner as the {@link #accept(Object, CompletionHandler)} method
+ * except that instead of specifying a completion handler, this method
+ * returns a {@code Future} representing the pending result. The {@code
+ * Future}'s {@link Future#get() get} method returns the {@link
+ * AsynchronousSocketChannel} to the new connection on successful completion.
+ *
+ * @return a {@code Future} object representing the pending result
+ *
+ * @throws AcceptPendingException
+ * If an accept operation is already in progress on this channel
+ * @throws NotYetBoundException
+ * If this channel's socket has not yet been bound
+ */
+ public abstract Future<AsynchronousSocketChannel> accept();
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * If there is a security manager set, its {@code checkConnect} method is
+ * called with the local address and {@code -1} as its arguments to see
+ * if the operation is allowed. If the operation is not allowed,
+ * a {@code SocketAddress} representing the
+ * {@link java.net.InetAddress#getLoopbackAddress loopback} address and the
+ * local port of the channel's socket is returned.
+ *
+ * @return The {@code SocketAddress} that the socket is bound to, or the
+ * {@code SocketAddress} representing the loopback address if
+ * denied by the security manager, or {@code null} if the
+ * channel's socket is not bound
+ *
+ * @throws ClosedChannelException {@inheritDoc}
+ * @throws IOException {@inheritDoc}
+ */
+ @Override
+ public abstract SocketAddress getLocalAddress() throws IOException;
+}
diff --git a/java/nio/channels/AsynchronousSocketChannel.java b/java/nio/channels/AsynchronousSocketChannel.java
new file mode 100644
index 0000000..1ed1e86
--- /dev/null
+++ b/java/nio/channels/AsynchronousSocketChannel.java
@@ -0,0 +1,687 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+import java.nio.channels.spi.*;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.Future;
+import java.io.IOException;
+import java.net.SocketOption;
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+
+/**
+ * An asynchronous channel for stream-oriented connecting sockets.
+ *
+ * <p> Asynchronous socket channels are created in one of two ways. A newly-created
+ * {@code AsynchronousSocketChannel} is created by invoking one of the {@link
+ * #open open} methods defined by this class. A newly-created channel is open but
+ * not yet connected. A connected {@code AsynchronousSocketChannel} is created
+ * when a connection is made to the socket of an {@link AsynchronousServerSocketChannel}.
+ * It is not possible to create an asynchronous socket channel for an arbitrary,
+ * pre-existing {@link java.net.Socket socket}.
+ *
+ * <p> A newly-created channel is connected by invoking its {@link #connect connect}
+ * method; once connected, a channel remains connected until it is closed. Whether
+ * or not a socket channel is connected may be determined by invoking its {@link
+ * #getRemoteAddress getRemoteAddress} method. An attempt to invoke an I/O
+ * operation upon an unconnected channel will cause a {@link NotYetConnectedException}
+ * to be thrown.
+ *
+ * <p> Channels of this type are safe for use by multiple concurrent threads.
+ * They support concurrent reading and writing, though at most one read operation
+ * and one write operation can be outstanding at any time.
+ * If a thread initiates a read operation before a previous read operation has
+ * completed then a {@link ReadPendingException} will be thrown. Similarly, an
+ * attempt to initiate a write operation before a previous write has completed
+ * will throw a {@link WritePendingException}.
+ *
+ * <p> Socket options are configured using the {@link #setOption(SocketOption,Object)
+ * setOption} method. Asynchronous socket channels support the following options:
+ * <blockquote>
+ * <table border summary="Socket options">
+ * <tr>
+ * <th>Option Name</th>
+ * <th>Description</th>
+ * </tr>
+ * <tr>
+ * <td> {@link java.net.StandardSocketOptions#SO_SNDBUF SO_SNDBUF} </td>
+ * <td> The size of the socket send buffer </td>
+ * </tr>
+ * <tr>
+ * <td> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </td>
+ * <td> The size of the socket receive buffer </td>
+ * </tr>
+ * <tr>
+ * <td> {@link java.net.StandardSocketOptions#SO_KEEPALIVE SO_KEEPALIVE} </td>
+ * <td> Keep connection alive </td>
+ * </tr>
+ * <tr>
+ * <td> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </td>
+ * <td> Re-use address </td>
+ * </tr>
+ * <tr>
+ * <td> {@link java.net.StandardSocketOptions#TCP_NODELAY TCP_NODELAY} </td>
+ * <td> Disable the Nagle algorithm </td>
+ * </tr>
+ * </table>
+ * </blockquote>
+ * Additional (implementation specific) options may also be supported.
+ *
+ * <h2>Timeouts</h2>
+ *
+ * <p> The {@link #read(ByteBuffer,long,TimeUnit,Object,CompletionHandler) read}
+ * and {@link #write(ByteBuffer,long,TimeUnit,Object,CompletionHandler) write}
+ * methods defined by this class allow a timeout to be specified when initiating
+ * a read or write operation. If the timeout elapses before an operation completes
+ * then the operation completes with the exception {@link
+ * InterruptedByTimeoutException}. A timeout may leave the channel, or the
+ * underlying connection, in an inconsistent state. Where the implementation
+ * cannot guarantee that bytes have not been read from the channel then it puts
+ * the channel into an implementation specific <em>error state</em>. A subsequent
+ * attempt to initiate a {@code read} operation causes an unspecified runtime
+ * exception to be thrown. Similarly if a {@code write} operation times out and
+ * the implementation cannot guarantee bytes have not been written to the
+ * channel then further attempts to {@code write} to the channel cause an
+ * unspecified runtime exception to be thrown. When a timeout elapses then the
+ * state of the {@link ByteBuffer}, or the sequence of buffers, for the I/O
+ * operation is not defined. Buffers should be discarded or at least care must
+ * be taken to ensure that the buffers are not accessed while the channel remains
+ * open. All methods that accept timeout parameters treat values less than or
+ * equal to zero to mean that the I/O operation does not timeout.
+ *
+ * @since 1.7
+ */
+
+public abstract class AsynchronousSocketChannel
+ implements AsynchronousByteChannel, NetworkChannel
+{
+ private final AsynchronousChannelProvider provider;
+
+ /**
+ * Initializes a new instance of this class.
+ *
+ * @param provider
+ * The provider that created this channel
+ */
+ protected AsynchronousSocketChannel(AsynchronousChannelProvider provider) {
+ this.provider = provider;
+ }
+
+ /**
+ * Returns the provider that created this channel.
+ *
+ * @return The provider that created this channel
+ */
+ public final AsynchronousChannelProvider provider() {
+ return provider;
+ }
+
+ /**
+ * Opens an asynchronous socket channel.
+ *
+ * <p> The new channel is created by invoking the {@link
+ * AsynchronousChannelProvider#openAsynchronousSocketChannel
+ * openAsynchronousSocketChannel} method on the {@link
+ * AsynchronousChannelProvider} that created the group. If the group parameter
+ * is {@code null} then the resulting channel is created by the system-wide
+ * default provider, and bound to the <em>default group</em>.
+ *
+ * @param group
+ * The group to which the newly constructed channel should be bound,
+ * or {@code null} for the default group
+ *
+ * @return A new asynchronous socket channel
+ *
+ * @throws ShutdownChannelGroupException
+ * If the channel group is shutdown
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ public static AsynchronousSocketChannel open(AsynchronousChannelGroup group)
+ throws IOException
+ {
+ AsynchronousChannelProvider provider = (group == null) ?
+ AsynchronousChannelProvider.provider() : group.provider();
+ return provider.openAsynchronousSocketChannel(group);
+ }
+
+ /**
+ * Opens an asynchronous socket channel.
+ *
+ * <p> This method returns an asynchronous socket channel that is bound to
+ * the <em>default group</em>.This method is equivalent to evaluating the
+ * expression:
+ * <blockquote><pre>
+ * open((AsynchronousChannelGroup)null);
+ * </pre></blockquote>
+ *
+ * @return A new asynchronous socket channel
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ public static AsynchronousSocketChannel open()
+ throws IOException
+ {
+ return open(null);
+ }
+
+
+ // -- socket options and related --
+
+ /**
+ * @throws ConnectionPendingException
+ * If a connection operation is already in progress on this channel
+ * @throws AlreadyBoundException {@inheritDoc}
+ * @throws UnsupportedAddressTypeException {@inheritDoc}
+ * @throws ClosedChannelException {@inheritDoc}
+ * @throws IOException {@inheritDoc}
+ * @throws SecurityException
+ * If a security manager has been installed and its
+ * {@link SecurityManager#checkListen checkListen} method denies
+ * the operation
+ */
+ @Override
+ public abstract AsynchronousSocketChannel bind(SocketAddress local)
+ throws IOException;
+
+ /**
+ * @throws IllegalArgumentException {@inheritDoc}
+ * @throws ClosedChannelException {@inheritDoc}
+ * @throws IOException {@inheritDoc}
+ */
+ @Override
+ public abstract <T> AsynchronousSocketChannel setOption(SocketOption<T> name, T value)
+ throws IOException;
+
+ /**
+ * Shutdown the connection for reading without closing the channel.
+ *
+ * <p> Once shutdown for reading then further reads on the channel will
+ * return {@code -1}, the end-of-stream indication. If the input side of the
+ * connection is already shutdown then invoking this method has no effect.
+ * The effect on an outstanding read operation is system dependent and
+ * therefore not specified. The effect, if any, when there is data in the
+ * socket receive buffer that has not been read, or data arrives subsequently,
+ * is also system dependent.
+ *
+ * @return The channel
+ *
+ * @throws NotYetConnectedException
+ * If this channel is not yet connected
+ * @throws ClosedChannelException
+ * If this channel is closed
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public abstract AsynchronousSocketChannel shutdownInput() throws IOException;
+
+ /**
+ * Shutdown the connection for writing without closing the channel.
+ *
+ * <p> Once shutdown for writing then further attempts to write to the
+ * channel will throw {@link ClosedChannelException}. If the output side of
+ * the connection is already shutdown then invoking this method has no
+ * effect. The effect on an outstanding write operation is system dependent
+ * and therefore not specified.
+ *
+ * @return The channel
+ *
+ * @throws NotYetConnectedException
+ * If this channel is not yet connected
+ * @throws ClosedChannelException
+ * If this channel is closed
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public abstract AsynchronousSocketChannel shutdownOutput() throws IOException;
+
+ // -- state --
+
+ /**
+ * Returns the remote address to which this channel's socket is connected.
+ *
+ * <p> Where the channel is bound and connected to an Internet Protocol
+ * socket address then the return value from this method is of type {@link
+ * java.net.InetSocketAddress}.
+ *
+ * @return The remote address; {@code null} if the channel's socket is not
+ * connected
+ *
+ * @throws ClosedChannelException
+ * If the channel is closed
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ public abstract SocketAddress getRemoteAddress() throws IOException;
+
+ // -- asynchronous operations --
+
+ /**
+ * Connects this channel.
+ *
+ * <p> This method initiates an operation to connect this channel. The
+ * {@code handler} parameter is a completion handler that is invoked when
+ * the connection is successfully established or connection cannot be
+ * established. If the connection cannot be established then the channel is
+ * closed.
+ *
+ * <p> This method performs exactly the same security checks as the {@link
+ * java.net.Socket} class. That is, if a security manager has been
+ * installed then this method verifies that its {@link
+ * java.lang.SecurityManager#checkConnect checkConnect} method permits
+ * connecting to the address and port number of the given remote endpoint.
+ *
+ * @param <A>
+ * The type of the attachment
+ * @param remote
+ * The remote address to which this channel is to be connected
+ * @param attachment
+ * The object to attach to the I/O operation; can be {@code null}
+ * @param handler
+ * The handler for consuming the result
+ *
+ * @throws UnresolvedAddressException
+ * If the given remote address is not fully resolved
+ * @throws UnsupportedAddressTypeException
+ * If the type of the given remote address is not supported
+ * @throws AlreadyConnectedException
+ * If this channel is already connected
+ * @throws ConnectionPendingException
+ * If a connection operation is already in progress on this channel
+ * @throws ShutdownChannelGroupException
+ * If the channel group has terminated
+ * @throws SecurityException
+ * If a security manager has been installed
+ * and it does not permit access to the given remote endpoint
+ *
+ * @see #getRemoteAddress
+ */
+ public abstract <A> void connect(SocketAddress remote,
+ A attachment,
+ CompletionHandler<Void,? super A> handler);
+
+ /**
+ * Connects this channel.
+ *
+ * <p> This method initiates an operation to connect this channel. This
+ * method behaves in exactly the same manner as the {@link
+ * #connect(SocketAddress, Object, CompletionHandler)} method except that
+ * instead of specifying a completion handler, this method returns a {@code
+ * Future} representing the pending result. The {@code Future}'s {@link
+ * Future#get() get} method returns {@code null} on successful completion.
+ *
+ * @param remote
+ * The remote address to which this channel is to be connected
+ *
+ * @return A {@code Future} object representing the pending result
+ *
+ * @throws UnresolvedAddressException
+ * If the given remote address is not fully resolved
+ * @throws UnsupportedAddressTypeException
+ * If the type of the given remote address is not supported
+ * @throws AlreadyConnectedException
+ * If this channel is already connected
+ * @throws ConnectionPendingException
+ * If a connection operation is already in progress on this channel
+ * @throws SecurityException
+ * If a security manager has been installed
+ * and it does not permit access to the given remote endpoint
+ */
+ public abstract Future<Void> connect(SocketAddress remote);
+
+ /**
+ * Reads a sequence of bytes from this channel into the given buffer.
+ *
+ * <p> This method initiates an asynchronous read operation to read a
+ * sequence of bytes from this channel into the given buffer. The {@code
+ * handler} parameter is a completion handler that is invoked when the read
+ * operation completes (or fails). The result passed to the completion
+ * handler is the number of bytes read or {@code -1} if no bytes could be
+ * read because the channel has reached end-of-stream.
+ *
+ * <p> If a timeout is specified and the timeout elapses before the operation
+ * completes then the operation completes with the exception {@link
+ * InterruptedByTimeoutException}. Where a timeout occurs, and the
+ * implementation cannot guarantee that bytes have not been read, or will not
+ * be read from the channel into the given buffer, then further attempts to
+ * read from the channel will cause an unspecific runtime exception to be
+ * thrown.
+ *
+ * <p> Otherwise this method works in the same manner as the {@link
+ * AsynchronousByteChannel#read(ByteBuffer,Object,CompletionHandler)}
+ * method.
+ *
+ * @param <A>
+ * The type of the attachment
+ * @param dst
+ * The buffer into which bytes are to be transferred
+ * @param timeout
+ * The maximum time for the I/O operation to complete
+ * @param unit
+ * The time unit of the {@code timeout} argument
+ * @param attachment
+ * The object to attach to the I/O operation; can be {@code null}
+ * @param handler
+ * The handler for consuming the result
+ *
+ * @throws IllegalArgumentException
+ * If the buffer is read-only
+ * @throws ReadPendingException
+ * If a read operation is already in progress on this channel
+ * @throws NotYetConnectedException
+ * If this channel is not yet connected
+ * @throws ShutdownChannelGroupException
+ * If the channel group has terminated
+ */
+ public abstract <A> void read(ByteBuffer dst,
+ long timeout,
+ TimeUnit unit,
+ A attachment,
+ CompletionHandler<Integer,? super A> handler);
+
+ /**
+ * @throws IllegalArgumentException {@inheritDoc}
+ * @throws ReadPendingException {@inheritDoc}
+ * @throws NotYetConnectedException
+ * If this channel is not yet connected
+ * @throws ShutdownChannelGroupException
+ * If the channel group has terminated
+ */
+ @Override
+ public final <A> void read(ByteBuffer dst,
+ A attachment,
+ CompletionHandler<Integer,? super A> handler)
+ {
+ read(dst, 0L, TimeUnit.MILLISECONDS, attachment, handler);
+ }
+
+ /**
+ * @throws IllegalArgumentException {@inheritDoc}
+ * @throws ReadPendingException {@inheritDoc}
+ * @throws NotYetConnectedException
+ * If this channel is not yet connected
+ */
+ @Override
+ public abstract Future<Integer> read(ByteBuffer dst);
+
+ /**
+ * Reads a sequence of bytes from this channel into a subsequence of the
+ * given buffers. This operation, sometimes called a <em>scattering read</em>,
+ * is often useful when implementing network protocols that group data into
+ * segments consisting of one or more fixed-length headers followed by a
+ * variable-length body. The {@code handler} parameter is a completion
+ * handler that is invoked when the read operation completes (or fails). The
+ * result passed to the completion handler is the number of bytes read or
+ * {@code -1} if no bytes could be read because the channel has reached
+ * end-of-stream.
+ *
+ * <p> This method initiates a read of up to <i>r</i> bytes from this channel,
+ * where <i>r</i> is the total number of bytes remaining in the specified
+ * subsequence of the given buffer array, that is,
+ *
+ * <blockquote><pre>
+ * dsts[offset].remaining()
+ * + dsts[offset+1].remaining()
+ * + ... + dsts[offset+length-1].remaining()</pre></blockquote>
+ *
+ * at the moment that the read is attempted.
+ *
+ * <p> Suppose that a byte sequence of length <i>n</i> is read, where
+ * <tt>0</tt> <tt><</tt> <i>n</i> <tt><=</tt> <i>r</i>.
+ * Up to the first <tt>dsts[offset].remaining()</tt> bytes of this sequence
+ * are transferred into buffer <tt>dsts[offset]</tt>, up to the next
+ * <tt>dsts[offset+1].remaining()</tt> bytes are transferred into buffer
+ * <tt>dsts[offset+1]</tt>, and so forth, until the entire byte sequence
+ * is transferred into the given buffers. As many bytes as possible are
+ * transferred into each buffer, hence the final position of each updated
+ * buffer, except the last updated buffer, is guaranteed to be equal to
+ * that buffer's limit. The underlying operating system may impose a limit
+ * on the number of buffers that may be used in an I/O operation. Where the
+ * number of buffers (with bytes remaining), exceeds this limit, then the
+ * I/O operation is performed with the maximum number of buffers allowed by
+ * the operating system.
+ *
+ * <p> If a timeout is specified and the timeout elapses before the operation
+ * completes then it completes with the exception {@link
+ * InterruptedByTimeoutException}. Where a timeout occurs, and the
+ * implementation cannot guarantee that bytes have not been read, or will not
+ * be read from the channel into the given buffers, then further attempts to
+ * read from the channel will cause an unspecific runtime exception to be
+ * thrown.
+ *
+ * @param <A>
+ * The type of the attachment
+ * @param dsts
+ * The buffers into which bytes are to be transferred
+ * @param offset
+ * The offset within the buffer array of the first buffer into which
+ * bytes are to be transferred; must be non-negative and no larger than
+ * {@code dsts.length}
+ * @param length
+ * The maximum number of buffers to be accessed; must be non-negative
+ * and no larger than {@code dsts.length - offset}
+ * @param timeout
+ * The maximum time for the I/O operation to complete
+ * @param unit
+ * The time unit of the {@code timeout} argument
+ * @param attachment
+ * The object to attach to the I/O operation; can be {@code null}
+ * @param handler
+ * The handler for consuming the result
+ *
+ * @throws IndexOutOfBoundsException
+ * If the pre-conditions for the {@code offset} and {@code length}
+ * parameter aren't met
+ * @throws IllegalArgumentException
+ * If the buffer is read-only
+ * @throws ReadPendingException
+ * If a read operation is already in progress on this channel
+ * @throws NotYetConnectedException
+ * If this channel is not yet connected
+ * @throws ShutdownChannelGroupException
+ * If the channel group has terminated
+ */
+ public abstract <A> void read(ByteBuffer[] dsts,
+ int offset,
+ int length,
+ long timeout,
+ TimeUnit unit,
+ A attachment,
+ CompletionHandler<Long,? super A> handler);
+
+ /**
+ * Writes a sequence of bytes to this channel from the given buffer.
+ *
+ * <p> This method initiates an asynchronous write operation to write a
+ * sequence of bytes to this channel from the given buffer. The {@code
+ * handler} parameter is a completion handler that is invoked when the write
+ * operation completes (or fails). The result passed to the completion
+ * handler is the number of bytes written.
+ *
+ * <p> If a timeout is specified and the timeout elapses before the operation
+ * completes then it completes with the exception {@link
+ * InterruptedByTimeoutException}. Where a timeout occurs, and the
+ * implementation cannot guarantee that bytes have not been written, or will
+ * not be written to the channel from the given buffer, then further attempts
+ * to write to the channel will cause an unspecific runtime exception to be
+ * thrown.
+ *
+ * <p> Otherwise this method works in the same manner as the {@link
+ * AsynchronousByteChannel#write(ByteBuffer,Object,CompletionHandler)}
+ * method.
+ *
+ * @param <A>
+ * The type of the attachment
+ * @param src
+ * The buffer from which bytes are to be retrieved
+ * @param timeout
+ * The maximum time for the I/O operation to complete
+ * @param unit
+ * The time unit of the {@code timeout} argument
+ * @param attachment
+ * The object to attach to the I/O operation; can be {@code null}
+ * @param handler
+ * The handler for consuming the result
+ *
+ * @throws WritePendingException
+ * If a write operation is already in progress on this channel
+ * @throws NotYetConnectedException
+ * If this channel is not yet connected
+ * @throws ShutdownChannelGroupException
+ * If the channel group has terminated
+ */
+ public abstract <A> void write(ByteBuffer src,
+ long timeout,
+ TimeUnit unit,
+ A attachment,
+ CompletionHandler<Integer,? super A> handler);
+
+ /**
+ * @throws WritePendingException {@inheritDoc}
+ * @throws NotYetConnectedException
+ * If this channel is not yet connected
+ * @throws ShutdownChannelGroupException
+ * If the channel group has terminated
+ */
+ @Override
+ public final <A> void write(ByteBuffer src,
+ A attachment,
+ CompletionHandler<Integer,? super A> handler)
+
+ {
+ write(src, 0L, TimeUnit.MILLISECONDS, attachment, handler);
+ }
+
+ /**
+ * @throws WritePendingException {@inheritDoc}
+ * @throws NotYetConnectedException
+ * If this channel is not yet connected
+ */
+ @Override
+ public abstract Future<Integer> write(ByteBuffer src);
+
+ /**
+ * Writes a sequence of bytes to this channel from a subsequence of the given
+ * buffers. This operation, sometimes called a <em>gathering write</em>, is
+ * often useful when implementing network protocols that group data into
+ * segments consisting of one or more fixed-length headers followed by a
+ * variable-length body. The {@code handler} parameter is a completion
+ * handler that is invoked when the write operation completes (or fails).
+ * The result passed to the completion handler is the number of bytes written.
+ *
+ * <p> This method initiates a write of up to <i>r</i> bytes to this channel,
+ * where <i>r</i> is the total number of bytes remaining in the specified
+ * subsequence of the given buffer array, that is,
+ *
+ * <blockquote><pre>
+ * srcs[offset].remaining()
+ * + srcs[offset+1].remaining()
+ * + ... + srcs[offset+length-1].remaining()</pre></blockquote>
+ *
+ * at the moment that the write is attempted.
+ *
+ * <p> Suppose that a byte sequence of length <i>n</i> is written, where
+ * <tt>0</tt> <tt><</tt> <i>n</i> <tt><=</tt> <i>r</i>.
+ * Up to the first <tt>srcs[offset].remaining()</tt> bytes of this sequence
+ * are written from buffer <tt>srcs[offset]</tt>, up to the next
+ * <tt>srcs[offset+1].remaining()</tt> bytes are written from buffer
+ * <tt>srcs[offset+1]</tt>, and so forth, until the entire byte sequence is
+ * written. As many bytes as possible are written from each buffer, hence
+ * the final position of each updated buffer, except the last updated
+ * buffer, is guaranteed to be equal to that buffer's limit. The underlying
+ * operating system may impose a limit on the number of buffers that may be
+ * used in an I/O operation. Where the number of buffers (with bytes
+ * remaining), exceeds this limit, then the I/O operation is performed with
+ * the maximum number of buffers allowed by the operating system.
+ *
+ * <p> If a timeout is specified and the timeout elapses before the operation
+ * completes then it completes with the exception {@link
+ * InterruptedByTimeoutException}. Where a timeout occurs, and the
+ * implementation cannot guarantee that bytes have not been written, or will
+ * not be written to the channel from the given buffers, then further attempts
+ * to write to the channel will cause an unspecific runtime exception to be
+ * thrown.
+ *
+ * @param <A>
+ * The type of the attachment
+ * @param srcs
+ * The buffers from which bytes are to be retrieved
+ * @param offset
+ * The offset within the buffer array of the first buffer from which
+ * bytes are to be retrieved; must be non-negative and no larger
+ * than {@code srcs.length}
+ * @param length
+ * The maximum number of buffers to be accessed; must be non-negative
+ * and no larger than {@code srcs.length - offset}
+ * @param timeout
+ * The maximum time for the I/O operation to complete
+ * @param unit
+ * The time unit of the {@code timeout} argument
+ * @param attachment
+ * The object to attach to the I/O operation; can be {@code null}
+ * @param handler
+ * The handler for consuming the result
+ *
+ * @throws IndexOutOfBoundsException
+ * If the pre-conditions for the {@code offset} and {@code length}
+ * parameter aren't met
+ * @throws WritePendingException
+ * If a write operation is already in progress on this channel
+ * @throws NotYetConnectedException
+ * If this channel is not yet connected
+ * @throws ShutdownChannelGroupException
+ * If the channel group has terminated
+ */
+ public abstract <A> void write(ByteBuffer[] srcs,
+ int offset,
+ int length,
+ long timeout,
+ TimeUnit unit,
+ A attachment,
+ CompletionHandler<Long,? super A> handler);
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * If there is a security manager set, its {@code checkConnect} method is
+ * called with the local address and {@code -1} as its arguments to see
+ * if the operation is allowed. If the operation is not allowed,
+ * a {@code SocketAddress} representing the
+ * {@link java.net.InetAddress#getLoopbackAddress loopback} address and the
+ * local port of the channel's socket is returned.
+ *
+ * @return The {@code SocketAddress} that the socket is bound to, or the
+ * {@code SocketAddress} representing the loopback address if
+ * denied by the security manager, or {@code null} if the
+ * channel's socket is not bound
+ *
+ * @throws ClosedChannelException {@inheritDoc}
+ * @throws IOException {@inheritDoc}
+ */
+ public abstract SocketAddress getLocalAddress() throws IOException;
+}
diff --git a/java/nio/channels/ByteChannel.java b/java/nio/channels/ByteChannel.java
new file mode 100644
index 0000000..85d5275
--- /dev/null
+++ b/java/nio/channels/ByteChannel.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+import java.io.IOException;
+
+
+/**
+ * A channel that can read and write bytes. This interface simply unifies
+ * {@link ReadableByteChannel} and {@link WritableByteChannel}; it does not
+ * specify any new operations.
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public interface ByteChannel
+ extends ReadableByteChannel, WritableByteChannel
+{
+
+}
diff --git a/java/nio/channels/CancelledKeyException.java b/java/nio/channels/CancelledKeyException.java
new file mode 100644
index 0000000..b5306f0
--- /dev/null
+++ b/java/nio/channels/CancelledKeyException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to use
+ * a selection key that is no longer valid.
+ *
+ * @since 1.4
+ */
+
+public class CancelledKeyException
+ extends IllegalStateException
+{
+
+ private static final long serialVersionUID = -8438032138028814268L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public CancelledKeyException() { }
+
+}
diff --git a/java/nio/channels/Channel.java b/java/nio/channels/Channel.java
new file mode 100644
index 0000000..663d0e0
--- /dev/null
+++ b/java/nio/channels/Channel.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+import java.io.IOException;
+import java.io.Closeable;
+
+
+/**
+ * A nexus for I/O operations.
+ *
+ * <p> A channel represents an open connection to an entity such as a hardware
+ * device, a file, a network socket, or a program component that is capable of
+ * performing one or more distinct I/O operations, for example reading or
+ * writing.
+ *
+ * <p> A channel is either open or closed. A channel is open upon creation,
+ * and once closed it remains closed. Once a channel is closed, any attempt to
+ * invoke an I/O operation upon it will cause a {@link ClosedChannelException}
+ * to be thrown. Whether or not a channel is open may be tested by invoking
+ * its {@link #isOpen isOpen} method.
+ *
+ * <p> Channels are, in general, intended to be safe for multithreaded access
+ * as described in the specifications of the interfaces and classes that extend
+ * and implement this interface.
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public interface Channel extends Closeable {
+
+ /**
+ * Tells whether or not this channel is open.
+ *
+ * @return <tt>true</tt> if, and only if, this channel is open
+ */
+ public boolean isOpen();
+
+ /**
+ * Closes this channel.
+ *
+ * <p> After a channel is closed, any further attempt to invoke I/O
+ * operations upon it will cause a {@link ClosedChannelException} to be
+ * thrown.
+ *
+ * <p> If this channel is already closed then invoking this method has no
+ * effect.
+ *
+ * <p> This method may be invoked at any time. If some other thread has
+ * already invoked it, however, then another invocation will block until
+ * the first invocation is complete, after which it will return without
+ * effect. </p>
+ *
+ * @throws IOException If an I/O error occurs
+ */
+ public void close() throws IOException;
+
+}
diff --git a/java/nio/channels/Channels.java b/java/nio/channels/Channels.java
new file mode 100644
index 0000000..1d11262
--- /dev/null
+++ b/java/nio/channels/Channels.java
@@ -0,0 +1,610 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.UnsupportedCharsetException;
+import java.nio.channels.spi.AbstractInterruptibleChannel;
+import java.util.concurrent.ExecutionException;
+import sun.nio.ch.ChannelInputStream;
+import sun.nio.cs.StreamDecoder;
+import sun.nio.cs.StreamEncoder;
+
+
+/**
+ * Utility methods for channels and streams.
+ *
+ * <p> This class defines static methods that support the interoperation of the
+ * stream classes of the <tt>{@link java.io}</tt> package with the channel
+ * classes of this package. </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author Mike McCloskey
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public final class Channels {
+
+ private Channels() { } // No instantiation
+
+ private static void checkNotNull(Object o, String name) {
+ if (o == null)
+ throw new NullPointerException("\"" + name + "\" is null!");
+ }
+
+ /**
+ * Write all remaining bytes in buffer to the given channel.
+ * If the channel is selectable then it must be configured blocking.
+ */
+ private static void writeFullyImpl(WritableByteChannel ch, ByteBuffer bb)
+ throws IOException
+ {
+ while (bb.remaining() > 0) {
+ int n = ch.write(bb);
+ if (n <= 0)
+ throw new RuntimeException("no bytes written");
+ }
+ }
+
+ /**
+ * Write all remaining bytes in buffer to the given channel.
+ *
+ * @throws IllegalBlockingModeException
+ * If the channel is selectable and configured non-blocking.
+ */
+ private static void writeFully(WritableByteChannel ch, ByteBuffer bb)
+ throws IOException
+ {
+ if (ch instanceof SelectableChannel) {
+ SelectableChannel sc = (SelectableChannel)ch;
+ synchronized (sc.blockingLock()) {
+ if (!sc.isBlocking())
+ throw new IllegalBlockingModeException();
+ writeFullyImpl(ch, bb);
+ }
+ } else {
+ writeFullyImpl(ch, bb);
+ }
+ }
+
+ // -- Byte streams from channels --
+
+ /**
+ * Constructs a stream that reads bytes from the given channel.
+ *
+ * <p> The <tt>read</tt> methods of the resulting stream will throw an
+ * {@link IllegalBlockingModeException} if invoked while the underlying
+ * channel is in non-blocking mode. The stream will not be buffered, and
+ * it will not support the {@link InputStream#mark mark} or {@link
+ * InputStream#reset reset} methods. The stream will be safe for access by
+ * multiple concurrent threads. Closing the stream will in turn cause the
+ * channel to be closed. </p>
+ *
+ * @param ch
+ * The channel from which bytes will be read
+ *
+ * @return A new input stream
+ */
+ public static InputStream newInputStream(ReadableByteChannel ch) {
+ checkNotNull(ch, "ch");
+ return new sun.nio.ch.ChannelInputStream(ch);
+ }
+
+ /**
+ * Constructs a stream that writes bytes to the given channel.
+ *
+ * <p> The <tt>write</tt> methods of the resulting stream will throw an
+ * {@link IllegalBlockingModeException} if invoked while the underlying
+ * channel is in non-blocking mode. The stream will not be buffered. The
+ * stream will be safe for access by multiple concurrent threads. Closing
+ * the stream will in turn cause the channel to be closed. </p>
+ *
+ * @param ch
+ * The channel to which bytes will be written
+ *
+ * @return A new output stream
+ */
+ public static OutputStream newOutputStream(final WritableByteChannel ch) {
+ checkNotNull(ch, "ch");
+
+ return new OutputStream() {
+
+ private ByteBuffer bb = null;
+ private byte[] bs = null; // Invoker's previous array
+ private byte[] b1 = null;
+
+ public synchronized void write(int b) throws IOException {
+ if (b1 == null)
+ b1 = new byte[1];
+ b1[0] = (byte)b;
+ this.write(b1);
+ }
+
+ public synchronized void write(byte[] bs, int off, int len)
+ throws IOException
+ {
+ if ((off < 0) || (off > bs.length) || (len < 0) ||
+ ((off + len) > bs.length) || ((off + len) < 0)) {
+ throw new IndexOutOfBoundsException();
+ } else if (len == 0) {
+ return;
+ }
+ ByteBuffer bb = ((this.bs == bs)
+ ? this.bb
+ : ByteBuffer.wrap(bs));
+ bb.limit(Math.min(off + len, bb.capacity()));
+ bb.position(off);
+ this.bb = bb;
+ this.bs = bs;
+ Channels.writeFully(ch, bb);
+ }
+
+ public void close() throws IOException {
+ ch.close();
+ }
+
+ };
+ }
+
+ /**
+ * Constructs a stream that reads bytes from the given channel.
+ *
+ * <p> The stream will not be buffered, and it will not support the {@link
+ * InputStream#mark mark} or {@link InputStream#reset reset} methods. The
+ * stream will be safe for access by multiple concurrent threads. Closing
+ * the stream will in turn cause the channel to be closed. </p>
+ *
+ * @param ch
+ * The channel from which bytes will be read
+ *
+ * @return A new input stream
+ *
+ * @since 1.7
+ */
+ public static InputStream newInputStream(final AsynchronousByteChannel ch) {
+ checkNotNull(ch, "ch");
+ return new InputStream() {
+
+ private ByteBuffer bb = null;
+ private byte[] bs = null; // Invoker's previous array
+ private byte[] b1 = null;
+
+ @Override
+ public synchronized int read() throws IOException {
+ if (b1 == null)
+ b1 = new byte[1];
+ int n = this.read(b1);
+ if (n == 1)
+ return b1[0] & 0xff;
+ return -1;
+ }
+
+ @Override
+ public synchronized int read(byte[] bs, int off, int len)
+ throws IOException
+ {
+ if ((off < 0) || (off > bs.length) || (len < 0) ||
+ ((off + len) > bs.length) || ((off + len) < 0)) {
+ throw new IndexOutOfBoundsException();
+ } else if (len == 0)
+ return 0;
+
+ ByteBuffer bb = ((this.bs == bs)
+ ? this.bb
+ : ByteBuffer.wrap(bs));
+ bb.position(off);
+ bb.limit(Math.min(off + len, bb.capacity()));
+ this.bb = bb;
+ this.bs = bs;
+
+ boolean interrupted = false;
+ try {
+ for (;;) {
+ try {
+ return ch.read(bb).get();
+ } catch (ExecutionException ee) {
+ throw new IOException(ee.getCause());
+ } catch (InterruptedException ie) {
+ interrupted = true;
+ }
+ }
+ } finally {
+ if (interrupted)
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ ch.close();
+ }
+ };
+ }
+
+ /**
+ * Constructs a stream that writes bytes to the given channel.
+ *
+ * <p> The stream will not be buffered. The stream will be safe for access
+ * by multiple concurrent threads. Closing the stream will in turn cause
+ * the channel to be closed. </p>
+ *
+ * @param ch
+ * The channel to which bytes will be written
+ *
+ * @return A new output stream
+ *
+ * @since 1.7
+ */
+ public static OutputStream newOutputStream(final AsynchronousByteChannel ch) {
+ checkNotNull(ch, "ch");
+ return new OutputStream() {
+
+ private ByteBuffer bb = null;
+ private byte[] bs = null; // Invoker's previous array
+ private byte[] b1 = null;
+
+ @Override
+ public synchronized void write(int b) throws IOException {
+ if (b1 == null)
+ b1 = new byte[1];
+ b1[0] = (byte)b;
+ this.write(b1);
+ }
+
+ @Override
+ public synchronized void write(byte[] bs, int off, int len)
+ throws IOException
+ {
+ if ((off < 0) || (off > bs.length) || (len < 0) ||
+ ((off + len) > bs.length) || ((off + len) < 0)) {
+ throw new IndexOutOfBoundsException();
+ } else if (len == 0) {
+ return;
+ }
+ ByteBuffer bb = ((this.bs == bs)
+ ? this.bb
+ : ByteBuffer.wrap(bs));
+ bb.limit(Math.min(off + len, bb.capacity()));
+ bb.position(off);
+ this.bb = bb;
+ this.bs = bs;
+
+ boolean interrupted = false;
+ try {
+ while (bb.remaining() > 0) {
+ try {
+ ch.write(bb).get();
+ } catch (ExecutionException ee) {
+ throw new IOException(ee.getCause());
+ } catch (InterruptedException ie) {
+ interrupted = true;
+ }
+ }
+ } finally {
+ if (interrupted)
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ ch.close();
+ }
+ };
+ }
+
+
+ // -- Channels from streams --
+
+ /**
+ * Constructs a channel that reads bytes from the given stream.
+ *
+ * <p> The resulting channel will not be buffered; it will simply redirect
+ * its I/O operations to the given stream. Closing the channel will in
+ * turn cause the stream to be closed. </p>
+ *
+ * @param in
+ * The stream from which bytes are to be read
+ *
+ * @return A new readable byte channel
+ */
+ public static ReadableByteChannel newChannel(final InputStream in) {
+ checkNotNull(in, "in");
+
+ if (in instanceof FileInputStream &&
+ FileInputStream.class.equals(in.getClass())) {
+ return ((FileInputStream)in).getChannel();
+ }
+
+ return new ReadableByteChannelImpl(in);
+ }
+
+ private static class ReadableByteChannelImpl
+ extends AbstractInterruptibleChannel // Not really interruptible
+ implements ReadableByteChannel
+ {
+ InputStream in;
+ private static final int TRANSFER_SIZE = 8192;
+ private byte buf[] = new byte[0];
+ private boolean open = true;
+ private Object readLock = new Object();
+
+ ReadableByteChannelImpl(InputStream in) {
+ this.in = in;
+ }
+
+ public int read(ByteBuffer dst) throws IOException {
+ int len = dst.remaining();
+ int totalRead = 0;
+ int bytesRead = 0;
+ synchronized (readLock) {
+ while (totalRead < len) {
+ int bytesToRead = Math.min((len - totalRead),
+ TRANSFER_SIZE);
+ if (buf.length < bytesToRead)
+ buf = new byte[bytesToRead];
+ if ((totalRead > 0) && !(in.available() > 0))
+ break; // block at most once
+ try {
+ begin();
+ bytesRead = in.read(buf, 0, bytesToRead);
+ } finally {
+ end(bytesRead > 0);
+ }
+ if (bytesRead < 0)
+ break;
+ else
+ totalRead += bytesRead;
+ dst.put(buf, 0, bytesRead);
+ }
+ if ((bytesRead < 0) && (totalRead == 0))
+ return -1;
+
+ return totalRead;
+ }
+ }
+
+ protected void implCloseChannel() throws IOException {
+ in.close();
+ open = false;
+ }
+ }
+
+
+ /**
+ * Constructs a channel that writes bytes to the given stream.
+ *
+ * <p> The resulting channel will not be buffered; it will simply redirect
+ * its I/O operations to the given stream. Closing the channel will in
+ * turn cause the stream to be closed. </p>
+ *
+ * @param out
+ * The stream to which bytes are to be written
+ *
+ * @return A new writable byte channel
+ */
+ public static WritableByteChannel newChannel(final OutputStream out) {
+ checkNotNull(out, "out");
+ return new WritableByteChannelImpl(out);
+ }
+
+ private static class WritableByteChannelImpl
+ extends AbstractInterruptibleChannel // Not really interruptible
+ implements WritableByteChannel
+ {
+ OutputStream out;
+ private static final int TRANSFER_SIZE = 8192;
+ private byte buf[] = new byte[0];
+ private boolean open = true;
+ private Object writeLock = new Object();
+
+ WritableByteChannelImpl(OutputStream out) {
+ this.out = out;
+ }
+
+ public int write(ByteBuffer src) throws IOException {
+ int len = src.remaining();
+ int totalWritten = 0;
+ synchronized (writeLock) {
+ while (totalWritten < len) {
+ int bytesToWrite = Math.min((len - totalWritten),
+ TRANSFER_SIZE);
+ if (buf.length < bytesToWrite)
+ buf = new byte[bytesToWrite];
+ src.get(buf, 0, bytesToWrite);
+ try {
+ begin();
+ out.write(buf, 0, bytesToWrite);
+ } finally {
+ end(bytesToWrite > 0);
+ }
+ totalWritten += bytesToWrite;
+ }
+ return totalWritten;
+ }
+ }
+
+ protected void implCloseChannel() throws IOException {
+ out.close();
+ open = false;
+ }
+ }
+
+
+ // -- Character streams from channels --
+
+ /**
+ * Constructs a reader that decodes bytes from the given channel using the
+ * given decoder.
+ *
+ * <p> The resulting stream will contain an internal input buffer of at
+ * least <tt>minBufferCap</tt> bytes. The stream's <tt>read</tt> methods
+ * will, as needed, fill the buffer by reading bytes from the underlying
+ * channel; if the channel is in non-blocking mode when bytes are to be
+ * read then an {@link IllegalBlockingModeException} will be thrown. The
+ * resulting stream will not otherwise be buffered, and it will not support
+ * the {@link Reader#mark mark} or {@link Reader#reset reset} methods.
+ * Closing the stream will in turn cause the channel to be closed. </p>
+ *
+ * @param ch
+ * The channel from which bytes will be read
+ *
+ * @param dec
+ * The charset decoder to be used
+ *
+ * @param minBufferCap
+ * The minimum capacity of the internal byte buffer,
+ * or <tt>-1</tt> if an implementation-dependent
+ * default capacity is to be used
+ *
+ * @return A new reader
+ */
+ public static Reader newReader(ReadableByteChannel ch,
+ CharsetDecoder dec,
+ int minBufferCap)
+ {
+ checkNotNull(ch, "ch");
+ return StreamDecoder.forDecoder(ch, dec.reset(), minBufferCap);
+ }
+
+ /**
+ * Constructs a reader that decodes bytes from the given channel according
+ * to the named charset.
+ *
+ * <p> An invocation of this method of the form
+ *
+ * <blockquote><pre>
+ * Channels.newReader(ch, csname)</pre></blockquote>
+ *
+ * behaves in exactly the same way as the expression
+ *
+ * <blockquote><pre>
+ * Channels.newReader(ch,
+ * Charset.forName(csName)
+ * .newDecoder(),
+ * -1);</pre></blockquote>
+ *
+ * @param ch
+ * The channel from which bytes will be read
+ *
+ * @param csName
+ * The name of the charset to be used
+ *
+ * @return A new reader
+ *
+ * @throws UnsupportedCharsetException
+ * If no support for the named charset is available
+ * in this instance of the Java virtual machine
+ */
+ public static Reader newReader(ReadableByteChannel ch,
+ String csName)
+ {
+ checkNotNull(csName, "csName");
+ return newReader(ch, Charset.forName(csName).newDecoder(), -1);
+ }
+
+ /**
+ * Constructs a writer that encodes characters using the given encoder and
+ * writes the resulting bytes to the given channel.
+ *
+ * <p> The resulting stream will contain an internal output buffer of at
+ * least <tt>minBufferCap</tt> bytes. The stream's <tt>write</tt> methods
+ * will, as needed, flush the buffer by writing bytes to the underlying
+ * channel; if the channel is in non-blocking mode when bytes are to be
+ * written then an {@link IllegalBlockingModeException} will be thrown.
+ * The resulting stream will not otherwise be buffered. Closing the stream
+ * will in turn cause the channel to be closed. </p>
+ *
+ * @param ch
+ * The channel to which bytes will be written
+ *
+ * @param enc
+ * The charset encoder to be used
+ *
+ * @param minBufferCap
+ * The minimum capacity of the internal byte buffer,
+ * or <tt>-1</tt> if an implementation-dependent
+ * default capacity is to be used
+ *
+ * @return A new writer
+ */
+ public static Writer newWriter(final WritableByteChannel ch,
+ final CharsetEncoder enc,
+ final int minBufferCap)
+ {
+ checkNotNull(ch, "ch");
+ return StreamEncoder.forEncoder(ch, enc.reset(), minBufferCap);
+ }
+
+ /**
+ * Constructs a writer that encodes characters according to the named
+ * charset and writes the resulting bytes to the given channel.
+ *
+ * <p> An invocation of this method of the form
+ *
+ * <blockquote><pre>
+ * Channels.newWriter(ch, csname)</pre></blockquote>
+ *
+ * behaves in exactly the same way as the expression
+ *
+ * <blockquote><pre>
+ * Channels.newWriter(ch,
+ * Charset.forName(csName)
+ * .newEncoder(),
+ * -1);</pre></blockquote>
+ *
+ * @param ch
+ * The channel to which bytes will be written
+ *
+ * @param csName
+ * The name of the charset to be used
+ *
+ * @return A new writer
+ *
+ * @throws UnsupportedCharsetException
+ * If no support for the named charset is available
+ * in this instance of the Java virtual machine
+ */
+ public static Writer newWriter(WritableByteChannel ch,
+ String csName)
+ {
+ checkNotNull(csName, "csName");
+ return newWriter(ch, Charset.forName(csName).newEncoder(), -1);
+ }
+}
diff --git a/java/nio/channels/ClosedByInterruptException.java b/java/nio/channels/ClosedByInterruptException.java
new file mode 100644
index 0000000..848ee61
--- /dev/null
+++ b/java/nio/channels/ClosedByInterruptException.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Checked exception received by a thread when another thread interrupts it
+ * while it is blocked in an I/O operation upon a channel. Before this
+ * exception is thrown the channel will have been closed and the interrupt
+ * status of the previously-blocked thread will have been set.
+ *
+ * @since 1.4
+ */
+
+public class ClosedByInterruptException
+ extends AsynchronousCloseException
+{
+
+ private static final long serialVersionUID = -4488191543534286750L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public ClosedByInterruptException() { }
+
+}
diff --git a/java/nio/channels/ClosedChannelException.java b/java/nio/channels/ClosedChannelException.java
new file mode 100644
index 0000000..a9a2277
--- /dev/null
+++ b/java/nio/channels/ClosedChannelException.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Checked exception thrown when an attempt is made to invoke or complete an
+ * I/O operation upon channel that is closed, or at least closed to that
+ * operation. That this exception is thrown does not necessarily imply that
+ * the channel is completely closed. A socket channel whose write half has
+ * been shut down, for example, may still be open for reading.
+ *
+ * @since 1.4
+ */
+
+public class ClosedChannelException
+ extends java.io.IOException
+{
+
+ private static final long serialVersionUID = 882777185433553857L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public ClosedChannelException() { }
+
+}
diff --git a/java/nio/channels/ClosedSelectorException.java b/java/nio/channels/ClosedSelectorException.java
new file mode 100644
index 0000000..f3168c2
--- /dev/null
+++ b/java/nio/channels/ClosedSelectorException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to invoke an I/O
+ * operation upon a closed selector.
+ *
+ * @since 1.4
+ */
+
+public class ClosedSelectorException
+ extends IllegalStateException
+{
+
+ private static final long serialVersionUID = 6466297122317847835L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public ClosedSelectorException() { }
+
+}
diff --git a/java/nio/channels/CompletionHandler.java b/java/nio/channels/CompletionHandler.java
new file mode 100644
index 0000000..2574dbf
--- /dev/null
+++ b/java/nio/channels/CompletionHandler.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+/**
+ * A handler for consuming the result of an asynchronous I/O operation.
+ *
+ * <p> The asynchronous channels defined in this package allow a completion
+ * handler to be specified to consume the result of an asynchronous operation.
+ * The {@link #completed completed} method is invoked when the I/O operation
+ * completes successfully. The {@link #failed failed} method is invoked if the
+ * I/O operations fails. The implementations of these methods should complete
+ * in a timely manner so as to avoid keeping the invoking thread from dispatching
+ * to other completion handlers.
+ *
+ * @param <V> The result type of the I/O operation
+ * @param <A> The type of the object attached to the I/O operation
+ *
+ * @since 1.7
+ */
+
+public interface CompletionHandler<V,A> {
+
+ /**
+ * Invoked when an operation has completed.
+ *
+ * @param result
+ * The result of the I/O operation.
+ * @param attachment
+ * The object attached to the I/O operation when it was initiated.
+ */
+ void completed(V result, A attachment);
+
+ /**
+ * Invoked when an operation fails.
+ *
+ * @param exc
+ * The exception to indicate why the I/O operation failed
+ * @param attachment
+ * The object attached to the I/O operation when it was initiated.
+ */
+ void failed(Throwable exc, A attachment);
+}
diff --git a/java/nio/channels/ConnectionPendingException.java b/java/nio/channels/ConnectionPendingException.java
new file mode 100644
index 0000000..c43927e
--- /dev/null
+++ b/java/nio/channels/ConnectionPendingException.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to connect a {@link
+ * SocketChannel} for which a non-blocking connection operation is already in
+ * progress.
+ *
+ * @since 1.4
+ */
+
+public class ConnectionPendingException
+ extends IllegalStateException
+{
+
+ private static final long serialVersionUID = 2008393366501760879L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public ConnectionPendingException() { }
+
+}
diff --git a/java/nio/channels/DatagramChannel.java b/java/nio/channels/DatagramChannel.java
new file mode 100644
index 0000000..b85c98c
--- /dev/null
+++ b/java/nio/channels/DatagramChannel.java
@@ -0,0 +1,592 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+import java.io.IOException;
+import java.net.ProtocolFamily;
+import java.net.DatagramSocket;
+import java.net.SocketOption;
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.spi.AbstractSelectableChannel;
+import java.nio.channels.spi.SelectorProvider;
+
+/**
+ * A selectable channel for datagram-oriented sockets.
+ *
+ * <p> A datagram channel is created by invoking one of the {@link #open open} methods
+ * of this class. It is not possible to create a channel for an arbitrary,
+ * pre-existing datagram socket. A newly-created datagram channel is open but not
+ * connected. A datagram channel need not be connected in order for the {@link #send
+ * send} and {@link #receive receive} methods to be used. A datagram channel may be
+ * connected, by invoking its {@link #connect connect} method, in order to
+ * avoid the overhead of the security checks are otherwise performed as part of
+ * every send and receive operation. A datagram channel must be connected in
+ * order to use the {@link #read(java.nio.ByteBuffer) read} and {@link
+ * #write(java.nio.ByteBuffer) write} methods, since those methods do not
+ * accept or return socket addresses.
+ *
+ * <p> Once connected, a datagram channel remains connected until it is
+ * disconnected or closed. Whether or not a datagram channel is connected may
+ * be determined by invoking its {@link #isConnected isConnected} method.
+ *
+ * <p> Socket options are configured using the {@link #setOption(SocketOption,Object)
+ * setOption} method. A datagram channel to an Internet Protocol socket supports
+ * the following options:
+ * <blockquote>
+ * <table border summary="Socket options">
+ * <tr>
+ * <th>Option Name</th>
+ * <th>Description</th>
+ * </tr>
+ * <tr>
+ * <td> {@link java.net.StandardSocketOptions#SO_SNDBUF SO_SNDBUF} </td>
+ * <td> The size of the socket send buffer </td>
+ * </tr>
+ * <tr>
+ * <td> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </td>
+ * <td> The size of the socket receive buffer </td>
+ * </tr>
+ * <tr>
+ * <td> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </td>
+ * <td> Re-use address </td>
+ * </tr>
+ * <tr>
+ * <td> {@link java.net.StandardSocketOptions#SO_BROADCAST SO_BROADCAST} </td>
+ * <td> Allow transmission of broadcast datagrams </td>
+ * </tr>
+ * <tr>
+ * <td> {@link java.net.StandardSocketOptions#IP_TOS IP_TOS} </td>
+ * <td> The Type of Service (ToS) octet in the Internet Protocol (IP) header </td>
+ * </tr>
+ * <tr>
+ * <td> {@link java.net.StandardSocketOptions#IP_MULTICAST_IF IP_MULTICAST_IF} </td>
+ * <td> The network interface for Internet Protocol (IP) multicast datagrams </td>
+ * </tr>
+ * <tr>
+ * <td> {@link java.net.StandardSocketOptions#IP_MULTICAST_TTL
+ * IP_MULTICAST_TTL} </td>
+ * <td> The <em>time-to-live</em> for Internet Protocol (IP) multicast
+ * datagrams </td>
+ * </tr>
+ * <tr>
+ * <td> {@link java.net.StandardSocketOptions#IP_MULTICAST_LOOP
+ * IP_MULTICAST_LOOP} </td>
+ * <td> Loopback for Internet Protocol (IP) multicast datagrams </td>
+ * </tr>
+ * </table>
+ * </blockquote>
+ * Additional (implementation specific) options may also be supported.
+ *
+ * <p> Datagram channels are safe for use by multiple concurrent threads. They
+ * support concurrent reading and writing, though at most one thread may be
+ * reading and at most one thread may be writing at any given time. </p>
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class DatagramChannel
+ extends AbstractSelectableChannel
+ implements ByteChannel, ScatteringByteChannel, GatheringByteChannel, MulticastChannel
+{
+
+ /**
+ * Initializes a new instance of this class.
+ *
+ * @param provider
+ * The provider that created this channel
+ */
+ protected DatagramChannel(SelectorProvider provider) {
+ super(provider);
+ }
+
+ /**
+ * Opens a datagram channel.
+ *
+ * <p> The new channel is created by invoking the {@link
+ * java.nio.channels.spi.SelectorProvider#openDatagramChannel()
+ * openDatagramChannel} method of the system-wide default {@link
+ * java.nio.channels.spi.SelectorProvider} object. The channel will not be
+ * connected.
+ *
+ * <p> The {@link ProtocolFamily ProtocolFamily} of the channel's socket
+ * is platform (and possibly configuration) dependent and therefore unspecified.
+ * The {@link #open(ProtocolFamily) open} allows the protocol family to be
+ * selected when opening a datagram channel, and should be used to open
+ * datagram channels that are intended for Internet Protocol multicasting.
+ *
+ * @return A new datagram channel
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ public static DatagramChannel open() throws IOException {
+ return SelectorProvider.provider().openDatagramChannel();
+ }
+
+ /**
+ * Opens a datagram channel.
+ *
+ * <p> The {@code family} parameter is used to specify the {@link
+ * ProtocolFamily}. If the datagram channel is to be used for IP multicasting
+ * then this should correspond to the address type of the multicast groups
+ * that this channel will join.
+ *
+ * <p> The new channel is created by invoking the {@link
+ * java.nio.channels.spi.SelectorProvider#openDatagramChannel(ProtocolFamily)
+ * openDatagramChannel} method of the system-wide default {@link
+ * java.nio.channels.spi.SelectorProvider} object. The channel will not be
+ * connected.
+ *
+ * @param family
+ * The protocol family
+ *
+ * @return A new datagram channel
+ *
+ * @throws UnsupportedOperationException
+ * If the specified protocol family is not supported. For example,
+ * suppose the parameter is specified as {@link
+ * java.net.StandardProtocolFamily#INET6 StandardProtocolFamily.INET6}
+ * but IPv6 is not enabled on the platform.
+ * @throws IOException
+ * If an I/O error occurs
+ *
+ * @since 1.7
+ */
+ public static DatagramChannel open(ProtocolFamily family) throws IOException {
+ return SelectorProvider.provider().openDatagramChannel(family);
+ }
+
+ /**
+ * Returns an operation set identifying this channel's supported
+ * operations.
+ *
+ * <p> Datagram channels support reading and writing, so this method
+ * returns <tt>(</tt>{@link SelectionKey#OP_READ} <tt>|</tt> {@link
+ * SelectionKey#OP_WRITE}<tt>)</tt>. </p>
+ *
+ * @return The valid-operation set
+ */
+ public final int validOps() {
+ return (SelectionKey.OP_READ
+ | SelectionKey.OP_WRITE);
+ }
+
+
+ // -- Socket-specific operations --
+
+ /**
+ * @throws AlreadyBoundException {@inheritDoc}
+ * @throws UnsupportedAddressTypeException {@inheritDoc}
+ * @throws ClosedChannelException {@inheritDoc}
+ * @throws IOException {@inheritDoc}
+ * @throws SecurityException
+ * If a security manager has been installed and its {@link
+ * SecurityManager#checkListen checkListen} method denies the
+ * operation
+ *
+ * @since 1.7
+ */
+ public abstract DatagramChannel bind(SocketAddress local)
+ throws IOException;
+
+ /**
+ * @throws UnsupportedOperationException {@inheritDoc}
+ * @throws IllegalArgumentException {@inheritDoc}
+ * @throws ClosedChannelException {@inheritDoc}
+ * @throws IOException {@inheritDoc}
+ *
+ * @since 1.7
+ */
+ public abstract <T> DatagramChannel setOption(SocketOption<T> name, T value)
+ throws IOException;
+
+ /**
+ * Retrieves a datagram socket associated with this channel.
+ *
+ * <p> The returned object will not declare any public methods that are not
+ * declared in the {@link java.net.DatagramSocket} class. </p>
+ *
+ * @return A datagram socket associated with this channel
+ */
+ public abstract DatagramSocket socket();
+
+ /**
+ * Tells whether or not this channel's socket is connected.
+ *
+ * @return {@code true} if, and only if, this channel's socket
+ * is {@link #isOpen open} and connected
+ */
+ public abstract boolean isConnected();
+
+ /**
+ * Connects this channel's socket.
+ *
+ * <p> The channel's socket is configured so that it only receives
+ * datagrams from, and sends datagrams to, the given remote <i>peer</i>
+ * address. Once connected, datagrams may not be received from or sent to
+ * any other address. A datagram socket remains connected until it is
+ * explicitly disconnected or until it is closed.
+ *
+ * <p> This method performs exactly the same security checks as the {@link
+ * java.net.DatagramSocket#connect connect} method of the {@link
+ * java.net.DatagramSocket} class. That is, if a security manager has been
+ * installed then this method verifies that its {@link
+ * java.lang.SecurityManager#checkAccept checkAccept} and {@link
+ * java.lang.SecurityManager#checkConnect checkConnect} methods permit
+ * datagrams to be received from and sent to, respectively, the given
+ * remote address.
+ *
+ * <p> This method may be invoked at any time. It will not have any effect
+ * on read or write operations that are already in progress at the moment
+ * that it is invoked. If this channel's socket is not bound then this method
+ * will first cause the socket to be bound to an address that is assigned
+ * automatically, as if invoking the {@link #bind bind} method with a
+ * parameter of {@code null}. </p>
+ *
+ * @param remote
+ * The remote address to which this channel is to be connected
+ *
+ * @return This datagram channel
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ *
+ * @throws AsynchronousCloseException
+ * If another thread closes this channel
+ * while the connect operation is in progress
+ *
+ * @throws ClosedByInterruptException
+ * If another thread interrupts the current thread
+ * while the connect operation is in progress, thereby
+ * closing the channel and setting the current thread's
+ * interrupt status
+ *
+ * @throws SecurityException
+ * If a security manager has been installed
+ * and it does not permit access to the given remote address
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public abstract DatagramChannel connect(SocketAddress remote)
+ throws IOException;
+
+ /**
+ * Disconnects this channel's socket.
+ *
+ * <p> The channel's socket is configured so that it can receive datagrams
+ * from, and sends datagrams to, any remote address so long as the security
+ * manager, if installed, permits it.
+ *
+ * <p> This method may be invoked at any time. It will not have any effect
+ * on read or write operations that are already in progress at the moment
+ * that it is invoked.
+ *
+ * <p> If this channel's socket is not connected, or if the channel is
+ * closed, then invoking this method has no effect. </p>
+ *
+ * @return This datagram channel
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public abstract DatagramChannel disconnect() throws IOException;
+
+ /**
+ * Returns the remote address to which this channel's socket is connected.
+ *
+ * @return The remote address; {@code null} if the channel's socket is not
+ * connected
+ *
+ * @throws ClosedChannelException
+ * If the channel is closed
+ * @throws IOException
+ * If an I/O error occurs
+ *
+ * @since 1.7
+ */
+ public abstract SocketAddress getRemoteAddress() throws IOException;
+
+ /**
+ * Receives a datagram via this channel.
+ *
+ * <p> If a datagram is immediately available, or if this channel is in
+ * blocking mode and one eventually becomes available, then the datagram is
+ * copied into the given byte buffer and its source address is returned.
+ * If this channel is in non-blocking mode and a datagram is not
+ * immediately available then this method immediately returns
+ * <tt>null</tt>.
+ *
+ * <p> The datagram is transferred into the given byte buffer starting at
+ * its current position, as if by a regular {@link
+ * ReadableByteChannel#read(java.nio.ByteBuffer) read} operation. If there
+ * are fewer bytes remaining in the buffer than are required to hold the
+ * datagram then the remainder of the datagram is silently discarded.
+ *
+ * <p> This method performs exactly the same security checks as the {@link
+ * java.net.DatagramSocket#receive receive} method of the {@link
+ * java.net.DatagramSocket} class. That is, if the socket is not connected
+ * to a specific remote address and a security manager has been installed
+ * then for each datagram received this method verifies that the source's
+ * address and port number are permitted by the security manager's {@link
+ * java.lang.SecurityManager#checkAccept checkAccept} method. The overhead
+ * of this security check can be avoided by first connecting the socket via
+ * the {@link #connect connect} method.
+ *
+ * <p> This method may be invoked at any time. If another thread has
+ * already initiated a read operation upon this channel, however, then an
+ * invocation of this method will block until the first operation is
+ * complete. If this channel's socket is not bound then this method will
+ * first cause the socket to be bound to an address that is assigned
+ * automatically, as if invoking the {@link #bind bind} method with a
+ * parameter of {@code null}. </p>
+ *
+ * @param dst
+ * The buffer into which the datagram is to be transferred
+ *
+ * @return The datagram's source address,
+ * or <tt>null</tt> if this channel is in non-blocking mode
+ * and no datagram was immediately available
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ *
+ * @throws AsynchronousCloseException
+ * If another thread closes this channel
+ * while the read operation is in progress
+ *
+ * @throws ClosedByInterruptException
+ * If another thread interrupts the current thread
+ * while the read operation is in progress, thereby
+ * closing the channel and setting the current thread's
+ * interrupt status
+ *
+ * @throws SecurityException
+ * If a security manager has been installed
+ * and it does not permit datagrams to be accepted
+ * from the datagram's sender
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public abstract SocketAddress receive(ByteBuffer dst) throws IOException;
+
+ /**
+ * Sends a datagram via this channel.
+ *
+ * <p> If this channel is in non-blocking mode and there is sufficient room
+ * in the underlying output buffer, or if this channel is in blocking mode
+ * and sufficient room becomes available, then the remaining bytes in the
+ * given buffer are transmitted as a single datagram to the given target
+ * address.
+ *
+ * <p> The datagram is transferred from the byte buffer as if by a regular
+ * {@link WritableByteChannel#write(java.nio.ByteBuffer) write} operation.
+ *
+ * <p> This method performs exactly the same security checks as the {@link
+ * java.net.DatagramSocket#send send} method of the {@link
+ * java.net.DatagramSocket} class. That is, if the socket is not connected
+ * to a specific remote address and a security manager has been installed
+ * then for each datagram sent this method verifies that the target address
+ * and port number are permitted by the security manager's {@link
+ * java.lang.SecurityManager#checkConnect checkConnect} method. The
+ * overhead of this security check can be avoided by first connecting the
+ * socket via the {@link #connect connect} method.
+ *
+ * <p> This method may be invoked at any time. If another thread has
+ * already initiated a write operation upon this channel, however, then an
+ * invocation of this method will block until the first operation is
+ * complete. If this channel's socket is not bound then this method will
+ * first cause the socket to be bound to an address that is assigned
+ * automatically, as if by invoking the {@link #bind bind} method with a
+ * parameter of {@code null}. </p>
+ *
+ * @param src
+ * The buffer containing the datagram to be sent
+ *
+ * @param target
+ * The address to which the datagram is to be sent
+ *
+ * @return The number of bytes sent, which will be either the number
+ * of bytes that were remaining in the source buffer when this
+ * method was invoked or, if this channel is non-blocking, may be
+ * zero if there was insufficient room for the datagram in the
+ * underlying output buffer
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ *
+ * @throws AsynchronousCloseException
+ * If another thread closes this channel
+ * while the read operation is in progress
+ *
+ * @throws ClosedByInterruptException
+ * If another thread interrupts the current thread
+ * while the read operation is in progress, thereby
+ * closing the channel and setting the current thread's
+ * interrupt status
+ *
+ * @throws SecurityException
+ * If a security manager has been installed
+ * and it does not permit datagrams to be sent
+ * to the given address
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public abstract int send(ByteBuffer src, SocketAddress target)
+ throws IOException;
+
+
+ // -- ByteChannel operations --
+
+ /**
+ * Reads a datagram from this channel.
+ *
+ * <p> This method may only be invoked if this channel's socket is
+ * connected, and it only accepts datagrams from the socket's peer. If
+ * there are more bytes in the datagram than remain in the given buffer
+ * then the remainder of the datagram is silently discarded. Otherwise
+ * this method behaves exactly as specified in the {@link
+ * ReadableByteChannel} interface. </p>
+ *
+ * @throws NotYetConnectedException
+ * If this channel's socket is not connected
+ */
+ public abstract int read(ByteBuffer dst) throws IOException;
+
+ /**
+ * Reads a datagram from this channel.
+ *
+ * <p> This method may only be invoked if this channel's socket is
+ * connected, and it only accepts datagrams from the socket's peer. If
+ * there are more bytes in the datagram than remain in the given buffers
+ * then the remainder of the datagram is silently discarded. Otherwise
+ * this method behaves exactly as specified in the {@link
+ * ScatteringByteChannel} interface. </p>
+ *
+ * @throws NotYetConnectedException
+ * If this channel's socket is not connected
+ */
+ public abstract long read(ByteBuffer[] dsts, int offset, int length)
+ throws IOException;
+
+ /**
+ * Reads a datagram from this channel.
+ *
+ * <p> This method may only be invoked if this channel's socket is
+ * connected, and it only accepts datagrams from the socket's peer. If
+ * there are more bytes in the datagram than remain in the given buffers
+ * then the remainder of the datagram is silently discarded. Otherwise
+ * this method behaves exactly as specified in the {@link
+ * ScatteringByteChannel} interface. </p>
+ *
+ * @throws NotYetConnectedException
+ * If this channel's socket is not connected
+ */
+ public final long read(ByteBuffer[] dsts) throws IOException {
+ return read(dsts, 0, dsts.length);
+ }
+
+ /**
+ * Writes a datagram to this channel.
+ *
+ * <p> This method may only be invoked if this channel's socket is
+ * connected, in which case it sends datagrams directly to the socket's
+ * peer. Otherwise it behaves exactly as specified in the {@link
+ * WritableByteChannel} interface. </p>
+ *
+ * @throws NotYetConnectedException
+ * If this channel's socket is not connected
+ */
+ public abstract int write(ByteBuffer src) throws IOException;
+
+ /**
+ * Writes a datagram to this channel.
+ *
+ * <p> This method may only be invoked if this channel's socket is
+ * connected, in which case it sends datagrams directly to the socket's
+ * peer. Otherwise it behaves exactly as specified in the {@link
+ * GatheringByteChannel} interface. </p>
+ *
+ * @return The number of bytes sent, which will be either the number
+ * of bytes that were remaining in the source buffer when this
+ * method was invoked or, if this channel is non-blocking, may be
+ * zero if there was insufficient room for the datagram in the
+ * underlying output buffer
+ *
+ * @throws NotYetConnectedException
+ * If this channel's socket is not connected
+ */
+ public abstract long write(ByteBuffer[] srcs, int offset, int length)
+ throws IOException;
+
+ /**
+ * Writes a datagram to this channel.
+ *
+ * <p> This method may only be invoked if this channel's socket is
+ * connected, in which case it sends datagrams directly to the socket's
+ * peer. Otherwise it behaves exactly as specified in the {@link
+ * GatheringByteChannel} interface. </p>
+ *
+ * @return The number of bytes sent, which will be either the number
+ * of bytes that were remaining in the source buffer when this
+ * method was invoked or, if this channel is non-blocking, may be
+ * zero if there was insufficient room for the datagram in the
+ * underlying output buffer
+ *
+ * @throws NotYetConnectedException
+ * If this channel's socket is not connected
+ */
+ public final long write(ByteBuffer[] srcs) throws IOException {
+ return write(srcs, 0, srcs.length);
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * If there is a security manager set, its {@code checkConnect} method is
+ * called with the local address and {@code -1} as its arguments to see
+ * if the operation is allowed. If the operation is not allowed,
+ * a {@code SocketAddress} representing the
+ * {@link java.net.InetAddress#getLoopbackAddress loopback} address and the
+ * local port of the channel's socket is returned.
+ *
+ * @return The {@code SocketAddress} that the socket is bound to, or the
+ * {@code SocketAddress} representing the loopback address if
+ * denied by the security manager, or {@code null} if the
+ * channel's socket is not bound
+ *
+ * @throws ClosedChannelException {@inheritDoc}
+ * @throws IOException {@inheritDoc}
+ */
+ @Override
+ public abstract SocketAddress getLocalAddress() throws IOException;
+
+}
diff --git a/java/nio/channels/FileChannel.java b/java/nio/channels/FileChannel.java
new file mode 100644
index 0000000..a23f1c3
--- /dev/null
+++ b/java/nio/channels/FileChannel.java
@@ -0,0 +1,1158 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+import java.io.*;
+import java.nio.ByteBuffer;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.spi.AbstractInterruptibleChannel;
+import java.nio.file.*;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.file.spi.*;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
+
+/**
+ * A channel for reading, writing, mapping, and manipulating a file.
+ *
+ * <p> A file channel is a {@link SeekableByteChannel} that is connected to
+ * a file. It has a current <i>position</i> within its file which can
+ * be both {@link #position() <i>queried</i>} and {@link #position(long)
+ * <i>modified</i>}. The file itself contains a variable-length sequence
+ * of bytes that can be read and written and whose current {@link #size
+ * <i>size</i>} can be queried. The size of the file increases
+ * when bytes are written beyond its current size; the size of the file
+ * decreases when it is {@link #truncate <i>truncated</i>}. The
+ * file may also have some associated <i>metadata</i> such as access
+ * permissions, content type, and last-modification time; this class does not
+ * define methods for metadata access.
+ *
+ * <p> In addition to the familiar read, write, and close operations of byte
+ * channels, this class defines the following file-specific operations: </p>
+ *
+ * <ul>
+ *
+ * <li><p> Bytes may be {@link #read(ByteBuffer, long) read} or
+ * {@link #write(ByteBuffer, long) <i>written</i>} at an absolute
+ * position in a file in a way that does not affect the channel's current
+ * position. </p></li>
+ *
+ * <li><p> A region of a file may be {@link #map <i>mapped</i>}
+ * directly into memory; for large files this is often much more efficient
+ * than invoking the usual <tt>read</tt> or <tt>write</tt> methods.
+ * </p></li>
+ *
+ * <li><p> Updates made to a file may be {@link #force <i>forced
+ * out</i>} to the underlying storage device, ensuring that data are not
+ * lost in the event of a system crash. </p></li>
+ *
+ * <li><p> Bytes can be transferred from a file {@link #transferTo <i>to
+ * some other channel</i>}, and {@link #transferFrom <i>vice
+ * versa</i>}, in a way that can be optimized by many operating systems
+ * into a very fast transfer directly to or from the filesystem cache.
+ * </p></li>
+ *
+ * <li><p> A region of a file may be {@link FileLock <i>locked</i>}
+ * against access by other programs. </p></li>
+ *
+ * </ul>
+ *
+ * <p> File channels are safe for use by multiple concurrent threads. The
+ * {@link Channel#close close} method may be invoked at any time, as specified
+ * by the {@link Channel} interface. Only one operation that involves the
+ * channel's position or can change its file's size may be in progress at any
+ * given time; attempts to initiate a second such operation while the first is
+ * still in progress will block until the first operation completes. Other
+ * operations, in particular those that take an explicit position, may proceed
+ * concurrently; whether they in fact do so is dependent upon the underlying
+ * implementation and is therefore unspecified.
+ *
+ * <p> The view of a file provided by an instance of this class is guaranteed
+ * to be consistent with other views of the same file provided by other
+ * instances in the same program. The view provided by an instance of this
+ * class may or may not, however, be consistent with the views seen by other
+ * concurrently-running programs due to caching performed by the underlying
+ * operating system and delays induced by network-filesystem protocols. This
+ * is true regardless of the language in which these other programs are
+ * written, and whether they are running on the same machine or on some other
+ * machine. The exact nature of any such inconsistencies are system-dependent
+ * and are therefore unspecified.
+ *
+ * <p> A file channel is created by invoking one of the {@link #open open}
+ * methods defined by this class. A file channel can also be obtained from an
+ * existing {@link java.io.FileInputStream#getChannel FileInputStream}, {@link
+ * java.io.FileOutputStream#getChannel FileOutputStream}, or {@link
+ * java.io.RandomAccessFile#getChannel RandomAccessFile} object by invoking
+ * that object's <tt>getChannel</tt> method, which returns a file channel that
+ * is connected to the same underlying file. Where the file channel is obtained
+ * from an existing stream or random access file then the state of the file
+ * channel is intimately connected to that of the object whose <tt>getChannel</tt>
+ * method returned the channel. Changing the channel's position, whether
+ * explicitly or by reading or writing bytes, will change the file position of
+ * the originating object, and vice versa. Changing the file's length via the
+ * file channel will change the length seen via the originating object, and vice
+ * versa. Changing the file's content by writing bytes will change the content
+ * seen by the originating object, and vice versa.
+ *
+ * <a name="open-mode"></a> <p> At various points this class specifies that an
+ * instance that is "open for reading," "open for writing," or "open for
+ * reading and writing" is required. A channel obtained via the {@link
+ * java.io.FileInputStream#getChannel getChannel} method of a {@link
+ * java.io.FileInputStream} instance will be open for reading. A channel
+ * obtained via the {@link java.io.FileOutputStream#getChannel getChannel}
+ * method of a {@link java.io.FileOutputStream} instance will be open for
+ * writing. Finally, a channel obtained via the {@link
+ * java.io.RandomAccessFile#getChannel getChannel} method of a {@link
+ * java.io.RandomAccessFile} instance will be open for reading if the instance
+ * was created with mode <tt>"r"</tt> and will be open for reading and writing
+ * if the instance was created with mode <tt>"rw"</tt>.
+ *
+ * <a name="append-mode"></a><p> A file channel that is open for writing may be in
+ * <i>append mode</i>, for example if it was obtained from a file-output stream
+ * that was created by invoking the {@link
+ * java.io.FileOutputStream#FileOutputStream(java.io.File,boolean)
+ * FileOutputStream(File,boolean)} constructor and passing <tt>true</tt> for
+ * the second parameter. In this mode each invocation of a relative write
+ * operation first advances the position to the end of the file and then writes
+ * the requested data. Whether the advancement of the position and the writing
+ * of the data are done in a single atomic operation is system-dependent and
+ * therefore unspecified.
+ *
+ * @see java.io.FileInputStream#getChannel()
+ * @see java.io.FileOutputStream#getChannel()
+ * @see java.io.RandomAccessFile#getChannel()
+ *
+ * @author Mark Reinhold
+ * @author Mike McCloskey
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class FileChannel
+ extends AbstractInterruptibleChannel
+ implements SeekableByteChannel, GatheringByteChannel, ScatteringByteChannel
+{
+ /**
+ * Initializes a new instance of this class.
+ */
+ protected FileChannel() { }
+
+ /**
+ * Opens or creates a file, returning a file channel to access the file.
+ *
+ * <p> The {@code options} parameter determines how the file is opened.
+ * The {@link StandardOpenOption#READ READ} and {@link StandardOpenOption#WRITE
+ * WRITE} options determine if the file should be opened for reading and/or
+ * writing. If neither option (or the {@link StandardOpenOption#APPEND APPEND}
+ * option) is contained in the array then the file is opened for reading.
+ * By default reading or writing commences at the beginning of the file.
+ *
+ * <p> In the addition to {@code READ} and {@code WRITE}, the following
+ * options may be present:
+ *
+ * <table border=1 cellpadding=5 summary="">
+ * <tr> <th>Option</th> <th>Description</th> </tr>
+ * <tr>
+ * <td> {@link StandardOpenOption#APPEND APPEND} </td>
+ * <td> If this option is present then the file is opened for writing and
+ * each invocation of the channel's {@code write} method first advances
+ * the position to the end of the file and then writes the requested
+ * data. Whether the advancement of the position and the writing of the
+ * data are done in a single atomic operation is system-dependent and
+ * therefore unspecified. This option may not be used in conjunction
+ * with the {@code READ} or {@code TRUNCATE_EXISTING} options. </td>
+ * </tr>
+ * <tr>
+ * <td> {@link StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING} </td>
+ * <td> If this option is present then the existing file is truncated to
+ * a size of 0 bytes. This option is ignored when the file is opened only
+ * for reading. </td>
+ * </tr>
+ * <tr>
+ * <td> {@link StandardOpenOption#CREATE_NEW CREATE_NEW} </td>
+ * <td> If this option is present then a new file is created, failing if
+ * the file already exists. When creating a file the check for the
+ * existence of the file and the creation of the file if it does not exist
+ * is atomic with respect to other file system operations. This option is
+ * ignored when the file is opened only for reading. </td>
+ * </tr>
+ * <tr>
+ * <td > {@link StandardOpenOption#CREATE CREATE} </td>
+ * <td> If this option is present then an existing file is opened if it
+ * exists, otherwise a new file is created. When creating a file the check
+ * for the existence of the file and the creation of the file if it does
+ * not exist is atomic with respect to other file system operations. This
+ * option is ignored if the {@code CREATE_NEW} option is also present or
+ * the file is opened only for reading. </td>
+ * </tr>
+ * <tr>
+ * <td > {@link StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} </td>
+ * <td> When this option is present then the implementation makes a
+ * <em>best effort</em> attempt to delete the file when closed by the
+ * the {@link #close close} method. If the {@code close} method is not
+ * invoked then a <em>best effort</em> attempt is made to delete the file
+ * when the Java virtual machine terminates. </td>
+ * </tr>
+ * <tr>
+ * <td>{@link StandardOpenOption#SPARSE SPARSE} </td>
+ * <td> When creating a new file this option is a <em>hint</em> that the
+ * new file will be sparse. This option is ignored when not creating
+ * a new file. </td>
+ * </tr>
+ * <tr>
+ * <td> {@link StandardOpenOption#SYNC SYNC} </td>
+ * <td> Requires that every update to the file's content or metadata be
+ * written synchronously to the underlying storage device. (see <a
+ * href="../file/package-summary.html#integrity"> Synchronized I/O file
+ * integrity</a>). </td>
+ * </tr>
+ * <tr>
+ * <td> {@link StandardOpenOption#DSYNC DSYNC} </td>
+ * <td> Requires that every update to the file's content be written
+ * synchronously to the underlying storage device. (see <a
+ * href="../file/package-summary.html#integrity"> Synchronized I/O file
+ * integrity</a>). </td>
+ * </tr>
+ * </table>
+ *
+ * <p> An implementation may also support additional options.
+ *
+ * <p> The {@code attrs} parameter is an optional array of file {@link
+ * FileAttribute file-attributes} to set atomically when creating the file.
+ *
+ * <p> The new channel is created by invoking the {@link
+ * FileSystemProvider#newFileChannel newFileChannel} method on the
+ * provider that created the {@code Path}.
+ *
+ * @param path
+ * The path of the file to open or create
+ * @param options
+ * Options specifying how the file is opened
+ * @param attrs
+ * An optional list of file attributes to set atomically when
+ * creating the file
+ *
+ * @return A new file channel
+ *
+ * @throws IllegalArgumentException
+ * If the set contains an invalid combination of options
+ * @throws UnsupportedOperationException
+ * If the {@code path} is associated with a provider that does not
+ * support creating file channels, or an unsupported open option is
+ * specified, or the array contains an attribute that cannot be set
+ * atomically when creating the file
+ * @throws IOException
+ * If an I/O error occurs
+ * @throws SecurityException
+ * If a security manager is installed and it denies an
+ * unspecified permission required by the implementation.
+ * In the case of the default provider, the {@link
+ * SecurityManager#checkRead(String)} method is invoked to check
+ * read access if the file is opened for reading. The {@link
+ * SecurityManager#checkWrite(String)} method is invoked to check
+ * write access if the file is opened for writing
+ *
+ * @since 1.7
+ */
+ public static FileChannel open(Path path,
+ Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ FileSystemProvider provider = path.getFileSystem().provider();
+ return provider.newFileChannel(path, options, attrs);
+ }
+
+ @SuppressWarnings({"unchecked", "rawtypes"}) // generic array construction
+ private static final FileAttribute<?>[] NO_ATTRIBUTES = new FileAttribute[0];
+
+ /**
+ * Opens or creates a file, returning a file channel to access the file.
+ *
+ * <p> An invocation of this method behaves in exactly the same way as the
+ * invocation
+ * <pre>
+ * fc.{@link #open(Path,Set,FileAttribute[]) open}(file, opts, new FileAttribute<?>[0]);
+ * </pre>
+ * where {@code opts} is a set of the options specified in the {@code
+ * options} array.
+ *
+ * @param path
+ * The path of the file to open or create
+ * @param options
+ * Options specifying how the file is opened
+ *
+ * @return A new file channel
+ *
+ * @throws IllegalArgumentException
+ * If the set contains an invalid combination of options
+ * @throws UnsupportedOperationException
+ * If the {@code path} is associated with a provider that does not
+ * support creating file channels, or an unsupported open option is
+ * specified
+ * @throws IOException
+ * If an I/O error occurs
+ * @throws SecurityException
+ * If a security manager is installed and it denies an
+ * unspecified permission required by the implementation.
+ * In the case of the default provider, the {@link
+ * SecurityManager#checkRead(String)} method is invoked to check
+ * read access if the file is opened for reading. The {@link
+ * SecurityManager#checkWrite(String)} method is invoked to check
+ * write access if the file is opened for writing
+ *
+ * @since 1.7
+ */
+ public static FileChannel open(Path path, OpenOption... options)
+ throws IOException
+ {
+ Set<OpenOption> set = new HashSet<OpenOption>(options.length);
+ Collections.addAll(set, options);
+ return open(path, set, NO_ATTRIBUTES);
+ }
+
+ // -- Channel operations --
+
+ /**
+ * Reads a sequence of bytes from this channel into the given buffer.
+ *
+ * <p> Bytes are read starting at this channel's current file position, and
+ * then the file position is updated with the number of bytes actually
+ * read. Otherwise this method behaves exactly as specified in the {@link
+ * ReadableByteChannel} interface. </p>
+ */
+ public abstract int read(ByteBuffer dst) throws IOException;
+
+ /**
+ * Reads a sequence of bytes from this channel into a subsequence of the
+ * given buffers.
+ *
+ * <p> Bytes are read starting at this channel's current file position, and
+ * then the file position is updated with the number of bytes actually
+ * read. Otherwise this method behaves exactly as specified in the {@link
+ * ScatteringByteChannel} interface. </p>
+ */
+ public abstract long read(ByteBuffer[] dsts, int offset, int length)
+ throws IOException;
+
+ /**
+ * Reads a sequence of bytes from this channel into the given buffers.
+ *
+ * <p> Bytes are read starting at this channel's current file position, and
+ * then the file position is updated with the number of bytes actually
+ * read. Otherwise this method behaves exactly as specified in the {@link
+ * ScatteringByteChannel} interface. </p>
+ */
+ public final long read(ByteBuffer[] dsts) throws IOException {
+ return read(dsts, 0, dsts.length);
+ }
+
+ /**
+ * Writes a sequence of bytes to this channel from the given buffer.
+ *
+ * <p> Bytes are written starting at this channel's current file position
+ * unless the channel is in append mode, in which case the position is
+ * first advanced to the end of the file. The file is grown, if necessary,
+ * to accommodate the written bytes, and then the file position is updated
+ * with the number of bytes actually written. Otherwise this method
+ * behaves exactly as specified by the {@link WritableByteChannel}
+ * interface. </p>
+ */
+ public abstract int write(ByteBuffer src) throws IOException;
+
+ /**
+ * Writes a sequence of bytes to this channel from a subsequence of the
+ * given buffers.
+ *
+ * <p> Bytes are written starting at this channel's current file position
+ * unless the channel is in append mode, in which case the position is
+ * first advanced to the end of the file. The file is grown, if necessary,
+ * to accommodate the written bytes, and then the file position is updated
+ * with the number of bytes actually written. Otherwise this method
+ * behaves exactly as specified in the {@link GatheringByteChannel}
+ * interface. </p>
+ */
+ public abstract long write(ByteBuffer[] srcs, int offset, int length)
+ throws IOException;
+
+ /**
+ * Writes a sequence of bytes to this channel from the given buffers.
+ *
+ * <p> Bytes are written starting at this channel's current file position
+ * unless the channel is in append mode, in which case the position is
+ * first advanced to the end of the file. The file is grown, if necessary,
+ * to accommodate the written bytes, and then the file position is updated
+ * with the number of bytes actually written. Otherwise this method
+ * behaves exactly as specified in the {@link GatheringByteChannel}
+ * interface. </p>
+ */
+ public final long write(ByteBuffer[] srcs) throws IOException {
+ return write(srcs, 0, srcs.length);
+ }
+
+
+ // -- Other operations --
+
+ /**
+ * Returns this channel's file position.
+ *
+ * @return This channel's file position,
+ * a non-negative integer counting the number of bytes
+ * from the beginning of the file to the current position
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public abstract long position() throws IOException;
+
+ /**
+ * Sets this channel's file position.
+ *
+ * <p> Setting the position to a value that is greater than the file's
+ * current size is legal but does not change the size of the file. A later
+ * attempt to read bytes at such a position will immediately return an
+ * end-of-file indication. A later attempt to write bytes at such a
+ * position will cause the file to be grown to accommodate the new bytes;
+ * the values of any bytes between the previous end-of-file and the
+ * newly-written bytes are unspecified. </p>
+ *
+ * @param newPosition
+ * The new position, a non-negative integer counting
+ * the number of bytes from the beginning of the file
+ *
+ * @return This file channel
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ *
+ * @throws IllegalArgumentException
+ * If the new position is negative
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public abstract FileChannel position(long newPosition) throws IOException;
+
+ /**
+ * Returns the current size of this channel's file.
+ *
+ * @return The current size of this channel's file,
+ * measured in bytes
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public abstract long size() throws IOException;
+
+ /**
+ * Truncates this channel's file to the given size.
+ *
+ * <p> If the given size is less than the file's current size then the file
+ * is truncated, discarding any bytes beyond the new end of the file. If
+ * the given size is greater than or equal to the file's current size then
+ * the file is not modified. In either case, if this channel's file
+ * position is greater than the given size then it is set to that size.
+ * </p>
+ *
+ * @param size
+ * The new size, a non-negative byte count
+ *
+ * @return This file channel
+ *
+ * @throws NonWritableChannelException
+ * If this channel was not opened for writing
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ *
+ * @throws IllegalArgumentException
+ * If the new size is negative
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public abstract FileChannel truncate(long size) throws IOException;
+
+ /**
+ * Forces any updates to this channel's file to be written to the storage
+ * device that contains it.
+ *
+ * <p> If this channel's file resides on a local storage device then when
+ * this method returns it is guaranteed that all changes made to the file
+ * since this channel was created, or since this method was last invoked,
+ * will have been written to that device. This is useful for ensuring that
+ * critical information is not lost in the event of a system crash.
+ *
+ * <p> If the file does not reside on a local device then no such guarantee
+ * is made.
+ *
+ * <p> The <tt>metaData</tt> parameter can be used to limit the number of
+ * I/O operations that this method is required to perform. Passing
+ * <tt>false</tt> for this parameter indicates that only updates to the
+ * file's content need be written to storage; passing <tt>true</tt>
+ * indicates that updates to both the file's content and metadata must be
+ * written, which generally requires at least one more I/O operation.
+ * Whether this parameter actually has any effect is dependent upon the
+ * underlying operating system and is therefore unspecified.
+ *
+ * <p> Invoking this method may cause an I/O operation to occur even if the
+ * channel was only opened for reading. Some operating systems, for
+ * example, maintain a last-access time as part of a file's metadata, and
+ * this time is updated whenever the file is read. Whether or not this is
+ * actually done is system-dependent and is therefore unspecified.
+ *
+ * <p> This method is only guaranteed to force changes that were made to
+ * this channel's file via the methods defined in this class. It may or
+ * may not force changes that were made by modifying the content of a
+ * {@link MappedByteBuffer <i>mapped byte buffer</i>} obtained by
+ * invoking the {@link #map map} method. Invoking the {@link
+ * MappedByteBuffer#force force} method of the mapped byte buffer will
+ * force changes made to the buffer's content to be written. </p>
+ *
+ * @param metaData
+ * If <tt>true</tt> then this method is required to force changes
+ * to both the file's content and metadata to be written to
+ * storage; otherwise, it need only force content changes to be
+ * written
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public abstract void force(boolean metaData) throws IOException;
+
+ /**
+ * Transfers bytes from this channel's file to the given writable byte
+ * channel.
+ *
+ * <p> An attempt is made to read up to <tt>count</tt> bytes starting at
+ * the given <tt>position</tt> in this channel's file and write them to the
+ * target channel. An invocation of this method may or may not transfer
+ * all of the requested bytes; whether or not it does so depends upon the
+ * natures and states of the channels. Fewer than the requested number of
+ * bytes are transferred if this channel's file contains fewer than
+ * <tt>count</tt> bytes starting at the given <tt>position</tt>, or if the
+ * target channel is non-blocking and it has fewer than <tt>count</tt>
+ * bytes free in its output buffer.
+ *
+ * <p> This method does not modify this channel's position. If the given
+ * position is greater than the file's current size then no bytes are
+ * transferred. If the target channel has a position then bytes are
+ * written starting at that position and then the position is incremented
+ * by the number of bytes written.
+ *
+ * <p> This method is potentially much more efficient than a simple loop
+ * that reads from this channel and writes to the target channel. Many
+ * operating systems can transfer bytes directly from the filesystem cache
+ * to the target channel without actually copying them. </p>
+ *
+ * @param position
+ * The position within the file at which the transfer is to begin;
+ * must be non-negative
+ *
+ * @param count
+ * The maximum number of bytes to be transferred; must be
+ * non-negative
+ *
+ * @param target
+ * The target channel
+ *
+ * @return The number of bytes, possibly zero,
+ * that were actually transferred
+ *
+ * @throws IllegalArgumentException
+ * If the preconditions on the parameters do not hold
+ *
+ * @throws NonReadableChannelException
+ * If this channel was not opened for reading
+ *
+ * @throws NonWritableChannelException
+ * If the target channel was not opened for writing
+ *
+ * @throws ClosedChannelException
+ * If either this channel or the target channel is closed
+ *
+ * @throws AsynchronousCloseException
+ * If another thread closes either channel
+ * while the transfer is in progress
+ *
+ * @throws ClosedByInterruptException
+ * If another thread interrupts the current thread while the
+ * transfer is in progress, thereby closing both channels and
+ * setting the current thread's interrupt status
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public abstract long transferTo(long position, long count,
+ WritableByteChannel target)
+ throws IOException;
+
+ /**
+ * Transfers bytes into this channel's file from the given readable byte
+ * channel.
+ *
+ * <p> An attempt is made to read up to <tt>count</tt> bytes from the
+ * source channel and write them to this channel's file starting at the
+ * given <tt>position</tt>. An invocation of this method may or may not
+ * transfer all of the requested bytes; whether or not it does so depends
+ * upon the natures and states of the channels. Fewer than the requested
+ * number of bytes will be transferred if the source channel has fewer than
+ * <tt>count</tt> bytes remaining, or if the source channel is non-blocking
+ * and has fewer than <tt>count</tt> bytes immediately available in its
+ * input buffer.
+ *
+ * <p> This method does not modify this channel's position. If the given
+ * position is greater than the file's current size then no bytes are
+ * transferred. If the source channel has a position then bytes are read
+ * starting at that position and then the position is incremented by the
+ * number of bytes read.
+ *
+ * <p> This method is potentially much more efficient than a simple loop
+ * that reads from the source channel and writes to this channel. Many
+ * operating systems can transfer bytes directly from the source channel
+ * into the filesystem cache without actually copying them. </p>
+ *
+ * @param src
+ * The source channel
+ *
+ * @param position
+ * The position within the file at which the transfer is to begin;
+ * must be non-negative
+ *
+ * @param count
+ * The maximum number of bytes to be transferred; must be
+ * non-negative
+ *
+ * @return The number of bytes, possibly zero,
+ * that were actually transferred
+ *
+ * @throws IllegalArgumentException
+ * If the preconditions on the parameters do not hold
+ *
+ * @throws NonReadableChannelException
+ * If the source channel was not opened for reading
+ *
+ * @throws NonWritableChannelException
+ * If this channel was not opened for writing
+ *
+ * @throws ClosedChannelException
+ * If either this channel or the source channel is closed
+ *
+ * @throws AsynchronousCloseException
+ * If another thread closes either channel
+ * while the transfer is in progress
+ *
+ * @throws ClosedByInterruptException
+ * If another thread interrupts the current thread while the
+ * transfer is in progress, thereby closing both channels and
+ * setting the current thread's interrupt status
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public abstract long transferFrom(ReadableByteChannel src,
+ long position, long count)
+ throws IOException;
+
+ /**
+ * Reads a sequence of bytes from this channel into the given buffer,
+ * starting at the given file position.
+ *
+ * <p> This method works in the same manner as the {@link
+ * #read(ByteBuffer)} method, except that bytes are read starting at the
+ * given file position rather than at the channel's current position. This
+ * method does not modify this channel's position. If the given position
+ * is greater than the file's current size then no bytes are read. </p>
+ *
+ * @param dst
+ * The buffer into which bytes are to be transferred
+ *
+ * @param position
+ * The file position at which the transfer is to begin;
+ * must be non-negative
+ *
+ * @return The number of bytes read, possibly zero, or <tt>-1</tt> if the
+ * given position is greater than or equal to the file's current
+ * size
+ *
+ * @throws IllegalArgumentException
+ * If the position is negative
+ *
+ * @throws NonReadableChannelException
+ * If this channel was not opened for reading
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ *
+ * @throws AsynchronousCloseException
+ * If another thread closes this channel
+ * while the read operation is in progress
+ *
+ * @throws ClosedByInterruptException
+ * If another thread interrupts the current thread
+ * while the read operation is in progress, thereby
+ * closing the channel and setting the current thread's
+ * interrupt status
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public abstract int read(ByteBuffer dst, long position) throws IOException;
+
+ /**
+ * Writes a sequence of bytes to this channel from the given buffer,
+ * starting at the given file position.
+ *
+ * <p> This method works in the same manner as the {@link
+ * #write(ByteBuffer)} method, except that bytes are written starting at
+ * the given file position rather than at the channel's current position.
+ * This method does not modify this channel's position. If the given
+ * position is greater than the file's current size then the file will be
+ * grown to accommodate the new bytes; the values of any bytes between the
+ * previous end-of-file and the newly-written bytes are unspecified. </p>
+ *
+ * @param src
+ * The buffer from which bytes are to be transferred
+ *
+ * @param position
+ * The file position at which the transfer is to begin;
+ * must be non-negative
+ *
+ * @return The number of bytes written, possibly zero
+ *
+ * @throws IllegalArgumentException
+ * If the position is negative
+ *
+ * @throws NonWritableChannelException
+ * If this channel was not opened for writing
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ *
+ * @throws AsynchronousCloseException
+ * If another thread closes this channel
+ * while the write operation is in progress
+ *
+ * @throws ClosedByInterruptException
+ * If another thread interrupts the current thread
+ * while the write operation is in progress, thereby
+ * closing the channel and setting the current thread's
+ * interrupt status
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public abstract int write(ByteBuffer src, long position) throws IOException;
+
+
+ // -- Memory-mapped buffers --
+
+ /**
+ * A typesafe enumeration for file-mapping modes.
+ *
+ * @since 1.4
+ *
+ * @see java.nio.channels.FileChannel#map
+ */
+ public static class MapMode {
+
+ /**
+ * Mode for a read-only mapping.
+ */
+ public static final MapMode READ_ONLY
+ = new MapMode("READ_ONLY");
+
+ /**
+ * Mode for a read/write mapping.
+ */
+ public static final MapMode READ_WRITE
+ = new MapMode("READ_WRITE");
+
+ /**
+ * Mode for a private (copy-on-write) mapping.
+ */
+ public static final MapMode PRIVATE
+ = new MapMode("PRIVATE");
+
+ private final String name;
+
+ private MapMode(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Returns a string describing this file-mapping mode.
+ *
+ * @return A descriptive string
+ */
+ public String toString() {
+ return name;
+ }
+
+ }
+
+ /**
+ * Maps a region of this channel's file directly into memory.
+ *
+ * <p> A region of a file may be mapped into memory in one of three modes:
+ * </p>
+ *
+ * <ul>
+ *
+ * <li><p> <i>Read-only:</i> Any attempt to modify the resulting buffer
+ * will cause a {@link java.nio.ReadOnlyBufferException} to be thrown.
+ * ({@link MapMode#READ_ONLY MapMode.READ_ONLY}) </p></li>
+ *
+ * <li><p> <i>Read/write:</i> Changes made to the resulting buffer will
+ * eventually be propagated to the file; they may or may not be made
+ * visible to other programs that have mapped the same file. ({@link
+ * MapMode#READ_WRITE MapMode.READ_WRITE}) </p></li>
+ *
+ * <li><p> <i>Private:</i> Changes made to the resulting buffer will not
+ * be propagated to the file and will not be visible to other programs
+ * that have mapped the same file; instead, they will cause private
+ * copies of the modified portions of the buffer to be created. ({@link
+ * MapMode#PRIVATE MapMode.PRIVATE}) </p></li>
+ *
+ * </ul>
+ *
+ * <p> For a read-only mapping, this channel must have been opened for
+ * reading; for a read/write or private mapping, this channel must have
+ * been opened for both reading and writing.
+ *
+ * <p> The {@link MappedByteBuffer <i>mapped byte buffer</i>}
+ * returned by this method will have a position of zero and a limit and
+ * capacity of <tt>size</tt>; its mark will be undefined. The buffer and
+ * the mapping that it represents will remain valid until the buffer itself
+ * is garbage-collected.
+ *
+ * <p> A mapping, once established, is not dependent upon the file channel
+ * that was used to create it. Closing the channel, in particular, has no
+ * effect upon the validity of the mapping.
+ *
+ * <p> Many of the details of memory-mapped files are inherently dependent
+ * upon the underlying operating system and are therefore unspecified. The
+ * behavior of this method when the requested region is not completely
+ * contained within this channel's file is unspecified. Whether changes
+ * made to the content or size of the underlying file, by this program or
+ * another, are propagated to the buffer is unspecified. The rate at which
+ * changes to the buffer are propagated to the file is unspecified.
+ *
+ * <p> For most operating systems, mapping a file into memory is more
+ * expensive than reading or writing a few tens of kilobytes of data via
+ * the usual {@link #read read} and {@link #write write} methods. From the
+ * standpoint of performance it is generally only worth mapping relatively
+ * large files into memory. </p>
+ *
+ * @param mode
+ * One of the constants {@link MapMode#READ_ONLY READ_ONLY}, {@link
+ * MapMode#READ_WRITE READ_WRITE}, or {@link MapMode#PRIVATE
+ * PRIVATE} defined in the {@link MapMode} class, according to
+ * whether the file is to be mapped read-only, read/write, or
+ * privately (copy-on-write), respectively
+ *
+ * @param position
+ * The position within the file at which the mapped region
+ * is to start; must be non-negative
+ *
+ * @param size
+ * The size of the region to be mapped; must be non-negative and
+ * no greater than {@link java.lang.Integer#MAX_VALUE}
+ *
+ * @return The mapped byte buffer
+ *
+ * @throws NonReadableChannelException
+ * If the <tt>mode</tt> is {@link MapMode#READ_ONLY READ_ONLY} but
+ * this channel was not opened for reading
+ *
+ * @throws NonWritableChannelException
+ * If the <tt>mode</tt> is {@link MapMode#READ_WRITE READ_WRITE} or
+ * {@link MapMode#PRIVATE PRIVATE} but this channel was not opened
+ * for both reading and writing
+ *
+ * @throws IllegalArgumentException
+ * If the preconditions on the parameters do not hold
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ *
+ * @see java.nio.channels.FileChannel.MapMode
+ * @see java.nio.MappedByteBuffer
+ */
+ public abstract MappedByteBuffer map(MapMode mode,
+ long position, long size)
+ throws IOException;
+
+
+ // -- Locks --
+
+ /**
+ * Acquires a lock on the given region of this channel's file.
+ *
+ * <p> An invocation of this method will block until the region can be
+ * locked, this channel is closed, or the invoking thread is interrupted,
+ * whichever comes first.
+ *
+ * <p> If this channel is closed by another thread during an invocation of
+ * this method then an {@link AsynchronousCloseException} will be thrown.
+ *
+ * <p> If the invoking thread is interrupted while waiting to acquire the
+ * lock then its interrupt status will be set and a {@link
+ * FileLockInterruptionException} will be thrown. If the invoker's
+ * interrupt status is set when this method is invoked then that exception
+ * will be thrown immediately; the thread's interrupt status will not be
+ * changed.
+ *
+ * <p> The region specified by the <tt>position</tt> and <tt>size</tt>
+ * parameters need not be contained within, or even overlap, the actual
+ * underlying file. Lock regions are fixed in size; if a locked region
+ * initially contains the end of the file and the file grows beyond the
+ * region then the new portion of the file will not be covered by the lock.
+ * If a file is expected to grow in size and a lock on the entire file is
+ * required then a region starting at zero, and no smaller than the
+ * expected maximum size of the file, should be locked. The zero-argument
+ * {@link #lock()} method simply locks a region of size {@link
+ * Long#MAX_VALUE}.
+ *
+ * <p> Some operating systems do not support shared locks, in which case a
+ * request for a shared lock is automatically converted into a request for
+ * an exclusive lock. Whether the newly-acquired lock is shared or
+ * exclusive may be tested by invoking the resulting lock object's {@link
+ * FileLock#isShared() isShared} method.
+ *
+ * <p> File locks are held on behalf of the entire Java virtual machine.
+ * They are not suitable for controlling access to a file by multiple
+ * threads within the same virtual machine. </p>
+ *
+ * @param position
+ * The position at which the locked region is to start; must be
+ * non-negative
+ *
+ * @param size
+ * The size of the locked region; must be non-negative, and the sum
+ * <tt>position</tt> + <tt>size</tt> must be non-negative
+ *
+ * @param shared
+ * <tt>true</tt> to request a shared lock, in which case this
+ * channel must be open for reading (and possibly writing);
+ * <tt>false</tt> to request an exclusive lock, in which case this
+ * channel must be open for writing (and possibly reading)
+ *
+ * @return A lock object representing the newly-acquired lock
+ *
+ * @throws IllegalArgumentException
+ * If the preconditions on the parameters do not hold
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ *
+ * @throws AsynchronousCloseException
+ * If another thread closes this channel while the invoking
+ * thread is blocked in this method
+ *
+ * @throws FileLockInterruptionException
+ * If the invoking thread is interrupted while blocked in this
+ * method
+ *
+ * @throws OverlappingFileLockException
+ * If a lock that overlaps the requested region is already held by
+ * this Java virtual machine, or if another thread is already
+ * blocked in this method and is attempting to lock an overlapping
+ * region
+ *
+ * @throws NonReadableChannelException
+ * If <tt>shared</tt> is <tt>true</tt> this channel was not
+ * opened for reading
+ *
+ * @throws NonWritableChannelException
+ * If <tt>shared</tt> is <tt>false</tt> but this channel was not
+ * opened for writing
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ *
+ * @see #lock()
+ * @see #tryLock()
+ * @see #tryLock(long,long,boolean)
+ */
+ public abstract FileLock lock(long position, long size, boolean shared)
+ throws IOException;
+
+ /**
+ * Acquires an exclusive lock on this channel's file.
+ *
+ * <p> An invocation of this method of the form <tt>fc.lock()</tt> behaves
+ * in exactly the same way as the invocation
+ *
+ * <pre>
+ * fc.{@link #lock(long,long,boolean) lock}(0L, Long.MAX_VALUE, false) </pre>
+ *
+ * @return A lock object representing the newly-acquired lock
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ *
+ * @throws AsynchronousCloseException
+ * If another thread closes this channel while the invoking
+ * thread is blocked in this method
+ *
+ * @throws FileLockInterruptionException
+ * If the invoking thread is interrupted while blocked in this
+ * method
+ *
+ * @throws OverlappingFileLockException
+ * If a lock that overlaps the requested region is already held by
+ * this Java virtual machine, or if another thread is already
+ * blocked in this method and is attempting to lock an overlapping
+ * region of the same file
+ *
+ * @throws NonWritableChannelException
+ * If this channel was not opened for writing
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ *
+ * @see #lock(long,long,boolean)
+ * @see #tryLock()
+ * @see #tryLock(long,long,boolean)
+ */
+ public final FileLock lock() throws IOException {
+ return lock(0L, Long.MAX_VALUE, false);
+ }
+
+ /**
+ * Attempts to acquire a lock on the given region of this channel's file.
+ *
+ * <p> This method does not block. An invocation always returns
+ * immediately, either having acquired a lock on the requested region or
+ * having failed to do so. If it fails to acquire a lock because an
+ * overlapping lock is held by another program then it returns
+ * <tt>null</tt>. If it fails to acquire a lock for any other reason then
+ * an appropriate exception is thrown.
+ *
+ * <p> The region specified by the <tt>position</tt> and <tt>size</tt>
+ * parameters need not be contained within, or even overlap, the actual
+ * underlying file. Lock regions are fixed in size; if a locked region
+ * initially contains the end of the file and the file grows beyond the
+ * region then the new portion of the file will not be covered by the lock.
+ * If a file is expected to grow in size and a lock on the entire file is
+ * required then a region starting at zero, and no smaller than the
+ * expected maximum size of the file, should be locked. The zero-argument
+ * {@link #tryLock()} method simply locks a region of size {@link
+ * Long#MAX_VALUE}.
+ *
+ * <p> Some operating systems do not support shared locks, in which case a
+ * request for a shared lock is automatically converted into a request for
+ * an exclusive lock. Whether the newly-acquired lock is shared or
+ * exclusive may be tested by invoking the resulting lock object's {@link
+ * FileLock#isShared() isShared} method.
+ *
+ * <p> File locks are held on behalf of the entire Java virtual machine.
+ * They are not suitable for controlling access to a file by multiple
+ * threads within the same virtual machine. </p>
+ *
+ * @param position
+ * The position at which the locked region is to start; must be
+ * non-negative
+ *
+ * @param size
+ * The size of the locked region; must be non-negative, and the sum
+ * <tt>position</tt> + <tt>size</tt> must be non-negative
+ *
+ * @param shared
+ * <tt>true</tt> to request a shared lock,
+ * <tt>false</tt> to request an exclusive lock
+ *
+ * @return A lock object representing the newly-acquired lock,
+ * or <tt>null</tt> if the lock could not be acquired
+ * because another program holds an overlapping lock
+ *
+ * @throws IllegalArgumentException
+ * If the preconditions on the parameters do not hold
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ *
+ * @throws OverlappingFileLockException
+ * If a lock that overlaps the requested region is already held by
+ * this Java virtual machine, or if another thread is already
+ * blocked in this method and is attempting to lock an overlapping
+ * region of the same file
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ *
+ * @see #lock()
+ * @see #lock(long,long,boolean)
+ * @see #tryLock()
+ */
+ public abstract FileLock tryLock(long position, long size, boolean shared)
+ throws IOException;
+
+ /**
+ * Attempts to acquire an exclusive lock on this channel's file.
+ *
+ * <p> An invocation of this method of the form <tt>fc.tryLock()</tt>
+ * behaves in exactly the same way as the invocation
+ *
+ * <pre>
+ * fc.{@link #tryLock(long,long,boolean) tryLock}(0L, Long.MAX_VALUE, false) </pre>
+ *
+ * @return A lock object representing the newly-acquired lock,
+ * or <tt>null</tt> if the lock could not be acquired
+ * because another program holds an overlapping lock
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ *
+ * @throws OverlappingFileLockException
+ * If a lock that overlaps the requested region is already held by
+ * this Java virtual machine, or if another thread is already
+ * blocked in this method and is attempting to lock an overlapping
+ * region
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ *
+ * @see #lock()
+ * @see #lock(long,long,boolean)
+ * @see #tryLock(long,long,boolean)
+ */
+ public final FileLock tryLock() throws IOException {
+ return tryLock(0L, Long.MAX_VALUE, false);
+ }
+
+}
diff --git a/java/nio/channels/FileLock.java b/java/nio/channels/FileLock.java
new file mode 100644
index 0000000..156071c
--- /dev/null
+++ b/java/nio/channels/FileLock.java
@@ -0,0 +1,331 @@
+/*
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+import java.io.IOException;
+
+/**
+ * A token representing a lock on a region of a file.
+ *
+ * <p> A file-lock object is created each time a lock is acquired on a file via
+ * one of the {@link FileChannel#lock(long,long,boolean) lock} or {@link
+ * FileChannel#tryLock(long,long,boolean) tryLock} methods of the
+ * {@link FileChannel} class, or the {@link
+ * AsynchronousFileChannel#lock(long,long,boolean,Object,CompletionHandler) lock}
+ * or {@link AsynchronousFileChannel#tryLock(long,long,boolean) tryLock}
+ * methods of the {@link AsynchronousFileChannel} class.
+ *
+ * <p> A file-lock object is initially valid. It remains valid until the lock
+ * is released by invoking the {@link #release release} method, by closing the
+ * channel that was used to acquire it, or by the termination of the Java
+ * virtual machine, whichever comes first. The validity of a lock may be
+ * tested by invoking its {@link #isValid isValid} method.
+ *
+ * <p> A file lock is either <i>exclusive</i> or <i>shared</i>. A shared lock
+ * prevents other concurrently-running programs from acquiring an overlapping
+ * exclusive lock, but does allow them to acquire overlapping shared locks. An
+ * exclusive lock prevents other programs from acquiring an overlapping lock of
+ * either type. Once it is released, a lock has no further effect on the locks
+ * that may be acquired by other programs.
+ *
+ * <p> Whether a lock is exclusive or shared may be determined by invoking its
+ * {@link #isShared isShared} method. Some platforms do not support shared
+ * locks, in which case a request for a shared lock is automatically converted
+ * into a request for an exclusive lock.
+ *
+ * <p> The locks held on a particular file by a single Java virtual machine do
+ * not overlap. The {@link #overlaps overlaps} method may be used to test
+ * whether a candidate lock range overlaps an existing lock.
+ *
+ * <p> A file-lock object records the file channel upon whose file the lock is
+ * held, the type and validity of the lock, and the position and size of the
+ * locked region. Only the validity of a lock is subject to change over time;
+ * all other aspects of a lock's state are immutable.
+ *
+ * <p> File locks are held on behalf of the entire Java virtual machine.
+ * They are not suitable for controlling access to a file by multiple
+ * threads within the same virtual machine.
+ *
+ * <p> File-lock objects are safe for use by multiple concurrent threads.
+ *
+ *
+ * <a name="pdep"></a><h2> Platform dependencies </h2>
+ *
+ * <p> This file-locking API is intended to map directly to the native locking
+ * facility of the underlying operating system. Thus the locks held on a file
+ * should be visible to all programs that have access to the file, regardless
+ * of the language in which those programs are written.
+ *
+ * <p> Whether or not a lock actually prevents another program from accessing
+ * the content of the locked region is system-dependent and therefore
+ * unspecified. The native file-locking facilities of some systems are merely
+ * <i>advisory</i>, meaning that programs must cooperatively observe a known
+ * locking protocol in order to guarantee data integrity. On other systems
+ * native file locks are <i>mandatory</i>, meaning that if one program locks a
+ * region of a file then other programs are actually prevented from accessing
+ * that region in a way that would violate the lock. On yet other systems,
+ * whether native file locks are advisory or mandatory is configurable on a
+ * per-file basis. To ensure consistent and correct behavior across platforms,
+ * it is strongly recommended that the locks provided by this API be used as if
+ * they were advisory locks.
+ *
+ * <p> On some systems, acquiring a mandatory lock on a region of a file
+ * prevents that region from being {@link java.nio.channels.FileChannel#map
+ * <i>mapped into memory</i>}, and vice versa. Programs that combine
+ * locking and mapping should be prepared for this combination to fail.
+ *
+ * <p> On some systems, closing a channel releases all locks held by the Java
+ * virtual machine on the underlying file regardless of whether the locks were
+ * acquired via that channel or via another channel open on the same file. It
+ * is strongly recommended that, within a program, a unique channel be used to
+ * acquire all locks on any given file.
+ *
+ * <p> Some network filesystems permit file locking to be used with
+ * memory-mapped files only when the locked regions are page-aligned and a
+ * whole multiple of the underlying hardware's page size. Some network
+ * filesystems do not implement file locks on regions that extend past a
+ * certain position, often 2<sup>30</sup> or 2<sup>31</sup>. In general, great
+ * care should be taken when locking files that reside on network filesystems.
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class FileLock implements AutoCloseable {
+
+ private final Channel channel;
+ private final long position;
+ private final long size;
+ private final boolean shared;
+
+ /**
+ * Initializes a new instance of this class.
+ *
+ * @param channel
+ * The file channel upon whose file this lock is held
+ *
+ * @param position
+ * The position within the file at which the locked region starts;
+ * must be non-negative
+ *
+ * @param size
+ * The size of the locked region; must be non-negative, and the sum
+ * <tt>position</tt> + <tt>size</tt> must be non-negative
+ *
+ * @param shared
+ * <tt>true</tt> if this lock is shared,
+ * <tt>false</tt> if it is exclusive
+ *
+ * @throws IllegalArgumentException
+ * If the preconditions on the parameters do not hold
+ */
+ protected FileLock(FileChannel channel,
+ long position, long size, boolean shared)
+ {
+ if (position < 0)
+ throw new IllegalArgumentException("Negative position");
+ if (size < 0)
+ throw new IllegalArgumentException("Negative size");
+ if (position + size < 0)
+ throw new IllegalArgumentException("Negative position + size");
+ this.channel = channel;
+ this.position = position;
+ this.size = size;
+ this.shared = shared;
+ }
+
+ /**
+ * Initializes a new instance of this class.
+ *
+ * @param channel
+ * The channel upon whose file this lock is held
+ *
+ * @param position
+ * The position within the file at which the locked region starts;
+ * must be non-negative
+ *
+ * @param size
+ * The size of the locked region; must be non-negative, and the sum
+ * <tt>position</tt> + <tt>size</tt> must be non-negative
+ *
+ * @param shared
+ * <tt>true</tt> if this lock is shared,
+ * <tt>false</tt> if it is exclusive
+ *
+ * @throws IllegalArgumentException
+ * If the preconditions on the parameters do not hold
+ *
+ * @since 1.7
+ */
+ protected FileLock(AsynchronousFileChannel channel,
+ long position, long size, boolean shared)
+ {
+ if (position < 0)
+ throw new IllegalArgumentException("Negative position");
+ if (size < 0)
+ throw new IllegalArgumentException("Negative size");
+ if (position + size < 0)
+ throw new IllegalArgumentException("Negative position + size");
+ this.channel = channel;
+ this.position = position;
+ this.size = size;
+ this.shared = shared;
+ }
+
+ /**
+ * Returns the file channel upon whose file this lock was acquired.
+ *
+ * <p> This method has been superseded by the {@link #acquiredBy acquiredBy}
+ * method.
+ *
+ * @return The file channel, or {@code null} if the file lock was not
+ * acquired by a file channel.
+ */
+ public final FileChannel channel() {
+ return (channel instanceof FileChannel) ? (FileChannel)channel : null;
+ }
+
+ /**
+ * Returns the channel upon whose file this lock was acquired.
+ *
+ * @return The channel upon whose file this lock was acquired.
+ *
+ * @since 1.7
+ */
+ public Channel acquiredBy() {
+ return channel;
+ }
+
+ /**
+ * Returns the position within the file of the first byte of the locked
+ * region.
+ *
+ * <p> A locked region need not be contained within, or even overlap, the
+ * actual underlying file, so the value returned by this method may exceed
+ * the file's current size. </p>
+ *
+ * @return The position
+ */
+ public final long position() {
+ return position;
+ }
+
+ /**
+ * Returns the size of the locked region in bytes.
+ *
+ * <p> A locked region need not be contained within, or even overlap, the
+ * actual underlying file, so the value returned by this method may exceed
+ * the file's current size. </p>
+ *
+ * @return The size of the locked region
+ */
+ public final long size() {
+ return size;
+ }
+
+ /**
+ * Tells whether this lock is shared.
+ *
+ * @return <tt>true</tt> if lock is shared,
+ * <tt>false</tt> if it is exclusive
+ */
+ public final boolean isShared() {
+ return shared;
+ }
+
+ /**
+ * Tells whether or not this lock overlaps the given lock range.
+ *
+ * @param position
+ * The starting position of the lock range
+ * @param size
+ * The size of the lock range
+ *
+ * @return <tt>true</tt> if, and only if, this lock and the given lock
+ * range overlap by at least one byte
+ */
+ public final boolean overlaps(long position, long size) {
+ if (position + size <= this.position)
+ return false; // That is below this
+ if (this.position + this.size <= position)
+ return false; // This is below that
+ return true;
+ }
+
+ /**
+ * Tells whether or not this lock is valid.
+ *
+ * <p> A lock object remains valid until it is released or the associated
+ * file channel is closed, whichever comes first. </p>
+ *
+ * @return <tt>true</tt> if, and only if, this lock is valid
+ */
+ public abstract boolean isValid();
+
+ /**
+ * Releases this lock.
+ *
+ * <p> If this lock object is valid then invoking this method releases the
+ * lock and renders the object invalid. If this lock object is invalid
+ * then invoking this method has no effect. </p>
+ *
+ * @throws ClosedChannelException
+ * If the channel that was used to acquire this lock
+ * is no longer open
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ public abstract void release() throws IOException;
+
+ /**
+ * This method invokes the {@link #release} method. It was added
+ * to the class so that it could be used in conjunction with the
+ * automatic resource management block construct.
+ *
+ * @since 1.7
+ */
+ public final void close() throws IOException {
+ release();
+ }
+
+ /**
+ * Returns a string describing the range, type, and validity of this lock.
+ *
+ * @return A descriptive string
+ */
+ public final String toString() {
+ return (this.getClass().getName()
+ + "[" + position
+ + ":" + size
+ + " " + (shared ? "shared" : "exclusive")
+ + " " + (isValid() ? "valid" : "invalid")
+ + "]");
+ }
+
+}
diff --git a/java/nio/channels/FileLockInterruptionException.java b/java/nio/channels/FileLockInterruptionException.java
new file mode 100644
index 0000000..a9b1bd6
--- /dev/null
+++ b/java/nio/channels/FileLockInterruptionException.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Checked exception received by a thread when another thread interrupts it
+ * while it is waiting to acquire a file lock. Before this exception is thrown
+ * the interrupt status of the previously-blocked thread will have been set.
+ *
+ * @since 1.4
+ */
+
+public class FileLockInterruptionException
+ extends java.io.IOException
+{
+
+ private static final long serialVersionUID = 7104080643653532383L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public FileLockInterruptionException() { }
+
+}
diff --git a/java/nio/channels/GatheringByteChannel.java b/java/nio/channels/GatheringByteChannel.java
new file mode 100644
index 0000000..9c50d93
--- /dev/null
+++ b/java/nio/channels/GatheringByteChannel.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+
+/**
+ * A channel that can write bytes from a sequence of buffers.
+ *
+ * <p> A <i>gathering</i> write operation writes, in a single invocation, a
+ * sequence of bytes from one or more of a given sequence of buffers.
+ * Gathering writes are often useful when implementing network protocols or
+ * file formats that, for example, group data into segments consisting of one
+ * or more fixed-length headers followed by a variable-length body. Similar
+ * <i>scattering</i> read operations are defined in the {@link
+ * ScatteringByteChannel} interface. </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public interface GatheringByteChannel
+ extends WritableByteChannel
+{
+
+ /**
+ * Writes a sequence of bytes to this channel from a subsequence of the
+ * given buffers.
+ *
+ * <p> An attempt is made to write up to <i>r</i> bytes to this channel,
+ * where <i>r</i> is the total number of bytes remaining in the specified
+ * subsequence of the given buffer array, that is,
+ *
+ * <blockquote><pre>
+ * srcs[offset].remaining()
+ * + srcs[offset+1].remaining()
+ * + ... + srcs[offset+length-1].remaining()</pre></blockquote>
+ *
+ * at the moment that this method is invoked.
+ *
+ * <p> Suppose that a byte sequence of length <i>n</i> is written, where
+ * <tt>0</tt> <tt><=</tt> <i>n</i> <tt><=</tt> <i>r</i>.
+ * Up to the first <tt>srcs[offset].remaining()</tt> bytes of this sequence
+ * are written from buffer <tt>srcs[offset]</tt>, up to the next
+ * <tt>srcs[offset+1].remaining()</tt> bytes are written from buffer
+ * <tt>srcs[offset+1]</tt>, and so forth, until the entire byte sequence is
+ * written. As many bytes as possible are written from each buffer, hence
+ * the final position of each updated buffer, except the last updated
+ * buffer, is guaranteed to be equal to that buffer's limit.
+ *
+ * <p> Unless otherwise specified, a write operation will return only after
+ * writing all of the <i>r</i> requested bytes. Some types of channels,
+ * depending upon their state, may write only some of the bytes or possibly
+ * none at all. A socket channel in non-blocking mode, for example, cannot
+ * write any more bytes than are free in the socket's output buffer.
+ *
+ * <p> This method may be invoked at any time. If another thread has
+ * already initiated a write operation upon this channel, however, then an
+ * invocation of this method will block until the first operation is
+ * complete. </p>
+ *
+ * @param srcs
+ * The buffers from which bytes are to be retrieved
+ *
+ * @param offset
+ * The offset within the buffer array of the first buffer from
+ * which bytes are to be retrieved; must be non-negative and no
+ * larger than <tt>srcs.length</tt>
+ *
+ * @param length
+ * The maximum number of buffers to be accessed; must be
+ * non-negative and no larger than
+ * <tt>srcs.length</tt> - <tt>offset</tt>
+ *
+ * @return The number of bytes written, possibly zero
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ *
+ * @throws NonWritableChannelException
+ * If this channel was not opened for writing
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ *
+ * @throws AsynchronousCloseException
+ * If another thread closes this channel
+ * while the write operation is in progress
+ *
+ * @throws ClosedByInterruptException
+ * If another thread interrupts the current thread
+ * while the write operation is in progress, thereby
+ * closing the channel and setting the current thread's
+ * interrupt status
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public long write(ByteBuffer[] srcs, int offset, int length)
+ throws IOException;
+
+
+ /**
+ * Writes a sequence of bytes to this channel from the given buffers.
+ *
+ * <p> An invocation of this method of the form <tt>c.write(srcs)</tt>
+ * behaves in exactly the same manner as the invocation
+ *
+ * <blockquote><pre>
+ * c.write(srcs, 0, srcs.length);</pre></blockquote>
+ *
+ * @param srcs
+ * The buffers from which bytes are to be retrieved
+ *
+ * @return The number of bytes written, possibly zero
+ *
+ * @throws NonWritableChannelException
+ * If this channel was not opened for writing
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ *
+ * @throws AsynchronousCloseException
+ * If another thread closes this channel
+ * while the write operation is in progress
+ *
+ * @throws ClosedByInterruptException
+ * If another thread interrupts the current thread
+ * while the write operation is in progress, thereby
+ * closing the channel and setting the current thread's
+ * interrupt status
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public long write(ByteBuffer[] srcs) throws IOException;
+
+}
diff --git a/java/nio/channels/IllegalBlockingModeException.java b/java/nio/channels/IllegalBlockingModeException.java
new file mode 100644
index 0000000..19d0300
--- /dev/null
+++ b/java/nio/channels/IllegalBlockingModeException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when a blocking-mode-specific operation
+ * is invoked upon a channel in the incorrect blocking mode.
+ *
+ * @since 1.4
+ */
+
+public class IllegalBlockingModeException
+ extends IllegalStateException
+{
+
+ private static final long serialVersionUID = -3335774961855590474L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public IllegalBlockingModeException() { }
+
+}
diff --git a/java/nio/channels/IllegalChannelGroupException.java b/java/nio/channels/IllegalChannelGroupException.java
new file mode 100644
index 0000000..dd47105
--- /dev/null
+++ b/java/nio/channels/IllegalChannelGroupException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to open a channel
+ * in a group that was not created by the same provider.
+ *
+ * @since 1.7
+ */
+
+public class IllegalChannelGroupException
+ extends IllegalArgumentException
+{
+
+ private static final long serialVersionUID = -2495041211157744253L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public IllegalChannelGroupException() { }
+
+}
diff --git a/java/nio/channels/IllegalSelectorException.java b/java/nio/channels/IllegalSelectorException.java
new file mode 100644
index 0000000..b10f071
--- /dev/null
+++ b/java/nio/channels/IllegalSelectorException.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to register a channel
+ * with a selector that was not created by the provider that created the
+ * channel.
+ *
+ * @since 1.4
+ */
+
+public class IllegalSelectorException
+ extends IllegalArgumentException
+{
+
+ private static final long serialVersionUID = -8406323347253320987L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public IllegalSelectorException() { }
+
+}
diff --git a/java/nio/channels/InterruptedByTimeoutException.java b/java/nio/channels/InterruptedByTimeoutException.java
new file mode 100644
index 0000000..ae2018d
--- /dev/null
+++ b/java/nio/channels/InterruptedByTimeoutException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Checked exception received by a thread when a timeout elapses before an
+ * asynchronous operation completes.
+ *
+ * @since 1.7
+ */
+
+public class InterruptedByTimeoutException
+ extends java.io.IOException
+{
+
+ private static final long serialVersionUID = -4268008601014042947L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public InterruptedByTimeoutException() { }
+
+}
diff --git a/java/nio/channels/InterruptibleChannel.java b/java/nio/channels/InterruptibleChannel.java
new file mode 100644
index 0000000..0e49aa6
--- /dev/null
+++ b/java/nio/channels/InterruptibleChannel.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ */
+
+package java.nio.channels;
+
+import java.io.IOException;
+
+
+/**
+ * A channel that can be asynchronously closed and interrupted.
+ *
+ * <p> A channel that implements this interface is <i>asynchronously
+ * closeable:</i> If a thread is blocked in an I/O operation on an
+ * interruptible channel then another thread may invoke the channel's {@link
+ * #close close} method. This will cause the blocked thread to receive an
+ * {@link AsynchronousCloseException}.
+ *
+ * <p> A channel that implements this interface is also <i>interruptible:</i>
+ * If a thread is blocked in an I/O operation on an interruptible channel then
+ * another thread may invoke the blocked thread's {@link Thread#interrupt()
+ * interrupt} method. This will cause the channel to be closed, the blocked
+ * thread to receive a {@link ClosedByInterruptException}, and the blocked
+ * thread's interrupt status to be set.
+ *
+ * <p> If a thread's interrupt status is already set and it invokes a blocking
+ * I/O operation upon a channel then the channel will be closed and the thread
+ * will immediately receive a {@link ClosedByInterruptException}; its interrupt
+ * status will remain set.
+ *
+ * <p> A channel supports asynchronous closing and interruption if, and only
+ * if, it implements this interface. This can be tested at runtime, if
+ * necessary, via the <tt>instanceof</tt> operator.
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public interface InterruptibleChannel
+ extends Channel
+{
+
+ /**
+ * Closes this channel.
+ *
+ * <p> Any thread currently blocked in an I/O operation upon this channel
+ * will receive an {@link AsynchronousCloseException}.
+ *
+ * <p> This method otherwise behaves exactly as specified by the {@link
+ * Channel#close Channel} interface. </p>
+ *
+ * @throws IOException If an I/O error occurs
+ */
+ public void close() throws IOException;
+
+}
diff --git a/java/nio/channels/MembershipKey.java b/java/nio/channels/MembershipKey.java
new file mode 100644
index 0000000..91c2632
--- /dev/null
+++ b/java/nio/channels/MembershipKey.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.io.IOException;
+
+/**
+ * A token representing the membership of an Internet Protocol (IP) multicast
+ * group.
+ *
+ * <p> A membership key may represent a membership to receive all datagrams sent
+ * to the group, or it may be <em>source-specific</em>, meaning that it
+ * represents a membership that receives only datagrams from a specific source
+ * address. Whether or not a membership key is source-specific may be determined
+ * by invoking its {@link #sourceAddress() sourceAddress} method.
+ *
+ * <p> A membership key is valid upon creation and remains valid until the
+ * membership is dropped by invoking the {@link #drop() drop} method, or
+ * the channel is closed. The validity of the membership key may be tested
+ * by invoking its {@link #isValid() isValid} method.
+ *
+ * <p> Where a membership key is not source-specific and the underlying operation
+ * system supports source filtering, then the {@link #block block} and {@link
+ * #unblock unblock} methods can be used to block or unblock multicast datagrams
+ * from particular source addresses.
+ *
+ * @see MulticastChannel
+ *
+ * @since 1.7
+ */
+public abstract class MembershipKey {
+
+ /**
+ * Initializes a new instance of this class.
+ */
+ protected MembershipKey() {
+ }
+
+ /**
+ * Tells whether or not this membership is valid.
+ *
+ * <p> A multicast group membership is valid upon creation and remains
+ * valid until the membership is dropped by invoking the {@link #drop() drop}
+ * method, or the channel is closed.
+ *
+ * @return {@code true} if this membership key is valid, {@code false}
+ * otherwise
+ */
+ public abstract boolean isValid();
+
+ /**
+ * Drop membership.
+ *
+ * <p> If the membership key represents a membership to receive all datagrams
+ * then the membership is dropped and the channel will no longer receive any
+ * datagrams sent to the group. If the membership key is source-specific
+ * then the channel will no longer receive datagrams sent to the group from
+ * that source address.
+ *
+ * <p> After membership is dropped it may still be possible to receive
+ * datagrams sent to the group. This can arise when datagrams are waiting to
+ * be received in the socket's receive buffer. After membership is dropped
+ * then the channel may {@link MulticastChannel#join join} the group again
+ * in which case a new membership key is returned.
+ *
+ * <p> Upon return, this membership object will be {@link #isValid() invalid}.
+ * If the multicast group membership is already invalid then invoking this
+ * method has no effect. Once a multicast group membership is invalid,
+ * it remains invalid forever.
+ */
+ public abstract void drop();
+
+ /**
+ * Block multicast datagrams from the given source address.
+ *
+ * <p> If this membership key is not source-specific, and the underlying
+ * operating system supports source filtering, then this method blocks
+ * multicast datagrams from the given source address. If the given source
+ * address is already blocked then this method has no effect.
+ * After a source address is blocked it may still be possible to receive
+ * datagrams from that source. This can arise when datagrams are waiting to
+ * be received in the socket's receive buffer.
+ *
+ * @param source
+ * The source address to block
+ *
+ * @return This membership key
+ *
+ * @throws IllegalArgumentException
+ * If the {@code source} parameter is not a unicast address or
+ * is not the same address type as the multicast group
+ * @throws IllegalStateException
+ * If this membership key is source-specific or is no longer valid
+ * @throws UnsupportedOperationException
+ * If the underlying operating system does not support source
+ * filtering
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ public abstract MembershipKey block(InetAddress source) throws IOException;
+
+ /**
+ * Unblock multicast datagrams from the given source address that was
+ * previously blocked using the {@link #block(InetAddress) block} method.
+ *
+ * @param source
+ * The source address to unblock
+ *
+ * @return This membership key
+ *
+ * @throws IllegalStateException
+ * If the given source address is not currently blocked or the
+ * membership key is no longer valid
+ */
+ public abstract MembershipKey unblock(InetAddress source);
+
+ /**
+ * Returns the channel for which this membership key was created. This
+ * method will continue to return the channel even after the membership
+ * becomes {@link #isValid invalid}.
+ *
+ * @return the channel
+ */
+ public abstract MulticastChannel channel();
+
+ /**
+ * Returns the multicast group for which this membership key was created.
+ * This method will continue to return the group even after the membership
+ * becomes {@link #isValid invalid}.
+ *
+ * @return the multicast group
+ */
+ public abstract InetAddress group();
+
+ /**
+ * Returns the network interface for which this membership key was created.
+ * This method will continue to return the network interface even after the
+ * membership becomes {@link #isValid invalid}.
+ *
+ * @return the network interface
+ */
+ public abstract NetworkInterface networkInterface();
+
+ /**
+ * Returns the source address if this membership key is source-specific,
+ * or {@code null} if this membership is not source-specific.
+ *
+ * @return The source address if this membership key is source-specific,
+ * otherwise {@code null}
+ */
+ public abstract InetAddress sourceAddress();
+}
diff --git a/java/nio/channels/MulticastChannel.java b/java/nio/channels/MulticastChannel.java
new file mode 100644
index 0000000..d1d13eb
--- /dev/null
+++ b/java/nio/channels/MulticastChannel.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.io.IOException;
+import java.net.ProtocolFamily; // javadoc
+import java.net.StandardProtocolFamily; // javadoc
+import java.net.StandardSocketOptions; // javadoc
+
+/**
+ * A network channel that supports Internet Protocol (IP) multicasting.
+ *
+ * <p> IP multicasting is the transmission of IP datagrams to members of
+ * a <em>group</em> that is zero or more hosts identified by a single destination
+ * address.
+ *
+ * <p> In the case of a channel to an {@link StandardProtocolFamily#INET IPv4} socket,
+ * the underlying operating system supports <a href="http://www.ietf.org/rfc/rfc2236.txt">
+ * <i>RFC 2236: Internet Group Management Protocol, Version 2 (IGMPv2)</i></a>.
+ * It may optionally support source filtering as specified by <a
+ * href="http://www.ietf.org/rfc/rfc3376.txt"> <i>RFC 3376: Internet Group
+ * Management Protocol, Version 3 (IGMPv3)</i></a>.
+ * For channels to an {@link StandardProtocolFamily#INET6 IPv6} socket, the equivalent
+ * standards are <a href="http://www.ietf.org/rfc/rfc2710.txt"> <i>RFC 2710:
+ * Multicast Listener Discovery (MLD) for IPv6</i></a> and <a
+ * href="http://www.ietf.org/rfc/rfc3810.txt"> <i>RFC 3810: Multicast Listener
+ * Discovery Version 2 (MLDv2) for IPv6</i></a>.
+ *
+ * <p> The {@link #join(InetAddress,NetworkInterface)} method is used to
+ * join a group and receive all multicast datagrams sent to the group. A channel
+ * may join several multicast groups and may join the same group on several
+ * {@link NetworkInterface interfaces}. Membership is dropped by invoking the {@link
+ * MembershipKey#drop drop} method on the returned {@link MembershipKey}. If the
+ * underlying platform supports source filtering then the {@link MembershipKey#block
+ * block} and {@link MembershipKey#unblock unblock} methods can be used to block or
+ * unblock multicast datagrams from particular source addresses.
+ *
+ * <p> The {@link #join(InetAddress,NetworkInterface,InetAddress)} method
+ * is used to begin receiving datagrams sent to a group whose source address matches
+ * a given source address. This method throws {@link UnsupportedOperationException}
+ * if the underlying platform does not support source filtering. Membership is
+ * <em>cumulative</em> and this method may be invoked again with the same group
+ * and interface to allow receiving datagrams from other source addresses. The
+ * method returns a {@link MembershipKey} that represents membership to receive
+ * datagrams from the given source address. Invoking the key's {@link
+ * MembershipKey#drop drop} method drops membership so that datagrams from the
+ * source address can no longer be received.
+ *
+ * <h2>Platform dependencies</h2>
+ *
+ * The multicast implementation is intended to map directly to the native
+ * multicasting facility. Consequently, the following items should be considered
+ * when developing an application that receives IP multicast datagrams:
+ *
+ * <ol>
+ *
+ * <li><p> The creation of the channel should specify the {@link ProtocolFamily}
+ * that corresponds to the address type of the multicast groups that the channel
+ * will join. There is no guarantee that a channel to a socket in one protocol
+ * family can join and receive multicast datagrams when the address of the
+ * multicast group corresponds to another protocol family. For example, it is
+ * implementation specific if a channel to an {@link StandardProtocolFamily#INET6 IPv6}
+ * socket can join an {@link StandardProtocolFamily#INET IPv4} multicast group and receive
+ * multicast datagrams sent to the group. </p></li>
+ *
+ * <li><p> The channel's socket should be bound to the {@link
+ * InetAddress#isAnyLocalAddress wildcard} address. If the socket is bound to
+ * a specific address, rather than the wildcard address then it is implementation
+ * specific if multicast datagrams are received by the socket. </p></li>
+ *
+ * <li><p> The {@link StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} option should be
+ * enabled prior to {@link NetworkChannel#bind binding} the socket. This is
+ * required to allow multiple members of the group to bind to the same
+ * address. </p></li>
+ *
+ * </ol>
+ *
+ * <p> <b>Usage Example:</b>
+ * <pre>
+ * // join multicast group on this interface, and also use this
+ * // interface for outgoing multicast datagrams
+ * NetworkInterface ni = NetworkInterface.getByName("hme0");
+ *
+ * DatagramChannel dc = DatagramChannel.open(StandardProtocolFamily.INET)
+ * .setOption(StandardSocketOptions.SO_REUSEADDR, true)
+ * .bind(new InetSocketAddress(5000))
+ * .setOption(StandardSocketOptions.IP_MULTICAST_IF, ni);
+ *
+ * InetAddress group = InetAddress.getByName("225.4.5.6");
+ *
+ * MembershipKey key = dc.join(group, ni);
+ * </pre>
+ *
+ * @since 1.7
+ */
+
+public interface MulticastChannel
+ extends NetworkChannel
+{
+ /**
+ * Closes this channel.
+ *
+ * <p> If the channel is a member of a multicast group then the membership
+ * is {@link MembershipKey#drop dropped}. Upon return, the {@link
+ * MembershipKey membership-key} will be {@link MembershipKey#isValid
+ * invalid}.
+ *
+ * <p> This method otherwise behaves exactly as specified by the {@link
+ * Channel} interface.
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ @Override void close() throws IOException;
+
+ /**
+ * Joins a multicast group to begin receiving all datagrams sent to the group,
+ * returning a membership key.
+ *
+ * <p> If this channel is currently a member of the group on the given
+ * interface to receive all datagrams then the membership key, representing
+ * that membership, is returned. Otherwise this channel joins the group and
+ * the resulting new membership key is returned. The resulting membership key
+ * is not {@link MembershipKey#sourceAddress source-specific}.
+ *
+ * <p> A multicast channel may join several multicast groups, including
+ * the same group on more than one interface. An implementation may impose a
+ * limit on the number of groups that may be joined at the same time.
+ *
+ * @param group
+ * The multicast address to join
+ * @param interf
+ * The network interface on which to join the group
+ *
+ * @return The membership key
+ *
+ * @throws IllegalArgumentException
+ * If the group parameter is not a {@link InetAddress#isMulticastAddress
+ * multicast} address, or the group parameter is an address type
+ * that is not supported by this channel
+ * @throws IllegalStateException
+ * If the channel already has source-specific membership of the
+ * group on the interface
+ * @throws UnsupportedOperationException
+ * If the channel's socket is not an Internet Protocol socket
+ * @throws ClosedChannelException
+ * If this channel is closed
+ * @throws IOException
+ * If an I/O error occurs
+ * @throws SecurityException
+ * If a security manager is set, and its
+ * {@link SecurityManager#checkMulticast(InetAddress) checkMulticast}
+ * method denies access to the multiast group
+ */
+ MembershipKey join(InetAddress group, NetworkInterface interf)
+ throws IOException;
+
+ /**
+ * Joins a multicast group to begin receiving datagrams sent to the group
+ * from a given source address.
+ *
+ * <p> If this channel is currently a member of the group on the given
+ * interface to receive datagrams from the given source address then the
+ * membership key, representing that membership, is returned. Otherwise this
+ * channel joins the group and the resulting new membership key is returned.
+ * The resulting membership key is {@link MembershipKey#sourceAddress
+ * source-specific}.
+ *
+ * <p> Membership is <em>cumulative</em> and this method may be invoked
+ * again with the same group and interface to allow receiving datagrams sent
+ * by other source addresses to the group.
+ *
+ * @param group
+ * The multicast address to join
+ * @param interf
+ * The network interface on which to join the group
+ * @param source
+ * The source address
+ *
+ * @return The membership key
+ *
+ * @throws IllegalArgumentException
+ * If the group parameter is not a {@link
+ * InetAddress#isMulticastAddress multicast} address, the
+ * source parameter is not a unicast address, the group
+ * parameter is an address type that is not supported by this channel,
+ * or the source parameter is not the same address type as the group
+ * @throws IllegalStateException
+ * If the channel is currently a member of the group on the given
+ * interface to receive all datagrams
+ * @throws UnsupportedOperationException
+ * If the channel's socket is not an Internet Protocol socket or
+ * source filtering is not supported
+ * @throws ClosedChannelException
+ * If this channel is closed
+ * @throws IOException
+ * If an I/O error occurs
+ * @throws SecurityException
+ * If a security manager is set, and its
+ * {@link SecurityManager#checkMulticast(InetAddress) checkMulticast}
+ * method denies access to the multiast group
+ */
+ MembershipKey join(InetAddress group, NetworkInterface interf, InetAddress source)
+ throws IOException;
+}
diff --git a/java/nio/channels/NetworkChannel.java b/java/nio/channels/NetworkChannel.java
new file mode 100644
index 0000000..65a7c22
--- /dev/null
+++ b/java/nio/channels/NetworkChannel.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+import java.net.SocketOption;
+import java.net.SocketAddress;
+import java.util.Set;
+import java.io.IOException;
+
+/**
+ * A channel to a network socket.
+ *
+ * <p> A channel that implements this interface is a channel to a network
+ * socket. The {@link #bind(SocketAddress) bind} method is used to bind the
+ * socket to a local {@link SocketAddress address}, the {@link #getLocalAddress()
+ * getLocalAddress} method returns the address that the socket is bound to, and
+ * the {@link #setOption(SocketOption,Object) setOption} and {@link
+ * #getOption(SocketOption) getOption} methods are used to set and query socket
+ * options. An implementation of this interface should specify the socket options
+ * that it supports.
+ *
+ * <p> The {@link #bind bind} and {@link #setOption setOption} methods that do
+ * not otherwise have a value to return are specified to return the network
+ * channel upon which they are invoked. This allows method invocations to be
+ * chained. Implementations of this interface should specialize the return type
+ * so that method invocations on the implementation class can be chained.
+ *
+ * @since 1.7
+ */
+
+public interface NetworkChannel
+ extends Channel
+{
+ /**
+ * Binds the channel's socket to a local address.
+ *
+ * <p> This method is used to establish an association between the socket and
+ * a local address. Once an association is established then the socket remains
+ * bound until the channel is closed. If the {@code local} parameter has the
+ * value {@code null} then the socket will be bound to an address that is
+ * assigned automatically.
+ *
+ * @param local
+ * The address to bind the socket, or {@code null} to bind the socket
+ * to an automatically assigned socket address
+ *
+ * @return This channel
+ *
+ * @throws AlreadyBoundException
+ * If the socket is already bound
+ * @throws UnsupportedAddressTypeException
+ * If the type of the given address is not supported
+ * @throws ClosedChannelException
+ * If the channel is closed
+ * @throws IOException
+ * If some other I/O error occurs
+ * @throws SecurityException
+ * If a security manager is installed and it denies an unspecified
+ * permission. An implementation of this interface should specify
+ * any required permissions.
+ *
+ * @see #getLocalAddress
+ */
+ NetworkChannel bind(SocketAddress local) throws IOException;
+
+ /**
+ * Returns the socket address that this channel's socket is bound to.
+ *
+ * <p> Where the channel is {@link #bind bound} to an Internet Protocol
+ * socket address then the return value from this method is of type {@link
+ * java.net.InetSocketAddress}.
+ *
+ * @return The socket address that the socket is bound to, or {@code null}
+ * if the channel's socket is not bound
+ *
+ * @throws ClosedChannelException
+ * If the channel is closed
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ SocketAddress getLocalAddress() throws IOException;
+
+ /**
+ * Sets the value of a socket option.
+ *
+ * @param <T>
+ * The type of the socket option value
+ * @param name
+ * The socket option
+ * @param value
+ * The value of the socket option. A value of {@code null} may be
+ * a valid value for some socket options.
+ *
+ * @return This channel
+ *
+ * @throws UnsupportedOperationException
+ * If the socket option is not supported by this channel
+ * @throws IllegalArgumentException
+ * If the value is not a valid value for this socket option
+ * @throws ClosedChannelException
+ * If this channel is closed
+ * @throws IOException
+ * If an I/O error occurs
+ *
+ * @see java.net.StandardSocketOptions
+ */
+ <T> NetworkChannel setOption(SocketOption<T> name, T value) throws IOException;
+
+ /**
+ * Returns the value of a socket option.
+ *
+ * @param <T>
+ * The type of the socket option value
+ * @param name
+ * The socket option
+ *
+ * @return The value of the socket option. A value of {@code null} may be
+ * a valid value for some socket options.
+ *
+ * @throws UnsupportedOperationException
+ * If the socket option is not supported by this channel
+ * @throws ClosedChannelException
+ * If this channel is closed
+ * @throws IOException
+ * If an I/O error occurs
+ *
+ * @see java.net.StandardSocketOptions
+ */
+ <T> T getOption(SocketOption<T> name) throws IOException;
+
+ /**
+ * Returns a set of the socket options supported by this channel.
+ *
+ * <p> This method will continue to return the set of options even after the
+ * channel has been closed.
+ *
+ * @return A set of the socket options supported by this channel
+ */
+ Set<SocketOption<?>> supportedOptions();
+}
diff --git a/java/nio/channels/NoConnectionPendingException.java b/java/nio/channels/NoConnectionPendingException.java
new file mode 100644
index 0000000..cea5ad1
--- /dev/null
+++ b/java/nio/channels/NoConnectionPendingException.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when the {@link SocketChannel#finishConnect
+ * finishConnect} method of a {@link SocketChannel} is invoked without first
+ * successfully invoking its {@link SocketChannel#connect connect} method.
+ *
+ * @since 1.4
+ */
+
+public class NoConnectionPendingException
+ extends IllegalStateException
+{
+
+ private static final long serialVersionUID = -8296561183633134743L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public NoConnectionPendingException() { }
+
+}
diff --git a/java/nio/channels/NonReadableChannelException.java b/java/nio/channels/NonReadableChannelException.java
new file mode 100644
index 0000000..ddfa7fa
--- /dev/null
+++ b/java/nio/channels/NonReadableChannelException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to read
+ * from a channel that was not originally opened for reading.
+ *
+ * @since 1.4
+ */
+
+public class NonReadableChannelException
+ extends IllegalStateException
+{
+
+ private static final long serialVersionUID = -3200915679294993514L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public NonReadableChannelException() { }
+
+}
diff --git a/java/nio/channels/NonWritableChannelException.java b/java/nio/channels/NonWritableChannelException.java
new file mode 100644
index 0000000..17c90f3
--- /dev/null
+++ b/java/nio/channels/NonWritableChannelException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to write
+ * to a channel that was not originally opened for writing.
+ *
+ * @since 1.4
+ */
+
+public class NonWritableChannelException
+ extends IllegalStateException
+{
+
+ private static final long serialVersionUID = -7071230488279011621L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public NonWritableChannelException() { }
+
+}
diff --git a/java/nio/channels/NotYetBoundException.java b/java/nio/channels/NotYetBoundException.java
new file mode 100644
index 0000000..b6c6af3
--- /dev/null
+++ b/java/nio/channels/NotYetBoundException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to invoke an I/O
+ * operation upon a server socket channel that is not yet bound.
+ *
+ * @since 1.4
+ */
+
+public class NotYetBoundException
+ extends IllegalStateException
+{
+
+ private static final long serialVersionUID = 4640999303950202242L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public NotYetBoundException() { }
+
+}
diff --git a/java/nio/channels/NotYetConnectedException.java b/java/nio/channels/NotYetConnectedException.java
new file mode 100644
index 0000000..9e56d07
--- /dev/null
+++ b/java/nio/channels/NotYetConnectedException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to invoke an I/O
+ * operation upon a socket channel that is not yet connected.
+ *
+ * @since 1.4
+ */
+
+public class NotYetConnectedException
+ extends IllegalStateException
+{
+
+ private static final long serialVersionUID = 4697316551909513464L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public NotYetConnectedException() { }
+
+}
diff --git a/java/nio/channels/OverlappingFileLockException.java b/java/nio/channels/OverlappingFileLockException.java
new file mode 100644
index 0000000..7dd8f24
--- /dev/null
+++ b/java/nio/channels/OverlappingFileLockException.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to acquire a lock on a
+ * region of a file that overlaps a region already locked by the same Java
+ * virtual machine, or when another thread is already waiting to lock an
+ * overlapping region of the same file.
+ *
+ * @since 1.4
+ */
+
+public class OverlappingFileLockException
+ extends IllegalStateException
+{
+
+ private static final long serialVersionUID = 2047812138163068433L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public OverlappingFileLockException() { }
+
+}
diff --git a/java/nio/channels/Pipe.java b/java/nio/channels/Pipe.java
new file mode 100644
index 0000000..d704680
--- /dev/null
+++ b/java/nio/channels/Pipe.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+import java.io.IOException;
+import java.nio.channels.spi.*;
+
+
+/**
+ * A pair of channels that implements a unidirectional pipe.
+ *
+ * <p> A pipe consists of a pair of channels: A writable {@link
+ * Pipe.SinkChannel sink} channel and a readable {@link Pipe.SourceChannel source}
+ * channel. Once some bytes are written to the sink channel they can be read
+ * from source channel in exactlyAthe order in which they were written.
+ *
+ * <p> Whether or not a thread writing bytes to a pipe will block until another
+ * thread reads those bytes, or some previously-written bytes, from the pipe is
+ * system-dependent and therefore unspecified. Many pipe implementations will
+ * buffer up to a certain number of bytes between the sink and source channels,
+ * but such buffering should not be assumed. </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class Pipe {
+
+ /**
+ * A channel representing the readable end of a {@link Pipe}.
+ *
+ * @since 1.4
+ */
+ public static abstract class SourceChannel
+ extends AbstractSelectableChannel
+ implements ReadableByteChannel, ScatteringByteChannel
+ {
+ /**
+ * Constructs a new instance of this class.
+ *
+ * @param provider
+ * The selector provider
+ */
+ protected SourceChannel(SelectorProvider provider) {
+ super(provider);
+ }
+
+ /**
+ * Returns an operation set identifying this channel's supported
+ * operations.
+ *
+ * <p> Pipe-source channels only support reading, so this method
+ * returns {@link SelectionKey#OP_READ}. </p>
+ *
+ * @return The valid-operation set
+ */
+ public final int validOps() {
+ return SelectionKey.OP_READ;
+ }
+
+ }
+
+ /**
+ * A channel representing the writable end of a {@link Pipe}.
+ *
+ * @since 1.4
+ */
+ public static abstract class SinkChannel
+ extends AbstractSelectableChannel
+ implements WritableByteChannel, GatheringByteChannel
+ {
+ /**
+ * Initializes a new instance of this class.
+ *
+ * @param provider
+ * The selector provider
+ */
+ protected SinkChannel(SelectorProvider provider) {
+ super(provider);
+ }
+
+ /**
+ * Returns an operation set identifying this channel's supported
+ * operations.
+ *
+ * <p> Pipe-sink channels only support writing, so this method returns
+ * {@link SelectionKey#OP_WRITE}. </p>
+ *
+ * @return The valid-operation set
+ */
+ public final int validOps() {
+ return SelectionKey.OP_WRITE;
+ }
+
+ }
+
+ /**
+ * Initializes a new instance of this class.
+ */
+ protected Pipe() { }
+
+ /**
+ * Returns this pipe's source channel.
+ *
+ * @return This pipe's source channel
+ */
+ public abstract SourceChannel source();
+
+ /**
+ * Returns this pipe's sink channel.
+ *
+ * @return This pipe's sink channel
+ */
+ public abstract SinkChannel sink();
+
+ /**
+ * Opens a pipe.
+ *
+ * <p> The new pipe is created by invoking the {@link
+ * java.nio.channels.spi.SelectorProvider#openPipe openPipe} method of the
+ * system-wide default {@link java.nio.channels.spi.SelectorProvider}
+ * object. </p>
+ *
+ * @return A new pipe
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ public static Pipe open() throws IOException {
+ return SelectorProvider.provider().openPipe();
+ }
+
+}
diff --git a/java/nio/channels/ReadPendingException.java b/java/nio/channels/ReadPendingException.java
new file mode 100644
index 0000000..770c9de
--- /dev/null
+++ b/java/nio/channels/ReadPendingException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to read from an
+ * asynchronous socket channel and a previous read has not completed.
+ *
+ * @since 1.7
+ */
+
+public class ReadPendingException
+ extends IllegalStateException
+{
+
+ private static final long serialVersionUID = 1986315242191227217L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public ReadPendingException() { }
+
+}
diff --git a/java/nio/channels/ReadableByteChannel.java b/java/nio/channels/ReadableByteChannel.java
new file mode 100644
index 0000000..4cd99c0
--- /dev/null
+++ b/java/nio/channels/ReadableByteChannel.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+
+/**
+ * A channel that can read bytes.
+ *
+ * <p> Only one read operation upon a readable channel may be in progress at
+ * any given time. If one thread initiates a read operation upon a channel
+ * then any other thread that attempts to initiate another read operation will
+ * block until the first operation is complete. Whether or not other kinds of
+ * I/O operations may proceed concurrently with a read operation depends upon
+ * the type of the channel. </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public interface ReadableByteChannel extends Channel {
+
+ /**
+ * Reads a sequence of bytes from this channel into the given buffer.
+ *
+ * <p> An attempt is made to read up to <i>r</i> bytes from the channel,
+ * where <i>r</i> is the number of bytes remaining in the buffer, that is,
+ * <tt>dst.remaining()</tt>, at the moment this method is invoked.
+ *
+ * <p> Suppose that a byte sequence of length <i>n</i> is read, where
+ * <tt>0</tt> <tt><=</tt> <i>n</i> <tt><=</tt> <i>r</i>.
+ * This byte sequence will be transferred into the buffer so that the first
+ * byte in the sequence is at index <i>p</i> and the last byte is at index
+ * <i>p</i> <tt>+</tt> <i>n</i> <tt>-</tt> <tt>1</tt>,
+ * where <i>p</i> is the buffer's position at the moment this method is
+ * invoked. Upon return the buffer's position will be equal to
+ * <i>p</i> <tt>+</tt> <i>n</i>; its limit will not have changed.
+ *
+ * <p> A read operation might not fill the buffer, and in fact it might not
+ * read any bytes at all. Whether or not it does so depends upon the
+ * nature and state of the channel. A socket channel in non-blocking mode,
+ * for example, cannot read any more bytes than are immediately available
+ * from the socket's input buffer; similarly, a file channel cannot read
+ * any more bytes than remain in the file. It is guaranteed, however, that
+ * if a channel is in blocking mode and there is at least one byte
+ * remaining in the buffer then this method will block until at least one
+ * byte is read.
+ *
+ * <p> This method may be invoked at any time. If another thread has
+ * already initiated a read operation upon this channel, however, then an
+ * invocation of this method will block until the first operation is
+ * complete. </p>
+ *
+ * @param dst
+ * The buffer into which bytes are to be transferred
+ *
+ * @return The number of bytes read, possibly zero, or <tt>-1</tt> if the
+ * channel has reached end-of-stream
+ *
+ * @throws NonReadableChannelException
+ * If this channel was not opened for reading
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ *
+ * @throws AsynchronousCloseException
+ * If another thread closes this channel
+ * while the read operation is in progress
+ *
+ * @throws ClosedByInterruptException
+ * If another thread interrupts the current thread
+ * while the read operation is in progress, thereby
+ * closing the channel and setting the current thread's
+ * interrupt status
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public int read(ByteBuffer dst) throws IOException;
+
+}
diff --git a/java/nio/channels/ScatteringByteChannel.java b/java/nio/channels/ScatteringByteChannel.java
new file mode 100644
index 0000000..7922909
--- /dev/null
+++ b/java/nio/channels/ScatteringByteChannel.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+
+/**
+ * A channel that can read bytes into a sequence of buffers.
+ *
+ * <p> A <i>scattering</i> read operation reads, in a single invocation, a
+ * sequence of bytes into one or more of a given sequence of buffers.
+ * Scattering reads are often useful when implementing network protocols or
+ * file formats that, for example, group data into segments consisting of one
+ * or more fixed-length headers followed by a variable-length body. Similar
+ * <i>gathering</i> write operations are defined in the {@link
+ * GatheringByteChannel} interface. </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public interface ScatteringByteChannel
+ extends ReadableByteChannel
+{
+
+ /**
+ * Reads a sequence of bytes from this channel into a subsequence of the
+ * given buffers.
+ *
+ * <p> An invocation of this method attempts to read up to <i>r</i> bytes
+ * from this channel, where <i>r</i> is the total number of bytes remaining
+ * the specified subsequence of the given buffer array, that is,
+ *
+ * <blockquote><pre>
+ * dsts[offset].remaining()
+ * + dsts[offset+1].remaining()
+ * + ... + dsts[offset+length-1].remaining()</pre></blockquote>
+ *
+ * at the moment that this method is invoked.
+ *
+ * <p> Suppose that a byte sequence of length <i>n</i> is read, where
+ * <tt>0</tt> <tt><=</tt> <i>n</i> <tt><=</tt> <i>r</i>.
+ * Up to the first <tt>dsts[offset].remaining()</tt> bytes of this sequence
+ * are transferred into buffer <tt>dsts[offset]</tt>, up to the next
+ * <tt>dsts[offset+1].remaining()</tt> bytes are transferred into buffer
+ * <tt>dsts[offset+1]</tt>, and so forth, until the entire byte sequence
+ * is transferred into the given buffers. As many bytes as possible are
+ * transferred into each buffer, hence the final position of each updated
+ * buffer, except the last updated buffer, is guaranteed to be equal to
+ * that buffer's limit.
+ *
+ * <p> This method may be invoked at any time. If another thread has
+ * already initiated a read operation upon this channel, however, then an
+ * invocation of this method will block until the first operation is
+ * complete. </p>
+ *
+ * @param dsts
+ * The buffers into which bytes are to be transferred
+ *
+ * @param offset
+ * The offset within the buffer array of the first buffer into
+ * which bytes are to be transferred; must be non-negative and no
+ * larger than <tt>dsts.length</tt>
+ *
+ * @param length
+ * The maximum number of buffers to be accessed; must be
+ * non-negative and no larger than
+ * <tt>dsts.length</tt> - <tt>offset</tt>
+ *
+ * @return The number of bytes read, possibly zero,
+ * or <tt>-1</tt> if the channel has reached end-of-stream
+ *
+ * @throws IndexOutOfBoundsException
+ * If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+ * parameters do not hold
+ *
+ * @throws NonReadableChannelException
+ * If this channel was not opened for reading
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ *
+ * @throws AsynchronousCloseException
+ * If another thread closes this channel
+ * while the read operation is in progress
+ *
+ * @throws ClosedByInterruptException
+ * If another thread interrupts the current thread
+ * while the read operation is in progress, thereby
+ * closing the channel and setting the current thread's
+ * interrupt status
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public long read(ByteBuffer[] dsts, int offset, int length)
+ throws IOException;
+
+ /**
+ * Reads a sequence of bytes from this channel into the given buffers.
+ *
+ * <p> An invocation of this method of the form <tt>c.read(dsts)</tt>
+ * behaves in exactly the same manner as the invocation
+ *
+ * <blockquote><pre>
+ * c.read(dsts, 0, dsts.length);</pre></blockquote>
+ *
+ * @param dsts
+ * The buffers into which bytes are to be transferred
+ *
+ * @return The number of bytes read, possibly zero,
+ * or <tt>-1</tt> if the channel has reached end-of-stream
+ *
+ * @throws NonReadableChannelException
+ * If this channel was not opened for reading
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ *
+ * @throws AsynchronousCloseException
+ * If another thread closes this channel
+ * while the read operation is in progress
+ *
+ * @throws ClosedByInterruptException
+ * If another thread interrupts the current thread
+ * while the read operation is in progress, thereby
+ * closing the channel and setting the current thread's
+ * interrupt status
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public long read(ByteBuffer[] dsts) throws IOException;
+
+}
diff --git a/java/nio/channels/SeekableByteChannel.java b/java/nio/channels/SeekableByteChannel.java
new file mode 100644
index 0000000..3f5be1c
--- /dev/null
+++ b/java/nio/channels/SeekableByteChannel.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+import java.nio.ByteBuffer;
+import java.io.IOException;
+
+/**
+ * A byte channel that maintains a current <i>position</i> and allows the
+ * position to be changed.
+ *
+ * <p> A seekable byte channel is connected to an entity, typically a file,
+ * that contains a variable-length sequence of bytes that can be read and
+ * written. The current position can be {@link #position() <i>queried</i>} and
+ * {@link #position(long) <i>modified</i>}. The channel also provides access to
+ * the current <i>size</i> of the entity to which the channel is connected. The
+ * size increases when bytes are written beyond its current size; the size
+ * decreases when it is {@link #truncate <i>truncated</i>}.
+ *
+ * <p> The {@link #position(long) position} and {@link #truncate truncate} methods
+ * which do not otherwise have a value to return are specified to return the
+ * channel upon which they are invoked. This allows method invocations to be
+ * chained. Implementations of this interface should specialize the return type
+ * so that method invocations on the implementation class can be chained.
+ *
+ * @since 1.7
+ * @see java.nio.file.Files#newByteChannel
+ */
+
+public interface SeekableByteChannel
+ extends ByteChannel
+{
+ /**
+ * Reads a sequence of bytes from this channel into the given buffer.
+ *
+ * <p> Bytes are read starting at this channel's current position, and
+ * then the position is updated with the number of bytes actually read.
+ * Otherwise this method behaves exactly as specified in the {@link
+ * ReadableByteChannel} interface.
+ */
+ @Override
+ int read(ByteBuffer dst) throws IOException;
+
+ /**
+ * Writes a sequence of bytes to this channel from the given buffer.
+ *
+ * <p> Bytes are written starting at this channel's current position, unless
+ * the channel is connected to an entity such as a file that is opened with
+ * the {@link java.nio.file.StandardOpenOption#APPEND APPEND} option, in
+ * which case the position is first advanced to the end. The entity to which
+ * the channel is connected is grown, if necessary, to accommodate the
+ * written bytes, and then the position is updated with the number of bytes
+ * actually written. Otherwise this method behaves exactly as specified by
+ * the {@link WritableByteChannel} interface.
+ */
+ @Override
+ int write(ByteBuffer src) throws IOException;
+
+ /**
+ * Returns this channel's position.
+ *
+ * @return This channel's position,
+ * a non-negative integer counting the number of bytes
+ * from the beginning of the entity to the current position
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ long position() throws IOException;
+
+ /**
+ * Sets this channel's position.
+ *
+ * <p> Setting the position to a value that is greater than the current size
+ * is legal but does not change the size of the entity. A later attempt to
+ * read bytes at such a position will immediately return an end-of-file
+ * indication. A later attempt to write bytes at such a position will cause
+ * the entity to grow to accommodate the new bytes; the values of any bytes
+ * between the previous end-of-file and the newly-written bytes are
+ * unspecified.
+ *
+ * <p> Setting the channel's position is not recommended when connected to
+ * an entity, typically a file, that is opened with the {@link
+ * java.nio.file.StandardOpenOption#APPEND APPEND} option. When opened for
+ * append, the position is first advanced to the end before writing.
+ *
+ * @param newPosition
+ * The new position, a non-negative integer counting
+ * the number of bytes from the beginning of the entity
+ *
+ * @return This channel
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ * @throws IllegalArgumentException
+ * If the new position is negative
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ SeekableByteChannel position(long newPosition) throws IOException;
+
+ /**
+ * Returns the current size of entity to which this channel is connected.
+ *
+ * @return The current size, measured in bytes
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ long size() throws IOException;
+
+ /**
+ * Truncates the entity, to which this channel is connected, to the given
+ * size.
+ *
+ * <p> If the given size is less than the current size then the entity is
+ * truncated, discarding any bytes beyond the new end. If the given size is
+ * greater than or equal to the current size then the entity is not modified.
+ * In either case, if the current position is greater than the given size
+ * then it is set to that size.
+ *
+ * <p> An implementation of this interface may prohibit truncation when
+ * connected to an entity, typically a file, opened with the {@link
+ * java.nio.file.StandardOpenOption#APPEND APPEND} option.
+ *
+ * @param size
+ * The new size, a non-negative byte count
+ *
+ * @return This channel
+ *
+ * @throws NonWritableChannelException
+ * If this channel was not opened for writing
+ * @throws ClosedChannelException
+ * If this channel is closed
+ * @throws IllegalArgumentException
+ * If the new size is negative
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ SeekableByteChannel truncate(long size) throws IOException;
+}
diff --git a/java/nio/channels/SelectableChannel.java b/java/nio/channels/SelectableChannel.java
new file mode 100644
index 0000000..997d5c5
--- /dev/null
+++ b/java/nio/channels/SelectableChannel.java
@@ -0,0 +1,344 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+import java.io.IOException;
+import java.nio.channels.spi.AbstractInterruptibleChannel;
+import java.nio.channels.spi.SelectorProvider;
+
+
+/**
+ * A channel that can be multiplexed via a {@link Selector}.
+ *
+ * <p> In order to be used with a selector, an instance of this class must
+ * first be <i>registered</i> via the {@link #register(Selector,int,Object)
+ * register} method. This method returns a new {@link SelectionKey} object
+ * that represents the channel's registration with the selector.
+ *
+ * <p> Once registered with a selector, a channel remains registered until it
+ * is <i>deregistered</i>. This involves deallocating whatever resources were
+ * allocated to the channel by the selector.
+ *
+ * <p> A channel cannot be deregistered directly; instead, the key representing
+ * its registration must be <i>cancelled</i>. Cancelling a key requests that
+ * the channel be deregistered during the selector's next selection operation.
+ * A key may be cancelled explicitly by invoking its {@link
+ * SelectionKey#cancel() cancel} method. All of a channel's keys are cancelled
+ * implicitly when the channel is closed, whether by invoking its {@link
+ * Channel#close close} method or by interrupting a thread blocked in an I/O
+ * operation upon the channel.
+ *
+ * <p> If the selector itself is closed then the channel will be deregistered,
+ * and the key representing its registration will be invalidated, without
+ * further delay.
+ *
+ * <p> A channel may be registered at most once with any particular selector.
+ *
+ * <p> Whether or not a channel is registered with one or more selectors may be
+ * determined by invoking the {@link #isRegistered isRegistered} method.
+ *
+ * <p> Selectable channels are safe for use by multiple concurrent
+ * threads. </p>
+ *
+ *
+ * <a name="bm"></a>
+ * <h2>Blocking mode</h2>
+ *
+ * A selectable channel is either in <i>blocking</i> mode or in
+ * <i>non-blocking</i> mode. In blocking mode, every I/O operation invoked
+ * upon the channel will block until it completes. In non-blocking mode an I/O
+ * operation will never block and may transfer fewer bytes than were requested
+ * or possibly no bytes at all. The blocking mode of a selectable channel may
+ * be determined by invoking its {@link #isBlocking isBlocking} method.
+ *
+ * <p> Newly-created selectable channels are always in blocking mode.
+ * Non-blocking mode is most useful in conjunction with selector-based
+ * multiplexing. A channel must be placed into non-blocking mode before being
+ * registered with a selector, and may not be returned to blocking mode until
+ * it has been deregistered.
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ *
+ * @see SelectionKey
+ * @see Selector
+ */
+
+public abstract class SelectableChannel
+ extends AbstractInterruptibleChannel
+ implements Channel
+{
+
+ /**
+ * Initializes a new instance of this class.
+ */
+ protected SelectableChannel() { }
+
+ /**
+ * Returns the provider that created this channel.
+ *
+ * @return The provider that created this channel
+ */
+ public abstract SelectorProvider provider();
+
+ /**
+ * Returns an <a href="SelectionKey.html#opsets">operation set</a>
+ * identifying this channel's supported operations. The bits that are set
+ * in this integer value denote exactly the operations that are valid for
+ * this channel. This method always returns the same value for a given
+ * concrete channel class.
+ *
+ * @return The valid-operation set
+ */
+ public abstract int validOps();
+
+ // Internal state:
+ // keySet, may be empty but is never null, typ. a tiny array
+ // boolean isRegistered, protected by key set
+ // regLock, lock object to prevent duplicate registrations
+ // boolean isBlocking, protected by regLock
+
+ /**
+ * Tells whether or not this channel is currently registered with any
+ * selectors. A newly-created channel is not registered.
+ *
+ * <p> Due to the inherent delay between key cancellation and channel
+ * deregistration, a channel may remain registered for some time after all
+ * of its keys have been cancelled. A channel may also remain registered
+ * for some time after it is closed. </p>
+ *
+ * @return <tt>true</tt> if, and only if, this channel is registered
+ */
+ public abstract boolean isRegistered();
+ //
+ // sync(keySet) { return isRegistered; }
+
+ /**
+ * Retrieves the key representing the channel's registration with the given
+ * selector.
+ *
+ * @param sel
+ * The selector
+ *
+ * @return The key returned when this channel was last registered with the
+ * given selector, or <tt>null</tt> if this channel is not
+ * currently registered with that selector
+ */
+ public abstract SelectionKey keyFor(Selector sel);
+ //
+ // sync(keySet) { return findKey(sel); }
+
+ /**
+ * Registers this channel with the given selector, returning a selection
+ * key.
+ *
+ * <p> If this channel is currently registered with the given selector then
+ * the selection key representing that registration is returned. The key's
+ * interest set will have been changed to <tt>ops</tt>, as if by invoking
+ * the {@link SelectionKey#interestOps(int) interestOps(int)} method. If
+ * the <tt>att</tt> argument is not <tt>null</tt> then the key's attachment
+ * will have been set to that value. A {@link CancelledKeyException} will
+ * be thrown if the key has already been cancelled.
+ *
+ * <p> Otherwise this channel has not yet been registered with the given
+ * selector, so it is registered and the resulting new key is returned.
+ * The key's initial interest set will be <tt>ops</tt> and its attachment
+ * will be <tt>att</tt>.
+ *
+ * <p> This method may be invoked at any time. If this method is invoked
+ * while another invocation of this method or of the {@link
+ * #configureBlocking(boolean) configureBlocking} method is in progress
+ * then it will first block until the other operation is complete. This
+ * method will then synchronize on the selector's key set and therefore may
+ * block if invoked concurrently with another registration or selection
+ * operation involving the same selector. </p>
+ *
+ * <p> If this channel is closed while this operation is in progress then
+ * the key returned by this method will have been cancelled and will
+ * therefore be invalid. </p>
+ *
+ * @param sel
+ * The selector with which this channel is to be registered
+ *
+ * @param ops
+ * The interest set for the resulting key
+ *
+ * @param att
+ * The attachment for the resulting key; may be <tt>null</tt>
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ *
+ * @throws ClosedSelectorException
+ * If the selector is closed
+ *
+ * @throws IllegalBlockingModeException
+ * If this channel is in blocking mode
+ *
+ * @throws IllegalSelectorException
+ * If this channel was not created by the same provider
+ * as the given selector
+ *
+ * @throws CancelledKeyException
+ * If this channel is currently registered with the given selector
+ * but the corresponding key has already been cancelled
+ *
+ * @throws IllegalArgumentException
+ * If a bit in the <tt>ops</tt> set does not correspond to an
+ * operation that is supported by this channel, that is, if
+ * {@code set & ~validOps() != 0}
+ *
+ * @return A key representing the registration of this channel with
+ * the given selector
+ */
+ public abstract SelectionKey register(Selector sel, int ops, Object att)
+ throws ClosedChannelException;
+ //
+ // sync(regLock) {
+ // sync(keySet) { look for selector }
+ // if (channel found) { set interest ops -- may block in selector;
+ // return key; }
+ // create new key -- may block somewhere in selector;
+ // sync(keySet) { add key; }
+ // attach(attachment);
+ // return key;
+ // }
+
+ /**
+ * Registers this channel with the given selector, returning a selection
+ * key.
+ *
+ * <p> An invocation of this convenience method of the form
+ *
+ * <blockquote><tt>sc.register(sel, ops)</tt></blockquote>
+ *
+ * behaves in exactly the same way as the invocation
+ *
+ * <blockquote><tt>sc.{@link
+ * #register(java.nio.channels.Selector,int,java.lang.Object)
+ * register}(sel, ops, null)</tt></blockquote>
+ *
+ * @param sel
+ * The selector with which this channel is to be registered
+ *
+ * @param ops
+ * The interest set for the resulting key
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ *
+ * @throws ClosedSelectorException
+ * If the selector is closed
+ *
+ * @throws IllegalBlockingModeException
+ * If this channel is in blocking mode
+ *
+ * @throws IllegalSelectorException
+ * If this channel was not created by the same provider
+ * as the given selector
+ *
+ * @throws CancelledKeyException
+ * If this channel is currently registered with the given selector
+ * but the corresponding key has already been cancelled
+ *
+ * @throws IllegalArgumentException
+ * If a bit in <tt>ops</tt> does not correspond to an operation
+ * that is supported by this channel, that is, if {@code set &
+ * ~validOps() != 0}
+ *
+ * @return A key representing the registration of this channel with
+ * the given selector
+ */
+ public final SelectionKey register(Selector sel, int ops)
+ throws ClosedChannelException
+ {
+ return register(sel, ops, null);
+ }
+
+ /**
+ * Adjusts this channel's blocking mode.
+ *
+ * <p> If this channel is registered with one or more selectors then an
+ * attempt to place it into blocking mode will cause an {@link
+ * IllegalBlockingModeException} to be thrown.
+ *
+ * <p> This method may be invoked at any time. The new blocking mode will
+ * only affect I/O operations that are initiated after this method returns.
+ * For some implementations this may require blocking until all pending I/O
+ * operations are complete.
+ *
+ * <p> If this method is invoked while another invocation of this method or
+ * of the {@link #register(Selector, int) register} method is in progress
+ * then it will first block until the other operation is complete. </p>
+ *
+ * @param block If <tt>true</tt> then this channel will be placed in
+ * blocking mode; if <tt>false</tt> then it will be placed
+ * non-blocking mode
+ *
+ * @return This selectable channel
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ *
+ * @throws IllegalBlockingModeException
+ * If <tt>block</tt> is <tt>true</tt> and this channel is
+ * registered with one or more selectors
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ public abstract SelectableChannel configureBlocking(boolean block)
+ throws IOException;
+ //
+ // sync(regLock) {
+ // sync(keySet) { throw IBME if block && isRegistered; }
+ // change mode;
+ // }
+
+ /**
+ * Tells whether or not every I/O operation on this channel will block
+ * until it completes. A newly-created channel is always in blocking mode.
+ *
+ * <p> If this channel is closed then the value returned by this method is
+ * not specified. </p>
+ *
+ * @return <tt>true</tt> if, and only if, this channel is in blocking mode
+ */
+ public abstract boolean isBlocking();
+
+ /**
+ * Retrieves the object upon which the {@link #configureBlocking
+ * configureBlocking} and {@link #register register} methods synchronize.
+ * This is often useful in the implementation of adaptors that require a
+ * specific blocking mode to be maintained for a short period of time.
+ *
+ * @return The blocking-mode lock object
+ */
+ public abstract Object blockingLock();
+
+}
diff --git a/java/nio/channels/SelectionKey.java b/java/nio/channels/SelectionKey.java
new file mode 100644
index 0000000..00ea670
--- /dev/null
+++ b/java/nio/channels/SelectionKey.java
@@ -0,0 +1,401 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
+import java.io.IOException;
+
+
+/**
+ * A token representing the registration of a {@link SelectableChannel} with a
+ * {@link Selector}.
+ *
+ * <p> A selection key is created each time a channel is registered with a
+ * selector. A key remains valid until it is <i>cancelled</i> by invoking its
+ * {@link #cancel cancel} method, by closing its channel, or by closing its
+ * selector. Cancelling a key does not immediately remove it from its
+ * selector; it is instead added to the selector's <a
+ * href="Selector.html#ks"><i>cancelled-key set</i></a> for removal during the
+ * next selection operation. The validity of a key may be tested by invoking
+ * its {@link #isValid isValid} method.
+ *
+ * <a name="opsets"></a>
+ *
+ * <p> A selection key contains two <i>operation sets</i> represented as
+ * integer values. Each bit of an operation set denotes a category of
+ * selectable operations that are supported by the key's channel.
+ *
+ * <ul>
+ *
+ * <li><p> The <i>interest set</i> determines which operation categories will
+ * be tested for readiness the next time one of the selector's selection
+ * methods is invoked. The interest set is initialized with the value given
+ * when the key is created; it may later be changed via the {@link
+ * #interestOps(int)} method. </p></li>
+ *
+ * <li><p> The <i>ready set</i> identifies the operation categories for which
+ * the key's channel has been detected to be ready by the key's selector.
+ * The ready set is initialized to zero when the key is created; it may later
+ * be updated by the selector during a selection operation, but it cannot be
+ * updated directly. </p></li>
+ *
+ * </ul>
+ *
+ * <p> That a selection key's ready set indicates that its channel is ready for
+ * some operation category is a hint, but not a guarantee, that an operation in
+ * such a category may be performed by a thread without causing the thread to
+ * block. A ready set is most likely to be accurate immediately after the
+ * completion of a selection operation. It is likely to be made inaccurate by
+ * external events and by I/O operations that are invoked upon the
+ * corresponding channel.
+ *
+ * <p> This class defines all known operation-set bits, but precisely which
+ * bits are supported by a given channel depends upon the type of the channel.
+ * Each subclass of {@link SelectableChannel} defines an {@link
+ * SelectableChannel#validOps() validOps()} method which returns a set
+ * identifying just those operations that are supported by the channel. An
+ * attempt to set or test an operation-set bit that is not supported by a key's
+ * channel will result in an appropriate run-time exception.
+ *
+ * <p> It is often necessary to associate some application-specific data with a
+ * selection key, for example an object that represents the state of a
+ * higher-level protocol and handles readiness notifications in order to
+ * implement that protocol. Selection keys therefore support the
+ * <i>attachment</i> of a single arbitrary object to a key. An object can be
+ * attached via the {@link #attach attach} method and then later retrieved via
+ * the {@link #attachment() attachment} method.
+ *
+ * <p> Selection keys are safe for use by multiple concurrent threads. The
+ * operations of reading and writing the interest set will, in general, be
+ * synchronized with certain operations of the selector. Exactly how this
+ * synchronization is performed is implementation-dependent: In a naive
+ * implementation, reading or writing the interest set may block indefinitely
+ * if a selection operation is already in progress; in a high-performance
+ * implementation, reading or writing the interest set may block briefly, if at
+ * all. In any case, a selection operation will always use the interest-set
+ * value that was current at the moment that the operation began. </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ *
+ * @see SelectableChannel
+ * @see Selector
+ */
+
+public abstract class SelectionKey {
+
+ /**
+ * Constructs an instance of this class.
+ */
+ protected SelectionKey() { }
+
+
+ // -- Channel and selector operations --
+
+ /**
+ * Returns the channel for which this key was created. This method will
+ * continue to return the channel even after the key is cancelled.
+ *
+ * @return This key's channel
+ */
+ public abstract SelectableChannel channel();
+
+ /**
+ * Returns the selector for which this key was created. This method will
+ * continue to return the selector even after the key is cancelled.
+ *
+ * @return This key's selector
+ */
+ public abstract Selector selector();
+
+ /**
+ * Tells whether or not this key is valid.
+ *
+ * <p> A key is valid upon creation and remains so until it is cancelled,
+ * its channel is closed, or its selector is closed. </p>
+ *
+ * @return <tt>true</tt> if, and only if, this key is valid
+ */
+ public abstract boolean isValid();
+
+ /**
+ * Requests that the registration of this key's channel with its selector
+ * be cancelled. Upon return the key will be invalid and will have been
+ * added to its selector's cancelled-key set. The key will be removed from
+ * all of the selector's key sets during the next selection operation.
+ *
+ * <p> If this key has already been cancelled then invoking this method has
+ * no effect. Once cancelled, a key remains forever invalid. </p>
+ *
+ * <p> This method may be invoked at any time. It synchronizes on the
+ * selector's cancelled-key set, and therefore may block briefly if invoked
+ * concurrently with a cancellation or selection operation involving the
+ * same selector. </p>
+ */
+ public abstract void cancel();
+
+
+ // -- Operation-set accessors --
+
+ /**
+ * Retrieves this key's interest set.
+ *
+ * <p> It is guaranteed that the returned set will only contain operation
+ * bits that are valid for this key's channel.
+ *
+ * <p> This method may be invoked at any time. Whether or not it blocks,
+ * and for how long, is implementation-dependent. </p>
+ *
+ * @return This key's interest set
+ *
+ * @throws CancelledKeyException
+ * If this key has been cancelled
+ */
+ public abstract int interestOps();
+
+ /**
+ * Sets this key's interest set to the given value.
+ *
+ * <p> This method may be invoked at any time. Whether or not it blocks,
+ * and for how long, is implementation-dependent. </p>
+ *
+ * @param ops The new interest set
+ *
+ * @return This selection key
+ *
+ * @throws IllegalArgumentException
+ * If a bit in the set does not correspond to an operation that
+ * is supported by this key's channel, that is, if
+ * {@code (ops & ~channel().validOps()) != 0}
+ *
+ * @throws CancelledKeyException
+ * If this key has been cancelled
+ */
+ public abstract SelectionKey interestOps(int ops);
+
+ /**
+ * Retrieves this key's ready-operation set.
+ *
+ * <p> It is guaranteed that the returned set will only contain operation
+ * bits that are valid for this key's channel. </p>
+ *
+ * @return This key's ready-operation set
+ *
+ * @throws CancelledKeyException
+ * If this key has been cancelled
+ */
+ public abstract int readyOps();
+
+
+ // -- Operation bits and bit-testing convenience methods --
+
+ /**
+ * Operation-set bit for read operations.
+ *
+ * <p> Suppose that a selection key's interest set contains
+ * <tt>OP_READ</tt> at the start of a <a
+ * href="Selector.html#selop">selection operation</a>. If the selector
+ * detects that the corresponding channel is ready for reading, has reached
+ * end-of-stream, has been remotely shut down for further reading, or has
+ * an error pending, then it will add <tt>OP_READ</tt> to the key's
+ * ready-operation set and add the key to its selected-key set. </p>
+ */
+ public static final int OP_READ = 1 << 0;
+
+ /**
+ * Operation-set bit for write operations.
+ *
+ * <p> Suppose that a selection key's interest set contains
+ * <tt>OP_WRITE</tt> at the start of a <a
+ * href="Selector.html#selop">selection operation</a>. If the selector
+ * detects that the corresponding channel is ready for writing, has been
+ * remotely shut down for further writing, or has an error pending, then it
+ * will add <tt>OP_WRITE</tt> to the key's ready set and add the key to its
+ * selected-key set. </p>
+ */
+ public static final int OP_WRITE = 1 << 2;
+
+ /**
+ * Operation-set bit for socket-connect operations.
+ *
+ * <p> Suppose that a selection key's interest set contains
+ * <tt>OP_CONNECT</tt> at the start of a <a
+ * href="Selector.html#selop">selection operation</a>. If the selector
+ * detects that the corresponding socket channel is ready to complete its
+ * connection sequence, or has an error pending, then it will add
+ * <tt>OP_CONNECT</tt> to the key's ready set and add the key to its
+ * selected-key set. </p>
+ */
+ public static final int OP_CONNECT = 1 << 3;
+
+ /**
+ * Operation-set bit for socket-accept operations.
+ *
+ * <p> Suppose that a selection key's interest set contains
+ * <tt>OP_ACCEPT</tt> at the start of a <a
+ * href="Selector.html#selop">selection operation</a>. If the selector
+ * detects that the corresponding server-socket channel is ready to accept
+ * another connection, or has an error pending, then it will add
+ * <tt>OP_ACCEPT</tt> to the key's ready set and add the key to its
+ * selected-key set. </p>
+ */
+ public static final int OP_ACCEPT = 1 << 4;
+
+ /**
+ * Tests whether this key's channel is ready for reading.
+ *
+ * <p> An invocation of this method of the form <tt>k.isReadable()</tt>
+ * behaves in exactly the same way as the expression
+ *
+ * <blockquote><pre>{@code
+ * k.readyOps() & OP_READ != 0
+ * }</pre></blockquote>
+ *
+ * <p> If this key's channel does not support read operations then this
+ * method always returns <tt>false</tt>. </p>
+ *
+ * @return <tt>true</tt> if, and only if,
+ {@code readyOps() & OP_READ} is nonzero
+ *
+ * @throws CancelledKeyException
+ * If this key has been cancelled
+ */
+ public final boolean isReadable() {
+ return (readyOps() & OP_READ) != 0;
+ }
+
+ /**
+ * Tests whether this key's channel is ready for writing.
+ *
+ * <p> An invocation of this method of the form <tt>k.isWritable()</tt>
+ * behaves in exactly the same way as the expression
+ *
+ * <blockquote><pre>{@code
+ * k.readyOps() & OP_WRITE != 0
+ * }</pre></blockquote>
+ *
+ * <p> If this key's channel does not support write operations then this
+ * method always returns <tt>false</tt>. </p>
+ *
+ * @return <tt>true</tt> if, and only if,
+ * {@code readyOps() & OP_WRITE} is nonzero
+ *
+ * @throws CancelledKeyException
+ * If this key has been cancelled
+ */
+ public final boolean isWritable() {
+ return (readyOps() & OP_WRITE) != 0;
+ }
+
+ /**
+ * Tests whether this key's channel has either finished, or failed to
+ * finish, its socket-connection operation.
+ *
+ * <p> An invocation of this method of the form <tt>k.isConnectable()</tt>
+ * behaves in exactly the same way as the expression
+ *
+ * <blockquote><pre>{@code
+ * k.readyOps() & OP_CONNECT != 0
+ * }</pre></blockquote>
+ *
+ * <p> If this key's channel does not support socket-connect operations
+ * then this method always returns <tt>false</tt>. </p>
+ *
+ * @return <tt>true</tt> if, and only if,
+ * {@code readyOps() & OP_CONNECT} is nonzero
+ *
+ * @throws CancelledKeyException
+ * If this key has been cancelled
+ */
+ public final boolean isConnectable() {
+ return (readyOps() & OP_CONNECT) != 0;
+ }
+
+ /**
+ * Tests whether this key's channel is ready to accept a new socket
+ * connection.
+ *
+ * <p> An invocation of this method of the form <tt>k.isAcceptable()</tt>
+ * behaves in exactly the same way as the expression
+ *
+ * <blockquote><pre>{@code
+ * k.readyOps() & OP_ACCEPT != 0
+ * }</pre></blockquote>
+ *
+ * <p> If this key's channel does not support socket-accept operations then
+ * this method always returns <tt>false</tt>. </p>
+ *
+ * @return <tt>true</tt> if, and only if,
+ * {@code readyOps() & OP_ACCEPT} is nonzero
+ *
+ * @throws CancelledKeyException
+ * If this key has been cancelled
+ */
+ public final boolean isAcceptable() {
+ return (readyOps() & OP_ACCEPT) != 0;
+ }
+
+
+ // -- Attachments --
+
+ private volatile Object attachment = null;
+
+ private static final AtomicReferenceFieldUpdater<SelectionKey,Object>
+ attachmentUpdater = AtomicReferenceFieldUpdater.newUpdater(
+ SelectionKey.class, Object.class, "attachment"
+ );
+
+ /**
+ * Attaches the given object to this key.
+ *
+ * <p> An attached object may later be retrieved via the {@link #attachment()
+ * attachment} method. Only one object may be attached at a time; invoking
+ * this method causes any previous attachment to be discarded. The current
+ * attachment may be discarded by attaching <tt>null</tt>. </p>
+ *
+ * @param ob
+ * The object to be attached; may be <tt>null</tt>
+ *
+ * @return The previously-attached object, if any,
+ * otherwise <tt>null</tt>
+ */
+ public final Object attach(Object ob) {
+ return attachmentUpdater.getAndSet(this, ob);
+ }
+
+ /**
+ * Retrieves the current attachment.
+ *
+ * @return The object currently attached to this key,
+ * or <tt>null</tt> if there is no attachment
+ */
+ public final Object attachment() {
+ return attachment;
+ }
+
+}
diff --git a/java/nio/channels/Selector.java b/java/nio/channels/Selector.java
new file mode 100644
index 0000000..ea72acb
--- /dev/null
+++ b/java/nio/channels/Selector.java
@@ -0,0 +1,396 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.nio.channels.spi.SelectorProvider;
+import java.util.Set;
+
+
+/**
+ * A multiplexor of {@link SelectableChannel} objects.
+ *
+ * <p> A selector may be created by invoking the {@link #open open} method of
+ * this class, which will use the system's default {@link
+ * java.nio.channels.spi.SelectorProvider selector provider} to
+ * create a new selector. A selector may also be created by invoking the
+ * {@link java.nio.channels.spi.SelectorProvider#openSelector openSelector}
+ * method of a custom selector provider. A selector remains open until it is
+ * closed via its {@link #close close} method.
+ *
+ * <a name="ks"></a>
+ *
+ * <p> A selectable channel's registration with a selector is represented by a
+ * {@link SelectionKey} object. A selector maintains three sets of selection
+ * keys:
+ *
+ * <ul>
+ *
+ * <li><p> The <i>key set</i> contains the keys representing the current
+ * channel registrations of this selector. This set is returned by the
+ * {@link #keys() keys} method. </p></li>
+ *
+ * <li><p> The <i>selected-key set</i> is the set of keys such that each
+ * key's channel was detected to be ready for at least one of the operations
+ * identified in the key's interest set during a prior selection operation.
+ * This set is returned by the {@link #selectedKeys() selectedKeys} method.
+ * The selected-key set is always a subset of the key set. </p></li>
+ *
+ * <li><p> The <i>cancelled-key</i> set is the set of keys that have been
+ * cancelled but whose channels have not yet been deregistered. This set is
+ * not directly accessible. The cancelled-key set is always a subset of the
+ * key set. </p></li>
+ *
+ * </ul>
+ *
+ * <p> All three sets are empty in a newly-created selector.
+ *
+ * <p> A key is added to a selector's key set as a side effect of registering a
+ * channel via the channel's {@link SelectableChannel#register(Selector,int)
+ * register} method. Cancelled keys are removed from the key set during
+ * selection operations. The key set itself is not directly modifiable.
+ *
+ * <p> A key is added to its selector's cancelled-key set when it is cancelled,
+ * whether by closing its channel or by invoking its {@link SelectionKey#cancel
+ * cancel} method. Cancelling a key will cause its channel to be deregistered
+ * during the next selection operation, at which time the key will removed from
+ * all of the selector's key sets.
+ *
+ * <a name="sks"></a><p> Keys are added to the selected-key set by selection
+ * operations. A key may be removed directly from the selected-key set by
+ * invoking the set's {@link java.util.Set#remove(java.lang.Object) remove}
+ * method or by invoking the {@link java.util.Iterator#remove() remove} method
+ * of an {@link java.util.Iterator iterator} obtained from the
+ * set. Keys are never removed from the selected-key set in any other way;
+ * they are not, in particular, removed as a side effect of selection
+ * operations. Keys may not be added directly to the selected-key set. </p>
+ *
+ *
+ * <a name="selop"></a>
+ * <h2>Selection</h2>
+ *
+ * <p> During each selection operation, keys may be added to and removed from a
+ * selector's selected-key set and may be removed from its key and
+ * cancelled-key sets. Selection is performed by the {@link #select()}, {@link
+ * #select(long)}, and {@link #selectNow()} methods, and involves three steps:
+ * </p>
+ *
+ * <ol>
+ *
+ * <li><p> Each key in the cancelled-key set is removed from each key set of
+ * which it is a member, and its channel is deregistered. This step leaves
+ * the cancelled-key set empty. </p></li>
+ *
+ * <li><p> The underlying operating system is queried for an update as to the
+ * readiness of each remaining channel to perform any of the operations
+ * identified by its key's interest set as of the moment that the selection
+ * operation began. For a channel that is ready for at least one such
+ * operation, one of the following two actions is performed: </p>
+ *
+ * <ol>
+ *
+ * <li><p> If the channel's key is not already in the selected-key set then
+ * it is added to that set and its ready-operation set is modified to
+ * identify exactly those operations for which the channel is now reported
+ * to be ready. Any readiness information previously recorded in the ready
+ * set is discarded. </p></li>
+ *
+ * <li><p> Otherwise the channel's key is already in the selected-key set,
+ * so its ready-operation set is modified to identify any new operations
+ * for which the channel is reported to be ready. Any readiness
+ * information previously recorded in the ready set is preserved; in other
+ * words, the ready set returned by the underlying system is
+ * bitwise-disjoined into the key's current ready set. </p></li>
+ *
+ * </ol>
+ *
+ * If all of the keys in the key set at the start of this step have empty
+ * interest sets then neither the selected-key set nor any of the keys'
+ * ready-operation sets will be updated.
+ *
+ * <li><p> If any keys were added to the cancelled-key set while step (2) was
+ * in progress then they are processed as in step (1). </p></li>
+ *
+ * </ol>
+ *
+ * <p> Whether or not a selection operation blocks to wait for one or more
+ * channels to become ready, and if so for how long, is the only essential
+ * difference between the three selection methods. </p>
+ *
+ *
+ * <h2>Concurrency</h2>
+ *
+ * <p> Selectors are themselves safe for use by multiple concurrent threads;
+ * their key sets, however, are not.
+ *
+ * <p> The selection operations synchronize on the selector itself, on the key
+ * set, and on the selected-key set, in that order. They also synchronize on
+ * the cancelled-key set during steps (1) and (3) above.
+ *
+ * <p> Changes made to the interest sets of a selector's keys while a
+ * selection operation is in progress have no effect upon that operation; they
+ * will be seen by the next selection operation.
+ *
+ * <p> Keys may be cancelled and channels may be closed at any time. Hence the
+ * presence of a key in one or more of a selector's key sets does not imply
+ * that the key is valid or that its channel is open. Application code should
+ * be careful to synchronize and check these conditions as necessary if there
+ * is any possibility that another thread will cancel a key or close a channel.
+ *
+ * <p> A thread blocked in one of the {@link #select()} or {@link
+ * #select(long)} methods may be interrupted by some other thread in one of
+ * three ways:
+ *
+ * <ul>
+ *
+ * <li><p> By invoking the selector's {@link #wakeup wakeup} method,
+ * </p></li>
+ *
+ * <li><p> By invoking the selector's {@link #close close} method, or
+ * </p></li>
+ *
+ * <li><p> By invoking the blocked thread's {@link
+ * java.lang.Thread#interrupt() interrupt} method, in which case its
+ * interrupt status will be set and the selector's {@link #wakeup wakeup}
+ * method will be invoked. </p></li>
+ *
+ * </ul>
+ *
+ * <p> The {@link #close close} method synchronizes on the selector and all
+ * three key sets in the same order as in a selection operation.
+ *
+ * <a name="ksc"></a>
+ *
+ * <p> A selector's key and selected-key sets are not, in general, safe for use
+ * by multiple concurrent threads. If such a thread might modify one of these
+ * sets directly then access should be controlled by synchronizing on the set
+ * itself. The iterators returned by these sets' {@link
+ * java.util.Set#iterator() iterator} methods are <i>fail-fast:</i> If the set
+ * is modified after the iterator is created, in any way except by invoking the
+ * iterator's own {@link java.util.Iterator#remove() remove} method, then a
+ * {@link java.util.ConcurrentModificationException} will be thrown. </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ *
+ * @see SelectableChannel
+ * @see SelectionKey
+ */
+
+public abstract class Selector implements Closeable {
+
+ /**
+ * Initializes a new instance of this class.
+ */
+ protected Selector() { }
+
+ /**
+ * Opens a selector.
+ *
+ * <p> The new selector is created by invoking the {@link
+ * java.nio.channels.spi.SelectorProvider#openSelector openSelector} method
+ * of the system-wide default {@link
+ * java.nio.channels.spi.SelectorProvider} object. </p>
+ *
+ * @return A new selector
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ public static Selector open() throws IOException {
+ return SelectorProvider.provider().openSelector();
+ }
+
+ /**
+ * Tells whether or not this selector is open.
+ *
+ * @return <tt>true</tt> if, and only if, this selector is open
+ */
+ public abstract boolean isOpen();
+
+ /**
+ * Returns the provider that created this channel.
+ *
+ * @return The provider that created this channel
+ */
+ public abstract SelectorProvider provider();
+
+ /**
+ * Returns this selector's key set.
+ *
+ * <p> The key set is not directly modifiable. A key is removed only after
+ * it has been cancelled and its channel has been deregistered. Any
+ * attempt to modify the key set will cause an {@link
+ * UnsupportedOperationException} to be thrown.
+ *
+ * <p> The key set is <a href="#ksc">not thread-safe</a>. </p>
+ *
+ * @return This selector's key set
+ *
+ * @throws ClosedSelectorException
+ * If this selector is closed
+ */
+ public abstract Set<SelectionKey> keys();
+
+ /**
+ * Returns this selector's selected-key set.
+ *
+ * <p> Keys may be removed from, but not directly added to, the
+ * selected-key set. Any attempt to add an object to the key set will
+ * cause an {@link UnsupportedOperationException} to be thrown.
+ *
+ * <p> The selected-key set is <a href="#ksc">not thread-safe</a>. </p>
+ *
+ * @return This selector's selected-key set
+ *
+ * @throws ClosedSelectorException
+ * If this selector is closed
+ */
+ public abstract Set<SelectionKey> selectedKeys();
+
+ /**
+ * Selects a set of keys whose corresponding channels are ready for I/O
+ * operations.
+ *
+ * <p> This method performs a non-blocking <a href="#selop">selection
+ * operation</a>. If no channels have become selectable since the previous
+ * selection operation then this method immediately returns zero.
+ *
+ * <p> Invoking this method clears the effect of any previous invocations
+ * of the {@link #wakeup wakeup} method. </p>
+ *
+ * @return The number of keys, possibly zero, whose ready-operation sets
+ * were updated by the selection operation
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ *
+ * @throws ClosedSelectorException
+ * If this selector is closed
+ */
+ public abstract int selectNow() throws IOException;
+
+ /**
+ * Selects a set of keys whose corresponding channels are ready for I/O
+ * operations.
+ *
+ * <p> This method performs a blocking <a href="#selop">selection
+ * operation</a>. It returns only after at least one channel is selected,
+ * this selector's {@link #wakeup wakeup} method is invoked, the current
+ * thread is interrupted, or the given timeout period expires, whichever
+ * comes first.
+ *
+ * <p> This method does not offer real-time guarantees: It schedules the
+ * timeout as if by invoking the {@link Object#wait(long)} method. </p>
+ *
+ * @param timeout If positive, block for up to <tt>timeout</tt>
+ * milliseconds, more or less, while waiting for a
+ * channel to become ready; if zero, block indefinitely;
+ * must not be negative
+ *
+ * @return The number of keys, possibly zero,
+ * whose ready-operation sets were updated
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ *
+ * @throws ClosedSelectorException
+ * If this selector is closed
+ *
+ * @throws IllegalArgumentException
+ * If the value of the timeout argument is negative
+ */
+ public abstract int select(long timeout)
+ throws IOException;
+
+ /**
+ * Selects a set of keys whose corresponding channels are ready for I/O
+ * operations.
+ *
+ * <p> This method performs a blocking <a href="#selop">selection
+ * operation</a>. It returns only after at least one channel is selected,
+ * this selector's {@link #wakeup wakeup} method is invoked, or the current
+ * thread is interrupted, whichever comes first. </p>
+ *
+ * @return The number of keys, possibly zero,
+ * whose ready-operation sets were updated
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ *
+ * @throws ClosedSelectorException
+ * If this selector is closed
+ */
+ public abstract int select() throws IOException;
+
+ /**
+ * Causes the first selection operation that has not yet returned to return
+ * immediately.
+ *
+ * <p> If another thread is currently blocked in an invocation of the
+ * {@link #select()} or {@link #select(long)} methods then that invocation
+ * will return immediately. If no selection operation is currently in
+ * progress then the next invocation of one of these methods will return
+ * immediately unless the {@link #selectNow()} method is invoked in the
+ * meantime. In any case the value returned by that invocation may be
+ * non-zero. Subsequent invocations of the {@link #select()} or {@link
+ * #select(long)} methods will block as usual unless this method is invoked
+ * again in the meantime.
+ *
+ * <p> Invoking this method more than once between two successive selection
+ * operations has the same effect as invoking it just once. </p>
+ *
+ * @return This selector
+ */
+ public abstract Selector wakeup();
+
+ /**
+ * Closes this selector.
+ *
+ * <p> If a thread is currently blocked in one of this selector's selection
+ * methods then it is interrupted as if by invoking the selector's {@link
+ * #wakeup wakeup} method.
+ *
+ * <p> Any uncancelled keys still associated with this selector are
+ * invalidated, their channels are deregistered, and any other resources
+ * associated with this selector are released.
+ *
+ * <p> If this selector is already closed then invoking this method has no
+ * effect.
+ *
+ * <p> After a selector is closed, any further attempt to use it, except by
+ * invoking this method or the {@link #wakeup wakeup} method, will cause a
+ * {@link ClosedSelectorException} to be thrown. </p>
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ public abstract void close() throws IOException;
+
+}
diff --git a/java/nio/channels/ServerSocketChannel.java b/java/nio/channels/ServerSocketChannel.java
new file mode 100644
index 0000000..8d967b3
--- /dev/null
+++ b/java/nio/channels/ServerSocketChannel.java
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.SocketOption;
+import java.net.SocketAddress;
+import java.nio.channels.spi.AbstractSelectableChannel;
+import java.nio.channels.spi.SelectorProvider;
+
+/**
+ * A selectable channel for stream-oriented listening sockets.
+ *
+ * <p> A server-socket channel is created by invoking the {@link #open() open}
+ * method of this class. It is not possible to create a channel for an arbitrary,
+ * pre-existing {@link ServerSocket}. A newly-created server-socket channel is
+ * open but not yet bound. An attempt to invoke the {@link #accept() accept}
+ * method of an unbound server-socket channel will cause a {@link NotYetBoundException}
+ * to be thrown. A server-socket channel can be bound by invoking one of the
+ * {@link #bind(java.net.SocketAddress,int) bind} methods defined by this class.
+ *
+ * <p> Socket options are configured using the {@link #setOption(SocketOption,Object)
+ * setOption} method. Server-socket channels support the following options:
+ * <blockquote>
+ * <table border summary="Socket options">
+ * <tr>
+ * <th>Option Name</th>
+ * <th>Description</th>
+ * </tr>
+ * <tr>
+ * <td> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </td>
+ * <td> The size of the socket receive buffer </td>
+ * </tr>
+ * <tr>
+ * <td> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </td>
+ * <td> Re-use address </td>
+ * </tr>
+ * </table>
+ * </blockquote>
+ * Additional (implementation specific) options may also be supported.
+ *
+ * <p> Server-socket channels are safe for use by multiple concurrent threads.
+ * </p>
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class ServerSocketChannel
+ extends AbstractSelectableChannel
+ implements NetworkChannel
+{
+
+ /**
+ * Initializes a new instance of this class.
+ *
+ * @param provider
+ * The provider that created this channel
+ */
+ protected ServerSocketChannel(SelectorProvider provider) {
+ super(provider);
+ }
+
+ /**
+ * Opens a server-socket channel.
+ *
+ * <p> The new channel is created by invoking the {@link
+ * java.nio.channels.spi.SelectorProvider#openServerSocketChannel
+ * openServerSocketChannel} method of the system-wide default {@link
+ * java.nio.channels.spi.SelectorProvider} object.
+ *
+ * <p> The new channel's socket is initially unbound; it must be bound to a
+ * specific address via one of its socket's {@link
+ * java.net.ServerSocket#bind(SocketAddress) bind} methods before
+ * connections can be accepted. </p>
+ *
+ * @return A new socket channel
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ public static ServerSocketChannel open() throws IOException {
+ return SelectorProvider.provider().openServerSocketChannel();
+ }
+
+ /**
+ * Returns an operation set identifying this channel's supported
+ * operations.
+ *
+ * <p> Server-socket channels only support the accepting of new
+ * connections, so this method returns {@link SelectionKey#OP_ACCEPT}.
+ * </p>
+ *
+ * @return The valid-operation set
+ */
+ public final int validOps() {
+ return SelectionKey.OP_ACCEPT;
+ }
+
+
+ // -- ServerSocket-specific operations --
+
+ /**
+ * Binds the channel's socket to a local address and configures the socket
+ * to listen for connections.
+ *
+ * <p> An invocation of this method is equivalent to the following:
+ * <blockquote><pre>
+ * bind(local, 0);
+ * </pre></blockquote>
+ *
+ * @param local
+ * The local address to bind the socket, or {@code null} to bind
+ * to an automatically assigned socket address
+ *
+ * @return This channel
+ *
+ * @throws AlreadyBoundException {@inheritDoc}
+ * @throws UnsupportedAddressTypeException {@inheritDoc}
+ * @throws ClosedChannelException {@inheritDoc}
+ * @throws IOException {@inheritDoc}
+ * @throws SecurityException
+ * If a security manager has been installed and its {@link
+ * SecurityManager#checkListen checkListen} method denies the
+ * operation
+ *
+ * @since 1.7
+ */
+ public final ServerSocketChannel bind(SocketAddress local)
+ throws IOException
+ {
+ return bind(local, 0);
+ }
+
+ /**
+ * Binds the channel's socket to a local address and configures the socket to
+ * listen for connections.
+ *
+ * <p> This method is used to establish an association between the socket and
+ * a local address. Once an association is established then the socket remains
+ * bound until the channel is closed.
+ *
+ * <p> The {@code backlog} parameter is the maximum number of pending
+ * connections on the socket. Its exact semantics are implementation specific.
+ * In particular, an implementation may impose a maximum length or may choose
+ * to ignore the parameter altogther. If the {@code backlog} parameter has
+ * the value {@code 0}, or a negative value, then an implementation specific
+ * default is used.
+ *
+ * @param local
+ * The address to bind the socket, or {@code null} to bind to an
+ * automatically assigned socket address
+ * @param backlog
+ * The maximum number of pending connections
+ *
+ * @return This channel
+ *
+ * @throws AlreadyBoundException
+ * If the socket is already bound
+ * @throws UnsupportedAddressTypeException
+ * If the type of the given address is not supported
+ * @throws ClosedChannelException
+ * If this channel is closed
+ * @throws IOException
+ * If some other I/O error occurs
+ * @throws SecurityException
+ * If a security manager has been installed and its {@link
+ * SecurityManager#checkListen checkListen} method denies the
+ * operation
+ *
+ * @since 1.7
+ */
+ public abstract ServerSocketChannel bind(SocketAddress local, int backlog)
+ throws IOException;
+
+ /**
+ * @throws UnsupportedOperationException {@inheritDoc}
+ * @throws IllegalArgumentException {@inheritDoc}
+ * @throws ClosedChannelException {@inheritDoc}
+ * @throws IOException {@inheritDoc}
+ *
+ * @since 1.7
+ */
+ public abstract <T> ServerSocketChannel setOption(SocketOption<T> name, T value)
+ throws IOException;
+
+ /**
+ * Retrieves a server socket associated with this channel.
+ *
+ * <p> The returned object will not declare any public methods that are not
+ * declared in the {@link java.net.ServerSocket} class. </p>
+ *
+ * @return A server socket associated with this channel
+ */
+ public abstract ServerSocket socket();
+
+ /**
+ * Accepts a connection made to this channel's socket.
+ *
+ * <p> If this channel is in non-blocking mode then this method will
+ * immediately return <tt>null</tt> if there are no pending connections.
+ * Otherwise it will block indefinitely until a new connection is available
+ * or an I/O error occurs.
+ *
+ * <p> The socket channel returned by this method, if any, will be in
+ * blocking mode regardless of the blocking mode of this channel.
+ *
+ * <p> This method performs exactly the same security checks as the {@link
+ * java.net.ServerSocket#accept accept} method of the {@link
+ * java.net.ServerSocket} class. That is, if a security manager has been
+ * installed then for each new connection this method verifies that the
+ * address and port number of the connection's remote endpoint are
+ * permitted by the security manager's {@link
+ * java.lang.SecurityManager#checkAccept checkAccept} method. </p>
+ *
+ * @return The socket channel for the new connection,
+ * or <tt>null</tt> if this channel is in non-blocking mode
+ * and no connection is available to be accepted
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ *
+ * @throws AsynchronousCloseException
+ * If another thread closes this channel
+ * while the accept operation is in progress
+ *
+ * @throws ClosedByInterruptException
+ * If another thread interrupts the current thread
+ * while the accept operation is in progress, thereby
+ * closing the channel and setting the current thread's
+ * interrupt status
+ *
+ * @throws NotYetBoundException
+ * If this channel's socket has not yet been bound
+ *
+ * @throws SecurityException
+ * If a security manager has been installed
+ * and it does not permit access to the remote endpoint
+ * of the new connection
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public abstract SocketChannel accept() throws IOException;
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * If there is a security manager set, its {@code checkConnect} method is
+ * called with the local address and {@code -1} as its arguments to see
+ * if the operation is allowed. If the operation is not allowed,
+ * a {@code SocketAddress} representing the
+ * {@link java.net.InetAddress#getLoopbackAddress loopback} address and the
+ * local port of the channel's socket is returned.
+ *
+ * @return The {@code SocketAddress} that the socket is bound to, or the
+ * {@code SocketAddress} representing the loopback address if
+ * denied by the security manager, or {@code null} if the
+ * channel's socket is not bound
+ *
+ * @throws ClosedChannelException {@inheritDoc}
+ * @throws IOException {@inheritDoc}
+ */
+ @Override
+ public abstract SocketAddress getLocalAddress() throws IOException;
+
+}
diff --git a/java/nio/channels/ShutdownChannelGroupException.java b/java/nio/channels/ShutdownChannelGroupException.java
new file mode 100644
index 0000000..b4e4b7d
--- /dev/null
+++ b/java/nio/channels/ShutdownChannelGroupException.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to construct a channel in
+ * a group that is shutdown or the completion handler for an I/O operation
+ * cannot be invoked because the channel group has terminated.
+ *
+ * @since 1.7
+ */
+
+public class ShutdownChannelGroupException
+ extends IllegalStateException
+{
+
+ private static final long serialVersionUID = -3903801676350154157L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public ShutdownChannelGroupException() { }
+
+}
diff --git a/java/nio/channels/SocketChannel.java b/java/nio/channels/SocketChannel.java
new file mode 100644
index 0000000..eb13b15
--- /dev/null
+++ b/java/nio/channels/SocketChannel.java
@@ -0,0 +1,526 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.net.SocketOption;
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.spi.AbstractSelectableChannel;
+import java.nio.channels.spi.SelectorProvider;
+
+/**
+ * A selectable channel for stream-oriented connecting sockets.
+ *
+ * <p> A socket channel is created by invoking one of the {@link #open open}
+ * methods of this class. It is not possible to create a channel for an arbitrary,
+ * pre-existing socket. A newly-created socket channel is open but not yet
+ * connected. An attempt to invoke an I/O operation upon an unconnected
+ * channel will cause a {@link NotYetConnectedException} to be thrown. A
+ * socket channel can be connected by invoking its {@link #connect connect}
+ * method; once connected, a socket channel remains connected until it is
+ * closed. Whether or not a socket channel is connected may be determined by
+ * invoking its {@link #isConnected isConnected} method.
+ *
+ * <p> Socket channels support <i>non-blocking connection:</i> A socket
+ * channel may be created and the process of establishing the link to the
+ * remote socket may be initiated via the {@link #connect connect} method for
+ * later completion by the {@link #finishConnect finishConnect} method.
+ * Whether or not a connection operation is in progress may be determined by
+ * invoking the {@link #isConnectionPending isConnectionPending} method.
+ *
+ * <p> Socket channels support <i>asynchronous shutdown,</i> which is similar
+ * to the asynchronous close operation specified in the {@link Channel} class.
+ * If the input side of a socket is shut down by one thread while another
+ * thread is blocked in a read operation on the socket's channel, then the read
+ * operation in the blocked thread will complete without reading any bytes and
+ * will return <tt>-1</tt>. If the output side of a socket is shut down by one
+ * thread while another thread is blocked in a write operation on the socket's
+ * channel, then the blocked thread will receive an {@link
+ * AsynchronousCloseException}.
+ *
+ * <p> Socket options are configured using the {@link #setOption(SocketOption,Object)
+ * setOption} method. Socket channels support the following options:
+ * <blockquote>
+ * <table border summary="Socket options">
+ * <tr>
+ * <th>Option Name</th>
+ * <th>Description</th>
+ * </tr>
+ * <tr>
+ * <td> {@link java.net.StandardSocketOptions#SO_SNDBUF SO_SNDBUF} </td>
+ * <td> The size of the socket send buffer </td>
+ * </tr>
+ * <tr>
+ * <td> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </td>
+ * <td> The size of the socket receive buffer </td>
+ * </tr>
+ * <tr>
+ * <td> {@link java.net.StandardSocketOptions#SO_KEEPALIVE SO_KEEPALIVE} </td>
+ * <td> Keep connection alive </td>
+ * </tr>
+ * <tr>
+ * <td> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </td>
+ * <td> Re-use address </td>
+ * </tr>
+ * <tr>
+ * <td> {@link java.net.StandardSocketOptions#SO_LINGER SO_LINGER} </td>
+ * <td> Linger on close if data is present (when configured in blocking mode
+ * only) </td>
+ * </tr>
+ * <tr>
+ * <td> {@link java.net.StandardSocketOptions#TCP_NODELAY TCP_NODELAY} </td>
+ * <td> Disable the Nagle algorithm </td>
+ * </tr>
+ * </table>
+ * </blockquote>
+ * Additional (implementation specific) options may also be supported.
+ *
+ * <p> Socket channels are safe for use by multiple concurrent threads. They
+ * support concurrent reading and writing, though at most one thread may be
+ * reading and at most one thread may be writing at any given time. The {@link
+ * #connect connect} and {@link #finishConnect finishConnect} methods are
+ * mutually synchronized against each other, and an attempt to initiate a read
+ * or write operation while an invocation of one of these methods is in
+ * progress will block until that invocation is complete. </p>
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class SocketChannel
+ extends AbstractSelectableChannel
+ implements ByteChannel, ScatteringByteChannel, GatheringByteChannel, NetworkChannel
+{
+
+ /**
+ * Initializes a new instance of this class.
+ *
+ * @param provider
+ * The provider that created this channel
+ */
+ protected SocketChannel(SelectorProvider provider) {
+ super(provider);
+ }
+
+ /**
+ * Opens a socket channel.
+ *
+ * <p> The new channel is created by invoking the {@link
+ * java.nio.channels.spi.SelectorProvider#openSocketChannel
+ * openSocketChannel} method of the system-wide default {@link
+ * java.nio.channels.spi.SelectorProvider} object. </p>
+ *
+ * @return A new socket channel
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ public static SocketChannel open() throws IOException {
+ return SelectorProvider.provider().openSocketChannel();
+ }
+
+ /**
+ * Opens a socket channel and connects it to a remote address.
+ *
+ * <p> This convenience method works as if by invoking the {@link #open()}
+ * method, invoking the {@link #connect(SocketAddress) connect} method upon
+ * the resulting socket channel, passing it <tt>remote</tt>, and then
+ * returning that channel. </p>
+ *
+ * @param remote
+ * The remote address to which the new channel is to be connected
+ *
+ * @return A new, and connected, socket channel
+ *
+ * @throws AsynchronousCloseException
+ * If another thread closes this channel
+ * while the connect operation is in progress
+ *
+ * @throws ClosedByInterruptException
+ * If another thread interrupts the current thread
+ * while the connect operation is in progress, thereby
+ * closing the channel and setting the current thread's
+ * interrupt status
+ *
+ * @throws UnresolvedAddressException
+ * If the given remote address is not fully resolved
+ *
+ * @throws UnsupportedAddressTypeException
+ * If the type of the given remote address is not supported
+ *
+ * @throws SecurityException
+ * If a security manager has been installed
+ * and it does not permit access to the given remote endpoint
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public static SocketChannel open(SocketAddress remote)
+ throws IOException
+ {
+ SocketChannel sc = open();
+ try {
+ sc.connect(remote);
+ } catch (Throwable x) {
+ try {
+ sc.close();
+ } catch (Throwable suppressed) {
+ x.addSuppressed(suppressed);
+ }
+ throw x;
+ }
+ assert sc.isConnected();
+ return sc;
+ }
+
+ /**
+ * Returns an operation set identifying this channel's supported
+ * operations.
+ *
+ * <p> Socket channels support connecting, reading, and writing, so this
+ * method returns <tt>(</tt>{@link SelectionKey#OP_CONNECT}
+ * <tt>|</tt> {@link SelectionKey#OP_READ} <tt>|</tt> {@link
+ * SelectionKey#OP_WRITE}<tt>)</tt>. </p>
+ *
+ * @return The valid-operation set
+ */
+ public final int validOps() {
+ return (SelectionKey.OP_READ
+ | SelectionKey.OP_WRITE
+ | SelectionKey.OP_CONNECT);
+ }
+
+
+ // -- Socket-specific operations --
+
+ /**
+ * @throws ConnectionPendingException
+ * If a non-blocking connect operation is already in progress on
+ * this channel
+ * @throws AlreadyBoundException {@inheritDoc}
+ * @throws UnsupportedAddressTypeException {@inheritDoc}
+ * @throws ClosedChannelException {@inheritDoc}
+ * @throws IOException {@inheritDoc}
+ * @throws SecurityException
+ * If a security manager has been installed and its
+ * {@link SecurityManager#checkListen checkListen} method denies
+ * the operation
+ *
+ * @since 1.7
+ */
+ @Override
+ public abstract SocketChannel bind(SocketAddress local)
+ throws IOException;
+
+ /**
+ * @throws UnsupportedOperationException {@inheritDoc}
+ * @throws IllegalArgumentException {@inheritDoc}
+ * @throws ClosedChannelException {@inheritDoc}
+ * @throws IOException {@inheritDoc}
+ *
+ * @since 1.7
+ */
+ @Override
+ public abstract <T> SocketChannel setOption(SocketOption<T> name, T value)
+ throws IOException;
+
+ /**
+ * Shutdown the connection for reading without closing the channel.
+ *
+ * <p> Once shutdown for reading then further reads on the channel will
+ * return {@code -1}, the end-of-stream indication. If the input side of the
+ * connection is already shutdown then invoking this method has no effect.
+ *
+ * @return The channel
+ *
+ * @throws NotYetConnectedException
+ * If this channel is not yet connected
+ * @throws ClosedChannelException
+ * If this channel is closed
+ * @throws IOException
+ * If some other I/O error occurs
+ *
+ * @since 1.7
+ */
+ public abstract SocketChannel shutdownInput() throws IOException;
+
+ /**
+ * Shutdown the connection for writing without closing the channel.
+ *
+ * <p> Once shutdown for writing then further attempts to write to the
+ * channel will throw {@link ClosedChannelException}. If the output side of
+ * the connection is already shutdown then invoking this method has no
+ * effect.
+ *
+ * @return The channel
+ *
+ * @throws NotYetConnectedException
+ * If this channel is not yet connected
+ * @throws ClosedChannelException
+ * If this channel is closed
+ * @throws IOException
+ * If some other I/O error occurs
+ *
+ * @since 1.7
+ */
+ public abstract SocketChannel shutdownOutput() throws IOException;
+
+ /**
+ * Retrieves a socket associated with this channel.
+ *
+ * <p> The returned object will not declare any public methods that are not
+ * declared in the {@link java.net.Socket} class. </p>
+ *
+ * @return A socket associated with this channel
+ */
+ public abstract Socket socket();
+
+ /**
+ * Tells whether or not this channel's network socket is connected.
+ *
+ * @return <tt>true</tt> if, and only if, this channel's network socket
+ * is {@link #isOpen open} and connected
+ */
+ public abstract boolean isConnected();
+
+ /**
+ * Tells whether or not a connection operation is in progress on this
+ * channel.
+ *
+ * @return <tt>true</tt> if, and only if, a connection operation has been
+ * initiated on this channel but not yet completed by invoking the
+ * {@link #finishConnect finishConnect} method
+ */
+ public abstract boolean isConnectionPending();
+
+ /**
+ * Connects this channel's socket.
+ *
+ * <p> If this channel is in non-blocking mode then an invocation of this
+ * method initiates a non-blocking connection operation. If the connection
+ * is established immediately, as can happen with a local connection, then
+ * this method returns <tt>true</tt>. Otherwise this method returns
+ * <tt>false</tt> and the connection operation must later be completed by
+ * invoking the {@link #finishConnect finishConnect} method.
+ *
+ * <p> If this channel is in blocking mode then an invocation of this
+ * method will block until the connection is established or an I/O error
+ * occurs.
+ *
+ * <p> This method performs exactly the same security checks as the {@link
+ * java.net.Socket} class. That is, if a security manager has been
+ * installed then this method verifies that its {@link
+ * java.lang.SecurityManager#checkConnect checkConnect} method permits
+ * connecting to the address and port number of the given remote endpoint.
+ *
+ * <p> This method may be invoked at any time. If a read or write
+ * operation upon this channel is invoked while an invocation of this
+ * method is in progress then that operation will first block until this
+ * invocation is complete. If a connection attempt is initiated but fails,
+ * that is, if an invocation of this method throws a checked exception,
+ * then the channel will be closed. </p>
+ *
+ * @param remote
+ * The remote address to which this channel is to be connected
+ *
+ * @return <tt>true</tt> if a connection was established,
+ * <tt>false</tt> if this channel is in non-blocking mode
+ * and the connection operation is in progress
+ *
+ * @throws AlreadyConnectedException
+ * If this channel is already connected
+ *
+ * @throws ConnectionPendingException
+ * If a non-blocking connection operation is already in progress
+ * on this channel
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ *
+ * @throws AsynchronousCloseException
+ * If another thread closes this channel
+ * while the connect operation is in progress
+ *
+ * @throws ClosedByInterruptException
+ * If another thread interrupts the current thread
+ * while the connect operation is in progress, thereby
+ * closing the channel and setting the current thread's
+ * interrupt status
+ *
+ * @throws UnresolvedAddressException
+ * If the given remote address is not fully resolved
+ *
+ * @throws UnsupportedAddressTypeException
+ * If the type of the given remote address is not supported
+ *
+ * @throws SecurityException
+ * If a security manager has been installed
+ * and it does not permit access to the given remote endpoint
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public abstract boolean connect(SocketAddress remote) throws IOException;
+
+ /**
+ * Finishes the process of connecting a socket channel.
+ *
+ * <p> A non-blocking connection operation is initiated by placing a socket
+ * channel in non-blocking mode and then invoking its {@link #connect
+ * connect} method. Once the connection is established, or the attempt has
+ * failed, the socket channel will become connectable and this method may
+ * be invoked to complete the connection sequence. If the connection
+ * operation failed then invoking this method will cause an appropriate
+ * {@link java.io.IOException} to be thrown.
+ *
+ * <p> If this channel is already connected then this method will not block
+ * and will immediately return <tt>true</tt>. If this channel is in
+ * non-blocking mode then this method will return <tt>false</tt> if the
+ * connection process is not yet complete. If this channel is in blocking
+ * mode then this method will block until the connection either completes
+ * or fails, and will always either return <tt>true</tt> or throw a checked
+ * exception describing the failure.
+ *
+ * <p> This method may be invoked at any time. If a read or write
+ * operation upon this channel is invoked while an invocation of this
+ * method is in progress then that operation will first block until this
+ * invocation is complete. If a connection attempt fails, that is, if an
+ * invocation of this method throws a checked exception, then the channel
+ * will be closed. </p>
+ *
+ * @return <tt>true</tt> if, and only if, this channel's socket is now
+ * connected
+ *
+ * @throws NoConnectionPendingException
+ * If this channel is not connected and a connection operation
+ * has not been initiated
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ *
+ * @throws AsynchronousCloseException
+ * If another thread closes this channel
+ * while the connect operation is in progress
+ *
+ * @throws ClosedByInterruptException
+ * If another thread interrupts the current thread
+ * while the connect operation is in progress, thereby
+ * closing the channel and setting the current thread's
+ * interrupt status
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public abstract boolean finishConnect() throws IOException;
+
+ /**
+ * Returns the remote address to which this channel's socket is connected.
+ *
+ * <p> Where the channel is bound and connected to an Internet Protocol
+ * socket address then the return value from this method is of type {@link
+ * java.net.InetSocketAddress}.
+ *
+ * @return The remote address; {@code null} if the channel's socket is not
+ * connected
+ *
+ * @throws ClosedChannelException
+ * If the channel is closed
+ * @throws IOException
+ * If an I/O error occurs
+ *
+ * @since 1.7
+ */
+ public abstract SocketAddress getRemoteAddress() throws IOException;
+
+ // -- ByteChannel operations --
+
+ /**
+ * @throws NotYetConnectedException
+ * If this channel is not yet connected
+ */
+ public abstract int read(ByteBuffer dst) throws IOException;
+
+ /**
+ * @throws NotYetConnectedException
+ * If this channel is not yet connected
+ */
+ public abstract long read(ByteBuffer[] dsts, int offset, int length)
+ throws IOException;
+
+ /**
+ * @throws NotYetConnectedException
+ * If this channel is not yet connected
+ */
+ public final long read(ByteBuffer[] dsts) throws IOException {
+ return read(dsts, 0, dsts.length);
+ }
+
+ /**
+ * @throws NotYetConnectedException
+ * If this channel is not yet connected
+ */
+ public abstract int write(ByteBuffer src) throws IOException;
+
+ /**
+ * @throws NotYetConnectedException
+ * If this channel is not yet connected
+ */
+ public abstract long write(ByteBuffer[] srcs, int offset, int length)
+ throws IOException;
+
+ /**
+ * @throws NotYetConnectedException
+ * If this channel is not yet connected
+ */
+ public final long write(ByteBuffer[] srcs) throws IOException {
+ return write(srcs, 0, srcs.length);
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * If there is a security manager set, its {@code checkConnect} method is
+ * called with the local address and {@code -1} as its arguments to see
+ * if the operation is allowed. If the operation is not allowed,
+ * a {@code SocketAddress} representing the
+ * {@link java.net.InetAddress#getLoopbackAddress loopback} address and the
+ * local port of the channel's socket is returned.
+ *
+ * @return The {@code SocketAddress} that the socket is bound to, or the
+ * {@code SocketAddress} representing the loopback address if
+ * denied by the security manager, or {@code null} if the
+ * channel's socket is not bound
+ *
+ * @throws ClosedChannelException {@inheritDoc}
+ * @throws IOException {@inheritDoc}
+ */
+ @Override
+ public abstract SocketAddress getLocalAddress() throws IOException;
+
+}
diff --git a/java/nio/channels/UnresolvedAddressException.java b/java/nio/channels/UnresolvedAddressException.java
new file mode 100644
index 0000000..f5e61b8
--- /dev/null
+++ b/java/nio/channels/UnresolvedAddressException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to invoke a network
+ * operation upon an unresolved socket address.
+ *
+ * @since 1.4
+ */
+
+public class UnresolvedAddressException
+ extends IllegalArgumentException
+{
+
+ private static final long serialVersionUID = 6136959093620794148L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public UnresolvedAddressException() { }
+
+}
diff --git a/java/nio/channels/UnsupportedAddressTypeException.java b/java/nio/channels/UnsupportedAddressTypeException.java
new file mode 100644
index 0000000..9c88b89
--- /dev/null
+++ b/java/nio/channels/UnsupportedAddressTypeException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to bind or connect
+ * to a socket address of a type that is not supported.
+ *
+ * @since 1.4
+ */
+
+public class UnsupportedAddressTypeException
+ extends IllegalArgumentException
+{
+
+ private static final long serialVersionUID = -2964323842829700493L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public UnsupportedAddressTypeException() { }
+
+}
diff --git a/java/nio/channels/WritableByteChannel.java b/java/nio/channels/WritableByteChannel.java
new file mode 100644
index 0000000..b2ea065
--- /dev/null
+++ b/java/nio/channels/WritableByteChannel.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+
+/**
+ * A channel that can write bytes.
+ *
+ * <p> Only one write operation upon a writable channel may be in progress at
+ * any given time. If one thread initiates a write operation upon a channel
+ * then any other thread that attempts to initiate another write operation will
+ * block until the first operation is complete. Whether or not other kinds of
+ * I/O operations may proceed concurrently with a write operation depends upon
+ * the type of the channel. </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public interface WritableByteChannel
+ extends Channel
+{
+
+ /**
+ * Writes a sequence of bytes to this channel from the given buffer.
+ *
+ * <p> An attempt is made to write up to <i>r</i> bytes to the channel,
+ * where <i>r</i> is the number of bytes remaining in the buffer, that is,
+ * <tt>src.remaining()</tt>, at the moment this method is invoked.
+ *
+ * <p> Suppose that a byte sequence of length <i>n</i> is written, where
+ * <tt>0</tt> <tt><=</tt> <i>n</i> <tt><=</tt> <i>r</i>.
+ * This byte sequence will be transferred from the buffer starting at index
+ * <i>p</i>, where <i>p</i> is the buffer's position at the moment this
+ * method is invoked; the index of the last byte written will be
+ * <i>p</i> <tt>+</tt> <i>n</i> <tt>-</tt> <tt>1</tt>.
+ * Upon return the buffer's position will be equal to
+ * <i>p</i> <tt>+</tt> <i>n</i>; its limit will not have changed.
+ *
+ * <p> Unless otherwise specified, a write operation will return only after
+ * writing all of the <i>r</i> requested bytes. Some types of channels,
+ * depending upon their state, may write only some of the bytes or possibly
+ * none at all. A socket channel in non-blocking mode, for example, cannot
+ * write any more bytes than are free in the socket's output buffer.
+ *
+ * <p> This method may be invoked at any time. If another thread has
+ * already initiated a write operation upon this channel, however, then an
+ * invocation of this method will block until the first operation is
+ * complete. </p>
+ *
+ * @param src
+ * The buffer from which bytes are to be retrieved
+ *
+ * @return The number of bytes written, possibly zero
+ *
+ * @throws NonWritableChannelException
+ * If this channel was not opened for writing
+ *
+ * @throws ClosedChannelException
+ * If this channel is closed
+ *
+ * @throws AsynchronousCloseException
+ * If another thread closes this channel
+ * while the write operation is in progress
+ *
+ * @throws ClosedByInterruptException
+ * If another thread interrupts the current thread
+ * while the write operation is in progress, thereby
+ * closing the channel and setting the current thread's
+ * interrupt status
+ *
+ * @throws IOException
+ * If some other I/O error occurs
+ */
+ public int write(ByteBuffer src) throws IOException;
+
+}
diff --git a/java/nio/channels/WritePendingException.java b/java/nio/channels/WritePendingException.java
new file mode 100644
index 0000000..8957702
--- /dev/null
+++ b/java/nio/channels/WritePendingException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to write to an
+ * asynchronous socket channel and a previous write has not completed.
+ *
+ * @since 1.7
+ */
+
+public class WritePendingException
+ extends IllegalStateException
+{
+
+ private static final long serialVersionUID = 7031871839266032276L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public WritePendingException() { }
+
+}
diff --git a/java/nio/channels/package-info.java b/java/nio/channels/package-info.java
new file mode 100644
index 0000000..8118347
--- /dev/null
+++ b/java/nio/channels/package-info.java
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Defines channels, which represent connections to entities that are capable of
+ * performing I/O operations, such as files and sockets; defines selectors, for
+ * multiplexed, non-blocking I/O operations.
+ *
+ * <a name="channels"></a>
+ *
+ * <blockquote><table cellspacing=1 cellpadding=0 summary="Lists channels and their descriptions">
+ * <tr><th align="left">Channels</th><th align="left">Description</th></tr>
+ * <tr><td valign=top><tt><i>{@link java.nio.channels.Channel}</i></tt></td>
+ * <td>A nexus for I/O operations</td></tr>
+ * <tr><td valign=top><tt> <i>{@link java.nio.channels.ReadableByteChannel}</i></tt></td>
+ * <td>Can read into a buffer</td></tr>
+ * <tr><td valign=top><tt> <i>{@link java.nio.channels.ScatteringByteChannel} </i></tt></td>
+ * <td>Can read into a sequence of buffers</td></tr>
+ * <tr><td valign=top><tt> <i>{@link java.nio.channels.WritableByteChannel}</i></tt></td>
+ * <td>Can write from a buffer</td></tr>
+ * <tr><td valign=top><tt> <i>{@link java.nio.channels.GatheringByteChannel}</i></tt></td>
+ * <td>Can write from a sequence of buffers</td></tr>
+ * <tr><td valign=top><tt> <i>{@link java.nio.channels.ByteChannel}</i></tt></td>
+ * <td>Can read/write to/from a buffer</td></tr>
+ * <tr><td valign=top><tt> <i>{@link java.nio.channels.SeekableByteChannel}</i></tt></td>
+ * <td>A {@code ByteChannel} connected to an entity that contains a variable-length sequence of bytes</td></tr>
+ * <tr><td valign=top><tt> <i>{@link java.nio.channels.AsynchronousChannel}</i></tt></td>
+ * <td>Supports asynchronous I/O operations.</td></tr>
+ * <tr><td valign=top><tt> <i>{@link java.nio.channels.AsynchronousByteChannel}</i></tt></td>
+ * <td>Can read and write bytes asynchronously</td></tr>
+ * <tr><td valign=top><tt> <i>{@link java.nio.channels.NetworkChannel}</i></tt></td>
+ * <td>A channel to a network socket</td></tr>
+ * <tr><td valign=top><tt> <i>{@link java.nio.channels.MulticastChannel}</i></tt></td>
+ * <td>Can join Internet Protocol (IP) multicast groups</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.Channels}</tt></td>
+ * <td>Utility methods for channel/stream interoperation</td></tr>
+ * </table></blockquote>
+ *
+ * <p> A <i>channel</i> represents an open connection to an entity such as a
+ * hardware device, a file, a network socket, or a program component that is
+ * capable of performing one or more distinct I/O operations, for example reading
+ * or writing. As specified in the {@link java.nio.channels.Channel} interface,
+ * channels are either open or closed, and they are both <i>asynchronously
+ * closeable</i> and <i>interruptible</i>.
+ *
+ * <p> The {@link java.nio.channels.Channel} interface is extended by several
+ * other interfaces.
+ *
+ * <p> The {@link java.nio.channels.ReadableByteChannel} interface specifies a
+ * {@link java.nio.channels.ReadableByteChannel#read read} method that reads bytes
+ * from the channel into a buffer; similarly, the {@link
+ * java.nio.channels.WritableByteChannel} interface specifies a {@link
+ * java.nio.channels.WritableByteChannel#write write} method that writes bytes
+ * from a buffer to the channel. The {@link java.nio.channels.ByteChannel}
+ * interface unifies these two interfaces for the common case of channels that can
+ * both read and write bytes. The {@link java.nio.channels.SeekableByteChannel}
+ * interface extends the {@code ByteChannel} interface with methods to {@link
+ * java.nio.channels.SeekableByteChannel#position() query} and {@link
+ * java.nio.channels.SeekableByteChannel#position(long) modify} the channel's
+ * current position, and its {@link java.nio.channels.SeekableByteChannel#size
+ * size}.
+ *
+ * <p> The {@link java.nio.channels.ScatteringByteChannel} and {@link
+ * java.nio.channels.GatheringByteChannel} interfaces extend the {@link
+ * java.nio.channels.ReadableByteChannel} and {@link
+ * java.nio.channels.WritableByteChannel} interfaces, respectively, adding {@link
+ * java.nio.channels.ScatteringByteChannel#read read} and {@link
+ * java.nio.channels.GatheringByteChannel#write write} methods that take a
+ * sequence of buffers rather than a single buffer.
+ *
+ * <p> The {@link java.nio.channels.NetworkChannel} interface specifies methods
+ * to {@link java.nio.channels.NetworkChannel#bind bind} the channel's socket,
+ * obtain the address to which the socket is bound, and methods to {@link
+ * java.nio.channels.NetworkChannel#getOption get} and {@link
+ * java.nio.channels.NetworkChannel#setOption set} socket options. The {@link
+ * java.nio.channels.MulticastChannel} interface specifies methods to join
+ * Internet Protocol (IP) multicast groups.
+ *
+ * <p> The {@link java.nio.channels.Channels} utility class defines static methods
+ * that support the interoperation of the stream classes of the <tt>{@link
+ * java.io}</tt> package with the channel classes of this package. An appropriate
+ * channel can be constructed from an {@link java.io.InputStream} or an {@link
+ * java.io.OutputStream}, and conversely an {@link java.io.InputStream} or an
+ * {@link java.io.OutputStream} can be constructed from a channel. A {@link
+ * java.io.Reader} can be constructed that uses a given charset to decode bytes
+ * from a given readable byte channel, and conversely a {@link java.io.Writer} can
+ * be constructed that uses a given charset to encode characters into bytes and
+ * write them to a given writable byte channel.
+ *
+ * <blockquote><table cellspacing=1 cellpadding=0 summary="Lists file channels and their descriptions">
+ * <tr><th align="left">File channels</th><th align="left">Description</th></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.FileChannel}</tt></td>
+ * <td>Reads, writes, maps, and manipulates files</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.FileLock}</tt></td>
+ * <td>A lock on a (region of a) file</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.MappedByteBuffer} </tt></td>
+ * <td>A direct byte buffer mapped to a region of a file</td></tr>
+ * </table></blockquote>
+ *
+ * <p> The {@link java.nio.channels.FileChannel} class supports the usual
+ * operations of reading bytes from, and writing bytes to, a channel connected to
+ * a file, as well as those of querying and modifying the current file position
+ * and truncating the file to a specific size. It defines methods for acquiring
+ * locks on the whole file or on a specific region of a file; these methods return
+ * instances of the {@link java.nio.channels.FileLock} class. Finally, it defines
+ * methods for forcing updates to the file to be written to the storage device that
+ * contains it, for efficiently transferring bytes between the file and other
+ * channels, and for mapping a region of the file directly into memory.
+ *
+ * <p> A {@code FileChannel} is created by invoking one of its static {@link
+ * java.nio.channels.FileChannel#open open} methods, or by invoking the {@code
+ * getChannel} method of a {@link java.io.FileInputStream}, {@link
+ * java.io.FileOutputStream}, or {@link java.io.RandomAccessFile} to return a
+ * file channel connected to the same underlying file as the <tt>{@link java.io}</tt>
+ * class.
+ *
+ * <a name="multiplex"></a>
+ * <blockquote><table cellspacing=1 cellpadding=0 summary="Lists multiplexed, non-blocking channels and their descriptions">
+ * <tr><th align="left">Multiplexed, non-blocking I/O</th><th align="left"><p>Description</th></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.SelectableChannel}</tt></td>
+ * <td>A channel that can be multiplexed</td></tr>
+ * <tr><td valign=top><tt> {@link java.nio.channels.DatagramChannel}</tt></td>
+ * <td>A channel to a datagram-oriented socket</td></tr>
+ * <tr><td valign=top><tt> {@link java.nio.channels.Pipe.SinkChannel}</tt></td>
+ * <td>The write end of a pipe</td></tr>
+ * <tr><td valign=top><tt> {@link java.nio.channels.Pipe.SourceChannel}</tt></td>
+ * <td>The read end of a pipe</td></tr>
+ * <tr><td valign=top><tt> {@link java.nio.channels.ServerSocketChannel} </tt></td>
+ * <td>A channel to a stream-oriented listening socket</td></tr>
+ * <tr><td valign=top><tt> {@link java.nio.channels.SocketChannel}</tt></td>
+ * <td>A channel for a stream-oriented connecting socket</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.Selector}</tt></td>
+ * <td>A multiplexor of selectable channels</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.SelectionKey}</tt></td>
+ * <td>A token representing the registration <br> of a channel
+ * with a selector</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.Pipe}</tt></td>
+ * <td>Two channels that form a unidirectional pipe</td></tr>
+ * </table></blockquote>
+ *
+ * <p> Multiplexed, non-blocking I/O, which is much more scalable than
+ * thread-oriented, blocking I/O, is provided by <i>selectors</i>, <i>selectable
+ * channels</i>, and <i>selection keys</i>.
+ *
+ * <p> A <a href="Selector.html"><i>selector</i></a> is a multiplexor of <a
+ * href="SelectableChannel.html"><i>selectable channels</i></a>, which in turn are
+ * a special type of channel that can be put into <a
+ * href="SelectableChannel.html#bm"><i>non-blocking mode</i></a>. To perform
+ * multiplexed I/O operations, one or more selectable channels are first created,
+ * put into non-blocking mode, and {@link
+ * java.nio.channels.SelectableChannel#register <i>registered</i>}
+ * with a selector. Registering a channel specifies the set of I/O operations
+ * that will be tested for readiness by the selector, and returns a <a
+ * href="SelectionKey.html"><i>selection key</i></a> that represents the
+ * registration.
+ *
+ * <p> Once some channels have been registered with a selector, a <a
+ * href="Selector.html#selop"><i>selection operation</i></a> can be performed in
+ * order to discover which channels, if any, have become ready to perform one or
+ * more of the operations in which interest was previously declared. If a channel
+ * is ready then the key returned when it was registered will be added to the
+ * selector's <i>selected-key set</i>. The key set, and the keys within it, can
+ * be examined in order to determine the operations for which each channel is
+ * ready. From each key one can retrieve the corresponding channel in order to
+ * perform whatever I/O operations are required.
+ *
+ * <p> That a selection key indicates that its channel is ready for some operation
+ * is a hint, but not a guarantee, that such an operation can be performed by a
+ * thread without causing the thread to block. It is imperative that code that
+ * performs multiplexed I/O be written so as to ignore these hints when they prove
+ * to be incorrect.
+ *
+ * <p> This package defines selectable-channel classes corresponding to the {@link
+ * java.net.DatagramSocket}, {@link java.net.ServerSocket}, and {@link
+ * java.net.Socket} classes defined in the <tt>{@link java.net}</tt> package.
+ * Minor changes to these classes have been made in order to support sockets that
+ * are associated with channels. This package also defines a simple class that
+ * implements unidirectional pipes. In all cases, a new selectable channel is
+ * created by invoking the static <tt>open</tt> method of the corresponding class.
+ * If a channel needs an associated socket then a socket will be created as a side
+ * effect of this operation.
+ *
+ * <p> The implementation of selectors, selectable channels, and selection keys
+ * can be replaced by "plugging in" an alternative definition or instance of the
+ * {@link java.nio.channels.spi.SelectorProvider} class defined in the <tt>{@link
+ * java.nio.channels.spi}</tt> package. It is not expected that many developers
+ * will actually make use of this facility; it is provided primarily so that
+ * sophisticated users can take advantage of operating-system-specific
+ * I/O-multiplexing mechanisms when very high performance is required.
+ *
+ * <p> Much of the bookkeeping and synchronization required to implement the
+ * multiplexed-I/O abstractions is performed by the {@link
+ * java.nio.channels.spi.AbstractInterruptibleChannel}, {@link
+ * java.nio.channels.spi.AbstractSelectableChannel}, {@link
+ * java.nio.channels.spi.AbstractSelectionKey}, and {@link
+ * java.nio.channels.spi.AbstractSelector} classes in the <tt>{@link
+ * java.nio.channels.spi}</tt> package. When defining a custom selector provider,
+ * only the {@link java.nio.channels.spi.AbstractSelector} and {@link
+ * java.nio.channels.spi.AbstractSelectionKey} classes should be subclassed
+ * directly; custom channel classes should extend the appropriate {@link
+ * java.nio.channels.SelectableChannel} subclasses defined in this package.
+ *
+ * <a name="async"></a>
+ *
+ * <blockquote><table cellspacing=1 cellpadding=0 summary="Lists asynchronous channels and their descriptions">
+ * <tr><th align="left">Asynchronous I/O</th><th align="left">Description</th></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.AsynchronousFileChannel}</tt></td>
+ * <td>An asynchronous channel for reading, writing, and manipulating a file</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.AsynchronousSocketChannel}</tt></td>
+ * <td>An asynchronous channel to a stream-oriented connecting socket</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.AsynchronousServerSocketChannel} </tt></td>
+ * <td>An asynchronous channel to a stream-oriented listening socket</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.CompletionHandler}</tt></td>
+ * <td>A handler for consuming the result of an asynchronous operation</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.AsynchronousChannelGroup}</tt></td>
+ * <td>A grouping of asynchronous channels for the purpose of resource sharing</td></tr>
+ * </table></blockquote>
+ *
+ * <p> {@link java.nio.channels.AsynchronousChannel Asynchronous channels} are a
+ * special type of channel capable of asynchronous I/O operations. Asynchronous
+ * channels are non-blocking and define methods to initiate asynchronous
+ * operations, returning a {@link java.util.concurrent.Future} representing the
+ * pending result of each operation. The {@code Future} can be used to poll or
+ * wait for the result of the operation. Asynchronous I/O operations can also
+ * specify a {@link java.nio.channels.CompletionHandler} to invoke when the
+ * operation completes. A completion handler is user provided code that is executed
+ * to consume the result of I/O operation.
+ *
+ * <p> This package defines asynchronous-channel classes that are connected to
+ * a stream-oriented connecting or listening socket, or a datagram-oriented socket.
+ * It also defines the {@link java.nio.channels.AsynchronousFileChannel} class
+ * for asynchronous reading, writing, and manipulating a file. As with the {@link
+ * java.nio.channels.FileChannel} it supports operations to truncate the file
+ * to a specific size, force updates to the file to be written to the storage
+ * device, or acquire locks on the whole file or on a specific region of the file.
+ * Unlike the {@code FileChannel} it does not define methods for mapping a
+ * region of the file directly into memory. Where memory mapped I/O is required,
+ * then a {@code FileChannel} can be used.
+ *
+ * <p> Asynchronous channels are bound to an asynchronous channel group for the
+ * purpose of resource sharing. A group has an associated {@link
+ * java.util.concurrent.ExecutorService} to which tasks are submitted to handle
+ * I/O events and dispatch to completion handlers that consume the result of
+ * asynchronous operations performed on channels in the group. The group can
+ * optionally be specified when creating the channel or the channel can be bound
+ * to a <em>default group</em>. Sophisticated users may wish to create their
+ * own asynchronous channel groups or configure the {@code ExecutorService}
+ * that will be used for the default group.
+ *
+ * <p> As with selectors, the implementation of asynchronous channels can be
+ * replaced by "plugging in" an alternative definition or instance of the {@link
+ * java.nio.channels.spi.AsynchronousChannelProvider} class defined in the
+ * <tt>{@link java.nio.channels.spi}</tt> package. It is not expected that many
+ * developers will actually make use of this facility; it is provided primarily
+ * so that sophisticated users can take advantage of operating-system-specific
+ * asynchronous I/O mechanisms when very high performance is required.
+ *
+ * <hr width="80%">
+ * <p> Unless otherwise noted, passing a <tt>null</tt> argument to a constructor
+ * or method in any class or interface in this package will cause a {@link
+ * java.lang.NullPointerException NullPointerException} to be thrown.
+ *
+ * @since 1.4
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ */
+
+package java.nio.channels;
diff --git a/java/nio/channels/spi/AbstractInterruptibleChannel.java b/java/nio/channels/spi/AbstractInterruptibleChannel.java
new file mode 100644
index 0000000..137c449
--- /dev/null
+++ b/java/nio/channels/spi/AbstractInterruptibleChannel.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ */
+
+package java.nio.channels.spi;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.nio.channels.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import sun.nio.ch.Interruptible;
+
+
+/**
+ * Base implementation class for interruptible channels.
+ *
+ * <p> This class encapsulates the low-level machinery required to implement
+ * the asynchronous closing and interruption of channels. A concrete channel
+ * class must invoke the {@link #begin begin} and {@link #end end} methods
+ * before and after, respectively, invoking an I/O operation that might block
+ * indefinitely. In order to ensure that the {@link #end end} method is always
+ * invoked, these methods should be used within a
+ * <tt>try</tt> ... <tt>finally</tt> block:
+ *
+ * <blockquote><pre>
+ * boolean completed = false;
+ * try {
+ * begin();
+ * completed = ...; // Perform blocking I/O operation
+ * return ...; // Return result
+ * } finally {
+ * end(completed);
+ * }</pre></blockquote>
+ *
+ * <p> The <tt>completed</tt> argument to the {@link #end end} method tells
+ * whether or not the I/O operation actually completed, that is, whether it had
+ * any effect that would be visible to the invoker. In the case of an
+ * operation that reads bytes, for example, this argument should be
+ * <tt>true</tt> if, and only if, some bytes were actually transferred into the
+ * invoker's target buffer.
+ *
+ * <p> A concrete channel class must also implement the {@link
+ * #implCloseChannel implCloseChannel} method in such a way that if it is
+ * invoked while another thread is blocked in a native I/O operation upon the
+ * channel then that operation will immediately return, either by throwing an
+ * exception or by returning normally. If a thread is interrupted or the
+ * channel upon which it is blocked is asynchronously closed then the channel's
+ * {@link #end end} method will throw the appropriate exception.
+ *
+ * <p> This class performs the synchronization required to implement the {@link
+ * java.nio.channels.Channel} specification. Implementations of the {@link
+ * #implCloseChannel implCloseChannel} method need not synchronize against
+ * other threads that might be attempting to close the channel. </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class AbstractInterruptibleChannel
+ implements Channel, InterruptibleChannel
+{
+
+ private final Object closeLock = new Object();
+ private volatile boolean open = true;
+
+ /**
+ * Initializes a new instance of this class.
+ */
+ protected AbstractInterruptibleChannel() { }
+
+ /**
+ * Closes this channel.
+ *
+ * <p> If the channel has already been closed then this method returns
+ * immediately. Otherwise it marks the channel as closed and then invokes
+ * the {@link #implCloseChannel implCloseChannel} method in order to
+ * complete the close operation. </p>
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ public final void close() throws IOException {
+ synchronized (closeLock) {
+ if (!open)
+ return;
+ open = false;
+ implCloseChannel();
+ }
+ }
+
+ /**
+ * Closes this channel.
+ *
+ * <p> This method is invoked by the {@link #close close} method in order
+ * to perform the actual work of closing the channel. This method is only
+ * invoked if the channel has not yet been closed, and it is never invoked
+ * more than once.
+ *
+ * <p> An implementation of this method must arrange for any other thread
+ * that is blocked in an I/O operation upon this channel to return
+ * immediately, either by throwing an exception or by returning normally.
+ * </p>
+ *
+ * @throws IOException
+ * If an I/O error occurs while closing the channel
+ */
+ protected abstract void implCloseChannel() throws IOException;
+
+ public final boolean isOpen() {
+ return open;
+ }
+
+
+ // -- Interruption machinery --
+
+ private Interruptible interruptor;
+ private volatile Thread interrupted;
+
+ /**
+ * Marks the beginning of an I/O operation that might block indefinitely.
+ *
+ * <p> This method should be invoked in tandem with the {@link #end end}
+ * method, using a <tt>try</tt> ... <tt>finally</tt> block as
+ * shown <a href="#be">above</a>, in order to implement asynchronous
+ * closing and interruption for this channel. </p>
+ */
+ protected final void begin() {
+ if (interruptor == null) {
+ interruptor = new Interruptible() {
+ public void interrupt(Thread target) {
+ synchronized (closeLock) {
+ if (!open)
+ return;
+ open = false;
+ interrupted = target;
+ try {
+ AbstractInterruptibleChannel.this.implCloseChannel();
+ } catch (IOException x) { }
+ }
+ }};
+ }
+ blockedOn(interruptor);
+ Thread me = Thread.currentThread();
+ if (me.isInterrupted())
+ interruptor.interrupt(me);
+ }
+
+ /**
+ * Marks the end of an I/O operation that might block indefinitely.
+ *
+ * <p> This method should be invoked in tandem with the {@link #begin
+ * begin} method, using a <tt>try</tt> ... <tt>finally</tt> block
+ * as shown <a href="#be">above</a>, in order to implement asynchronous
+ * closing and interruption for this channel. </p>
+ *
+ * @param completed
+ * <tt>true</tt> if, and only if, the I/O operation completed
+ * successfully, that is, had some effect that would be visible to
+ * the operation's invoker
+ *
+ * @throws AsynchronousCloseException
+ * If the channel was asynchronously closed
+ *
+ * @throws ClosedByInterruptException
+ * If the thread blocked in the I/O operation was interrupted
+ */
+ protected final void end(boolean completed)
+ throws AsynchronousCloseException
+ {
+ blockedOn(null);
+ Thread interrupted = this.interrupted;
+ if (interrupted != null && interrupted == Thread.currentThread()) {
+ interrupted = null;
+ throw new ClosedByInterruptException();
+ }
+ if (!completed && !open)
+ throw new AsynchronousCloseException();
+ }
+
+
+ // -- sun.misc.SharedSecrets --
+ static void blockedOn(Interruptible intr) { // package-private
+ // Android-changed: Call Thread.currentThread().blockedOn() directly.
+ Thread.currentThread().blockedOn(intr);
+ }
+}
diff --git a/java/nio/channels/spi/AbstractSelectableChannel.java b/java/nio/channels/spi/AbstractSelectableChannel.java
new file mode 100644
index 0000000..0de212d
--- /dev/null
+++ b/java/nio/channels/spi/AbstractSelectableChannel.java
@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels.spi;
+
+import java.io.IOException;
+import java.nio.channels.*;
+
+
+/**
+ * Base implementation class for selectable channels.
+ *
+ * <p> This class defines methods that handle the mechanics of channel
+ * registration, deregistration, and closing. It maintains the current
+ * blocking mode of this channel as well as its current set of selection keys.
+ * It performs all of the synchronization required to implement the {@link
+ * java.nio.channels.SelectableChannel} specification. Implementations of the
+ * abstract protected methods defined in this class need not synchronize
+ * against other threads that might be engaged in the same operations. </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author Mike McCloskey
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class AbstractSelectableChannel
+ extends SelectableChannel
+{
+
+ // The provider that created this channel
+ private final SelectorProvider provider;
+
+ // Keys that have been created by registering this channel with selectors.
+ // They are saved because if this channel is closed the keys must be
+ // deregistered. Protected by keyLock.
+ //
+ private SelectionKey[] keys = null;
+ private int keyCount = 0;
+
+ // Lock for key set and count
+ private final Object keyLock = new Object();
+
+ // Lock for registration and configureBlocking operations
+ private final Object regLock = new Object();
+
+ // Blocking mode, protected by regLock
+ boolean blocking = true;
+
+ /**
+ * Initializes a new instance of this class.
+ *
+ * @param provider
+ * The provider that created this channel
+ */
+ protected AbstractSelectableChannel(SelectorProvider provider) {
+ this.provider = provider;
+ }
+
+ /**
+ * Returns the provider that created this channel.
+ *
+ * @return The provider that created this channel
+ */
+ public final SelectorProvider provider() {
+ return provider;
+ }
+
+
+ // -- Utility methods for the key set --
+
+ private void addKey(SelectionKey k) {
+ assert Thread.holdsLock(keyLock);
+ int i = 0;
+ if ((keys != null) && (keyCount < keys.length)) {
+ // Find empty element of key array
+ for (i = 0; i < keys.length; i++)
+ if (keys[i] == null)
+ break;
+ } else if (keys == null) {
+ keys = new SelectionKey[3];
+ } else {
+ // Grow key array
+ int n = keys.length * 2;
+ SelectionKey[] ks = new SelectionKey[n];
+ for (i = 0; i < keys.length; i++)
+ ks[i] = keys[i];
+ keys = ks;
+ i = keyCount;
+ }
+ keys[i] = k;
+ keyCount++;
+ }
+
+ private SelectionKey findKey(Selector sel) {
+ synchronized (keyLock) {
+ if (keys == null)
+ return null;
+ for (int i = 0; i < keys.length; i++)
+ if ((keys[i] != null) && (keys[i].selector() == sel))
+ return keys[i];
+ return null;
+ }
+ }
+
+ void removeKey(SelectionKey k) { // package-private
+ synchronized (keyLock) {
+ for (int i = 0; i < keys.length; i++)
+ if (keys[i] == k) {
+ keys[i] = null;
+ keyCount--;
+ }
+ ((AbstractSelectionKey)k).invalidate();
+ }
+ }
+
+ private boolean haveValidKeys() {
+ synchronized (keyLock) {
+ if (keyCount == 0)
+ return false;
+ for (int i = 0; i < keys.length; i++) {
+ if ((keys[i] != null) && keys[i].isValid())
+ return true;
+ }
+ return false;
+ }
+ }
+
+
+ // -- Registration --
+
+ public final boolean isRegistered() {
+ synchronized (keyLock) {
+ return keyCount != 0;
+ }
+ }
+
+ public final SelectionKey keyFor(Selector sel) {
+ return findKey(sel);
+ }
+
+ /**
+ * Registers this channel with the given selector, returning a selection key.
+ *
+ * <p> This method first verifies that this channel is open and that the
+ * given initial interest set is valid.
+ *
+ * <p> If this channel is already registered with the given selector then
+ * the selection key representing that registration is returned after
+ * setting its interest set to the given value.
+ *
+ * <p> Otherwise this channel has not yet been registered with the given
+ * selector, so the {@link AbstractSelector#register register} method of
+ * the selector is invoked while holding the appropriate locks. The
+ * resulting key is added to this channel's key set before being returned.
+ * </p>
+ *
+ * @throws ClosedSelectorException {@inheritDoc}
+ *
+ * @throws IllegalBlockingModeException {@inheritDoc}
+ *
+ * @throws IllegalSelectorException {@inheritDoc}
+ *
+ * @throws CancelledKeyException {@inheritDoc}
+ *
+ * @throws IllegalArgumentException {@inheritDoc}
+ */
+ public final SelectionKey register(Selector sel, int ops,
+ Object att)
+ throws ClosedChannelException
+ {
+ synchronized (regLock) {
+ if (!isOpen())
+ throw new ClosedChannelException();
+ if ((ops & ~validOps()) != 0)
+ throw new IllegalArgumentException();
+ if (blocking)
+ throw new IllegalBlockingModeException();
+ SelectionKey k = findKey(sel);
+ if (k != null) {
+ k.interestOps(ops);
+ k.attach(att);
+ }
+ if (k == null) {
+ // New registration
+ synchronized (keyLock) {
+ if (!isOpen())
+ throw new ClosedChannelException();
+ k = ((AbstractSelector)sel).register(this, ops, att);
+ addKey(k);
+ }
+ }
+ return k;
+ }
+ }
+
+
+ // -- Closing --
+
+ /**
+ * Closes this channel.
+ *
+ * <p> This method, which is specified in the {@link
+ * AbstractInterruptibleChannel} class and is invoked by the {@link
+ * java.nio.channels.Channel#close close} method, in turn invokes the
+ * {@link #implCloseSelectableChannel implCloseSelectableChannel} method in
+ * order to perform the actual work of closing this channel. It then
+ * cancels all of this channel's keys. </p>
+ */
+ protected final void implCloseChannel() throws IOException {
+ implCloseSelectableChannel();
+ synchronized (keyLock) {
+ int count = (keys == null) ? 0 : keys.length;
+ for (int i = 0; i < count; i++) {
+ SelectionKey k = keys[i];
+ if (k != null)
+ k.cancel();
+ }
+ }
+ }
+
+ /**
+ * Closes this selectable channel.
+ *
+ * <p> This method is invoked by the {@link java.nio.channels.Channel#close
+ * close} method in order to perform the actual work of closing the
+ * channel. This method is only invoked if the channel has not yet been
+ * closed, and it is never invoked more than once.
+ *
+ * <p> An implementation of this method must arrange for any other thread
+ * that is blocked in an I/O operation upon this channel to return
+ * immediately, either by throwing an exception or by returning normally.
+ * </p>
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ protected abstract void implCloseSelectableChannel() throws IOException;
+
+
+ // -- Blocking --
+
+ public final boolean isBlocking() {
+ synchronized (regLock) {
+ return blocking;
+ }
+ }
+
+ public final Object blockingLock() {
+ return regLock;
+ }
+
+ /**
+ * Adjusts this channel's blocking mode.
+ *
+ * <p> If the given blocking mode is different from the current blocking
+ * mode then this method invokes the {@link #implConfigureBlocking
+ * implConfigureBlocking} method, while holding the appropriate locks, in
+ * order to change the mode. </p>
+ */
+ public final SelectableChannel configureBlocking(boolean block)
+ throws IOException
+ {
+ synchronized (regLock) {
+ if (!isOpen())
+ throw new ClosedChannelException();
+ if (blocking == block)
+ return this;
+ if (block && haveValidKeys())
+ throw new IllegalBlockingModeException();
+ implConfigureBlocking(block);
+ blocking = block;
+ }
+ return this;
+ }
+
+ /**
+ * Adjusts this channel's blocking mode.
+ *
+ * <p> This method is invoked by the {@link #configureBlocking
+ * configureBlocking} method in order to perform the actual work of
+ * changing the blocking mode. This method is only invoked if the new mode
+ * is different from the current mode. </p>
+ *
+ * @param block If <tt>true</tt> then this channel will be placed in
+ * blocking mode; if <tt>false</tt> then it will be placed
+ * non-blocking mode
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ protected abstract void implConfigureBlocking(boolean block)
+ throws IOException;
+
+}
diff --git a/java/nio/channels/spi/AbstractSelectionKey.java b/java/nio/channels/spi/AbstractSelectionKey.java
new file mode 100644
index 0000000..015e6c7
--- /dev/null
+++ b/java/nio/channels/spi/AbstractSelectionKey.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels.spi;
+
+import java.nio.channels.*;
+
+
+/**
+ * Base implementation class for selection keys.
+ *
+ * <p> This class tracks the validity of the key and implements cancellation.
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class AbstractSelectionKey
+ extends SelectionKey
+{
+
+ /**
+ * Initializes a new instance of this class.
+ */
+ protected AbstractSelectionKey() { }
+
+ private volatile boolean valid = true;
+
+ public final boolean isValid() {
+ return valid;
+ }
+
+ void invalidate() { // package-private
+ valid = false;
+ }
+
+ /**
+ * Cancels this key.
+ *
+ * <p> If this key has not yet been cancelled then it is added to its
+ * selector's cancelled-key set while synchronized on that set. </p>
+ */
+ public final void cancel() {
+ // Synchronizing "this" to prevent this key from getting canceled
+ // multiple times by different threads, which might cause race
+ // condition between selector's select() and channel's close().
+ synchronized (this) {
+ if (valid) {
+ valid = false;
+ ((AbstractSelector)selector()).cancel(this);
+ }
+ }
+ }
+}
diff --git a/java/nio/channels/spi/AbstractSelector.java b/java/nio/channels/spi/AbstractSelector.java
new file mode 100644
index 0000000..09e3b61
--- /dev/null
+++ b/java/nio/channels/spi/AbstractSelector.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels.spi;
+
+import java.io.IOException;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.util.HashSet;
+import java.util.Set;
+import sun.nio.ch.Interruptible;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+
+/**
+ * Base implementation class for selectors.
+ *
+ * <p> This class encapsulates the low-level machinery required to implement
+ * the interruption of selection operations. A concrete selector class must
+ * invoke the {@link #begin begin} and {@link #end end} methods before and
+ * after, respectively, invoking an I/O operation that might block
+ * indefinitely. In order to ensure that the {@link #end end} method is always
+ * invoked, these methods should be used within a
+ * <tt>try</tt> ... <tt>finally</tt> block:
+ *
+ * <blockquote><pre>
+ * try {
+ * begin();
+ * // Perform blocking I/O operation here
+ * ...
+ * } finally {
+ * end();
+ * }</pre></blockquote>
+ *
+ * <p> This class also defines methods for maintaining a selector's
+ * cancelled-key set and for removing a key from its channel's key set, and
+ * declares the abstract {@link #register register} method that is invoked by a
+ * selectable channel's {@link AbstractSelectableChannel#register register}
+ * method in order to perform the actual work of registering a channel. </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class AbstractSelector
+ extends Selector
+{
+
+ private AtomicBoolean selectorOpen = new AtomicBoolean(true);
+
+ // The provider that created this selector
+ private final SelectorProvider provider;
+
+ /**
+ * Initializes a new instance of this class.
+ *
+ * @param provider
+ * The provider that created this selector
+ */
+ protected AbstractSelector(SelectorProvider provider) {
+ this.provider = provider;
+ }
+
+ private final Set<SelectionKey> cancelledKeys = new HashSet<SelectionKey>();
+
+ void cancel(SelectionKey k) { // package-private
+ synchronized (cancelledKeys) {
+ cancelledKeys.add(k);
+ }
+ }
+
+ /**
+ * Closes this selector.
+ *
+ * <p> If the selector has already been closed then this method returns
+ * immediately. Otherwise it marks the selector as closed and then invokes
+ * the {@link #implCloseSelector implCloseSelector} method in order to
+ * complete the close operation. </p>
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ public final void close() throws IOException {
+ boolean open = selectorOpen.getAndSet(false);
+ if (!open)
+ return;
+ implCloseSelector();
+ }
+
+ /**
+ * Closes this selector.
+ *
+ * <p> This method is invoked by the {@link #close close} method in order
+ * to perform the actual work of closing the selector. This method is only
+ * invoked if the selector has not yet been closed, and it is never invoked
+ * more than once.
+ *
+ * <p> An implementation of this method must arrange for any other thread
+ * that is blocked in a selection operation upon this selector to return
+ * immediately as if by invoking the {@link
+ * java.nio.channels.Selector#wakeup wakeup} method. </p>
+ *
+ * @throws IOException
+ * If an I/O error occurs while closing the selector
+ */
+ protected abstract void implCloseSelector() throws IOException;
+
+ public final boolean isOpen() {
+ return selectorOpen.get();
+ }
+
+ /**
+ * Returns the provider that created this channel.
+ *
+ * @return The provider that created this channel
+ */
+ public final SelectorProvider provider() {
+ return provider;
+ }
+
+ /**
+ * Retrieves this selector's cancelled-key set.
+ *
+ * <p> This set should only be used while synchronized upon it. </p>
+ *
+ * @return The cancelled-key set
+ */
+ protected final Set<SelectionKey> cancelledKeys() {
+ return cancelledKeys;
+ }
+
+ /**
+ * Registers the given channel with this selector.
+ *
+ * <p> This method is invoked by a channel's {@link
+ * AbstractSelectableChannel#register register} method in order to perform
+ * the actual work of registering the channel with this selector. </p>
+ *
+ * @param ch
+ * The channel to be registered
+ *
+ * @param ops
+ * The initial interest set, which must be valid
+ *
+ * @param att
+ * The initial attachment for the resulting key
+ *
+ * @return A new key representing the registration of the given channel
+ * with this selector
+ */
+ protected abstract SelectionKey register(AbstractSelectableChannel ch,
+ int ops, Object att);
+
+ /**
+ * Removes the given key from its channel's key set.
+ *
+ * <p> This method must be invoked by the selector for each channel that it
+ * deregisters. </p>
+ *
+ * @param key
+ * The selection key to be removed
+ */
+ protected final void deregister(AbstractSelectionKey key) {
+ ((AbstractSelectableChannel)key.channel()).removeKey(key);
+ }
+
+
+ // -- Interruption machinery --
+
+ private Interruptible interruptor = null;
+
+ /**
+ * Marks the beginning of an I/O operation that might block indefinitely.
+ *
+ * <p> This method should be invoked in tandem with the {@link #end end}
+ * method, using a <tt>try</tt> ... <tt>finally</tt> block as
+ * shown <a href="#be">above</a>, in order to implement interruption for
+ * this selector.
+ *
+ * <p> Invoking this method arranges for the selector's {@link
+ * Selector#wakeup wakeup} method to be invoked if a thread's {@link
+ * Thread#interrupt interrupt} method is invoked while the thread is
+ * blocked in an I/O operation upon the selector. </p>
+ */
+ protected final void begin() {
+ if (interruptor == null) {
+ interruptor = new Interruptible() {
+ public void interrupt(Thread ignore) {
+ AbstractSelector.this.wakeup();
+ }};
+ }
+ AbstractInterruptibleChannel.blockedOn(interruptor);
+ Thread me = Thread.currentThread();
+ if (me.isInterrupted())
+ interruptor.interrupt(me);
+ }
+
+ /**
+ * Marks the end of an I/O operation that might block indefinitely.
+ *
+ * <p> This method should be invoked in tandem with the {@link #begin begin}
+ * method, using a <tt>try</tt> ... <tt>finally</tt> block as
+ * shown <a href="#be">above</a>, in order to implement interruption for
+ * this selector. </p>
+ */
+ protected final void end() {
+ AbstractInterruptibleChannel.blockedOn(null);
+ }
+
+}
diff --git a/java/nio/channels/spi/AsynchronousChannelProvider.java b/java/nio/channels/spi/AsynchronousChannelProvider.java
new file mode 100644
index 0000000..464b4fc
--- /dev/null
+++ b/java/nio/channels/spi/AsynchronousChannelProvider.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels.spi;
+
+import java.nio.channels.*;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.ServiceLoader;
+import java.util.ServiceConfigurationError;
+import java.util.concurrent.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Service-provider class for asynchronous channels.
+ *
+ * <p> An asynchronous channel provider is a concrete subclass of this class that
+ * has a zero-argument constructor and implements the abstract methods specified
+ * below. A given invocation of the Java virtual machine maintains a single
+ * system-wide default provider instance, which is returned by the {@link
+ * #provider() provider} method. The first invocation of that method will locate
+ * the default provider as specified below.
+ *
+ * <p> All of the methods in this class are safe for use by multiple concurrent
+ * threads. </p>
+ *
+ * @since 1.7
+ */
+
+public abstract class AsynchronousChannelProvider {
+ private static Void checkPermission() {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("asynchronousChannelProvider"));
+ return null;
+ }
+ private AsynchronousChannelProvider(Void ignore) { }
+
+ /**
+ * Initializes a new instance of this class.
+ *
+ * @throws SecurityException
+ * If a security manager has been installed and it denies
+ * {@link RuntimePermission}<tt>("asynchronousChannelProvider")</tt>
+ */
+ protected AsynchronousChannelProvider() {
+ this(checkPermission());
+ }
+
+ // lazy initialization of default provider
+ private static class ProviderHolder {
+ static final AsynchronousChannelProvider provider = load();
+
+ private static AsynchronousChannelProvider load() {
+ return AccessController
+ .doPrivileged(new PrivilegedAction<AsynchronousChannelProvider>() {
+ public AsynchronousChannelProvider run() {
+ AsynchronousChannelProvider p;
+ p = loadProviderFromProperty();
+ if (p != null)
+ return p;
+ p = loadProviderAsService();
+ if (p != null)
+ return p;
+ return sun.nio.ch.DefaultAsynchronousChannelProvider.create();
+ }});
+ }
+
+ private static AsynchronousChannelProvider loadProviderFromProperty() {
+ String cn = System.getProperty("java.nio.channels.spi.AsynchronousChannelProvider");
+ if (cn == null)
+ return null;
+ try {
+ Class<?> c = Class.forName(cn, true,
+ ClassLoader.getSystemClassLoader());
+ return (AsynchronousChannelProvider)c.newInstance();
+ } catch (ClassNotFoundException x) {
+ throw new ServiceConfigurationError(null, x);
+ } catch (IllegalAccessException x) {
+ throw new ServiceConfigurationError(null, x);
+ } catch (InstantiationException x) {
+ throw new ServiceConfigurationError(null, x);
+ } catch (SecurityException x) {
+ throw new ServiceConfigurationError(null, x);
+ }
+ }
+
+ private static AsynchronousChannelProvider loadProviderAsService() {
+ ServiceLoader<AsynchronousChannelProvider> sl =
+ ServiceLoader.load(AsynchronousChannelProvider.class,
+ ClassLoader.getSystemClassLoader());
+ Iterator<AsynchronousChannelProvider> i = sl.iterator();
+ for (;;) {
+ try {
+ return (i.hasNext()) ? i.next() : null;
+ } catch (ServiceConfigurationError sce) {
+ if (sce.getCause() instanceof SecurityException) {
+ // Ignore the security exception, try the next provider
+ continue;
+ }
+ throw sce;
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the system-wide default asynchronous channel provider for this
+ * invocation of the Java virtual machine.
+ *
+ * <p> The first invocation of this method locates the default provider
+ * object as follows: </p>
+ *
+ * <ol>
+ *
+ * <li><p> If the system property
+ * <tt>java.nio.channels.spi.AsynchronousChannelProvider</tt> is defined
+ * then it is taken to be the fully-qualified name of a concrete provider class.
+ * The class is loaded and instantiated; if this process fails then an
+ * unspecified error is thrown. </p></li>
+ *
+ * <li><p> If a provider class has been installed in a jar file that is
+ * visible to the system class loader, and that jar file contains a
+ * provider-configuration file named
+ * <tt>java.nio.channels.spi.AsynchronousChannelProvider</tt> in the resource
+ * directory <tt>META-INF/services</tt>, then the first class name
+ * specified in that file is taken. The class is loaded and
+ * instantiated; if this process fails then an unspecified error is
+ * thrown. </p></li>
+ *
+ * <li><p> Finally, if no provider has been specified by any of the above
+ * means then the system-default provider class is instantiated and the
+ * result is returned. </p></li>
+ *
+ * </ol>
+ *
+ * <p> Subsequent invocations of this method return the provider that was
+ * returned by the first invocation. </p>
+ *
+ * @return The system-wide default AsynchronousChannel provider
+ */
+ public static AsynchronousChannelProvider provider() {
+ return ProviderHolder.provider;
+ }
+
+ /**
+ * Constructs a new asynchronous channel group with a fixed thread pool.
+ *
+ * @param nThreads
+ * The number of threads in the pool
+ * @param threadFactory
+ * The factory to use when creating new threads
+ *
+ * @return A new asynchronous channel group
+ *
+ * @throws IllegalArgumentException
+ * If {@code nThreads <= 0}
+ * @throws IOException
+ * If an I/O error occurs
+ *
+ * @see AsynchronousChannelGroup#withFixedThreadPool
+ */
+ public abstract AsynchronousChannelGroup
+ openAsynchronousChannelGroup(int nThreads, ThreadFactory threadFactory) throws IOException;
+
+ /**
+ * Constructs a new asynchronous channel group with the given thread pool.
+ *
+ * @param executor
+ * The thread pool
+ * @param initialSize
+ * A value {@code >=0} or a negative value for implementation
+ * specific default
+ *
+ * @return A new asynchronous channel group
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ *
+ * @see AsynchronousChannelGroup#withCachedThreadPool
+ */
+ public abstract AsynchronousChannelGroup
+ openAsynchronousChannelGroup(ExecutorService executor, int initialSize) throws IOException;
+
+ /**
+ * Opens an asynchronous server-socket channel.
+ *
+ * @param group
+ * The group to which the channel is bound, or {@code null} to
+ * bind to the default group
+ *
+ * @return The new channel
+ *
+ * @throws IllegalChannelGroupException
+ * If the provider that created the group differs from this provider
+ * @throws ShutdownChannelGroupException
+ * The group is shutdown
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ public abstract AsynchronousServerSocketChannel openAsynchronousServerSocketChannel
+ (AsynchronousChannelGroup group) throws IOException;
+
+ /**
+ * Opens an asynchronous socket channel.
+ *
+ * @param group
+ * The group to which the channel is bound, or {@code null} to
+ * bind to the default group
+ *
+ * @return The new channel
+ *
+ * @throws IllegalChannelGroupException
+ * If the provider that created the group differs from this provider
+ * @throws ShutdownChannelGroupException
+ * The group is shutdown
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ public abstract AsynchronousSocketChannel openAsynchronousSocketChannel
+ (AsynchronousChannelGroup group) throws IOException;
+}
diff --git a/java/nio/channels/spi/SelectorProvider.java b/java/nio/channels/spi/SelectorProvider.java
new file mode 100644
index 0000000..2dbef05
--- /dev/null
+++ b/java/nio/channels/spi/SelectorProvider.java
@@ -0,0 +1,317 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels.spi;
+
+import java.io.IOException;
+import java.net.ProtocolFamily;
+import java.nio.channels.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Iterator;
+import java.util.ServiceLoader;
+import java.util.ServiceConfigurationError;
+import sun.security.action.GetPropertyAction;
+
+
+/**
+ * Service-provider class for selectors and selectable channels.
+ *
+ * <p> A selector provider is a concrete subclass of this class that has a
+ * zero-argument constructor and implements the abstract methods specified
+ * below. A given invocation of the Java virtual machine maintains a single
+ * system-wide default provider instance, which is returned by the {@link
+ * #provider() provider} method. The first invocation of that method will locate
+ * the default provider as specified below.
+ *
+ * <p> The system-wide default provider is used by the static <tt>open</tt>
+ * methods of the {@link java.nio.channels.DatagramChannel#open
+ * DatagramChannel}, {@link java.nio.channels.Pipe#open Pipe}, {@link
+ * java.nio.channels.Selector#open Selector}, {@link
+ * java.nio.channels.ServerSocketChannel#open ServerSocketChannel}, and {@link
+ * java.nio.channels.SocketChannel#open SocketChannel} classes. It is also
+ * used by the {@link java.lang.System#inheritedChannel System.inheritedChannel()}
+ * method. A program may make use of a provider other than the default provider
+ * by instantiating that provider and then directly invoking the <tt>open</tt>
+ * methods defined in this class.
+ *
+ * <p> All of the methods in this class are safe for use by multiple concurrent
+ * threads. </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class SelectorProvider {
+
+ private static final Object lock = new Object();
+ private static SelectorProvider provider = null;
+
+ /**
+ * Initializes a new instance of this class.
+ *
+ * @throws SecurityException
+ * If a security manager has been installed and it denies
+ * {@link RuntimePermission}<tt>("selectorProvider")</tt>
+ */
+ protected SelectorProvider() {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("selectorProvider"));
+ }
+
+ private static boolean loadProviderFromProperty() {
+ String cn = System.getProperty("java.nio.channels.spi.SelectorProvider");
+ if (cn == null)
+ return false;
+ try {
+ Class<?> c = Class.forName(cn, true,
+ ClassLoader.getSystemClassLoader());
+ provider = (SelectorProvider)c.newInstance();
+ return true;
+ } catch (ClassNotFoundException x) {
+ throw new ServiceConfigurationError(null, x);
+ } catch (IllegalAccessException x) {
+ throw new ServiceConfigurationError(null, x);
+ } catch (InstantiationException x) {
+ throw new ServiceConfigurationError(null, x);
+ } catch (SecurityException x) {
+ throw new ServiceConfigurationError(null, x);
+ }
+ }
+
+ private static boolean loadProviderAsService() {
+
+ ServiceLoader<SelectorProvider> sl =
+ ServiceLoader.load(SelectorProvider.class,
+ ClassLoader.getSystemClassLoader());
+ Iterator<SelectorProvider> i = sl.iterator();
+ for (;;) {
+ try {
+ if (!i.hasNext())
+ return false;
+ provider = i.next();
+ return true;
+ } catch (ServiceConfigurationError sce) {
+ if (sce.getCause() instanceof SecurityException) {
+ // Ignore the security exception, try the next provider
+ continue;
+ }
+ throw sce;
+ }
+ }
+ }
+
+ /**
+ * Returns the system-wide default selector provider for this invocation of
+ * the Java virtual machine.
+ *
+ * <p> The first invocation of this method locates the default provider
+ * object as follows: </p>
+ *
+ * <ol>
+ *
+ * <li><p> If the system property
+ * <tt>java.nio.channels.spi.SelectorProvider</tt> is defined then it is
+ * taken to be the fully-qualified name of a concrete provider class.
+ * The class is loaded and instantiated; if this process fails then an
+ * unspecified error is thrown. </p></li>
+ *
+ * <li><p> If a provider class has been installed in a jar file that is
+ * visible to the system class loader, and that jar file contains a
+ * provider-configuration file named
+ * <tt>java.nio.channels.spi.SelectorProvider</tt> in the resource
+ * directory <tt>META-INF/services</tt>, then the first class name
+ * specified in that file is taken. The class is loaded and
+ * instantiated; if this process fails then an unspecified error is
+ * thrown. </p></li>
+ *
+ * <li><p> Finally, if no provider has been specified by any of the above
+ * means then the system-default provider class is instantiated and the
+ * result is returned. </p></li>
+ *
+ * </ol>
+ *
+ * <p> Subsequent invocations of this method return the provider that was
+ * returned by the first invocation. </p>
+ *
+ * @return The system-wide default selector provider
+ */
+ public static SelectorProvider provider() {
+ synchronized (lock) {
+ if (provider != null)
+ return provider;
+ return AccessController.doPrivileged(
+ new PrivilegedAction<SelectorProvider>() {
+ public SelectorProvider run() {
+ if (loadProviderFromProperty())
+ return provider;
+ if (loadProviderAsService())
+ return provider;
+ provider = sun.nio.ch.DefaultSelectorProvider.create();
+ return provider;
+ }
+ });
+ }
+ }
+
+ /**
+ * Opens a datagram channel.
+ *
+ * @return The new channel
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ public abstract DatagramChannel openDatagramChannel()
+ throws IOException;
+
+ /**
+ * Opens a datagram channel.
+ *
+ * @param family
+ * The protocol family
+ *
+ * @return A new datagram channel
+ *
+ * @throws UnsupportedOperationException
+ * If the specified protocol family is not supported
+ * @throws IOException
+ * If an I/O error occurs
+ *
+ * @since 1.7
+ */
+ public abstract DatagramChannel openDatagramChannel(ProtocolFamily family)
+ throws IOException;
+
+ /**
+ * Opens a pipe.
+ *
+ * @return The new pipe
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ public abstract Pipe openPipe()
+ throws IOException;
+
+ /**
+ * Opens a selector.
+ *
+ * @return The new selector
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ public abstract AbstractSelector openSelector()
+ throws IOException;
+
+ /**
+ * Opens a server-socket channel.
+ *
+ * @return The new channel
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ public abstract ServerSocketChannel openServerSocketChannel()
+ throws IOException;
+
+ /**
+ * Opens a socket channel.
+ *
+ * @return The new channel
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ public abstract SocketChannel openSocketChannel()
+ throws IOException;
+
+ /**
+ * Returns the channel inherited from the entity that created this
+ * Java virtual machine.
+ *
+ * <p> On many operating systems a process, such as a Java virtual
+ * machine, can be started in a manner that allows the process to
+ * inherit a channel from the entity that created the process. The
+ * manner in which this is done is system dependent, as are the
+ * possible entities to which the channel may be connected. For example,
+ * on UNIX systems, the Internet services daemon (<i>inetd</i>) is used to
+ * start programs to service requests when a request arrives on an
+ * associated network port. In this example, the process that is started,
+ * inherits a channel representing a network socket.
+ *
+ * <p> In cases where the inherited channel represents a network socket
+ * then the {@link java.nio.channels.Channel Channel} type returned
+ * by this method is determined as follows:
+ *
+ * <ul>
+ *
+ * <li><p> If the inherited channel represents a stream-oriented connected
+ * socket then a {@link java.nio.channels.SocketChannel SocketChannel} is
+ * returned. The socket channel is, at least initially, in blocking
+ * mode, bound to a socket address, and connected to a peer.
+ * </p></li>
+ *
+ * <li><p> If the inherited channel represents a stream-oriented listening
+ * socket then a {@link java.nio.channels.ServerSocketChannel
+ * ServerSocketChannel} is returned. The server-socket channel is, at
+ * least initially, in blocking mode, and bound to a socket address.
+ * </p></li>
+ *
+ * <li><p> If the inherited channel is a datagram-oriented socket
+ * then a {@link java.nio.channels.DatagramChannel DatagramChannel} is
+ * returned. The datagram channel is, at least initially, in blocking
+ * mode, and bound to a socket address.
+ * </p></li>
+ *
+ * </ul>
+ *
+ * <p> In addition to the network-oriented channels described, this method
+ * may return other kinds of channels in the future.
+ *
+ * <p> The first invocation of this method creates the channel that is
+ * returned. Subsequent invocations of this method return the same
+ * channel. </p>
+ *
+ * @return The inherited channel, if any, otherwise <tt>null</tt>.
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ *
+ * @throws SecurityException
+ * If a security manager has been installed and it denies
+ * {@link RuntimePermission}<tt>("inheritedChannel")</tt>
+ *
+ * @since 1.5
+ */
+ public Channel inheritedChannel() throws IOException {
+ return null;
+ }
+
+}
diff --git a/java/nio/charset/CharacterCodingException.java b/java/nio/charset/CharacterCodingException.java
new file mode 100644
index 0000000..1cfeb5f
--- /dev/null
+++ b/java/nio/charset/CharacterCodingException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.charset;
+
+
+/**
+ * Checked exception thrown when a character encoding
+ * or decoding error occurs.
+ *
+ * @since 1.4
+ */
+
+public class CharacterCodingException
+ extends java.io.IOException
+{
+
+ private static final long serialVersionUID = 8421532232154627783L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public CharacterCodingException() { }
+
+}
diff --git a/java/nio/charset/Charset.java b/java/nio/charset/Charset.java
new file mode 100644
index 0000000..5a3b35a
--- /dev/null
+++ b/java/nio/charset/Charset.java
@@ -0,0 +1,967 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.charset;
+
+import com.android.icu.charset.CharsetICU;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.spi.CharsetProvider;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.AbstractMap;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.ServiceLoader;
+import java.util.ServiceConfigurationError;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import sun.misc.ASCIICaseInsensitiveComparator;
+import sun.nio.cs.ThreadLocalCoders;
+import sun.security.action.GetPropertyAction;
+
+
+// Android-changed: Docs to say UTF-8 is always the platform default charset.
+/**
+ * A named mapping between sequences of sixteen-bit Unicode <a
+ * href="../../lang/Character.html#unicode">code units</a> and sequences of
+ * bytes. This class defines methods for creating decoders and encoders and
+ * for retrieving the various names associated with a charset. Instances of
+ * this class are immutable.
+ *
+ * <p> This class also defines static methods for testing whether a particular
+ * charset is supported, for locating charset instances by name, and for
+ * constructing a map that contains every charset for which support is
+ * available in the current Java virtual machine. Support for new charsets can
+ * be added via the service-provider interface defined in the {@link
+ * java.nio.charset.spi.CharsetProvider} class.
+ *
+ * <p> All of the methods defined in this class are safe for use by multiple
+ * concurrent threads.
+ *
+ *
+ * <a name="names"></a><a name="charenc"></a>
+ * <h2>Charset names</h2>
+ *
+ * <p> Charsets are named by strings composed of the following characters:
+ *
+ * <ul>
+ *
+ * <li> The uppercase letters <tt>'A'</tt> through <tt>'Z'</tt>
+ * (<tt>'\u0041'</tt> through <tt>'\u005a'</tt>),
+ *
+ * <li> The lowercase letters <tt>'a'</tt> through <tt>'z'</tt>
+ * (<tt>'\u0061'</tt> through <tt>'\u007a'</tt>),
+ *
+ * <li> The digits <tt>'0'</tt> through <tt>'9'</tt>
+ * (<tt>'\u0030'</tt> through <tt>'\u0039'</tt>),
+ *
+ * <li> The dash character <tt>'-'</tt>
+ * (<tt>'\u002d'</tt>, <small>HYPHEN-MINUS</small>),
+ *
+ * <li> The plus character <tt>'+'</tt>
+ * (<tt>'\u002b'</tt>, <small>PLUS SIGN</small>),
+ *
+ * <li> The period character <tt>'.'</tt>
+ * (<tt>'\u002e'</tt>, <small>FULL STOP</small>),
+ *
+ * <li> The colon character <tt>':'</tt>
+ * (<tt>'\u003a'</tt>, <small>COLON</small>), and
+ *
+ * <li> The underscore character <tt>'_'</tt>
+ * (<tt>'\u005f'</tt>, <small>LOW LINE</small>).
+ *
+ * </ul>
+ *
+ * A charset name must begin with either a letter or a digit. The empty string
+ * is not a legal charset name. Charset names are not case-sensitive; that is,
+ * case is always ignored when comparing charset names. Charset names
+ * generally follow the conventions documented in <a
+ * href="http://www.ietf.org/rfc/rfc2278.txt"><i>RFC 2278: IANA Charset
+ * Registration Procedures</i></a>.
+ *
+ * <p> Every charset has a <i>canonical name</i> and may also have one or more
+ * <i>aliases</i>. The canonical name is returned by the {@link #name() name} method
+ * of this class. Canonical names are, by convention, usually in upper case.
+ * The aliases of a charset are returned by the {@link #aliases() aliases}
+ * method.
+ *
+ * <p><a name="hn">Some charsets have an <i>historical name</i> that is defined for
+ * compatibility with previous versions of the Java platform.</a> A charset's
+ * historical name is either its canonical name or one of its aliases. The
+ * historical name is returned by the <tt>getEncoding()</tt> methods of the
+ * {@link java.io.InputStreamReader#getEncoding InputStreamReader} and {@link
+ * java.io.OutputStreamWriter#getEncoding OutputStreamWriter} classes.
+ *
+ * <p><a name="iana"> </a>If a charset listed in the <a
+ * href="http://www.iana.org/assignments/character-sets"><i>IANA Charset
+ * Registry</i></a> is supported by an implementation of the Java platform then
+ * its canonical name must be the name listed in the registry. Many charsets
+ * are given more than one name in the registry, in which case the registry
+ * identifies one of the names as <i>MIME-preferred</i>. If a charset has more
+ * than one registry name then its canonical name must be the MIME-preferred
+ * name and the other names in the registry must be valid aliases. If a
+ * supported charset is not listed in the IANA registry then its canonical name
+ * must begin with one of the strings <tt>"X-"</tt> or <tt>"x-"</tt>.
+ *
+ * <p> The IANA charset registry does change over time, and so the canonical
+ * name and the aliases of a particular charset may also change over time. To
+ * ensure compatibility it is recommended that no alias ever be removed from a
+ * charset, and that if the canonical name of a charset is changed then its
+ * previous canonical name be made into an alias.
+ *
+ *
+ * <h2>Standard charsets</h2>
+ *
+ *
+ *
+ * <p><a name="standard">Every implementation of the Java platform is required to support the
+ * following standard charsets.</a> Consult the release documentation for your
+ * implementation to see if any other charsets are supported. The behavior
+ * of such optional charsets may differ between implementations.
+ *
+ * <blockquote><table width="80%" summary="Description of standard charsets">
+ * <tr><th align="left">Charset</th><th align="left">Description</th></tr>
+ * <tr><td valign=top><tt>US-ASCII</tt></td>
+ * <td>Seven-bit ASCII, a.k.a. <tt>ISO646-US</tt>,
+ * a.k.a. the Basic Latin block of the Unicode character set</td></tr>
+ * <tr><td valign=top><tt>ISO-8859-1 </tt></td>
+ * <td>ISO Latin Alphabet No. 1, a.k.a. <tt>ISO-LATIN-1</tt></td></tr>
+ * <tr><td valign=top><tt>UTF-8</tt></td>
+ * <td>Eight-bit UCS Transformation Format</td></tr>
+ * <tr><td valign=top><tt>UTF-16BE</tt></td>
+ * <td>Sixteen-bit UCS Transformation Format,
+ * big-endian byte order</td></tr>
+ * <tr><td valign=top><tt>UTF-16LE</tt></td>
+ * <td>Sixteen-bit UCS Transformation Format,
+ * little-endian byte order</td></tr>
+ * <tr><td valign=top><tt>UTF-16</tt></td>
+ * <td>Sixteen-bit UCS Transformation Format,
+ * byte order identified by an optional byte-order mark</td></tr>
+ * </table></blockquote>
+ *
+ * <p> The <tt>UTF-8</tt> charset is specified by <a
+ * href="http://www.ietf.org/rfc/rfc2279.txt"><i>RFC 2279</i></a>; the
+ * transformation format upon which it is based is specified in
+ * Amendment 2 of ISO 10646-1 and is also described in the <a
+ * href="http://www.unicode.org/unicode/standard/standard.html"><i>Unicode
+ * Standard</i></a>.
+ *
+ * <p> The <tt>UTF-16</tt> charsets are specified by <a
+ * href="http://www.ietf.org/rfc/rfc2781.txt"><i>RFC 2781</i></a>; the
+ * transformation formats upon which they are based are specified in
+ * Amendment 1 of ISO 10646-1 and are also described in the <a
+ * href="http://www.unicode.org/unicode/standard/standard.html"><i>Unicode
+ * Standard</i></a>.
+ *
+ * <p> The <tt>UTF-16</tt> charsets use sixteen-bit quantities and are
+ * therefore sensitive to byte order. In these encodings the byte order of a
+ * stream may be indicated by an initial <i>byte-order mark</i> represented by
+ * the Unicode character <tt>'\uFEFF'</tt>. Byte-order marks are handled
+ * as follows:
+ *
+ * <ul>
+ *
+ * <li><p> When decoding, the <tt>UTF-16BE</tt> and <tt>UTF-16LE</tt>
+ * charsets interpret the initial byte-order marks as a <small>ZERO-WIDTH
+ * NON-BREAKING SPACE</small>; when encoding, they do not write
+ * byte-order marks. </p></li>
+
+ *
+ * <li><p> When decoding, the <tt>UTF-16</tt> charset interprets the
+ * byte-order mark at the beginning of the input stream to indicate the
+ * byte-order of the stream but defaults to big-endian if there is no
+ * byte-order mark; when encoding, it uses big-endian byte order and writes
+ * a big-endian byte-order mark. </p></li>
+ *
+ * </ul>
+ *
+ * In any case, byte order marks occurring after the first element of an
+ * input sequence are not omitted since the same code is used to represent
+ * <small>ZERO-WIDTH NON-BREAKING SPACE</small>.
+ *
+ * <p>Android note: The Android platform default is always UTF-8.
+ *
+ * <p>The {@link StandardCharsets} class defines constants for each of the
+ * standard charsets.
+ *
+ * <h2>Terminology</h2>
+ *
+ * <p> The name of this class is taken from the terms used in
+ * <a href="http://www.ietf.org/rfc/rfc2278.txt"><i>RFC 2278</i></a>.
+ * In that document a <i>charset</i> is defined as the combination of
+ * one or more coded character sets and a character-encoding scheme.
+ * (This definition is confusing; some other software systems define
+ * <i>charset</i> as a synonym for <i>coded character set</i>.)
+ *
+ * <p> A <i>coded character set</i> is a mapping between a set of abstract
+ * characters and a set of integers. US-ASCII, ISO 8859-1,
+ * JIS X 0201, and Unicode are examples of coded character sets.
+ *
+ * <p> Some standards have defined a <i>character set</i> to be simply a
+ * set of abstract characters without an associated assigned numbering.
+ * An alphabet is an example of such a character set. However, the subtle
+ * distinction between <i>character set</i> and <i>coded character set</i>
+ * is rarely used in practice; the former has become a short form for the
+ * latter, including in the Java API specification.
+ *
+ * <p> A <i>character-encoding scheme</i> is a mapping between one or more
+ * coded character sets and a set of octet (eight-bit byte) sequences.
+ * UTF-8, UTF-16, ISO 2022, and EUC are examples of
+ * character-encoding schemes. Encoding schemes are often associated with
+ * a particular coded character set; UTF-8, for example, is used only to
+ * encode Unicode. Some schemes, however, are associated with multiple
+ * coded character sets; EUC, for example, can be used to encode
+ * characters in a variety of Asian coded character sets.
+ *
+ * <p> When a coded character set is used exclusively with a single
+ * character-encoding scheme then the corresponding charset is usually
+ * named for the coded character set; otherwise a charset is usually named
+ * for the encoding scheme and, possibly, the locale of the coded
+ * character sets that it supports. Hence <tt>US-ASCII</tt> is both the
+ * name of a coded character set and of the charset that encodes it, while
+ * <tt>EUC-JP</tt> is the name of the charset that encodes the
+ * JIS X 0201, JIS X 0208, and JIS X 0212
+ * coded character sets for the Japanese language.
+ *
+ * <p> The native character encoding of the Java programming language is
+ * UTF-16. A charset in the Java platform therefore defines a mapping
+ * between sequences of sixteen-bit UTF-16 code units (that is, sequences
+ * of chars) and sequences of bytes. </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ *
+ * @see CharsetDecoder
+ * @see CharsetEncoder
+ * @see java.nio.charset.spi.CharsetProvider
+ * @see java.lang.Character
+ */
+
+public abstract class Charset
+ implements Comparable<Charset>
+{
+
+ /* -- Static methods -- */
+
+ private static volatile String bugLevel = null;
+
+ static boolean atBugLevel(String bl) { // package-private
+ String level = bugLevel;
+ if (level == null) {
+ if (!sun.misc.VM.isBooted())
+ return false;
+ bugLevel = level = AccessController.doPrivileged(
+ new GetPropertyAction("sun.nio.cs.bugLevel", ""));
+ }
+ return level.equals(bl);
+ }
+
+ /**
+ * Checks that the given string is a legal charset name. </p>
+ *
+ * @param s
+ * A purported charset name
+ *
+ * @throws IllegalCharsetNameException
+ * If the given name is not a legal charset name
+ */
+ private static void checkName(String s) {
+ int n = s.length();
+ if (!atBugLevel("1.4")) {
+ if (n == 0)
+ throw new IllegalCharsetNameException(s);
+ }
+ for (int i = 0; i < n; i++) {
+ char c = s.charAt(i);
+ if (c >= 'A' && c <= 'Z') continue;
+ if (c >= 'a' && c <= 'z') continue;
+ if (c >= '0' && c <= '9') continue;
+ if (c == '-' && i != 0) continue;
+ if (c == '+' && i != 0) continue;
+ if (c == ':' && i != 0) continue;
+ if (c == '_' && i != 0) continue;
+ if (c == '.' && i != 0) continue;
+ throw new IllegalCharsetNameException(s);
+ }
+ }
+
+ // Android-removed: We use ICU's list of standard charsets.
+ /* The standard set of charsets */
+ // private static CharsetProvider standardProvider = new StandardCharsets();
+
+ // Cache of the most-recently-returned charsets,
+ // along with the names that were used to find them
+ //
+ // cache1/2 usage is explained in the lookup method
+ //
+ private static volatile Map.Entry<String, Charset> cache1 = null; // "Level 1" cache
+ private static final HashMap<String, Charset> cache2 = new HashMap<>(); // "Level 2" cache
+
+ private static void cache(String charsetName, Charset cs) {
+ synchronized(cache2) {
+ String canonicalName = cs.name();
+ Charset canonicalCharset = cache2.get(canonicalName);
+
+ if (canonicalCharset != null) {
+ cs = canonicalCharset;
+ } else {
+ cache2.put(canonicalName, cs);
+
+ for (String alias : cs.aliases()) {
+ cache2.put(alias, cs);
+ }
+ }
+
+ cache2.put(charsetName, cs);
+ }
+
+ cache1 = new AbstractMap.SimpleImmutableEntry<>(charsetName, cs);
+ }
+
+ // Creates an iterator that walks over the available providers, ignoring
+ // those whose lookup or instantiation causes a security exception to be
+ // thrown. Should be invoked with full privileges.
+ //
+ private static Iterator<CharsetProvider> providers() {
+ return new Iterator<CharsetProvider>() {
+
+ ServiceLoader<CharsetProvider> sl =
+ ServiceLoader.load(CharsetProvider.class);
+ Iterator<CharsetProvider> i = sl.iterator();
+
+ CharsetProvider next = null;
+
+ private boolean getNext() {
+ while (next == null) {
+ try {
+ if (!i.hasNext())
+ return false;
+ next = i.next();
+ } catch (ServiceConfigurationError sce) {
+ if (sce.getCause() instanceof SecurityException) {
+ // Ignore security exceptions
+ continue;
+ }
+ throw sce;
+ }
+ }
+ return true;
+ }
+
+ public boolean hasNext() {
+ return getNext();
+ }
+
+ public CharsetProvider next() {
+ if (!getNext())
+ throw new NoSuchElementException();
+ CharsetProvider n = next;
+ next = null;
+ return n;
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ };
+ }
+
+ // Thread-local gate to prevent recursive provider lookups
+ private static ThreadLocal<ThreadLocal<?>> gate =
+ new ThreadLocal<ThreadLocal<?>>();
+
+ private static Charset lookupViaProviders(final String charsetName) {
+
+ // The runtime startup sequence looks up standard charsets as a
+ // consequence of the VM's invocation of System.initializeSystemClass
+ // in order to, e.g., set system properties and encode filenames. At
+ // that point the application class loader has not been initialized,
+ // however, so we can't look for providers because doing so will cause
+ // that loader to be prematurely initialized with incomplete
+ // information.
+ //
+ if (!sun.misc.VM.isBooted())
+ return null;
+
+ if (gate.get() != null)
+ // Avoid recursive provider lookups
+ return null;
+ try {
+ gate.set(gate);
+
+ return AccessController.doPrivileged(
+ new PrivilegedAction<Charset>() {
+ public Charset run() {
+ for (Iterator<CharsetProvider> i = providers();
+ i.hasNext();) {
+ CharsetProvider cp = i.next();
+ Charset cs = cp.charsetForName(charsetName);
+ if (cs != null)
+ return cs;
+ }
+ return null;
+ }
+ });
+
+ } finally {
+ gate.set(null);
+ }
+ }
+
+ // Android-removed: Remove support for the extended charset provider.
+ //
+ /* The extended set of charsets */
+ // private static Object extendedProviderLock = new Object();
+ // private static boolean extendedProviderProbed = false;
+ // private static CharsetProvider extendedProvider = null;
+ //
+ // private static void probeExtendedProvider() {
+ // AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ // public Object run() {
+ // try {
+ // Class epc
+ // = Class.forName("sun.nio.cs.ext.ExtendedCharsets");
+ // extendedProvider = (CharsetProvider)epc.newInstance();
+ // } catch (ClassNotFoundException x) {
+ // // Extended charsets not available
+ // // (charsets.jar not present)
+ // } catch (InstantiationException x) {
+ // throw new Error(x);
+ // } catch (IllegalAccessException x) {
+ // throw new Error(x);
+ // }
+ // return null;
+ // }
+ // });
+ // }
+ //
+ // private static Charset lookupExtendedCharset(String charsetName) {
+ // CharsetProvider ecp = null;
+ // synchronized (extendedProviderLock) {
+ // if (!extendedProviderProbed) {
+ // probeExtendedProvider();
+ // extendedProviderProbed = true;
+ // }
+ // ecp = extendedProvider;
+ // }
+ // return (ecp != null) ? ecp.charsetForName(charsetName) : null;
+ // }
+
+ // We expect most programs to use one Charset repeatedly, so the most recently used Charset
+ // instance is stored in the level 1 cache. We convey a hint to this effect to the VM by putting
+ // the level 1 cache miss code in a separate method. Since charsetName is not necessarily in
+ // canonical form, we store the mapping from both the canonical name and the aliases to the
+ // instance in a map for level 2 cache.
+ private static Charset lookup(String charsetName) {
+ if (charsetName == null)
+ throw new IllegalArgumentException("Null charset name");
+
+
+ final Map.Entry<String, Charset> cached = cache1;
+ if (cached != null && charsetName.equals(cached.getKey()))
+ return cached.getValue();
+ return lookup2(charsetName);
+ }
+
+ private static Charset lookup2(String charsetName) {
+ Charset cs;
+ synchronized (cache2) {
+ if ((cs = cache2.get(charsetName)) != null) {
+ cache1 = new AbstractMap.SimpleImmutableEntry<>(charsetName, cs);
+ return cs;
+ }
+ }
+
+ // Android-changed: Drop support for "standard" and "extended"
+ // providers.
+ if ((cs = CharsetICU.charsetForName(charsetName)) != null ||
+ (cs = lookupViaProviders(charsetName)) != null)
+ {
+ cache(charsetName, cs);
+ return cs;
+ }
+
+ /* Only need to check the name if we didn't find a charset for it */
+ checkName(charsetName);
+ return null;
+ }
+
+ /**
+ * Tells whether the named charset is supported.
+ *
+ * @param charsetName
+ * The name of the requested charset; may be either
+ * a canonical name or an alias
+ *
+ * @return <tt>true</tt> if, and only if, support for the named charset
+ * is available in the current Java virtual machine
+ *
+ * @throws IllegalCharsetNameException
+ * If the given charset name is illegal
+ *
+ * @throws IllegalArgumentException
+ * If the given <tt>charsetName</tt> is null
+ */
+ public static boolean isSupported(String charsetName) {
+ return (lookup(charsetName) != null);
+ }
+
+ /**
+ * Returns a charset object for the named charset.
+ *
+ * @param charsetName
+ * The name of the requested charset; may be either
+ * a canonical name or an alias
+ *
+ * @return A charset object for the named charset
+ *
+ * @throws IllegalCharsetNameException
+ * If the given charset name is illegal
+ *
+ * @throws IllegalArgumentException
+ * If the given <tt>charsetName</tt> is null
+ *
+ * @throws UnsupportedCharsetException
+ * If no support for the named charset is available
+ * in this instance of the Java virtual machine
+ */
+ public static Charset forName(String charsetName) {
+ Charset cs = lookup(charsetName);
+ if (cs != null)
+ return cs;
+ throw new UnsupportedCharsetException(charsetName);
+ }
+
+ // BEGIN Android-added: forNameUEE(String) method.
+ /**
+ * Equivalent to {@code forName} but only throws {@code UnsupportedEncodingException},
+ * which is all pre-nio code claims to throw.
+ *
+ * @hide internal use only
+ */
+ public static Charset forNameUEE(String charsetName) throws UnsupportedEncodingException {
+ try {
+ return Charset.forName(charsetName);
+ } catch (Exception cause) {
+ UnsupportedEncodingException ex = new UnsupportedEncodingException(charsetName);
+ ex.initCause(cause);
+ throw ex;
+ }
+ }
+ // END Android-added: forNameUEE(String) method.
+
+ // Fold charsets from the given iterator into the given map, ignoring
+ // charsets whose names already have entries in the map.
+ //
+ private static void put(Iterator<Charset> i, Map<String,Charset> m) {
+ while (i.hasNext()) {
+ Charset cs = i.next();
+ if (!m.containsKey(cs.name()))
+ m.put(cs.name(), cs);
+ }
+ }
+
+ /**
+ * Constructs a sorted map from canonical charset names to charset objects.
+ *
+ * <p> The map returned by this method will have one entry for each charset
+ * for which support is available in the current Java virtual machine. If
+ * two or more supported charsets have the same canonical name then the
+ * resulting map will contain just one of them; which one it will contain
+ * is not specified. </p>
+ *
+ * <p> The invocation of this method, and the subsequent use of the
+ * resulting map, may cause time-consuming disk or network I/O operations
+ * to occur. This method is provided for applications that need to
+ * enumerate all of the available charsets, for example to allow user
+ * charset selection. This method is not used by the {@link #forName
+ * forName} method, which instead employs an efficient incremental lookup
+ * algorithm.
+ *
+ * <p> This method may return different results at different times if new
+ * charset providers are dynamically made available to the current Java
+ * virtual machine. In the absence of such changes, the charsets returned
+ * by this method are exactly those that can be retrieved via the {@link
+ * #forName forName} method. </p>
+ *
+ * @return An immutable, case-insensitive map from canonical charset names
+ * to charset objects
+ */
+ public static SortedMap<String,Charset> availableCharsets() {
+ return AccessController.doPrivileged(
+ new PrivilegedAction<SortedMap<String,Charset>>() {
+ public SortedMap<String,Charset> run() {
+ TreeMap<String,Charset> m =
+ new TreeMap<String,Charset>(
+ ASCIICaseInsensitiveComparator.CASE_INSENSITIVE_ORDER);
+ for (String charsetName : CharsetICU.getAvailableCharsetNames()) {
+ Charset charset = CharsetICU.charsetForName(charsetName);
+ m.put(charset.name(), charset);
+ }
+ // Android-changed: No more "standard" provider.
+ // put(standardProvider.charsets(), m);
+ for (Iterator i = providers(); i.hasNext();) {
+ CharsetProvider cp = (CharsetProvider)i.next();
+ put(cp.charsets(), m);
+ }
+ return Collections.unmodifiableSortedMap(m);
+ }
+ });
+ }
+
+ private static Charset defaultCharset;
+
+ /**
+ * Returns the default charset of this Java virtual machine.
+ *
+ * <p>Android note: The Android platform default is always UTF-8.
+ *
+ * @return A charset object for the default charset
+ *
+ * @since 1.5
+ */
+ public static Charset defaultCharset() {
+ // Android-changed: Use UTF_8 unconditionally.
+ synchronized (Charset.class) {
+ if (defaultCharset == null) {
+ defaultCharset = java.nio.charset.StandardCharsets.UTF_8;
+ }
+
+ return defaultCharset;
+ }
+ }
+
+
+ /* -- Instance fields and methods -- */
+
+ private final String name; // tickles a bug in oldjavac
+ private final String[] aliases; // tickles a bug in oldjavac
+ private Set<String> aliasSet = null;
+
+ /**
+ * Initializes a new charset with the given canonical name and alias
+ * set.
+ *
+ * @param canonicalName
+ * The canonical name of this charset
+ *
+ * @param aliases
+ * An array of this charset's aliases, or null if it has no aliases
+ *
+ * @throws IllegalCharsetNameException
+ * If the canonical name or any of the aliases are illegal
+ */
+ @libcore.api.IntraCoreApi
+ protected Charset(String canonicalName, String[] aliases) {
+ checkName(canonicalName);
+ String[] as = (aliases == null) ? new String[0] : aliases;
+ for (int i = 0; i < as.length; i++)
+ checkName(as[i]);
+ this.name = canonicalName;
+ this.aliases = as;
+ }
+
+ /**
+ * Returns this charset's canonical name.
+ *
+ * @return The canonical name of this charset
+ */
+ public final String name() {
+ return name;
+ }
+
+ /**
+ * Returns a set containing this charset's aliases.
+ *
+ * @return An immutable set of this charset's aliases
+ */
+ public final Set<String> aliases() {
+ if (aliasSet != null)
+ return aliasSet;
+ int n = aliases.length;
+ HashSet<String> hs = new HashSet<String>(n);
+ for (int i = 0; i < n; i++)
+ hs.add(aliases[i]);
+ aliasSet = Collections.unmodifiableSet(hs);
+ return aliasSet;
+ }
+
+ /**
+ * Returns this charset's human-readable name for the default locale.
+ *
+ * <p> The default implementation of this method simply returns this
+ * charset's canonical name. Concrete subclasses of this class may
+ * override this method in order to provide a localized display name. </p>
+ *
+ * @return The display name of this charset in the default locale
+ */
+ public String displayName() {
+ return name;
+ }
+
+ /**
+ * Tells whether or not this charset is registered in the <a
+ * href="http://www.iana.org/assignments/character-sets">IANA Charset
+ * Registry</a>.
+ *
+ * @return <tt>true</tt> if, and only if, this charset is known by its
+ * implementor to be registered with the IANA
+ */
+ public final boolean isRegistered() {
+ return !name.startsWith("X-") && !name.startsWith("x-");
+ }
+
+ /**
+ * Returns this charset's human-readable name for the given locale.
+ *
+ * <p> The default implementation of this method simply returns this
+ * charset's canonical name. Concrete subclasses of this class may
+ * override this method in order to provide a localized display name. </p>
+ *
+ * @param locale
+ * The locale for which the display name is to be retrieved
+ *
+ * @return The display name of this charset in the given locale
+ */
+ public String displayName(Locale locale) {
+ return name;
+ }
+
+ /**
+ * Tells whether or not this charset contains the given charset.
+ *
+ * <p> A charset <i>C</i> is said to <i>contain</i> a charset <i>D</i> if,
+ * and only if, every character representable in <i>D</i> is also
+ * representable in <i>C</i>. If this relationship holds then it is
+ * guaranteed that every string that can be encoded in <i>D</i> can also be
+ * encoded in <i>C</i> without performing any replacements.
+ *
+ * <p> That <i>C</i> contains <i>D</i> does not imply that each character
+ * representable in <i>C</i> by a particular byte sequence is represented
+ * in <i>D</i> by the same byte sequence, although sometimes this is the
+ * case.
+ *
+ * <p> Every charset contains itself.
+ *
+ * <p> This method computes an approximation of the containment relation:
+ * If it returns <tt>true</tt> then the given charset is known to be
+ * contained by this charset; if it returns <tt>false</tt>, however, then
+ * it is not necessarily the case that the given charset is not contained
+ * in this charset.
+ *
+ * @param cs
+ * The given charset
+ *
+ * @return <tt>true</tt> if the given charset is contained in this charset
+ */
+ public abstract boolean contains(Charset cs);
+
+ /**
+ * Constructs a new decoder for this charset.
+ *
+ * @return A new decoder for this charset
+ */
+ public abstract CharsetDecoder newDecoder();
+
+ /**
+ * Constructs a new encoder for this charset.
+ *
+ * @return A new encoder for this charset
+ *
+ * @throws UnsupportedOperationException
+ * If this charset does not support encoding
+ */
+ public abstract CharsetEncoder newEncoder();
+
+ /**
+ * Tells whether or not this charset supports encoding.
+ *
+ * <p> Nearly all charsets support encoding. The primary exceptions are
+ * special-purpose <i>auto-detect</i> charsets whose decoders can determine
+ * which of several possible encoding schemes is in use by examining the
+ * input byte sequence. Such charsets do not support encoding because
+ * there is no way to determine which encoding should be used on output.
+ * Implementations of such charsets should override this method to return
+ * <tt>false</tt>. </p>
+ *
+ * @return <tt>true</tt> if, and only if, this charset supports encoding
+ */
+ public boolean canEncode() {
+ return true;
+ }
+
+ /**
+ * Convenience method that decodes bytes in this charset into Unicode
+ * characters.
+ *
+ * <p> An invocation of this method upon a charset <tt>cs</tt> returns the
+ * same result as the expression
+ *
+ * <pre>
+ * cs.newDecoder()
+ * .onMalformedInput(CodingErrorAction.REPLACE)
+ * .onUnmappableCharacter(CodingErrorAction.REPLACE)
+ * .decode(bb); </pre>
+ *
+ * except that it is potentially more efficient because it can cache
+ * decoders between successive invocations.
+ *
+ * <p> This method always replaces malformed-input and unmappable-character
+ * sequences with this charset's default replacement byte array. In order
+ * to detect such sequences, use the {@link
+ * CharsetDecoder#decode(java.nio.ByteBuffer)} method directly. </p>
+ *
+ * @param bb The byte buffer to be decoded
+ *
+ * @return A char buffer containing the decoded characters
+ */
+ public final CharBuffer decode(ByteBuffer bb) {
+ try {
+ return ThreadLocalCoders.decoderFor(this)
+ .onMalformedInput(CodingErrorAction.REPLACE)
+ .onUnmappableCharacter(CodingErrorAction.REPLACE)
+ .decode(bb);
+ } catch (CharacterCodingException x) {
+ throw new Error(x); // Can't happen
+ }
+ }
+
+ /**
+ * Convenience method that encodes Unicode characters into bytes in this
+ * charset.
+ *
+ * <p> An invocation of this method upon a charset <tt>cs</tt> returns the
+ * same result as the expression
+ *
+ * <pre>
+ * cs.newEncoder()
+ * .onMalformedInput(CodingErrorAction.REPLACE)
+ * .onUnmappableCharacter(CodingErrorAction.REPLACE)
+ * .encode(bb); </pre>
+ *
+ * except that it is potentially more efficient because it can cache
+ * encoders between successive invocations.
+ *
+ * <p> This method always replaces malformed-input and unmappable-character
+ * sequences with this charset's default replacement string. In order to
+ * detect such sequences, use the {@link
+ * CharsetEncoder#encode(java.nio.CharBuffer)} method directly. </p>
+ *
+ * @param cb The char buffer to be encoded
+ *
+ * @return A byte buffer containing the encoded characters
+ */
+ public final ByteBuffer encode(CharBuffer cb) {
+ try {
+ return ThreadLocalCoders.encoderFor(this)
+ .onMalformedInput(CodingErrorAction.REPLACE)
+ .onUnmappableCharacter(CodingErrorAction.REPLACE)
+ .encode(cb);
+ } catch (CharacterCodingException x) {
+ throw new Error(x); // Can't happen
+ }
+ }
+
+ /**
+ * Convenience method that encodes a string into bytes in this charset.
+ *
+ * <p> An invocation of this method upon a charset <tt>cs</tt> returns the
+ * same result as the expression
+ *
+ * <pre>
+ * cs.encode(CharBuffer.wrap(s)); </pre>
+ *
+ * @param str The string to be encoded
+ *
+ * @return A byte buffer containing the encoded characters
+ */
+ public final ByteBuffer encode(String str) {
+ return encode(CharBuffer.wrap(str));
+ }
+
+ /**
+ * Compares this charset to another.
+ *
+ * <p> Charsets are ordered by their canonical names, without regard to
+ * case. </p>
+ *
+ * @param that
+ * The charset to which this charset is to be compared
+ *
+ * @return A negative integer, zero, or a positive integer as this charset
+ * is less than, equal to, or greater than the specified charset
+ */
+ public final int compareTo(Charset that) {
+ return (name().compareToIgnoreCase(that.name()));
+ }
+
+ /**
+ * Computes a hashcode for this charset.
+ *
+ * @return An integer hashcode
+ */
+ public final int hashCode() {
+ return name().hashCode();
+ }
+
+ /**
+ * Tells whether or not this object is equal to another.
+ *
+ * <p> Two charsets are equal if, and only if, they have the same canonical
+ * names. A charset is never equal to any other type of object. </p>
+ *
+ * @return <tt>true</tt> if, and only if, this charset is equal to the
+ * given object
+ */
+ public final boolean equals(Object ob) {
+ if (!(ob instanceof Charset))
+ return false;
+ if (this == ob)
+ return true;
+ return name.equals(((Charset)ob).name());
+ }
+
+ /**
+ * Returns a string describing this charset.
+ *
+ * @return A string describing this charset
+ */
+ public final String toString() {
+ return name();
+ }
+
+}
diff --git a/java/nio/charset/CharsetDecoder.annotated.java b/java/nio/charset/CharsetDecoder.annotated.java
new file mode 100644
index 0000000..ed0f378
--- /dev/null
+++ b/java/nio/charset/CharsetDecoder.annotated.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+
+package java.nio.charset;
+
+import java.nio.CharBuffer;
+import java.nio.ByteBuffer;
+import java.nio.Buffer;
+import java.nio.charset.CoderMalfunctionError;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class CharsetDecoder {
+
[email protected]
+protected CharsetDecoder(java.nio.charset.Charset cs, float averageCharsPerByte, float maxCharsPerByte) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.charset.Charset charset() { throw new RuntimeException("Stub!"); }
+
+public final java.lang.String replacement() { throw new RuntimeException("Stub!"); }
+
+public final java.nio.charset.CharsetDecoder replaceWith(java.lang.String newReplacement) { throw new RuntimeException("Stub!"); }
+
+protected void implReplaceWith(java.lang.String newReplacement) { throw new RuntimeException("Stub!"); }
+
+public java.nio.charset.CodingErrorAction malformedInputAction() { throw new RuntimeException("Stub!"); }
+
+public final java.nio.charset.CharsetDecoder onMalformedInput(java.nio.charset.CodingErrorAction newAction) { throw new RuntimeException("Stub!"); }
+
+protected void implOnMalformedInput(java.nio.charset.CodingErrorAction newAction) { throw new RuntimeException("Stub!"); }
+
+public java.nio.charset.CodingErrorAction unmappableCharacterAction() { throw new RuntimeException("Stub!"); }
+
+public final java.nio.charset.CharsetDecoder onUnmappableCharacter(java.nio.charset.CodingErrorAction newAction) { throw new RuntimeException("Stub!"); }
+
+protected void implOnUnmappableCharacter(java.nio.charset.CodingErrorAction newAction) { throw new RuntimeException("Stub!"); }
+
+public final float averageCharsPerByte() { throw new RuntimeException("Stub!"); }
+
+public final float maxCharsPerByte() { throw new RuntimeException("Stub!"); }
+
+public final java.nio.charset.CoderResult decode(java.nio.ByteBuffer in, java.nio.CharBuffer out, boolean endOfInput) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.charset.CoderResult flush(java.nio.CharBuffer out) { throw new RuntimeException("Stub!"); }
+
+protected java.nio.charset.CoderResult implFlush(java.nio.CharBuffer out) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.charset.CharsetDecoder reset() { throw new RuntimeException("Stub!"); }
+
+protected void implReset() { throw new RuntimeException("Stub!"); }
+
+protected abstract java.nio.charset.CoderResult decodeLoop(java.nio.ByteBuffer in, java.nio.CharBuffer out);
+
+public final java.nio.CharBuffer decode(java.nio.ByteBuffer in) throws java.nio.charset.CharacterCodingException { throw new RuntimeException("Stub!"); }
+
+public boolean isAutoDetecting() { throw new RuntimeException("Stub!"); }
+
+public boolean isCharsetDetected() { throw new RuntimeException("Stub!"); }
+
+public java.nio.charset.Charset detectedCharset() { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/java/nio/charset/CharsetDecoder.java b/java/nio/charset/CharsetDecoder.java
new file mode 100644
index 0000000..34065ee
--- /dev/null
+++ b/java/nio/charset/CharsetDecoder.java
@@ -0,0 +1,998 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.charset;
+
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.BufferOverflowException;
+import java.nio.BufferUnderflowException;
+import java.lang.ref.WeakReference;
+import java.nio.charset.CoderMalfunctionError; // javadoc
+import java.util.Arrays;
+
+
+/**
+ * An engine that can transform a sequence of bytes in a specific charset into a sequence of
+ * sixteen-bit Unicode characters.
+ *
+ * <a name="steps"></a>
+ *
+ * <p> The input byte sequence is provided in a byte buffer or a series
+ * of such buffers. The output character sequence is written to a character buffer
+ * or a series of such buffers. A decoder should always be used by making
+ * the following sequence of method invocations, hereinafter referred to as a
+ * <i>decoding operation</i>:
+ *
+ * <ol>
+ *
+ * <li><p> Reset the decoder via the {@link #reset reset} method, unless it
+ * has not been used before; </p></li>
+ *
+ * <li><p> Invoke the {@link #decode decode} method zero or more times, as
+ * long as additional input may be available, passing <tt>false</tt> for the
+ * <tt>endOfInput</tt> argument and filling the input buffer and flushing the
+ * output buffer between invocations; </p></li>
+ *
+ * <li><p> Invoke the {@link #decode decode} method one final time, passing
+ * <tt>true</tt> for the <tt>endOfInput</tt> argument; and then </p></li>
+ *
+ * <li><p> Invoke the {@link #flush flush} method so that the decoder can
+ * flush any internal state to the output buffer. </p></li>
+ *
+ * </ol>
+ *
+ * Each invocation of the {@link #decode decode} method will decode as many
+ * bytes as possible from the input buffer, writing the resulting characters
+ * to the output buffer. The {@link #decode decode} method returns when more
+ * input is required, when there is not enough room in the output buffer, or
+ * when a decoding error has occurred. In each case a {@link CoderResult}
+ * object is returned to describe the reason for termination. An invoker can
+ * examine this object and fill the input buffer, flush the output buffer, or
+ * attempt to recover from a decoding error, as appropriate, and try again.
+ *
+ * <a name="ce"></a>
+ *
+ * <p> There are two general types of decoding errors. If the input byte
+ * sequence is not legal for this charset then the input is considered <i>malformed</i>. If
+ * the input byte sequence is legal but cannot be mapped to a valid
+ * Unicode character then an <i>unmappable character</i> has been encountered.
+ *
+ * <a name="cae"></a>
+ *
+ * <p> How a decoding error is handled depends upon the action requested for
+ * that type of error, which is described by an instance of the {@link
+ * CodingErrorAction} class. The possible error actions are to {@linkplain
+ * CodingErrorAction#IGNORE ignore} the erroneous input, {@linkplain
+ * CodingErrorAction#REPORT report} the error to the invoker via
+ * the returned {@link CoderResult} object, or {@linkplain CodingErrorAction#REPLACE
+ * replace} the erroneous input with the current value of the
+ * replacement string. The replacement
+ *
+
+
+
+
+
+ * has the initial value <tt>"\uFFFD"</tt>;
+
+ *
+ * its value may be changed via the {@link #replaceWith(java.lang.String)
+ * replaceWith} method.
+ *
+ * <p> The default action for malformed-input and unmappable-character errors
+ * is to {@linkplain CodingErrorAction#REPORT report} them. The
+ * malformed-input error action may be changed via the {@link
+ * #onMalformedInput(CodingErrorAction) onMalformedInput} method; the
+ * unmappable-character action may be changed via the {@link
+ * #onUnmappableCharacter(CodingErrorAction) onUnmappableCharacter} method.
+ *
+ * <p> This class is designed to handle many of the details of the decoding
+ * process, including the implementation of error actions. A decoder for a
+ * specific charset, which is a concrete subclass of this class, need only
+ * implement the abstract {@link #decodeLoop decodeLoop} method, which
+ * encapsulates the basic decoding loop. A subclass that maintains internal
+ * state should, additionally, override the {@link #implFlush implFlush} and
+ * {@link #implReset implReset} methods.
+ *
+ * <p> Instances of this class are not safe for use by multiple concurrent
+ * threads. </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ *
+ * @see ByteBuffer
+ * @see CharBuffer
+ * @see Charset
+ * @see CharsetEncoder
+ */
+
+public abstract class CharsetDecoder {
+
+ private final Charset charset;
+ private final float averageCharsPerByte;
+ private final float maxCharsPerByte;
+
+ private String replacement;
+ private CodingErrorAction malformedInputAction
+ = CodingErrorAction.REPORT;
+ private CodingErrorAction unmappableCharacterAction
+ = CodingErrorAction.REPORT;
+
+ // Internal states
+ //
+ private static final int ST_RESET = 0;
+ private static final int ST_CODING = 1;
+ private static final int ST_END = 2;
+ private static final int ST_FLUSHED = 3;
+
+ private int state = ST_RESET;
+
+ private static String stateNames[]
+ = { "RESET", "CODING", "CODING_END", "FLUSHED" };
+
+
+ /**
+ * Initializes a new decoder. The new decoder will have the given
+ * chars-per-byte and replacement values.
+ *
+ * @param cs
+ * The charset that created this decoder
+ *
+ * @param averageCharsPerByte
+ * A positive float value indicating the expected number of
+ * characters that will be produced for each input byte
+ *
+ * @param maxCharsPerByte
+ * A positive float value indicating the maximum number of
+ * characters that will be produced for each input byte
+ *
+ * @param replacement
+ * The initial replacement; must not be <tt>null</tt>, must have
+ * non-zero length, must not be longer than maxCharsPerByte,
+ * and must be {@linkplain #isLegalReplacement legal}
+ *
+ * @throws IllegalArgumentException
+ * If the preconditions on the parameters do not hold
+ */
+ private
+ CharsetDecoder(Charset cs,
+ float averageCharsPerByte,
+ float maxCharsPerByte,
+ String replacement)
+ {
+ this.charset = cs;
+ if (averageCharsPerByte <= 0.0f)
+ throw new IllegalArgumentException("Non-positive "
+ + "averageCharsPerByte");
+ if (maxCharsPerByte <= 0.0f)
+ throw new IllegalArgumentException("Non-positive "
+ + "maxCharsPerByte");
+ if (!Charset.atBugLevel("1.4")) {
+ if (averageCharsPerByte > maxCharsPerByte)
+ throw new IllegalArgumentException("averageCharsPerByte"
+ + " exceeds "
+ + "maxCharsPerByte");
+ }
+ this.replacement = replacement;
+ this.averageCharsPerByte = averageCharsPerByte;
+ this.maxCharsPerByte = maxCharsPerByte;
+ // Android-removed
+ // replaceWith(replacement);
+ }
+
+ /**
+ * Initializes a new decoder. The new decoder will have the given
+ * chars-per-byte values and its replacement will be the
+ * string <tt>"\uFFFD"</tt>.
+ *
+ * @param cs
+ * The charset that created this decoder
+ *
+ * @param averageCharsPerByte
+ * A positive float value indicating the expected number of
+ * characters that will be produced for each input byte
+ *
+ * @param maxCharsPerByte
+ * A positive float value indicating the maximum number of
+ * characters that will be produced for each input byte
+ *
+ * @throws IllegalArgumentException
+ * If the preconditions on the parameters do not hold
+ */
+ protected CharsetDecoder(Charset cs,
+ float averageCharsPerByte,
+ float maxCharsPerByte)
+ {
+ this(cs,
+ averageCharsPerByte, maxCharsPerByte,
+ "\uFFFD");
+ }
+
+ /**
+ * Returns the charset that created this decoder.
+ *
+ * @return This decoder's charset
+ */
+ public final Charset charset() {
+ return charset;
+ }
+
+ /**
+ * Returns this decoder's replacement value.
+ *
+ * @return This decoder's current replacement,
+ * which is never <tt>null</tt> and is never empty
+ */
+ public final String replacement() {
+
+ return replacement;
+
+
+
+
+ }
+
+ /**
+ * Changes this decoder's replacement value.
+ *
+ * <p> This method invokes the {@link #implReplaceWith implReplaceWith}
+ * method, passing the new replacement, after checking that the new
+ * replacement is acceptable. </p>
+ *
+ * @param newReplacement The replacement value
+ *
+
+ * The new replacement; must not be <tt>null</tt>
+ * and must have non-zero length
+
+
+
+
+
+
+
+ *
+ * @return This decoder
+ *
+ * @throws IllegalArgumentException
+ * If the preconditions on the parameter do not hold
+ */
+ public final CharsetDecoder replaceWith(String newReplacement) {
+ if (newReplacement == null)
+ throw new IllegalArgumentException("Null replacement");
+ int len = newReplacement.length();
+ if (len == 0)
+ throw new IllegalArgumentException("Empty replacement");
+ if (len > maxCharsPerByte)
+ throw new IllegalArgumentException("Replacement too long");
+
+ this.replacement = newReplacement;
+
+
+
+
+
+
+ implReplaceWith(this.replacement);
+ return this;
+ }
+
+ /**
+ * Reports a change to this decoder's replacement value.
+ *
+ * <p> The default implementation of this method does nothing. This method
+ * should be overridden by decoders that require notification of changes to
+ * the replacement. </p>
+ *
+ * @param newReplacement The replacement value
+ */
+ protected void implReplaceWith(String newReplacement) {
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ /**
+ * Returns this decoder's current action for malformed-input errors.
+ *
+ * @return The current malformed-input action, which is never <tt>null</tt>
+ */
+ public CodingErrorAction malformedInputAction() {
+ return malformedInputAction;
+ }
+
+ /**
+ * Changes this decoder's action for malformed-input errors.
+ *
+ * <p> This method invokes the {@link #implOnMalformedInput
+ * implOnMalformedInput} method, passing the new action. </p>
+ *
+ * @param newAction The new action; must not be <tt>null</tt>
+ *
+ * @return This decoder
+ *
+ * @throws IllegalArgumentException
+ * If the precondition on the parameter does not hold
+ */
+ public final CharsetDecoder onMalformedInput(CodingErrorAction newAction) {
+ if (newAction == null)
+ throw new IllegalArgumentException("Null action");
+ malformedInputAction = newAction;
+ implOnMalformedInput(newAction);
+ return this;
+ }
+
+ /**
+ * Reports a change to this decoder's malformed-input action.
+ *
+ * <p> The default implementation of this method does nothing. This method
+ * should be overridden by decoders that require notification of changes to
+ * the malformed-input action. </p>
+ *
+ * @param newAction The new action
+ */
+ protected void implOnMalformedInput(CodingErrorAction newAction) { }
+
+ /**
+ * Returns this decoder's current action for unmappable-character errors.
+ *
+ * @return The current unmappable-character action, which is never
+ * <tt>null</tt>
+ */
+ public CodingErrorAction unmappableCharacterAction() {
+ return unmappableCharacterAction;
+ }
+
+ /**
+ * Changes this decoder's action for unmappable-character errors.
+ *
+ * <p> This method invokes the {@link #implOnUnmappableCharacter
+ * implOnUnmappableCharacter} method, passing the new action. </p>
+ *
+ * @param newAction The new action; must not be <tt>null</tt>
+ *
+ * @return This decoder
+ *
+ * @throws IllegalArgumentException
+ * If the precondition on the parameter does not hold
+ */
+ public final CharsetDecoder onUnmappableCharacter(CodingErrorAction
+ newAction)
+ {
+ if (newAction == null)
+ throw new IllegalArgumentException("Null action");
+ unmappableCharacterAction = newAction;
+ implOnUnmappableCharacter(newAction);
+ return this;
+ }
+
+ /**
+ * Reports a change to this decoder's unmappable-character action.
+ *
+ * <p> The default implementation of this method does nothing. This method
+ * should be overridden by decoders that require notification of changes to
+ * the unmappable-character action. </p>
+ *
+ * @param newAction The new action
+ */
+ protected void implOnUnmappableCharacter(CodingErrorAction newAction) { }
+
+ /**
+ * Returns the average number of characters that will be produced for each
+ * byte of input. This heuristic value may be used to estimate the size
+ * of the output buffer required for a given input sequence.
+ *
+ * @return The average number of characters produced
+ * per byte of input
+ */
+ public final float averageCharsPerByte() {
+ return averageCharsPerByte;
+ }
+
+ /**
+ * Returns the maximum number of characters that will be produced for each
+ * byte of input. This value may be used to compute the worst-case size
+ * of the output buffer required for a given input sequence.
+ *
+ * @return The maximum number of characters that will be produced per
+ * byte of input
+ */
+ public final float maxCharsPerByte() {
+ return maxCharsPerByte;
+ }
+
+ /**
+ * Decodes as many bytes as possible from the given input buffer,
+ * writing the results to the given output buffer.
+ *
+ * <p> The buffers are read from, and written to, starting at their current
+ * positions. At most {@link Buffer#remaining in.remaining()} bytes
+ * will be read and at most {@link Buffer#remaining out.remaining()}
+ * characters will be written. The buffers' positions will be advanced to
+ * reflect the bytes read and the characters written, but their marks and
+ * limits will not be modified.
+ *
+ * <p> In addition to reading bytes from the input buffer and writing
+ * characters to the output buffer, this method returns a {@link CoderResult}
+ * object to describe its reason for termination:
+ *
+ * <ul>
+ *
+ * <li><p> {@link CoderResult#UNDERFLOW} indicates that as much of the
+ * input buffer as possible has been decoded. If there is no further
+ * input then the invoker can proceed to the next step of the
+ * <a href="#steps">decoding operation</a>. Otherwise this method
+ * should be invoked again with further input. </p></li>
+ *
+ * <li><p> {@link CoderResult#OVERFLOW} indicates that there is
+ * insufficient space in the output buffer to decode any more bytes.
+ * This method should be invoked again with an output buffer that has
+ * more {@linkplain Buffer#remaining remaining} characters. This is
+ * typically done by draining any decoded characters from the output
+ * buffer. </p></li>
+ *
+ * <li><p> A {@linkplain CoderResult#malformedForLength
+ * malformed-input} result indicates that a malformed-input
+ * error has been detected. The malformed bytes begin at the input
+ * buffer's (possibly incremented) position; the number of malformed
+ * bytes may be determined by invoking the result object's {@link
+ * CoderResult#length() length} method. This case applies only if the
+ * {@linkplain #onMalformedInput malformed action} of this decoder
+ * is {@link CodingErrorAction#REPORT}; otherwise the malformed input
+ * will be ignored or replaced, as requested. </p></li>
+ *
+ * <li><p> An {@linkplain CoderResult#unmappableForLength
+ * unmappable-character} result indicates that an
+ * unmappable-character error has been detected. The bytes that
+ * decode the unmappable character begin at the input buffer's (possibly
+ * incremented) position; the number of such bytes may be determined
+ * by invoking the result object's {@link CoderResult#length() length}
+ * method. This case applies only if the {@linkplain #onUnmappableCharacter
+ * unmappable action} of this decoder is {@link
+ * CodingErrorAction#REPORT}; otherwise the unmappable character will be
+ * ignored or replaced, as requested. </p></li>
+ *
+ * </ul>
+ *
+ * In any case, if this method is to be reinvoked in the same decoding
+ * operation then care should be taken to preserve any bytes remaining
+ * in the input buffer so that they are available to the next invocation.
+ *
+ * <p> The <tt>endOfInput</tt> parameter advises this method as to whether
+ * the invoker can provide further input beyond that contained in the given
+ * input buffer. If there is a possibility of providing additional input
+ * then the invoker should pass <tt>false</tt> for this parameter; if there
+ * is no possibility of providing further input then the invoker should
+ * pass <tt>true</tt>. It is not erroneous, and in fact it is quite
+ * common, to pass <tt>false</tt> in one invocation and later discover that
+ * no further input was actually available. It is critical, however, that
+ * the final invocation of this method in a sequence of invocations always
+ * pass <tt>true</tt> so that any remaining undecoded input will be treated
+ * as being malformed.
+ *
+ * <p> This method works by invoking the {@link #decodeLoop decodeLoop}
+ * method, interpreting its results, handling error conditions, and
+ * reinvoking it as necessary. </p>
+ *
+ *
+ * @param in
+ * The input byte buffer
+ *
+ * @param out
+ * The output character buffer
+ *
+ * @param endOfInput
+ * <tt>true</tt> if, and only if, the invoker can provide no
+ * additional input bytes beyond those in the given buffer
+ *
+ * @return A coder-result object describing the reason for termination
+ *
+ * @throws IllegalStateException
+ * If a decoding operation is already in progress and the previous
+ * step was an invocation neither of the {@link #reset reset}
+ * method, nor of this method with a value of <tt>false</tt> for
+ * the <tt>endOfInput</tt> parameter, nor of this method with a
+ * value of <tt>true</tt> for the <tt>endOfInput</tt> parameter
+ * but a return value indicating an incomplete decoding operation
+ *
+ * @throws CoderMalfunctionError
+ * If an invocation of the decodeLoop method threw
+ * an unexpected exception
+ */
+ public final CoderResult decode(ByteBuffer in, CharBuffer out,
+ boolean endOfInput)
+ {
+ int newState = endOfInput ? ST_END : ST_CODING;
+ if ((state != ST_RESET) && (state != ST_CODING)
+ && !(endOfInput && (state == ST_END)))
+ throwIllegalStateException(state, newState);
+ state = newState;
+
+ for (;;) {
+
+ CoderResult cr;
+ try {
+ cr = decodeLoop(in, out);
+ } catch (BufferUnderflowException x) {
+ throw new CoderMalfunctionError(x);
+ } catch (BufferOverflowException x) {
+ throw new CoderMalfunctionError(x);
+ }
+
+ if (cr.isOverflow())
+ return cr;
+
+ if (cr.isUnderflow()) {
+ if (endOfInput && in.hasRemaining()) {
+ cr = CoderResult.malformedForLength(in.remaining());
+ // Fall through to malformed-input case
+ } else {
+ return cr;
+ }
+ }
+
+ CodingErrorAction action = null;
+ if (cr.isMalformed())
+ action = malformedInputAction;
+ else if (cr.isUnmappable())
+ action = unmappableCharacterAction;
+ else
+ assert false : cr.toString();
+
+ if (action == CodingErrorAction.REPORT)
+ return cr;
+
+ if (action == CodingErrorAction.REPLACE) {
+ if (out.remaining() < replacement.length())
+ return CoderResult.OVERFLOW;
+ out.put(replacement);
+ }
+
+ if ((action == CodingErrorAction.IGNORE)
+ || (action == CodingErrorAction.REPLACE)) {
+ // Skip erroneous input either way
+ in.position(in.position() + cr.length());
+ continue;
+ }
+
+ assert false;
+ }
+
+ }
+
+ /**
+ * Flushes this decoder.
+ *
+ * <p> Some decoders maintain internal state and may need to write some
+ * final characters to the output buffer once the overall input sequence has
+ * been read.
+ *
+ * <p> Any additional output is written to the output buffer beginning at
+ * its current position. At most {@link Buffer#remaining out.remaining()}
+ * characters will be written. The buffer's position will be advanced
+ * appropriately, but its mark and limit will not be modified.
+ *
+ * <p> If this method completes successfully then it returns {@link
+ * CoderResult#UNDERFLOW}. If there is insufficient room in the output
+ * buffer then it returns {@link CoderResult#OVERFLOW}. If this happens
+ * then this method must be invoked again, with an output buffer that has
+ * more room, in order to complete the current <a href="#steps">decoding
+ * operation</a>.
+ *
+ * <p> If this decoder has already been flushed then invoking this method
+ * has no effect.
+ *
+ * <p> This method invokes the {@link #implFlush implFlush} method to
+ * perform the actual flushing operation. </p>
+ *
+ * @param out
+ * The output character buffer
+ *
+ * @return A coder-result object, either {@link CoderResult#UNDERFLOW} or
+ * {@link CoderResult#OVERFLOW}
+ *
+ * @throws IllegalStateException
+ * If the previous step of the current decoding operation was an
+ * invocation neither of the {@link #flush flush} method nor of
+ * the three-argument {@link
+ * #decode(ByteBuffer,CharBuffer,boolean) decode} method
+ * with a value of <tt>true</tt> for the <tt>endOfInput</tt>
+ * parameter
+ */
+ public final CoderResult flush(CharBuffer out) {
+ if (state == ST_END) {
+ CoderResult cr = implFlush(out);
+ if (cr.isUnderflow())
+ state = ST_FLUSHED;
+ return cr;
+ }
+
+ if (state != ST_FLUSHED)
+ throwIllegalStateException(state, ST_FLUSHED);
+
+ return CoderResult.UNDERFLOW; // Already flushed
+ }
+
+ /**
+ * Flushes this decoder.
+ *
+ * <p> The default implementation of this method does nothing, and always
+ * returns {@link CoderResult#UNDERFLOW}. This method should be overridden
+ * by decoders that may need to write final characters to the output buffer
+ * once the entire input sequence has been read. </p>
+ *
+ * @param out
+ * The output character buffer
+ *
+ * @return A coder-result object, either {@link CoderResult#UNDERFLOW} or
+ * {@link CoderResult#OVERFLOW}
+ */
+ protected CoderResult implFlush(CharBuffer out) {
+ return CoderResult.UNDERFLOW;
+ }
+
+ /**
+ * Resets this decoder, clearing any internal state.
+ *
+ * <p> This method resets charset-independent state and also invokes the
+ * {@link #implReset() implReset} method in order to perform any
+ * charset-specific reset actions. </p>
+ *
+ * @return This decoder
+ *
+ */
+ public final CharsetDecoder reset() {
+ implReset();
+ state = ST_RESET;
+ return this;
+ }
+
+ /**
+ * Resets this decoder, clearing any charset-specific internal state.
+ *
+ * <p> The default implementation of this method does nothing. This method
+ * should be overridden by decoders that maintain internal state. </p>
+ */
+ protected void implReset() { }
+
+ /**
+ * Decodes one or more bytes into one or more characters.
+ *
+ * <p> This method encapsulates the basic decoding loop, decoding as many
+ * bytes as possible until it either runs out of input, runs out of room
+ * in the output buffer, or encounters a decoding error. This method is
+ * invoked by the {@link #decode decode} method, which handles result
+ * interpretation and error recovery.
+ *
+ * <p> The buffers are read from, and written to, starting at their current
+ * positions. At most {@link Buffer#remaining in.remaining()} bytes
+ * will be read, and at most {@link Buffer#remaining out.remaining()}
+ * characters will be written. The buffers' positions will be advanced to
+ * reflect the bytes read and the characters written, but their marks and
+ * limits will not be modified.
+ *
+ * <p> This method returns a {@link CoderResult} object to describe its
+ * reason for termination, in the same manner as the {@link #decode decode}
+ * method. Most implementations of this method will handle decoding errors
+ * by returning an appropriate result object for interpretation by the
+ * {@link #decode decode} method. An optimized implementation may instead
+ * examine the relevant error action and implement that action itself.
+ *
+ * <p> An implementation of this method may perform arbitrary lookahead by
+ * returning {@link CoderResult#UNDERFLOW} until it receives sufficient
+ * input. </p>
+ *
+ * @param in
+ * The input byte buffer
+ *
+ * @param out
+ * The output character buffer
+ *
+ * @return A coder-result object describing the reason for termination
+ */
+ protected abstract CoderResult decodeLoop(ByteBuffer in,
+ CharBuffer out);
+
+ /**
+ * Convenience method that decodes the remaining content of a single input
+ * byte buffer into a newly-allocated character buffer.
+ *
+ * <p> This method implements an entire <a href="#steps">decoding
+ * operation</a>; that is, it resets this decoder, then it decodes the
+ * bytes in the given byte buffer, and finally it flushes this
+ * decoder. This method should therefore not be invoked if a decoding
+ * operation is already in progress. </p>
+ *
+ * @param in
+ * The input byte buffer
+ *
+ * @return A newly-allocated character buffer containing the result of the
+ * decoding operation. The buffer's position will be zero and its
+ * limit will follow the last character written.
+ *
+ * @throws IllegalStateException
+ * If a decoding operation is already in progress
+ *
+ * @throws MalformedInputException
+ * If the byte sequence starting at the input buffer's current
+ * position is not legal for this charset and the current malformed-input action
+ * is {@link CodingErrorAction#REPORT}
+ *
+ * @throws UnmappableCharacterException
+ * If the byte sequence starting at the input buffer's current
+ * position cannot be mapped to an equivalent character sequence and
+ * the current unmappable-character action is {@link
+ * CodingErrorAction#REPORT}
+ */
+ public final CharBuffer decode(ByteBuffer in)
+ throws CharacterCodingException
+ {
+ int n = (int)(in.remaining() * averageCharsPerByte());
+ CharBuffer out = CharBuffer.allocate(n);
+
+ if ((n == 0) && (in.remaining() == 0))
+ return out;
+ reset();
+ for (;;) {
+ CoderResult cr = in.hasRemaining() ?
+ decode(in, out, true) : CoderResult.UNDERFLOW;
+ if (cr.isUnderflow())
+ cr = flush(out);
+
+ if (cr.isUnderflow())
+ break;
+ if (cr.isOverflow()) {
+ n = 2*n + 1; // Ensure progress; n might be 0!
+ CharBuffer o = CharBuffer.allocate(n);
+ out.flip();
+ o.put(out);
+ out = o;
+ continue;
+ }
+ cr.throwException();
+ }
+ out.flip();
+ return out;
+ }
+
+
+
+ /**
+ * Tells whether or not this decoder implements an auto-detecting charset.
+ *
+ * <p> The default implementation of this method always returns
+ * <tt>false</tt>; it should be overridden by auto-detecting decoders to
+ * return <tt>true</tt>. </p>
+ *
+ * @return <tt>true</tt> if, and only if, this decoder implements an
+ * auto-detecting charset
+ */
+ public boolean isAutoDetecting() {
+ return false;
+ }
+
+ /**
+ * Tells whether or not this decoder has yet detected a
+ * charset <i>(optional operation)</i>.
+ *
+ * <p> If this decoder implements an auto-detecting charset then at a
+ * single point during a decoding operation this method may start returning
+ * <tt>true</tt> to indicate that a specific charset has been detected in
+ * the input byte sequence. Once this occurs, the {@link #detectedCharset
+ * detectedCharset} method may be invoked to retrieve the detected charset.
+ *
+ * <p> That this method returns <tt>false</tt> does not imply that no bytes
+ * have yet been decoded. Some auto-detecting decoders are capable of
+ * decoding some, or even all, of an input byte sequence without fixing on
+ * a particular charset.
+ *
+ * <p> The default implementation of this method always throws an {@link
+ * UnsupportedOperationException}; it should be overridden by
+ * auto-detecting decoders to return <tt>true</tt> once the input charset
+ * has been determined. </p>
+ *
+ * @return <tt>true</tt> if, and only if, this decoder has detected a
+ * specific charset
+ *
+ * @throws UnsupportedOperationException
+ * If this decoder does not implement an auto-detecting charset
+ */
+ public boolean isCharsetDetected() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Retrieves the charset that was detected by this
+ * decoder <i>(optional operation)</i>.
+ *
+ * <p> If this decoder implements an auto-detecting charset then this
+ * method returns the actual charset once it has been detected. After that
+ * point, this method returns the same value for the duration of the
+ * current decoding operation. If not enough input bytes have yet been
+ * read to determine the actual charset then this method throws an {@link
+ * IllegalStateException}.
+ *
+ * <p> The default implementation of this method always throws an {@link
+ * UnsupportedOperationException}; it should be overridden by
+ * auto-detecting decoders to return the appropriate value. </p>
+ *
+ * @return The charset detected by this auto-detecting decoder,
+ * or <tt>null</tt> if the charset has not yet been determined
+ *
+ * @throws IllegalStateException
+ * If insufficient bytes have been read to determine a charset
+ *
+ * @throws UnsupportedOperationException
+ * If this decoder does not implement an auto-detecting charset
+ */
+ public Charset detectedCharset() {
+ throw new UnsupportedOperationException();
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ private void throwIllegalStateException(int from, int to) {
+ throw new IllegalStateException("Current state = " + stateNames[from]
+ + ", new state = " + stateNames[to]);
+ }
+
+}
diff --git a/java/nio/charset/CharsetEncoder.annotated.java b/java/nio/charset/CharsetEncoder.annotated.java
new file mode 100644
index 0000000..ceb323e
--- /dev/null
+++ b/java/nio/charset/CharsetEncoder.annotated.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+
+package java.nio.charset;
+
+import java.nio.CharBuffer;
+import java.nio.ByteBuffer;
+import java.nio.Buffer;
+import java.nio.charset.CoderMalfunctionError;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class CharsetEncoder {
+
+protected CharsetEncoder(java.nio.charset.Charset cs, float averageBytesPerChar, float maxBytesPerChar, byte[] replacement) { throw new RuntimeException("Stub!"); }
+
[email protected]
+protected CharsetEncoder(java.nio.charset.Charset cs, float averageBytesPerChar, float maxBytesPerChar, byte[] replacement, boolean trusted) { throw new RuntimeException("Stub!"); }
+
+protected CharsetEncoder(java.nio.charset.Charset cs, float averageBytesPerChar, float maxBytesPerChar) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.charset.Charset charset() { throw new RuntimeException("Stub!"); }
+
+public final byte[] replacement() { throw new RuntimeException("Stub!"); }
+
+public final java.nio.charset.CharsetEncoder replaceWith(byte[] newReplacement) { throw new RuntimeException("Stub!"); }
+
+protected void implReplaceWith(byte[] newReplacement) { throw new RuntimeException("Stub!"); }
+
+public boolean isLegalReplacement(byte[] repl) { throw new RuntimeException("Stub!"); }
+
+public java.nio.charset.CodingErrorAction malformedInputAction() { throw new RuntimeException("Stub!"); }
+
+public final java.nio.charset.CharsetEncoder onMalformedInput(java.nio.charset.CodingErrorAction newAction) { throw new RuntimeException("Stub!"); }
+
+protected void implOnMalformedInput(java.nio.charset.CodingErrorAction newAction) { throw new RuntimeException("Stub!"); }
+
+public java.nio.charset.CodingErrorAction unmappableCharacterAction() { throw new RuntimeException("Stub!"); }
+
+public final java.nio.charset.CharsetEncoder onUnmappableCharacter(java.nio.charset.CodingErrorAction newAction) { throw new RuntimeException("Stub!"); }
+
+protected void implOnUnmappableCharacter(java.nio.charset.CodingErrorAction newAction) { throw new RuntimeException("Stub!"); }
+
+public final float averageBytesPerChar() { throw new RuntimeException("Stub!"); }
+
+public final float maxBytesPerChar() { throw new RuntimeException("Stub!"); }
+
+public final java.nio.charset.CoderResult encode(java.nio.CharBuffer in, java.nio.ByteBuffer out, boolean endOfInput) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.charset.CoderResult flush(java.nio.ByteBuffer out) { throw new RuntimeException("Stub!"); }
+
+protected java.nio.charset.CoderResult implFlush(java.nio.ByteBuffer out) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.charset.CharsetEncoder reset() { throw new RuntimeException("Stub!"); }
+
+protected void implReset() { throw new RuntimeException("Stub!"); }
+
+protected abstract java.nio.charset.CoderResult encodeLoop(java.nio.CharBuffer in, java.nio.ByteBuffer out);
+
+public final java.nio.ByteBuffer encode(java.nio.CharBuffer in) throws java.nio.charset.CharacterCodingException { throw new RuntimeException("Stub!"); }
+
+public boolean canEncode(char c) { throw new RuntimeException("Stub!"); }
+
+public boolean canEncode(java.lang.CharSequence cs) { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/java/nio/charset/CharsetEncoder.java b/java/nio/charset/CharsetEncoder.java
new file mode 100644
index 0000000..98b4dea
--- /dev/null
+++ b/java/nio/charset/CharsetEncoder.java
@@ -0,0 +1,1026 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.charset;
+
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.BufferOverflowException;
+import java.nio.BufferUnderflowException;
+import java.lang.ref.WeakReference;
+import java.nio.charset.CoderMalfunctionError; // javadoc
+import java.util.Arrays;
+
+
+/**
+ * An engine that can transform a sequence of sixteen-bit Unicode characters into a sequence of
+ * bytes in a specific charset.
+ *
+ * <a name="steps"></a>
+ *
+ * <p> The input character sequence is provided in a character buffer or a series
+ * of such buffers. The output byte sequence is written to a byte buffer
+ * or a series of such buffers. An encoder should always be used by making
+ * the following sequence of method invocations, hereinafter referred to as an
+ * <i>encoding operation</i>:
+ *
+ * <ol>
+ *
+ * <li><p> Reset the encoder via the {@link #reset reset} method, unless it
+ * has not been used before; </p></li>
+ *
+ * <li><p> Invoke the {@link #encode encode} method zero or more times, as
+ * long as additional input may be available, passing <tt>false</tt> for the
+ * <tt>endOfInput</tt> argument and filling the input buffer and flushing the
+ * output buffer between invocations; </p></li>
+ *
+ * <li><p> Invoke the {@link #encode encode} method one final time, passing
+ * <tt>true</tt> for the <tt>endOfInput</tt> argument; and then </p></li>
+ *
+ * <li><p> Invoke the {@link #flush flush} method so that the encoder can
+ * flush any internal state to the output buffer. </p></li>
+ *
+ * </ol>
+ *
+ * Each invocation of the {@link #encode encode} method will encode as many
+ * characters as possible from the input buffer, writing the resulting bytes
+ * to the output buffer. The {@link #encode encode} method returns when more
+ * input is required, when there is not enough room in the output buffer, or
+ * when an encoding error has occurred. In each case a {@link CoderResult}
+ * object is returned to describe the reason for termination. An invoker can
+ * examine this object and fill the input buffer, flush the output buffer, or
+ * attempt to recover from an encoding error, as appropriate, and try again.
+ *
+ * <a name="ce"></a>
+ *
+ * <p> There are two general types of encoding errors. If the input character
+ * sequence is not a legal sixteen-bit Unicode sequence then the input is considered <i>malformed</i>. If
+ * the input character sequence is legal but cannot be mapped to a valid
+ * byte sequence in the given charset then an <i>unmappable character</i> has been encountered.
+ *
+ * <a name="cae"></a>
+ *
+ * <p> How an encoding error is handled depends upon the action requested for
+ * that type of error, which is described by an instance of the {@link
+ * CodingErrorAction} class. The possible error actions are to {@linkplain
+ * CodingErrorAction#IGNORE ignore} the erroneous input, {@linkplain
+ * CodingErrorAction#REPORT report} the error to the invoker via
+ * the returned {@link CoderResult} object, or {@linkplain CodingErrorAction#REPLACE
+ * replace} the erroneous input with the current value of the
+ * replacement byte array. The replacement
+ *
+
+ * is initially set to the encoder's default replacement, which often
+ * (but not always) has the initial value <tt>{</tt> <tt>(byte)'?'</tt> <tt>}</tt>;
+
+
+
+
+ *
+ * its value may be changed via the {@link #replaceWith(byte[])
+ * replaceWith} method.
+ *
+ * <p> The default action for malformed-input and unmappable-character errors
+ * is to {@linkplain CodingErrorAction#REPORT report} them. The
+ * malformed-input error action may be changed via the {@link
+ * #onMalformedInput(CodingErrorAction) onMalformedInput} method; the
+ * unmappable-character action may be changed via the {@link
+ * #onUnmappableCharacter(CodingErrorAction) onUnmappableCharacter} method.
+ *
+ * <p> This class is designed to handle many of the details of the encoding
+ * process, including the implementation of error actions. An encoder for a
+ * specific charset, which is a concrete subclass of this class, need only
+ * implement the abstract {@link #encodeLoop encodeLoop} method, which
+ * encapsulates the basic encoding loop. A subclass that maintains internal
+ * state should, additionally, override the {@link #implFlush implFlush} and
+ * {@link #implReset implReset} methods.
+ *
+ * <p> Instances of this class are not safe for use by multiple concurrent
+ * threads. </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ *
+ * @see ByteBuffer
+ * @see CharBuffer
+ * @see Charset
+ * @see CharsetDecoder
+ */
+
+public abstract class CharsetEncoder {
+
+ private final Charset charset;
+ private final float averageBytesPerChar;
+ private final float maxBytesPerChar;
+
+ private byte[] replacement;
+ private CodingErrorAction malformedInputAction
+ = CodingErrorAction.REPORT;
+ private CodingErrorAction unmappableCharacterAction
+ = CodingErrorAction.REPORT;
+
+ // Internal states
+ //
+ private static final int ST_RESET = 0;
+ private static final int ST_CODING = 1;
+ private static final int ST_END = 2;
+ private static final int ST_FLUSHED = 3;
+
+ private int state = ST_RESET;
+
+ private static String stateNames[]
+ = { "RESET", "CODING", "CODING_END", "FLUSHED" };
+
+
+ /**
+ * Initializes a new encoder. The new encoder will have the given
+ * bytes-per-char and replacement values.
+ *
+ * @param cs
+ * The charset that created this encoder
+ *
+ * @param averageBytesPerChar
+ * A positive float value indicating the expected number of
+ * bytes that will be produced for each input character
+ *
+ * @param maxBytesPerChar
+ * A positive float value indicating the maximum number of
+ * bytes that will be produced for each input character
+ *
+ * @param replacement
+ * The initial replacement; must not be <tt>null</tt>, must have
+ * non-zero length, must not be longer than maxBytesPerChar,
+ * and must be {@linkplain #isLegalReplacement legal}
+ *
+ * @throws IllegalArgumentException
+ * If the preconditions on the parameters do not hold
+ */
+ protected
+ CharsetEncoder(Charset cs,
+ float averageBytesPerChar,
+ float maxBytesPerChar,
+ byte[] replacement)
+ {
+ // BEGIN Android-added: A hidden constructor for the CharsetEncoderICU subclass.
+ this(cs, averageBytesPerChar, maxBytesPerChar, replacement, false);
+ }
+
+ /**
+ * This constructor is for subclasses to specify whether {@code replacement} can be used as it
+ * is ("trusted"). If it is trusted, {@link #replaceWith(byte[])} and
+ * {@link #implReplaceWith(byte[])} will not be called.
+ * @hide
+ */
+ protected CharsetEncoder(Charset cs, float averageBytesPerChar, float maxBytesPerChar, byte[] replacement,
+ boolean trusted)
+ {
+ // END Android-added: A hidden constructor for the CharsetEncoderICU subclass.
+ this.charset = cs;
+ if (averageBytesPerChar <= 0.0f)
+ throw new IllegalArgumentException("Non-positive "
+ + "averageBytesPerChar");
+ if (maxBytesPerChar <= 0.0f)
+ throw new IllegalArgumentException("Non-positive "
+ + "maxBytesPerChar");
+ if (!Charset.atBugLevel("1.4")) {
+ if (averageBytesPerChar > maxBytesPerChar)
+ throw new IllegalArgumentException("averageBytesPerChar"
+ + " exceeds "
+ + "maxBytesPerChar");
+ }
+ this.replacement = replacement;
+ this.averageBytesPerChar = averageBytesPerChar;
+ this.maxBytesPerChar = maxBytesPerChar;
+ // BEGIN Android-changed: Avoid calling replaceWith() for trusted subclasses.
+ // replaceWith(replacement);
+ if (!trusted) {
+ replaceWith(replacement);
+ }
+ // END Android-changed: Avoid calling replaceWith() for trusted subclasses.
+ }
+
+ /**
+ * Initializes a new encoder. The new encoder will have the given
+ * bytes-per-char values and its replacement will be the
+ * byte array <tt>{</tt> <tt>(byte)'?'</tt> <tt>}</tt>.
+ *
+ * @param cs
+ * The charset that created this encoder
+ *
+ * @param averageBytesPerChar
+ * A positive float value indicating the expected number of
+ * bytes that will be produced for each input character
+ *
+ * @param maxBytesPerChar
+ * A positive float value indicating the maximum number of
+ * bytes that will be produced for each input character
+ *
+ * @throws IllegalArgumentException
+ * If the preconditions on the parameters do not hold
+ */
+ protected CharsetEncoder(Charset cs,
+ float averageBytesPerChar,
+ float maxBytesPerChar)
+ {
+ this(cs,
+ averageBytesPerChar, maxBytesPerChar,
+ new byte[] { (byte)'?' });
+ }
+
+ /**
+ * Returns the charset that created this encoder.
+ *
+ * @return This encoder's charset
+ */
+ public final Charset charset() {
+ return charset;
+ }
+
+ /**
+ * Returns this encoder's replacement value.
+ *
+ * @return This encoder's current replacement,
+ * which is never <tt>null</tt> and is never empty
+ */
+ public final byte[] replacement() {
+
+
+
+
+ return Arrays.copyOf(replacement, replacement.length);
+
+ }
+
+ /**
+ * Changes this encoder's replacement value.
+ *
+ * <p> This method invokes the {@link #implReplaceWith implReplaceWith}
+ * method, passing the new replacement, after checking that the new
+ * replacement is acceptable. </p>
+ *
+ * @param newReplacement The replacement value
+ *
+
+
+
+
+
+ * The new replacement; must not be <tt>null</tt>, must have
+ * non-zero length, must not be longer than the value returned by
+ * the {@link #maxBytesPerChar() maxBytesPerChar} method, and
+ * must be {@link #isLegalReplacement legal}
+
+ *
+ * @return This encoder
+ *
+ * @throws IllegalArgumentException
+ * If the preconditions on the parameter do not hold
+ */
+ public final CharsetEncoder replaceWith(byte[] newReplacement) {
+ if (newReplacement == null)
+ throw new IllegalArgumentException("Null replacement");
+ int len = newReplacement.length;
+ if (len == 0)
+ throw new IllegalArgumentException("Empty replacement");
+ if (len > maxBytesPerChar)
+ throw new IllegalArgumentException("Replacement too long");
+
+
+
+
+ if (!isLegalReplacement(newReplacement))
+ throw new IllegalArgumentException("Illegal replacement");
+ this.replacement = Arrays.copyOf(newReplacement, newReplacement.length);
+
+ implReplaceWith(this.replacement);
+ return this;
+ }
+
+ /**
+ * Reports a change to this encoder's replacement value.
+ *
+ * <p> The default implementation of this method does nothing. This method
+ * should be overridden by encoders that require notification of changes to
+ * the replacement. </p>
+ *
+ * @param newReplacement The replacement value
+ */
+ protected void implReplaceWith(byte[] newReplacement) {
+ }
+
+
+
+ private WeakReference<CharsetDecoder> cachedDecoder = null;
+
+ /**
+ * Tells whether or not the given byte array is a legal replacement value
+ * for this encoder.
+ *
+ * <p> A replacement is legal if, and only if, it is a legal sequence of
+ * bytes in this encoder's charset; that is, it must be possible to decode
+ * the replacement into one or more sixteen-bit Unicode characters.
+ *
+ * <p> The default implementation of this method is not very efficient; it
+ * should generally be overridden to improve performance. </p>
+ *
+ * @param repl The byte array to be tested
+ *
+ * @return <tt>true</tt> if, and only if, the given byte array
+ * is a legal replacement value for this encoder
+ */
+ public boolean isLegalReplacement(byte[] repl) {
+ WeakReference<CharsetDecoder> wr = cachedDecoder;
+ CharsetDecoder dec = null;
+ if ((wr == null) || ((dec = wr.get()) == null)) {
+ dec = charset().newDecoder();
+ dec.onMalformedInput(CodingErrorAction.REPORT);
+ dec.onUnmappableCharacter(CodingErrorAction.REPORT);
+ cachedDecoder = new WeakReference<CharsetDecoder>(dec);
+ } else {
+ dec.reset();
+ }
+ ByteBuffer bb = ByteBuffer.wrap(repl);
+ CharBuffer cb = CharBuffer.allocate((int)(bb.remaining()
+ * dec.maxCharsPerByte()));
+ CoderResult cr = dec.decode(bb, cb, true);
+ return !cr.isError();
+ }
+
+
+
+ /**
+ * Returns this encoder's current action for malformed-input errors.
+ *
+ * @return The current malformed-input action, which is never <tt>null</tt>
+ */
+ public CodingErrorAction malformedInputAction() {
+ return malformedInputAction;
+ }
+
+ /**
+ * Changes this encoder's action for malformed-input errors.
+ *
+ * <p> This method invokes the {@link #implOnMalformedInput
+ * implOnMalformedInput} method, passing the new action. </p>
+ *
+ * @param newAction The new action; must not be <tt>null</tt>
+ *
+ * @return This encoder
+ *
+ * @throws IllegalArgumentException
+ * If the precondition on the parameter does not hold
+ */
+ public final CharsetEncoder onMalformedInput(CodingErrorAction newAction) {
+ if (newAction == null)
+ throw new IllegalArgumentException("Null action");
+ malformedInputAction = newAction;
+ implOnMalformedInput(newAction);
+ return this;
+ }
+
+ /**
+ * Reports a change to this encoder's malformed-input action.
+ *
+ * <p> The default implementation of this method does nothing. This method
+ * should be overridden by encoders that require notification of changes to
+ * the malformed-input action. </p>
+ *
+ * @param newAction The new action
+ */
+ protected void implOnMalformedInput(CodingErrorAction newAction) { }
+
+ /**
+ * Returns this encoder's current action for unmappable-character errors.
+ *
+ * @return The current unmappable-character action, which is never
+ * <tt>null</tt>
+ */
+ public CodingErrorAction unmappableCharacterAction() {
+ return unmappableCharacterAction;
+ }
+
+ /**
+ * Changes this encoder's action for unmappable-character errors.
+ *
+ * <p> This method invokes the {@link #implOnUnmappableCharacter
+ * implOnUnmappableCharacter} method, passing the new action. </p>
+ *
+ * @param newAction The new action; must not be <tt>null</tt>
+ *
+ * @return This encoder
+ *
+ * @throws IllegalArgumentException
+ * If the precondition on the parameter does not hold
+ */
+ public final CharsetEncoder onUnmappableCharacter(CodingErrorAction
+ newAction)
+ {
+ if (newAction == null)
+ throw new IllegalArgumentException("Null action");
+ unmappableCharacterAction = newAction;
+ implOnUnmappableCharacter(newAction);
+ return this;
+ }
+
+ /**
+ * Reports a change to this encoder's unmappable-character action.
+ *
+ * <p> The default implementation of this method does nothing. This method
+ * should be overridden by encoders that require notification of changes to
+ * the unmappable-character action. </p>
+ *
+ * @param newAction The new action
+ */
+ protected void implOnUnmappableCharacter(CodingErrorAction newAction) { }
+
+ /**
+ * Returns the average number of bytes that will be produced for each
+ * character of input. This heuristic value may be used to estimate the size
+ * of the output buffer required for a given input sequence.
+ *
+ * @return The average number of bytes produced
+ * per character of input
+ */
+ public final float averageBytesPerChar() {
+ return averageBytesPerChar;
+ }
+
+ /**
+ * Returns the maximum number of bytes that will be produced for each
+ * character of input. This value may be used to compute the worst-case size
+ * of the output buffer required for a given input sequence.
+ *
+ * @return The maximum number of bytes that will be produced per
+ * character of input
+ */
+ public final float maxBytesPerChar() {
+ return maxBytesPerChar;
+ }
+
+ /**
+ * Encodes as many characters as possible from the given input buffer,
+ * writing the results to the given output buffer.
+ *
+ * <p> The buffers are read from, and written to, starting at their current
+ * positions. At most {@link Buffer#remaining in.remaining()} characters
+ * will be read and at most {@link Buffer#remaining out.remaining()}
+ * bytes will be written. The buffers' positions will be advanced to
+ * reflect the characters read and the bytes written, but their marks and
+ * limits will not be modified.
+ *
+ * <p> In addition to reading characters from the input buffer and writing
+ * bytes to the output buffer, this method returns a {@link CoderResult}
+ * object to describe its reason for termination:
+ *
+ * <ul>
+ *
+ * <li><p> {@link CoderResult#UNDERFLOW} indicates that as much of the
+ * input buffer as possible has been encoded. If there is no further
+ * input then the invoker can proceed to the next step of the
+ * <a href="#steps">encoding operation</a>. Otherwise this method
+ * should be invoked again with further input. </p></li>
+ *
+ * <li><p> {@link CoderResult#OVERFLOW} indicates that there is
+ * insufficient space in the output buffer to encode any more characters.
+ * This method should be invoked again with an output buffer that has
+ * more {@linkplain Buffer#remaining remaining} bytes. This is
+ * typically done by draining any encoded bytes from the output
+ * buffer. </p></li>
+ *
+ * <li><p> A {@linkplain CoderResult#malformedForLength
+ * malformed-input} result indicates that a malformed-input
+ * error has been detected. The malformed characters begin at the input
+ * buffer's (possibly incremented) position; the number of malformed
+ * characters may be determined by invoking the result object's {@link
+ * CoderResult#length() length} method. This case applies only if the
+ * {@linkplain #onMalformedInput malformed action} of this encoder
+ * is {@link CodingErrorAction#REPORT}; otherwise the malformed input
+ * will be ignored or replaced, as requested. </p></li>
+ *
+ * <li><p> An {@linkplain CoderResult#unmappableForLength
+ * unmappable-character} result indicates that an
+ * unmappable-character error has been detected. The characters that
+ * encode the unmappable character begin at the input buffer's (possibly
+ * incremented) position; the number of such characters may be determined
+ * by invoking the result object's {@link CoderResult#length() length}
+ * method. This case applies only if the {@linkplain #onUnmappableCharacter
+ * unmappable action} of this encoder is {@link
+ * CodingErrorAction#REPORT}; otherwise the unmappable character will be
+ * ignored or replaced, as requested. </p></li>
+ *
+ * </ul>
+ *
+ * In any case, if this method is to be reinvoked in the same encoding
+ * operation then care should be taken to preserve any characters remaining
+ * in the input buffer so that they are available to the next invocation.
+ *
+ * <p> The <tt>endOfInput</tt> parameter advises this method as to whether
+ * the invoker can provide further input beyond that contained in the given
+ * input buffer. If there is a possibility of providing additional input
+ * then the invoker should pass <tt>false</tt> for this parameter; if there
+ * is no possibility of providing further input then the invoker should
+ * pass <tt>true</tt>. It is not erroneous, and in fact it is quite
+ * common, to pass <tt>false</tt> in one invocation and later discover that
+ * no further input was actually available. It is critical, however, that
+ * the final invocation of this method in a sequence of invocations always
+ * pass <tt>true</tt> so that any remaining unencoded input will be treated
+ * as being malformed.
+ *
+ * <p> This method works by invoking the {@link #encodeLoop encodeLoop}
+ * method, interpreting its results, handling error conditions, and
+ * reinvoking it as necessary. </p>
+ *
+ *
+ * @param in
+ * The input character buffer
+ *
+ * @param out
+ * The output byte buffer
+ *
+ * @param endOfInput
+ * <tt>true</tt> if, and only if, the invoker can provide no
+ * additional input characters beyond those in the given buffer
+ *
+ * @return A coder-result object describing the reason for termination
+ *
+ * @throws IllegalStateException
+ * If an encoding operation is already in progress and the previous
+ * step was an invocation neither of the {@link #reset reset}
+ * method, nor of this method with a value of <tt>false</tt> for
+ * the <tt>endOfInput</tt> parameter, nor of this method with a
+ * value of <tt>true</tt> for the <tt>endOfInput</tt> parameter
+ * but a return value indicating an incomplete encoding operation
+ *
+ * @throws CoderMalfunctionError
+ * If an invocation of the encodeLoop method threw
+ * an unexpected exception
+ */
+ public final CoderResult encode(CharBuffer in, ByteBuffer out,
+ boolean endOfInput)
+ {
+ int newState = endOfInput ? ST_END : ST_CODING;
+ if ((state != ST_RESET) && (state != ST_CODING)
+ && !(endOfInput && (state == ST_END)))
+ throwIllegalStateException(state, newState);
+ state = newState;
+
+ for (;;) {
+
+ CoderResult cr;
+ try {
+ cr = encodeLoop(in, out);
+ } catch (BufferUnderflowException x) {
+ throw new CoderMalfunctionError(x);
+ } catch (BufferOverflowException x) {
+ throw new CoderMalfunctionError(x);
+ }
+
+ if (cr.isOverflow())
+ return cr;
+
+ if (cr.isUnderflow()) {
+ if (endOfInput && in.hasRemaining()) {
+ cr = CoderResult.malformedForLength(in.remaining());
+ // Fall through to malformed-input case
+ } else {
+ return cr;
+ }
+ }
+
+ CodingErrorAction action = null;
+ if (cr.isMalformed())
+ action = malformedInputAction;
+ else if (cr.isUnmappable())
+ action = unmappableCharacterAction;
+ else
+ assert false : cr.toString();
+
+ if (action == CodingErrorAction.REPORT)
+ return cr;
+
+ if (action == CodingErrorAction.REPLACE) {
+ if (out.remaining() < replacement.length)
+ return CoderResult.OVERFLOW;
+ out.put(replacement);
+ }
+
+ if ((action == CodingErrorAction.IGNORE)
+ || (action == CodingErrorAction.REPLACE)) {
+ // Skip erroneous input either way
+ in.position(in.position() + cr.length());
+ continue;
+ }
+
+ assert false;
+ }
+
+ }
+
+ /**
+ * Flushes this encoder.
+ *
+ * <p> Some encoders maintain internal state and may need to write some
+ * final bytes to the output buffer once the overall input sequence has
+ * been read.
+ *
+ * <p> Any additional output is written to the output buffer beginning at
+ * its current position. At most {@link Buffer#remaining out.remaining()}
+ * bytes will be written. The buffer's position will be advanced
+ * appropriately, but its mark and limit will not be modified.
+ *
+ * <p> If this method completes successfully then it returns {@link
+ * CoderResult#UNDERFLOW}. If there is insufficient room in the output
+ * buffer then it returns {@link CoderResult#OVERFLOW}. If this happens
+ * then this method must be invoked again, with an output buffer that has
+ * more room, in order to complete the current <a href="#steps">encoding
+ * operation</a>.
+ *
+ * <p> If this encoder has already been flushed then invoking this method
+ * has no effect.
+ *
+ * <p> This method invokes the {@link #implFlush implFlush} method to
+ * perform the actual flushing operation. </p>
+ *
+ * @param out
+ * The output byte buffer
+ *
+ * @return A coder-result object, either {@link CoderResult#UNDERFLOW} or
+ * {@link CoderResult#OVERFLOW}
+ *
+ * @throws IllegalStateException
+ * If the previous step of the current encoding operation was an
+ * invocation neither of the {@link #flush flush} method nor of
+ * the three-argument {@link
+ * #encode(CharBuffer,ByteBuffer,boolean) encode} method
+ * with a value of <tt>true</tt> for the <tt>endOfInput</tt>
+ * parameter
+ */
+ public final CoderResult flush(ByteBuffer out) {
+ if (state == ST_END) {
+ CoderResult cr = implFlush(out);
+ if (cr.isUnderflow())
+ state = ST_FLUSHED;
+ return cr;
+ }
+
+ if (state != ST_FLUSHED)
+ throwIllegalStateException(state, ST_FLUSHED);
+
+ return CoderResult.UNDERFLOW; // Already flushed
+ }
+
+ /**
+ * Flushes this encoder.
+ *
+ * <p> The default implementation of this method does nothing, and always
+ * returns {@link CoderResult#UNDERFLOW}. This method should be overridden
+ * by encoders that may need to write final bytes to the output buffer
+ * once the entire input sequence has been read. </p>
+ *
+ * @param out
+ * The output byte buffer
+ *
+ * @return A coder-result object, either {@link CoderResult#UNDERFLOW} or
+ * {@link CoderResult#OVERFLOW}
+ */
+ protected CoderResult implFlush(ByteBuffer out) {
+ return CoderResult.UNDERFLOW;
+ }
+
+ /**
+ * Resets this encoder, clearing any internal state.
+ *
+ * <p> This method resets charset-independent state and also invokes the
+ * {@link #implReset() implReset} method in order to perform any
+ * charset-specific reset actions. </p>
+ *
+ * @return This encoder
+ *
+ */
+ public final CharsetEncoder reset() {
+ implReset();
+ state = ST_RESET;
+ return this;
+ }
+
+ /**
+ * Resets this encoder, clearing any charset-specific internal state.
+ *
+ * <p> The default implementation of this method does nothing. This method
+ * should be overridden by encoders that maintain internal state. </p>
+ */
+ protected void implReset() { }
+
+ /**
+ * Encodes one or more characters into one or more bytes.
+ *
+ * <p> This method encapsulates the basic encoding loop, encoding as many
+ * characters as possible until it either runs out of input, runs out of room
+ * in the output buffer, or encounters an encoding error. This method is
+ * invoked by the {@link #encode encode} method, which handles result
+ * interpretation and error recovery.
+ *
+ * <p> The buffers are read from, and written to, starting at their current
+ * positions. At most {@link Buffer#remaining in.remaining()} characters
+ * will be read, and at most {@link Buffer#remaining out.remaining()}
+ * bytes will be written. The buffers' positions will be advanced to
+ * reflect the characters read and the bytes written, but their marks and
+ * limits will not be modified.
+ *
+ * <p> This method returns a {@link CoderResult} object to describe its
+ * reason for termination, in the same manner as the {@link #encode encode}
+ * method. Most implementations of this method will handle encoding errors
+ * by returning an appropriate result object for interpretation by the
+ * {@link #encode encode} method. An optimized implementation may instead
+ * examine the relevant error action and implement that action itself.
+ *
+ * <p> An implementation of this method may perform arbitrary lookahead by
+ * returning {@link CoderResult#UNDERFLOW} until it receives sufficient
+ * input. </p>
+ *
+ * @param in
+ * The input character buffer
+ *
+ * @param out
+ * The output byte buffer
+ *
+ * @return A coder-result object describing the reason for termination
+ */
+ protected abstract CoderResult encodeLoop(CharBuffer in,
+ ByteBuffer out);
+
+ /**
+ * Convenience method that encodes the remaining content of a single input
+ * character buffer into a newly-allocated byte buffer.
+ *
+ * <p> This method implements an entire <a href="#steps">encoding
+ * operation</a>; that is, it resets this encoder, then it encodes the
+ * characters in the given character buffer, and finally it flushes this
+ * encoder. This method should therefore not be invoked if an encoding
+ * operation is already in progress. </p>
+ *
+ * @param in
+ * The input character buffer
+ *
+ * @return A newly-allocated byte buffer containing the result of the
+ * encoding operation. The buffer's position will be zero and its
+ * limit will follow the last byte written.
+ *
+ * @throws IllegalStateException
+ * If an encoding operation is already in progress
+ *
+ * @throws MalformedInputException
+ * If the character sequence starting at the input buffer's current
+ * position is not a legal sixteen-bit Unicode sequence and the current malformed-input action
+ * is {@link CodingErrorAction#REPORT}
+ *
+ * @throws UnmappableCharacterException
+ * If the character sequence starting at the input buffer's current
+ * position cannot be mapped to an equivalent byte sequence and
+ * the current unmappable-character action is {@link
+ * CodingErrorAction#REPORT}
+ */
+ public final ByteBuffer encode(CharBuffer in)
+ throws CharacterCodingException
+ {
+ int n = (int)(in.remaining() * averageBytesPerChar());
+ ByteBuffer out = ByteBuffer.allocate(n);
+
+ if ((n == 0) && (in.remaining() == 0))
+ return out;
+ reset();
+ for (;;) {
+ CoderResult cr = in.hasRemaining() ?
+ encode(in, out, true) : CoderResult.UNDERFLOW;
+ if (cr.isUnderflow())
+ cr = flush(out);
+
+ if (cr.isUnderflow())
+ break;
+ if (cr.isOverflow()) {
+ n = 2*n + 1; // Ensure progress; n might be 0!
+ ByteBuffer o = ByteBuffer.allocate(n);
+ out.flip();
+ o.put(out);
+ out = o;
+ continue;
+ }
+ cr.throwException();
+ }
+ out.flip();
+ return out;
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ private boolean canEncode(CharBuffer cb) {
+ if (state == ST_FLUSHED)
+ reset();
+ else if (state != ST_RESET)
+ throwIllegalStateException(state, ST_CODING);
+
+ // BEGIN Android-added: Fast path handling for empty buffers.
+ // Empty buffers can always be "encoded".
+ if (!cb.hasRemaining()) {
+ return true;
+ }
+ // END Android-added: Fast path handling for empty buffers.
+
+ CodingErrorAction ma = malformedInputAction();
+ CodingErrorAction ua = unmappableCharacterAction();
+ try {
+ onMalformedInput(CodingErrorAction.REPORT);
+ onUnmappableCharacter(CodingErrorAction.REPORT);
+ encode(cb);
+ } catch (CharacterCodingException x) {
+ return false;
+ } finally {
+ onMalformedInput(ma);
+ onUnmappableCharacter(ua);
+ reset();
+ }
+ return true;
+ }
+
+ /**
+ * Tells whether or not this encoder can encode the given character.
+ *
+ * <p> This method returns <tt>false</tt> if the given character is a
+ * surrogate character; such characters can be interpreted only when they
+ * are members of a pair consisting of a high surrogate followed by a low
+ * surrogate. The {@link #canEncode(java.lang.CharSequence)
+ * canEncode(CharSequence)} method may be used to test whether or not a
+ * character sequence can be encoded.
+ *
+ * <p> This method may modify this encoder's state; it should therefore not
+ * be invoked if an <a href="#steps">encoding operation</a> is already in
+ * progress.
+ *
+ * <p> The default implementation of this method is not very efficient; it
+ * should generally be overridden to improve performance. </p>
+ *
+ * @param c
+ * The given character
+ *
+ * @return <tt>true</tt> if, and only if, this encoder can encode
+ * the given character
+ *
+ * @throws IllegalStateException
+ * If an encoding operation is already in progress
+ */
+ public boolean canEncode(char c) {
+ CharBuffer cb = CharBuffer.allocate(1);
+ cb.put(c);
+ cb.flip();
+ return canEncode(cb);
+ }
+
+ /**
+ * Tells whether or not this encoder can encode the given character
+ * sequence.
+ *
+ * <p> If this method returns <tt>false</tt> for a particular character
+ * sequence then more information about why the sequence cannot be encoded
+ * may be obtained by performing a full <a href="#steps">encoding
+ * operation</a>.
+ *
+ * <p> This method may modify this encoder's state; it should therefore not
+ * be invoked if an encoding operation is already in progress.
+ *
+ * <p> The default implementation of this method is not very efficient; it
+ * should generally be overridden to improve performance. </p>
+ *
+ * @param cs
+ * The given character sequence
+ *
+ * @return <tt>true</tt> if, and only if, this encoder can encode
+ * the given character without throwing any exceptions and without
+ * performing any replacements
+ *
+ * @throws IllegalStateException
+ * If an encoding operation is already in progress
+ */
+ public boolean canEncode(CharSequence cs) {
+ CharBuffer cb;
+ if (cs instanceof CharBuffer)
+ cb = ((CharBuffer)cs).duplicate();
+ else
+ // Android-removed: An unnecessary call to toString().
+ // cb = CharBuffer.wrap(cs.toString());
+ cb = CharBuffer.wrap(cs);
+ return canEncode(cb);
+ }
+
+
+
+
+ private void throwIllegalStateException(int from, int to) {
+ throw new IllegalStateException("Current state = " + stateNames[from]
+ + ", new state = " + stateNames[to]);
+ }
+
+}
diff --git a/java/nio/charset/CoderMalfunctionError.java b/java/nio/charset/CoderMalfunctionError.java
new file mode 100644
index 0000000..aec47e5
--- /dev/null
+++ b/java/nio/charset/CoderMalfunctionError.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2001, 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.charset;
+
+
+/**
+ * Error thrown when the {@link CharsetDecoder#decodeLoop decodeLoop} method of
+ * a {@link CharsetDecoder}, or the {@link CharsetEncoder#encodeLoop
+ * encodeLoop} method of a {@link CharsetEncoder}, throws an unexpected
+ * exception.
+ *
+ * @since 1.4
+ */
+
+public class CoderMalfunctionError
+ extends Error
+{
+
+ private static final long serialVersionUID = -1151412348057794301L;
+
+ /**
+ * Initializes an instance of this class.
+ *
+ * @param cause
+ * The unexpected exception that was thrown
+ */
+ public CoderMalfunctionError(Exception cause) {
+ super(cause);
+ }
+
+}
diff --git a/java/nio/charset/CoderResult.java b/java/nio/charset/CoderResult.java
new file mode 100644
index 0000000..d087c97
--- /dev/null
+++ b/java/nio/charset/CoderResult.java
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.charset;
+
+import java.lang.ref.WeakReference;
+import java.nio.*;
+import java.util.Map;
+import java.util.HashMap;
+
+
+/**
+ * A description of the result state of a coder.
+ *
+ * <p> A charset coder, that is, either a decoder or an encoder, consumes bytes
+ * (or characters) from an input buffer, translates them, and writes the
+ * resulting characters (or bytes) to an output buffer. A coding process
+ * terminates for one of four categories of reasons, which are described by
+ * instances of this class:
+ *
+ * <ul>
+ *
+ * <li><p> <i>Underflow</i> is reported when there is no more input to be
+ * processed, or there is insufficient input and additional input is
+ * required. This condition is represented by the unique result object
+ * {@link #UNDERFLOW}, whose {@link #isUnderflow() isUnderflow} method
+ * returns <tt>true</tt>. </p></li>
+ *
+ * <li><p> <i>Overflow</i> is reported when there is insufficient room
+ * remaining in the output buffer. This condition is represented by the
+ * unique result object {@link #OVERFLOW}, whose {@link #isOverflow()
+ * isOverflow} method returns <tt>true</tt>. </p></li>
+ *
+ * <li><p> A <i>malformed-input error</i> is reported when a sequence of
+ * input units is not well-formed. Such errors are described by instances of
+ * this class whose {@link #isMalformed() isMalformed} method returns
+ * <tt>true</tt> and whose {@link #length() length} method returns the length
+ * of the malformed sequence. There is one unique instance of this class for
+ * all malformed-input errors of a given length. </p></li>
+ *
+ * <li><p> An <i>unmappable-character error</i> is reported when a sequence
+ * of input units denotes a character that cannot be represented in the
+ * output charset. Such errors are described by instances of this class
+ * whose {@link #isUnmappable() isUnmappable} method returns <tt>true</tt> and
+ * whose {@link #length() length} method returns the length of the input
+ * sequence denoting the unmappable character. There is one unique instance
+ * of this class for all unmappable-character errors of a given length.
+ * </p></li>
+ *
+ * </ul>
+ *
+ * <p> For convenience, the {@link #isError() isError} method returns <tt>true</tt>
+ * for result objects that describe malformed-input and unmappable-character
+ * errors but <tt>false</tt> for those that describe underflow or overflow
+ * conditions. </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public class CoderResult {
+
+ private static final int CR_UNDERFLOW = 0;
+ private static final int CR_OVERFLOW = 1;
+ private static final int CR_ERROR_MIN = 2;
+ private static final int CR_MALFORMED = 2;
+ private static final int CR_UNMAPPABLE = 3;
+
+ private static final String[] names
+ = { "UNDERFLOW", "OVERFLOW", "MALFORMED", "UNMAPPABLE" };
+
+ private final int type;
+ private final int length;
+
+ private CoderResult(int type, int length) {
+ this.type = type;
+ this.length = length;
+ }
+
+ /**
+ * Returns a string describing this coder result.
+ *
+ * @return A descriptive string
+ */
+ public String toString() {
+ String nm = names[type];
+ return isError() ? nm + "[" + length + "]" : nm;
+ }
+
+ /**
+ * Tells whether or not this object describes an underflow condition.
+ *
+ * @return <tt>true</tt> if, and only if, this object denotes underflow
+ */
+ public boolean isUnderflow() {
+ return (type == CR_UNDERFLOW);
+ }
+
+ /**
+ * Tells whether or not this object describes an overflow condition.
+ *
+ * @return <tt>true</tt> if, and only if, this object denotes overflow
+ */
+ public boolean isOverflow() {
+ return (type == CR_OVERFLOW);
+ }
+
+ /**
+ * Tells whether or not this object describes an error condition.
+ *
+ * @return <tt>true</tt> if, and only if, this object denotes either a
+ * malformed-input error or an unmappable-character error
+ */
+ public boolean isError() {
+ return (type >= CR_ERROR_MIN);
+ }
+
+ /**
+ * Tells whether or not this object describes a malformed-input error.
+ *
+ * @return <tt>true</tt> if, and only if, this object denotes a
+ * malformed-input error
+ */
+ public boolean isMalformed() {
+ return (type == CR_MALFORMED);
+ }
+
+ /**
+ * Tells whether or not this object describes an unmappable-character
+ * error.
+ *
+ * @return <tt>true</tt> if, and only if, this object denotes an
+ * unmappable-character error
+ */
+ public boolean isUnmappable() {
+ return (type == CR_UNMAPPABLE);
+ }
+
+ /**
+ * Returns the length of the erroneous input described by this
+ * object <i>(optional operation)</i>.
+ *
+ * @return The length of the erroneous input, a positive integer
+ *
+ * @throws UnsupportedOperationException
+ * If this object does not describe an error condition, that is,
+ * if the {@link #isError() isError} does not return <tt>true</tt>
+ */
+ public int length() {
+ if (!isError())
+ throw new UnsupportedOperationException();
+ return length;
+ }
+
+ /**
+ * Result object indicating underflow, meaning that either the input buffer
+ * has been completely consumed or, if the input buffer is not yet empty,
+ * that additional input is required.
+ */
+ public static final CoderResult UNDERFLOW
+ = new CoderResult(CR_UNDERFLOW, 0);
+
+ /**
+ * Result object indicating overflow, meaning that there is insufficient
+ * room in the output buffer.
+ */
+ public static final CoderResult OVERFLOW
+ = new CoderResult(CR_OVERFLOW, 0);
+
+ private static abstract class Cache {
+
+ private Map<Integer,WeakReference<CoderResult>> cache = null;
+
+ protected abstract CoderResult create(int len);
+
+ private synchronized CoderResult get(int len) {
+ if (len <= 0)
+ throw new IllegalArgumentException("Non-positive length");
+ Integer k = new Integer(len);
+ WeakReference<CoderResult> w;
+ CoderResult e = null;
+ if (cache == null) {
+ cache = new HashMap<Integer,WeakReference<CoderResult>>();
+ } else if ((w = cache.get(k)) != null) {
+ e = w.get();
+ }
+ if (e == null) {
+ e = create(len);
+ cache.put(k, new WeakReference<CoderResult>(e));
+ }
+ return e;
+ }
+
+ }
+
+ private static Cache malformedCache
+ = new Cache() {
+ public CoderResult create(int len) {
+ return new CoderResult(CR_MALFORMED, len);
+ }};
+
+ /**
+ * Static factory method that returns the unique object describing a
+ * malformed-input error of the given length.
+ *
+ * @param length
+ * The given length
+ *
+ * @return The requested coder-result object
+ */
+ public static CoderResult malformedForLength(int length) {
+ return malformedCache.get(length);
+ }
+
+ private static Cache unmappableCache
+ = new Cache() {
+ public CoderResult create(int len) {
+ return new CoderResult(CR_UNMAPPABLE, len);
+ }};
+
+ /**
+ * Static factory method that returns the unique result object describing
+ * an unmappable-character error of the given length.
+ *
+ * @param length
+ * The given length
+ *
+ * @return The requested coder-result object
+ */
+ public static CoderResult unmappableForLength(int length) {
+ return unmappableCache.get(length);
+ }
+
+ /**
+ * Throws an exception appropriate to the result described by this object.
+ *
+ * @throws BufferUnderflowException
+ * If this object is {@link #UNDERFLOW}
+ *
+ * @throws BufferOverflowException
+ * If this object is {@link #OVERFLOW}
+ *
+ * @throws MalformedInputException
+ * If this object represents a malformed-input error; the
+ * exception's length value will be that of this object
+ *
+ * @throws UnmappableCharacterException
+ * If this object represents an unmappable-character error; the
+ * exceptions length value will be that of this object
+ */
+ public void throwException()
+ throws CharacterCodingException
+ {
+ switch (type) {
+ case CR_UNDERFLOW: throw new BufferUnderflowException();
+ case CR_OVERFLOW: throw new BufferOverflowException();
+ case CR_MALFORMED: throw new MalformedInputException(length);
+ case CR_UNMAPPABLE: throw new UnmappableCharacterException(length);
+ default:
+ assert false;
+ }
+ }
+
+}
diff --git a/java/nio/charset/CodingErrorAction.java b/java/nio/charset/CodingErrorAction.java
new file mode 100644
index 0000000..c708e63
--- /dev/null
+++ b/java/nio/charset/CodingErrorAction.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.charset;
+
+
+/**
+ * A typesafe enumeration for coding-error actions.
+ *
+ * <p> Instances of this class are used to specify how malformed-input and
+ * unmappable-character errors are to be handled by charset <a
+ * href="CharsetDecoder.html#cae">decoders</a> and <a
+ * href="CharsetEncoder.html#cae">encoders</a>. </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public class CodingErrorAction {
+
+ private String name;
+
+ private CodingErrorAction(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Action indicating that a coding error is to be handled by dropping the
+ * erroneous input and resuming the coding operation.
+ */
+ public static final CodingErrorAction IGNORE
+ = new CodingErrorAction("IGNORE");
+
+ /**
+ * Action indicating that a coding error is to be handled by dropping the
+ * erroneous input, appending the coder's replacement value to the output
+ * buffer, and resuming the coding operation.
+ */
+ public static final CodingErrorAction REPLACE
+ = new CodingErrorAction("REPLACE");
+
+ /**
+ * Action indicating that a coding error is to be reported, either by
+ * returning a {@link CoderResult} object or by throwing a {@link
+ * CharacterCodingException}, whichever is appropriate for the method
+ * implementing the coding process.
+ */
+ public static final CodingErrorAction REPORT
+ = new CodingErrorAction("REPORT");
+
+ /**
+ * Returns a string describing this action.
+ *
+ * @return A descriptive string
+ */
+ public String toString() {
+ return name;
+ }
+
+}
diff --git a/java/nio/charset/IllegalCharsetNameException.java b/java/nio/charset/IllegalCharsetNameException.java
new file mode 100644
index 0000000..9124282
--- /dev/null
+++ b/java/nio/charset/IllegalCharsetNameException.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.charset;
+
+
+/**
+ * Unchecked exception thrown when a string that is not a
+ * <a href=Charset.html#names>legal charset name</a> is used as such.
+ *
+ * @since 1.4
+ */
+
+public class IllegalCharsetNameException
+ extends IllegalArgumentException
+{
+
+ private static final long serialVersionUID = 1457525358470002989L;
+
+ private String charsetName;
+
+ /**
+ * Constructs an instance of this class.
+ *
+ * @param charsetName
+ * The illegal charset name
+ */
+ public IllegalCharsetNameException(String charsetName) {
+ super(String.valueOf(charsetName));
+ this.charsetName = charsetName;
+ }
+
+ /**
+ * Retrieves the illegal charset name.
+ *
+ * @return The illegal charset name
+ */
+ public String getCharsetName() {
+ return charsetName;
+ }
+
+}
diff --git a/java/nio/charset/MalformedInputException.java b/java/nio/charset/MalformedInputException.java
new file mode 100644
index 0000000..aadbadc
--- /dev/null
+++ b/java/nio/charset/MalformedInputException.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.charset;
+
+
+/**
+ * Checked exception thrown when an input byte sequence is not legal for given
+ * charset, or an input character sequence is not a legal sixteen-bit Unicode
+ * sequence.
+ *
+ * @since 1.4
+ */
+
+public class MalformedInputException
+ extends CharacterCodingException
+{
+
+ private static final long serialVersionUID = -3438823399834806194L;
+
+ private int inputLength;
+
+ /**
+ * Constructs an {@code MalformedInputException} with the given
+ * length.
+ * @param inputLength the length of the input
+ */
+ public MalformedInputException(int inputLength) {
+ this.inputLength = inputLength;
+ }
+
+ /**
+ * Returns the length of the input.
+ * @return the length of the input
+ */
+ public int getInputLength() {
+ return inputLength;
+ }
+
+ /**
+ * Returns the message.
+ * @return the message
+ */
+ public String getMessage() {
+ return "Input length = " + inputLength;
+ }
+
+}
diff --git a/java/nio/charset/StandardCharsets.java b/java/nio/charset/StandardCharsets.java
new file mode 100644
index 0000000..b2572c3
--- /dev/null
+++ b/java/nio/charset/StandardCharsets.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.nio.charset;
+
+/**
+ * Constant definitions for the standard {@link Charset Charsets}. These
+ * charsets are guaranteed to be available on every implementation of the Java
+ * platform.
+ *
+ * @see <a href="Charset#standard">Standard Charsets</a>
+ * @since 1.7
+ */
+public final class StandardCharsets {
+
+ private StandardCharsets() {
+ throw new AssertionError("No java.nio.charset.StandardCharsets instances for you!");
+ }
+ /**
+ * Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the
+ * Unicode character set
+ */
+ public static final Charset US_ASCII = Charset.forName("US-ASCII");
+ /**
+ * ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1
+ */
+ public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
+ /**
+ * Eight-bit UCS Transformation Format
+ */
+ public static final Charset UTF_8 = Charset.forName("UTF-8");
+ /**
+ * Sixteen-bit UCS Transformation Format, big-endian byte order
+ */
+ public static final Charset UTF_16BE = Charset.forName("UTF-16BE");
+ /**
+ * Sixteen-bit UCS Transformation Format, little-endian byte order
+ */
+ public static final Charset UTF_16LE = Charset.forName("UTF-16LE");
+ /**
+ * Sixteen-bit UCS Transformation Format, byte order identified by an
+ * optional byte-order mark
+ */
+ public static final Charset UTF_16 = Charset.forName("UTF-16");
+}
diff --git a/java/nio/charset/UnmappableCharacterException.java b/java/nio/charset/UnmappableCharacterException.java
new file mode 100644
index 0000000..c33f040
--- /dev/null
+++ b/java/nio/charset/UnmappableCharacterException.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.charset;
+
+
+/**
+ * Checked exception thrown when an input character (or byte) sequence
+ * is valid but cannot be mapped to an output byte (or character)
+ * sequence.
+ *
+ * @since 1.4
+ */
+
+public class UnmappableCharacterException
+ extends CharacterCodingException
+{
+
+ private static final long serialVersionUID = -7026962371537706123L;
+
+ private int inputLength;
+
+ /**
+ * Constructs an {@code UnmappableCharacterException} with the
+ * given length.
+ * @param inputLength the length of the input
+ */
+ public UnmappableCharacterException(int inputLength) {
+ this.inputLength = inputLength;
+ }
+
+ /**
+ * Returns the length of the input.
+ * @return the length of the input
+ */
+ public int getInputLength() {
+ return inputLength;
+ }
+
+ /**
+ * Returns the message.
+ * @return the message
+ */
+ public String getMessage() {
+ return "Input length = " + inputLength;
+ }
+
+}
diff --git a/java/nio/charset/UnsupportedCharsetException.java b/java/nio/charset/UnsupportedCharsetException.java
new file mode 100644
index 0000000..1774fc0
--- /dev/null
+++ b/java/nio/charset/UnsupportedCharsetException.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.charset;
+
+
+/**
+ * Unchecked exception thrown when no support is available
+ * for a requested charset.
+ *
+ * @since 1.4
+ */
+
+public class UnsupportedCharsetException
+ extends IllegalArgumentException
+{
+
+ private static final long serialVersionUID = 1490765524727386367L;
+
+ private String charsetName;
+
+ /**
+ * Constructs an instance of this class.
+ *
+ * @param charsetName
+ * The name of the unsupported charset
+ */
+ public UnsupportedCharsetException(String charsetName) {
+ super(String.valueOf(charsetName));
+ this.charsetName = charsetName;
+ }
+
+ /**
+ * Retrieves the name of the unsupported charset.
+ *
+ * @return The name of the unsupported charset
+ */
+ public String getCharsetName() {
+ return charsetName;
+ }
+
+}
diff --git a/java/nio/charset/package-info.java b/java/nio/charset/package-info.java
new file mode 100644
index 0000000..1fc81e0
--- /dev/null
+++ b/java/nio/charset/package-info.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Defines charsets, decoders, and encoders, for translating between bytes and
+ * Unicode characters.
+ *
+ * <blockquote><table cellspacing=1 cellpadding=0 summary="Summary of charsets, decoders, and encoders in this package">
+ * <tr><th><p align="left">Class name</p></th><th><p align="left">Description</p></th></tr>
+ * <tr><td valign=top><tt>{@link java.nio.charset.Charset}</tt></td>
+ * <td>A named mapping between characters<br>and bytes</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.charset.CharsetDecoder}</tt></td>
+ * <td>Decodes bytes into characters</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.charset.CharsetEncoder} </tt></td>
+ * <td>Encodes characters into bytes</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.charset.CoderResult} </tt></td>
+ * <td>Describes coder results</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.charset.CodingErrorAction} </tt></td>
+ * <td>Describes actions to take when<br>coding errors are detected</td></tr>
+ *
+ * </table></blockquote>
+ *
+ * <p> A <i>charset</i> is named mapping between sequences of sixteen-bit Unicode
+ * characters and sequences of bytes, in the sense defined in <a
+ * href="http://www.ietf.org/rfc/rfc2278.txt"><i>RFC 2278</i></a>. A
+ * <i>decoder</i> is an engine which transforms bytes in a specific charset into
+ * characters, and an <i>encoder</i> is an engine which transforms characters into
+ * bytes. Encoders and decoders operate on byte and character buffers. They are
+ * collectively referred to as <i>coders</i>.
+ *
+ * <p> The {@link java.nio.charset.Charset} class defines methods for creating
+ * coders for a given charset and for retrieving the various names associated with
+ * a charset. It also defines static methods for testing whether a particular
+ * charset is supported, for locating charset instances by name, and for
+ * constructing a map that contains every charset for which support is available
+ * in the current Java virtual machine.
+ *
+ * <p> Most users will not use these classes directly; instead they will use the
+ * existing charset-related constructors and methods in the {@link
+ * java.lang.String} class, together with the existing {@link
+ * java.io.InputStreamReader} and {@link java.io.OutputStreamWriter} classes, all
+ * of whose implementations have been reworked to make use of the charset
+ * facilities defined in this package. A small number of changes have been made
+ * to the {@link java.io.InputStreamReader} and {@link java.io.OutputStreamWriter}
+ * classes in order to allow explicit charset objects to be specified in the
+ * construction of instances of those classes.
+ *
+ * <p> Support for new charsets can be made available via the interface defined in
+ * the {@link java.nio.charset.spi.CharsetProvider} class in the <tt>{@link
+ * java.nio.charset.spi}</tt> package.
+ *
+ * <p> Unless otherwise noted, passing a <tt>null</tt> argument to a constructor
+ * or method in any class or interface in this package will cause a {@link
+ * java.lang.NullPointerException NullPointerException} to be thrown.
+ *
+ *
+ * @since 1.4
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ */
+
+package java.nio.charset;
diff --git a/java/nio/charset/spi/CharsetProvider.java b/java/nio/charset/spi/CharsetProvider.java
new file mode 100644
index 0000000..f7821e7
--- /dev/null
+++ b/java/nio/charset/spi/CharsetProvider.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.charset.spi;
+
+import java.nio.charset.Charset;
+import java.util.Iterator;
+
+
+/**
+ * Charset service-provider class.
+ *
+ * <p> A charset provider is a concrete subclass of this class that has a
+ * zero-argument constructor and some number of associated charset
+ * implementation classes. Charset providers may be installed in an instance
+ * of the Java platform as extensions, that is, jar files placed into any of
+ * the usual extension directories. Providers may also be made available by
+ * adding them to the applet or application class path or by some other
+ * platform-specific means. Charset providers are looked up via the current
+ * thread's {@link java.lang.Thread#getContextClassLoader() context class
+ * loader}.
+ *
+ * <p> A charset provider identifies itself with a provider-configuration file
+ * named <tt>java.nio.charset.spi.CharsetProvider</tt> in the resource
+ * directory <tt>META-INF/services</tt>. The file should contain a list of
+ * fully-qualified concrete charset-provider class names, one per line. A line
+ * is terminated by any one of a line feed (<tt>'\n'</tt>), a carriage return
+ * (<tt>'\r'</tt>), or a carriage return followed immediately by a line feed.
+ * Space and tab characters surrounding each name, as well as blank lines, are
+ * ignored. The comment character is <tt>'#'</tt> (<tt>'\u0023'</tt>); on
+ * each line all characters following the first comment character are ignored.
+ * The file must be encoded in UTF-8.
+ *
+ * <p> If a particular concrete charset provider class is named in more than
+ * one configuration file, or is named in the same configuration file more than
+ * once, then the duplicates will be ignored. The configuration file naming a
+ * particular provider need not be in the same jar file or other distribution
+ * unit as the provider itself. The provider must be accessible from the same
+ * class loader that was initially queried to locate the configuration file;
+ * this is not necessarily the class loader that loaded the file. </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ *
+ * @see java.nio.charset.Charset
+ */
+
+public abstract class CharsetProvider {
+
+ /**
+ * Initializes a new charset provider.
+ *
+ * @throws SecurityException
+ * If a security manager has been installed and it denies
+ * {@link RuntimePermission}<tt>("charsetProvider")</tt>
+ */
+ protected CharsetProvider() {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("charsetProvider"));
+ }
+
+ /**
+ * Creates an iterator that iterates over the charsets supported by this
+ * provider. This method is used in the implementation of the {@link
+ * java.nio.charset.Charset#availableCharsets Charset.availableCharsets}
+ * method.
+ *
+ * @return The new iterator
+ */
+ public abstract Iterator<Charset> charsets();
+
+ /**
+ * Retrieves a charset for the given charset name.
+ *
+ * @param charsetName
+ * The name of the requested charset; may be either
+ * a canonical name or an alias
+ *
+ * @return A charset object for the named charset,
+ * or <tt>null</tt> if the named charset
+ * is not supported by this provider
+ */
+ public abstract Charset charsetForName(String charsetName);
+
+}
diff --git a/java/nio/file/AccessDeniedException.java b/java/nio/file/AccessDeniedException.java
new file mode 100644
index 0000000..43b3862
--- /dev/null
+++ b/java/nio/file/AccessDeniedException.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Checked exception thrown when a file system operation is denied, typically
+ * due to a file permission or other access check.
+ *
+ * <p> This exception is not related to the {@link
+ * java.security.AccessControlException AccessControlException} or {@link
+ * SecurityException} thrown by access controllers or security managers when
+ * access to a file is denied.
+ *
+ * @since 1.7
+ */
+
+public class AccessDeniedException
+ extends FileSystemException
+{
+ private static final long serialVersionUID = 4943049599949219617L;
+
+ /**
+ * Constructs an instance of this class.
+ *
+ * @param file
+ * a string identifying the file or {@code null} if not known
+ */
+ public AccessDeniedException(String file) {
+ super(file);
+ }
+
+ /**
+ * Constructs an instance of this class.
+ *
+ * @param file
+ * a string identifying the file or {@code null} if not known
+ * @param other
+ * a string identifying the other file or {@code null} if not known
+ * @param reason
+ * a reason message with additional information or {@code null}
+ */
+ public AccessDeniedException(String file, String other, String reason) {
+ super(file, other, reason);
+ }
+}
diff --git a/java/nio/file/AccessMode.java b/java/nio/file/AccessMode.java
new file mode 100644
index 0000000..8816e9b
--- /dev/null
+++ b/java/nio/file/AccessMode.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Defines access modes used to test the accessibility of a file.
+ *
+ * @since 1.7
+ */
+
+public enum AccessMode {
+ /**
+ * Test read access.
+ */
+ READ,
+ /**
+ * Test write access.
+ */
+ WRITE,
+ /**
+ * Test execute access.
+ */
+ EXECUTE;
+}
diff --git a/java/nio/file/AtomicMoveNotSupportedException.java b/java/nio/file/AtomicMoveNotSupportedException.java
new file mode 100644
index 0000000..27947c3
--- /dev/null
+++ b/java/nio/file/AtomicMoveNotSupportedException.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Checked exception thrown when a file cannot be moved as an atomic file system
+ * operation.
+ *
+ * @since 1.7
+ */
+
+public class AtomicMoveNotSupportedException
+ extends FileSystemException
+{
+ static final long serialVersionUID = 5402760225333135579L;
+
+ /**
+ * Constructs an instance of this class.
+ *
+ * @param source
+ * a string identifying the source file or {@code null} if not known
+ * @param target
+ * a string identifying the target file or {@code null} if not known
+ * @param reason
+ * a reason message with additional information
+ */
+ public AtomicMoveNotSupportedException(String source,
+ String target,
+ String reason)
+ {
+ super(source, target, reason);
+ }
+}
diff --git a/java/nio/file/ClosedDirectoryStreamException.java b/java/nio/file/ClosedDirectoryStreamException.java
new file mode 100644
index 0000000..aa1e0ce
--- /dev/null
+++ b/java/nio/file/ClosedDirectoryStreamException.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Unchecked exception thrown when an attempt is made to invoke an operation on
+ * a directory stream that is closed.
+ *
+ * @since 1.7
+ */
+
+public class ClosedDirectoryStreamException
+ extends IllegalStateException
+{
+ static final long serialVersionUID = 4228386650900895400L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public ClosedDirectoryStreamException() {
+ }
+}
diff --git a/java/nio/file/ClosedFileSystemException.java b/java/nio/file/ClosedFileSystemException.java
new file mode 100644
index 0000000..82cf096
--- /dev/null
+++ b/java/nio/file/ClosedFileSystemException.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Unchecked exception thrown when an attempt is made to invoke an operation on
+ * a file and the file system is closed.
+ */
+
+public class ClosedFileSystemException
+ extends IllegalStateException
+{
+ static final long serialVersionUID = -8158336077256193488L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public ClosedFileSystemException() {
+ }
+}
diff --git a/java/nio/file/ClosedWatchServiceException.java b/java/nio/file/ClosedWatchServiceException.java
new file mode 100644
index 0000000..3995b6d
--- /dev/null
+++ b/java/nio/file/ClosedWatchServiceException.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Unchecked exception thrown when an attempt is made to invoke an operation on
+ * a watch service that is closed.
+ */
+
+public class ClosedWatchServiceException
+ extends IllegalStateException
+{
+ static final long serialVersionUID = 1853336266231677732L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public ClosedWatchServiceException() {
+ }
+}
diff --git a/java/nio/file/CopyMoveHelper.java b/java/nio/file/CopyMoveHelper.java
new file mode 100644
index 0000000..ab92818
--- /dev/null
+++ b/java/nio/file/CopyMoveHelper.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+import java.nio.file.attribute.*;
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * Helper class to support copying or moving files when the source and target
+ * are associated with different providers.
+ */
+
+class CopyMoveHelper {
+ private CopyMoveHelper() { }
+
+ /**
+ * Parses the arguments for a file copy operation.
+ */
+ private static class CopyOptions {
+ boolean replaceExisting = false;
+ boolean copyAttributes = false;
+ boolean followLinks = true;
+
+ private CopyOptions() { }
+
+ static CopyOptions parse(CopyOption... options) {
+ CopyOptions result = new CopyOptions();
+ for (CopyOption option: options) {
+ if (option == StandardCopyOption.REPLACE_EXISTING) {
+ result.replaceExisting = true;
+ continue;
+ }
+ if (option == LinkOption.NOFOLLOW_LINKS) {
+ result.followLinks = false;
+ continue;
+ }
+ if (option == StandardCopyOption.COPY_ATTRIBUTES) {
+ result.copyAttributes = true;
+ continue;
+ }
+ if (option == null)
+ throw new NullPointerException();
+ throw new UnsupportedOperationException("'" + option +
+ "' is not a recognized copy option");
+ }
+ return result;
+ }
+ }
+
+ /**
+ * Converts the given array of options for moving a file to options suitable
+ * for copying the file when a move is implemented as copy + delete.
+ */
+ private static CopyOption[] convertMoveToCopyOptions(CopyOption... options)
+ throws AtomicMoveNotSupportedException
+ {
+ int len = options.length;
+ CopyOption[] newOptions = new CopyOption[len+2];
+ for (int i=0; i<len; i++) {
+ CopyOption option = options[i];
+ if (option == StandardCopyOption.ATOMIC_MOVE) {
+ throw new AtomicMoveNotSupportedException(null, null,
+ "Atomic move between providers is not supported");
+ }
+ newOptions[i] = option;
+ }
+ newOptions[len] = LinkOption.NOFOLLOW_LINKS;
+ newOptions[len+1] = StandardCopyOption.COPY_ATTRIBUTES;
+ return newOptions;
+ }
+
+ /**
+ * Simple copy for use when source and target are associated with different
+ * providers
+ */
+ static void copyToForeignTarget(Path source, Path target,
+ CopyOption... options)
+ throws IOException
+ {
+ CopyOptions opts = CopyOptions.parse(options);
+ LinkOption[] linkOptions = (opts.followLinks) ? new LinkOption[0] :
+ new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
+
+ // attributes of source file
+ BasicFileAttributes attrs = Files.readAttributes(source,
+ BasicFileAttributes.class,
+ linkOptions);
+ if (attrs.isSymbolicLink())
+ throw new IOException("Copying of symbolic links not supported");
+
+ // delete target if it exists and REPLACE_EXISTING is specified
+ if (opts.replaceExisting) {
+ Files.deleteIfExists(target);
+ } else if (Files.exists(target))
+ throw new FileAlreadyExistsException(target.toString());
+
+ // create directory or copy file
+ if (attrs.isDirectory()) {
+ Files.createDirectory(target);
+ } else {
+ try (InputStream in = Files.newInputStream(source)) {
+ Files.copy(in, target);
+ }
+ }
+
+ // copy basic attributes to target
+ if (opts.copyAttributes) {
+ BasicFileAttributeView view =
+ Files.getFileAttributeView(target, BasicFileAttributeView.class);
+ try {
+ view.setTimes(attrs.lastModifiedTime(),
+ attrs.lastAccessTime(),
+ attrs.creationTime());
+ } catch (Throwable x) {
+ // rollback
+ try {
+ Files.delete(target);
+ } catch (Throwable suppressed) {
+ x.addSuppressed(suppressed);
+ }
+ throw x;
+ }
+ }
+ }
+
+ /**
+ * Simple move implements as copy+delete for use when source and target are
+ * associated with different providers
+ */
+ static void moveToForeignTarget(Path source, Path target,
+ CopyOption... options) throws IOException
+ {
+ copyToForeignTarget(source, target, convertMoveToCopyOptions(options));
+ Files.delete(source);
+ }
+}
diff --git a/java/nio/file/CopyOption.java b/java/nio/file/CopyOption.java
new file mode 100644
index 0000000..e70bf95
--- /dev/null
+++ b/java/nio/file/CopyOption.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * An object that configures how to copy or move a file.
+ *
+ * <p> Objects of this type may be used with the {@link
+ * Files#copy(Path,Path,CopyOption[]) Files.copy(Path,Path,CopyOption...)},
+ * {@link Files#copy(java.io.InputStream,Path,CopyOption[])
+ * Files.copy(InputStream,Path,CopyOption...)} and {@link Files#move
+ * Files.move(Path,Path,CopyOption...)} methods to configure how a file is
+ * copied or moved.
+ *
+ * <p> The {@link StandardCopyOption} enumeration type defines the
+ * <i>standard</i> options.
+ *
+ * @since 1.7
+ */
+
+public interface CopyOption {
+}
diff --git a/java/nio/file/DirectoryIteratorException.java b/java/nio/file/DirectoryIteratorException.java
new file mode 100644
index 0000000..4f5a551
--- /dev/null
+++ b/java/nio/file/DirectoryIteratorException.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+import java.util.ConcurrentModificationException;
+import java.util.Objects;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.InvalidObjectException;
+
+/**
+ * Runtime exception thrown if an I/O error is encountered when iterating over
+ * the entries in a directory. The I/O error is retrieved as an {@link
+ * IOException} using the {@link #getCause() getCause()} method.
+ *
+ * @since 1.7
+ * @see DirectoryStream
+ */
+
+public final class DirectoryIteratorException
+ extends ConcurrentModificationException
+{
+ private static final long serialVersionUID = -6012699886086212874L;
+
+ /**
+ * Constructs an instance of this class.
+ *
+ * @param cause
+ * the {@code IOException} that caused the directory iteration
+ * to fail
+ *
+ * @throws NullPointerException
+ * if the cause is {@code null}
+ */
+ public DirectoryIteratorException(IOException cause) {
+ super(Objects.requireNonNull(cause));
+ }
+
+ /**
+ * Returns the cause of this exception.
+ *
+ * @return the cause
+ */
+ @Override
+ public IOException getCause() {
+ return (IOException)super.getCause();
+ }
+
+ /**
+ * Called to read the object from a stream.
+ *
+ * @throws InvalidObjectException
+ * if the object is invalid or has a cause that is not
+ * an {@code IOException}
+ */
+ private void readObject(ObjectInputStream s)
+ throws IOException, ClassNotFoundException
+ {
+ s.defaultReadObject();
+ Throwable cause = super.getCause();
+ if (!(cause instanceof IOException))
+ throw new InvalidObjectException("Cause must be an IOException");
+ }
+}
diff --git a/java/nio/file/DirectoryNotEmptyException.java b/java/nio/file/DirectoryNotEmptyException.java
new file mode 100644
index 0000000..7ae9080
--- /dev/null
+++ b/java/nio/file/DirectoryNotEmptyException.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Checked exception thrown when a file system operation fails because a
+ * directory is not empty.
+ *
+ * @since 1.7
+ */
+
+public class DirectoryNotEmptyException
+ extends FileSystemException
+{
+ static final long serialVersionUID = 3056667871802779003L;
+
+ /**
+ * Constructs an instance of this class.
+ *
+ * @param dir
+ * a string identifying the directory or {@code null} if not known
+ */
+ public DirectoryNotEmptyException(String dir) {
+ super(dir);
+ }
+}
diff --git a/java/nio/file/DirectoryStream.java b/java/nio/file/DirectoryStream.java
new file mode 100644
index 0000000..48da97e
--- /dev/null
+++ b/java/nio/file/DirectoryStream.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+import java.util.Iterator;
+import java.io.Closeable;
+import java.io.IOException;
+
+/**
+ * An object to iterate over the entries in a directory. A directory stream
+ * allows for the convenient use of the for-each construct to iterate over a
+ * directory.
+ *
+ * <p> <b> While {@code DirectoryStream} extends {@code Iterable}, it is not a
+ * general-purpose {@code Iterable} as it supports only a single {@code
+ * Iterator}; invoking the {@link #iterator iterator} method to obtain a second
+ * or subsequent iterator throws {@code IllegalStateException}. </b>
+ *
+ * <p> An important property of the directory stream's {@code Iterator} is that
+ * its {@link Iterator#hasNext() hasNext} method is guaranteed to read-ahead by
+ * at least one element. If {@code hasNext} method returns {@code true}, and is
+ * followed by a call to the {@code next} method, it is guaranteed that the
+ * {@code next} method will not throw an exception due to an I/O error, or
+ * because the stream has been {@link #close closed}. The {@code Iterator} does
+ * not support the {@link Iterator#remove remove} operation.
+ *
+ * <p> A {@code DirectoryStream} is opened upon creation and is closed by
+ * invoking the {@code close} method. Closing a directory stream releases any
+ * resources associated with the stream. Failure to close the stream may result
+ * in a resource leak. The try-with-resources statement provides a useful
+ * construct to ensure that the stream is closed:
+ * <pre>
+ * Path dir = ...
+ * try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
+ * for (Path entry: stream) {
+ * ...
+ * }
+ * }
+ * </pre>
+ *
+ * <p> Once a directory stream is closed, then further access to the directory,
+ * using the {@code Iterator}, behaves as if the end of stream has been reached.
+ * Due to read-ahead, the {@code Iterator} may return one or more elements
+ * after the directory stream has been closed. Once these buffered elements
+ * have been read, then subsequent calls to the {@code hasNext} method returns
+ * {@code false}, and subsequent calls to the {@code next} method will throw
+ * {@code NoSuchElementException}.
+ *
+ * <p> A directory stream is not required to be <i>asynchronously closeable</i>.
+ * If a thread is blocked on the directory stream's iterator reading from the
+ * directory, and another thread invokes the {@code close} method, then the
+ * second thread may block until the read operation is complete.
+ *
+ * <p> If an I/O error is encountered when accessing the directory then it
+ * causes the {@code Iterator}'s {@code hasNext} or {@code next} methods to
+ * throw {@link DirectoryIteratorException} with the {@link IOException} as the
+ * cause. As stated above, the {@code hasNext} method is guaranteed to
+ * read-ahead by at least one element. This means that if {@code hasNext} method
+ * returns {@code true}, and is followed by a call to the {@code next} method,
+ * then it is guaranteed that the {@code next} method will not fail with a
+ * {@code DirectoryIteratorException}.
+ *
+ * <p> The elements returned by the iterator are in no specific order. Some file
+ * systems maintain special links to the directory itself and the directory's
+ * parent directory. Entries representing these links are not returned by the
+ * iterator.
+ *
+ * <p> The iterator is <i>weakly consistent</i>. It is thread safe but does not
+ * freeze the directory while iterating, so it may (or may not) reflect updates
+ * to the directory that occur after the {@code DirectoryStream} is created.
+ *
+ * <p> <b>Usage Examples:</b>
+ * Suppose we want a list of the source files in a directory. This example uses
+ * both the for-each and try-with-resources constructs.
+ * <pre>
+ * List<Path> listSourceFiles(Path dir) throws IOException {
+ * List<Path> result = new ArrayList<>();
+ * try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "*.{c,h,cpp,hpp,java}")) {
+ * for (Path entry: stream) {
+ * result.add(entry);
+ * }
+ * } catch (DirectoryIteratorException ex) {
+ * // I/O error encounted during the iteration, the cause is an IOException
+ * throw ex.getCause();
+ * }
+ * return result;
+ * }
+ * </pre>
+ * @param <T> The type of element returned by the iterator
+ *
+ * @since 1.7
+ *
+ * @see Files#newDirectoryStream(Path)
+ */
+
+public interface DirectoryStream<T>
+ extends Closeable, Iterable<T> {
+ /**
+ * An interface that is implemented by objects that decide if a directory
+ * entry should be accepted or filtered. A {@code Filter} is passed as the
+ * parameter to the {@link Files#newDirectoryStream(Path,DirectoryStream.Filter)}
+ * method when opening a directory to iterate over the entries in the
+ * directory.
+ *
+ * @param <T> the type of the directory entry
+ *
+ * @since 1.7
+ */
+ @FunctionalInterface
+ public static interface Filter<T> {
+ /**
+ * Decides if the given directory entry should be accepted or filtered.
+ *
+ * @param entry
+ * the directory entry to be tested
+ *
+ * @return {@code true} if the directory entry should be accepted
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ boolean accept(T entry) throws IOException;
+ }
+
+ /**
+ * Returns the iterator associated with this {@code DirectoryStream}.
+ *
+ * @return the iterator associated with this {@code DirectoryStream}
+ *
+ * @throws IllegalStateException
+ * if this directory stream is closed or the iterator has already
+ * been returned
+ */
+ @Override
+ Iterator<T> iterator();
+}
diff --git a/java/nio/file/FileAlreadyExistsException.java b/java/nio/file/FileAlreadyExistsException.java
new file mode 100644
index 0000000..14496a1
--- /dev/null
+++ b/java/nio/file/FileAlreadyExistsException.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Checked exception thrown when an attempt is made to create a file or
+ * directory and a file of that name already exists.
+ *
+ * @since 1.7
+ */
+
+public class FileAlreadyExistsException
+ extends FileSystemException
+{
+ static final long serialVersionUID = 7579540934498831181L;
+
+ /**
+ * Constructs an instance of this class.
+ *
+ * @param file
+ * a string identifying the file or {@code null} if not known
+ */
+ public FileAlreadyExistsException(String file) {
+ super(file);
+ }
+
+ /**
+ * Constructs an instance of this class.
+ *
+ * @param file
+ * a string identifying the file or {@code null} if not known
+ * @param other
+ * a string identifying the other file or {@code null} if not known
+ * @param reason
+ * a reason message with additional information or {@code null}
+ */
+ public FileAlreadyExistsException(String file, String other, String reason) {
+ super(file, other, reason);
+ }
+}
diff --git a/java/nio/file/FileStore.java b/java/nio/file/FileStore.java
new file mode 100644
index 0000000..2b14a4b
--- /dev/null
+++ b/java/nio/file/FileStore.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+import java.nio.file.attribute.*;
+import java.io.IOException;
+
+/**
+ * Storage for files. A {@code FileStore} represents a storage pool, device,
+ * partition, volume, concrete file system or other implementation specific means
+ * of file storage. The {@code FileStore} for where a file is stored is obtained
+ * by invoking the {@link Files#getFileStore getFileStore} method, or all file
+ * stores can be enumerated by invoking the {@link FileSystem#getFileStores
+ * getFileStores} method.
+ *
+ * <p> In addition to the methods defined by this class, a file store may support
+ * one or more {@link FileStoreAttributeView FileStoreAttributeView} classes
+ * that provide a read-only or updatable view of a set of file store attributes.
+ *
+ * @since 1.7
+ */
+
+public abstract class FileStore {
+
+ /**
+ * Initializes a new instance of this class.
+ */
+ protected FileStore() {
+ }
+
+ /**
+ * Returns the name of this file store. The format of the name is highly
+ * implementation specific. It will typically be the name of the storage
+ * pool or volume.
+ *
+ * <p> The string returned by this method may differ from the string
+ * returned by the {@link Object#toString() toString} method.
+ *
+ * @return the name of this file store
+ */
+ public abstract String name();
+
+ /**
+ * Returns the <em>type</em> of this file store. The format of the string
+ * returned by this method is highly implementation specific. It may
+ * indicate, for example, the format used or if the file store is local
+ * or remote.
+ *
+ * @return a string representing the type of this file store
+ */
+ public abstract String type();
+
+ /**
+ * Tells whether this file store is read-only. A file store is read-only if
+ * it does not support write operations or other changes to files. Any
+ * attempt to create a file, open an existing file for writing etc. causes
+ * an {@code IOException} to be thrown.
+ *
+ * @return {@code true} if, and only if, this file store is read-only
+ */
+ public abstract boolean isReadOnly();
+
+ /**
+ * Returns the size, in bytes, of the file store.
+ *
+ * @return the size of the file store, in bytes
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ public abstract long getTotalSpace() throws IOException;
+
+ /**
+ * Returns the number of bytes available to this Java virtual machine on the
+ * file store.
+ *
+ * <p> The returned number of available bytes is a hint, but not a
+ * guarantee, that it is possible to use most or any of these bytes. The
+ * number of usable bytes is most likely to be accurate immediately
+ * after the space attributes are obtained. It is likely to be made inaccurate
+ * by any external I/O operations including those made on the system outside
+ * of this Java virtual machine.
+ *
+ * @return the number of bytes available
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ public abstract long getUsableSpace() throws IOException;
+
+ /**
+ * Returns the number of unallocated bytes in the file store.
+ *
+ * <p> The returned number of unallocated bytes is a hint, but not a
+ * guarantee, that it is possible to use most or any of these bytes. The
+ * number of unallocated bytes is most likely to be accurate immediately
+ * after the space attributes are obtained. It is likely to be
+ * made inaccurate by any external I/O operations including those made on
+ * the system outside of this virtual machine.
+ *
+ * @return the number of unallocated bytes
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ public abstract long getUnallocatedSpace() throws IOException;
+
+ /**
+ * Tells whether or not this file store supports the file attributes
+ * identified by the given file attribute view.
+ *
+ * <p> Invoking this method to test if the file store supports {@link
+ * BasicFileAttributeView} will always return {@code true}. In the case of
+ * the default provider, this method cannot guarantee to give the correct
+ * result when the file store is not a local storage device. The reasons for
+ * this are implementation specific and therefore unspecified.
+ *
+ * @param type
+ * the file attribute view type
+ *
+ * @return {@code true} if, and only if, the file attribute view is
+ * supported
+ */
+ public abstract boolean supportsFileAttributeView(Class<? extends FileAttributeView> type);
+
+ /**
+ * Tells whether or not this file store supports the file attributes
+ * identified by the given file attribute view.
+ *
+ * <p> Invoking this method to test if the file store supports {@link
+ * BasicFileAttributeView}, identified by the name "{@code basic}" will
+ * always return {@code true}. In the case of the default provider, this
+ * method cannot guarantee to give the correct result when the file store is
+ * not a local storage device. The reasons for this are implementation
+ * specific and therefore unspecified.
+ *
+ * @param name
+ * the {@link FileAttributeView#name name} of file attribute view
+ *
+ * @return {@code true} if, and only if, the file attribute view is
+ * supported
+ */
+ public abstract boolean supportsFileAttributeView(String name);
+
+ /**
+ * Returns a {@code FileStoreAttributeView} of the given type.
+ *
+ * <p> This method is intended to be used where the file store attribute
+ * view defines type-safe methods to read or update the file store attributes.
+ * The {@code type} parameter is the type of the attribute view required and
+ * the method returns an instance of that type if supported.
+ *
+ * @param <V>
+ * The {@code FileStoreAttributeView} type
+ * @param type
+ * the {@code Class} object corresponding to the attribute view
+ *
+ * @return a file store attribute view of the specified type or
+ * {@code null} if the attribute view is not available
+ */
+ public abstract <V extends FileStoreAttributeView> V
+ getFileStoreAttributeView(Class<V> type);
+
+ /**
+ * Reads the value of a file store attribute.
+ *
+ * <p> The {@code attribute} parameter identifies the attribute to be read
+ * and takes the form:
+ * <blockquote>
+ * <i>view-name</i><b>:</b><i>attribute-name</i>
+ * </blockquote>
+ * where the character {@code ':'} stands for itself.
+ *
+ * <p> <i>view-name</i> is the {@link FileStoreAttributeView#name name} of
+ * a {@link FileStore AttributeView} that identifies a set of file attributes.
+ * <i>attribute-name</i> is the name of the attribute.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to know if ZFS compression is enabled (assuming the "zfs"
+ * view is supported):
+ * <pre>
+ * boolean compression = (Boolean)fs.getAttribute("zfs:compression");
+ * </pre>
+ *
+ * @param attribute
+ * the attribute to read
+
+ * @return the attribute value; {@code null} may be a valid valid for some
+ * attributes
+ *
+ * @throws UnsupportedOperationException
+ * if the attribute view is not available or it does not support
+ * reading the attribute
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ public abstract Object getAttribute(String attribute) throws IOException;
+}
diff --git a/java/nio/file/FileSystem.java b/java/nio/file/FileSystem.java
new file mode 100644
index 0000000..755d64f
--- /dev/null
+++ b/java/nio/file/FileSystem.java
@@ -0,0 +1,463 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+import java.nio.file.attribute.*;
+import java.nio.file.spi.FileSystemProvider;
+import java.util.Set;
+import java.io.Closeable;
+import java.io.IOException;
+
+/**
+ * Provides an interface to a file system and is the factory for objects to
+ * access files and other objects in the file system.
+ *
+ * <p> The default file system, obtained by invoking the {@link FileSystems#getDefault
+ * FileSystems.getDefault} method, provides access to the file system that is
+ * accessible to the Java virtual machine. The {@link FileSystems} class defines
+ * methods to create file systems that provide access to other types of (custom)
+ * file systems.
+ *
+ * <p> A file system is the factory for several types of objects:
+ *
+ * <ul>
+ * <li><p> The {@link #getPath getPath} method converts a system dependent
+ * <em>path string</em>, returning a {@link Path} object that may be used
+ * to locate and access a file. </p></li>
+ * <li><p> The {@link #getPathMatcher getPathMatcher} method is used
+ * to create a {@link PathMatcher} that performs match operations on
+ * paths. </p></li>
+ * <li><p> The {@link #getFileStores getFileStores} method returns an iterator
+ * over the underlying {@link FileStore file-stores}. </p></li>
+ * <li><p> The {@link #getUserPrincipalLookupService getUserPrincipalLookupService}
+ * method returns the {@link UserPrincipalLookupService} to lookup users or
+ * groups by name. </p></li>
+ * <li><p> The {@link #newWatchService newWatchService} method creates a
+ * {@link WatchService} that may be used to watch objects for changes and
+ * events. </p></li>
+ * </ul>
+ *
+ * <p> File systems vary greatly. In some cases the file system is a single
+ * hierarchy of files with one top-level root directory. In other cases it may
+ * have several distinct file hierarchies, each with its own top-level root
+ * directory. The {@link #getRootDirectories getRootDirectories} method may be
+ * used to iterate over the root directories in the file system. A file system
+ * is typically composed of one or more underlying {@link FileStore file-stores}
+ * that provide the storage for the files. Theses file stores can also vary in
+ * the features they support, and the file attributes or <em>meta-data</em> that
+ * they associate with files.
+ *
+ * <p> A file system is open upon creation and can be closed by invoking its
+ * {@link #close() close} method. Once closed, any further attempt to access
+ * objects in the file system cause {@link ClosedFileSystemException} to be
+ * thrown. File systems created by the default {@link FileSystemProvider provider}
+ * cannot be closed.
+ *
+ * <p> A {@code FileSystem} can provide read-only or read-write access to the
+ * file system. Whether or not a file system provides read-only access is
+ * established when the {@code FileSystem} is created and can be tested by invoking
+ * its {@link #isReadOnly() isReadOnly} method. Attempts to write to file stores
+ * by means of an object associated with a read-only file system throws {@link
+ * ReadOnlyFileSystemException}.
+ *
+ * <p> File systems are safe for use by multiple concurrent threads. The {@link
+ * #close close} method may be invoked at any time to close a file system but
+ * whether a file system is <i>asynchronously closeable</i> is provider specific
+ * and therefore unspecified. In other words, if a thread is accessing an
+ * object in a file system, and another thread invokes the {@code close} method
+ * then it may require to block until the first operation is complete. Closing
+ * a file system causes all open channels, watch services, and other {@link
+ * Closeable closeable} objects associated with the file system to be closed.
+ *
+ * @since 1.7
+ */
+
+public abstract class FileSystem
+ implements Closeable
+{
+ /**
+ * Initializes a new instance of this class.
+ */
+ protected FileSystem() {
+ }
+
+ /**
+ * Returns the provider that created this file system.
+ *
+ * @return The provider that created this file system.
+ */
+ public abstract FileSystemProvider provider();
+
+ /**
+ * Closes this file system.
+ *
+ * <p> After a file system is closed then all subsequent access to the file
+ * system, either by methods defined by this class or on objects associated
+ * with this file system, throw {@link ClosedFileSystemException}. If the
+ * file system is already closed then invoking this method has no effect.
+ *
+ * <p> Closing a file system will close all open {@link
+ * java.nio.channels.Channel channels}, {@link DirectoryStream directory-streams},
+ * {@link WatchService watch-service}, and other closeable objects associated
+ * with this file system. The {@link FileSystems#getDefault default} file
+ * system cannot be closed.
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ * @throws UnsupportedOperationException
+ * Thrown in the case of the default file system
+ */
+ @Override
+ public abstract void close() throws IOException;
+
+ /**
+ * Tells whether or not this file system is open.
+ *
+ * <p> File systems created by the default provider are always open.
+ *
+ * @return {@code true} if, and only if, this file system is open
+ */
+ public abstract boolean isOpen();
+
+ /**
+ * Tells whether or not this file system allows only read-only access to
+ * its file stores.
+ *
+ * @return {@code true} if, and only if, this file system provides
+ * read-only access
+ */
+ public abstract boolean isReadOnly();
+
+ /**
+ * Returns the name separator, represented as a string.
+ *
+ * <p> The name separator is used to separate names in a path string. An
+ * implementation may support multiple name separators in which case this
+ * method returns an implementation specific <em>default</em> name separator.
+ * This separator is used when creating path strings by invoking the {@link
+ * Path#toString() toString()} method.
+ *
+ * <p> In the case of the default provider, this method returns the same
+ * separator as {@link java.io.File#separator}.
+ *
+ * @return The name separator
+ */
+ public abstract String getSeparator();
+
+ /**
+ * Returns an object to iterate over the paths of the root directories.
+ *
+ * <p> A file system provides access to a file store that may be composed
+ * of a number of distinct file hierarchies, each with its own top-level
+ * root directory. Unless denied by the security manager, each element in
+ * the returned iterator corresponds to the root directory of a distinct
+ * file hierarchy. The order of the elements is not defined. The file
+ * hierarchies may change during the lifetime of the Java virtual machine.
+ * For example, in some implementations, the insertion of removable media
+ * may result in the creation of a new file hierarchy with its own
+ * top-level directory.
+ *
+ * <p> When a security manager is installed, it is invoked to check access
+ * to the each root directory. If denied, the root directory is not returned
+ * by the iterator. In the case of the default provider, the {@link
+ * SecurityManager#checkRead(String)} method is invoked to check read access
+ * to each root directory. It is system dependent if the permission checks
+ * are done when the iterator is obtained or during iteration.
+ *
+ * @return An object to iterate over the root directories
+ */
+ public abstract Iterable<Path> getRootDirectories();
+
+ /**
+ * Returns an object to iterate over the underlying file stores.
+ *
+ * <p> The elements of the returned iterator are the {@link
+ * FileStore FileStores} for this file system. The order of the elements is
+ * not defined and the file stores may change during the lifetime of the
+ * Java virtual machine. When an I/O error occurs, perhaps because a file
+ * store is not accessible, then it is not returned by the iterator.
+ *
+ * <p> In the case of the default provider, and a security manager is
+ * installed, the security manager is invoked to check {@link
+ * RuntimePermission}<tt>("getFileStoreAttributes")</tt>. If denied, then
+ * no file stores are returned by the iterator. In addition, the security
+ * manager's {@link SecurityManager#checkRead(String)} method is invoked to
+ * check read access to the file store's <em>top-most</em> directory. If
+ * denied, the file store is not returned by the iterator. It is system
+ * dependent if the permission checks are done when the iterator is obtained
+ * or during iteration.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to print the space usage for all file stores:
+ * <pre>
+ * for (FileStore store: FileSystems.getDefault().getFileStores()) {
+ * long total = store.getTotalSpace() / 1024;
+ * long used = (store.getTotalSpace() - store.getUnallocatedSpace()) / 1024;
+ * long avail = store.getUsableSpace() / 1024;
+ * System.out.format("%-20s %12d %12d %12d%n", store, total, used, avail);
+ * }
+ * </pre>
+ *
+ * @return An object to iterate over the backing file stores
+ */
+ public abstract Iterable<FileStore> getFileStores();
+
+ /**
+ * Returns the set of the {@link FileAttributeView#name names} of the file
+ * attribute views supported by this {@code FileSystem}.
+ *
+ * <p> The {@link BasicFileAttributeView} is required to be supported and
+ * therefore the set contains at least one element, "basic".
+ *
+ * <p> The {@link FileStore#supportsFileAttributeView(String)
+ * supportsFileAttributeView(String)} method may be used to test if an
+ * underlying {@link FileStore} supports the file attributes identified by a
+ * file attribute view.
+ *
+ * @return An unmodifiable set of the names of the supported file attribute
+ * views
+ */
+ public abstract Set<String> supportedFileAttributeViews();
+
+ /**
+ * Converts a path string, or a sequence of strings that when joined form
+ * a path string, to a {@code Path}. If {@code more} does not specify any
+ * elements then the value of the {@code first} parameter is the path string
+ * to convert. If {@code more} specifies one or more elements then each
+ * non-empty string, including {@code first}, is considered to be a sequence
+ * of name elements (see {@link Path}) and is joined to form a path string.
+ * The details as to how the Strings are joined is provider specific but
+ * typically they will be joined using the {@link #getSeparator
+ * name-separator} as the separator. For example, if the name separator is
+ * "{@code /}" and {@code getPath("/foo","bar","gus")} is invoked, then the
+ * path string {@code "/foo/bar/gus"} is converted to a {@code Path}.
+ * A {@code Path} representing an empty path is returned if {@code first}
+ * is the empty string and {@code more} does not contain any non-empty
+ * strings.
+ *
+ * <p> The parsing and conversion to a path object is inherently
+ * implementation dependent. In the simplest case, the path string is rejected,
+ * and {@link InvalidPathException} thrown, if the path string contains
+ * characters that cannot be converted to characters that are <em>legal</em>
+ * to the file store. For example, on UNIX systems, the NUL (\u0000)
+ * character is not allowed to be present in a path. An implementation may
+ * choose to reject path strings that contain names that are longer than those
+ * allowed by any file store, and where an implementation supports a complex
+ * path syntax, it may choose to reject path strings that are <em>badly
+ * formed</em>.
+ *
+ * <p> In the case of the default provider, path strings are parsed based
+ * on the definition of paths at the platform or virtual file system level.
+ * For example, an operating system may not allow specific characters to be
+ * present in a file name, but a specific underlying file store may impose
+ * different or additional restrictions on the set of legal
+ * characters.
+ *
+ * <p> This method throws {@link InvalidPathException} when the path string
+ * cannot be converted to a path. Where possible, and where applicable,
+ * the exception is created with an {@link InvalidPathException#getIndex
+ * index} value indicating the first position in the {@code path} parameter
+ * that caused the path string to be rejected.
+ *
+ * @param first
+ * the path string or initial part of the path string
+ * @param more
+ * additional strings to be joined to form the path string
+ *
+ * @return the resulting {@code Path}
+ *
+ * @throws InvalidPathException
+ * If the path string cannot be converted
+ */
+ public abstract Path getPath(String first, String... more);
+
+ // Android-changed: Removed javadoc references to UNIX and Windows.
+ /**
+ * Returns a {@code PathMatcher} that performs match operations on the
+ * {@code String} representation of {@link Path} objects by interpreting a
+ * given pattern.
+ *
+ * The {@code syntaxAndPattern} parameter identifies the syntax and the
+ * pattern and takes the form:
+ * <blockquote><pre>
+ * <i>syntax</i><b>:</b><i>pattern</i>
+ * </pre></blockquote>
+ * where {@code ':'} stands for itself.
+ *
+ * <p> A {@code FileSystem} implementation supports the "{@code glob}" and
+ * "{@code regex}" syntaxes, and may support others. The value of the syntax
+ * component is compared without regard to case.
+ *
+ * <p> When the syntax is "{@code glob}" then the {@code String}
+ * representation of the path is matched using a limited pattern language
+ * that resembles regular expressions but with a simpler syntax. For example:
+ *
+ * <blockquote>
+ * <table border="0" summary="Pattern Language">
+ * <tr>
+ * <td>{@code *.java}</td>
+ * <td>Matches a path that represents a file name ending in {@code .java}</td>
+ * </tr>
+ * <tr>
+ * <td>{@code *.*}</td>
+ * <td>Matches file names containing a dot</td>
+ * </tr>
+ * <tr>
+ * <td>{@code *.{java,class}}</td>
+ * <td>Matches file names ending with {@code .java} or {@code .class}</td>
+ * </tr>
+ * <tr>
+ * <td>{@code foo.?}</td>
+ * <td>Matches file names starting with {@code foo.} and a single
+ * character extension</td>
+ * </tr>
+ * <tr>
+ * <td><tt>/home/*/*</tt>
+ * <td>Matches <tt>/home/gus/data</tt></td>
+ * </tr>
+ * <tr>
+ * <td><tt>/home/**</tt>
+ * <td>Matches <tt>/home/gus</tt> and
+ * <tt>/home/gus/data</tt></td>
+ * </tr>
+ *
+ * </table>
+ * </blockquote>
+ *
+ * <p> The following rules are used to interpret glob patterns:
+ *
+ * <ul>
+ * <li><p> The {@code *} character matches zero or more {@link Character
+ * characters} of a {@link Path#getName(int) name} component without
+ * crossing directory boundaries. </p></li>
+ *
+ * <li><p> The {@code **} characters matches zero or more {@link Character
+ * characters} crossing directory boundaries. </p></li>
+ *
+ * <li><p> The {@code ?} character matches exactly one character of a
+ * name component.</p></li>
+ *
+ * <li><p> The backslash character ({@code \}) is used to escape characters
+ * that would otherwise be interpreted as special characters. The expression
+ * {@code \\} matches a single backslash and "\{" matches a left brace
+ * for example. </p></li>
+ *
+ * <li><p> The {@code [ ]} characters are a <i>bracket expression</i> that
+ * match a single character of a name component out of a set of characters.
+ * For example, {@code [abc]} matches {@code "a"}, {@code "b"}, or {@code "c"}.
+ * The hyphen ({@code -}) may be used to specify a range so {@code [a-z]}
+ * specifies a range that matches from {@code "a"} to {@code "z"} (inclusive).
+ * These forms can be mixed so [abce-g] matches {@code "a"}, {@code "b"},
+ * {@code "c"}, {@code "e"}, {@code "f"} or {@code "g"}. If the character
+ * after the {@code [} is a {@code !} then it is used for negation so {@code
+ * [!a-c]} matches any character except {@code "a"}, {@code "b"}, or {@code
+ * "c"}.
+ * <p> Within a bracket expression the {@code *}, {@code ?} and {@code \}
+ * characters match themselves. The ({@code -}) character matches itself if
+ * it is the first character within the brackets, or the first character
+ * after the {@code !} if negating.</p></li>
+ *
+ * <li><p> The {@code { }} characters are a group of subpatterns, where
+ * the group matches if any subpattern in the group matches. The {@code ","}
+ * character is used to separate the subpatterns. Groups cannot be nested.
+ * </p></li>
+ *
+ * <li><p> Leading period<tt>/</tt>dot characters in file name are
+ * treated as regular characters in match operations. For example,
+ * the {@code "*"} glob pattern matches file name {@code ".login"}.
+ * The {@link Files#isHidden} method may be used to test whether a file
+ * is considered hidden.
+ * </p></li>
+ *
+ * <li><p> All other characters match themselves in an implementation
+ * dependent manner. This includes characters representing any {@link
+ * FileSystem#getSeparator name-separators}. </p></li>
+ *
+ * <li><p> The matching of {@link Path#getRoot root} components is highly
+ * implementation-dependent and is not specified. </p></li>
+ *
+ * </ul>
+ *
+ * <p> When the syntax is "{@code regex}" then the pattern component is a
+ * regular expression as defined by the {@link java.util.regex.Pattern}
+ * class.
+ *
+ * <p> For both the glob and regex syntaxes, the matching details, such as
+ * whether the matching is case sensitive, are implementation-dependent
+ * and therefore not specified.
+ *
+ * @param syntaxAndPattern
+ * The syntax and pattern
+ *
+ * @return A path matcher that may be used to match paths against the pattern
+ *
+ * @throws IllegalArgumentException
+ * If the parameter does not take the form: {@code syntax:pattern}
+ * @throws java.util.regex.PatternSyntaxException
+ * If the pattern is invalid
+ * @throws UnsupportedOperationException
+ * If the pattern syntax is not known to the implementation
+ *
+ * @see Files#newDirectoryStream(Path,String)
+ */
+ public abstract PathMatcher getPathMatcher(String syntaxAndPattern);
+
+ /**
+ * Returns the {@code UserPrincipalLookupService} for this file system
+ * <i>(optional operation)</i>. The resulting lookup service may be used to
+ * lookup user or group names.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to make "joe" the owner of a file:
+ * <pre>
+ * UserPrincipalLookupService lookupService = FileSystems.getDefault().getUserPrincipalLookupService();
+ * Files.setOwner(path, lookupService.lookupPrincipalByName("joe"));
+ * </pre>
+ *
+ * @throws UnsupportedOperationException
+ * If this {@code FileSystem} does not does have a lookup service
+ *
+ * @return The {@code UserPrincipalLookupService} for this file system
+ */
+ public abstract UserPrincipalLookupService getUserPrincipalLookupService();
+
+ /**
+ * Constructs a new {@link WatchService} <i>(optional operation)</i>.
+ *
+ * <p> This method constructs a new watch service that may be used to watch
+ * registered objects for changes and events.
+ *
+ * @return a new watch service
+ *
+ * @throws UnsupportedOperationException
+ * If this {@code FileSystem} does not support watching file system
+ * objects for changes and events. This exception is not thrown
+ * by {@code FileSystems} created by the default provider.
+ * @throws IOException
+ * If an I/O error occurs
+ */
+ public abstract WatchService newWatchService() throws IOException;
+}
diff --git a/java/nio/file/FileSystemAlreadyExistsException.java b/java/nio/file/FileSystemAlreadyExistsException.java
new file mode 100644
index 0000000..e305542
--- /dev/null
+++ b/java/nio/file/FileSystemAlreadyExistsException.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Runtime exception thrown when an attempt is made to create a file system that
+ * already exists.
+ */
+
+public class FileSystemAlreadyExistsException
+ extends RuntimeException
+{
+ static final long serialVersionUID = -5438419127181131148L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public FileSystemAlreadyExistsException() {
+ }
+
+ /**
+ * Constructs an instance of this class.
+ *
+ * @param msg
+ * the detail message
+ */
+ public FileSystemAlreadyExistsException(String msg) {
+ super(msg);
+ }
+}
diff --git a/java/nio/file/FileSystemException.java b/java/nio/file/FileSystemException.java
new file mode 100644
index 0000000..b130584
--- /dev/null
+++ b/java/nio/file/FileSystemException.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+import java.io.IOException;
+
+/**
+ * Thrown when a file system operation fails on one or two files. This class is
+ * the general class for file system exceptions.
+ *
+ * @since 1.7
+ */
+
+public class FileSystemException
+ extends IOException
+{
+ static final long serialVersionUID = -3055425747967319812L;
+
+ private final String file;
+ private final String other;
+
+ /**
+ * Constructs an instance of this class. This constructor should be used
+ * when an operation involving one file fails and there isn't any additional
+ * information to explain the reason.
+ *
+ * @param file
+ * a string identifying the file or {@code null} if not known.
+ */
+ public FileSystemException(String file) {
+ super((String)null);
+ this.file = file;
+ this.other = null;
+ }
+
+ /**
+ * Constructs an instance of this class. This constructor should be used
+ * when an operation involving two files fails, or there is additional
+ * information to explain the reason.
+ *
+ * @param file
+ * a string identifying the file or {@code null} if not known.
+ * @param other
+ * a string identifying the other file or {@code null} if there
+ * isn't another file or if not known
+ * @param reason
+ * a reason message with additional information or {@code null}
+ */
+ public FileSystemException(String file, String other, String reason) {
+ super(reason);
+ this.file = file;
+ this.other = other;
+ }
+
+ /**
+ * Returns the file used to create this exception.
+ *
+ * @return the file (can be {@code null})
+ */
+ public String getFile() {
+ return file;
+ }
+
+ /**
+ * Returns the other file used to create this exception.
+ *
+ * @return the other file (can be {@code null})
+ */
+ public String getOtherFile() {
+ return other;
+ }
+
+ /**
+ * Returns the string explaining why the file system operation failed.
+ *
+ * @return the string explaining why the file system operation failed
+ */
+ public String getReason() {
+ return super.getMessage();
+ }
+
+ /**
+ * Returns the detail message string.
+ */
+ @Override
+ public String getMessage() {
+ if (file == null && other == null)
+ return getReason();
+ StringBuilder sb = new StringBuilder();
+ if (file != null)
+ sb.append(file);
+ if (other != null) {
+ sb.append(" -> ");
+ sb.append(other);
+ }
+ if (getReason() != null) {
+ sb.append(": ");
+ sb.append(getReason());
+ }
+ return sb.toString();
+ }
+}
diff --git a/java/nio/file/FileSystemLoopException.java b/java/nio/file/FileSystemLoopException.java
new file mode 100644
index 0000000..fe6beb5
--- /dev/null
+++ b/java/nio/file/FileSystemLoopException.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Checked exception thrown when a file system loop, or cycle, is encountered.
+ *
+ * @since 1.7
+ * @see Files#walkFileTree
+ */
+
+public class FileSystemLoopException
+ extends FileSystemException
+{
+ private static final long serialVersionUID = 4843039591949217617L;
+
+ /**
+ * Constructs an instance of this class.
+ *
+ * @param file
+ * a string identifying the file causing the cycle or {@code null} if
+ * not known
+ */
+ public FileSystemLoopException(String file) {
+ super(file);
+ }
+}
diff --git a/java/nio/file/FileSystemNotFoundException.java b/java/nio/file/FileSystemNotFoundException.java
new file mode 100644
index 0000000..1c0ee4c
--- /dev/null
+++ b/java/nio/file/FileSystemNotFoundException.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Runtime exception thrown when a file system cannot be found.
+ */
+
+public class FileSystemNotFoundException
+ extends RuntimeException
+{
+ static final long serialVersionUID = 7999581764446402397L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public FileSystemNotFoundException() {
+ }
+
+ /**
+ * Constructs an instance of this class.
+ *
+ * @param msg
+ * the detail message
+ */
+ public FileSystemNotFoundException(String msg) {
+ super(msg);
+ }
+}
diff --git a/java/nio/file/FileSystems.java b/java/nio/file/FileSystems.java
new file mode 100644
index 0000000..a38aaae
--- /dev/null
+++ b/java/nio/file/FileSystems.java
@@ -0,0 +1,409 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+import java.nio.file.spi.FileSystemProvider;
+import java.net.URI;
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.*;
+import java.lang.reflect.Constructor;
+
+/**
+ * Factory methods for file systems. This class defines the {@link #getDefault
+ * getDefault} method to get the default file system and factory methods to
+ * construct other types of file systems.
+ *
+ * <p> The first invocation of any of the methods defined by this class causes
+ * the default {@link FileSystemProvider provider} to be loaded. The default
+ * provider, identified by the URI scheme "file", creates the {@link FileSystem}
+ * that provides access to the file systems accessible to the Java virtual
+ * machine. If the process of loading or initializing the default provider fails
+ * then an unspecified error is thrown.
+ *
+ * <p> The first invocation of the {@link FileSystemProvider#installedProviders
+ * installedProviders} method, by way of invoking any of the {@code
+ * newFileSystem} methods defined by this class, locates and loads all
+ * installed file system providers. Installed providers are loaded using the
+ * service-provider loading facility defined by the {@link ServiceLoader} class.
+ * Installed providers are loaded using the system class loader. If the
+ * system class loader cannot be found then the extension class loader is used;
+ * if there is no extension class loader then the bootstrap class loader is used.
+ * Providers are typically installed by placing them in a JAR file on the
+ * application class path or in the extension directory, the JAR file contains a
+ * provider-configuration file named {@code java.nio.file.spi.FileSystemProvider}
+ * in the resource directory {@code META-INF/services}, and the file lists one or
+ * more fully-qualified names of concrete subclass of {@link FileSystemProvider}
+ * that have a zero argument constructor.
+ * The ordering that installed providers are located is implementation specific.
+ * If a provider is instantiated and its {@link FileSystemProvider#getScheme()
+ * getScheme} returns the same URI scheme of a provider that was previously
+ * instantiated then the most recently instantiated duplicate is discarded. URI
+ * schemes are compared without regard to case. During construction a provider
+ * may safely access files associated with the default provider but care needs
+ * to be taken to avoid circular loading of other installed providers. If
+ * circular loading of installed providers is detected then an unspecified error
+ * is thrown.
+ *
+ * <p> This class also defines factory methods that allow a {@link ClassLoader}
+ * to be specified when locating a provider. As with installed providers, the
+ * provider classes are identified by placing the provider configuration file
+ * in the resource directory {@code META-INF/services}.
+ *
+ * <p> If a thread initiates the loading of the installed file system providers
+ * and another thread invokes a method that also attempts to load the providers
+ * then the method will block until the loading completes.
+ *
+ * @since 1.7
+ */
+
+public final class FileSystems {
+ private FileSystems() {
+ }
+
+ // lazy initialization of default file system
+ private static class DefaultFileSystemHolder {
+ static final FileSystem defaultFileSystem = defaultFileSystem();
+
+ // returns default file system
+ private static FileSystem defaultFileSystem() {
+ // load default provider
+ FileSystemProvider provider = AccessController
+ .doPrivileged(new PrivilegedAction<FileSystemProvider>() {
+ public FileSystemProvider run() {
+ return getDefaultProvider();
+ }
+ });
+
+ // return file system
+ return provider.getFileSystem(URI.create("file:///"));
+ }
+
+ // returns default provider
+ private static FileSystemProvider getDefaultProvider() {
+ FileSystemProvider provider = sun.nio.fs.DefaultFileSystemProvider.create();
+
+ // if the property java.nio.file.spi.DefaultFileSystemProvider is
+ // set then its value is the name of the default provider (or a list)
+ String propValue = System
+ .getProperty("java.nio.file.spi.DefaultFileSystemProvider");
+ if (propValue != null) {
+ for (String cn: propValue.split(",")) {
+ try {
+ Class<?> c = Class
+ .forName(cn, true, ClassLoader.getSystemClassLoader());
+ Constructor<?> ctor = c
+ .getDeclaredConstructor(FileSystemProvider.class);
+ provider = (FileSystemProvider)ctor.newInstance(provider);
+
+ // must be "file"
+ if (!provider.getScheme().equals("file"))
+ throw new Error("Default provider must use scheme 'file'");
+
+ } catch (Exception x) {
+ throw new Error(x);
+ }
+ }
+ }
+ return provider;
+ }
+ }
+
+ /**
+ * Returns the default {@code FileSystem}. The default file system creates
+ * objects that provide access to the file systems accessible to the Java
+ * virtual machine. The <em>working directory</em> of the file system is
+ * the current user directory, named by the system property {@code user.dir}.
+ * This allows for interoperability with the {@link java.io.File java.io.File}
+ * class.
+ *
+ * <p> The first invocation of any of the methods defined by this class
+ * locates the default {@link FileSystemProvider provider} object. Where the
+ * system property {@code java.nio.file.spi.DefaultFileSystemProvider} is
+ * not defined then the default provider is a system-default provider that
+ * is invoked to create the default file system.
+ *
+ * <p> If the system property {@code java.nio.file.spi.DefaultFileSystemProvider}
+ * is defined then it is taken to be a list of one or more fully-qualified
+ * names of concrete provider classes identified by the URI scheme
+ * {@code "file"}. Where the property is a list of more than one name then
+ * the names are separated by a comma. Each class is loaded, using the system
+ * class loader, and instantiated by invoking a one argument constructor
+ * whose formal parameter type is {@code FileSystemProvider}. The providers
+ * are loaded and instantiated in the order they are listed in the property.
+ * If this process fails or a provider's scheme is not equal to {@code "file"}
+ * then an unspecified error is thrown. URI schemes are normally compared
+ * without regard to case but for the default provider, the scheme is
+ * required to be {@code "file"}. The first provider class is instantiated
+ * by invoking it with a reference to the system-default provider.
+ * The second provider class is instantiated by invoking it with a reference
+ * to the first provider instance. The third provider class is instantiated
+ * by invoking it with a reference to the second instance, and so on. The
+ * last provider to be instantiated becomes the default provider; its {@code
+ * getFileSystem} method is invoked with the URI {@code "file:///"} to
+ * get a reference to the default file system.
+ *
+ * <p> Subsequent invocations of this method return the file system that was
+ * returned by the first invocation.
+ *
+ * @return the default file system
+ */
+ public static FileSystem getDefault() {
+ return DefaultFileSystemHolder.defaultFileSystem;
+ }
+
+ /**
+ * Returns a reference to an existing {@code FileSystem}.
+ *
+ * <p> This method iterates over the {@link FileSystemProvider#installedProviders()
+ * installed} providers to locate the provider that is identified by the URI
+ * {@link URI#getScheme scheme} of the given URI. URI schemes are compared
+ * without regard to case. The exact form of the URI is highly provider
+ * dependent. If found, the provider's {@link FileSystemProvider#getFileSystem
+ * getFileSystem} method is invoked to obtain a reference to the {@code
+ * FileSystem}.
+ *
+ * <p> Once a file system created by this provider is {@link FileSystem#close
+ * closed} it is provider-dependent if this method returns a reference to
+ * the closed file system or throws {@link FileSystemNotFoundException}.
+ * If the provider allows a new file system to be created with the same URI
+ * as a file system it previously created then this method throws the
+ * exception if invoked after the file system is closed (and before a new
+ * instance is created by the {@link #newFileSystem newFileSystem} method).
+ *
+ * <p> If a security manager is installed then a provider implementation
+ * may require to check a permission before returning a reference to an
+ * existing file system. In the case of the {@link FileSystems#getDefault
+ * default} file system, no permission check is required.
+ *
+ * @param uri the URI to locate the file system
+ *
+ * @return the reference to the file system
+ *
+ * @throws IllegalArgumentException
+ * if the pre-conditions for the {@code uri} parameter are not met
+ * @throws FileSystemNotFoundException
+ * if the file system, identified by the URI, does not exist
+ * @throws ProviderNotFoundException
+ * if a provider supporting the URI scheme is not installed
+ * @throws SecurityException
+ * if a security manager is installed and it denies an unspecified
+ * permission
+ */
+ public static FileSystem getFileSystem(URI uri) {
+ String scheme = uri.getScheme();
+ for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
+ if (scheme.equalsIgnoreCase(provider.getScheme())) {
+ return provider.getFileSystem(uri);
+ }
+ }
+ throw new ProviderNotFoundException("Provider \"" + scheme + "\" not found");
+ }
+
+ /**
+ * Constructs a new file system that is identified by a {@link URI}
+ *
+ * <p> This method iterates over the {@link FileSystemProvider#installedProviders()
+ * installed} providers to locate the provider that is identified by the URI
+ * {@link URI#getScheme scheme} of the given URI. URI schemes are compared
+ * without regard to case. The exact form of the URI is highly provider
+ * dependent. If found, the provider's {@link FileSystemProvider#newFileSystem(URI,Map)
+ * newFileSystem(URI,Map)} method is invoked to construct the new file system.
+ *
+ * <p> Once a file system is {@link FileSystem#close closed} it is
+ * provider-dependent if the provider allows a new file system to be created
+ * with the same URI as a file system it previously created.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose there is a provider identified by the scheme {@code "memory"}
+ * installed:
+ * <pre>
+ * Map<String,String> env = new HashMap<>();
+ * env.put("capacity", "16G");
+ * env.put("blockSize", "4k");
+ * FileSystem fs = FileSystems.newFileSystem(URI.create("memory:///?name=logfs"), env);
+ * </pre>
+ *
+ * @param uri
+ * the URI identifying the file system
+ * @param env
+ * a map of provider specific properties to configure the file system;
+ * may be empty
+ *
+ * @return a new file system
+ *
+ * @throws IllegalArgumentException
+ * if the pre-conditions for the {@code uri} parameter are not met,
+ * or the {@code env} parameter does not contain properties required
+ * by the provider, or a property value is invalid
+ * @throws FileSystemAlreadyExistsException
+ * if the file system has already been created
+ * @throws ProviderNotFoundException
+ * if a provider supporting the URI scheme is not installed
+ * @throws IOException
+ * if an I/O error occurs creating the file system
+ * @throws SecurityException
+ * if a security manager is installed and it denies an unspecified
+ * permission required by the file system provider implementation
+ */
+ public static FileSystem newFileSystem(URI uri, Map<String,?> env)
+ throws IOException
+ {
+ return newFileSystem(uri, env, null);
+ }
+
+ /**
+ * Constructs a new file system that is identified by a {@link URI}
+ *
+ * <p> This method first attempts to locate an installed provider in exactly
+ * the same manner as the {@link #newFileSystem(URI,Map) newFileSystem(URI,Map)}
+ * method. If none of the installed providers support the URI scheme then an
+ * attempt is made to locate the provider using the given class loader. If a
+ * provider supporting the URI scheme is located then its {@link
+ * FileSystemProvider#newFileSystem(URI,Map) newFileSystem(URI,Map)} is
+ * invoked to construct the new file system.
+ *
+ * @param uri
+ * the URI identifying the file system
+ * @param env
+ * a map of provider specific properties to configure the file system;
+ * may be empty
+ * @param loader
+ * the class loader to locate the provider or {@code null} to only
+ * attempt to locate an installed provider
+ *
+ * @return a new file system
+ *
+ * @throws IllegalArgumentException
+ * if the pre-conditions for the {@code uri} parameter are not met,
+ * or the {@code env} parameter does not contain properties required
+ * by the provider, or a property value is invalid
+ * @throws FileSystemAlreadyExistsException
+ * if the URI scheme identifies an installed provider and the file
+ * system has already been created
+ * @throws ProviderNotFoundException
+ * if a provider supporting the URI scheme is not found
+ * @throws ServiceConfigurationError
+ * when an error occurs while loading a service provider
+ * @throws IOException
+ * an I/O error occurs creating the file system
+ * @throws SecurityException
+ * if a security manager is installed and it denies an unspecified
+ * permission required by the file system provider implementation
+ */
+ public static FileSystem newFileSystem(URI uri, Map<String,?> env, ClassLoader loader)
+ throws IOException
+ {
+ String scheme = uri.getScheme();
+
+ // check installed providers
+ for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
+ if (scheme.equalsIgnoreCase(provider.getScheme())) {
+ return provider.newFileSystem(uri, env);
+ }
+ }
+
+ // if not found, use service-provider loading facility
+ if (loader != null) {
+ ServiceLoader<FileSystemProvider> sl = ServiceLoader
+ .load(FileSystemProvider.class, loader);
+ for (FileSystemProvider provider: sl) {
+ if (scheme.equalsIgnoreCase(provider.getScheme())) {
+ return provider.newFileSystem(uri, env);
+ }
+ }
+ }
+
+ throw new ProviderNotFoundException("Provider \"" + scheme + "\" not found");
+ }
+
+ /**
+ * Constructs a new {@code FileSystem} to access the contents of a file as a
+ * file system.
+ *
+ * <p> This method makes use of specialized providers that create pseudo file
+ * systems where the contents of one or more files is treated as a file
+ * system.
+ *
+ * <p> This method iterates over the {@link FileSystemProvider#installedProviders()
+ * installed} providers. It invokes, in turn, each provider's {@link
+ * FileSystemProvider#newFileSystem(Path,Map) newFileSystem(Path,Map)} method
+ * with an empty map. If a provider returns a file system then the iteration
+ * terminates and the file system is returned. If none of the installed
+ * providers return a {@code FileSystem} then an attempt is made to locate
+ * the provider using the given class loader. If a provider returns a file
+ * system then the lookup terminates and the file system is returned.
+ *
+ * @param path
+ * the path to the file
+ * @param loader
+ * the class loader to locate the provider or {@code null} to only
+ * attempt to locate an installed provider
+ *
+ * @return a new file system
+ *
+ * @throws ProviderNotFoundException
+ * if a provider supporting this file type cannot be located
+ * @throws ServiceConfigurationError
+ * when an error occurs while loading a service provider
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * if a security manager is installed and it denies an unspecified
+ * permission
+ */
+ public static FileSystem newFileSystem(Path path,
+ ClassLoader loader)
+ throws IOException
+ {
+ if (path == null)
+ throw new NullPointerException();
+ Map<String,?> env = Collections.emptyMap();
+
+ // check installed providers
+ for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
+ try {
+ return provider.newFileSystem(path, env);
+ } catch (UnsupportedOperationException uoe) {
+ }
+ }
+
+ // if not found, use service-provider loading facility
+ if (loader != null) {
+ ServiceLoader<FileSystemProvider> sl = ServiceLoader
+ .load(FileSystemProvider.class, loader);
+ for (FileSystemProvider provider: sl) {
+ try {
+ return provider.newFileSystem(path, env);
+ } catch (UnsupportedOperationException uoe) {
+ }
+ }
+ }
+
+ throw new ProviderNotFoundException("Provider not found");
+ }
+}
diff --git a/java/nio/file/FileTreeIterator.java b/java/nio/file/FileTreeIterator.java
new file mode 100644
index 0000000..63b4dc7
--- /dev/null
+++ b/java/nio/file/FileTreeIterator.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+import java.nio.file.FileTreeWalker.Event;
+
+/**
+ * An {@code Iterator to iterate over the nodes of a file tree.
+ *
+ * <pre>{@code
+ * try (FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options)) {
+ * while (iterator.hasNext()) {
+ * Event ev = iterator.next();
+ * Path path = ev.file();
+ * BasicFileAttributes attrs = ev.attributes();
+ * }
+ * }
+ * }</pre>
+ */
+
+class FileTreeIterator implements Iterator<Event>, Closeable {
+ private final FileTreeWalker walker;
+ private Event next;
+
+ /**
+ * Creates a new iterator to walk the file tree starting at the given file.
+ *
+ * @throws IllegalArgumentException
+ * if {@code maxDepth} is negative
+ * @throws IOException
+ * if an I/O errors occurs opening the starting file
+ * @throws SecurityException
+ * if the security manager denies access to the starting file
+ * @throws NullPointerException
+ * if {@code start} or {@code options} is {@ocde null} or
+ * the options array contains a {@code null} element
+ */
+ FileTreeIterator(Path start, int maxDepth, FileVisitOption... options)
+ throws IOException
+ {
+ this.walker = new FileTreeWalker(Arrays.asList(options), maxDepth);
+ this.next = walker.walk(start);
+ assert next.type() == FileTreeWalker.EventType.ENTRY ||
+ next.type() == FileTreeWalker.EventType.START_DIRECTORY;
+
+ // IOException if there a problem accessing the starting file
+ IOException ioe = next.ioeException();
+ if (ioe != null)
+ throw ioe;
+ }
+
+ private void fetchNextIfNeeded() {
+ if (next == null) {
+ FileTreeWalker.Event ev = walker.next();
+ while (ev != null) {
+ IOException ioe = ev.ioeException();
+ if (ioe != null)
+ throw new UncheckedIOException(ioe);
+
+ // END_DIRECTORY events are ignored
+ if (ev.type() != FileTreeWalker.EventType.END_DIRECTORY) {
+ next = ev;
+ return;
+ }
+ ev = walker.next();
+ }
+ }
+ }
+
+ @Override
+ public boolean hasNext() {
+ if (!walker.isOpen())
+ throw new IllegalStateException();
+ fetchNextIfNeeded();
+ return next != null;
+ }
+
+ @Override
+ public Event next() {
+ if (!walker.isOpen())
+ throw new IllegalStateException();
+ fetchNextIfNeeded();
+ if (next == null)
+ throw new NoSuchElementException();
+ Event result = next;
+ next = null;
+ return result;
+ }
+
+ @Override
+ public void close() {
+ walker.close();
+ }
+}
diff --git a/java/nio/file/FileTreeWalker.java b/java/nio/file/FileTreeWalker.java
new file mode 100644
index 0000000..b0cf0d3
--- /dev/null
+++ b/java/nio/file/FileTreeWalker.java
@@ -0,0 +1,425 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+import java.nio.file.attribute.BasicFileAttributes;
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.Collection;
+import java.util.Iterator;
+import sun.nio.fs.BasicFileAttributesHolder;
+
+/**
+ * Walks a file tree, generating a sequence of events corresponding to the files
+ * in the tree.
+ *
+ * <pre>{@code
+ * Path top = ...
+ * Set<FileVisitOption> options = ...
+ * int maxDepth = ...
+ *
+ * try (FileTreeWalker walker = new FileTreeWalker(options, maxDepth)) {
+ * FileTreeWalker.Event ev = walker.walk(top);
+ * do {
+ * process(ev);
+ * ev = walker.next();
+ * } while (ev != null);
+ * }
+ * }</pre>
+ *
+ * @see Files#walkFileTree
+ */
+
+class FileTreeWalker implements Closeable {
+ private final boolean followLinks;
+ private final LinkOption[] linkOptions;
+ private final int maxDepth;
+ private final ArrayDeque<DirectoryNode> stack = new ArrayDeque<>();
+ private boolean closed;
+
+ /**
+ * The element on the walking stack corresponding to a directory node.
+ */
+ private static class DirectoryNode {
+ private final Path dir;
+ private final Object key;
+ private final DirectoryStream<Path> stream;
+ private final Iterator<Path> iterator;
+ private boolean skipped;
+
+ DirectoryNode(Path dir, Object key, DirectoryStream<Path> stream) {
+ this.dir = dir;
+ this.key = key;
+ this.stream = stream;
+ this.iterator = stream.iterator();
+ }
+
+ Path directory() {
+ return dir;
+ }
+
+ Object key() {
+ return key;
+ }
+
+ DirectoryStream<Path> stream() {
+ return stream;
+ }
+
+ Iterator<Path> iterator() {
+ return iterator;
+ }
+
+ void skip() {
+ skipped = true;
+ }
+
+ boolean skipped() {
+ return skipped;
+ }
+ }
+
+ /**
+ * The event types.
+ */
+ static enum EventType {
+ /**
+ * Start of a directory
+ */
+ START_DIRECTORY,
+ /**
+ * End of a directory
+ */
+ END_DIRECTORY,
+ /**
+ * An entry in a directory
+ */
+ ENTRY;
+ }
+
+ /**
+ * Events returned by the {@link #walk} and {@link #next} methods.
+ */
+ static class Event {
+ private final EventType type;
+ private final Path file;
+ private final BasicFileAttributes attrs;
+ private final IOException ioe;
+
+ private Event(EventType type, Path file, BasicFileAttributes attrs, IOException ioe) {
+ this.type = type;
+ this.file = file;
+ this.attrs = attrs;
+ this.ioe = ioe;
+ }
+
+ Event(EventType type, Path file, BasicFileAttributes attrs) {
+ this(type, file, attrs, null);
+ }
+
+ Event(EventType type, Path file, IOException ioe) {
+ this(type, file, null, ioe);
+ }
+
+ EventType type() {
+ return type;
+ }
+
+ Path file() {
+ return file;
+ }
+
+ BasicFileAttributes attributes() {
+ return attrs;
+ }
+
+ IOException ioeException() {
+ return ioe;
+ }
+ }
+
+ /**
+ * Creates a {@code FileTreeWalker}.
+ *
+ * @throws IllegalArgumentException
+ * if {@code maxDepth} is negative
+ * @throws ClassCastException
+ * if (@code options} contains an element that is not a
+ * {@code FileVisitOption}
+ * @throws NullPointerException
+ * if {@code options} is {@ocde null} or the options
+ * array contains a {@code null} element
+ */
+ FileTreeWalker(Collection<FileVisitOption> options, int maxDepth) {
+ boolean fl = false;
+ for (FileVisitOption option: options) {
+ // will throw NPE if options contains null
+ switch (option) {
+ case FOLLOW_LINKS : fl = true; break;
+ default:
+ throw new AssertionError("Should not get here");
+ }
+ }
+ if (maxDepth < 0)
+ throw new IllegalArgumentException("'maxDepth' is negative");
+
+ this.followLinks = fl;
+ this.linkOptions = (fl) ? new LinkOption[0] :
+ new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
+ this.maxDepth = maxDepth;
+ }
+
+ /**
+ * Returns the attributes of the given file, taking into account whether
+ * the walk is following sym links is not. The {@code canUseCached}
+ * argument determines whether this method can use cached attributes.
+ */
+ private BasicFileAttributes getAttributes(Path file, boolean canUseCached)
+ throws IOException
+ {
+ // if attributes are cached then use them if possible
+ if (canUseCached &&
+ (file instanceof BasicFileAttributesHolder) &&
+ (System.getSecurityManager() == null))
+ {
+ BasicFileAttributes cached = ((BasicFileAttributesHolder)file).get();
+ if (cached != null && (!followLinks || !cached.isSymbolicLink())) {
+ return cached;
+ }
+ }
+
+ // attempt to get attributes of file. If fails and we are following
+ // links then a link target might not exist so get attributes of link
+ BasicFileAttributes attrs;
+ try {
+ attrs = Files.readAttributes(file, BasicFileAttributes.class, linkOptions);
+ } catch (IOException ioe) {
+ if (!followLinks)
+ throw ioe;
+
+ // attempt to get attrmptes without following links
+ attrs = Files.readAttributes(file,
+ BasicFileAttributes.class,
+ LinkOption.NOFOLLOW_LINKS);
+ }
+ return attrs;
+ }
+
+ /**
+ * Returns true if walking into the given directory would result in a
+ * file system loop/cycle.
+ */
+ private boolean wouldLoop(Path dir, Object key) {
+ // if this directory and ancestor has a file key then we compare
+ // them; otherwise we use less efficient isSameFile test.
+ for (DirectoryNode ancestor: stack) {
+ Object ancestorKey = ancestor.key();
+ if (key != null && ancestorKey != null) {
+ if (key.equals(ancestorKey)) {
+ // cycle detected
+ return true;
+ }
+ } else {
+ try {
+ if (Files.isSameFile(dir, ancestor.directory())) {
+ // cycle detected
+ return true;
+ }
+ } catch (IOException | SecurityException x) {
+ // ignore
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Visits the given file, returning the {@code Event} corresponding to that
+ * visit.
+ *
+ * The {@code ignoreSecurityException} parameter determines whether
+ * any SecurityException should be ignored or not. If a SecurityException
+ * is thrown, and is ignored, then this method returns {@code null} to
+ * mean that there is no event corresponding to a visit to the file.
+ *
+ * The {@code canUseCached} parameter determines whether cached attributes
+ * for the file can be used or not.
+ */
+ private Event visit(Path entry, boolean ignoreSecurityException, boolean canUseCached) {
+ // need the file attributes
+ BasicFileAttributes attrs;
+ try {
+ attrs = getAttributes(entry, canUseCached);
+ } catch (IOException ioe) {
+ return new Event(EventType.ENTRY, entry, ioe);
+ } catch (SecurityException se) {
+ if (ignoreSecurityException)
+ return null;
+ throw se;
+ }
+
+ // at maximum depth or file is not a directory
+ int depth = stack.size();
+ if (depth >= maxDepth || !attrs.isDirectory()) {
+ return new Event(EventType.ENTRY, entry, attrs);
+ }
+
+ // check for cycles when following links
+ if (followLinks && wouldLoop(entry, attrs.fileKey())) {
+ return new Event(EventType.ENTRY, entry,
+ new FileSystemLoopException(entry.toString()));
+ }
+
+ // file is a directory, attempt to open it
+ DirectoryStream<Path> stream = null;
+ try {
+ stream = Files.newDirectoryStream(entry);
+ } catch (IOException ioe) {
+ return new Event(EventType.ENTRY, entry, ioe);
+ } catch (SecurityException se) {
+ if (ignoreSecurityException)
+ return null;
+ throw se;
+ }
+
+ // push a directory node to the stack and return an event
+ stack.push(new DirectoryNode(entry, attrs.fileKey(), stream));
+ return new Event(EventType.START_DIRECTORY, entry, attrs);
+ }
+
+
+ /**
+ * Start walking from the given file.
+ */
+ Event walk(Path file) {
+ if (closed)
+ throw new IllegalStateException("Closed");
+
+ Event ev = visit(file,
+ false, // ignoreSecurityException
+ false); // canUseCached
+ assert ev != null;
+ return ev;
+ }
+
+ /**
+ * Returns the next Event or {@code null} if there are no more events or
+ * the walker is closed.
+ */
+ Event next() {
+ DirectoryNode top = stack.peek();
+ if (top == null)
+ return null; // stack is empty, we are done
+
+ // continue iteration of the directory at the top of the stack
+ Event ev;
+ do {
+ Path entry = null;
+ IOException ioe = null;
+
+ // get next entry in the directory
+ if (!top.skipped()) {
+ Iterator<Path> iterator = top.iterator();
+ try {
+ if (iterator.hasNext()) {
+ entry = iterator.next();
+ }
+ } catch (DirectoryIteratorException x) {
+ ioe = x.getCause();
+ }
+ }
+
+ // no next entry so close and pop directory, creating corresponding event
+ if (entry == null) {
+ try {
+ top.stream().close();
+ } catch (IOException e) {
+ if (ioe != null) {
+ ioe = e;
+ } else {
+ ioe.addSuppressed(e);
+ }
+ }
+ stack.pop();
+ return new Event(EventType.END_DIRECTORY, top.directory(), ioe);
+ }
+
+ // visit the entry
+ ev = visit(entry,
+ true, // ignoreSecurityException
+ true); // canUseCached
+
+ } while (ev == null);
+
+ return ev;
+ }
+
+ /**
+ * Pops the directory node that is the current top of the stack so that
+ * there are no more events for the directory (including no END_DIRECTORY)
+ * event. This method is a no-op if the stack is empty or the walker is
+ * closed.
+ */
+ void pop() {
+ if (!stack.isEmpty()) {
+ DirectoryNode node = stack.pop();
+ try {
+ node.stream().close();
+ } catch (IOException ignore) { }
+ }
+ }
+
+ /**
+ * Skips the remaining entries in the directory at the top of the stack.
+ * This method is a no-op if the stack is empty or the walker is closed.
+ */
+ void skipRemainingSiblings() {
+ if (!stack.isEmpty()) {
+ stack.peek().skip();
+ }
+ }
+
+ /**
+ * Returns {@code true} if the walker is open.
+ */
+ boolean isOpen() {
+ return !closed;
+ }
+
+ /**
+ * Closes/pops all directories on the stack.
+ */
+ @Override
+ public void close() {
+ if (!closed) {
+ while (!stack.isEmpty()) {
+ pop();
+ }
+ closed = true;
+ }
+ }
+}
diff --git a/java/nio/file/FileVisitOption.java b/java/nio/file/FileVisitOption.java
new file mode 100644
index 0000000..c6c00e5
--- /dev/null
+++ b/java/nio/file/FileVisitOption.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Defines the file tree traversal options.
+ *
+ * @since 1.7
+ *
+ * @see Files#walkFileTree
+ */
+
+public enum FileVisitOption {
+ /**
+ * Follow symbolic links.
+ */
+ FOLLOW_LINKS;
+}
diff --git a/java/nio/file/FileVisitResult.java b/java/nio/file/FileVisitResult.java
new file mode 100644
index 0000000..36bd5c9
--- /dev/null
+++ b/java/nio/file/FileVisitResult.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * The result type of a {@link FileVisitor FileVisitor}.
+ *
+ * @since 1.7
+ *
+ * @see Files#walkFileTree
+ */
+
+public enum FileVisitResult {
+ /**
+ * Continue. When returned from a {@link FileVisitor#preVisitDirectory
+ * preVisitDirectory} method then the entries in the directory should also
+ * be visited.
+ */
+ CONTINUE,
+ /**
+ * Terminate.
+ */
+ TERMINATE,
+ /**
+ * Continue without visiting the entries in this directory. This result
+ * is only meaningful when returned from the {@link
+ * FileVisitor#preVisitDirectory preVisitDirectory} method; otherwise
+ * this result type is the same as returning {@link #CONTINUE}.
+ */
+ SKIP_SUBTREE,
+ /**
+ * Continue without visiting the <em>siblings</em> of this file or directory.
+ * If returned from the {@link FileVisitor#preVisitDirectory
+ * preVisitDirectory} method then the entries in the directory are also
+ * skipped and the {@link FileVisitor#postVisitDirectory postVisitDirectory}
+ * method is not invoked.
+ */
+ SKIP_SIBLINGS;
+}
diff --git a/java/nio/file/FileVisitor.java b/java/nio/file/FileVisitor.java
new file mode 100644
index 0000000..5c555ae
--- /dev/null
+++ b/java/nio/file/FileVisitor.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+import java.nio.file.attribute.BasicFileAttributes;
+import java.io.IOException;
+
+/**
+ * A visitor of files. An implementation of this interface is provided to the
+ * {@link Files#walkFileTree Files.walkFileTree} methods to visit each file in
+ * a file tree.
+ *
+ * <p> <b>Usage Examples:</b>
+ * Suppose we want to delete a file tree. In that case, each directory should
+ * be deleted after the entries in the directory are deleted.
+ * <pre>
+ * Path start = ...
+ * Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
+ * @Override
+ * public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+ * throws IOException
+ * {
+ * Files.delete(file);
+ * return FileVisitResult.CONTINUE;
+ * }
+ * @Override
+ * public FileVisitResult postVisitDirectory(Path dir, IOException e)
+ * throws IOException
+ * {
+ * if (e == null) {
+ * Files.delete(dir);
+ * return FileVisitResult.CONTINUE;
+ * } else {
+ * // directory iteration failed
+ * throw e;
+ * }
+ * }
+ * });
+ * </pre>
+ * <p> Furthermore, suppose we want to copy a file tree to a target location.
+ * In that case, symbolic links should be followed and the target directory
+ * should be created before the entries in the directory are copied.
+ * <pre>
+ * final Path source = ...
+ * final Path target = ...
+ *
+ * Files.walkFileTree(source, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
+ * new SimpleFileVisitor<Path>() {
+ * @Override
+ * public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
+ * throws IOException
+ * {
+ * Path targetdir = target.resolve(source.relativize(dir));
+ * try {
+ * Files.copy(dir, targetdir);
+ * } catch (FileAlreadyExistsException e) {
+ * if (!Files.isDirectory(targetdir))
+ * throw e;
+ * }
+ * return CONTINUE;
+ * }
+ * @Override
+ * public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+ * throws IOException
+ * {
+ * Files.copy(file, target.resolve(source.relativize(file)));
+ * return CONTINUE;
+ * }
+ * });
+ * </pre>
+ *
+ * @since 1.7
+ */
+
+public interface FileVisitor<T> {
+
+ /**
+ * Invoked for a directory before entries in the directory are visited.
+ *
+ * <p> If this method returns {@link FileVisitResult#CONTINUE CONTINUE},
+ * then entries in the directory are visited. If this method returns {@link
+ * FileVisitResult#SKIP_SUBTREE SKIP_SUBTREE} or {@link
+ * FileVisitResult#SKIP_SIBLINGS SKIP_SIBLINGS} then entries in the
+ * directory (and any descendants) will not be visited.
+ *
+ * @param dir
+ * a reference to the directory
+ * @param attrs
+ * the directory's basic attributes
+ *
+ * @return the visit result
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
+ throws IOException;
+
+ /**
+ * Invoked for a file in a directory.
+ *
+ * @param file
+ * a reference to the file
+ * @param attrs
+ * the file's basic attributes
+ *
+ * @return the visit result
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ FileVisitResult visitFile(T file, BasicFileAttributes attrs)
+ throws IOException;
+
+ /**
+ * Invoked for a file that could not be visited. This method is invoked
+ * if the file's attributes could not be read, the file is a directory
+ * that could not be opened, and other reasons.
+ *
+ * @param file
+ * a reference to the file
+ * @param exc
+ * the I/O exception that prevented the file from being visited
+ *
+ * @return the visit result
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ FileVisitResult visitFileFailed(T file, IOException exc)
+ throws IOException;
+
+ /**
+ * Invoked for a directory after entries in the directory, and all of their
+ * descendants, have been visited. This method is also invoked when iteration
+ * of the directory completes prematurely (by a {@link #visitFile visitFile}
+ * method returning {@link FileVisitResult#SKIP_SIBLINGS SKIP_SIBLINGS},
+ * or an I/O error when iterating over the directory).
+ *
+ * @param dir
+ * a reference to the directory
+ * @param exc
+ * {@code null} if the iteration of the directory completes without
+ * an error; otherwise the I/O exception that caused the iteration
+ * of the directory to complete prematurely
+ *
+ * @return the visit result
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ FileVisitResult postVisitDirectory(T dir, IOException exc)
+ throws IOException;
+}
diff --git a/java/nio/file/Files.java b/java/nio/file/Files.java
new file mode 100644
index 0000000..012118c
--- /dev/null
+++ b/java/nio/file/Files.java
@@ -0,0 +1,3787 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.Closeable;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.UncheckedIOException;
+import java.io.Writer;
+import java.nio.channels.Channels;
+import java.nio.channels.FileChannel;
+import java.nio.channels.SeekableByteChannel;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.attribute.BasicFileAttributeView;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.attribute.DosFileAttributes; // javadoc
+import java.nio.file.attribute.FileAttribute;
+import java.nio.file.attribute.FileAttributeView;
+import java.nio.file.attribute.FileOwnerAttributeView;
+import java.nio.file.attribute.FileStoreAttributeView;
+import java.nio.file.attribute.FileTime;
+import java.nio.file.attribute.PosixFileAttributeView;
+import java.nio.file.attribute.PosixFileAttributes;
+import java.nio.file.attribute.PosixFilePermission;
+import java.nio.file.attribute.UserPrincipal;
+import java.nio.file.spi.FileSystemProvider;
+import java.nio.file.spi.FileTypeDetector;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.ServiceLoader;
+import java.util.Set;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.BiPredicate;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+/**
+ * This class consists exclusively of static methods that operate on files,
+ * directories, or other types of files.
+ *
+ * <p> In most cases, the methods defined here will delegate to the associated
+ * file system provider to perform the file operations.
+ *
+ * @since 1.7
+ */
+
+public final class Files {
+ private Files() { }
+
+ /**
+ * Returns the {@code FileSystemProvider} to delegate to.
+ */
+ private static FileSystemProvider provider(Path path) {
+ return path.getFileSystem().provider();
+ }
+
+ /**
+ * Convert a Closeable to a Runnable by converting checked IOException
+ * to UncheckedIOException
+ */
+ private static Runnable asUncheckedRunnable(Closeable c) {
+ return () -> {
+ try {
+ c.close();
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ };
+ }
+
+ // -- File contents --
+
+ /**
+ * Opens a file, returning an input stream to read from the file. The stream
+ * will not be buffered, and is not required to support the {@link
+ * InputStream#mark mark} or {@link InputStream#reset reset} methods. The
+ * stream will be safe for access by multiple concurrent threads. Reading
+ * commences at the beginning of the file. Whether the returned stream is
+ * <i>asynchronously closeable</i> and/or <i>interruptible</i> is highly
+ * file system provider specific and therefore not specified.
+ *
+ * <p> The {@code options} parameter determines how the file is opened.
+ * If no options are present then it is equivalent to opening the file with
+ * the {@link StandardOpenOption#READ READ} option. In addition to the {@code
+ * READ} option, an implementation may also support additional implementation
+ * specific options.
+ *
+ * @param path
+ * the path to the file to open
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return a new input stream
+ *
+ * @throws IllegalArgumentException
+ * if an invalid combination of options is specified
+ * @throws UnsupportedOperationException
+ * if an unsupported option is specified
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file.
+ */
+ public static InputStream newInputStream(Path path, OpenOption... options)
+ throws IOException
+ {
+ return provider(path).newInputStream(path, options);
+ }
+
+ /**
+ * Opens or creates a file, returning an output stream that may be used to
+ * write bytes to the file. The resulting stream will not be buffered. The
+ * stream will be safe for access by multiple concurrent threads. Whether
+ * the returned stream is <i>asynchronously closeable</i> and/or
+ * <i>interruptible</i> is highly file system provider specific and
+ * therefore not specified.
+ *
+ * <p> This method opens or creates a file in exactly the manner specified
+ * by the {@link #newByteChannel(Path,Set,FileAttribute[]) newByteChannel}
+ * method with the exception that the {@link StandardOpenOption#READ READ}
+ * option may not be present in the array of options. If no options are
+ * present then this method works as if the {@link StandardOpenOption#CREATE
+ * CREATE}, {@link StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING},
+ * and {@link StandardOpenOption#WRITE WRITE} options are present. In other
+ * words, it opens the file for writing, creating the file if it doesn't
+ * exist, or initially truncating an existing {@link #isRegularFile
+ * regular-file} to a size of {@code 0} if it exists.
+ *
+ * <p> <b>Usage Examples:</b>
+ * <pre>
+ * Path path = ...
+ *
+ * // truncate and overwrite an existing file, or create the file if
+ * // it doesn't initially exist
+ * OutputStream out = Files.newOutputStream(path);
+ *
+ * // append to an existing file, fail if the file does not exist
+ * out = Files.newOutputStream(path, APPEND);
+ *
+ * // append to an existing file, create file if it doesn't initially exist
+ * out = Files.newOutputStream(path, CREATE, APPEND);
+ *
+ * // always create new file, failing if it already exists
+ * out = Files.newOutputStream(path, CREATE_NEW);
+ * </pre>
+ *
+ * @param path
+ * the path to the file to open or create
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return a new output stream
+ *
+ * @throws IllegalArgumentException
+ * if {@code options} contains an invalid combination of options
+ * @throws UnsupportedOperationException
+ * if an unsupported option is specified
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to the file. The {@link
+ * SecurityManager#checkDelete(String) checkDelete} method is
+ * invoked to check delete access if the file is opened with the
+ * {@code DELETE_ON_CLOSE} option.
+ */
+ public static OutputStream newOutputStream(Path path, OpenOption... options)
+ throws IOException
+ {
+ return provider(path).newOutputStream(path, options);
+ }
+
+ /**
+ * Opens or creates a file, returning a seekable byte channel to access the
+ * file.
+ *
+ * <p> The {@code options} parameter determines how the file is opened.
+ * The {@link StandardOpenOption#READ READ} and {@link
+ * StandardOpenOption#WRITE WRITE} options determine if the file should be
+ * opened for reading and/or writing. If neither option (or the {@link
+ * StandardOpenOption#APPEND APPEND} option) is present then the file is
+ * opened for reading. By default reading or writing commence at the
+ * beginning of the file.
+ *
+ * <p> In the addition to {@code READ} and {@code WRITE}, the following
+ * options may be present:
+ *
+ * <table border=1 cellpadding=5 summary="Options">
+ * <tr> <th>Option</th> <th>Description</th> </tr>
+ * <tr>
+ * <td> {@link StandardOpenOption#APPEND APPEND} </td>
+ * <td> If this option is present then the file is opened for writing and
+ * each invocation of the channel's {@code write} method first advances
+ * the position to the end of the file and then writes the requested
+ * data. Whether the advancement of the position and the writing of the
+ * data are done in a single atomic operation is system-dependent and
+ * therefore unspecified. This option may not be used in conjunction
+ * with the {@code READ} or {@code TRUNCATE_EXISTING} options. </td>
+ * </tr>
+ * <tr>
+ * <td> {@link StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING} </td>
+ * <td> If this option is present then the existing file is truncated to
+ * a size of 0 bytes. This option is ignored when the file is opened only
+ * for reading. </td>
+ * </tr>
+ * <tr>
+ * <td> {@link StandardOpenOption#CREATE_NEW CREATE_NEW} </td>
+ * <td> If this option is present then a new file is created, failing if
+ * the file already exists or is a symbolic link. When creating a file the
+ * check for the existence of the file and the creation of the file if it
+ * does not exist is atomic with respect to other file system operations.
+ * This option is ignored when the file is opened only for reading. </td>
+ * </tr>
+ * <tr>
+ * <td > {@link StandardOpenOption#CREATE CREATE} </td>
+ * <td> If this option is present then an existing file is opened if it
+ * exists, otherwise a new file is created. This option is ignored if the
+ * {@code CREATE_NEW} option is also present or the file is opened only
+ * for reading. </td>
+ * </tr>
+ * <tr>
+ * <td > {@link StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} </td>
+ * <td> When this option is present then the implementation makes a
+ * <em>best effort</em> attempt to delete the file when closed by the
+ * {@link SeekableByteChannel#close close} method. If the {@code close}
+ * method is not invoked then a <em>best effort</em> attempt is made to
+ * delete the file when the Java virtual machine terminates. </td>
+ * </tr>
+ * <tr>
+ * <td>{@link StandardOpenOption#SPARSE SPARSE} </td>
+ * <td> When creating a new file this option is a <em>hint</em> that the
+ * new file will be sparse. This option is ignored when not creating
+ * a new file. </td>
+ * </tr>
+ * <tr>
+ * <td> {@link StandardOpenOption#SYNC SYNC} </td>
+ * <td> Requires that every update to the file's content or metadata be
+ * written synchronously to the underlying storage device. (see <a
+ * href="package-summary.html#integrity"> Synchronized I/O file
+ * integrity</a>). </td>
+ * </tr>
+ * <tr>
+ * <td> {@link StandardOpenOption#DSYNC DSYNC} </td>
+ * <td> Requires that every update to the file's content be written
+ * synchronously to the underlying storage device. (see <a
+ * href="package-summary.html#integrity"> Synchronized I/O file
+ * integrity</a>). </td>
+ * </tr>
+ * </table>
+ *
+ * <p> An implementation may also support additional implementation specific
+ * options.
+ *
+ * <p> The {@code attrs} parameter is optional {@link FileAttribute
+ * file-attributes} to set atomically when a new file is created.
+ *
+ * <p> In the case of the default provider, the returned seekable byte channel
+ * is a {@link java.nio.channels.FileChannel}.
+ *
+ * <p> <b>Usage Examples:</b>
+ * <pre>
+ * Path path = ...
+ *
+ * // open file for reading
+ * ReadableByteChannel rbc = Files.newByteChannel(path, EnumSet.of(READ)));
+ *
+ * // open file for writing to the end of an existing file, creating
+ * // the file if it doesn't already exist
+ * WritableByteChannel wbc = Files.newByteChannel(path, EnumSet.of(CREATE,APPEND));
+ *
+ * // create file with initial permissions, opening it for both reading and writing
+ * {@code FileAttribute<Set<PosixFilePermission>> perms = ...}
+ * SeekableByteChannel sbc = Files.newByteChannel(path, EnumSet.of(CREATE_NEW,READ,WRITE), perms);
+ * </pre>
+ *
+ * @param path
+ * the path to the file to open or create
+ * @param options
+ * options specifying how the file is opened
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the file
+ *
+ * @return a new seekable byte channel
+ *
+ * @throws IllegalArgumentException
+ * if the set contains an invalid combination of options
+ * @throws UnsupportedOperationException
+ * if an unsupported open option is specified or the array contains
+ * attributes that cannot be set atomically when creating the file
+ * @throws FileAlreadyExistsException
+ * if a file of that name already exists and the {@link
+ * StandardOpenOption#CREATE_NEW CREATE_NEW} option is specified
+ * <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the path if the file is
+ * opened for reading. The {@link SecurityManager#checkWrite(String)
+ * checkWrite} method is invoked to check write access to the path
+ * if the file is opened for writing. The {@link
+ * SecurityManager#checkDelete(String) checkDelete} method is
+ * invoked to check delete access if the file is opened with the
+ * {@code DELETE_ON_CLOSE} option.
+ *
+ * @see java.nio.channels.FileChannel#open(Path,Set,FileAttribute[])
+ */
+ public static SeekableByteChannel newByteChannel(Path path,
+ Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ return provider(path).newByteChannel(path, options, attrs);
+ }
+
+ /**
+ * Opens or creates a file, returning a seekable byte channel to access the
+ * file.
+ *
+ * <p> This method opens or creates a file in exactly the manner specified
+ * by the {@link #newByteChannel(Path,Set,FileAttribute[]) newByteChannel}
+ * method.
+ *
+ * @param path
+ * the path to the file to open or create
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return a new seekable byte channel
+ *
+ * @throws IllegalArgumentException
+ * if the set contains an invalid combination of options
+ * @throws UnsupportedOperationException
+ * if an unsupported open option is specified
+ * @throws FileAlreadyExistsException
+ * if a file of that name already exists and the {@link
+ * StandardOpenOption#CREATE_NEW CREATE_NEW} option is specified
+ * <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the path if the file is
+ * opened for reading. The {@link SecurityManager#checkWrite(String)
+ * checkWrite} method is invoked to check write access to the path
+ * if the file is opened for writing. The {@link
+ * SecurityManager#checkDelete(String) checkDelete} method is
+ * invoked to check delete access if the file is opened with the
+ * {@code DELETE_ON_CLOSE} option.
+ *
+ * @see java.nio.channels.FileChannel#open(Path,OpenOption[])
+ */
+ public static SeekableByteChannel newByteChannel(Path path, OpenOption... options)
+ throws IOException
+ {
+ Set<OpenOption> set = new HashSet<OpenOption>(options.length);
+ Collections.addAll(set, options);
+ return newByteChannel(path, set);
+ }
+
+ // -- Directories --
+
+ private static class AcceptAllFilter
+ implements DirectoryStream.Filter<Path>
+ {
+ private AcceptAllFilter() { }
+
+ @Override
+ public boolean accept(Path entry) { return true; }
+
+ static final AcceptAllFilter FILTER = new AcceptAllFilter();
+ }
+
+ /**
+ * Opens a directory, returning a {@link DirectoryStream} to iterate over
+ * all entries in the directory. The elements returned by the directory
+ * stream's {@link DirectoryStream#iterator iterator} are of type {@code
+ * Path}, each one representing an entry in the directory. The {@code Path}
+ * objects are obtained as if by {@link Path#resolve(Path) resolving} the
+ * name of the directory entry against {@code dir}.
+ *
+ * <p> When not using the try-with-resources construct, then directory
+ * stream's {@code close} method should be invoked after iteration is
+ * completed so as to free any resources held for the open directory.
+ *
+ * <p> When an implementation supports operations on entries in the
+ * directory that execute in a race-free manner then the returned directory
+ * stream is a {@link SecureDirectoryStream}.
+ *
+ * @param dir
+ * the path to the directory
+ *
+ * @return a new and open {@code DirectoryStream} object
+ *
+ * @throws NotDirectoryException
+ * if the file could not otherwise be opened because it is not
+ * a directory <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the directory.
+ */
+ public static DirectoryStream<Path> newDirectoryStream(Path dir)
+ throws IOException
+ {
+ return provider(dir).newDirectoryStream(dir, AcceptAllFilter.FILTER);
+ }
+
+ /**
+ * Opens a directory, returning a {@link DirectoryStream} to iterate over
+ * the entries in the directory. The elements returned by the directory
+ * stream's {@link DirectoryStream#iterator iterator} are of type {@code
+ * Path}, each one representing an entry in the directory. The {@code Path}
+ * objects are obtained as if by {@link Path#resolve(Path) resolving} the
+ * name of the directory entry against {@code dir}. The entries returned by
+ * the iterator are filtered by matching the {@code String} representation
+ * of their file names against the given <em>globbing</em> pattern.
+ *
+ * <p> For example, suppose we want to iterate over the files ending with
+ * ".java" in a directory:
+ * <pre>
+ * Path dir = ...
+ * try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "*.java")) {
+ * :
+ * }
+ * </pre>
+ *
+ * <p> The globbing pattern is specified by the {@link
+ * FileSystem#getPathMatcher getPathMatcher} method.
+ *
+ * <p> When not using the try-with-resources construct, then directory
+ * stream's {@code close} method should be invoked after iteration is
+ * completed so as to free any resources held for the open directory.
+ *
+ * <p> When an implementation supports operations on entries in the
+ * directory that execute in a race-free manner then the returned directory
+ * stream is a {@link SecureDirectoryStream}.
+ *
+ * @param dir
+ * the path to the directory
+ * @param glob
+ * the glob pattern
+ *
+ * @return a new and open {@code DirectoryStream} object
+ *
+ * @throws java.util.regex.PatternSyntaxException
+ * if the pattern is invalid
+ * @throws NotDirectoryException
+ * if the file could not otherwise be opened because it is not
+ * a directory <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the directory.
+ */
+ public static DirectoryStream<Path> newDirectoryStream(Path dir, String glob)
+ throws IOException
+ {
+ // avoid creating a matcher if all entries are required.
+ if (glob.equals("*"))
+ return newDirectoryStream(dir);
+
+ // create a matcher and return a filter that uses it.
+ FileSystem fs = dir.getFileSystem();
+ final PathMatcher matcher = fs.getPathMatcher("glob:" + glob);
+ DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
+ @Override
+ public boolean accept(Path entry) {
+ return matcher.matches(entry.getFileName());
+ }
+ };
+ return fs.provider().newDirectoryStream(dir, filter);
+ }
+
+ /**
+ * Opens a directory, returning a {@link DirectoryStream} to iterate over
+ * the entries in the directory. The elements returned by the directory
+ * stream's {@link DirectoryStream#iterator iterator} are of type {@code
+ * Path}, each one representing an entry in the directory. The {@code Path}
+ * objects are obtained as if by {@link Path#resolve(Path) resolving} the
+ * name of the directory entry against {@code dir}. The entries returned by
+ * the iterator are filtered by the given {@link DirectoryStream.Filter
+ * filter}.
+ *
+ * <p> When not using the try-with-resources construct, then directory
+ * stream's {@code close} method should be invoked after iteration is
+ * completed so as to free any resources held for the open directory.
+ *
+ * <p> Where the filter terminates due to an uncaught error or runtime
+ * exception then it is propagated to the {@link Iterator#hasNext()
+ * hasNext} or {@link Iterator#next() next} method. Where an {@code
+ * IOException} is thrown, it results in the {@code hasNext} or {@code
+ * next} method throwing a {@link DirectoryIteratorException} with the
+ * {@code IOException} as the cause.
+ *
+ * <p> When an implementation supports operations on entries in the
+ * directory that execute in a race-free manner then the returned directory
+ * stream is a {@link SecureDirectoryStream}.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to iterate over the files in a directory that are
+ * larger than 8K.
+ * <pre>
+ * DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
+ * public boolean accept(Path file) throws IOException {
+ * return (Files.size(file) > 8192L);
+ * }
+ * };
+ * Path dir = ...
+ * try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, filter)) {
+ * :
+ * }
+ * </pre>
+ *
+ * @param dir
+ * the path to the directory
+ * @param filter
+ * the directory stream filter
+ *
+ * @return a new and open {@code DirectoryStream} object
+ *
+ * @throws NotDirectoryException
+ * if the file could not otherwise be opened because it is not
+ * a directory <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the directory.
+ */
+ public static DirectoryStream<Path> newDirectoryStream(Path dir,
+ DirectoryStream.Filter<? super Path> filter)
+ throws IOException
+ {
+ return provider(dir).newDirectoryStream(dir, filter);
+ }
+
+ // -- Creation and deletion --
+
+ /**
+ * Creates a new and empty file, failing if the file already exists. The
+ * check for the existence of the file and the creation of the new file if
+ * it does not exist are a single operation that is atomic with respect to
+ * all other filesystem activities that might affect the directory.
+ *
+ * <p> The {@code attrs} parameter is optional {@link FileAttribute
+ * file-attributes} to set atomically when creating the file. Each attribute
+ * is identified by its {@link FileAttribute#name name}. If more than one
+ * attribute of the same name is included in the array then all but the last
+ * occurrence is ignored.
+ *
+ * @param path
+ * the path to the file to create
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the file
+ *
+ * @return the file
+ *
+ * @throws UnsupportedOperationException
+ * if the array contains an attribute that cannot be set atomically
+ * when creating the file
+ * @throws FileAlreadyExistsException
+ * if a file of that name already exists
+ * <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs or the parent directory does not exist
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to the new file.
+ */
+ public static Path createFile(Path path, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ EnumSet<StandardOpenOption> options =
+ EnumSet.<StandardOpenOption>of(StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE);
+ newByteChannel(path, options, attrs).close();
+ return path;
+ }
+
+ /**
+ * Creates a new directory. The check for the existence of the file and the
+ * creation of the directory if it does not exist are a single operation
+ * that is atomic with respect to all other filesystem activities that might
+ * affect the directory. The {@link #createDirectories createDirectories}
+ * method should be used where it is required to create all nonexistent
+ * parent directories first.
+ *
+ * <p> The {@code attrs} parameter is optional {@link FileAttribute
+ * file-attributes} to set atomically when creating the directory. Each
+ * attribute is identified by its {@link FileAttribute#name name}. If more
+ * than one attribute of the same name is included in the array then all but
+ * the last occurrence is ignored.
+ *
+ * @param dir
+ * the directory to create
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the directory
+ *
+ * @return the directory
+ *
+ * @throws UnsupportedOperationException
+ * if the array contains an attribute that cannot be set atomically
+ * when creating the directory
+ * @throws FileAlreadyExistsException
+ * if a directory could not otherwise be created because a file of
+ * that name already exists <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs or the parent directory does not exist
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to the new directory.
+ */
+ public static Path createDirectory(Path dir, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ provider(dir).createDirectory(dir, attrs);
+ return dir;
+ }
+
+ /**
+ * Creates a directory by creating all nonexistent parent directories first.
+ * Unlike the {@link #createDirectory createDirectory} method, an exception
+ * is not thrown if the directory could not be created because it already
+ * exists.
+ *
+ * <p> The {@code attrs} parameter is optional {@link FileAttribute
+ * file-attributes} to set atomically when creating the nonexistent
+ * directories. Each file attribute is identified by its {@link
+ * FileAttribute#name name}. If more than one attribute of the same name is
+ * included in the array then all but the last occurrence is ignored.
+ *
+ * <p> If this method fails, then it may do so after creating some, but not
+ * all, of the parent directories.
+ *
+ * @param dir
+ * the directory to create
+ *
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the directory
+ *
+ * @return the directory
+ *
+ * @throws UnsupportedOperationException
+ * if the array contains an attribute that cannot be set atomically
+ * when creating the directory
+ * @throws FileAlreadyExistsException
+ * if {@code dir} exists but is not a directory <i>(optional specific
+ * exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * in the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked prior to attempting to create a directory and
+ * its {@link SecurityManager#checkRead(String) checkRead} is
+ * invoked for each parent directory that is checked. If {@code
+ * dir} is not an absolute path then its {@link Path#toAbsolutePath
+ * toAbsolutePath} may need to be invoked to get its absolute path.
+ * This may invoke the security manager's {@link
+ * SecurityManager#checkPropertyAccess(String) checkPropertyAccess}
+ * method to check access to the system property {@code user.dir}
+ */
+ public static Path createDirectories(Path dir, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ // attempt to create the directory
+ try {
+ createAndCheckIsDirectory(dir, attrs);
+ return dir;
+ } catch (FileAlreadyExistsException x) {
+ // file exists and is not a directory
+ throw x;
+ } catch (IOException x) {
+ // parent may not exist or other reason
+ }
+ SecurityException se = null;
+ try {
+ dir = dir.toAbsolutePath();
+ } catch (SecurityException x) {
+ // don't have permission to get absolute path
+ se = x;
+ }
+ // find a decendent that exists
+ Path parent = dir.getParent();
+ while (parent != null) {
+ try {
+ provider(parent).checkAccess(parent);
+ break;
+ } catch (NoSuchFileException x) {
+ // does not exist
+ }
+ parent = parent.getParent();
+ }
+ if (parent == null) {
+ // unable to find existing parent
+ if (se == null) {
+ throw new FileSystemException(dir.toString(), null,
+ "Unable to determine if root directory exists");
+ } else {
+ throw se;
+ }
+ }
+
+ // create directories
+ Path child = parent;
+ for (Path name: parent.relativize(dir)) {
+ child = child.resolve(name);
+ createAndCheckIsDirectory(child, attrs);
+ }
+ return dir;
+ }
+
+ /**
+ * Used by createDirectories to attempt to create a directory. A no-op
+ * if the directory already exists.
+ */
+ private static void createAndCheckIsDirectory(Path dir,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ try {
+ createDirectory(dir, attrs);
+ } catch (FileAlreadyExistsException x) {
+ if (!isDirectory(dir, LinkOption.NOFOLLOW_LINKS))
+ throw x;
+ }
+ }
+
+ /**
+ * Creates a new empty file in the specified directory, using the given
+ * prefix and suffix strings to generate its name. The resulting
+ * {@code Path} is associated with the same {@code FileSystem} as the given
+ * directory.
+ *
+ * <p> The details as to how the name of the file is constructed is
+ * implementation dependent and therefore not specified. Where possible
+ * the {@code prefix} and {@code suffix} are used to construct candidate
+ * names in the same manner as the {@link
+ * java.io.File#createTempFile(String,String,File)} method.
+ *
+ * <p> As with the {@code File.createTempFile} methods, this method is only
+ * part of a temporary-file facility. Where used as a <em>work files</em>,
+ * the resulting file may be opened using the {@link
+ * StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} option so that the
+ * file is deleted when the appropriate {@code close} method is invoked.
+ * Alternatively, a {@link Runtime#addShutdownHook shutdown-hook}, or the
+ * {@link java.io.File#deleteOnExit} mechanism may be used to delete the
+ * file automatically.
+ *
+ * <p> The {@code attrs} parameter is optional {@link FileAttribute
+ * file-attributes} to set atomically when creating the file. Each attribute
+ * is identified by its {@link FileAttribute#name name}. If more than one
+ * attribute of the same name is included in the array then all but the last
+ * occurrence is ignored. When no file attributes are specified, then the
+ * resulting file may have more restrictive access permissions to files
+ * created by the {@link java.io.File#createTempFile(String,String,File)}
+ * method.
+ *
+ * @param dir
+ * the path to directory in which to create the file
+ * @param prefix
+ * the prefix string to be used in generating the file's name;
+ * may be {@code null}
+ * @param suffix
+ * the suffix string to be used in generating the file's name;
+ * may be {@code null}, in which case "{@code .tmp}" is used
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the file
+ *
+ * @return the path to the newly created file that did not exist before
+ * this method was invoked
+ *
+ * @throws IllegalArgumentException
+ * if the prefix or suffix parameters cannot be used to generate
+ * a candidate file name
+ * @throws UnsupportedOperationException
+ * if the array contains an attribute that cannot be set atomically
+ * when creating the directory
+ * @throws IOException
+ * if an I/O error occurs or {@code dir} does not exist
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to the file.
+ */
+ public static Path createTempFile(Path dir,
+ String prefix,
+ String suffix,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ return TempFileHelper.createTempFile(Objects.requireNonNull(dir),
+ prefix, suffix, attrs);
+ }
+
+ /**
+ * Creates an empty file in the default temporary-file directory, using
+ * the given prefix and suffix to generate its name. The resulting {@code
+ * Path} is associated with the default {@code FileSystem}.
+ *
+ * <p> This method works in exactly the manner specified by the
+ * {@link #createTempFile(Path,String,String,FileAttribute[])} method for
+ * the case that the {@code dir} parameter is the temporary-file directory.
+ *
+ * @param prefix
+ * the prefix string to be used in generating the file's name;
+ * may be {@code null}
+ * @param suffix
+ * the suffix string to be used in generating the file's name;
+ * may be {@code null}, in which case "{@code .tmp}" is used
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the file
+ *
+ * @return the path to the newly created file that did not exist before
+ * this method was invoked
+ *
+ * @throws IllegalArgumentException
+ * if the prefix or suffix parameters cannot be used to generate
+ * a candidate file name
+ * @throws UnsupportedOperationException
+ * if the array contains an attribute that cannot be set atomically
+ * when creating the directory
+ * @throws IOException
+ * if an I/O error occurs or the temporary-file directory does not
+ * exist
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to the file.
+ */
+ public static Path createTempFile(String prefix,
+ String suffix,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ return TempFileHelper.createTempFile(null, prefix, suffix, attrs);
+ }
+
+ /**
+ * Creates a new directory in the specified directory, using the given
+ * prefix to generate its name. The resulting {@code Path} is associated
+ * with the same {@code FileSystem} as the given directory.
+ *
+ * <p> The details as to how the name of the directory is constructed is
+ * implementation dependent and therefore not specified. Where possible
+ * the {@code prefix} is used to construct candidate names.
+ *
+ * <p> As with the {@code createTempFile} methods, this method is only
+ * part of a temporary-file facility. A {@link Runtime#addShutdownHook
+ * shutdown-hook}, or the {@link java.io.File#deleteOnExit} mechanism may be
+ * used to delete the directory automatically.
+ *
+ * <p> The {@code attrs} parameter is optional {@link FileAttribute
+ * file-attributes} to set atomically when creating the directory. Each
+ * attribute is identified by its {@link FileAttribute#name name}. If more
+ * than one attribute of the same name is included in the array then all but
+ * the last occurrence is ignored.
+ *
+ * @param dir
+ * the path to directory in which to create the directory
+ * @param prefix
+ * the prefix string to be used in generating the directory's name;
+ * may be {@code null}
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the directory
+ *
+ * @return the path to the newly created directory that did not exist before
+ * this method was invoked
+ *
+ * @throws IllegalArgumentException
+ * if the prefix cannot be used to generate a candidate directory name
+ * @throws UnsupportedOperationException
+ * if the array contains an attribute that cannot be set atomically
+ * when creating the directory
+ * @throws IOException
+ * if an I/O error occurs or {@code dir} does not exist
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access when creating the
+ * directory.
+ */
+ public static Path createTempDirectory(Path dir,
+ String prefix,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ return TempFileHelper.createTempDirectory(Objects.requireNonNull(dir),
+ prefix, attrs);
+ }
+
+ /**
+ * Creates a new directory in the default temporary-file directory, using
+ * the given prefix to generate its name. The resulting {@code Path} is
+ * associated with the default {@code FileSystem}.
+ *
+ * <p> This method works in exactly the manner specified by {@link
+ * #createTempDirectory(Path,String,FileAttribute[])} method for the case
+ * that the {@code dir} parameter is the temporary-file directory.
+ *
+ * @param prefix
+ * the prefix string to be used in generating the directory's name;
+ * may be {@code null}
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the directory
+ *
+ * @return the path to the newly created directory that did not exist before
+ * this method was invoked
+ *
+ * @throws IllegalArgumentException
+ * if the prefix cannot be used to generate a candidate directory name
+ * @throws UnsupportedOperationException
+ * if the array contains an attribute that cannot be set atomically
+ * when creating the directory
+ * @throws IOException
+ * if an I/O error occurs or the temporary-file directory does not
+ * exist
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access when creating the
+ * directory.
+ */
+ public static Path createTempDirectory(String prefix,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ return TempFileHelper.createTempDirectory(null, prefix, attrs);
+ }
+
+ /**
+ * Creates a symbolic link to a target <i>(optional operation)</i>.
+ *
+ * <p> The {@code target} parameter is the target of the link. It may be an
+ * {@link Path#isAbsolute absolute} or relative path and may not exist. When
+ * the target is a relative path then file system operations on the resulting
+ * link are relative to the path of the link.
+ *
+ * <p> The {@code attrs} parameter is optional {@link FileAttribute
+ * attributes} to set atomically when creating the link. Each attribute is
+ * identified by its {@link FileAttribute#name name}. If more than one attribute
+ * of the same name is included in the array then all but the last occurrence
+ * is ignored.
+ *
+ * <p> Where symbolic links are supported, but the underlying {@link FileStore}
+ * does not support symbolic links, then this may fail with an {@link
+ * IOException}. Additionally, some operating systems may require that the
+ * Java virtual machine be started with implementation specific privileges to
+ * create symbolic links, in which case this method may throw {@code IOException}.
+ *
+ * @param link
+ * the path of the symbolic link to create
+ * @param target
+ * the target of the symbolic link
+ * @param attrs
+ * the array of attributes to set atomically when creating the
+ * symbolic link
+ *
+ * @return the path to the symbolic link
+ *
+ * @throws UnsupportedOperationException
+ * if the implementation does not support symbolic links or the
+ * array contains an attribute that cannot be set atomically when
+ * creating the symbolic link
+ * @throws FileAlreadyExistsException
+ * if a file with the name already exists <i>(optional specific
+ * exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager
+ * is installed, it denies {@link LinkPermission}<tt>("symbolic")</tt>
+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to the path of the symbolic link.
+ */
+ public static Path createSymbolicLink(Path link, Path target,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ provider(link).createSymbolicLink(link, target, attrs);
+ return link;
+ }
+
+ /**
+ * Creates a new link (directory entry) for an existing file <i>(optional
+ * operation)</i>.
+ *
+ * <p> The {@code link} parameter locates the directory entry to create.
+ * The {@code existing} parameter is the path to an existing file. This
+ * method creates a new directory entry for the file so that it can be
+ * accessed using {@code link} as the path. On some file systems this is
+ * known as creating a "hard link". Whether the file attributes are
+ * maintained for the file or for each directory entry is file system
+ * specific and therefore not specified. Typically, a file system requires
+ * that all links (directory entries) for a file be on the same file system.
+ * Furthermore, on some platforms, the Java virtual machine may require to
+ * be started with implementation specific privileges to create hard links
+ * or to create links to directories.
+ *
+ * @param link
+ * the link (directory entry) to create
+ * @param existing
+ * a path to an existing file
+ *
+ * @return the path to the link (directory entry)
+ *
+ * @throws UnsupportedOperationException
+ * if the implementation does not support adding an existing file
+ * to a directory
+ * @throws FileAlreadyExistsException
+ * if the entry could not otherwise be created because a file of
+ * that name already exists <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager
+ * is installed, it denies {@link LinkPermission}<tt>("hard")</tt>
+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to either the link or the
+ * existing file.
+ */
+ public static Path createLink(Path link, Path existing) throws IOException {
+ provider(link).createLink(link, existing);
+ return link;
+ }
+
+ /**
+ * Deletes a file.
+ *
+ * <p> An implementation may require to examine the file to determine if the
+ * file is a directory. Consequently this method may not be atomic with respect
+ * to other file system operations. If the file is a symbolic link then the
+ * symbolic link itself, not the final target of the link, is deleted.
+ *
+ * <p> If the file is a directory then the directory must be empty. In some
+ * implementations a directory has entries for special files or links that
+ * are created when the directory is created. In such implementations a
+ * directory is considered empty when only the special entries exist.
+ * This method can be used with the {@link #walkFileTree walkFileTree}
+ * method to delete a directory and all entries in the directory, or an
+ * entire <i>file-tree</i> where required.
+ *
+ * <p> On some operating systems it may not be possible to remove a file when
+ * it is open and in use by this Java virtual machine or other programs.
+ *
+ * @param path
+ * the path to the file to delete
+ *
+ * @throws NoSuchFileException
+ * if the file does not exist <i>(optional specific exception)</i>
+ * @throws DirectoryNotEmptyException
+ * if the file is a directory and could not otherwise be deleted
+ * because the directory is not empty <i>(optional specific
+ * exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkDelete(String)} method
+ * is invoked to check delete access to the file
+ */
+ public static void delete(Path path) throws IOException {
+ provider(path).delete(path);
+ }
+
+ /**
+ * Deletes a file if it exists.
+ *
+ * <p> As with the {@link #delete(Path) delete(Path)} method, an
+ * implementation may need to examine the file to determine if the file is a
+ * directory. Consequently this method may not be atomic with respect to
+ * other file system operations. If the file is a symbolic link, then the
+ * symbolic link itself, not the final target of the link, is deleted.
+ *
+ * <p> If the file is a directory then the directory must be empty. In some
+ * implementations a directory has entries for special files or links that
+ * are created when the directory is created. In such implementations a
+ * directory is considered empty when only the special entries exist.
+ *
+ * <p> On some operating systems it may not be possible to remove a file when
+ * it is open and in use by this Java virtual machine or other programs.
+ *
+ * @param path
+ * the path to the file to delete
+ *
+ * @return {@code true} if the file was deleted by this method; {@code
+ * false} if the file could not be deleted because it did not
+ * exist
+ *
+ * @throws DirectoryNotEmptyException
+ * if the file is a directory and could not otherwise be deleted
+ * because the directory is not empty <i>(optional specific
+ * exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkDelete(String)} method
+ * is invoked to check delete access to the file.
+ */
+ public static boolean deleteIfExists(Path path) throws IOException {
+ return provider(path).deleteIfExists(path);
+ }
+
+ // -- Copying and moving files --
+
+ /**
+ * Copy a file to a target file.
+ *
+ * <p> This method copies a file to the target file with the {@code
+ * options} parameter specifying how the copy is performed. By default, the
+ * copy fails if the target file already exists or is a symbolic link,
+ * except if the source and target are the {@link #isSameFile same} file, in
+ * which case the method completes without copying the file. File attributes
+ * are not required to be copied to the target file. If symbolic links are
+ * supported, and the file is a symbolic link, then the final target of the
+ * link is copied. If the file is a directory then it creates an empty
+ * directory in the target location (entries in the directory are not
+ * copied). This method can be used with the {@link #walkFileTree
+ * walkFileTree} method to copy a directory and all entries in the directory,
+ * or an entire <i>file-tree</i> where required.
+ *
+ * <p> The {@code options} parameter may include any of the following:
+ *
+ * <table border=1 cellpadding=5 summary="">
+ * <tr> <th>Option</th> <th>Description</th> </tr>
+ * <tr>
+ * <td> {@link StandardCopyOption#REPLACE_EXISTING REPLACE_EXISTING} </td>
+ * <td> If the target file exists, then the target file is replaced if it
+ * is not a non-empty directory. If the target file exists and is a
+ * symbolic link, then the symbolic link itself, not the target of
+ * the link, is replaced. </td>
+ * </tr>
+ * <tr>
+ * <td> {@link StandardCopyOption#COPY_ATTRIBUTES COPY_ATTRIBUTES} </td>
+ * <td> Attempts to copy the file attributes associated with this file to
+ * the target file. The exact file attributes that are copied is platform
+ * and file system dependent and therefore unspecified. Minimally, the
+ * {@link BasicFileAttributes#lastModifiedTime last-modified-time} is
+ * copied to the target file if supported by both the source and target
+ * file stores. Copying of file timestamps may result in precision
+ * loss. </td>
+ * </tr>
+ * <tr>
+ * <td> {@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} </td>
+ * <td> Symbolic links are not followed. If the file is a symbolic link,
+ * then the symbolic link itself, not the target of the link, is copied.
+ * It is implementation specific if file attributes can be copied to the
+ * new link. In other words, the {@code COPY_ATTRIBUTES} option may be
+ * ignored when copying a symbolic link. </td>
+ * </tr>
+ * </table>
+ *
+ * <p> An implementation of this interface may support additional
+ * implementation specific options.
+ *
+ * <p> Copying a file is not an atomic operation. If an {@link IOException}
+ * is thrown, then it is possible that the target file is incomplete or some
+ * of its file attributes have not been copied from the source file. When
+ * the {@code REPLACE_EXISTING} option is specified and the target file
+ * exists, then the target file is replaced. The check for the existence of
+ * the file and the creation of the new file may not be atomic with respect
+ * to other file system activities.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to copy a file into a directory, giving it the same file
+ * name as the source file:
+ * <pre>
+ * Path source = ...
+ * Path newdir = ...
+ * Files.copy(source, newdir.resolve(source.getFileName());
+ * </pre>
+ *
+ * @param source
+ * the path to the file to copy
+ * @param target
+ * the path to the target file (may be associated with a different
+ * provider to the source path)
+ * @param options
+ * options specifying how the copy should be done
+ *
+ * @return the path to the target file
+ *
+ * @throws UnsupportedOperationException
+ * if the array contains a copy option that is not supported
+ * @throws FileAlreadyExistsException
+ * if the target file exists but cannot be replaced because the
+ * {@code REPLACE_EXISTING} option is not specified <i>(optional
+ * specific exception)</i>
+ * @throws DirectoryNotEmptyException
+ * the {@code REPLACE_EXISTING} option is specified but the file
+ * cannot be replaced because it is a non-empty directory
+ * <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the source file, the
+ * {@link SecurityManager#checkWrite(String) checkWrite} is invoked
+ * to check write access to the target file. If a symbolic link is
+ * copied the security manager is invoked to check {@link
+ * LinkPermission}{@code ("symbolic")}.
+ */
+ public static Path copy(Path source, Path target, CopyOption... options)
+ throws IOException
+ {
+ FileSystemProvider provider = provider(source);
+ if (provider(target) == provider) {
+ // same provider
+ provider.copy(source, target, options);
+ } else {
+ // different providers
+ CopyMoveHelper.copyToForeignTarget(source, target, options);
+ }
+ return target;
+ }
+
+ /**
+ * Move or rename a file to a target file.
+ *
+ * <p> By default, this method attempts to move the file to the target
+ * file, failing if the target file exists except if the source and
+ * target are the {@link #isSameFile same} file, in which case this method
+ * has no effect. If the file is a symbolic link then the symbolic link
+ * itself, not the target of the link, is moved. This method may be
+ * invoked to move an empty directory. In some implementations a directory
+ * has entries for special files or links that are created when the
+ * directory is created. In such implementations a directory is considered
+ * empty when only the special entries exist. When invoked to move a
+ * directory that is not empty then the directory is moved if it does not
+ * require moving the entries in the directory. For example, renaming a
+ * directory on the same {@link FileStore} will usually not require moving
+ * the entries in the directory. When moving a directory requires that its
+ * entries be moved then this method fails (by throwing an {@code
+ * IOException}). To move a <i>file tree</i> may involve copying rather
+ * than moving directories and this can be done using the {@link
+ * #copy copy} method in conjunction with the {@link
+ * #walkFileTree Files.walkFileTree} utility method.
+ *
+ * <p> The {@code options} parameter may include any of the following:
+ *
+ * <table border=1 cellpadding=5 summary="">
+ * <tr> <th>Option</th> <th>Description</th> </tr>
+ * <tr>
+ * <td> {@link StandardCopyOption#REPLACE_EXISTING REPLACE_EXISTING} </td>
+ * <td> If the target file exists, then the target file is replaced if it
+ * is not a non-empty directory. If the target file exists and is a
+ * symbolic link, then the symbolic link itself, not the target of
+ * the link, is replaced. </td>
+ * </tr>
+ * <tr>
+ * <td> {@link StandardCopyOption#ATOMIC_MOVE ATOMIC_MOVE} </td>
+ * <td> The move is performed as an atomic file system operation and all
+ * other options are ignored. If the target file exists then it is
+ * implementation specific if the existing file is replaced or this method
+ * fails by throwing an {@link IOException}. If the move cannot be
+ * performed as an atomic file system operation then {@link
+ * AtomicMoveNotSupportedException} is thrown. This can arise, for
+ * example, when the target location is on a different {@code FileStore}
+ * and would require that the file be copied, or target location is
+ * associated with a different provider to this object. </td>
+ * </table>
+ *
+ * <p> An implementation of this interface may support additional
+ * implementation specific options.
+ *
+ * <p> Moving a file will copy the {@link
+ * BasicFileAttributes#lastModifiedTime last-modified-time} to the target
+ * file if supported by both source and target file stores. Copying of file
+ * timestamps may result in precision loss. An implementation may also
+ * attempt to copy other file attributes but is not required to fail if the
+ * file attributes cannot be copied. When the move is performed as
+ * a non-atomic operation, and an {@code IOException} is thrown, then the
+ * state of the files is not defined. The original file and the target file
+ * may both exist, the target file may be incomplete or some of its file
+ * attributes may not been copied from the original file.
+ *
+ * <p> <b>Usage Examples:</b>
+ * Suppose we want to rename a file to "newname", keeping the file in the
+ * same directory:
+ * <pre>
+ * Path source = ...
+ * Files.move(source, source.resolveSibling("newname"));
+ * </pre>
+ * Alternatively, suppose we want to move a file to new directory, keeping
+ * the same file name, and replacing any existing file of that name in the
+ * directory:
+ * <pre>
+ * Path source = ...
+ * Path newdir = ...
+ * Files.move(source, newdir.resolve(source.getFileName()), REPLACE_EXISTING);
+ * </pre>
+ *
+ * @param source
+ * the path to the file to move
+ * @param target
+ * the path to the target file (may be associated with a different
+ * provider to the source path)
+ * @param options
+ * options specifying how the move should be done
+ *
+ * @return the path to the target file
+ *
+ * @throws UnsupportedOperationException
+ * if the array contains a copy option that is not supported
+ * @throws FileAlreadyExistsException
+ * if the target file exists but cannot be replaced because the
+ * {@code REPLACE_EXISTING} option is not specified <i>(optional
+ * specific exception)</i>
+ * @throws DirectoryNotEmptyException
+ * the {@code REPLACE_EXISTING} option is specified but the file
+ * cannot be replaced because it is a non-empty directory
+ * <i>(optional specific exception)</i>
+ * @throws AtomicMoveNotSupportedException
+ * if the options array contains the {@code ATOMIC_MOVE} option but
+ * the file cannot be moved as an atomic file system operation.
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to both the source and
+ * target file.
+ */
+ public static Path move(Path source, Path target, CopyOption... options)
+ throws IOException
+ {
+ FileSystemProvider provider = provider(source);
+ if (provider(target) == provider) {
+ // same provider
+ provider.move(source, target, options);
+ } else {
+ // different providers
+ CopyMoveHelper.moveToForeignTarget(source, target, options);
+ }
+ return target;
+ }
+
+ // -- Miscellenous --
+
+ /**
+ * Reads the target of a symbolic link <i>(optional operation)</i>.
+ *
+ * <p> If the file system supports <a href="package-summary.html#links">symbolic
+ * links</a> then this method is used to read the target of the link, failing
+ * if the file is not a symbolic link. The target of the link need not exist.
+ * The returned {@code Path} object will be associated with the same file
+ * system as {@code link}.
+ *
+ * @param link
+ * the path to the symbolic link
+ *
+ * @return a {@code Path} object representing the target of the link
+ *
+ * @throws UnsupportedOperationException
+ * if the implementation does not support symbolic links
+ * @throws NotLinkException
+ * if the target could otherwise not be read because the file
+ * is not a symbolic link <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager
+ * is installed, it checks that {@code FilePermission} has been
+ * granted with the "{@code readlink}" action to read the link.
+ */
+ public static Path readSymbolicLink(Path link) throws IOException {
+ return provider(link).readSymbolicLink(link);
+ }
+
+ /**
+ * Returns the {@link FileStore} representing the file store where a file
+ * is located.
+ *
+ * <p> Once a reference to the {@code FileStore} is obtained it is
+ * implementation specific if operations on the returned {@code FileStore},
+ * or {@link FileStoreAttributeView} objects obtained from it, continue
+ * to depend on the existence of the file. In particular the behavior is not
+ * defined for the case that the file is deleted or moved to a different
+ * file store.
+ *
+ * @param path
+ * the path to the file
+ *
+ * @return the file store where the file is stored
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file, and in
+ * addition it checks {@link RuntimePermission}<tt>
+ * ("getFileStoreAttributes")</tt>
+ */
+ public static FileStore getFileStore(Path path) throws IOException {
+ return provider(path).getFileStore(path);
+ }
+
+ /**
+ * Tests if two paths locate the same file.
+ *
+ * <p> If both {@code Path} objects are {@link Path#equals(Object) equal}
+ * then this method returns {@code true} without checking if the file exists.
+ * If the two {@code Path} objects are associated with different providers
+ * then this method returns {@code false}. Otherwise, this method checks if
+ * both {@code Path} objects locate the same file, and depending on the
+ * implementation, may require to open or access both files.
+ *
+ * <p> If the file system and files remain static, then this method implements
+ * an equivalence relation for non-null {@code Paths}.
+ * <ul>
+ * <li>It is <i>reflexive</i>: for {@code Path} {@code f},
+ * {@code isSameFile(f,f)} should return {@code true}.
+ * <li>It is <i>symmetric</i>: for two {@code Paths} {@code f} and {@code g},
+ * {@code isSameFile(f,g)} will equal {@code isSameFile(g,f)}.
+ * <li>It is <i>transitive</i>: for three {@code Paths}
+ * {@code f}, {@code g}, and {@code h}, if {@code isSameFile(f,g)} returns
+ * {@code true} and {@code isSameFile(g,h)} returns {@code true}, then
+ * {@code isSameFile(f,h)} will return return {@code true}.
+ * </ul>
+ *
+ * @param path
+ * one path to the file
+ * @param path2
+ * the other path
+ *
+ * @return {@code true} if, and only if, the two paths locate the same file
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to both files.
+ *
+ * @see java.nio.file.attribute.BasicFileAttributes#fileKey
+ */
+ public static boolean isSameFile(Path path, Path path2) throws IOException {
+ return provider(path).isSameFile(path, path2);
+ }
+
+ /**
+ * Tells whether or not a file is considered <em>hidden</em>. The exact
+ * definition of hidden is platform or provider dependent. On UNIX for
+ * example a file is considered to be hidden if its name begins with a
+ * period character ('.'). On Windows a file is considered hidden if it
+ * isn't a directory and the DOS {@link DosFileAttributes#isHidden hidden}
+ * attribute is set.
+ *
+ * <p> Depending on the implementation this method may require to access
+ * the file system to determine if the file is considered hidden.
+ *
+ * @param path
+ * the path to the file to test
+ *
+ * @return {@code true} if the file is considered hidden
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file.
+ */
+ public static boolean isHidden(Path path) throws IOException {
+ return provider(path).isHidden(path);
+ }
+
+ // lazy loading of default and installed file type detectors
+ private static class FileTypeDetectors{
+ static final FileTypeDetector defaultFileTypeDetector =
+ createDefaultFileTypeDetector();
+ static final List<FileTypeDetector> installeDetectors =
+ loadInstalledDetectors();
+
+ // creates the default file type detector
+ private static FileTypeDetector createDefaultFileTypeDetector() {
+ return AccessController
+ .doPrivileged(new PrivilegedAction<FileTypeDetector>() {
+ @Override public FileTypeDetector run() {
+ return sun.nio.fs.DefaultFileTypeDetector.create();
+ }});
+ }
+
+ // loads all installed file type detectors
+ private static List<FileTypeDetector> loadInstalledDetectors() {
+ return AccessController
+ .doPrivileged(new PrivilegedAction<List<FileTypeDetector>>() {
+ @Override public List<FileTypeDetector> run() {
+ List<FileTypeDetector> list = new ArrayList<>();
+ ServiceLoader<FileTypeDetector> loader = ServiceLoader
+ .load(FileTypeDetector.class, ClassLoader.getSystemClassLoader());
+ for (FileTypeDetector detector: loader) {
+ list.add(detector);
+ }
+ return list;
+ }});
+ }
+ }
+
+ /**
+ * Probes the content type of a file.
+ *
+ * <p> This method uses the installed {@link FileTypeDetector} implementations
+ * to probe the given file to determine its content type. Each file type
+ * detector's {@link FileTypeDetector#probeContentType probeContentType} is
+ * invoked, in turn, to probe the file type. If the file is recognized then
+ * the content type is returned. If the file is not recognized by any of the
+ * installed file type detectors then a system-default file type detector is
+ * invoked to guess the content type.
+ *
+ * <p> A given invocation of the Java virtual machine maintains a system-wide
+ * list of file type detectors. Installed file type detectors are loaded
+ * using the service-provider loading facility defined by the {@link ServiceLoader}
+ * class. Installed file type detectors are loaded using the system class
+ * loader. If the system class loader cannot be found then the extension class
+ * loader is used; If the extension class loader cannot be found then the
+ * bootstrap class loader is used. File type detectors are typically installed
+ * by placing them in a JAR file on the application class path or in the
+ * extension directory, the JAR file contains a provider-configuration file
+ * named {@code java.nio.file.spi.FileTypeDetector} in the resource directory
+ * {@code META-INF/services}, and the file lists one or more fully-qualified
+ * names of concrete subclass of {@code FileTypeDetector } that have a zero
+ * argument constructor. If the process of locating or instantiating the
+ * installed file type detectors fails then an unspecified error is thrown.
+ * The ordering that installed providers are located is implementation
+ * specific.
+ *
+ * <p> The return value of this method is the string form of the value of a
+ * Multipurpose Internet Mail Extension (MIME) content type as
+ * defined by <a href="http://www.ietf.org/rfc/rfc2045.txt"><i>RFC 2045:
+ * Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet
+ * Message Bodies</i></a>. The string is guaranteed to be parsable according
+ * to the grammar in the RFC.
+ *
+ * @param path
+ * the path to the file to probe
+ *
+ * @return The content type of the file, or {@code null} if the content
+ * type cannot be determined
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * If a security manager is installed and it denies an unspecified
+ * permission required by a file type detector implementation.
+ */
+ public static String probeContentType(Path path)
+ throws IOException
+ {
+ // try installed file type detectors
+ for (FileTypeDetector detector: FileTypeDetectors.installeDetectors) {
+ String result = detector.probeContentType(path);
+ if (result != null)
+ return result;
+ }
+
+ // fallback to default
+ return FileTypeDetectors.defaultFileTypeDetector.probeContentType(path);
+ }
+
+ // -- File Attributes --
+
+ /**
+ * Returns a file attribute view of a given type.
+ *
+ * <p> A file attribute view provides a read-only or updatable view of a
+ * set of file attributes. This method is intended to be used where the file
+ * attribute view defines type-safe methods to read or update the file
+ * attributes. The {@code type} parameter is the type of the attribute view
+ * required and the method returns an instance of that type if supported.
+ * The {@link BasicFileAttributeView} type supports access to the basic
+ * attributes of a file. Invoking this method to select a file attribute
+ * view of that type will always return an instance of that class.
+ *
+ * <p> The {@code options} array may be used to indicate how symbolic links
+ * are handled by the resulting file attribute view for the case that the
+ * file is a symbolic link. By default, symbolic links are followed. If the
+ * option {@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} is present then
+ * symbolic links are not followed. This option is ignored by implementations
+ * that do not support symbolic links.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want read or set a file's ACL, if supported:
+ * <pre>
+ * Path path = ...
+ * AclFileAttributeView view = Files.getFileAttributeView(path, AclFileAttributeView.class);
+ * if (view != null) {
+ * List<AclEntry> acl = view.getAcl();
+ * :
+ * }
+ * </pre>
+ *
+ * @param <V>
+ * The {@code FileAttributeView} type
+ * @param path
+ * the path to the file
+ * @param type
+ * the {@code Class} object corresponding to the file attribute view
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return a file attribute view of the specified type, or {@code null} if
+ * the attribute view type is not available
+ */
+ public static <V extends FileAttributeView> V getFileAttributeView(Path path,
+ Class<V> type,
+ LinkOption... options)
+ {
+ return provider(path).getFileAttributeView(path, type, options);
+ }
+
+ /**
+ * Reads a file's attributes as a bulk operation.
+ *
+ * <p> The {@code type} parameter is the type of the attributes required
+ * and this method returns an instance of that type if supported. All
+ * implementations support a basic set of file attributes and so invoking
+ * this method with a {@code type} parameter of {@code
+ * BasicFileAttributes.class} will not throw {@code
+ * UnsupportedOperationException}.
+ *
+ * <p> The {@code options} array may be used to indicate how symbolic links
+ * are handled for the case that the file is a symbolic link. By default,
+ * symbolic links are followed and the file attribute of the final target
+ * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+ *
+ * <p> It is implementation specific if all file attributes are read as an
+ * atomic operation with respect to other file system operations.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to read a file's attributes in bulk:
+ * <pre>
+ * Path path = ...
+ * BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
+ * </pre>
+ * Alternatively, suppose we want to read file's POSIX attributes without
+ * following symbolic links:
+ * <pre>
+ * PosixFileAttributes attrs = Files.readAttributes(path, PosixFileAttributes.class, NOFOLLOW_LINKS);
+ * </pre>
+ *
+ * @param <A>
+ * The {@code BasicFileAttributes} type
+ * @param path
+ * the path to the file
+ * @param type
+ * the {@code Class} of the file attributes required
+ * to read
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return the file attributes
+ *
+ * @throws UnsupportedOperationException
+ * if an attributes of the given type are not supported
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, a security manager is
+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file. If this
+ * method is invoked to read security sensitive attributes then the
+ * security manager may be invoke to check for additional permissions.
+ */
+ public static <A extends BasicFileAttributes> A readAttributes(Path path,
+ Class<A> type,
+ LinkOption... options)
+ throws IOException
+ {
+ return provider(path).readAttributes(path, type, options);
+ }
+
+ /**
+ * Sets the value of a file attribute.
+ *
+ * <p> The {@code attribute} parameter identifies the attribute to be set
+ * and takes the form:
+ * <blockquote>
+ * [<i>view-name</i><b>:</b>]<i>attribute-name</i>
+ * </blockquote>
+ * where square brackets [...] delineate an optional component and the
+ * character {@code ':'} stands for itself.
+ *
+ * <p> <i>view-name</i> is the {@link FileAttributeView#name name} of a {@link
+ * FileAttributeView} that identifies a set of file attributes. If not
+ * specified then it defaults to {@code "basic"}, the name of the file
+ * attribute view that identifies the basic set of file attributes common to
+ * many file systems. <i>attribute-name</i> is the name of the attribute
+ * within the set.
+ *
+ * <p> The {@code options} array may be used to indicate how symbolic links
+ * are handled for the case that the file is a symbolic link. By default,
+ * symbolic links are followed and the file attribute of the final target
+ * of the link is set. If the option {@link LinkOption#NOFOLLOW_LINKS
+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to set the DOS "hidden" attribute:
+ * <pre>
+ * Path path = ...
+ * Files.setAttribute(path, "dos:hidden", true);
+ * </pre>
+ *
+ * @param path
+ * the path to the file
+ * @param attribute
+ * the attribute to set
+ * @param value
+ * the attribute value
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return the {@code path} parameter
+ *
+ * @throws UnsupportedOperationException
+ * if the attribute view is not available
+ * @throws IllegalArgumentException
+ * if the attribute name is not specified, or is not recognized, or
+ * the attribute value is of the correct type but has an
+ * inappropriate value
+ * @throws ClassCastException
+ * if the attribute value is not of the expected type or is a
+ * collection containing elements that are not of the expected
+ * type
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to the file. If this method is invoked
+ * to set security sensitive attributes then the security manager
+ * may be invoked to check for additional permissions.
+ */
+ public static Path setAttribute(Path path, String attribute, Object value,
+ LinkOption... options)
+ throws IOException
+ {
+ provider(path).setAttribute(path, attribute, value, options);
+ return path;
+ }
+
+ /**
+ * Reads the value of a file attribute.
+ *
+ * <p> The {@code attribute} parameter identifies the attribute to be read
+ * and takes the form:
+ * <blockquote>
+ * [<i>view-name</i><b>:</b>]<i>attribute-name</i>
+ * </blockquote>
+ * where square brackets [...] delineate an optional component and the
+ * character {@code ':'} stands for itself.
+ *
+ * <p> <i>view-name</i> is the {@link FileAttributeView#name name} of a {@link
+ * FileAttributeView} that identifies a set of file attributes. If not
+ * specified then it defaults to {@code "basic"}, the name of the file
+ * attribute view that identifies the basic set of file attributes common to
+ * many file systems. <i>attribute-name</i> is the name of the attribute.
+ *
+ * <p> The {@code options} array may be used to indicate how symbolic links
+ * are handled for the case that the file is a symbolic link. By default,
+ * symbolic links are followed and the file attribute of the final target
+ * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we require the user ID of the file owner on a system that
+ * supports a "{@code unix}" view:
+ * <pre>
+ * Path path = ...
+ * int uid = (Integer)Files.getAttribute(path, "unix:uid");
+ * </pre>
+ *
+ * @param path
+ * the path to the file
+ * @param attribute
+ * the attribute to read
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return the attribute value
+ *
+ * @throws UnsupportedOperationException
+ * if the attribute view is not available
+ * @throws IllegalArgumentException
+ * if the attribute name is not specified or is not recognized
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
+ * method denies read access to the file. If this method is invoked
+ * to read security sensitive attributes then the security manager
+ * may be invoked to check for additional permissions.
+ */
+ public static Object getAttribute(Path path, String attribute,
+ LinkOption... options)
+ throws IOException
+ {
+ // only one attribute should be read
+ if (attribute.indexOf('*') >= 0 || attribute.indexOf(',') >= 0)
+ throw new IllegalArgumentException(attribute);
+ Map<String,Object> map = readAttributes(path, attribute, options);
+ assert map.size() == 1;
+ String name;
+ int pos = attribute.indexOf(':');
+ if (pos == -1) {
+ name = attribute;
+ } else {
+ name = (pos == attribute.length()) ? "" : attribute.substring(pos+1);
+ }
+ return map.get(name);
+ }
+
+ /**
+ * Reads a set of file attributes as a bulk operation.
+ *
+ * <p> The {@code attributes} parameter identifies the attributes to be read
+ * and takes the form:
+ * <blockquote>
+ * [<i>view-name</i><b>:</b>]<i>attribute-list</i>
+ * </blockquote>
+ * where square brackets [...] delineate an optional component and the
+ * character {@code ':'} stands for itself.
+ *
+ * <p> <i>view-name</i> is the {@link FileAttributeView#name name} of a {@link
+ * FileAttributeView} that identifies a set of file attributes. If not
+ * specified then it defaults to {@code "basic"}, the name of the file
+ * attribute view that identifies the basic set of file attributes common to
+ * many file systems.
+ *
+ * <p> The <i>attribute-list</i> component is a comma separated list of
+ * zero or more names of attributes to read. If the list contains the value
+ * {@code "*"} then all attributes are read. Attributes that are not supported
+ * are ignored and will not be present in the returned map. It is
+ * implementation specific if all attributes are read as an atomic operation
+ * with respect to other file system operations.
+ *
+ * <p> The following examples demonstrate possible values for the {@code
+ * attributes} parameter:
+ *
+ * <blockquote>
+ * <table border="0" summary="Possible values">
+ * <tr>
+ * <td> {@code "*"} </td>
+ * <td> Read all {@link BasicFileAttributes basic-file-attributes}. </td>
+ * </tr>
+ * <tr>
+ * <td> {@code "size,lastModifiedTime,lastAccessTime"} </td>
+ * <td> Reads the file size, last modified time, and last access time
+ * attributes. </td>
+ * </tr>
+ * <tr>
+ * <td> {@code "posix:*"} </td>
+ * <td> Read all {@link PosixFileAttributes POSIX-file-attributes}. </td>
+ * </tr>
+ * <tr>
+ * <td> {@code "posix:permissions,owner,size"} </td>
+ * <td> Reads the POSX file permissions, owner, and file size. </td>
+ * </tr>
+ * </table>
+ * </blockquote>
+ *
+ * <p> The {@code options} array may be used to indicate how symbolic links
+ * are handled for the case that the file is a symbolic link. By default,
+ * symbolic links are followed and the file attribute of the final target
+ * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+ *
+ * @param path
+ * the path to the file
+ * @param attributes
+ * the attributes to read
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return a map of the attributes returned; The map's keys are the
+ * attribute names, its values are the attribute values
+ *
+ * @throws UnsupportedOperationException
+ * if the attribute view is not available
+ * @throws IllegalArgumentException
+ * if no attributes are specified or an unrecognized attributes is
+ * specified
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
+ * method denies read access to the file. If this method is invoked
+ * to read security sensitive attributes then the security manager
+ * may be invoke to check for additional permissions.
+ */
+ public static Map<String,Object> readAttributes(Path path, String attributes,
+ LinkOption... options)
+ throws IOException
+ {
+ return provider(path).readAttributes(path, attributes, options);
+ }
+
+ /**
+ * Returns a file's POSIX file permissions.
+ *
+ * <p> The {@code path} parameter is associated with a {@code FileSystem}
+ * that supports the {@link PosixFileAttributeView}. This attribute view
+ * provides access to file attributes commonly associated with files on file
+ * systems used by operating systems that implement the Portable Operating
+ * System Interface (POSIX) family of standards.
+ *
+ * <p> The {@code options} array may be used to indicate how symbolic links
+ * are handled for the case that the file is a symbolic link. By default,
+ * symbolic links are followed and the file attribute of the final target
+ * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+ *
+ * @param path
+ * the path to the file
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return the file permissions
+ *
+ * @throws UnsupportedOperationException
+ * if the associated file system does not support the {@code
+ * PosixFileAttributeView}
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, a security manager is
+ * installed, and it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+ * or its {@link SecurityManager#checkRead(String) checkRead} method
+ * denies read access to the file.
+ */
+ public static Set<PosixFilePermission> getPosixFilePermissions(Path path,
+ LinkOption... options)
+ throws IOException
+ {
+ return readAttributes(path, PosixFileAttributes.class, options).permissions();
+ }
+
+ /**
+ * Sets a file's POSIX permissions.
+ *
+ * <p> The {@code path} parameter is associated with a {@code FileSystem}
+ * that supports the {@link PosixFileAttributeView}. This attribute view
+ * provides access to file attributes commonly associated with files on file
+ * systems used by operating systems that implement the Portable Operating
+ * System Interface (POSIX) family of standards.
+ *
+ * @param path
+ * The path to the file
+ * @param perms
+ * The new set of permissions
+ *
+ * @return The path
+ *
+ * @throws UnsupportedOperationException
+ * if the associated file system does not support the {@code
+ * PosixFileAttributeView}
+ * @throws ClassCastException
+ * if the sets contains elements that are not of type {@code
+ * PosixFilePermission}
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to the file.
+ */
+ public static Path setPosixFilePermissions(Path path,
+ Set<PosixFilePermission> perms)
+ throws IOException
+ {
+ PosixFileAttributeView view =
+ getFileAttributeView(path, PosixFileAttributeView.class);
+ if (view == null)
+ throw new UnsupportedOperationException();
+ view.setPermissions(perms);
+ return path;
+ }
+
+ /**
+ * Returns the owner of a file.
+ *
+ * <p> The {@code path} parameter is associated with a file system that
+ * supports {@link FileOwnerAttributeView}. This file attribute view provides
+ * access to a file attribute that is the owner of the file.
+ *
+ * @param path
+ * The path to the file
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return A user principal representing the owner of the file
+ *
+ * @throws UnsupportedOperationException
+ * if the associated file system does not support the {@code
+ * FileOwnerAttributeView}
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+ * or its {@link SecurityManager#checkRead(String) checkRead} method
+ * denies read access to the file.
+ */
+ public static UserPrincipal getOwner(Path path, LinkOption... options) throws IOException {
+ FileOwnerAttributeView view =
+ getFileAttributeView(path, FileOwnerAttributeView.class, options);
+ if (view == null)
+ throw new UnsupportedOperationException();
+ return view.getOwner();
+ }
+
+ /**
+ * Updates the file owner.
+ *
+ * <p> The {@code path} parameter is associated with a file system that
+ * supports {@link FileOwnerAttributeView}. This file attribute view provides
+ * access to a file attribute that is the owner of the file.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to make "joe" the owner of a file:
+ * <pre>
+ * Path path = ...
+ * UserPrincipalLookupService lookupService =
+ * provider(path).getUserPrincipalLookupService();
+ * UserPrincipal joe = lookupService.lookupPrincipalByName("joe");
+ * Files.setOwner(path, joe);
+ * </pre>
+ *
+ * @param path
+ * The path to the file
+ * @param owner
+ * The new file owner
+ *
+ * @return The path
+ *
+ * @throws UnsupportedOperationException
+ * if the associated file system does not support the {@code
+ * FileOwnerAttributeView}
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to the file.
+ *
+ * @see FileSystem#getUserPrincipalLookupService
+ * @see java.nio.file.attribute.UserPrincipalLookupService
+ */
+ public static Path setOwner(Path path, UserPrincipal owner)
+ throws IOException
+ {
+ FileOwnerAttributeView view =
+ getFileAttributeView(path, FileOwnerAttributeView.class);
+ if (view == null)
+ throw new UnsupportedOperationException();
+ view.setOwner(owner);
+ return path;
+ }
+
+ /**
+ * Tests whether a file is a symbolic link.
+ *
+ * <p> Where it is required to distinguish an I/O exception from the case
+ * that the file is not a symbolic link then the file attributes can be
+ * read with the {@link #readAttributes(Path,Class,LinkOption[])
+ * readAttributes} method and the file type tested with the {@link
+ * BasicFileAttributes#isSymbolicLink} method.
+ *
+ * @param path The path to the file
+ *
+ * @return {@code true} if the file is a symbolic link; {@code false} if
+ * the file does not exist, is not a symbolic link, or it cannot
+ * be determined if the file is a symbolic link or not.
+ *
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
+ * method denies read access to the file.
+ */
+ public static boolean isSymbolicLink(Path path) {
+ try {
+ return readAttributes(path,
+ BasicFileAttributes.class,
+ LinkOption.NOFOLLOW_LINKS).isSymbolicLink();
+ } catch (IOException ioe) {
+ return false;
+ }
+ }
+
+ /**
+ * Tests whether a file is a directory.
+ *
+ * <p> The {@code options} array may be used to indicate how symbolic links
+ * are handled for the case that the file is a symbolic link. By default,
+ * symbolic links are followed and the file attribute of the final target
+ * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+ *
+ * <p> Where it is required to distinguish an I/O exception from the case
+ * that the file is not a directory then the file attributes can be
+ * read with the {@link #readAttributes(Path,Class,LinkOption[])
+ * readAttributes} method and the file type tested with the {@link
+ * BasicFileAttributes#isDirectory} method.
+ *
+ * @param path
+ * the path to the file to test
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return {@code true} if the file is a directory; {@code false} if
+ * the file does not exist, is not a directory, or it cannot
+ * be determined if the file is a directory or not.
+ *
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
+ * method denies read access to the file.
+ */
+ public static boolean isDirectory(Path path, LinkOption... options) {
+ try {
+ return readAttributes(path, BasicFileAttributes.class, options).isDirectory();
+ } catch (IOException ioe) {
+ return false;
+ }
+ }
+
+ /**
+ * Tests whether a file is a regular file with opaque content.
+ *
+ * <p> The {@code options} array may be used to indicate how symbolic links
+ * are handled for the case that the file is a symbolic link. By default,
+ * symbolic links are followed and the file attribute of the final target
+ * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+ *
+ * <p> Where it is required to distinguish an I/O exception from the case
+ * that the file is not a regular file then the file attributes can be
+ * read with the {@link #readAttributes(Path,Class,LinkOption[])
+ * readAttributes} method and the file type tested with the {@link
+ * BasicFileAttributes#isRegularFile} method.
+ *
+ * @param path
+ * the path to the file
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return {@code true} if the file is a regular file; {@code false} if
+ * the file does not exist, is not a regular file, or it
+ * cannot be determined if the file is a regular file or not.
+ *
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
+ * method denies read access to the file.
+ */
+ public static boolean isRegularFile(Path path, LinkOption... options) {
+ try {
+ return readAttributes(path, BasicFileAttributes.class, options).isRegularFile();
+ } catch (IOException ioe) {
+ return false;
+ }
+ }
+
+ /**
+ * Returns a file's last modified time.
+ *
+ * <p> The {@code options} array may be used to indicate how symbolic links
+ * are handled for the case that the file is a symbolic link. By default,
+ * symbolic links are followed and the file attribute of the final target
+ * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+ *
+ * @param path
+ * the path to the file
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return a {@code FileTime} representing the time the file was last
+ * modified, or an implementation specific default when a time
+ * stamp to indicate the time of last modification is not supported
+ * by the file system
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
+ * method denies read access to the file.
+ *
+ * @see BasicFileAttributes#lastModifiedTime
+ */
+ public static FileTime getLastModifiedTime(Path path, LinkOption... options)
+ throws IOException
+ {
+ return readAttributes(path, BasicFileAttributes.class, options).lastModifiedTime();
+ }
+
+ /**
+ * Updates a file's last modified time attribute. The file time is converted
+ * to the epoch and precision supported by the file system. Converting from
+ * finer to coarser granularities result in precision loss. The behavior of
+ * this method when attempting to set the last modified time when it is not
+ * supported by the file system or is outside the range supported by the
+ * underlying file store is not defined. It may or not fail by throwing an
+ * {@code IOException}.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to set the last modified time to the current time:
+ * <pre>
+ * Path path = ...
+ * FileTime now = FileTime.fromMillis(System.currentTimeMillis());
+ * Files.setLastModifiedTime(path, now);
+ * </pre>
+ *
+ * @param path
+ * the path to the file
+ * @param time
+ * the new last modified time
+ *
+ * @return the path
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, the security manager's {@link
+ * SecurityManager#checkWrite(String) checkWrite} method is invoked
+ * to check write access to file
+ *
+ * @see BasicFileAttributeView#setTimes
+ */
+ public static Path setLastModifiedTime(Path path, FileTime time)
+ throws IOException
+ {
+ getFileAttributeView(path, BasicFileAttributeView.class)
+ .setTimes(time, null, null);
+ return path;
+ }
+
+ /**
+ * Returns the size of a file (in bytes). The size may differ from the
+ * actual size on the file system due to compression, support for sparse
+ * files, or other reasons. The size of files that are not {@link
+ * #isRegularFile regular} files is implementation specific and
+ * therefore unspecified.
+ *
+ * @param path
+ * the path to the file
+ *
+ * @return the file size, in bytes
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
+ * method denies read access to the file.
+ *
+ * @see BasicFileAttributes#size
+ */
+ public static long size(Path path) throws IOException {
+ return readAttributes(path, BasicFileAttributes.class).size();
+ }
+
+ // -- Accessibility --
+
+ /**
+ * Returns {@code false} if NOFOLLOW_LINKS is present.
+ */
+ private static boolean followLinks(LinkOption... options) {
+ boolean followLinks = true;
+ for (LinkOption opt: options) {
+ if (opt == LinkOption.NOFOLLOW_LINKS) {
+ followLinks = false;
+ continue;
+ }
+ if (opt == null)
+ throw new NullPointerException();
+ throw new AssertionError("Should not get here");
+ }
+ return followLinks;
+ }
+
+ /**
+ * Tests whether a file exists.
+ *
+ * <p> The {@code options} parameter may be used to indicate how symbolic links
+ * are handled for the case that the file is a symbolic link. By default,
+ * symbolic links are followed. If the option {@link LinkOption#NOFOLLOW_LINKS
+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+ *
+ * <p> Note that the result of this method is immediately outdated. If this
+ * method indicates the file exists then there is no guarantee that a
+ * subsequence access will succeed. Care should be taken when using this
+ * method in security sensitive applications.
+ *
+ * @param path
+ * the path to the file to test
+ * @param options
+ * options indicating how symbolic links are handled
+ * .
+ * @return {@code true} if the file exists; {@code false} if the file does
+ * not exist or its existence cannot be determined.
+ *
+ * @throws SecurityException
+ * In the case of the default provider, the {@link
+ * SecurityManager#checkRead(String)} is invoked to check
+ * read access to the file.
+ *
+ * @see #notExists
+ */
+ public static boolean exists(Path path, LinkOption... options) {
+ try {
+ if (followLinks(options)) {
+ provider(path).checkAccess(path);
+ } else {
+ // attempt to read attributes without following links
+ readAttributes(path, BasicFileAttributes.class,
+ LinkOption.NOFOLLOW_LINKS);
+ }
+ // file exists
+ return true;
+ } catch (IOException x) {
+ // does not exist or unable to determine if file exists
+ return false;
+ }
+
+ }
+
+ /**
+ * Tests whether the file located by this path does not exist. This method
+ * is intended for cases where it is required to take action when it can be
+ * confirmed that a file does not exist.
+ *
+ * <p> The {@code options} parameter may be used to indicate how symbolic links
+ * are handled for the case that the file is a symbolic link. By default,
+ * symbolic links are followed. If the option {@link LinkOption#NOFOLLOW_LINKS
+ * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+ *
+ * <p> Note that this method is not the complement of the {@link #exists
+ * exists} method. Where it is not possible to determine if a file exists
+ * or not then both methods return {@code false}. As with the {@code exists}
+ * method, the result of this method is immediately outdated. If this
+ * method indicates the file does exist then there is no guarantee that a
+ * subsequence attempt to create the file will succeed. Care should be taken
+ * when using this method in security sensitive applications.
+ *
+ * @param path
+ * the path to the file to test
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return {@code true} if the file does not exist; {@code false} if the
+ * file exists or its existence cannot be determined
+ *
+ * @throws SecurityException
+ * In the case of the default provider, the {@link
+ * SecurityManager#checkRead(String)} is invoked to check
+ * read access to the file.
+ */
+ public static boolean notExists(Path path, LinkOption... options) {
+ try {
+ if (followLinks(options)) {
+ provider(path).checkAccess(path);
+ } else {
+ // attempt to read attributes without following links
+ readAttributes(path, BasicFileAttributes.class,
+ LinkOption.NOFOLLOW_LINKS);
+ }
+ // file exists
+ return false;
+ } catch (NoSuchFileException x) {
+ // file confirmed not to exist
+ return true;
+ } catch (IOException x) {
+ return false;
+ }
+ }
+
+ /**
+ * Used by isReadbale, isWritable, isExecutable to test access to a file.
+ */
+ private static boolean isAccessible(Path path, AccessMode... modes) {
+ try {
+ provider(path).checkAccess(path, modes);
+ return true;
+ } catch (IOException x) {
+ return false;
+ }
+ }
+
+ /**
+ * Tests whether a file is readable. This method checks that a file exists
+ * and that this Java virtual machine has appropriate privileges that would
+ * allow it open the file for reading. Depending on the implementation, this
+ * method may require to read file permissions, access control lists, or
+ * other file attributes in order to check the effective access to the file.
+ * Consequently, this method may not be atomic with respect to other file
+ * system operations.
+ *
+ * <p> Note that the result of this method is immediately outdated, there is
+ * no guarantee that a subsequent attempt to open the file for reading will
+ * succeed (or even that it will access the same file). Care should be taken
+ * when using this method in security sensitive applications.
+ *
+ * @param path
+ * the path to the file to check
+ *
+ * @return {@code true} if the file exists and is readable; {@code false}
+ * if the file does not exist, read access would be denied because
+ * the Java virtual machine has insufficient privileges, or access
+ * cannot be determined
+ *
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * is invoked to check read access to the file.
+ */
+ public static boolean isReadable(Path path) {
+ return isAccessible(path, AccessMode.READ);
+ }
+
+ /**
+ * Tests whether a file is writable. This method checks that a file exists
+ * and that this Java virtual machine has appropriate privileges that would
+ * allow it open the file for writing. Depending on the implementation, this
+ * method may require to read file permissions, access control lists, or
+ * other file attributes in order to check the effective access to the file.
+ * Consequently, this method may not be atomic with respect to other file
+ * system operations.
+ *
+ * <p> Note that result of this method is immediately outdated, there is no
+ * guarantee that a subsequent attempt to open the file for writing will
+ * succeed (or even that it will access the same file). Care should be taken
+ * when using this method in security sensitive applications.
+ *
+ * @param path
+ * the path to the file to check
+ *
+ * @return {@code true} if the file exists and is writable; {@code false}
+ * if the file does not exist, write access would be denied because
+ * the Java virtual machine has insufficient privileges, or access
+ * cannot be determined
+ *
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * is invoked to check write access to the file.
+ */
+ public static boolean isWritable(Path path) {
+ return isAccessible(path, AccessMode.WRITE);
+ }
+
+ /**
+ * Tests whether a file is executable. This method checks that a file exists
+ * and that this Java virtual machine has appropriate privileges to {@link
+ * Runtime#exec execute} the file. The semantics may differ when checking
+ * access to a directory. For example, on UNIX systems, checking for
+ * execute access checks that the Java virtual machine has permission to
+ * search the directory in order to access file or subdirectories.
+ *
+ * <p> Depending on the implementation, this method may require to read file
+ * permissions, access control lists, or other file attributes in order to
+ * check the effective access to the file. Consequently, this method may not
+ * be atomic with respect to other file system operations.
+ *
+ * <p> Note that the result of this method is immediately outdated, there is
+ * no guarantee that a subsequent attempt to execute the file will succeed
+ * (or even that it will access the same file). Care should be taken when
+ * using this method in security sensitive applications.
+ *
+ * @param path
+ * the path to the file to check
+ *
+ * @return {@code true} if the file exists and is executable; {@code false}
+ * if the file does not exist, execute access would be denied because
+ * the Java virtual machine has insufficient privileges, or access
+ * cannot be determined
+ *
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkExec(String)
+ * checkExec} is invoked to check execute access to the file.
+ */
+ public static boolean isExecutable(Path path) {
+ return isAccessible(path, AccessMode.EXECUTE);
+ }
+
+ // -- Recursive operations --
+
+ /**
+ * Walks a file tree.
+ *
+ * <p> This method walks a file tree rooted at a given starting file. The
+ * file tree traversal is <em>depth-first</em> with the given {@link
+ * FileVisitor} invoked for each file encountered. File tree traversal
+ * completes when all accessible files in the tree have been visited, or a
+ * visit method returns a result of {@link FileVisitResult#TERMINATE
+ * TERMINATE}. Where a visit method terminates due an {@code IOException},
+ * an uncaught error, or runtime exception, then the traversal is terminated
+ * and the error or exception is propagated to the caller of this method.
+ *
+ * <p> For each file encountered this method attempts to read its {@link
+ * java.nio.file.attribute.BasicFileAttributes}. If the file is not a
+ * directory then the {@link FileVisitor#visitFile visitFile} method is
+ * invoked with the file attributes. If the file attributes cannot be read,
+ * due to an I/O exception, then the {@link FileVisitor#visitFileFailed
+ * visitFileFailed} method is invoked with the I/O exception.
+ *
+ * <p> Where the file is a directory, and the directory could not be opened,
+ * then the {@code visitFileFailed} method is invoked with the I/O exception,
+ * after which, the file tree walk continues, by default, at the next
+ * <em>sibling</em> of the directory.
+ *
+ * <p> Where the directory is opened successfully, then the entries in the
+ * directory, and their <em>descendants</em> are visited. When all entries
+ * have been visited, or an I/O error occurs during iteration of the
+ * directory, then the directory is closed and the visitor's {@link
+ * FileVisitor#postVisitDirectory postVisitDirectory} method is invoked.
+ * The file tree walk then continues, by default, at the next <em>sibling</em>
+ * of the directory.
+ *
+ * <p> By default, symbolic links are not automatically followed by this
+ * method. If the {@code options} parameter contains the {@link
+ * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then symbolic links are
+ * followed. When following links, and the attributes of the target cannot
+ * be read, then this method attempts to get the {@code BasicFileAttributes}
+ * of the link. If they can be read then the {@code visitFile} method is
+ * invoked with the attributes of the link (otherwise the {@code visitFileFailed}
+ * method is invoked as specified above).
+ *
+ * <p> If the {@code options} parameter contains the {@link
+ * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then this method keeps
+ * track of directories visited so that cycles can be detected. A cycle
+ * arises when there is an entry in a directory that is an ancestor of the
+ * directory. Cycle detection is done by recording the {@link
+ * java.nio.file.attribute.BasicFileAttributes#fileKey file-key} of directories,
+ * or if file keys are not available, by invoking the {@link #isSameFile
+ * isSameFile} method to test if a directory is the same file as an
+ * ancestor. When a cycle is detected it is treated as an I/O error, and the
+ * {@link FileVisitor#visitFileFailed visitFileFailed} method is invoked with
+ * an instance of {@link FileSystemLoopException}.
+ *
+ * <p> The {@code maxDepth} parameter is the maximum number of levels of
+ * directories to visit. A value of {@code 0} means that only the starting
+ * file is visited, unless denied by the security manager. A value of
+ * {@link Integer#MAX_VALUE MAX_VALUE} may be used to indicate that all
+ * levels should be visited. The {@code visitFile} method is invoked for all
+ * files, including directories, encountered at {@code maxDepth}, unless the
+ * basic file attributes cannot be read, in which case the {@code
+ * visitFileFailed} method is invoked.
+ *
+ * <p> If a visitor returns a result of {@code null} then {@code
+ * NullPointerException} is thrown.
+ *
+ * <p> When a security manager is installed and it denies access to a file
+ * (or directory), then it is ignored and the visitor is not invoked for
+ * that file (or directory).
+ *
+ * @param start
+ * the starting file
+ * @param options
+ * options to configure the traversal
+ * @param maxDepth
+ * the maximum number of directory levels to visit
+ * @param visitor
+ * the file visitor to invoke for each file
+ *
+ * @return the starting file
+ *
+ * @throws IllegalArgumentException
+ * if the {@code maxDepth} parameter is negative
+ * @throws SecurityException
+ * If the security manager denies access to the starting file.
+ * In the case of the default provider, the {@link
+ * SecurityManager#checkRead(String) checkRead} method is invoked
+ * to check read access to the directory.
+ * @throws IOException
+ * if an I/O error is thrown by a visitor method
+ */
+ public static Path walkFileTree(Path start,
+ Set<FileVisitOption> options,
+ int maxDepth,
+ FileVisitor<? super Path> visitor)
+ throws IOException
+ {
+ /**
+ * Create a FileTreeWalker to walk the file tree, invoking the visitor
+ * for each event.
+ */
+ try (FileTreeWalker walker = new FileTreeWalker(options, maxDepth)) {
+ FileTreeWalker.Event ev = walker.walk(start);
+ do {
+ FileVisitResult result;
+ switch (ev.type()) {
+ case ENTRY :
+ IOException ioe = ev.ioeException();
+ if (ioe == null) {
+ assert ev.attributes() != null;
+ result = visitor.visitFile(ev.file(), ev.attributes());
+ } else {
+ result = visitor.visitFileFailed(ev.file(), ioe);
+ }
+ break;
+
+ case START_DIRECTORY :
+ result = visitor.preVisitDirectory(ev.file(), ev.attributes());
+
+ // if SKIP_SIBLINGS and SKIP_SUBTREE is returned then
+ // there shouldn't be any more events for the current
+ // directory.
+ if (result == FileVisitResult.SKIP_SUBTREE ||
+ result == FileVisitResult.SKIP_SIBLINGS)
+ walker.pop();
+ break;
+
+ case END_DIRECTORY :
+ result = visitor.postVisitDirectory(ev.file(), ev.ioeException());
+
+ // SKIP_SIBLINGS is a no-op for postVisitDirectory
+ if (result == FileVisitResult.SKIP_SIBLINGS)
+ result = FileVisitResult.CONTINUE;
+ break;
+
+ default :
+ throw new AssertionError("Should not get here");
+ }
+
+ if (Objects.requireNonNull(result) != FileVisitResult.CONTINUE) {
+ if (result == FileVisitResult.TERMINATE) {
+ break;
+ } else if (result == FileVisitResult.SKIP_SIBLINGS) {
+ walker.skipRemainingSiblings();
+ }
+ }
+ ev = walker.next();
+ } while (ev != null);
+ }
+
+ return start;
+ }
+
+ /**
+ * Walks a file tree.
+ *
+ * <p> This method works as if invoking it were equivalent to evaluating the
+ * expression:
+ * <blockquote><pre>
+ * walkFileTree(start, EnumSet.noneOf(FileVisitOption.class), Integer.MAX_VALUE, visitor)
+ * </pre></blockquote>
+ * In other words, it does not follow symbolic links, and visits all levels
+ * of the file tree.
+ *
+ * @param start
+ * the starting file
+ * @param visitor
+ * the file visitor to invoke for each file
+ *
+ * @return the starting file
+ *
+ * @throws SecurityException
+ * If the security manager denies access to the starting file.
+ * In the case of the default provider, the {@link
+ * SecurityManager#checkRead(String) checkRead} method is invoked
+ * to check read access to the directory.
+ * @throws IOException
+ * if an I/O error is thrown by a visitor method
+ */
+ public static Path walkFileTree(Path start, FileVisitor<? super Path> visitor)
+ throws IOException
+ {
+ return walkFileTree(start,
+ EnumSet.noneOf(FileVisitOption.class),
+ Integer.MAX_VALUE,
+ visitor);
+ }
+
+
+ // -- Utility methods for simple usages --
+
+ // buffer size used for reading and writing
+ private static final int BUFFER_SIZE = 8192;
+
+ /**
+ * Opens a file for reading, returning a {@code BufferedReader} that may be
+ * used to read text from the file in an efficient manner. Bytes from the
+ * file are decoded into characters using the specified charset. Reading
+ * commences at the beginning of the file.
+ *
+ * <p> The {@code Reader} methods that read from the file throw {@code
+ * IOException} if a malformed or unmappable byte sequence is read.
+ *
+ * @param path
+ * the path to the file
+ * @param cs
+ * the charset to use for decoding
+ *
+ * @return a new buffered reader, with default buffer size, to read text
+ * from the file
+ *
+ * @throws IOException
+ * if an I/O error occurs opening the file
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file.
+ *
+ * @see #readAllLines
+ */
+ public static BufferedReader newBufferedReader(Path path, Charset cs)
+ throws IOException
+ {
+ CharsetDecoder decoder = cs.newDecoder();
+ Reader reader = new InputStreamReader(newInputStream(path), decoder);
+ return new BufferedReader(reader);
+ }
+
+ /**
+ * Opens a file for reading, returning a {@code BufferedReader} to read text
+ * from the file in an efficient manner. Bytes from the file are decoded into
+ * characters using the {@link StandardCharsets#UTF_8 UTF-8} {@link Charset
+ * charset}.
+ *
+ * <p> This method works as if invoking it were equivalent to evaluating the
+ * expression:
+ * <pre>{@code
+ * Files.newBufferedReader(path, StandardCharsets.UTF_8)
+ * }</pre>
+ *
+ * @param path
+ * the path to the file
+ *
+ * @return a new buffered reader, with default buffer size, to read text
+ * from the file
+ *
+ * @throws IOException
+ * if an I/O error occurs opening the file
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file.
+ *
+ * @since 1.8
+ */
+ public static BufferedReader newBufferedReader(Path path) throws IOException {
+ return newBufferedReader(path, StandardCharsets.UTF_8);
+ }
+
+ /**
+ * Opens or creates a file for writing, returning a {@code BufferedWriter}
+ * that may be used to write text to the file in an efficient manner.
+ * The {@code options} parameter specifies how the the file is created or
+ * opened. If no options are present then this method works as if the {@link
+ * StandardOpenOption#CREATE CREATE}, {@link
+ * StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING}, and {@link
+ * StandardOpenOption#WRITE WRITE} options are present. In other words, it
+ * opens the file for writing, creating the file if it doesn't exist, or
+ * initially truncating an existing {@link #isRegularFile regular-file} to
+ * a size of {@code 0} if it exists.
+ *
+ * <p> The {@code Writer} methods to write text throw {@code IOException}
+ * if the text cannot be encoded using the specified charset.
+ *
+ * @param path
+ * the path to the file
+ * @param cs
+ * the charset to use for encoding
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return a new buffered writer, with default buffer size, to write text
+ * to the file
+ *
+ * @throws IOException
+ * if an I/O error occurs opening or creating the file
+ * @throws UnsupportedOperationException
+ * if an unsupported option is specified
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to the file.
+ *
+ * @see #write(Path,Iterable,Charset,OpenOption[])
+ */
+ public static BufferedWriter newBufferedWriter(Path path, Charset cs,
+ OpenOption... options)
+ throws IOException
+ {
+ CharsetEncoder encoder = cs.newEncoder();
+ Writer writer = new OutputStreamWriter(newOutputStream(path, options), encoder);
+ return new BufferedWriter(writer);
+ }
+
+ /**
+ * Opens or creates a file for writing, returning a {@code BufferedWriter}
+ * to write text to the file in an efficient manner. The text is encoded
+ * into bytes for writing using the {@link StandardCharsets#UTF_8 UTF-8}
+ * {@link Charset charset}.
+ *
+ * <p> This method works as if invoking it were equivalent to evaluating the
+ * expression:
+ * <pre>{@code
+ * Files.newBufferedWriter(path, StandardCharsets.UTF_8, options)
+ * }</pre>
+ *
+ * @param path
+ * the path to the file
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return a new buffered writer, with default buffer size, to write text
+ * to the file
+ *
+ * @throws IOException
+ * if an I/O error occurs opening or creating the file
+ * @throws UnsupportedOperationException
+ * if an unsupported option is specified
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to the file.
+ *
+ * @since 1.8
+ */
+ public static BufferedWriter newBufferedWriter(Path path, OpenOption... options) throws IOException {
+ return newBufferedWriter(path, StandardCharsets.UTF_8, options);
+ }
+
+ /**
+ * Reads all bytes from an input stream and writes them to an output stream.
+ */
+ private static long copy(InputStream source, OutputStream sink)
+ throws IOException
+ {
+ long nread = 0L;
+ byte[] buf = new byte[BUFFER_SIZE];
+ int n;
+ while ((n = source.read(buf)) > 0) {
+ sink.write(buf, 0, n);
+ nread += n;
+ }
+ return nread;
+ }
+
+ /**
+ * Copies all bytes from an input stream to a file. On return, the input
+ * stream will be at end of stream.
+ *
+ * <p> By default, the copy fails if the target file already exists or is a
+ * symbolic link. If the {@link StandardCopyOption#REPLACE_EXISTING
+ * REPLACE_EXISTING} option is specified, and the target file already exists,
+ * then it is replaced if it is not a non-empty directory. If the target
+ * file exists and is a symbolic link, then the symbolic link is replaced.
+ * In this release, the {@code REPLACE_EXISTING} option is the only option
+ * required to be supported by this method. Additional options may be
+ * supported in future releases.
+ *
+ * <p> If an I/O error occurs reading from the input stream or writing to
+ * the file, then it may do so after the target file has been created and
+ * after some bytes have been read or written. Consequently the input
+ * stream may not be at end of stream and may be in an inconsistent state.
+ * It is strongly recommended that the input stream be promptly closed if an
+ * I/O error occurs.
+ *
+ * <p> This method may block indefinitely reading from the input stream (or
+ * writing to the file). The behavior for the case that the input stream is
+ * <i>asynchronously closed</i> or the thread interrupted during the copy is
+ * highly input stream and file system provider specific and therefore not
+ * specified.
+ *
+ * <p> <b>Usage example</b>: Suppose we want to capture a web page and save
+ * it to a file:
+ * <pre>
+ * Path path = ...
+ * URI u = URI.create("http://java.sun.com/");
+ * try (InputStream in = u.toURL().openStream()) {
+ * Files.copy(in, path);
+ * }
+ * </pre>
+ *
+ * @param in
+ * the input stream to read from
+ * @param target
+ * the path to the file
+ * @param options
+ * options specifying how the copy should be done
+ *
+ * @return the number of bytes read or written
+ *
+ * @throws IOException
+ * if an I/O error occurs when reading or writing
+ * @throws FileAlreadyExistsException
+ * if the target file exists but cannot be replaced because the
+ * {@code REPLACE_EXISTING} option is not specified <i>(optional
+ * specific exception)</i>
+ * @throws DirectoryNotEmptyException
+ * the {@code REPLACE_EXISTING} option is specified but the file
+ * cannot be replaced because it is a non-empty directory
+ * <i>(optional specific exception)</i> *
+ * @throws UnsupportedOperationException
+ * if {@code options} contains a copy option that is not supported
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to the file. Where the
+ * {@code REPLACE_EXISTING} option is specified, the security
+ * manager's {@link SecurityManager#checkDelete(String) checkDelete}
+ * method is invoked to check that an existing file can be deleted.
+ */
+ public static long copy(InputStream in, Path target, CopyOption... options)
+ throws IOException
+ {
+ // ensure not null before opening file
+ Objects.requireNonNull(in);
+
+ // check for REPLACE_EXISTING
+ boolean replaceExisting = false;
+ for (CopyOption opt: options) {
+ if (opt == StandardCopyOption.REPLACE_EXISTING) {
+ replaceExisting = true;
+ } else {
+ if (opt == null) {
+ throw new NullPointerException("options contains 'null'");
+ } else {
+ throw new UnsupportedOperationException(opt + " not supported");
+ }
+ }
+ }
+
+ // attempt to delete an existing file
+ SecurityException se = null;
+ if (replaceExisting) {
+ try {
+ deleteIfExists(target);
+ } catch (SecurityException x) {
+ se = x;
+ }
+ }
+
+ // attempt to create target file. If it fails with
+ // FileAlreadyExistsException then it may be because the security
+ // manager prevented us from deleting the file, in which case we just
+ // throw the SecurityException.
+ OutputStream ostream;
+ try {
+ ostream = newOutputStream(target, StandardOpenOption.CREATE_NEW,
+ StandardOpenOption.WRITE);
+ } catch (FileAlreadyExistsException x) {
+ if (se != null)
+ throw se;
+ // someone else won the race and created the file
+ throw x;
+ }
+
+ // do the copy
+ try (OutputStream out = ostream) {
+ return copy(in, out);
+ }
+ }
+
+ /**
+ * Copies all bytes from a file to an output stream.
+ *
+ * <p> If an I/O error occurs reading from the file or writing to the output
+ * stream, then it may do so after some bytes have been read or written.
+ * Consequently the output stream may be in an inconsistent state. It is
+ * strongly recommended that the output stream be promptly closed if an I/O
+ * error occurs.
+ *
+ * <p> This method may block indefinitely writing to the output stream (or
+ * reading from the file). The behavior for the case that the output stream
+ * is <i>asynchronously closed</i> or the thread interrupted during the copy
+ * is highly output stream and file system provider specific and therefore
+ * not specified.
+ *
+ * <p> Note that if the given output stream is {@link java.io.Flushable}
+ * then its {@link java.io.Flushable#flush flush} method may need to invoked
+ * after this method completes so as to flush any buffered output.
+ *
+ * @param source
+ * the path to the file
+ * @param out
+ * the output stream to write to
+ *
+ * @return the number of bytes read or written
+ *
+ * @throws IOException
+ * if an I/O error occurs when reading or writing
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file.
+ */
+ public static long copy(Path source, OutputStream out) throws IOException {
+ // ensure not null before opening file
+ Objects.requireNonNull(out);
+
+ try (InputStream in = newInputStream(source)) {
+ return copy(in, out);
+ }
+ }
+
+ /**
+ * The maximum size of array to allocate.
+ * Some VMs reserve some header words in an array.
+ * Attempts to allocate larger arrays may result in
+ * OutOfMemoryError: Requested array size exceeds VM limit
+ */
+ private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
+
+ /**
+ * Reads all the bytes from an input stream. Uses {@code initialSize} as a hint
+ * about how many bytes the stream will have.
+ *
+ * @param source
+ * the input stream to read from
+ * @param initialSize
+ * the initial size of the byte array to allocate
+ *
+ * @return a byte array containing the bytes read from the file
+ *
+ * @throws IOException
+ * if an I/O error occurs reading from the stream
+ * @throws OutOfMemoryError
+ * if an array of the required size cannot be allocated
+ */
+ private static byte[] read(InputStream source, int initialSize) throws IOException {
+ int capacity = initialSize;
+ byte[] buf = new byte[capacity];
+ int nread = 0;
+ int n;
+ for (;;) {
+ // read to EOF which may read more or less than initialSize (eg: file
+ // is truncated while we are reading)
+ while ((n = source.read(buf, nread, capacity - nread)) > 0)
+ nread += n;
+
+ // if last call to source.read() returned -1, we are done
+ // otherwise, try to read one more byte; if that failed we're done too
+ if (n < 0 || (n = source.read()) < 0)
+ break;
+
+ // one more byte was read; need to allocate a larger buffer
+ if (capacity <= MAX_BUFFER_SIZE - capacity) {
+ capacity = Math.max(capacity << 1, BUFFER_SIZE);
+ } else {
+ if (capacity == MAX_BUFFER_SIZE)
+ throw new OutOfMemoryError("Required array size too large");
+ capacity = MAX_BUFFER_SIZE;
+ }
+ buf = Arrays.copyOf(buf, capacity);
+ buf[nread++] = (byte)n;
+ }
+ return (capacity == nread) ? buf : Arrays.copyOf(buf, nread);
+ }
+
+ /**
+ * Reads all the bytes from a file. The method ensures that the file is
+ * closed when all bytes have been read or an I/O error, or other runtime
+ * exception, is thrown.
+ *
+ * <p> Note that this method is intended for simple cases where it is
+ * convenient to read all bytes into a byte array. It is not intended for
+ * reading in large files.
+ *
+ * @param path
+ * the path to the file
+ *
+ * @return a byte array containing the bytes read from the file
+ *
+ * @throws IOException
+ * if an I/O error occurs reading from the stream
+ * @throws OutOfMemoryError
+ * if an array of the required size cannot be allocated, for
+ * example the file is larger that {@code 2GB}
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file.
+ */
+ public static byte[] readAllBytes(Path path) throws IOException {
+ try (SeekableByteChannel sbc = Files.newByteChannel(path);
+ InputStream in = Channels.newInputStream(sbc)) {
+ long size = sbc.size();
+ if (size > (long)MAX_BUFFER_SIZE)
+ throw new OutOfMemoryError("Required array size too large");
+
+ return read(in, (int)size);
+ }
+ }
+
+ /**
+ * Read all lines from a file. This method ensures that the file is
+ * closed when all bytes have been read or an I/O error, or other runtime
+ * exception, is thrown. Bytes from the file are decoded into characters
+ * using the specified charset.
+ *
+ * <p> This method recognizes the following as line terminators:
+ * <ul>
+ * <li> <code>\u000D</code> followed by <code>\u000A</code>,
+ * CARRIAGE RETURN followed by LINE FEED </li>
+ * <li> <code>\u000A</code>, LINE FEED </li>
+ * <li> <code>\u000D</code>, CARRIAGE RETURN </li>
+ * </ul>
+ * <p> Additional Unicode line terminators may be recognized in future
+ * releases.
+ *
+ * <p> Note that this method is intended for simple cases where it is
+ * convenient to read all lines in a single operation. It is not intended
+ * for reading in large files.
+ *
+ * @param path
+ * the path to the file
+ * @param cs
+ * the charset to use for decoding
+ *
+ * @return the lines from the file as a {@code List}; whether the {@code
+ * List} is modifiable or not is implementation dependent and
+ * therefore not specified
+ *
+ * @throws IOException
+ * if an I/O error occurs reading from the file or a malformed or
+ * unmappable byte sequence is read
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file.
+ *
+ * @see #newBufferedReader
+ */
+ public static List<String> readAllLines(Path path, Charset cs) throws IOException {
+ try (BufferedReader reader = newBufferedReader(path, cs)) {
+ List<String> result = new ArrayList<>();
+ for (;;) {
+ String line = reader.readLine();
+ if (line == null)
+ break;
+ result.add(line);
+ }
+ return result;
+ }
+ }
+
+ /**
+ * Read all lines from a file. Bytes from the file are decoded into characters
+ * using the {@link StandardCharsets#UTF_8 UTF-8} {@link Charset charset}.
+ *
+ * <p> This method works as if invoking it were equivalent to evaluating the
+ * expression:
+ * <pre>{@code
+ * Files.readAllLines(path, StandardCharsets.UTF_8)
+ * }</pre>
+ *
+ * @param path
+ * the path to the file
+ *
+ * @return the lines from the file as a {@code List}; whether the {@code
+ * List} is modifiable or not is implementation dependent and
+ * therefore not specified
+ *
+ * @throws IOException
+ * if an I/O error occurs reading from the file or a malformed or
+ * unmappable byte sequence is read
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file.
+ *
+ * @since 1.8
+ */
+ public static List<String> readAllLines(Path path) throws IOException {
+ return readAllLines(path, StandardCharsets.UTF_8);
+ }
+
+ /**
+ * Writes bytes to a file. The {@code options} parameter specifies how the
+ * the file is created or opened. If no options are present then this method
+ * works as if the {@link StandardOpenOption#CREATE CREATE}, {@link
+ * StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING}, and {@link
+ * StandardOpenOption#WRITE WRITE} options are present. In other words, it
+ * opens the file for writing, creating the file if it doesn't exist, or
+ * initially truncating an existing {@link #isRegularFile regular-file} to
+ * a size of {@code 0}. All bytes in the byte array are written to the file.
+ * The method ensures that the file is closed when all bytes have been
+ * written (or an I/O error or other runtime exception is thrown). If an I/O
+ * error occurs then it may do so after the file has created or truncated,
+ * or after some bytes have been written to the file.
+ *
+ * <p> <b>Usage example</b>: By default the method creates a new file or
+ * overwrites an existing file. Suppose you instead want to append bytes
+ * to an existing file:
+ * <pre>
+ * Path path = ...
+ * byte[] bytes = ...
+ * Files.write(path, bytes, StandardOpenOption.APPEND);
+ * </pre>
+ *
+ * @param path
+ * the path to the file
+ * @param bytes
+ * the byte array with the bytes to write
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return the path
+ *
+ * @throws IOException
+ * if an I/O error occurs writing to or creating the file
+ * @throws UnsupportedOperationException
+ * if an unsupported option is specified
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to the file.
+ */
+ public static Path write(Path path, byte[] bytes, OpenOption... options)
+ throws IOException
+ {
+ // ensure bytes is not null before opening file
+ Objects.requireNonNull(bytes);
+
+ try (OutputStream out = Files.newOutputStream(path, options)) {
+ int len = bytes.length;
+ int rem = len;
+ while (rem > 0) {
+ int n = Math.min(rem, BUFFER_SIZE);
+ out.write(bytes, (len-rem), n);
+ rem -= n;
+ }
+ }
+ return path;
+ }
+
+ /**
+ * Write lines of text to a file. Each line is a char sequence and is
+ * written to the file in sequence with each line terminated by the
+ * platform's line separator, as defined by the system property {@code
+ * line.separator}. Characters are encoded into bytes using the specified
+ * charset.
+ *
+ * <p> The {@code options} parameter specifies how the the file is created
+ * or opened. If no options are present then this method works as if the
+ * {@link StandardOpenOption#CREATE CREATE}, {@link
+ * StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING}, and {@link
+ * StandardOpenOption#WRITE WRITE} options are present. In other words, it
+ * opens the file for writing, creating the file if it doesn't exist, or
+ * initially truncating an existing {@link #isRegularFile regular-file} to
+ * a size of {@code 0}. The method ensures that the file is closed when all
+ * lines have been written (or an I/O error or other runtime exception is
+ * thrown). If an I/O error occurs then it may do so after the file has
+ * created or truncated, or after some bytes have been written to the file.
+ *
+ * @param path
+ * the path to the file
+ * @param lines
+ * an object to iterate over the char sequences
+ * @param cs
+ * the charset to use for encoding
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return the path
+ *
+ * @throws IOException
+ * if an I/O error occurs writing to or creating the file, or the
+ * text cannot be encoded using the specified charset
+ * @throws UnsupportedOperationException
+ * if an unsupported option is specified
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to the file.
+ */
+ public static Path write(Path path, Iterable<? extends CharSequence> lines,
+ Charset cs, OpenOption... options)
+ throws IOException
+ {
+ // ensure lines is not null before opening file
+ Objects.requireNonNull(lines);
+ CharsetEncoder encoder = cs.newEncoder();
+ OutputStream out = newOutputStream(path, options);
+ try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, encoder))) {
+ for (CharSequence line: lines) {
+ writer.append(line);
+ writer.newLine();
+ }
+ }
+ return path;
+ }
+
+ /**
+ * Write lines of text to a file. Characters are encoded into bytes using
+ * the {@link StandardCharsets#UTF_8 UTF-8} {@link Charset charset}.
+ *
+ * <p> This method works as if invoking it were equivalent to evaluating the
+ * expression:
+ * <pre>{@code
+ * Files.write(path, lines, StandardCharsets.UTF_8, options);
+ * }</pre>
+ *
+ * @param path
+ * the path to the file
+ * @param lines
+ * an object to iterate over the char sequences
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return the path
+ *
+ * @throws IOException
+ * if an I/O error occurs writing to or creating the file, or the
+ * text cannot be encoded as {@code UTF-8}
+ * @throws UnsupportedOperationException
+ * if an unsupported option is specified
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to the file.
+ *
+ * @since 1.8
+ */
+ public static Path write(Path path,
+ Iterable<? extends CharSequence> lines,
+ OpenOption... options)
+ throws IOException
+ {
+ return write(path, lines, StandardCharsets.UTF_8, options);
+ }
+
+ // -- Stream APIs --
+
+ /**
+ * Return a lazily populated {@code Stream}, the elements of
+ * which are the entries in the directory. The listing is not recursive.
+ *
+ * <p> The elements of the stream are {@link Path} objects that are
+ * obtained as if by {@link Path#resolve(Path) resolving} the name of the
+ * directory entry against {@code dir}. Some file systems maintain special
+ * links to the directory itself and the directory's parent directory.
+ * Entries representing these links are not included.
+ *
+ * <p> The stream is <i>weakly consistent</i>. It is thread safe but does
+ * not freeze the directory while iterating, so it may (or may not)
+ * reflect updates to the directory that occur after returning from this
+ * method.
+ *
+ * <p> The returned stream encapsulates a {@link DirectoryStream}.
+ * If timely disposal of file system resources is required, the
+ * {@code try}-with-resources construct should be used to ensure that the
+ * stream's {@link Stream#close close} method is invoked after the stream
+ * operations are completed.
+ *
+ * <p> Operating on a closed stream behaves as if the end of stream
+ * has been reached. Due to read-ahead, one or more elements may be
+ * returned after the stream has been closed.
+ *
+ * <p> If an {@link IOException} is thrown when accessing the directory
+ * after this method has returned, it is wrapped in an {@link
+ * UncheckedIOException} which will be thrown from the method that caused
+ * the access to take place.
+ *
+ * @param dir The path to the directory
+ *
+ * @return The {@code Stream} describing the content of the
+ * directory
+ *
+ * @throws NotDirectoryException
+ * if the file could not otherwise be opened because it is not
+ * a directory <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs when opening the directory
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the directory.
+ *
+ * @see #newDirectoryStream(Path)
+ * @since 1.8
+ */
+ public static Stream<Path> list(Path dir) throws IOException {
+ DirectoryStream<Path> ds = Files.newDirectoryStream(dir);
+ try {
+ final Iterator<Path> delegate = ds.iterator();
+
+ // Re-wrap DirectoryIteratorException to UncheckedIOException
+ Iterator<Path> it = new Iterator<Path>() {
+ @Override
+ public boolean hasNext() {
+ try {
+ return delegate.hasNext();
+ } catch (DirectoryIteratorException e) {
+ throw new UncheckedIOException(e.getCause());
+ }
+ }
+ @Override
+ public Path next() {
+ try {
+ return delegate.next();
+ } catch (DirectoryIteratorException e) {
+ throw new UncheckedIOException(e.getCause());
+ }
+ }
+ };
+
+ return StreamSupport.stream(Spliterators.spliteratorUnknownSize(it, Spliterator.DISTINCT), false)
+ .onClose(asUncheckedRunnable(ds));
+ } catch (Error|RuntimeException e) {
+ try {
+ ds.close();
+ } catch (IOException ex) {
+ try {
+ e.addSuppressed(ex);
+ } catch (Throwable ignore) {}
+ }
+ throw e;
+ }
+ }
+
+ /**
+ * Return a {@code Stream} that is lazily populated with {@code
+ * Path} by walking the file tree rooted at a given starting file. The
+ * file tree is traversed <em>depth-first</em>, the elements in the stream
+ * are {@link Path} objects that are obtained as if by {@link
+ * Path#resolve(Path) resolving} the relative path against {@code start}.
+ *
+ * <p> The {@code stream} walks the file tree as elements are consumed.
+ * The {@code Stream} returned is guaranteed to have at least one
+ * element, the starting file itself. For each file visited, the stream
+ * attempts to read its {@link BasicFileAttributes}. If the file is a
+ * directory and can be opened successfully, entries in the directory, and
+ * their <em>descendants</em> will follow the directory in the stream as
+ * they are encountered. When all entries have been visited, then the
+ * directory is closed. The file tree walk then continues at the next
+ * <em>sibling</em> of the directory.
+ *
+ * <p> The stream is <i>weakly consistent</i>. It does not freeze the
+ * file tree while iterating, so it may (or may not) reflect updates to
+ * the file tree that occur after returned from this method.
+ *
+ * <p> By default, symbolic links are not automatically followed by this
+ * method. If the {@code options} parameter contains the {@link
+ * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then symbolic links are
+ * followed. When following links, and the attributes of the target cannot
+ * be read, then this method attempts to get the {@code BasicFileAttributes}
+ * of the link.
+ *
+ * <p> If the {@code options} parameter contains the {@link
+ * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then the stream keeps
+ * track of directories visited so that cycles can be detected. A cycle
+ * arises when there is an entry in a directory that is an ancestor of the
+ * directory. Cycle detection is done by recording the {@link
+ * java.nio.file.attribute.BasicFileAttributes#fileKey file-key} of directories,
+ * or if file keys are not available, by invoking the {@link #isSameFile
+ * isSameFile} method to test if a directory is the same file as an
+ * ancestor. When a cycle is detected it is treated as an I/O error with
+ * an instance of {@link FileSystemLoopException}.
+ *
+ * <p> The {@code maxDepth} parameter is the maximum number of levels of
+ * directories to visit. A value of {@code 0} means that only the starting
+ * file is visited, unless denied by the security manager. A value of
+ * {@link Integer#MAX_VALUE MAX_VALUE} may be used to indicate that all
+ * levels should be visited.
+ *
+ * <p> When a security manager is installed and it denies access to a file
+ * (or directory), then it is ignored and not included in the stream.
+ *
+ * <p> The returned stream encapsulates one or more {@link DirectoryStream}s.
+ * If timely disposal of file system resources is required, the
+ * {@code try}-with-resources construct should be used to ensure that the
+ * stream's {@link Stream#close close} method is invoked after the stream
+ * operations are completed. Operating on a closed stream will result in an
+ * {@link java.lang.IllegalStateException}.
+ *
+ * <p> If an {@link IOException} is thrown when accessing the directory
+ * after this method has returned, it is wrapped in an {@link
+ * UncheckedIOException} which will be thrown from the method that caused
+ * the access to take place.
+ *
+ * @param start
+ * the starting file
+ * @param maxDepth
+ * the maximum number of directory levels to visit
+ * @param options
+ * options to configure the traversal
+ *
+ * @return the {@link Stream} of {@link Path}
+ *
+ * @throws IllegalArgumentException
+ * if the {@code maxDepth} parameter is negative
+ * @throws SecurityException
+ * If the security manager denies access to the starting file.
+ * In the case of the default provider, the {@link
+ * SecurityManager#checkRead(String) checkRead} method is invoked
+ * to check read access to the directory.
+ * @throws IOException
+ * if an I/O error is thrown when accessing the starting file.
+ * @since 1.8
+ */
+ public static Stream<Path> walk(Path start,
+ int maxDepth,
+ FileVisitOption... options)
+ throws IOException
+ {
+ FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options);
+ try {
+ return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT), false)
+ .onClose(iterator::close)
+ .map(entry -> entry.file());
+ } catch (Error|RuntimeException e) {
+ iterator.close();
+ throw e;
+ }
+ }
+
+ /**
+ * Return a {@code Stream} that is lazily populated with {@code
+ * Path} by walking the file tree rooted at a given starting file. The
+ * file tree is traversed <em>depth-first</em>, the elements in the stream
+ * are {@link Path} objects that are obtained as if by {@link
+ * Path#resolve(Path) resolving} the relative path against {@code start}.
+ *
+ * <p> This method works as if invoking it were equivalent to evaluating the
+ * expression:
+ * <blockquote><pre>
+ * walk(start, Integer.MAX_VALUE, options)
+ * </pre></blockquote>
+ * In other words, it visits all levels of the file tree.
+ *
+ * <p> The returned stream encapsulates one or more {@link DirectoryStream}s.
+ * If timely disposal of file system resources is required, the
+ * {@code try}-with-resources construct should be used to ensure that the
+ * stream's {@link Stream#close close} method is invoked after the stream
+ * operations are completed. Operating on a closed stream will result in an
+ * {@link java.lang.IllegalStateException}.
+ *
+ * @param start
+ * the starting file
+ * @param options
+ * options to configure the traversal
+ *
+ * @return the {@link Stream} of {@link Path}
+ *
+ * @throws SecurityException
+ * If the security manager denies access to the starting file.
+ * In the case of the default provider, the {@link
+ * SecurityManager#checkRead(String) checkRead} method is invoked
+ * to check read access to the directory.
+ * @throws IOException
+ * if an I/O error is thrown when accessing the starting file.
+ *
+ * @see #walk(Path, int, FileVisitOption...)
+ * @since 1.8
+ */
+ public static Stream<Path> walk(Path start, FileVisitOption... options) throws IOException {
+ return walk(start, Integer.MAX_VALUE, options);
+ }
+
+ /**
+ * Return a {@code Stream} that is lazily populated with {@code
+ * Path} by searching for files in a file tree rooted at a given starting
+ * file.
+ *
+ * <p> This method walks the file tree in exactly the manner specified by
+ * the {@link #walk walk} method. For each file encountered, the given
+ * {@link BiPredicate} is invoked with its {@link Path} and {@link
+ * BasicFileAttributes}. The {@code Path} object is obtained as if by
+ * {@link Path#resolve(Path) resolving} the relative path against {@code
+ * start} and is only included in the returned {@link Stream} if
+ * the {@code BiPredicate} returns true. Compare to calling {@link
+ * java.util.stream.Stream#filter filter} on the {@code Stream}
+ * returned by {@code walk} method, this method may be more efficient by
+ * avoiding redundant retrieval of the {@code BasicFileAttributes}.
+ *
+ * <p> The returned stream encapsulates one or more {@link DirectoryStream}s.
+ * If timely disposal of file system resources is required, the
+ * {@code try}-with-resources construct should be used to ensure that the
+ * stream's {@link Stream#close close} method is invoked after the stream
+ * operations are completed. Operating on a closed stream will result in an
+ * {@link java.lang.IllegalStateException}.
+ *
+ * <p> If an {@link IOException} is thrown when accessing the directory
+ * after returned from this method, it is wrapped in an {@link
+ * UncheckedIOException} which will be thrown from the method that caused
+ * the access to take place.
+ *
+ * @param start
+ * the starting file
+ * @param maxDepth
+ * the maximum number of directory levels to search
+ * @param matcher
+ * the function used to decide whether a file should be included
+ * in the returned stream
+ * @param options
+ * options to configure the traversal
+ *
+ * @return the {@link Stream} of {@link Path}
+ *
+ * @throws IllegalArgumentException
+ * if the {@code maxDepth} parameter is negative
+ * @throws SecurityException
+ * If the security manager denies access to the starting file.
+ * In the case of the default provider, the {@link
+ * SecurityManager#checkRead(String) checkRead} method is invoked
+ * to check read access to the directory.
+ * @throws IOException
+ * if an I/O error is thrown when accessing the starting file.
+ *
+ * @see #walk(Path, int, FileVisitOption...)
+ * @since 1.8
+ */
+ public static Stream<Path> find(Path start,
+ int maxDepth,
+ BiPredicate<Path, BasicFileAttributes> matcher,
+ FileVisitOption... options)
+ throws IOException
+ {
+ FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options);
+ try {
+ return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT), false)
+ .onClose(iterator::close)
+ .filter(entry -> matcher.test(entry.file(), entry.attributes()))
+ .map(entry -> entry.file());
+ } catch (Error|RuntimeException e) {
+ iterator.close();
+ throw e;
+ }
+ }
+
+ /**
+ * Read all lines from a file as a {@code Stream}. Unlike {@link
+ * #readAllLines(Path, Charset) readAllLines}, this method does not read
+ * all lines into a {@code List}, but instead populates lazily as the stream
+ * is consumed.
+ *
+ * <p> Bytes from the file are decoded into characters using the specified
+ * charset and the same line terminators as specified by {@code
+ * readAllLines} are supported.
+ *
+ * <p> After this method returns, then any subsequent I/O exception that
+ * occurs while reading from the file or when a malformed or unmappable byte
+ * sequence is read, is wrapped in an {@link UncheckedIOException} that will
+ * be thrown from the
+ * {@link java.util.stream.Stream} method that caused the read to take
+ * place. In case an {@code IOException} is thrown when closing the file,
+ * it is also wrapped as an {@code UncheckedIOException}.
+ *
+ * <p> The returned stream encapsulates a {@link Reader}. If timely
+ * disposal of file system resources is required, the try-with-resources
+ * construct should be used to ensure that the stream's
+ * {@link Stream#close close} method is invoked after the stream operations
+ * are completed.
+ *
+ *
+ * @param path
+ * the path to the file
+ * @param cs
+ * the charset to use for decoding
+ *
+ * @return the lines from the file as a {@code Stream}
+ *
+ * @throws IOException
+ * if an I/O error occurs opening the file
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file.
+ *
+ * @see #readAllLines(Path, Charset)
+ * @see #newBufferedReader(Path, Charset)
+ * @see java.io.BufferedReader#lines()
+ * @since 1.8
+ */
+ public static Stream<String> lines(Path path, Charset cs) throws IOException {
+ BufferedReader br = Files.newBufferedReader(path, cs);
+ try {
+ return br.lines().onClose(asUncheckedRunnable(br));
+ } catch (Error|RuntimeException e) {
+ try {
+ br.close();
+ } catch (IOException ex) {
+ try {
+ e.addSuppressed(ex);
+ } catch (Throwable ignore) {}
+ }
+ throw e;
+ }
+ }
+
+ /**
+ * Read all lines from a file as a {@code Stream}. Bytes from the file are
+ * decoded into characters using the {@link StandardCharsets#UTF_8 UTF-8}
+ * {@link Charset charset}.
+ *
+ * <p> This method works as if invoking it were equivalent to evaluating the
+ * expression:
+ * <pre>{@code
+ * Files.lines(path, StandardCharsets.UTF_8)
+ * }</pre>
+ *
+ * @param path
+ * the path to the file
+ *
+ * @return the lines from the file as a {@code Stream}
+ *
+ * @throws IOException
+ * if an I/O error occurs opening the file
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file.
+ *
+ * @since 1.8
+ */
+ public static Stream<String> lines(Path path) throws IOException {
+ return lines(path, StandardCharsets.UTF_8);
+ }
+}
diff --git a/java/nio/file/InvalidPathException.java b/java/nio/file/InvalidPathException.java
new file mode 100644
index 0000000..2c62865
--- /dev/null
+++ b/java/nio/file/InvalidPathException.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Unchecked exception thrown when path string cannot be converted into a
+ * {@link Path} because the path string contains invalid characters, or
+ * the path string is invalid for other file system specific reasons.
+ */
+
+public class InvalidPathException
+ extends IllegalArgumentException
+{
+ static final long serialVersionUID = 4355821422286746137L;
+
+ private String input;
+ private int index;
+
+ /**
+ * Constructs an instance from the given input string, reason, and error
+ * index.
+ *
+ * @param input the input string
+ * @param reason a string explaining why the input was rejected
+ * @param index the index at which the error occurred,
+ * or <tt>-1</tt> if the index is not known
+ *
+ * @throws NullPointerException
+ * if either the input or reason strings are <tt>null</tt>
+ *
+ * @throws IllegalArgumentException
+ * if the error index is less than <tt>-1</tt>
+ */
+ public InvalidPathException(String input, String reason, int index) {
+ super(reason);
+ if ((input == null) || (reason == null))
+ throw new NullPointerException();
+ if (index < -1)
+ throw new IllegalArgumentException();
+ this.input = input;
+ this.index = index;
+ }
+
+ /**
+ * Constructs an instance from the given input string and reason. The
+ * resulting object will have an error index of <tt>-1</tt>.
+ *
+ * @param input the input string
+ * @param reason a string explaining why the input was rejected
+ *
+ * @throws NullPointerException
+ * if either the input or reason strings are <tt>null</tt>
+ */
+ public InvalidPathException(String input, String reason) {
+ this(input, reason, -1);
+ }
+
+ /**
+ * Returns the input string.
+ *
+ * @return the input string
+ */
+ public String getInput() {
+ return input;
+ }
+
+ /**
+ * Returns a string explaining why the input string was rejected.
+ *
+ * @return the reason string
+ */
+ public String getReason() {
+ return super.getMessage();
+ }
+
+ /**
+ * Returns an index into the input string of the position at which the
+ * error occurred, or <tt>-1</tt> if this position is not known.
+ *
+ * @return the error index
+ */
+ public int getIndex() {
+ return index;
+ }
+
+ /**
+ * Returns a string describing the error. The resulting string
+ * consists of the reason string followed by a colon character
+ * (<tt>':'</tt>), a space, and the input string. If the error index is
+ * defined then the string <tt>" at index "</tt> followed by the index, in
+ * decimal, is inserted after the reason string and before the colon
+ * character.
+ *
+ * @return a string describing the error
+ */
+ public String getMessage() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(getReason());
+ if (index > -1) {
+ sb.append(" at index ");
+ sb.append(index);
+ }
+ sb.append(": ");
+ sb.append(input);
+ return sb.toString();
+ }
+}
diff --git a/java/nio/file/LinkOption.java b/java/nio/file/LinkOption.java
new file mode 100644
index 0000000..f1e133f
--- /dev/null
+++ b/java/nio/file/LinkOption.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Defines the options as to how symbolic links are handled.
+ *
+ * @since 1.7
+ */
+
+public enum LinkOption implements OpenOption, CopyOption {
+ /**
+ * Do not follow symbolic links.
+ *
+ * @see Files#getFileAttributeView(Path,Class,LinkOption[])
+ * @see Files#copy
+ * @see SecureDirectoryStream#newByteChannel
+ */
+ NOFOLLOW_LINKS;
+}
diff --git a/java/nio/file/LinkPermission.java b/java/nio/file/LinkPermission.java
new file mode 100644
index 0000000..bf54e16
--- /dev/null
+++ b/java/nio/file/LinkPermission.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+import java.security.BasicPermission;
+
+/**
+ * The {@code Permission} class for link creation operations.
+ *
+ * <p> The following table provides a summary description of what the permission
+ * allows, and discusses the risks of granting code the permission.
+ *
+ * <table border=1 cellpadding=5
+ * summary="Table shows permission target name, what the permission allows, and associated risks">
+ * <tr>
+ * <th>Permission Target Name</th>
+ * <th>What the Permission Allows</th>
+ * <th>Risks of Allowing this Permission</th>
+ * </tr>
+ * <tr>
+ * <td>hard</td>
+ * <td> Ability to add an existing file to a directory. This is sometimes
+ * known as creating a link, or hard link. </td>
+ * <td> Extreme care should be taken when granting this permission. It allows
+ * linking to any file or directory in the file system thus allowing the
+ * attacker access to all files. </td>
+ * </tr>
+ * <tr>
+ * <td>symbolic</td>
+ * <td> Ability to create symbolic links. </td>
+ * <td> Extreme care should be taken when granting this permission. It allows
+ * linking to any file or directory in the file system thus allowing the
+ * attacker to access to all files. </td>
+ * </tr>
+ * </table>
+ *
+ * @since 1.7
+ *
+ * @see Files#createLink
+ * @see Files#createSymbolicLink
+ */
+public final class LinkPermission extends BasicPermission {
+ static final long serialVersionUID = -1441492453772213220L;
+
+ private void checkName(String name) {
+ if (!name.equals("hard") && !name.equals("symbolic")) {
+ throw new IllegalArgumentException("name: " + name);
+ }
+ }
+
+ /**
+ * Constructs a {@code LinkPermission} with the specified name.
+ *
+ * @param name
+ * the name of the permission. It must be "hard" or "symbolic".
+ *
+ * @throws IllegalArgumentException
+ * if name is empty or invalid
+ */
+ public LinkPermission(String name) {
+ super(name);
+ checkName(name);
+ }
+
+ /**
+ * Constructs a {@code LinkPermission} with the specified name.
+ *
+ * @param name
+ * the name of the permission; must be "hard" or "symbolic".
+ * @param actions
+ * the actions for the permission; must be the empty string or
+ * {@code null}
+ *
+ * @throws IllegalArgumentException
+ * if name is empty or invalid, or actions is a non-empty string
+ */
+ public LinkPermission(String name, String actions) {
+ super(name);
+ checkName(name);
+ if (actions != null && actions.length() > 0) {
+ throw new IllegalArgumentException("actions: " + actions);
+ }
+ }
+}
diff --git a/java/nio/file/NoSuchFileException.java b/java/nio/file/NoSuchFileException.java
new file mode 100644
index 0000000..1f2ab3d
--- /dev/null
+++ b/java/nio/file/NoSuchFileException.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Checked exception thrown when an attempt is made to access a file that does
+ * not exist.
+ *
+ * @since 1.7
+ */
+
+public class NoSuchFileException
+ extends FileSystemException
+{
+ static final long serialVersionUID = -1390291775875351931L;
+
+ /**
+ * Constructs an instance of this class.
+ *
+ * @param file
+ * a string identifying the file or {@code null} if not known.
+ */
+ public NoSuchFileException(String file) {
+ super(file);
+ }
+
+ /**
+ * Constructs an instance of this class.
+ *
+ * @param file
+ * a string identifying the file or {@code null} if not known.
+ * @param other
+ * a string identifying the other file or {@code null} if not known.
+ * @param reason
+ * a reason message with additional information or {@code null}
+ */
+ public NoSuchFileException(String file, String other, String reason) {
+ super(file, other, reason);
+ }
+}
diff --git a/java/nio/file/NotDirectoryException.java b/java/nio/file/NotDirectoryException.java
new file mode 100644
index 0000000..4082cea
--- /dev/null
+++ b/java/nio/file/NotDirectoryException.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Checked exception thrown when a file system operation, intended for a
+ * directory, fails because the file is not a directory.
+ *
+ * @since 1.7
+ */
+
+public class NotDirectoryException
+ extends FileSystemException
+{
+ private static final long serialVersionUID = -9011457427178200199L;
+
+ /**
+ * Constructs an instance of this class.
+ *
+ * @param file
+ * a string identifying the file or {@code null} if not known
+ */
+ public NotDirectoryException(String file) {
+ super(file);
+ }
+}
diff --git a/java/nio/file/NotLinkException.java b/java/nio/file/NotLinkException.java
new file mode 100644
index 0000000..353e4d7
--- /dev/null
+++ b/java/nio/file/NotLinkException.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Checked exception thrown when a file system operation fails because a file
+ * is not a symbolic link.
+ *
+ * @since 1.7
+ */
+
+public class NotLinkException
+ extends FileSystemException
+{
+ static final long serialVersionUID = -388655596416518021L;
+
+ /**
+ * Constructs an instance of this class.
+ *
+ * @param file
+ * a string identifying the file or {@code null} if not known
+ */
+ public NotLinkException(String file) {
+ super(file);
+ }
+
+ /**
+ * Constructs an instance of this class.
+ *
+ * @param file
+ * a string identifying the file or {@code null} if not known
+ * @param other
+ * a string identifying the other file or {@code null} if not known
+ * @param reason
+ * a reason message with additional information or {@code null}
+ */
+ public NotLinkException(String file, String other, String reason) {
+ super(file, other, reason);
+ }
+}
diff --git a/java/nio/file/OpenOption.java b/java/nio/file/OpenOption.java
new file mode 100644
index 0000000..aef96fb
--- /dev/null
+++ b/java/nio/file/OpenOption.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * An object that configures how to open or create a file.
+ *
+ * <p> Objects of this type are used by methods such as {@link
+ * Files#newOutputStream(Path,OpenOption[]) newOutputStream}, {@link
+ * Files#newByteChannel newByteChannel}, {@link
+ * java.nio.channels.FileChannel#open FileChannel.open}, and {@link
+ * java.nio.channels.AsynchronousFileChannel#open AsynchronousFileChannel.open}
+ * when opening or creating a file.
+ *
+ * <p> The {@link StandardOpenOption} enumeration type defines the
+ * <i>standard</i> options.
+ *
+ * @since 1.7
+ */
+
+public interface OpenOption {
+}
diff --git a/java/nio/file/Path.java b/java/nio/file/Path.java
new file mode 100644
index 0000000..daa09f4
--- /dev/null
+++ b/java/nio/file/Path.java
@@ -0,0 +1,801 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.util.Iterator;
+
+/**
+ * An object that may be used to locate a file in a file system. It will
+ * typically represent a system dependent file path.
+ *
+ * <p> A {@code Path} represents a path that is hierarchical and composed of a
+ * sequence of directory and file name elements separated by a special separator
+ * or delimiter. A <em>root component</em>, that identifies a file system
+ * hierarchy, may also be present. The name element that is <em>farthest</em>
+ * from the root of the directory hierarchy is the name of a file or directory.
+ * The other name elements are directory names. A {@code Path} can represent a
+ * root, a root and a sequence of names, or simply one or more name elements.
+ * A {@code Path} is considered to be an <i>empty path</i> if it consists
+ * solely of one name element that is empty. Accessing a file using an
+ * <i>empty path</i> is equivalent to accessing the default directory of the
+ * file system. {@code Path} defines the {@link #getFileName() getFileName},
+ * {@link #getParent getParent}, {@link #getRoot getRoot}, and {@link #subpath
+ * subpath} methods to access the path components or a subsequence of its name
+ * elements.
+ *
+ * <p> In addition to accessing the components of a path, a {@code Path} also
+ * defines the {@link #resolve(Path) resolve} and {@link #resolveSibling(Path)
+ * resolveSibling} methods to combine paths. The {@link #relativize relativize}
+ * method that can be used to construct a relative path between two paths.
+ * Paths can be {@link #compareTo compared}, and tested against each other using
+ * the {@link #startsWith startsWith} and {@link #endsWith endsWith} methods.
+ *
+ * <p> This interface extends {@link Watchable} interface so that a directory
+ * located by a path can be {@link #register registered} with a {@link
+ * WatchService} and entries in the directory watched. </p>
+ *
+ * <p> <b>WARNING:</b> This interface is only intended to be implemented by
+ * those developing custom file system implementations. Methods may be added to
+ * this interface in future releases. </p>
+ *
+ * <h2>Accessing Files</h2>
+ * <p> Paths may be used with the {@link Files} class to operate on files,
+ * directories, and other types of files. For example, suppose we want a {@link
+ * java.io.BufferedReader} to read text from a file "{@code access.log}". The
+ * file is located in a directory "{@code logs}" relative to the current working
+ * directory and is UTF-8 encoded.
+ * <pre>
+ * Path path = FileSystems.getDefault().getPath("logs", "access.log");
+ * BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8);
+ * </pre>
+ *
+ * <a name="interop"></a><h2>Interoperability</h2>
+ * <p> Paths associated with the default {@link
+ * java.nio.file.spi.FileSystemProvider provider} are generally interoperable
+ * with the {@link java.io.File java.io.File} class. Paths created by other
+ * providers are unlikely to be interoperable with the abstract path names
+ * represented by {@code java.io.File}. The {@link java.io.File#toPath toPath}
+ * method may be used to obtain a {@code Path} from the abstract path name
+ * represented by a {@code java.io.File} object. The resulting {@code Path} can
+ * be used to operate on the same file as the {@code java.io.File} object. In
+ * addition, the {@link #toFile toFile} method is useful to construct a {@code
+ * File} from the {@code String} representation of a {@code Path}.
+ *
+ * <h2>Concurrency</h2>
+ * <p> Implementations of this interface are immutable and safe for use by
+ * multiple concurrent threads.
+ *
+ * @since 1.7
+ * @see Paths
+ */
+
+public interface Path
+ extends Comparable<Path>, Iterable<Path>, Watchable
+{
+ /**
+ * Returns the file system that created this object.
+ *
+ * @return the file system that created this object
+ */
+ FileSystem getFileSystem();
+
+ /**
+ * Tells whether or not this path is absolute.
+ *
+ * <p> An absolute path is complete in that it doesn't need to be combined
+ * with other path information in order to locate a file.
+ *
+ * @return {@code true} if, and only if, this path is absolute
+ */
+ boolean isAbsolute();
+
+ /**
+ * Returns the root component of this path as a {@code Path} object,
+ * or {@code null} if this path does not have a root component.
+ *
+ * @return a path representing the root component of this path,
+ * or {@code null}
+ */
+ Path getRoot();
+
+ /**
+ * Returns the name of the file or directory denoted by this path as a
+ * {@code Path} object. The file name is the <em>farthest</em> element from
+ * the root in the directory hierarchy.
+ *
+ * @return a path representing the name of the file or directory, or
+ * {@code null} if this path has zero elements
+ */
+ Path getFileName();
+
+ /**
+ * Returns the <em>parent path</em>, or {@code null} if this path does not
+ * have a parent.
+ *
+ * <p> The parent of this path object consists of this path's root
+ * component, if any, and each element in the path except for the
+ * <em>farthest</em> from the root in the directory hierarchy. This method
+ * does not access the file system; the path or its parent may not exist.
+ * Furthermore, this method does not eliminate special names such as "."
+ * and ".." that may be used in some implementations. On UNIX for example,
+ * the parent of "{@code /a/b/c}" is "{@code /a/b}", and the parent of
+ * {@code "x/y/.}" is "{@code x/y}". This method may be used with the {@link
+ * #normalize normalize} method, to eliminate redundant names, for cases where
+ * <em>shell-like</em> navigation is required.
+ *
+ * <p> If this path has one or more elements, and no root component, then
+ * this method is equivalent to evaluating the expression:
+ * <blockquote><pre>
+ * subpath(0, getNameCount()-1);
+ * </pre></blockquote>
+ *
+ * @return a path representing the path's parent
+ */
+ Path getParent();
+
+ /**
+ * Returns the number of name elements in the path.
+ *
+ * @return the number of elements in the path, or {@code 0} if this path
+ * only represents a root component
+ */
+ int getNameCount();
+
+ /**
+ * Returns a name element of this path as a {@code Path} object.
+ *
+ * <p> The {@code index} parameter is the index of the name element to return.
+ * The element that is <em>closest</em> to the root in the directory hierarchy
+ * has index {@code 0}. The element that is <em>farthest</em> from the root
+ * has index {@link #getNameCount count}{@code -1}.
+ *
+ * @param index
+ * the index of the element
+ *
+ * @return the name element
+ *
+ * @throws IllegalArgumentException
+ * if {@code index} is negative, {@code index} is greater than or
+ * equal to the number of elements, or this path has zero name
+ * elements
+ */
+ Path getName(int index);
+
+ /**
+ * Returns a relative {@code Path} that is a subsequence of the name
+ * elements of this path.
+ *
+ * <p> The {@code beginIndex} and {@code endIndex} parameters specify the
+ * subsequence of name elements. The name that is <em>closest</em> to the root
+ * in the directory hierarchy has index {@code 0}. The name that is
+ * <em>farthest</em> from the root has index {@link #getNameCount
+ * count}{@code -1}. The returned {@code Path} object has the name elements
+ * that begin at {@code beginIndex} and extend to the element at index {@code
+ * endIndex-1}.
+ *
+ * @param beginIndex
+ * the index of the first element, inclusive
+ * @param endIndex
+ * the index of the last element, exclusive
+ *
+ * @return a new {@code Path} object that is a subsequence of the name
+ * elements in this {@code Path}
+ *
+ * @throws IllegalArgumentException
+ * if {@code beginIndex} is negative, or greater than or equal to
+ * the number of elements. If {@code endIndex} is less than or
+ * equal to {@code beginIndex}, or larger than the number of elements.
+ */
+ Path subpath(int beginIndex, int endIndex);
+
+ /**
+ * Tests if this path starts with the given path.
+ *
+ * <p> This path <em>starts</em> with the given path if this path's root
+ * component <em>starts</em> with the root component of the given path,
+ * and this path starts with the same name elements as the given path.
+ * If the given path has more name elements than this path then {@code false}
+ * is returned.
+ *
+ * <p> Whether or not the root component of this path starts with the root
+ * component of the given path is file system specific. If this path does
+ * not have a root component and the given path has a root component then
+ * this path does not start with the given path.
+ *
+ * <p> If the given path is associated with a different {@code FileSystem}
+ * to this path then {@code false} is returned.
+ *
+ * @param other
+ * the given path
+ *
+ * @return {@code true} if this path starts with the given path; otherwise
+ * {@code false}
+ */
+ boolean startsWith(Path other);
+
+ /**
+ * Tests if this path starts with a {@code Path}, constructed by converting
+ * the given path string, in exactly the manner specified by the {@link
+ * #startsWith(Path) startsWith(Path)} method. On UNIX for example, the path
+ * "{@code foo/bar}" starts with "{@code foo}" and "{@code foo/bar}". It
+ * does not start with "{@code f}" or "{@code fo}".
+ *
+ * @param other
+ * the given path string
+ *
+ * @return {@code true} if this path starts with the given path; otherwise
+ * {@code false}
+ *
+ * @throws InvalidPathException
+ * If the path string cannot be converted to a Path.
+ */
+ boolean startsWith(String other);
+
+ /**
+ * Tests if this path ends with the given path.
+ *
+ * <p> If the given path has <em>N</em> elements, and no root component,
+ * and this path has <em>N</em> or more elements, then this path ends with
+ * the given path if the last <em>N</em> elements of each path, starting at
+ * the element farthest from the root, are equal.
+ *
+ * <p> If the given path has a root component then this path ends with the
+ * given path if the root component of this path <em>ends with</em> the root
+ * component of the given path, and the corresponding elements of both paths
+ * are equal. Whether or not the root component of this path ends with the
+ * root component of the given path is file system specific. If this path
+ * does not have a root component and the given path has a root component
+ * then this path does not end with the given path.
+ *
+ * <p> If the given path is associated with a different {@code FileSystem}
+ * to this path then {@code false} is returned.
+ *
+ * @param other
+ * the given path
+ *
+ * @return {@code true} if this path ends with the given path; otherwise
+ * {@code false}
+ */
+ boolean endsWith(Path other);
+
+ /**
+ * Tests if this path ends with a {@code Path}, constructed by converting
+ * the given path string, in exactly the manner specified by the {@link
+ * #endsWith(Path) endsWith(Path)} method. On UNIX for example, the path
+ * "{@code foo/bar}" ends with "{@code foo/bar}" and "{@code bar}". It does
+ * not end with "{@code r}" or "{@code /bar}". Note that trailing separators
+ * are not taken into account, and so invoking this method on the {@code
+ * Path}"{@code foo/bar}" with the {@code String} "{@code bar/}" returns
+ * {@code true}.
+ *
+ * @param other
+ * the given path string
+ *
+ * @return {@code true} if this path ends with the given path; otherwise
+ * {@code false}
+ *
+ * @throws InvalidPathException
+ * If the path string cannot be converted to a Path.
+ */
+ boolean endsWith(String other);
+
+ /**
+ * Returns a path that is this path with redundant name elements eliminated.
+ *
+ * <p> The precise definition of this method is implementation dependent but
+ * in general it derives from this path, a path that does not contain
+ * <em>redundant</em> name elements. In many file systems, the "{@code .}"
+ * and "{@code ..}" are special names used to indicate the current directory
+ * and parent directory. In such file systems all occurrences of "{@code .}"
+ * are considered redundant. If a "{@code ..}" is preceded by a
+ * non-"{@code ..}" name then both names are considered redundant (the
+ * process to identify such names is repeated until it is no longer
+ * applicable).
+ *
+ * <p> This method does not access the file system; the path may not locate
+ * a file that exists. Eliminating "{@code ..}" and a preceding name from a
+ * path may result in the path that locates a different file than the original
+ * path. This can arise when the preceding name is a symbolic link.
+ *
+ * @return the resulting path or this path if it does not contain
+ * redundant name elements; an empty path is returned if this path
+ * does have a root component and all name elements are redundant
+ *
+ * @see #getParent
+ * @see #toRealPath
+ */
+ Path normalize();
+
+ // -- resolution and relativization --
+
+ /**
+ * Resolve the given path against this path.
+ *
+ * <p> If the {@code other} parameter is an {@link #isAbsolute() absolute}
+ * path then this method trivially returns {@code other}. If {@code other}
+ * is an <i>empty path</i> then this method trivially returns this path.
+ * Otherwise this method considers this path to be a directory and resolves
+ * the given path against this path. In the simplest case, the given path
+ * does not have a {@link #getRoot root} component, in which case this method
+ * <em>joins</em> the given path to this path and returns a resulting path
+ * that {@link #endsWith ends} with the given path. Where the given path has
+ * a root component then resolution is highly implementation dependent and
+ * therefore unspecified.
+ *
+ * @param other
+ * the path to resolve against this path
+ *
+ * @return the resulting path
+ *
+ * @see #relativize
+ */
+ Path resolve(Path other);
+
+ /**
+ * Converts a given path string to a {@code Path} and resolves it against
+ * this {@code Path} in exactly the manner specified by the {@link
+ * #resolve(Path) resolve} method. For example, suppose that the name
+ * separator is "{@code /}" and a path represents "{@code foo/bar}", then
+ * invoking this method with the path string "{@code gus}" will result in
+ * the {@code Path} "{@code foo/bar/gus}".
+ *
+ * @param other
+ * the path string to resolve against this path
+ *
+ * @return the resulting path
+ *
+ * @throws InvalidPathException
+ * if the path string cannot be converted to a Path.
+ *
+ * @see FileSystem#getPath
+ */
+ Path resolve(String other);
+
+ /**
+ * Resolves the given path against this path's {@link #getParent parent}
+ * path. This is useful where a file name needs to be <i>replaced</i> with
+ * another file name. For example, suppose that the name separator is
+ * "{@code /}" and a path represents "{@code dir1/dir2/foo}", then invoking
+ * this method with the {@code Path} "{@code bar}" will result in the {@code
+ * Path} "{@code dir1/dir2/bar}". If this path does not have a parent path,
+ * or {@code other} is {@link #isAbsolute() absolute}, then this method
+ * returns {@code other}. If {@code other} is an empty path then this method
+ * returns this path's parent, or where this path doesn't have a parent, the
+ * empty path.
+ *
+ * @param other
+ * the path to resolve against this path's parent
+ *
+ * @return the resulting path
+ *
+ * @see #resolve(Path)
+ */
+ Path resolveSibling(Path other);
+
+ /**
+ * Converts a given path string to a {@code Path} and resolves it against
+ * this path's {@link #getParent parent} path in exactly the manner
+ * specified by the {@link #resolveSibling(Path) resolveSibling} method.
+ *
+ * @param other
+ * the path string to resolve against this path's parent
+ *
+ * @return the resulting path
+ *
+ * @throws InvalidPathException
+ * if the path string cannot be converted to a Path.
+ *
+ * @see FileSystem#getPath
+ */
+ Path resolveSibling(String other);
+
+ /**
+ * Constructs a relative path between this path and a given path.
+ *
+ * <p> Relativization is the inverse of {@link #resolve(Path) resolution}.
+ * This method attempts to construct a {@link #isAbsolute relative} path
+ * that when {@link #resolve(Path) resolved} against this path, yields a
+ * path that locates the same file as the given path. For example, on UNIX,
+ * if this path is {@code "/a/b"} and the given path is {@code "/a/b/c/d"}
+ * then the resulting relative path would be {@code "c/d"}. Where this
+ * path and the given path do not have a {@link #getRoot root} component,
+ * then a relative path can be constructed. A relative path cannot be
+ * constructed if only one of the paths have a root component. Where both
+ * paths have a root component then it is implementation dependent if a
+ * relative path can be constructed. If this path and the given path are
+ * {@link #equals equal} then an <i>empty path</i> is returned.
+ *
+ * <p> For any two {@link #normalize normalized} paths <i>p</i> and
+ * <i>q</i>, where <i>q</i> does not have a root component,
+ * <blockquote>
+ * <i>p</i><tt>.relativize(</tt><i>p</i><tt>.resolve(</tt><i>q</i><tt>)).equals(</tt><i>q</i><tt>)</tt>
+ * </blockquote>
+ *
+ * <p> When symbolic links are supported, then whether the resulting path,
+ * when resolved against this path, yields a path that can be used to locate
+ * the {@link Files#isSameFile same} file as {@code other} is implementation
+ * dependent. For example, if this path is {@code "/a/b"} and the given
+ * path is {@code "/a/x"} then the resulting relative path may be {@code
+ * "../x"}. If {@code "b"} is a symbolic link then is implementation
+ * dependent if {@code "a/b/../x"} would locate the same file as {@code "/a/x"}.
+ *
+ * @param other
+ * the path to relativize against this path
+ *
+ * @return the resulting relative path, or an empty path if both paths are
+ * equal
+ *
+ * @throws IllegalArgumentException
+ * if {@code other} is not a {@code Path} that can be relativized
+ * against this path
+ */
+ Path relativize(Path other);
+
+ /**
+ * Returns a URI to represent this path.
+ *
+ * <p> This method constructs an absolute {@link URI} with a {@link
+ * URI#getScheme() scheme} equal to the URI scheme that identifies the
+ * provider. The exact form of the scheme specific part is highly provider
+ * dependent.
+ *
+ * <p> In the case of the default provider, the URI is hierarchical with
+ * a {@link URI#getPath() path} component that is absolute. The query and
+ * fragment components are undefined. Whether the authority component is
+ * defined or not is implementation dependent. There is no guarantee that
+ * the {@code URI} may be used to construct a {@link java.io.File java.io.File}.
+ * In particular, if this path represents a Universal Naming Convention (UNC)
+ * path, then the UNC server name may be encoded in the authority component
+ * of the resulting URI. In the case of the default provider, and the file
+ * exists, and it can be determined that the file is a directory, then the
+ * resulting {@code URI} will end with a slash.
+ *
+ * <p> The default provider provides a similar <em>round-trip</em> guarantee
+ * to the {@link java.io.File} class. For a given {@code Path} <i>p</i> it
+ * is guaranteed that
+ * <blockquote><tt>
+ * {@link Paths#get(URI) Paths.get}(</tt><i>p</i><tt>.toUri()).equals(</tt><i>p</i>
+ * <tt>.{@link #toAbsolutePath() toAbsolutePath}())</tt>
+ * </blockquote>
+ * so long as the original {@code Path}, the {@code URI}, and the new {@code
+ * Path} are all created in (possibly different invocations of) the same
+ * Java virtual machine. Whether other providers make any guarantees is
+ * provider specific and therefore unspecified.
+ *
+ * <p> When a file system is constructed to access the contents of a file
+ * as a file system then it is highly implementation specific if the returned
+ * URI represents the given path in the file system or it represents a
+ * <em>compound</em> URI that encodes the URI of the enclosing file system.
+ * A format for compound URIs is not defined in this release; such a scheme
+ * may be added in a future release.
+ *
+ * @return the URI representing this path
+ *
+ * @throws java.io.IOError
+ * if an I/O error occurs obtaining the absolute path, or where a
+ * file system is constructed to access the contents of a file as
+ * a file system, and the URI of the enclosing file system cannot be
+ * obtained
+ *
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager
+ * is installed, the {@link #toAbsolutePath toAbsolutePath} method
+ * throws a security exception.
+ */
+ URI toUri();
+
+ /**
+ * Returns a {@code Path} object representing the absolute path of this
+ * path.
+ *
+ * <p> If this path is already {@link Path#isAbsolute absolute} then this
+ * method simply returns this path. Otherwise, this method resolves the path
+ * in an implementation dependent manner, typically by resolving the path
+ * against a file system default directory. Depending on the implementation,
+ * this method may throw an I/O error if the file system is not accessible.
+ *
+ * @return a {@code Path} object representing the absolute path
+ *
+ * @throws java.io.IOError
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, a security manager
+ * is installed, and this path is not absolute, then the security
+ * manager's {@link SecurityManager#checkPropertyAccess(String)
+ * checkPropertyAccess} method is invoked to check access to the
+ * system property {@code user.dir}
+ */
+ Path toAbsolutePath();
+
+ /**
+ * Returns the <em>real</em> path of an existing file.
+ *
+ * <p> The precise definition of this method is implementation dependent but
+ * in general it derives from this path, an {@link #isAbsolute absolute}
+ * path that locates the {@link Files#isSameFile same} file as this path, but
+ * with name elements that represent the actual name of the directories
+ * and the file. For example, where filename comparisons on a file system
+ * are case insensitive then the name elements represent the names in their
+ * actual case. Additionally, the resulting path has redundant name
+ * elements removed.
+ *
+ * <p> If this path is relative then its absolute path is first obtained,
+ * as if by invoking the {@link #toAbsolutePath toAbsolutePath} method.
+ *
+ * <p> The {@code options} array may be used to indicate how symbolic links
+ * are handled. By default, symbolic links are resolved to their final
+ * target. If the option {@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} is
+ * present then this method does not resolve symbolic links.
+ *
+ * Some implementations allow special names such as "{@code ..}" to refer to
+ * the parent directory. When deriving the <em>real path</em>, and a
+ * "{@code ..}" (or equivalent) is preceded by a non-"{@code ..}" name then
+ * an implementation will typically cause both names to be removed. When
+ * not resolving symbolic links and the preceding name is a symbolic link
+ * then the names are only removed if it guaranteed that the resulting path
+ * will locate the same file as this path.
+ *
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return an absolute path represent the <em>real</em> path of the file
+ * located by this object
+ *
+ * @throws IOException
+ * if the file does not exist or an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager
+ * is installed, its {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file, and where
+ * this path is not absolute, its {@link SecurityManager#checkPropertyAccess(String)
+ * checkPropertyAccess} method is invoked to check access to the
+ * system property {@code user.dir}
+ */
+ Path toRealPath(LinkOption... options) throws IOException;
+
+ /**
+ * Returns a {@link File} object representing this path. Where this {@code
+ * Path} is associated with the default provider, then this method is
+ * equivalent to returning a {@code File} object constructed with the
+ * {@code String} representation of this path.
+ *
+ * <p> If this path was created by invoking the {@code File} {@link
+ * File#toPath toPath} method then there is no guarantee that the {@code
+ * File} object returned by this method is {@link #equals equal} to the
+ * original {@code File}.
+ *
+ * @return a {@code File} object representing this path
+ *
+ * @throws UnsupportedOperationException
+ * if this {@code Path} is not associated with the default provider
+ */
+ File toFile();
+
+ // -- watchable --
+
+ /**
+ * Registers the file located by this path with a watch service.
+ *
+ * <p> In this release, this path locates a directory that exists. The
+ * directory is registered with the watch service so that entries in the
+ * directory can be watched. The {@code events} parameter is the events to
+ * register and may contain the following events:
+ * <ul>
+ * <li>{@link StandardWatchEventKinds#ENTRY_CREATE ENTRY_CREATE} -
+ * entry created or moved into the directory</li>
+ * <li>{@link StandardWatchEventKinds#ENTRY_DELETE ENTRY_DELETE} -
+ * entry deleted or moved out of the directory</li>
+ * <li>{@link StandardWatchEventKinds#ENTRY_MODIFY ENTRY_MODIFY} -
+ * entry in directory was modified</li>
+ * </ul>
+ *
+ * <p> The {@link WatchEvent#context context} for these events is the
+ * relative path between the directory located by this path, and the path
+ * that locates the directory entry that is created, deleted, or modified.
+ *
+ * <p> The set of events may include additional implementation specific
+ * event that are not defined by the enum {@link StandardWatchEventKinds}
+ *
+ * <p> The {@code modifiers} parameter specifies <em>modifiers</em> that
+ * qualify how the directory is registered. This release does not define any
+ * <em>standard</em> modifiers. It may contain implementation specific
+ * modifiers.
+ *
+ * <p> Where a file is registered with a watch service by means of a symbolic
+ * link then it is implementation specific if the watch continues to depend
+ * on the existence of the symbolic link after it is registered.
+ *
+ * @param watcher
+ * the watch service to which this object is to be registered
+ * @param events
+ * the events for which this object should be registered
+ * @param modifiers
+ * the modifiers, if any, that modify how the object is registered
+ *
+ * @return a key representing the registration of this object with the
+ * given watch service
+ *
+ * @throws UnsupportedOperationException
+ * if unsupported events or modifiers are specified
+ * @throws IllegalArgumentException
+ * if an invalid combination of events or modifiers is specified
+ * @throws ClosedWatchServiceException
+ * if the watch service is closed
+ * @throws NotDirectoryException
+ * if the file is registered to watch the entries in a directory
+ * and the file is not a directory <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file.
+ */
+ @Override
+ WatchKey register(WatchService watcher,
+ WatchEvent.Kind<?>[] events,
+ WatchEvent.Modifier... modifiers)
+ throws IOException;
+
+ /**
+ * Registers the file located by this path with a watch service.
+ *
+ * <p> An invocation of this method behaves in exactly the same way as the
+ * invocation
+ * <pre>
+ * watchable.{@link #register(WatchService,WatchEvent.Kind[],WatchEvent.Modifier[]) register}(watcher, events, new WatchEvent.Modifier[0]);
+ * </pre>
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we wish to register a directory for entry create, delete, and modify
+ * events:
+ * <pre>
+ * Path dir = ...
+ * WatchService watcher = ...
+ *
+ * WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
+ * </pre>
+ * @param watcher
+ * The watch service to which this object is to be registered
+ * @param events
+ * The events for which this object should be registered
+ *
+ * @return A key representing the registration of this object with the
+ * given watch service
+ *
+ * @throws UnsupportedOperationException
+ * If unsupported events are specified
+ * @throws IllegalArgumentException
+ * If an invalid combination of events is specified
+ * @throws ClosedWatchServiceException
+ * If the watch service is closed
+ * @throws NotDirectoryException
+ * If the file is registered to watch the entries in a directory
+ * and the file is not a directory <i>(optional specific exception)</i>
+ * @throws IOException
+ * If an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file.
+ */
+ @Override
+ WatchKey register(WatchService watcher,
+ WatchEvent.Kind<?>... events)
+ throws IOException;
+
+ // -- Iterable --
+
+ /**
+ * Returns an iterator over the name elements of this path.
+ *
+ * <p> The first element returned by the iterator represents the name
+ * element that is closest to the root in the directory hierarchy, the
+ * second element is the next closest, and so on. The last element returned
+ * is the name of the file or directory denoted by this path. The {@link
+ * #getRoot root} component, if present, is not returned by the iterator.
+ *
+ * @return an iterator over the name elements of this path.
+ */
+ @Override
+ Iterator<Path> iterator();
+
+ // -- compareTo/equals/hashCode --
+
+ /**
+ * Compares two abstract paths lexicographically. The ordering defined by
+ * this method is provider specific, and in the case of the default
+ * provider, platform specific. This method does not access the file system
+ * and neither file is required to exist.
+ *
+ * <p> This method may not be used to compare paths that are associated
+ * with different file system providers.
+ *
+ * @param other the path compared to this path.
+ *
+ * @return zero if the argument is {@link #equals equal} to this path, a
+ * value less than zero if this path is lexicographically less than
+ * the argument, or a value greater than zero if this path is
+ * lexicographically greater than the argument
+ *
+ * @throws ClassCastException
+ * if the paths are associated with different providers
+ */
+ @Override
+ int compareTo(Path other);
+
+ /**
+ * Tests this path for equality with the given object.
+ *
+ * <p> If the given object is not a Path, or is a Path associated with a
+ * different {@code FileSystem}, then this method returns {@code false}.
+ *
+ * <p> Whether or not two path are equal depends on the file system
+ * implementation. In some cases the paths are compared without regard
+ * to case, and others are case sensitive. This method does not access the
+ * file system and the file is not required to exist. Where required, the
+ * {@link Files#isSameFile isSameFile} method may be used to check if two
+ * paths locate the same file.
+ *
+ * <p> This method satisfies the general contract of the {@link
+ * java.lang.Object#equals(Object) Object.equals} method. </p>
+ *
+ * @param other
+ * the object to which this object is to be compared
+ *
+ * @return {@code true} if, and only if, the given object is a {@code Path}
+ * that is identical to this {@code Path}
+ */
+ boolean equals(Object other);
+
+ /**
+ * Computes a hash code for this path.
+ *
+ * <p> The hash code is based upon the components of the path, and
+ * satisfies the general contract of the {@link Object#hashCode
+ * Object.hashCode} method.
+ *
+ * @return the hash-code value for this path
+ */
+ int hashCode();
+
+ /**
+ * Returns the string representation of this path.
+ *
+ * <p> If this path was created by converting a path string using the
+ * {@link FileSystem#getPath getPath} method then the path string returned
+ * by this method may differ from the original String used to create the path.
+ *
+ * <p> The returned path string uses the default name {@link
+ * FileSystem#getSeparator separator} to separate names in the path.
+ *
+ * @return the string representation of this path
+ */
+ String toString();
+}
diff --git a/java/nio/file/PathMatcher.java b/java/nio/file/PathMatcher.java
new file mode 100644
index 0000000..24e6149
--- /dev/null
+++ b/java/nio/file/PathMatcher.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * An interface that is implemented by objects that perform match operations on
+ * paths.
+ *
+ * @since 1.7
+ *
+ * @see FileSystem#getPathMatcher
+ * @see Files#newDirectoryStream(Path,String)
+ */
+@FunctionalInterface
+public interface PathMatcher {
+ /**
+ * Tells if given path matches this matcher's pattern.
+ *
+ * @param path
+ * the path to match
+ *
+ * @return {@code true} if, and only if, the path matches this
+ * matcher's pattern
+ */
+ boolean matches(Path path);
+}
diff --git a/java/nio/file/Paths.java b/java/nio/file/Paths.java
new file mode 100644
index 0000000..bb49f99
--- /dev/null
+++ b/java/nio/file/Paths.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+import java.nio.file.spi.FileSystemProvider;
+import java.net.URI;
+
+/**
+ * This class consists exclusively of static methods that return a {@link Path}
+ * by converting a path string or {@link URI}.
+ *
+ * @since 1.7
+ */
+
+public final class Paths {
+ private Paths() { }
+
+ /**
+ * Converts a path string, or a sequence of strings that when joined form
+ * a path string, to a {@code Path}. If {@code more} does not specify any
+ * elements then the value of the {@code first} parameter is the path string
+ * to convert. If {@code more} specifies one or more elements then each
+ * non-empty string, including {@code first}, is considered to be a sequence
+ * of name elements (see {@link Path}) and is joined to form a path string.
+ * The details as to how the Strings are joined is provider specific but
+ * typically they will be joined using the {@link FileSystem#getSeparator
+ * name-separator} as the separator. For example, if the name separator is
+ * "{@code /}" and {@code getPath("/foo","bar","gus")} is invoked, then the
+ * path string {@code "/foo/bar/gus"} is converted to a {@code Path}.
+ * A {@code Path} representing an empty path is returned if {@code first}
+ * is the empty string and {@code more} does not contain any non-empty
+ * strings.
+ *
+ * <p> The {@code Path} is obtained by invoking the {@link FileSystem#getPath
+ * getPath} method of the {@link FileSystems#getDefault default} {@link
+ * FileSystem}.
+ *
+ * <p> Note that while this method is very convenient, using it will imply
+ * an assumed reference to the default {@code FileSystem} and limit the
+ * utility of the calling code. Hence it should not be used in library code
+ * intended for flexible reuse. A more flexible alternative is to use an
+ * existing {@code Path} instance as an anchor, such as:
+ * <pre>
+ * Path dir = ...
+ * Path path = dir.resolve("file");
+ * </pre>
+ *
+ * @param first
+ * the path string or initial part of the path string
+ * @param more
+ * additional strings to be joined to form the path string
+ *
+ * @return the resulting {@code Path}
+ *
+ * @throws InvalidPathException
+ * if the path string cannot be converted to a {@code Path}
+ *
+ * @see FileSystem#getPath
+ */
+ public static Path get(String first, String... more) {
+ return FileSystems.getDefault().getPath(first, more);
+ }
+
+ /**
+ * Converts the given URI to a {@link Path} object.
+ *
+ * <p> This method iterates over the {@link FileSystemProvider#installedProviders()
+ * installed} providers to locate the provider that is identified by the
+ * URI {@link URI#getScheme scheme} of the given URI. URI schemes are
+ * compared without regard to case. If the provider is found then its {@link
+ * FileSystemProvider#getPath getPath} method is invoked to convert the
+ * URI.
+ *
+ * <p> In the case of the default provider, identified by the URI scheme
+ * "file", the given URI has a non-empty path component, and undefined query
+ * and fragment components. Whether the authority component may be present
+ * is platform specific. The returned {@code Path} is associated with the
+ * {@link FileSystems#getDefault default} file system.
+ *
+ * <p> The default provider provides a similar <em>round-trip</em> guarantee
+ * to the {@link java.io.File} class. For a given {@code Path} <i>p</i> it
+ * is guaranteed that
+ * <blockquote><tt>
+ * Paths.get(</tt><i>p</i><tt>.{@link Path#toUri() toUri}()).equals(</tt>
+ * <i>p</i><tt>.{@link Path#toAbsolutePath() toAbsolutePath}())</tt>
+ * </blockquote>
+ * so long as the original {@code Path}, the {@code URI}, and the new {@code
+ * Path} are all created in (possibly different invocations of) the same
+ * Java virtual machine. Whether other providers make any guarantees is
+ * provider specific and therefore unspecified.
+ *
+ * @param uri
+ * the URI to convert
+ *
+ * @return the resulting {@code Path}
+ *
+ * @throws IllegalArgumentException
+ * if preconditions on the {@code uri} parameter do not hold. The
+ * format of the URI is provider specific.
+ * @throws FileSystemNotFoundException
+ * The file system, identified by the URI, does not exist and
+ * cannot be created automatically, or the provider identified by
+ * the URI's scheme component is not installed
+ * @throws SecurityException
+ * if a security manager is installed and it denies an unspecified
+ * permission to access the file system
+ */
+ public static Path get(URI uri) {
+ String scheme = uri.getScheme();
+ if (scheme == null)
+ throw new IllegalArgumentException("Missing scheme");
+
+ // check for default provider to avoid loading of installed providers
+ if (scheme.equalsIgnoreCase("file"))
+ return FileSystems.getDefault().provider().getPath(uri);
+
+ // try to find provider
+ for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
+ if (provider.getScheme().equalsIgnoreCase(scheme)) {
+ return provider.getPath(uri);
+ }
+ }
+
+ throw new FileSystemNotFoundException("Provider \"" + scheme + "\" not installed");
+ }
+}
diff --git a/java/nio/file/ProviderMismatchException.java b/java/nio/file/ProviderMismatchException.java
new file mode 100644
index 0000000..0220d6e
--- /dev/null
+++ b/java/nio/file/ProviderMismatchException.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Unchecked exception thrown when an attempt is made to invoke a method on an
+ * object created by one file system provider with a parameter created by a
+ * different file system provider.
+ */
+public class ProviderMismatchException
+ extends java.lang.IllegalArgumentException
+{
+ static final long serialVersionUID = 4990847485741612530L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public ProviderMismatchException() {
+ }
+
+ /**
+ * Constructs an instance of this class.
+ *
+ * @param msg
+ * the detail message
+ */
+ public ProviderMismatchException(String msg) {
+ super(msg);
+ }
+}
diff --git a/java/nio/file/ProviderNotFoundException.java b/java/nio/file/ProviderNotFoundException.java
new file mode 100644
index 0000000..8fa0cef
--- /dev/null
+++ b/java/nio/file/ProviderNotFoundException.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Runtime exception thrown when a provider of the required type cannot be found.
+ */
+
+public class ProviderNotFoundException
+ extends RuntimeException
+{
+ static final long serialVersionUID = -1880012509822920354L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public ProviderNotFoundException() {
+ }
+
+ /**
+ * Constructs an instance of this class.
+ *
+ * @param msg
+ * the detail message
+ */
+ public ProviderNotFoundException(String msg) {
+ super(msg);
+ }
+}
diff --git a/java/nio/file/ReadOnlyFileSystemException.java b/java/nio/file/ReadOnlyFileSystemException.java
new file mode 100644
index 0000000..9b25e5f
--- /dev/null
+++ b/java/nio/file/ReadOnlyFileSystemException.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Unchecked exception thrown when an attempt is made to update an object
+ * associated with a {@link FileSystem#isReadOnly() read-only} {@code FileSystem}.
+ */
+
+public class ReadOnlyFileSystemException
+ extends UnsupportedOperationException
+{
+ static final long serialVersionUID = -6822409595617487197L;
+
+ /**
+ * Constructs an instance of this class.
+ */
+ public ReadOnlyFileSystemException() {
+ }
+}
diff --git a/java/nio/file/SecureDirectoryStream.java b/java/nio/file/SecureDirectoryStream.java
new file mode 100644
index 0000000..064618b
--- /dev/null
+++ b/java/nio/file/SecureDirectoryStream.java
@@ -0,0 +1,312 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.nio.file;
+
+import java.nio.file.attribute.*;
+import java.nio.channels.SeekableByteChannel;
+import java.util.Set;
+import java.io.IOException;
+
+/**
+ * A {@code DirectoryStream} that defines operations on files that are located
+ * relative to an open directory. A {@code SecureDirectoryStream} is intended
+ * for use by sophisticated or security sensitive applications requiring to
+ * traverse file trees or otherwise operate on directories in a race-free manner.
+ * Race conditions can arise when a sequence of file operations cannot be
+ * carried out in isolation. Each of the file operations defined by this
+ * interface specify a relative path. All access to the file is relative
+ * to the open directory irrespective of if the directory is moved or replaced
+ * by an attacker while the directory is open. A {@code SecureDirectoryStream}
+ * may also be used as a virtual <em>working directory</em>.
+ *
+ * <p> A {@code SecureDirectoryStream} requires corresponding support from the
+ * underlying operating system. Where an implementation supports this features
+ * then the {@code DirectoryStream} returned by the {@link Files#newDirectoryStream
+ * newDirectoryStream} method will be a {@code SecureDirectoryStream} and must
+ * be cast to that type in order to invoke the methods defined by this interface.
+ *
+ * <p> In the case of the default {@link java.nio.file.spi.FileSystemProvider
+ * provider}, and a security manager is set, then the permission checks are
+ * performed using the path obtained by resolving the given relative path
+ * against the <i>original path</i> of the directory (irrespective of if the
+ * directory is moved since it was opened).
+ *
+ * @since 1.7
+ */
+
+public interface SecureDirectoryStream<T>
+ extends DirectoryStream<T>
+{
+ /**
+ * Opens the directory identified by the given path, returning a {@code
+ * SecureDirectoryStream} to iterate over the entries in the directory.
+ *
+ * <p> This method works in exactly the manner specified by the {@link
+ * Files#newDirectoryStream(Path) newDirectoryStream} method for the case that
+ * the {@code path} parameter is an {@link Path#isAbsolute absolute} path.
+ * When the parameter is a relative path then the directory to open is
+ * relative to this open directory. The {@link
+ * LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} option may be used to
+ * ensure that this method fails if the file is a symbolic link.
+ *
+ * <p> The new directory stream, once created, is not dependent upon the
+ * directory stream used to create it. Closing this directory stream has no
+ * effect upon newly created directory stream.
+ *
+ * @param path
+ * the path to the directory to open
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return a new and open {@code SecureDirectoryStream} object
+ *
+ * @throws ClosedDirectoryStreamException
+ * if the directory stream is closed
+ * @throws NotDirectoryException
+ * if the file could not otherwise be opened because it is not
+ * a directory <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the directory.
+ */
+ SecureDirectoryStream<T> newDirectoryStream(T path, LinkOption... options)
+ throws IOException;
+
+ /**
+ * Opens or creates a file in this directory, returning a seekable byte
+ * channel to access the file.
+ *
+ * <p> This method works in exactly the manner specified by the {@link
+ * Files#newByteChannel Files.newByteChannel} method for the
+ * case that the {@code path} parameter is an {@link Path#isAbsolute absolute}
+ * path. When the parameter is a relative path then the file to open or
+ * create is relative to this open directory. In addition to the options
+ * defined by the {@code Files.newByteChannel} method, the {@link
+ * LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} option may be used to
+ * ensure that this method fails if the file is a symbolic link.
+ *
+ * <p> The channel, once created, is not dependent upon the directory stream
+ * used to create it. Closing this directory stream has no effect upon the
+ * channel.
+ *
+ * @param path
+ * the path of the file to open open or create
+ * @param options
+ * options specifying how the file is opened
+ * @param attrs
+ * an optional list of attributes to set atomically when creating
+ * the file
+ *
+ * @return the seekable byte channel
+ *
+ * @throws ClosedDirectoryStreamException
+ * if the directory stream is closed
+ * @throws IllegalArgumentException
+ * if the set contains an invalid combination of options
+ * @throws UnsupportedOperationException
+ * if an unsupported open option is specified or the array contains
+ * attributes that cannot be set atomically when creating the file
+ * @throws FileAlreadyExistsException
+ * if a file of that name already exists and the {@link
+ * StandardOpenOption#CREATE_NEW CREATE_NEW} option is specified
+ * <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the path if the file
+ * is opened for reading. The {@link SecurityManager#checkWrite(String)
+ * checkWrite} method is invoked to check write access to the path
+ * if the file is opened for writing.
+ */
+ SeekableByteChannel newByteChannel(T path,
+ Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
+ throws IOException;
+
+ /**
+ * Deletes a file.
+ *
+ * <p> Unlike the {@link Files#delete delete()} method, this method does
+ * not first examine the file to determine if the file is a directory.
+ * Whether a directory is deleted by this method is system dependent and
+ * therefore not specified. If the file is a symbolic link, then the link
+ * itself, not the final target of the link, is deleted. When the
+ * parameter is a relative path then the file to delete is relative to
+ * this open directory.
+ *
+ * @param path
+ * the path of the file to delete
+ *
+ * @throws ClosedDirectoryStreamException
+ * if the directory stream is closed
+ * @throws NoSuchFileException
+ * if the file does not exist <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkDelete(String) checkDelete}
+ * method is invoked to check delete access to the file
+ */
+ void deleteFile(T path) throws IOException;
+
+ /**
+ * Deletes a directory.
+ *
+ * <p> Unlike the {@link Files#delete delete()} method, this method
+ * does not first examine the file to determine if the file is a directory.
+ * Whether non-directories are deleted by this method is system dependent and
+ * therefore not specified. When the parameter is a relative path then the
+ * directory to delete is relative to this open directory.
+ *
+ * @param path
+ * the path of the directory to delete
+ *
+ * @throws ClosedDirectoryStreamException
+ * if the directory stream is closed
+ * @throws NoSuchFileException
+ * if the directory does not exist <i>(optional specific exception)</i>
+ * @throws DirectoryNotEmptyException
+ * if the directory could not otherwise be deleted because it is
+ * not empty <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkDelete(String) checkDelete}
+ * method is invoked to check delete access to the directory
+ */
+ void deleteDirectory(T path) throws IOException;
+
+ /**
+ * Move a file from this directory to another directory.
+ *
+ * <p> This method works in a similar manner to {@link Files#move move}
+ * method when the {@link StandardCopyOption#ATOMIC_MOVE ATOMIC_MOVE} option
+ * is specified. That is, this method moves a file as an atomic file system
+ * operation. If the {@code srcpath} parameter is an {@link Path#isAbsolute
+ * absolute} path then it locates the source file. If the parameter is a
+ * relative path then it is located relative to this open directory. If
+ * the {@code targetpath} parameter is absolute then it locates the target
+ * file (the {@code targetdir} parameter is ignored). If the parameter is
+ * a relative path it is located relative to the open directory identified
+ * by the {@code targetdir} parameter. In all cases, if the target file
+ * exists then it is implementation specific if it is replaced or this
+ * method fails.
+ *
+ * @param srcpath
+ * the name of the file to move
+ * @param targetdir
+ * the destination directory
+ * @param targetpath
+ * the name to give the file in the destination directory
+ *
+ * @throws ClosedDirectoryStreamException
+ * if this or the target directory stream is closed
+ * @throws FileAlreadyExistsException
+ * if the file already exists in the target directory and cannot
+ * be replaced <i>(optional specific exception)</i>
+ * @throws AtomicMoveNotSupportedException
+ * if the file cannot be moved as an atomic file system operation
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to both the source and
+ * target file.
+ */
+ void move(T srcpath, SecureDirectoryStream<T> targetdir, T targetpath)
+ throws IOException;
+
+ /**
+ * Returns a new file attribute view to access the file attributes of this
+ * directory.
+ *
+ * <p> The resulting file attribute view can be used to read or update the
+ * attributes of this (open) directory. The {@code type} parameter specifies
+ * the type of the attribute view and the method returns an instance of that
+ * type if supported. Invoking this method to obtain a {@link
+ * BasicFileAttributeView} always returns an instance of that class that is
+ * bound to this open directory.
+ *
+ * <p> The state of resulting file attribute view is intimately connected
+ * to this directory stream. Once the directory stream is {@link #close closed},
+ * then all methods to read or update attributes will throw {@link
+ * ClosedDirectoryStreamException ClosedDirectoryStreamException}.
+ *
+ * @param <V>
+ * The {@code FileAttributeView} type
+ * @param type
+ * the {@code Class} object corresponding to the file attribute view
+ *
+ * @return a new file attribute view of the specified type bound to
+ * this directory stream, or {@code null} if the attribute view
+ * type is not available
+ */
+ <V extends FileAttributeView> V getFileAttributeView(Class<V> type);
+
+ /**
+ * Returns a new file attribute view to access the file attributes of a file
+ * in this directory.
+ *
+ * <p> The resulting file attribute view can be used to read or update the
+ * attributes of file in this directory. The {@code type} parameter specifies
+ * the type of the attribute view and the method returns an instance of that
+ * type if supported. Invoking this method to obtain a {@link
+ * BasicFileAttributeView} always returns an instance of that class that is
+ * bound to the file in the directory.
+ *
+ * <p> The state of resulting file attribute view is intimately connected
+ * to this directory stream. Once the directory stream {@link #close closed},
+ * then all methods to read or update attributes will throw {@link
+ * ClosedDirectoryStreamException ClosedDirectoryStreamException}. The
+ * file is not required to exist at the time that the file attribute view
+ * is created but methods to read or update attributes of the file will
+ * fail when invoked and the file does not exist.
+ *
+ * @param <V>
+ * The {@code FileAttributeView} type
+ * @param path
+ * the path of the file
+ * @param type
+ * the {@code Class} object corresponding to the file attribute view
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return a new file attribute view of the specified type bound to a
+ * this directory stream, or {@code null} if the attribute view
+ * type is not available
+ *
+ */
+ <V extends FileAttributeView> V getFileAttributeView(T path,
+ Class<V> type,
+ LinkOption... options);
+}
diff --git a/java/nio/file/SimpleFileVisitor.java b/java/nio/file/SimpleFileVisitor.java
new file mode 100644
index 0000000..321e30e
--- /dev/null
+++ b/java/nio/file/SimpleFileVisitor.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+import java.nio.file.attribute.BasicFileAttributes;
+import java.io.IOException;
+import java.util.Objects;
+
+/**
+ * A simple visitor of files with default behavior to visit all files and to
+ * re-throw I/O errors.
+ *
+ * <p> Methods in this class may be overridden subject to their general contract.
+ *
+ * @param <T> The type of reference to the files
+ *
+ * @since 1.7
+ */
+
+public class SimpleFileVisitor<T> implements FileVisitor<T> {
+ /**
+ * Initializes a new instance of this class.
+ */
+ protected SimpleFileVisitor() {
+ }
+
+ /**
+ * Invoked for a directory before entries in the directory are visited.
+ *
+ * <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE
+ * CONTINUE}.
+ */
+ @Override
+ public FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
+ throws IOException
+ {
+ Objects.requireNonNull(dir);
+ Objects.requireNonNull(attrs);
+ return FileVisitResult.CONTINUE;
+ }
+
+ /**
+ * Invoked for a file in a directory.
+ *
+ * <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE
+ * CONTINUE}.
+ */
+ @Override
+ public FileVisitResult visitFile(T file, BasicFileAttributes attrs)
+ throws IOException
+ {
+ Objects.requireNonNull(file);
+ Objects.requireNonNull(attrs);
+ return FileVisitResult.CONTINUE;
+ }
+
+ /**
+ * Invoked for a file that could not be visited.
+ *
+ * <p> Unless overridden, this method re-throws the I/O exception that prevented
+ * the file from being visited.
+ */
+ @Override
+ public FileVisitResult visitFileFailed(T file, IOException exc)
+ throws IOException
+ {
+ Objects.requireNonNull(file);
+ throw exc;
+ }
+
+ /**
+ * Invoked for a directory after entries in the directory, and all of their
+ * descendants, have been visited.
+ *
+ * <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE
+ * CONTINUE} if the directory iteration completes without an I/O exception;
+ * otherwise this method re-throws the I/O exception that caused the iteration
+ * of the directory to terminate prematurely.
+ */
+ @Override
+ public FileVisitResult postVisitDirectory(T dir, IOException exc)
+ throws IOException
+ {
+ Objects.requireNonNull(dir);
+ if (exc != null)
+ throw exc;
+ return FileVisitResult.CONTINUE;
+ }
+}
diff --git a/java/nio/file/StandardCopyOption.java b/java/nio/file/StandardCopyOption.java
new file mode 100644
index 0000000..30a5786
--- /dev/null
+++ b/java/nio/file/StandardCopyOption.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Defines the standard copy options.
+ *
+ * @since 1.7
+ */
+
+public enum StandardCopyOption implements CopyOption {
+ /**
+ * Replace an existing file if it exists.
+ */
+ REPLACE_EXISTING,
+ /**
+ * Copy attributes to the new file.
+ */
+ COPY_ATTRIBUTES,
+ /**
+ * Move the file as an atomic file system operation.
+ */
+ ATOMIC_MOVE;
+}
diff --git a/java/nio/file/StandardOpenOption.java b/java/nio/file/StandardOpenOption.java
new file mode 100644
index 0000000..3ed2a9d
--- /dev/null
+++ b/java/nio/file/StandardOpenOption.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Defines the standard open options.
+ *
+ * @since 1.7
+ */
+
+public enum StandardOpenOption implements OpenOption {
+ /**
+ * Open for read access.
+ */
+ READ,
+
+ /**
+ * Open for write access.
+ */
+ WRITE,
+
+ /**
+ * If the file is opened for {@link #WRITE} access then bytes will be written
+ * to the end of the file rather than the beginning.
+ *
+ * <p> If the file is opened for write access by other programs, then it
+ * is file system specific if writing to the end of the file is atomic.
+ */
+ APPEND,
+
+ /**
+ * If the file already exists and it is opened for {@link #WRITE}
+ * access, then its length is truncated to 0. This option is ignored
+ * if the file is opened only for {@link #READ} access.
+ */
+ TRUNCATE_EXISTING,
+
+ /**
+ * Create a new file if it does not exist.
+ * This option is ignored if the {@link #CREATE_NEW} option is also set.
+ * The check for the existence of the file and the creation of the file
+ * if it does not exist is atomic with respect to other file system
+ * operations.
+ */
+ CREATE,
+
+ /**
+ * Create a new file, failing if the file already exists.
+ * The check for the existence of the file and the creation of the file
+ * if it does not exist is atomic with respect to other file system
+ * operations.
+ */
+ CREATE_NEW,
+
+ /**
+ * Delete on close. When this option is present then the implementation
+ * makes a <em>best effort</em> attempt to delete the file when closed
+ * by the appropriate {@code close} method. If the {@code close} method is
+ * not invoked then a <em>best effort</em> attempt is made to delete the
+ * file when the Java virtual machine terminates (either normally, as
+ * defined by the Java Language Specification, or where possible, abnormally).
+ * This option is primarily intended for use with <em>work files</em> that
+ * are used solely by a single instance of the Java virtual machine. This
+ * option is not recommended for use when opening files that are open
+ * concurrently by other entities. Many of the details as to when and how
+ * the file is deleted are implementation specific and therefore not
+ * specified. In particular, an implementation may be unable to guarantee
+ * that it deletes the expected file when replaced by an attacker while the
+ * file is open. Consequently, security sensitive applications should take
+ * care when using this option.
+ *
+ * <p> For security reasons, this option may imply the {@link
+ * LinkOption#NOFOLLOW_LINKS} option. In other words, if the option is present
+ * when opening an existing file that is a symbolic link then it may fail
+ * (by throwing {@link java.io.IOException}).
+ */
+ DELETE_ON_CLOSE,
+
+ /**
+ * Sparse file. When used with the {@link #CREATE_NEW} option then this
+ * option provides a <em>hint</em> that the new file will be sparse. The
+ * option is ignored when the file system does not support the creation of
+ * sparse files.
+ */
+ SPARSE,
+
+ /**
+ * Requires that every update to the file's content or metadata be written
+ * synchronously to the underlying storage device.
+ *
+ * @see <a href="package-summary.html#integrity">Synchronized I/O file integrity</a>
+ */
+ SYNC,
+
+ /**
+ * Requires that every update to the file's content be written
+ * synchronously to the underlying storage device.
+ *
+ * @see <a href="package-summary.html#integrity">Synchronized I/O file integrity</a>
+ */
+ DSYNC;
+}
diff --git a/java/nio/file/StandardWatchEventKinds.java b/java/nio/file/StandardWatchEventKinds.java
new file mode 100644
index 0000000..8b3aba0
--- /dev/null
+++ b/java/nio/file/StandardWatchEventKinds.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Defines the <em>standard</em> event kinds.
+ *
+ * @since 1.7
+ */
+
+public final class StandardWatchEventKinds {
+ private StandardWatchEventKinds() { }
+
+ /**
+ * A special event to indicate that events may have been lost or
+ * discarded.
+ *
+ * <p> The {@link WatchEvent#context context} for this event is
+ * implementation specific and may be {@code null}. The event {@link
+ * WatchEvent#count count} may be greater than {@code 1}.
+ *
+ * @see WatchService
+ */
+ public static final WatchEvent.Kind<Object> OVERFLOW =
+ new StdWatchEventKind<Object>("OVERFLOW", Object.class);
+
+ /**
+ * Directory entry created.
+ *
+ * <p> When a directory is registered for this event then the {@link WatchKey}
+ * is queued when it is observed that an entry is created in the directory
+ * or renamed into the directory. The event {@link WatchEvent#count count}
+ * for this event is always {@code 1}.
+ */
+ public static final WatchEvent.Kind<Path> ENTRY_CREATE =
+ new StdWatchEventKind<Path>("ENTRY_CREATE", Path.class);
+
+ /**
+ * Directory entry deleted.
+ *
+ * <p> When a directory is registered for this event then the {@link WatchKey}
+ * is queued when it is observed that an entry is deleted or renamed out of
+ * the directory. The event {@link WatchEvent#count count} for this event
+ * is always {@code 1}.
+ */
+ public static final WatchEvent.Kind<Path> ENTRY_DELETE =
+ new StdWatchEventKind<Path>("ENTRY_DELETE", Path.class);
+
+ /**
+ * Directory entry modified.
+ *
+ * <p> When a directory is registered for this event then the {@link WatchKey}
+ * is queued when it is observed that an entry in the directory has been
+ * modified. The event {@link WatchEvent#count count} for this event is
+ * {@code 1} or greater.
+ */
+ public static final WatchEvent.Kind<Path> ENTRY_MODIFY =
+ new StdWatchEventKind<Path>("ENTRY_MODIFY", Path.class);
+
+ private static class StdWatchEventKind<T> implements WatchEvent.Kind<T> {
+ private final String name;
+ private final Class<T> type;
+ StdWatchEventKind(String name, Class<T> type) {
+ this.name = name;
+ this.type = type;
+ }
+ @Override public String name() { return name; }
+ @Override public Class<T> type() { return type; }
+ @Override public String toString() { return name; }
+ }
+}
diff --git a/java/nio/file/TempFileHelper.java b/java/nio/file/TempFileHelper.java
new file mode 100644
index 0000000..8d171de
--- /dev/null
+++ b/java/nio/file/TempFileHelper.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+import java.util.Set;
+import java.util.EnumSet;
+import java.security.SecureRandom;
+import static java.security.AccessController.*;
+import java.io.IOException;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.file.attribute.PosixFilePermission;
+import java.nio.file.attribute.PosixFilePermissions;
+import static java.nio.file.attribute.PosixFilePermission.*;
+import sun.security.action.GetPropertyAction;
+
+
+/**
+ * Helper class to support creation of temporary files and directories with
+ * initial attributes.
+ */
+
+class TempFileHelper {
+ private TempFileHelper() { }
+
+ // temporary directory location
+ private static final Path tmpdir =
+ Paths.get(doPrivileged(new GetPropertyAction("java.io.tmpdir")));
+
+ private static final boolean isPosix =
+ FileSystems.getDefault().supportedFileAttributeViews().contains("posix");
+
+ // file name generation, same as java.io.File for now
+ private static final SecureRandom random = new SecureRandom();
+ private static Path generatePath(String prefix, String suffix, Path dir) {
+ long n = random.nextLong();
+ n = (n == Long.MIN_VALUE) ? 0 : Math.abs(n);
+ Path name = dir.getFileSystem().getPath(prefix + Long.toString(n) + suffix);
+ // the generated name should be a simple file name
+ if (name.getParent() != null)
+ throw new IllegalArgumentException("Invalid prefix or suffix");
+ return dir.resolve(name);
+ }
+
+ // default file and directory permissions (lazily initialized)
+ private static class PosixPermissions {
+ static final FileAttribute<Set<PosixFilePermission>> filePermissions =
+ PosixFilePermissions.asFileAttribute(EnumSet.of(OWNER_READ, OWNER_WRITE));
+ static final FileAttribute<Set<PosixFilePermission>> dirPermissions =
+ PosixFilePermissions.asFileAttribute(EnumSet
+ .of(OWNER_READ, OWNER_WRITE, OWNER_EXECUTE));
+ }
+
+ /**
+ * Creates a file or directory in in the given given directory (or in the
+ * temporary directory if dir is {@code null}).
+ */
+ private static Path create(Path dir,
+ String prefix,
+ String suffix,
+ boolean createDirectory,
+ FileAttribute<?>[] attrs)
+ throws IOException
+ {
+ if (prefix == null)
+ prefix = "";
+ if (suffix == null)
+ suffix = (createDirectory) ? "" : ".tmp";
+ if (dir == null)
+ dir = tmpdir;
+
+ // in POSIX environments use default file and directory permissions
+ // if initial permissions not given by caller.
+ if (isPosix && (dir.getFileSystem() == FileSystems.getDefault())) {
+ if (attrs.length == 0) {
+ // no attributes so use default permissions
+ attrs = new FileAttribute<?>[1];
+ attrs[0] = (createDirectory) ? PosixPermissions.dirPermissions :
+ PosixPermissions.filePermissions;
+ } else {
+ // check if posix permissions given; if not use default
+ boolean hasPermissions = false;
+ for (int i=0; i<attrs.length; i++) {
+ if (attrs[i].name().equals("posix:permissions")) {
+ hasPermissions = true;
+ break;
+ }
+ }
+ if (!hasPermissions) {
+ FileAttribute<?>[] copy = new FileAttribute<?>[attrs.length+1];
+ System.arraycopy(attrs, 0, copy, 0, attrs.length);
+ attrs = copy;
+ attrs[attrs.length-1] = (createDirectory) ?
+ PosixPermissions.dirPermissions :
+ PosixPermissions.filePermissions;
+ }
+ }
+ }
+
+ // loop generating random names until file or directory can be created
+ SecurityManager sm = System.getSecurityManager();
+ for (;;) {
+ Path f;
+ try {
+ f = generatePath(prefix, suffix, dir);
+ } catch (InvalidPathException e) {
+ // don't reveal temporary directory location
+ if (sm != null)
+ throw new IllegalArgumentException("Invalid prefix or suffix");
+ throw e;
+ }
+ try {
+ if (createDirectory) {
+ return Files.createDirectory(f, attrs);
+ } else {
+ return Files.createFile(f, attrs);
+ }
+ } catch (SecurityException e) {
+ // don't reveal temporary directory location
+ if (dir == tmpdir && sm != null)
+ throw new SecurityException("Unable to create temporary file or directory");
+ throw e;
+ } catch (FileAlreadyExistsException e) {
+ // ignore
+ }
+ }
+ }
+
+ /**
+ * Creates a temporary file in the given directory, or in in the
+ * temporary directory if dir is {@code null}.
+ */
+ static Path createTempFile(Path dir,
+ String prefix,
+ String suffix,
+ FileAttribute<?>[] attrs)
+ throws IOException
+ {
+ return create(dir, prefix, suffix, false, attrs);
+ }
+
+ /**
+ * Creates a temporary directory in the given directory, or in in the
+ * temporary directory if dir is {@code null}.
+ */
+ static Path createTempDirectory(Path dir,
+ String prefix,
+ FileAttribute<?>[] attrs)
+ throws IOException
+ {
+ return create(dir, prefix, null, true, attrs);
+ }
+}
diff --git a/java/nio/file/WatchEvent.java b/java/nio/file/WatchEvent.java
new file mode 100644
index 0000000..25438a8
--- /dev/null
+++ b/java/nio/file/WatchEvent.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * An event or a repeated event for an object that is registered with a {@link
+ * WatchService}.
+ *
+ * <p> An event is classified by its {@link #kind() kind} and has a {@link
+ * #count() count} to indicate the number of times that the event has been
+ * observed. This allows for efficient representation of repeated events. The
+ * {@link #context() context} method returns any context associated with
+ * the event. In the case of a repeated event then the context is the same for
+ * all events.
+ *
+ * <p> Watch events are immutable and safe for use by multiple concurrent
+ * threads.
+ *
+ * @param <T> The type of the context object associated with the event
+ *
+ * @since 1.7
+ */
+
+public interface WatchEvent<T> {
+
+ /**
+ * An event kind, for the purposes of identification.
+ *
+ * @since 1.7
+ * @see StandardWatchEventKinds
+ */
+ public static interface Kind<T> {
+ /**
+ * Returns the name of the event kind.
+ *
+ * @return the name of the event kind
+ */
+ String name();
+
+ /**
+ * Returns the type of the {@link WatchEvent#context context} value.
+ *
+ *
+ * @return the type of the context value
+ */
+ Class<T> type();
+ }
+
+ /**
+ * An event modifier that qualifies how a {@link Watchable} is registered
+ * with a {@link WatchService}.
+ *
+ * <p> This release does not define any <em>standard</em> modifiers.
+ *
+ * @since 1.7
+ * @see Watchable#register
+ */
+ public static interface Modifier {
+ /**
+ * Returns the name of the modifier.
+ *
+ * @return the name of the modifier
+ */
+ String name();
+ }
+
+ /**
+ * Returns the event kind.
+ *
+ * @return the event kind
+ */
+ Kind<T> kind();
+
+ /**
+ * Returns the event count. If the event count is greater than {@code 1}
+ * then this is a repeated event.
+ *
+ * @return the event count
+ */
+ int count();
+
+ /**
+ * Returns the context for the event.
+ *
+ * <p> In the case of {@link StandardWatchEventKinds#ENTRY_CREATE ENTRY_CREATE},
+ * {@link StandardWatchEventKinds#ENTRY_DELETE ENTRY_DELETE}, and {@link
+ * StandardWatchEventKinds#ENTRY_MODIFY ENTRY_MODIFY} events the context is
+ * a {@code Path} that is the {@link Path#relativize relative} path between
+ * the directory registered with the watch service, and the entry that is
+ * created, deleted, or modified.
+ *
+ * @return the event context; may be {@code null}
+ */
+ T context();
+}
diff --git a/java/nio/file/WatchKey.java b/java/nio/file/WatchKey.java
new file mode 100644
index 0000000..a4933f8
--- /dev/null
+++ b/java/nio/file/WatchKey.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+import java.util.List;
+
+/**
+ * A token representing the registration of a {@link Watchable watchable} object
+ * with a {@link WatchService}.
+ *
+ * <p> A watch key is created when a watchable object is registered with a watch
+ * service. The key remains {@link #isValid valid} until:
+ * <ol>
+ * <li> It is cancelled, explicitly, by invoking its {@link #cancel cancel}
+ * method, or</li>
+ * <li> Cancelled implicitly, because the object is no longer accessible,
+ * or </li>
+ * <li> By {@link WatchService#close closing} the watch service. </li>
+ * </ol>
+ *
+ * <p> A watch key has a state. When initially created the key is said to be
+ * <em>ready</em>. When an event is detected then the key is <em>signalled</em>
+ * and queued so that it can be retrieved by invoking the watch service's {@link
+ * WatchService#poll() poll} or {@link WatchService#take() take} methods. Once
+ * signalled, a key remains in this state until its {@link #reset reset} method
+ * is invoked to return the key to the ready state. Events detected while the
+ * key is in the signalled state are queued but do not cause the key to be
+ * re-queued for retrieval from the watch service. Events are retrieved by
+ * invoking the key's {@link #pollEvents pollEvents} method. This method
+ * retrieves and removes all events accumulated for the object. When initially
+ * created, a watch key has no pending events. Typically events are retrieved
+ * when the key is in the signalled state leading to the following idiom:
+ *
+ * <pre>
+ * for (;;) {
+ * // retrieve key
+ * WatchKey key = watcher.take();
+ *
+ * // process events
+ * for (WatchEvent<?> event: key.pollEvents()) {
+ * :
+ * }
+ *
+ * // reset the key
+ * boolean valid = key.reset();
+ * if (!valid) {
+ * // object no longer registered
+ * }
+ * }
+ * </pre>
+ *
+ * <p> Watch keys are safe for use by multiple concurrent threads. Where there
+ * are several threads retrieving signalled keys from a watch service then care
+ * should be taken to ensure that the {@code reset} method is only invoked after
+ * the events for the object have been processed. This ensures that one thread
+ * is processing the events for an object at any time.
+ *
+ * @since 1.7
+ */
+
+public interface WatchKey {
+
+ /**
+ * Tells whether or not this watch key is valid.
+ *
+ * <p> A watch key is valid upon creation and remains until it is cancelled,
+ * or its watch service is closed.
+ *
+ * @return {@code true} if, and only if, this watch key is valid
+ */
+ boolean isValid();
+
+ /**
+ * Retrieves and removes all pending events for this watch key, returning
+ * a {@code List} of the events that were retrieved.
+ *
+ * <p> Note that this method does not wait if there are no events pending.
+ *
+ * @return the list of the events retrieved; may be empty
+ */
+ List<WatchEvent<?>> pollEvents();
+
+ /**
+ * Resets this watch key.
+ *
+ * <p> If this watch key has been cancelled or this watch key is already in
+ * the ready state then invoking this method has no effect. Otherwise
+ * if there are pending events for the object then this watch key is
+ * immediately re-queued to the watch service. If there are no pending
+ * events then the watch key is put into the ready state and will remain in
+ * that state until an event is detected or the watch key is cancelled.
+ *
+ * @return {@code true} if the watch key is valid and has been reset, and
+ * {@code false} if the watch key could not be reset because it is
+ * no longer {@link #isValid valid}
+ */
+ boolean reset();
+
+ /**
+ * Cancels the registration with the watch service. Upon return the watch key
+ * will be invalid. If the watch key is enqueued, waiting to be retrieved
+ * from the watch service, then it will remain in the queue until it is
+ * removed. Pending events, if any, remain pending and may be retrieved by
+ * invoking the {@link #pollEvents pollEvents} method after the key is
+ * cancelled.
+ *
+ * <p> If this watch key has already been cancelled then invoking this
+ * method has no effect. Once cancelled, a watch key remains forever invalid.
+ */
+ void cancel();
+
+ /**
+ * Returns the object for which this watch key was created. This method will
+ * continue to return the object even after the key is cancelled.
+ *
+ * <p> As the {@code WatchService} is intended to map directly on to the
+ * native file event notification facility (where available) then many of
+ * details on how registered objects are watched is highly implementation
+ * specific. When watching a directory for changes for example, and the
+ * directory is moved or renamed in the file system, there is no guarantee
+ * that the watch key will be cancelled and so the object returned by this
+ * method may no longer be a valid path to the directory.
+ *
+ * @return the object for which this watch key was created
+ */
+ Watchable watchable();
+}
diff --git a/java/nio/file/WatchService.java b/java/nio/file/WatchService.java
new file mode 100644
index 0000000..d06222e
--- /dev/null
+++ b/java/nio/file/WatchService.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A watch service that <em>watches</em> registered objects for changes and
+ * events. For example a file manager may use a watch service to monitor a
+ * directory for changes so that it can update its display of the list of files
+ * when files are created or deleted.
+ *
+ * <p> A {@link Watchable} object is registered with a watch service by invoking
+ * its {@link Watchable#register register} method, returning a {@link WatchKey}
+ * to represent the registration. When an event for an object is detected the
+ * key is <em>signalled</em>, and if not currently signalled, it is queued to
+ * the watch service so that it can be retrieved by consumers that invoke the
+ * {@link #poll() poll} or {@link #take() take} methods to retrieve keys
+ * and process events. Once the events have been processed the consumer
+ * invokes the key's {@link WatchKey#reset reset} method to reset the key which
+ * allows the key to be signalled and re-queued with further events.
+ *
+ * <p> Registration with a watch service is cancelled by invoking the key's
+ * {@link WatchKey#cancel cancel} method. A key that is queued at the time that
+ * it is cancelled remains in the queue until it is retrieved. Depending on the
+ * object, a key may be cancelled automatically. For example, suppose a
+ * directory is watched and the watch service detects that it has been deleted
+ * or its file system is no longer accessible. When a key is cancelled in this
+ * manner it is signalled and queued, if not currently signalled. To ensure
+ * that the consumer is notified the return value from the {@code reset}
+ * method indicates if the key is valid.
+ *
+ * <p> A watch service is safe for use by multiple concurrent consumers. To
+ * ensure that only one consumer processes the events for a particular object at
+ * any time then care should be taken to ensure that the key's {@code reset}
+ * method is only invoked after its events have been processed. The {@link
+ * #close close} method may be invoked at any time to close the service causing
+ * any threads waiting to retrieve keys, to throw {@code
+ * ClosedWatchServiceException}.
+ *
+ * <p> File systems may report events faster than they can be retrieved or
+ * processed and an implementation may impose an unspecified limit on the number
+ * of events that it may accumulate. Where an implementation <em>knowingly</em>
+ * discards events then it arranges for the key's {@link WatchKey#pollEvents
+ * pollEvents} method to return an element with an event type of {@link
+ * StandardWatchEventKinds#OVERFLOW OVERFLOW}. This event can be used by the
+ * consumer as a trigger to re-examine the state of the object.
+ *
+ * <p> When an event is reported to indicate that a file in a watched directory
+ * has been modified then there is no guarantee that the program (or programs)
+ * that have modified the file have completed. Care should be taken to coordinate
+ * access with other programs that may be updating the file.
+ * The {@link java.nio.channels.FileChannel FileChannel} class defines methods
+ * to lock regions of a file against access by other programs.
+ *
+ * <h2>Platform dependencies</h2>
+ *
+ * <p> The implementation that observes events from the file system is intended
+ * to map directly on to the native file event notification facility where
+ * available, or to use a primitive mechanism, such as polling, when a native
+ * facility is not available. Consequently, many of the details on how events
+ * are detected, their timeliness, and whether their ordering is preserved are
+ * highly implementation specific. For example, when a file in a watched
+ * directory is modified then it may result in a single {@link
+ * StandardWatchEventKinds#ENTRY_MODIFY ENTRY_MODIFY} event in some
+ * implementations but several events in other implementations. Short-lived
+ * files (meaning files that are deleted very quickly after they are created)
+ * may not be detected by primitive implementations that periodically poll the
+ * file system to detect changes.
+ *
+ * <p> If a watched file is not located on a local storage device then it is
+ * implementation specific if changes to the file can be detected. In particular,
+ * it is not required that changes to files carried out on remote systems be
+ * detected.
+ *
+ * @since 1.7
+ *
+ * @see FileSystem#newWatchService
+ */
+
+public interface WatchService
+ extends Closeable
+{
+
+ /**
+ * Closes this watch service.
+ *
+ * <p> If a thread is currently blocked in the {@link #take take} or {@link
+ * #poll(long,TimeUnit) poll} methods waiting for a key to be queued then
+ * it immediately receives a {@link ClosedWatchServiceException}. Any
+ * valid keys associated with this watch service are {@link WatchKey#isValid
+ * invalidated}.
+ *
+ * <p> After a watch service is closed, any further attempt to invoke
+ * operations upon it will throw {@link ClosedWatchServiceException}.
+ * If this watch service is already closed then invoking this method
+ * has no effect.
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ @Override
+ void close() throws IOException;
+
+ /**
+ * Retrieves and removes the next watch key, or {@code null} if none are
+ * present.
+ *
+ * @return the next watch key, or {@code null}
+ *
+ * @throws ClosedWatchServiceException
+ * if this watch service is closed
+ */
+ WatchKey poll();
+
+ /**
+ * Retrieves and removes the next watch key, waiting if necessary up to the
+ * specified wait time if none are yet present.
+ *
+ * @param timeout
+ * how to wait before giving up, in units of unit
+ * @param unit
+ * a {@code TimeUnit} determining how to interpret the timeout
+ * parameter
+ *
+ * @return the next watch key, or {@code null}
+ *
+ * @throws ClosedWatchServiceException
+ * if this watch service is closed, or it is closed while waiting
+ * for the next key
+ * @throws InterruptedException
+ * if interrupted while waiting
+ */
+ WatchKey poll(long timeout, TimeUnit unit)
+ throws InterruptedException;
+
+ /**
+ * Retrieves and removes next watch key, waiting if none are yet present.
+ *
+ * @return the next watch key
+ *
+ * @throws ClosedWatchServiceException
+ * if this watch service is closed, or it is closed while waiting
+ * for the next key
+ * @throws InterruptedException
+ * if interrupted while waiting
+ */
+ WatchKey take() throws InterruptedException;
+}
diff --git a/java/nio/file/Watchable.java b/java/nio/file/Watchable.java
new file mode 100644
index 0000000..e3a86e6
--- /dev/null
+++ b/java/nio/file/Watchable.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+import java.io.IOException;
+
+/**
+ * An object that may be registered with a watch service so that it can be
+ * <em>watched</em> for changes and events.
+ *
+ * <p> This interface defines the {@link #register register} method to register
+ * the object with a {@link WatchService} returning a {@link WatchKey} to
+ * represent the registration. An object may be registered with more than one
+ * watch service. Registration with a watch service is cancelled by invoking the
+ * key's {@link WatchKey#cancel cancel} method.
+ *
+ * @since 1.7
+ *
+ * @see Path#register
+ */
+
+public interface Watchable {
+
+ /**
+ * Registers an object with a watch service.
+ *
+ * <p> If the file system object identified by this object is currently
+ * registered with the watch service then the watch key, representing that
+ * registration, is returned after changing the event set or modifiers to
+ * those specified by the {@code events} and {@code modifiers} parameters.
+ * Changing the event set does not cause pending events for the object to be
+ * discarded. Objects are automatically registered for the {@link
+ * StandardWatchEventKinds#OVERFLOW OVERFLOW} event. This event is not
+ * required to be present in the array of events.
+ *
+ * <p> Otherwise the file system object has not yet been registered with the
+ * given watch service, so it is registered and the resulting new key is
+ * returned.
+ *
+ * <p> Implementations of this interface should specify the events they
+ * support.
+ *
+ * @param watcher
+ * the watch service to which this object is to be registered
+ * @param events
+ * the events for which this object should be registered
+ * @param modifiers
+ * the modifiers, if any, that modify how the object is registered
+ *
+ * @return a key representing the registration of this object with the
+ * given watch service
+ *
+ * @throws UnsupportedOperationException
+ * if unsupported events or modifiers are specified
+ * @throws IllegalArgumentException
+ * if an invalid of combination of events are modifiers are specified
+ * @throws ClosedWatchServiceException
+ * if the watch service is closed
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * if a security manager is installed and it denies an unspecified
+ * permission required to monitor this object. Implementations of
+ * this interface should specify the permission checks.
+ */
+ WatchKey register(WatchService watcher,
+ WatchEvent.Kind<?>[] events,
+ WatchEvent.Modifier... modifiers)
+ throws IOException;
+
+
+ /**
+ * Registers an object with a watch service.
+ *
+ * <p> An invocation of this method behaves in exactly the same way as the
+ * invocation
+ * <pre>
+ * watchable.{@link #register(WatchService,WatchEvent.Kind[],WatchEvent.Modifier[]) register}(watcher, events, new WatchEvent.Modifier[0]);
+ * </pre>
+ *
+ * @param watcher
+ * the watch service to which this object is to be registered
+ * @param events
+ * the events for which this object should be registered
+ *
+ * @return a key representing the registration of this object with the
+ * given watch service
+ *
+ * @throws UnsupportedOperationException
+ * if unsupported events are specified
+ * @throws IllegalArgumentException
+ * if an invalid of combination of events are specified
+ * @throws ClosedWatchServiceException
+ * if the watch service is closed
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * if a security manager is installed and it denies an unspecified
+ * permission required to monitor this object. Implementations of
+ * this interface should specify the permission checks.
+ */
+ WatchKey register(WatchService watcher, WatchEvent.Kind<?>... events)
+ throws IOException;
+}
diff --git a/java/nio/file/attribute/AclEntry.java b/java/nio/file/attribute/AclEntry.java
new file mode 100644
index 0000000..b008494
--- /dev/null
+++ b/java/nio/file/attribute/AclEntry.java
@@ -0,0 +1,417 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.util.*;
+
+/**
+ * An entry in an access control list (ACL).
+ *
+ * <p> The ACL entry represented by this class is based on the ACL model
+ * specified in <a href="http://www.ietf.org/rfc/rfc3530.txt"><i>RFC 3530:
+ * Network File System (NFS) version 4 Protocol</i></a>. Each entry has four
+ * components as follows:
+ *
+ * <ol>
+ * <li><p> The {@link #type() type} component determines if the entry
+ * grants or denies access. </p></li>
+ *
+ * <li><p> The {@link #principal() principal} component, sometimes called the
+ * "who" component, is a {@link UserPrincipal} corresponding to the identity
+ * that the entry grants or denies access
+ * </p></li>
+ *
+ * <li><p> The {@link #permissions permissions} component is a set of
+ * {@link AclEntryPermission permissions}
+ * </p></li>
+ *
+ * <li><p> The {@link #flags flags} component is a set of {@link AclEntryFlag
+ * flags} to indicate how entries are inherited and propagated </p></li>
+ * </ol>
+ *
+ * <p> ACL entries are created using an associated {@link Builder} object by
+ * invoking its {@link Builder#build build} method.
+ *
+ * <p> ACL entries are immutable and are safe for use by multiple concurrent
+ * threads.
+ *
+ * @since 1.7
+ */
+
+public final class AclEntry {
+
+ private final AclEntryType type;
+ private final UserPrincipal who;
+ private final Set<AclEntryPermission> perms;
+ private final Set<AclEntryFlag> flags;
+
+ // cached hash code
+ private volatile int hash;
+
+ // private constructor
+ private AclEntry(AclEntryType type,
+ UserPrincipal who,
+ Set<AclEntryPermission> perms,
+ Set<AclEntryFlag> flags)
+ {
+ this.type = type;
+ this.who = who;
+ this.perms = perms;
+ this.flags = flags;
+ }
+
+ /**
+ * A builder of {@link AclEntry} objects.
+ *
+ * <p> A {@code Builder} object is obtained by invoking one of the {@link
+ * AclEntry#newBuilder newBuilder} methods defined by the {@code AclEntry}
+ * class.
+ *
+ * <p> Builder objects are mutable and are not safe for use by multiple
+ * concurrent threads without appropriate synchronization.
+ *
+ * @since 1.7
+ */
+ public static final class Builder {
+ private AclEntryType type;
+ private UserPrincipal who;
+ private Set<AclEntryPermission> perms;
+ private Set<AclEntryFlag> flags;
+
+ private Builder(AclEntryType type,
+ UserPrincipal who,
+ Set<AclEntryPermission> perms,
+ Set<AclEntryFlag> flags)
+ {
+ assert perms != null && flags != null;
+ this.type = type;
+ this.who = who;
+ this.perms = perms;
+ this.flags = flags;
+ }
+
+ /**
+ * Constructs an {@link AclEntry} from the components of this builder.
+ * The type and who components are required to have been set in order
+ * to construct an {@code AclEntry}.
+ *
+ * @return a new ACL entry
+ *
+ * @throws IllegalStateException
+ * if the type or who component have not been set
+ */
+ public AclEntry build() {
+ if (type == null)
+ throw new IllegalStateException("Missing type component");
+ if (who == null)
+ throw new IllegalStateException("Missing who component");
+ return new AclEntry(type, who, perms, flags);
+ }
+
+ /**
+ * Sets the type component of this builder.
+ *
+ * @param type the component type
+ * @return this builder
+ */
+ public Builder setType(AclEntryType type) {
+ if (type == null)
+ throw new NullPointerException();
+ this.type = type;
+ return this;
+ }
+
+ /**
+ * Sets the principal component of this builder.
+ *
+ * @param who the principal component
+ * @return this builder
+ */
+ public Builder setPrincipal(UserPrincipal who) {
+ if (who == null)
+ throw new NullPointerException();
+ this.who = who;
+ return this;
+ }
+
+ // check set only contains elements of the given type
+ private static void checkSet(Set<?> set, Class<?> type) {
+ for (Object e: set) {
+ if (e == null)
+ throw new NullPointerException();
+ type.cast(e);
+ }
+ }
+
+ /**
+ * Sets the permissions component of this builder. On return, the
+ * permissions component of this builder is a copy of the given set.
+ *
+ * @param perms the permissions component
+ * @return this builder
+ *
+ * @throws ClassCastException
+ * if the set contains elements that are not of type {@code
+ * AclEntryPermission}
+ */
+ public Builder setPermissions(Set<AclEntryPermission> perms) {
+ if (perms.isEmpty()) {
+ // EnumSet.copyOf does not allow empty set
+ perms = Collections.emptySet();
+ } else {
+ // copy and check for erroneous elements
+ perms = EnumSet.copyOf(perms);
+ checkSet(perms, AclEntryPermission.class);
+ }
+
+ this.perms = perms;
+ return this;
+ }
+
+ /**
+ * Sets the permissions component of this builder. On return, the
+ * permissions component of this builder is a copy of the permissions in
+ * the given array.
+ *
+ * @param perms the permissions component
+ * @return this builder
+ */
+ public Builder setPermissions(AclEntryPermission... perms) {
+ Set<AclEntryPermission> set = EnumSet.noneOf(AclEntryPermission.class);
+ // copy and check for null elements
+ for (AclEntryPermission p: perms) {
+ if (p == null)
+ throw new NullPointerException();
+ set.add(p);
+ }
+ this.perms = set;
+ return this;
+ }
+
+ /**
+ * Sets the flags component of this builder. On return, the flags
+ * component of this builder is a copy of the given set.
+ *
+ * @param flags the flags component
+ * @return this builder
+ *
+ * @throws ClassCastException
+ * if the set contains elements that are not of type {@code
+ * AclEntryFlag}
+ */
+ public Builder setFlags(Set<AclEntryFlag> flags) {
+ if (flags.isEmpty()) {
+ // EnumSet.copyOf does not allow empty set
+ flags = Collections.emptySet();
+ } else {
+ // copy and check for erroneous elements
+ flags = EnumSet.copyOf(flags);
+ checkSet(flags, AclEntryFlag.class);
+ }
+
+ this.flags = flags;
+ return this;
+ }
+
+ /**
+ * Sets the flags component of this builder. On return, the flags
+ * component of this builder is a copy of the flags in the given
+ * array.
+ *
+ * @param flags the flags component
+ * @return this builder
+ */
+ public Builder setFlags(AclEntryFlag... flags) {
+ Set<AclEntryFlag> set = EnumSet.noneOf(AclEntryFlag.class);
+ // copy and check for null elements
+ for (AclEntryFlag f: flags) {
+ if (f == null)
+ throw new NullPointerException();
+ set.add(f);
+ }
+ this.flags = set;
+ return this;
+ }
+ }
+
+ /**
+ * Constructs a new builder. The initial value of the type and who
+ * components is {@code null}. The initial value of the permissions and
+ * flags components is the empty set.
+ *
+ * @return a new builder
+ */
+ public static Builder newBuilder() {
+ Set<AclEntryPermission> perms = Collections.emptySet();
+ Set<AclEntryFlag> flags = Collections.emptySet();
+ return new Builder(null, null, perms, flags);
+ }
+
+ /**
+ * Constructs a new builder with the components of an existing ACL entry.
+ *
+ * @param entry an ACL entry
+ * @return a new builder
+ */
+ public static Builder newBuilder(AclEntry entry) {
+ return new Builder(entry.type, entry.who, entry.perms, entry.flags);
+ }
+
+ /**
+ * Returns the ACL entry type.
+ *
+ * @return the ACL entry type
+ */
+ public AclEntryType type() {
+ return type;
+ }
+
+ /**
+ * Returns the principal component.
+ *
+ * @return the principal component
+ */
+ public UserPrincipal principal() {
+ return who;
+ }
+
+ /**
+ * Returns a copy of the permissions component.
+ *
+ * <p> The returned set is a modifiable copy of the permissions.
+ *
+ * @return the permissions component
+ */
+ public Set<AclEntryPermission> permissions() {
+ return new HashSet<AclEntryPermission>(perms);
+ }
+
+ /**
+ * Returns a copy of the flags component.
+ *
+ * <p> The returned set is a modifiable copy of the flags.
+ *
+ * @return the flags component
+ */
+ public Set<AclEntryFlag> flags() {
+ return new HashSet<AclEntryFlag>(flags);
+ }
+
+ /**
+ * Compares the specified object with this ACL entry for equality.
+ *
+ * <p> If the given object is not an {@code AclEntry} then this method
+ * immediately returns {@code false}.
+ *
+ * <p> For two ACL entries to be considered equals requires that they are
+ * both the same type, their who components are equal, their permissions
+ * components are equal, and their flags components are equal.
+ *
+ * <p> This method satisfies the general contract of the {@link
+ * java.lang.Object#equals(Object) Object.equals} method. </p>
+ *
+ * @param ob the object to which this object is to be compared
+ *
+ * @return {@code true} if, and only if, the given object is an AclEntry that
+ * is identical to this AclEntry
+ */
+ @Override
+ public boolean equals(Object ob) {
+ if (ob == this)
+ return true;
+ if (ob == null || !(ob instanceof AclEntry))
+ return false;
+ AclEntry other = (AclEntry)ob;
+ if (this.type != other.type)
+ return false;
+ if (!this.who.equals(other.who))
+ return false;
+ if (!this.perms.equals(other.perms))
+ return false;
+ if (!this.flags.equals(other.flags))
+ return false;
+ return true;
+ }
+
+ private static int hash(int h, Object o) {
+ return h * 127 + o.hashCode();
+ }
+
+ /**
+ * Returns the hash-code value for this ACL entry.
+ *
+ * <p> This method satisfies the general contract of the {@link
+ * Object#hashCode} method.
+ */
+ @Override
+ public int hashCode() {
+ // return cached hash if available
+ if (hash != 0)
+ return hash;
+ int h = type.hashCode();
+ h = hash(h, who);
+ h = hash(h, perms);
+ h = hash(h, flags);
+ hash = h;
+ return hash;
+ }
+
+ /**
+ * Returns the string representation of this ACL entry.
+ *
+ * @return the string representation of this entry
+ */
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+
+ // who
+ sb.append(who.getName());
+ sb.append(':');
+
+ // permissions
+ for (AclEntryPermission perm: perms) {
+ sb.append(perm.name());
+ sb.append('/');
+ }
+ sb.setLength(sb.length()-1); // drop final slash
+ sb.append(':');
+
+ // flags
+ if (!flags.isEmpty()) {
+ for (AclEntryFlag flag: flags) {
+ sb.append(flag.name());
+ sb.append('/');
+ }
+ sb.setLength(sb.length()-1); // drop final slash
+ sb.append(':');
+ }
+
+ // type
+ sb.append(type.name());
+ return sb.toString();
+ }
+}
diff --git a/java/nio/file/attribute/AclEntryFlag.java b/java/nio/file/attribute/AclEntryFlag.java
new file mode 100644
index 0000000..6cb91f2
--- /dev/null
+++ b/java/nio/file/attribute/AclEntryFlag.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file.attribute;
+
+/**
+ * Defines the flags for used by the flags component of an ACL {@link AclEntry
+ * entry}.
+ *
+ * <p> In this release, this class does not define flags related to {@link
+ * AclEntryType#AUDIT} and {@link AclEntryType#ALARM} entry types.
+ *
+ * @since 1.7
+ */
+
+public enum AclEntryFlag {
+
+ /**
+ * Can be placed on a directory and indicates that the ACL entry should be
+ * added to each new non-directory file created.
+ */
+ FILE_INHERIT,
+
+ /**
+ * Can be placed on a directory and indicates that the ACL entry should be
+ * added to each new directory created.
+ */
+ DIRECTORY_INHERIT,
+
+ /**
+ * Can be placed on a directory to indicate that the ACL entry should not
+ * be placed on the newly created directory which is inheritable by
+ * subdirectories of the created directory.
+ */
+ NO_PROPAGATE_INHERIT,
+
+ /**
+ * Can be placed on a directory but does not apply to the directory,
+ * only to newly created files/directories as specified by the
+ * {@link #FILE_INHERIT} and {@link #DIRECTORY_INHERIT} flags.
+ */
+ INHERIT_ONLY;
+}
diff --git a/java/nio/file/attribute/AclEntryPermission.java b/java/nio/file/attribute/AclEntryPermission.java
new file mode 100644
index 0000000..492ab77
--- /dev/null
+++ b/java/nio/file/attribute/AclEntryPermission.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file.attribute;
+
+/**
+ * Defines the permissions for use with the permissions component of an ACL
+ * {@link AclEntry entry}.
+ *
+ * @since 1.7
+ */
+
+public enum AclEntryPermission {
+
+ /**
+ * Permission to read the data of the file.
+ */
+ READ_DATA,
+
+ /**
+ * Permission to modify the file's data.
+ */
+ WRITE_DATA,
+
+ /**
+ * Permission to append data to a file.
+ */
+ APPEND_DATA,
+
+ /**
+ * Permission to read the named attributes of a file.
+ *
+ * <p> <a href="http://www.ietf.org/rfc/rfc3530.txt">RFC 3530: Network
+ * File System (NFS) version 4 Protocol</a> defines <em>named attributes</em>
+ * as opaque files associated with a file in the file system.
+ */
+ READ_NAMED_ATTRS,
+
+ /**
+ * Permission to write the named attributes of a file.
+ *
+ * <p> <a href="http://www.ietf.org/rfc/rfc3530.txt">RFC 3530: Network
+ * File System (NFS) version 4 Protocol</a> defines <em>named attributes</em>
+ * as opaque files associated with a file in the file system.
+ */
+ WRITE_NAMED_ATTRS,
+
+ /**
+ * Permission to execute a file.
+ */
+ EXECUTE,
+
+ /**
+ * Permission to delete a file or directory within a directory.
+ */
+ DELETE_CHILD,
+
+ /**
+ * The ability to read (non-acl) file attributes.
+ */
+ READ_ATTRIBUTES,
+
+ /**
+ * The ability to write (non-acl) file attributes.
+ */
+ WRITE_ATTRIBUTES,
+
+ /**
+ * Permission to delete the file.
+ */
+ DELETE,
+
+ /**
+ * Permission to read the ACL attribute.
+ */
+ READ_ACL,
+
+ /**
+ * Permission to write the ACL attribute.
+ */
+ WRITE_ACL,
+
+ /**
+ * Permission to change the owner.
+ */
+ WRITE_OWNER,
+
+ /**
+ * Permission to access file locally at the server with synchronous reads
+ * and writes.
+ */
+ SYNCHRONIZE;
+
+ /**
+ * Permission to list the entries of a directory (equal to {@link #READ_DATA})
+ */
+ public static final AclEntryPermission LIST_DIRECTORY = READ_DATA;
+
+ /**
+ * Permission to add a new file to a directory (equal to {@link #WRITE_DATA})
+ */
+ public static final AclEntryPermission ADD_FILE = WRITE_DATA;
+
+ /**
+ * Permission to create a subdirectory to a directory (equal to {@link #APPEND_DATA})
+ */
+ public static final AclEntryPermission ADD_SUBDIRECTORY = APPEND_DATA;
+}
diff --git a/java/nio/file/attribute/AclEntryType.java b/java/nio/file/attribute/AclEntryType.java
new file mode 100644
index 0000000..9773b3f
--- /dev/null
+++ b/java/nio/file/attribute/AclEntryType.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file.attribute;
+
+/**
+ * A typesafe enumeration of the access control entry types.
+ *
+ * @since 1.7
+ */
+
+public enum AclEntryType {
+ /**
+ * Explicitly grants access to a file or directory.
+ */
+ ALLOW,
+
+ /**
+ * Explicitly denies access to a file or directory.
+ */
+ DENY,
+
+ /**
+ * Log, in a system dependent way, the access specified in the
+ * permissions component of the ACL entry.
+ */
+ AUDIT,
+
+ /**
+ * Generate an alarm, in a system dependent way, the access specified in the
+ * permissions component of the ACL entry.
+ */
+ ALARM
+}
diff --git a/java/nio/file/attribute/AclFileAttributeView.java b/java/nio/file/attribute/AclFileAttributeView.java
new file mode 100644
index 0000000..129d0ee
--- /dev/null
+++ b/java/nio/file/attribute/AclFileAttributeView.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.nio.file.*;
+import java.util.List;
+import java.io.IOException;
+
+/**
+ * A file attribute view that supports reading or updating a file's Access
+ * Control Lists (ACL) or file owner attributes.
+ *
+ * <p> ACLs are used to specify access rights to file system objects. An ACL is
+ * an ordered list of {@link AclEntry access-control-entries}, each specifying a
+ * {@link UserPrincipal} and the level of access for that user principal. This
+ * file attribute view defines the {@link #getAcl() getAcl}, and {@link
+ * #setAcl(List) setAcl} methods to read and write ACLs based on the ACL
+ * model specified in <a href="http://www.ietf.org/rfc/rfc3530.txt"><i>RFC 3530:
+ * Network File System (NFS) version 4 Protocol</i></a>. This file attribute view
+ * is intended for file system implementations that support the NFSv4 ACL model
+ * or have a <em>well-defined</em> mapping between the NFSv4 ACL model and the ACL
+ * model used by the file system. The details of such mapping are implementation
+ * dependent and are therefore unspecified.
+ *
+ * <p> This class also extends {@code FileOwnerAttributeView} so as to define
+ * methods to get and set the file owner.
+ *
+ * <p> When a file system provides access to a set of {@link FileStore
+ * file-systems} that are not homogeneous then only some of the file systems may
+ * support ACLs. The {@link FileStore#supportsFileAttributeView
+ * supportsFileAttributeView} method can be used to test if a file system
+ * supports ACLs.
+ *
+ * <h2>Interoperability</h2>
+ *
+ * RFC 3530 allows for special user identities to be used on platforms that
+ * support the POSIX defined access permissions. The special user identities
+ * are "{@code OWNER@}", "{@code GROUP@}", and "{@code EVERYONE@}". When both
+ * the {@code AclFileAttributeView} and the {@link PosixFileAttributeView}
+ * are supported then these special user identities may be included in ACL {@link
+ * AclEntry entries} that are read or written. The file system's {@link
+ * UserPrincipalLookupService} may be used to obtain a {@link UserPrincipal}
+ * to represent these special identities by invoking the {@link
+ * UserPrincipalLookupService#lookupPrincipalByName lookupPrincipalByName}
+ * method.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we wish to add an entry to an existing ACL to grant "joe" access:
+ * <pre>
+ * // lookup "joe"
+ * UserPrincipal joe = file.getFileSystem().getUserPrincipalLookupService()
+ * .lookupPrincipalByName("joe");
+ *
+ * // get view
+ * AclFileAttributeView view = Files.getFileAttributeView(file, AclFileAttributeView.class);
+ *
+ * // create ACE to give "joe" read access
+ * AclEntry entry = AclEntry.newBuilder()
+ * .setType(AclEntryType.ALLOW)
+ * .setPrincipal(joe)
+ * .setPermissions(AclEntryPermission.READ_DATA, AclEntryPermission.READ_ATTRIBUTES)
+ * .build();
+ *
+ * // read ACL, insert ACE, re-write ACL
+ * List<AclEntry> acl = view.getAcl();
+ * acl.add(0, entry); // insert before any DENY entries
+ * view.setAcl(acl);
+ * </pre>
+ *
+ * <h2> Dynamic Access </h2>
+ * <p> Where dynamic access to file attributes is required, the attributes
+ * supported by this attribute view are as follows:
+ * <blockquote>
+ * <table border="1" cellpadding="8" summary="Supported attributes">
+ * <tr>
+ * <th> Name </th>
+ * <th> Type </th>
+ * </tr>
+ * <tr>
+ * <td> "acl" </td>
+ * <td> {@link List}<{@link AclEntry}> </td>
+ * </tr>
+ * <tr>
+ * <td> "owner" </td>
+ * <td> {@link UserPrincipal} </td>
+ * </tr>
+ * </table>
+ * </blockquote>
+ *
+ * <p> The {@link Files#getAttribute getAttribute} method may be used to read
+ * the ACL or owner attributes as if by invoking the {@link #getAcl getAcl} or
+ * {@link #getOwner getOwner} methods.
+ *
+ * <p> The {@link Files#setAttribute setAttribute} method may be used to
+ * update the ACL or owner attributes as if by invoking the {@link #setAcl setAcl}
+ * or {@link #setOwner setOwner} methods.
+ *
+ * <h2> Setting the ACL when creating a file </h2>
+ *
+ * <p> Implementations supporting this attribute view may also support setting
+ * the initial ACL when creating a file or directory. The initial ACL
+ * may be provided to methods such as {@link Files#createFile createFile} or {@link
+ * Files#createDirectory createDirectory} as an {@link FileAttribute} with {@link
+ * FileAttribute#name name} {@code "acl:acl"} and a {@link FileAttribute#value
+ * value} that is the list of {@code AclEntry} objects.
+ *
+ * <p> Where an implementation supports an ACL model that differs from the NFSv4
+ * defined ACL model then setting the initial ACL when creating the file must
+ * translate the ACL to the model supported by the file system. Methods that
+ * create a file should reject (by throwing {@link IOException IOException})
+ * any attempt to create a file that would be less secure as a result of the
+ * translation.
+ *
+ * @since 1.7
+ */
+
+public interface AclFileAttributeView
+ extends FileOwnerAttributeView
+{
+ /**
+ * Returns the name of the attribute view. Attribute views of this type
+ * have the name {@code "acl"}.
+ */
+ @Override
+ String name();
+
+ /**
+ * Reads the access control list.
+ *
+ * <p> When the file system uses an ACL model that differs from the NFSv4
+ * defined ACL model, then this method returns an ACL that is the translation
+ * of the ACL to the NFSv4 ACL model.
+ *
+ * <p> The returned list is modifiable so as to facilitate changes to the
+ * existing ACL. The {@link #setAcl setAcl} method is used to update
+ * the file's ACL attribute.
+ *
+ * @return an ordered list of {@link AclEntry entries} representing the
+ * ACL
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, a security manager is
+ * installed, and it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+ * or its {@link SecurityManager#checkRead(String) checkRead} method
+ * denies read access to the file.
+ */
+ List<AclEntry> getAcl() throws IOException;
+
+ /**
+ * Updates (replace) the access control list.
+ *
+ * <p> Where the file system supports Access Control Lists, and it uses an
+ * ACL model that differs from the NFSv4 defined ACL model, then this method
+ * must translate the ACL to the model supported by the file system. This
+ * method should reject (by throwing {@link IOException IOException}) any
+ * attempt to write an ACL that would appear to make the file more secure
+ * than would be the case if the ACL were updated. Where an implementation
+ * does not support a mapping of {@link AclEntryType#AUDIT} or {@link
+ * AclEntryType#ALARM} entries, then this method ignores these entries when
+ * writing the ACL.
+ *
+ * <p> If an ACL entry contains a {@link AclEntry#principal user-principal}
+ * that is not associated with the same provider as this attribute view then
+ * {@link ProviderMismatchException} is thrown. Additional validation, if
+ * any, is implementation dependent.
+ *
+ * <p> If the file system supports other security related file attributes
+ * (such as a file {@link PosixFileAttributes#permissions
+ * access-permissions} for example), the updating the access control list
+ * may also cause these security related attributes to be updated.
+ *
+ * @param acl
+ * the new access control list
+ *
+ * @throws IOException
+ * if an I/O error occurs or the ACL is invalid
+ * @throws SecurityException
+ * In the case of the default provider, a security manager is
+ * installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to the file.
+ */
+ void setAcl(List<AclEntry> acl) throws IOException;
+}
diff --git a/java/nio/file/attribute/AttributeView.java b/java/nio/file/attribute/AttributeView.java
new file mode 100644
index 0000000..569076c
--- /dev/null
+++ b/java/nio/file/attribute/AttributeView.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file.attribute;
+
+/**
+ * An object that provides a read-only or updatable <em>view</em> of non-opaque
+ * values associated with an object in a filesystem. This interface is extended
+ * or implemented by specific attribute views that define the attributes
+ * supported by the view. A specific attribute view will typically define
+ * type-safe methods to read or update the attributes that it supports.
+ *
+ * @since 1.7
+ */
+
+public interface AttributeView {
+ /**
+ * Returns the name of the attribute view.
+ *
+ * @return the name of the attribute view
+ */
+ String name();
+}
diff --git a/java/nio/file/attribute/BasicFileAttributeView.java b/java/nio/file/attribute/BasicFileAttributeView.java
new file mode 100644
index 0000000..bfa3fdc
--- /dev/null
+++ b/java/nio/file/attribute/BasicFileAttributeView.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.io.IOException;
+
+/**
+ * A file attribute view that provides a view of a <em>basic set</em> of file
+ * attributes common to many file systems. The basic set of file attributes
+ * consist of <em>mandatory</em> and <em>optional</em> file attributes as
+ * defined by the {@link BasicFileAttributes} interface.
+
+ * <p> The file attributes are retrieved from the file system as a <em>bulk
+ * operation</em> by invoking the {@link #readAttributes() readAttributes} method.
+ * This class also defines the {@link #setTimes setTimes} method to update the
+ * file's time attributes.
+ *
+ * <p> Where dynamic access to file attributes is required, the attributes
+ * supported by this attribute view have the following names and types:
+ * <blockquote>
+ * <table border="1" cellpadding="8" summary="Supported attributes">
+ * <tr>
+ * <th> Name </th>
+ * <th> Type </th>
+ * </tr>
+ * <tr>
+ * <td> "lastModifiedTime" </td>
+ * <td> {@link FileTime} </td>
+ * </tr>
+ * <tr>
+ * <td> "lastAccessTime" </td>
+ * <td> {@link FileTime} </td>
+ * </tr>
+ * <tr>
+ * <td> "creationTime" </td>
+ * <td> {@link FileTime} </td>
+ * </tr>
+ * <tr>
+ * <td> "size" </td>
+ * <td> {@link Long} </td>
+ * </tr>
+ * <tr>
+ * <td> "isRegularFile" </td>
+ * <td> {@link Boolean} </td>
+ * </tr>
+ * <tr>
+ * <td> "isDirectory" </td>
+ * <td> {@link Boolean} </td>
+ * </tr>
+ * <tr>
+ * <td> "isSymbolicLink" </td>
+ * <td> {@link Boolean} </td>
+ * </tr>
+ * <tr>
+ * <td> "isOther" </td>
+ * <td> {@link Boolean} </td>
+ * </tr>
+ * <tr>
+ * <td> "fileKey" </td>
+ * <td> {@link Object} </td>
+ * </tr>
+ * </table>
+ * </blockquote>
+ *
+ * <p> The {@link java.nio.file.Files#getAttribute getAttribute} method may be
+ * used to read any of these attributes as if by invoking the {@link
+ * #readAttributes() readAttributes()} method.
+ *
+ * <p> The {@link java.nio.file.Files#setAttribute setAttribute} method may be
+ * used to update the file's last modified time, last access time or create time
+ * attributes as if by invoking the {@link #setTimes setTimes} method.
+ *
+ * @since 1.7
+ */
+
+public interface BasicFileAttributeView
+ extends FileAttributeView
+{
+ /**
+ * Returns the name of the attribute view. Attribute views of this type
+ * have the name {@code "basic"}.
+ */
+ @Override
+ String name();
+
+ /**
+ * Reads the basic file attributes as a bulk operation.
+ *
+ * <p> It is implementation specific if all file attributes are read as an
+ * atomic operation with respect to other file system operations.
+ *
+ * @return the file attributes
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, a security manager is
+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file
+ */
+ BasicFileAttributes readAttributes() throws IOException;
+
+ /**
+ * Updates any or all of the file's last modified time, last access time,
+ * and create time attributes.
+ *
+ * <p> This method updates the file's timestamp attributes. The values are
+ * converted to the epoch and precision supported by the file system.
+ * Converting from finer to coarser granularities result in precision loss.
+ * The behavior of this method when attempting to set a timestamp that is
+ * not supported or to a value that is outside the range supported by the
+ * underlying file store is not defined. It may or not fail by throwing an
+ * {@code IOException}.
+ *
+ * <p> If any of the {@code lastModifiedTime}, {@code lastAccessTime},
+ * or {@code createTime} parameters has the value {@code null} then the
+ * corresponding timestamp is not changed. An implementation may require to
+ * read the existing values of the file attributes when only some, but not
+ * all, of the timestamp attributes are updated. Consequently, this method
+ * may not be an atomic operation with respect to other file system
+ * operations. Reading and re-writing existing values may also result in
+ * precision loss. If all of the {@code lastModifiedTime}, {@code
+ * lastAccessTime} and {@code createTime} parameters are {@code null} then
+ * this method has no effect.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to change a file's last access time.
+ * <pre>
+ * Path path = ...
+ * FileTime time = ...
+ * Files.getFileAttributeView(path, BasicFileAttributeView.class).setTimes(null, time, null);
+ * </pre>
+ *
+ * @param lastModifiedTime
+ * the new last modified time, or {@code null} to not change the
+ * value
+ * @param lastAccessTime
+ * the last access time, or {@code null} to not change the value
+ * @param createTime
+ * the file's create time, or {@code null} to not change the value
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, a security manager is
+ * installed, its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to the file
+ *
+ * @see java.nio.file.Files#setLastModifiedTime
+ */
+ void setTimes(FileTime lastModifiedTime,
+ FileTime lastAccessTime,
+ FileTime createTime) throws IOException;
+}
diff --git a/java/nio/file/attribute/BasicFileAttributes.java b/java/nio/file/attribute/BasicFileAttributes.java
new file mode 100644
index 0000000..1aeb0d7
--- /dev/null
+++ b/java/nio/file/attribute/BasicFileAttributes.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file.attribute;
+
+/**
+ * Basic attributes associated with a file in a file system.
+ *
+ * <p> Basic file attributes are attributes that are common to many file systems
+ * and consist of mandatory and optional file attributes as defined by this
+ * interface.
+ *
+ * <p> <b>Usage Example:</b>
+ * <pre>
+ * Path file = ...
+ * BasicFileAttributes attrs = Files.readAttributes(file, BasicFileAttributes.class);
+ * </pre>
+ *
+ * @since 1.7
+ *
+ * @see BasicFileAttributeView
+ */
+
+public interface BasicFileAttributes {
+
+ /**
+ * Returns the time of last modification.
+ *
+ * <p> If the file system implementation does not support a time stamp
+ * to indicate the time of last modification then this method returns an
+ * implementation specific default value, typically a {@code FileTime}
+ * representing the epoch (1970-01-01T00:00:00Z).
+ *
+ * @return a {@code FileTime} representing the time the file was last
+ * modified
+ */
+ FileTime lastModifiedTime();
+
+ /**
+ * Returns the time of last access.
+ *
+ * <p> If the file system implementation does not support a time stamp
+ * to indicate the time of last access then this method returns
+ * an implementation specific default value, typically the {@link
+ * #lastModifiedTime() last-modified-time} or a {@code FileTime}
+ * representing the epoch (1970-01-01T00:00:00Z).
+ *
+ * @return a {@code FileTime} representing the time of last access
+ */
+ FileTime lastAccessTime();
+
+ /**
+ * Returns the creation time. The creation time is the time that the file
+ * was created.
+ *
+ * <p> If the file system implementation does not support a time stamp
+ * to indicate the time when the file was created then this method returns
+ * an implementation specific default value, typically the {@link
+ * #lastModifiedTime() last-modified-time} or a {@code FileTime}
+ * representing the epoch (1970-01-01T00:00:00Z).
+ *
+ * @return a {@code FileTime} representing the time the file was created
+ */
+ FileTime creationTime();
+
+ /**
+ * Tells whether the file is a regular file with opaque content.
+ *
+ * @return {@code true} if the file is a regular file with opaque content
+ */
+ boolean isRegularFile();
+
+ /**
+ * Tells whether the file is a directory.
+ *
+ * @return {@code true} if the file is a directory
+ */
+ boolean isDirectory();
+
+ /**
+ * Tells whether the file is a symbolic link.
+ *
+ * @return {@code true} if the file is a symbolic link
+ */
+ boolean isSymbolicLink();
+
+ /**
+ * Tells whether the file is something other than a regular file, directory,
+ * or symbolic link.
+ *
+ * @return {@code true} if the file something other than a regular file,
+ * directory or symbolic link
+ */
+ boolean isOther();
+
+ /**
+ * Returns the size of the file (in bytes). The size may differ from the
+ * actual size on the file system due to compression, support for sparse
+ * files, or other reasons. The size of files that are not {@link
+ * #isRegularFile regular} files is implementation specific and
+ * therefore unspecified.
+ *
+ * @return the file size, in bytes
+ */
+ long size();
+
+ /**
+ * Returns an object that uniquely identifies the given file, or {@code
+ * null} if a file key is not available. On some platforms or file systems
+ * it is possible to use an identifier, or a combination of identifiers to
+ * uniquely identify a file. Such identifiers are important for operations
+ * such as file tree traversal in file systems that support <a
+ * href="../package-summary.html#links">symbolic links</a> or file systems
+ * that allow a file to be an entry in more than one directory. On UNIX file
+ * systems, for example, the <em>device ID</em> and <em>inode</em> are
+ * commonly used for such purposes.
+ *
+ * <p> The file key returned by this method can only be guaranteed to be
+ * unique if the file system and files remain static. Whether a file system
+ * re-uses identifiers after a file is deleted is implementation dependent and
+ * therefore unspecified.
+ *
+ * <p> File keys returned by this method can be compared for equality and are
+ * suitable for use in collections. If the file system and files remain static,
+ * and two files are the {@link java.nio.file.Files#isSameFile same} with
+ * non-{@code null} file keys, then their file keys are equal.
+ *
+ * @return an object that uniquely identifies the given file, or {@code null}
+ *
+ * @see java.nio.file.Files#walkFileTree
+ */
+ Object fileKey();
+}
diff --git a/java/nio/file/attribute/DosFileAttributeView.java b/java/nio/file/attribute/DosFileAttributeView.java
new file mode 100644
index 0000000..c12d8a0
--- /dev/null
+++ b/java/nio/file/attribute/DosFileAttributeView.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.io.IOException;
+
+/**
+ * A file attribute view that provides a view of the legacy "DOS" file attributes.
+ * These attributes are supported by file systems such as the File Allocation
+ * Table (FAT) format commonly used in <em>consumer devices</em>.
+ *
+ * <p> A {@code DosFileAttributeView} is a {@link BasicFileAttributeView} that
+ * additionally supports access to the set of DOS attribute flags that are used
+ * to indicate if the file is read-only, hidden, a system file, or archived.
+ *
+ * <p> Where dynamic access to file attributes is required, the attributes
+ * supported by this attribute view are as defined by {@code
+ * BasicFileAttributeView}, and in addition, the following attributes are
+ * supported:
+ * <blockquote>
+ * <table border="1" cellpadding="8" summary="Supported attributes">
+ * <tr>
+ * <th> Name </th>
+ * <th> Type </th>
+ * </tr>
+ * <tr>
+ * <td> readonly </td>
+ * <td> {@link Boolean} </td>
+ * </tr>
+ * <tr>
+ * <td> hidden </td>
+ * <td> {@link Boolean} </td>
+ * </tr>
+ * <tr>
+ * <td> system </td>
+ * <td> {@link Boolean} </td>
+ * </tr>
+ * <tr>
+ * <td> archive </td>
+ * <td> {@link Boolean} </td>
+ * </tr>
+ * </table>
+ * </blockquote>
+ *
+ * <p> The {@link java.nio.file.Files#getAttribute getAttribute} method may
+ * be used to read any of these attributes, or any of the attributes defined by
+ * {@link BasicFileAttributeView} as if by invoking the {@link #readAttributes
+ * readAttributes()} method.
+ *
+ * <p> The {@link java.nio.file.Files#setAttribute setAttribute} method may
+ * be used to update the file's last modified time, last access time or create
+ * time attributes as defined by {@link BasicFileAttributeView}. It may also be
+ * used to update the DOS attributes as if by invoking the {@link #setReadOnly
+ * setReadOnly}, {@link #setHidden setHidden}, {@link #setSystem setSystem}, and
+ * {@link #setArchive setArchive} methods respectively.
+ *
+ * @since 1.7
+ */
+
+public interface DosFileAttributeView
+ extends BasicFileAttributeView
+{
+ /**
+ * Returns the name of the attribute view. Attribute views of this type
+ * have the name {@code "dos"}.
+ */
+ @Override
+ String name();
+
+ /**
+ * @throws IOException {@inheritDoc}
+ * @throws SecurityException {@inheritDoc}
+ */
+ @Override
+ DosFileAttributes readAttributes() throws IOException;
+
+ /**
+ * Updates the value of the read-only attribute.
+ *
+ * <p> It is implementation specific if the attribute can be updated as an
+ * atomic operation with respect to other file system operations. An
+ * implementation may, for example, require to read the existing value of
+ * the DOS attribute in order to update this attribute.
+ *
+ * @param value
+ * the new value of the attribute
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default, and a security manager is installed,
+ * its {@link SecurityManager#checkWrite(String) checkWrite} method
+ * is invoked to check write access to the file
+ */
+ void setReadOnly(boolean value) throws IOException;
+
+ /**
+ * Updates the value of the hidden attribute.
+ *
+ * <p> It is implementation specific if the attribute can be updated as an
+ * atomic operation with respect to other file system operations. An
+ * implementation may, for example, require to read the existing value of
+ * the DOS attribute in order to update this attribute.
+ *
+ * @param value
+ * the new value of the attribute
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default, and a security manager is installed,
+ * its {@link SecurityManager#checkWrite(String) checkWrite} method
+ * is invoked to check write access to the file
+ */
+ void setHidden(boolean value) throws IOException;
+
+ /**
+ * Updates the value of the system attribute.
+ *
+ * <p> It is implementation specific if the attribute can be updated as an
+ * atomic operation with respect to other file system operations. An
+ * implementation may, for example, require to read the existing value of
+ * the DOS attribute in order to update this attribute.
+ *
+ * @param value
+ * the new value of the attribute
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default, and a security manager is installed,
+ * its {@link SecurityManager#checkWrite(String) checkWrite} method
+ * is invoked to check write access to the file
+ */
+ void setSystem(boolean value) throws IOException;
+
+ /**
+ * Updates the value of the archive attribute.
+ *
+ * <p> It is implementation specific if the attribute can be updated as an
+ * atomic operation with respect to other file system operations. An
+ * implementation may, for example, require to read the existing value of
+ * the DOS attribute in order to update this attribute.
+ *
+ * @param value
+ * the new value of the attribute
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default, and a security manager is installed,
+ * its {@link SecurityManager#checkWrite(String) checkWrite} method
+ * is invoked to check write access to the file
+ */
+ void setArchive(boolean value) throws IOException;
+}
diff --git a/java/nio/file/attribute/DosFileAttributes.java b/java/nio/file/attribute/DosFileAttributes.java
new file mode 100644
index 0000000..e1fbca9
--- /dev/null
+++ b/java/nio/file/attribute/DosFileAttributes.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file.attribute;
+
+/**
+ * File attributes associated with a file in a file system that supports
+ * legacy "DOS" attributes.
+ *
+ * <p> <b>Usage Example:</b>
+ * <pre>
+ * Path file = ...
+ * DosFileAttributes attrs = Files.readAttributes(file, DosFileAttributes.class);
+ * </pre>
+ *
+ * @since 1.7
+ */
+
+public interface DosFileAttributes
+ extends BasicFileAttributes
+{
+ /**
+ * Returns the value of the read-only attribute.
+ *
+ * <p> This attribute is often used as a simple access control mechanism
+ * to prevent files from being deleted or updated. Whether the file system
+ * or platform does any enforcement to prevent <em>read-only</em> files
+ * from being updated is implementation specific.
+ *
+ * @return the value of the read-only attribute
+ */
+ boolean isReadOnly();
+
+ /**
+ * Returns the value of the hidden attribute.
+ *
+ * <p> This attribute is often used to indicate if the file is visible to
+ * users.
+ *
+ * @return the value of the hidden attribute
+ */
+ boolean isHidden();
+
+ /**
+ * Returns the value of the archive attribute.
+ *
+ * <p> This attribute is typically used by backup programs.
+ *
+ * @return the value of the archive attribute
+ */
+ boolean isArchive();
+
+ /**
+ * Returns the value of the system attribute.
+ *
+ * <p> This attribute is often used to indicate that the file is a component
+ * of the operating system.
+ *
+ * @return the value of the system attribute
+ */
+ boolean isSystem();
+}
diff --git a/java/nio/file/attribute/FileAttribute.java b/java/nio/file/attribute/FileAttribute.java
new file mode 100644
index 0000000..16181dd
--- /dev/null
+++ b/java/nio/file/attribute/FileAttribute.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file.attribute;
+
+/**
+ * An object that encapsulates the value of a file attribute that can be set
+ * atomically when creating a new file or directory by invoking the {@link
+ * java.nio.file.Files#createFile createFile} or {@link
+ * java.nio.file.Files#createDirectory createDirectory} methods.
+ *
+ * @param <T> The type of the file attribute value
+ *
+ * @since 1.7
+ * @see PosixFilePermissions#asFileAttribute
+ */
+
+public interface FileAttribute<T> {
+ /**
+ * Returns the attribute name.
+ *
+ * @return The attribute name
+ */
+ String name();
+
+ /**
+ * Returns the attribute value.
+ *
+ * @return The attribute value
+ */
+ T value();
+}
diff --git a/java/nio/file/attribute/FileAttributeView.java b/java/nio/file/attribute/FileAttributeView.java
new file mode 100644
index 0000000..d82e402
--- /dev/null
+++ b/java/nio/file/attribute/FileAttributeView.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file.attribute;
+
+/**
+ * An attribute view that is a read-only or updatable view of non-opaque
+ * values associated with a file in a filesystem. This interface is extended or
+ * implemented by specific file attribute views that define methods to read
+ * and/or update the attributes of a file.
+ *
+ * @since 1.7
+ *
+ * @see java.nio.file.Files#getFileAttributeView(Path,Class,java.nio.file.LinkOption[])
+ */
+
+public interface FileAttributeView
+ extends AttributeView
+{
+}
diff --git a/java/nio/file/attribute/FileOwnerAttributeView.java b/java/nio/file/attribute/FileOwnerAttributeView.java
new file mode 100644
index 0000000..f18caaf
--- /dev/null
+++ b/java/nio/file/attribute/FileOwnerAttributeView.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.io.IOException;
+
+/**
+ * A file attribute view that supports reading or updating the owner of a file.
+ * This file attribute view is intended for file system implementations that
+ * support a file attribute that represents an identity that is the owner of
+ * the file. Often the owner of a file is the identity of the entity that
+ * created the file.
+ *
+ * <p> The {@link #getOwner getOwner} or {@link #setOwner setOwner} methods may
+ * be used to read or update the owner of the file.
+ *
+ * <p> The {@link java.nio.file.Files#getAttribute getAttribute} and
+ * {@link java.nio.file.Files#setAttribute setAttribute} methods may also be
+ * used to read or update the owner. In that case, the owner attribute is
+ * identified by the name {@code "owner"}, and the value of the attribute is
+ * a {@link UserPrincipal}.
+ *
+ * @since 1.7
+ */
+
+public interface FileOwnerAttributeView
+ extends FileAttributeView
+{
+ /**
+ * Returns the name of the attribute view. Attribute views of this type
+ * have the name {@code "owner"}.
+ */
+ @Override
+ String name();
+
+ /**
+ * Read the file owner.
+ *
+ * <p> It it implementation specific if the file owner can be a {@link
+ * GroupPrincipal group}.
+ *
+ * @return the file owner
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, a security manager is
+ * installed, and it denies {@link
+ * RuntimePermission}<tt>("accessUserInformation")</tt> or its
+ * {@link SecurityManager#checkRead(String) checkRead} method
+ * denies read access to the file.
+ */
+ UserPrincipal getOwner() throws IOException;
+
+ /**
+ * Updates the file owner.
+ *
+ * <p> It it implementation specific if the file owner can be a {@link
+ * GroupPrincipal group}. To ensure consistent and correct behavior
+ * across platforms it is recommended that this method should only be used
+ * to set the file owner to a user principal that is not a group.
+ *
+ * @param owner
+ * the new file owner
+ *
+ * @throws IOException
+ * if an I/O error occurs, or the {@code owner} parameter is a
+ * group and this implementation does not support setting the owner
+ * to a group
+ * @throws SecurityException
+ * In the case of the default provider, a security manager is
+ * installed, and it denies {@link
+ * RuntimePermission}<tt>("accessUserInformation")</tt> or its
+ * {@link SecurityManager#checkWrite(String) checkWrite} method
+ * denies write access to the file.
+ */
+ void setOwner(UserPrincipal owner) throws IOException;
+}
diff --git a/java/nio/file/attribute/FileStoreAttributeView.java b/java/nio/file/attribute/FileStoreAttributeView.java
new file mode 100644
index 0000000..0efb9b6
--- /dev/null
+++ b/java/nio/file/attribute/FileStoreAttributeView.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file.attribute;
+
+/**
+ * An attribute view that is a read-only or updatable view of the attributes of
+ * a {@link java.nio.file.FileStore}.
+ *
+ * @since 1.7
+ */
+
+public interface FileStoreAttributeView
+ extends AttributeView
+{
+}
diff --git a/java/nio/file/attribute/FileTime.java b/java/nio/file/attribute/FileTime.java
new file mode 100644
index 0000000..2f3399b
--- /dev/null
+++ b/java/nio/file/attribute/FileTime.java
@@ -0,0 +1,475 @@
+/*
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Represents the value of a file's time stamp attribute. For example, it may
+ * represent the time that the file was last
+ * {@link BasicFileAttributes#lastModifiedTime() modified},
+ * {@link BasicFileAttributes#lastAccessTime() accessed},
+ * or {@link BasicFileAttributes#creationTime() created}.
+ *
+ * <p> Instances of this class are immutable.
+ *
+ * @since 1.7
+ * @see java.nio.file.Files#setLastModifiedTime
+ * @see java.nio.file.Files#getLastModifiedTime
+ */
+
+public final class FileTime
+ implements Comparable<FileTime>
+{
+ /**
+ * The unit of granularity to interpret the value. Null if
+ * this {@code FileTime} is converted from an {@code Instant},
+ * the {@code value} and {@code unit} pair will not be used
+ * in this scenario.
+ */
+ private final TimeUnit unit;
+
+ /**
+ * The value since the epoch; can be negative.
+ */
+ private final long value;
+
+ /**
+ * The value as Instant (created lazily, if not from an instant)
+ */
+ private Instant instant;
+
+ /**
+ * The value return by toString (created lazily)
+ */
+ private String valueAsString;
+
+ /**
+ * Initializes a new instance of this class.
+ */
+ private FileTime(long value, TimeUnit unit, Instant instant) {
+ this.value = value;
+ this.unit = unit;
+ this.instant = instant;
+ }
+
+ /**
+ * Returns a {@code FileTime} representing a value at the given unit of
+ * granularity.
+ *
+ * @param value
+ * the value since the epoch (1970-01-01T00:00:00Z); can be
+ * negative
+ * @param unit
+ * the unit of granularity to interpret the value
+ *
+ * @return a {@code FileTime} representing the given value
+ */
+ public static FileTime from(long value, TimeUnit unit) {
+ Objects.requireNonNull(unit, "unit");
+ return new FileTime(value, unit, null);
+ }
+
+ /**
+ * Returns a {@code FileTime} representing the given value in milliseconds.
+ *
+ * @param value
+ * the value, in milliseconds, since the epoch
+ * (1970-01-01T00:00:00Z); can be negative
+ *
+ * @return a {@code FileTime} representing the given value
+ */
+ public static FileTime fromMillis(long value) {
+ return new FileTime(value, TimeUnit.MILLISECONDS, null);
+ }
+
+ /**
+ * Returns a {@code FileTime} representing the same point of time value
+ * on the time-line as the provided {@code Instant} object.
+ *
+ * @param instant
+ * the instant to convert
+ * @return a {@code FileTime} representing the same point on the time-line
+ * as the provided instant
+ * @since 1.8
+ */
+ public static FileTime from(Instant instant) {
+ Objects.requireNonNull(instant, "instant");
+ return new FileTime(0, null, instant);
+ }
+
+ /**
+ * Returns the value at the given unit of granularity.
+ *
+ * <p> Conversion from a coarser granularity that would numerically overflow
+ * saturate to {@code Long.MIN_VALUE} if negative or {@code Long.MAX_VALUE}
+ * if positive.
+ *
+ * @param unit
+ * the unit of granularity for the return value
+ *
+ * @return value in the given unit of granularity, since the epoch
+ * since the epoch (1970-01-01T00:00:00Z); can be negative
+ */
+ public long to(TimeUnit unit) {
+ Objects.requireNonNull(unit, "unit");
+ if (this.unit != null) {
+ return unit.convert(this.value, this.unit);
+ } else {
+ long secs = unit.convert(instant.getEpochSecond(), TimeUnit.SECONDS);
+ if (secs == Long.MIN_VALUE || secs == Long.MAX_VALUE) {
+ return secs;
+ }
+ long nanos = unit.convert(instant.getNano(), TimeUnit.NANOSECONDS);
+ long r = secs + nanos;
+ // Math.addExact() variant
+ if (((secs ^ r) & (nanos ^ r)) < 0) {
+ return (secs < 0) ? Long.MIN_VALUE : Long.MAX_VALUE;
+ }
+ return r;
+ }
+ }
+
+ /**
+ * Returns the value in milliseconds.
+ *
+ * <p> Conversion from a coarser granularity that would numerically overflow
+ * saturate to {@code Long.MIN_VALUE} if negative or {@code Long.MAX_VALUE}
+ * if positive.
+ *
+ * @return the value in milliseconds, since the epoch (1970-01-01T00:00:00Z)
+ */
+ public long toMillis() {
+ if (unit != null) {
+ return unit.toMillis(value);
+ } else {
+ long secs = instant.getEpochSecond();
+ int nanos = instant.getNano();
+ // Math.multiplyExact() variant
+ long r = secs * 1000;
+ long ax = Math.abs(secs);
+ if (((ax | 1000) >>> 31 != 0)) {
+ if ((r / 1000) != secs) {
+ return (secs < 0) ? Long.MIN_VALUE : Long.MAX_VALUE;
+ }
+ }
+ return r + nanos / 1000_000;
+ }
+ }
+
+ /**
+ * Time unit constants for conversion.
+ */
+ private static final long HOURS_PER_DAY = 24L;
+ private static final long MINUTES_PER_HOUR = 60L;
+ private static final long SECONDS_PER_MINUTE = 60L;
+ private static final long SECONDS_PER_HOUR = SECONDS_PER_MINUTE * MINUTES_PER_HOUR;
+ private static final long SECONDS_PER_DAY = SECONDS_PER_HOUR * HOURS_PER_DAY;
+ private static final long MILLIS_PER_SECOND = 1000L;
+ private static final long MICROS_PER_SECOND = 1000_000L;
+ private static final long NANOS_PER_SECOND = 1000_000_000L;
+ private static final int NANOS_PER_MILLI = 1000_000;
+ private static final int NANOS_PER_MICRO = 1000;
+ // The epoch second of Instant.MIN.
+ private static final long MIN_SECOND = -31557014167219200L;
+ // The epoch second of Instant.MAX.
+ private static final long MAX_SECOND = 31556889864403199L;
+
+ /*
+ * Scale d by m, checking for overflow.
+ */
+ private static long scale(long d, long m, long over) {
+ if (d > over) return Long.MAX_VALUE;
+ if (d < -over) return Long.MIN_VALUE;
+ return d * m;
+ }
+
+ /**
+ * Converts this {@code FileTime} object to an {@code Instant}.
+ *
+ * <p> The conversion creates an {@code Instant} that represents the
+ * same point on the time-line as this {@code FileTime}.
+ *
+ * <p> {@code FileTime} can store points on the time-line further in the
+ * future and further in the past than {@code Instant}. Conversion
+ * from such further time points saturates to {@link Instant#MIN} if
+ * earlier than {@code Instant.MIN} or {@link Instant#MAX} if later
+ * than {@code Instant.MAX}.
+ *
+ * @return an instant representing the same point on the time-line as
+ * this {@code FileTime} object
+ * @since 1.8
+ */
+ public Instant toInstant() {
+ if (instant == null) {
+ long secs = 0L;
+ int nanos = 0;
+ switch (unit) {
+ case DAYS:
+ secs = scale(value, SECONDS_PER_DAY,
+ Long.MAX_VALUE/SECONDS_PER_DAY);
+ break;
+ case HOURS:
+ secs = scale(value, SECONDS_PER_HOUR,
+ Long.MAX_VALUE/SECONDS_PER_HOUR);
+ break;
+ case MINUTES:
+ secs = scale(value, SECONDS_PER_MINUTE,
+ Long.MAX_VALUE/SECONDS_PER_MINUTE);
+ break;
+ case SECONDS:
+ secs = value;
+ break;
+ case MILLISECONDS:
+ secs = Math.floorDiv(value, MILLIS_PER_SECOND);
+ nanos = (int)Math.floorMod(value, MILLIS_PER_SECOND)
+ * NANOS_PER_MILLI;
+ break;
+ case MICROSECONDS:
+ secs = Math.floorDiv(value, MICROS_PER_SECOND);
+ nanos = (int)Math.floorMod(value, MICROS_PER_SECOND)
+ * NANOS_PER_MICRO;
+ break;
+ case NANOSECONDS:
+ secs = Math.floorDiv(value, NANOS_PER_SECOND);
+ nanos = (int)Math.floorMod(value, NANOS_PER_SECOND);
+ break;
+ default : throw new AssertionError("Unit not handled");
+ }
+ if (secs <= MIN_SECOND)
+ instant = Instant.MIN;
+ else if (secs >= MAX_SECOND)
+ instant = Instant.MAX;
+ else
+ instant = Instant.ofEpochSecond(secs, nanos);
+ }
+ return instant;
+ }
+
+ /**
+ * Tests this {@code FileTime} for equality with the given object.
+ *
+ * <p> The result is {@code true} if and only if the argument is not {@code
+ * null} and is a {@code FileTime} that represents the same time. This
+ * method satisfies the general contract of the {@code Object.equals} method.
+ *
+ * @param obj
+ * the object to compare with
+ *
+ * @return {@code true} if, and only if, the given object is a {@code
+ * FileTime} that represents the same time
+ */
+ @Override
+ public boolean equals(Object obj) {
+ return (obj instanceof FileTime) ? compareTo((FileTime)obj) == 0 : false;
+ }
+
+ /**
+ * Computes a hash code for this file time.
+ *
+ * <p> The hash code is based upon the value represented, and satisfies the
+ * general contract of the {@link Object#hashCode} method.
+ *
+ * @return the hash-code value
+ */
+ @Override
+ public int hashCode() {
+ // hashcode of instant representation to satisfy contract with equals
+ return toInstant().hashCode();
+ }
+
+ private long toDays() {
+ if (unit != null) {
+ return unit.toDays(value);
+ } else {
+ return TimeUnit.SECONDS.toDays(toInstant().getEpochSecond());
+ }
+ }
+
+ private long toExcessNanos(long days) {
+ if (unit != null) {
+ return unit.toNanos(value - unit.convert(days, TimeUnit.DAYS));
+ } else {
+ return TimeUnit.SECONDS.toNanos(toInstant().getEpochSecond()
+ - TimeUnit.DAYS.toSeconds(days));
+ }
+ }
+
+ /**
+ * Compares the value of two {@code FileTime} objects for order.
+ *
+ * @param other
+ * the other {@code FileTime} to be compared
+ *
+ * @return {@code 0} if this {@code FileTime} is equal to {@code other}, a
+ * value less than 0 if this {@code FileTime} represents a time
+ * that is before {@code other}, and a value greater than 0 if this
+ * {@code FileTime} represents a time that is after {@code other}
+ */
+ @Override
+ public int compareTo(FileTime other) {
+ // same granularity
+ if (unit != null && unit == other.unit) {
+ return Long.compare(value, other.value);
+ } else {
+ // compare using instant representation when unit differs
+ long secs = toInstant().getEpochSecond();
+ long secsOther = other.toInstant().getEpochSecond();
+ int cmp = Long.compare(secs, secsOther);
+ if (cmp != 0) {
+ return cmp;
+ }
+ cmp = Long.compare(toInstant().getNano(), other.toInstant().getNano());
+ if (cmp != 0) {
+ return cmp;
+ }
+ if (secs != MAX_SECOND && secs != MIN_SECOND) {
+ return 0;
+ }
+ // if both this and other's Instant reps are MIN/MAX,
+ // use daysSinceEpoch and nanosOfDays, which will not
+ // saturate during calculation.
+ long days = toDays();
+ long daysOther = other.toDays();
+ if (days == daysOther) {
+ return Long.compare(toExcessNanos(days), other.toExcessNanos(daysOther));
+ }
+ return Long.compare(days, daysOther);
+ }
+ }
+
+ // days in a 400 year cycle = 146097
+ // days in a 10,000 year cycle = 146097 * 25
+ // seconds per day = 86400
+ private static final long DAYS_PER_10000_YEARS = 146097L * 25L;
+ private static final long SECONDS_PER_10000_YEARS = 146097L * 25L * 86400L;
+ private static final long SECONDS_0000_TO_1970 = ((146097L * 5L) - (30L * 365L + 7L)) * 86400L;
+
+ // append year/month/day/hour/minute/second/nano with width and 0 padding
+ private StringBuilder append(StringBuilder sb, int w, int d) {
+ while (w > 0) {
+ sb.append((char)(d/w + '0'));
+ d = d % w;
+ w /= 10;
+ }
+ return sb;
+ }
+
+ /**
+ * Returns the string representation of this {@code FileTime}. The string
+ * is returned in the <a
+ * href="http://www.w3.org/TR/NOTE-datetime">ISO 8601</a> format:
+ * <pre>
+ * YYYY-MM-DDThh:mm:ss[.s+]Z
+ * </pre>
+ * where "{@code [.s+]}" represents a dot followed by one of more digits
+ * for the decimal fraction of a second. It is only present when the decimal
+ * fraction of a second is not zero. For example, {@code
+ * FileTime.fromMillis(1234567890000L).toString()} yields {@code
+ * "2009-02-13T23:31:30Z"}, and {@code FileTime.fromMillis(1234567890123L).toString()}
+ * yields {@code "2009-02-13T23:31:30.123Z"}.
+ *
+ * <p> A {@code FileTime} is primarily intended to represent the value of a
+ * file's time stamp. Where used to represent <i>extreme values</i>, where
+ * the year is less than "{@code 0001}" or greater than "{@code 9999}" then
+ * this method deviates from ISO 8601 in the same manner as the
+ * <a href="http://www.w3.org/TR/xmlschema-2/#deviantformats">XML Schema
+ * language</a>. That is, the year may be expanded to more than four digits
+ * and may be negative-signed. If more than four digits then leading zeros
+ * are not present. The year before "{@code 0001}" is "{@code -0001}".
+ *
+ * @return the string representation of this file time
+ */
+ @Override
+ public String toString() {
+ if (valueAsString == null) {
+ long secs = 0L;
+ int nanos = 0;
+ if (instant == null && unit.compareTo(TimeUnit.SECONDS) >= 0) {
+ secs = unit.toSeconds(value);
+ } else {
+ secs = toInstant().getEpochSecond();
+ nanos = toInstant().getNano();
+ }
+ LocalDateTime ldt;
+ int year = 0;
+ if (secs >= -SECONDS_0000_TO_1970) {
+ // current era
+ long zeroSecs = secs - SECONDS_PER_10000_YEARS + SECONDS_0000_TO_1970;
+ long hi = Math.floorDiv(zeroSecs, SECONDS_PER_10000_YEARS) + 1;
+ long lo = Math.floorMod(zeroSecs, SECONDS_PER_10000_YEARS);
+ ldt = LocalDateTime.ofEpochSecond(lo - SECONDS_0000_TO_1970, nanos, ZoneOffset.UTC);
+ year = ldt.getYear() + (int)hi * 10000;
+ } else {
+ // before current era
+ long zeroSecs = secs + SECONDS_0000_TO_1970;
+ long hi = zeroSecs / SECONDS_PER_10000_YEARS;
+ long lo = zeroSecs % SECONDS_PER_10000_YEARS;
+ ldt = LocalDateTime.ofEpochSecond(lo - SECONDS_0000_TO_1970, nanos, ZoneOffset.UTC);
+ year = ldt.getYear() + (int)hi * 10000;
+ }
+ if (year <= 0) {
+ year = year - 1;
+ }
+ int fraction = ldt.getNano();
+ StringBuilder sb = new StringBuilder(64);
+ sb.append(year < 0 ? "-" : "");
+ year = Math.abs(year);
+ if (year < 10000) {
+ append(sb, 1000, Math.abs(year));
+ } else {
+ sb.append(String.valueOf(year));
+ }
+ sb.append('-');
+ append(sb, 10, ldt.getMonthValue());
+ sb.append('-');
+ append(sb, 10, ldt.getDayOfMonth());
+ sb.append('T');
+ append(sb, 10, ldt.getHour());
+ sb.append(':');
+ append(sb, 10, ldt.getMinute());
+ sb.append(':');
+ append(sb, 10, ldt.getSecond());
+ if (fraction != 0) {
+ sb.append('.');
+ // adding leading zeros and stripping any trailing zeros
+ int w = 100_000_000;
+ while (fraction % 10 == 0) {
+ fraction /= 10;
+ w /= 10;
+ }
+ append(sb, w, fraction);
+ }
+ sb.append('Z');
+ valueAsString = sb.toString();
+ }
+ return valueAsString;
+ }
+}
diff --git a/java/nio/file/attribute/GroupPrincipal.java b/java/nio/file/attribute/GroupPrincipal.java
new file mode 100644
index 0000000..8c679c5
--- /dev/null
+++ b/java/nio/file/attribute/GroupPrincipal.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file.attribute;
+
+/**
+ * A {@code UserPrincipal} representing a <em>group identity</em>, used to
+ * determine access rights to objects in a file system. The exact definition of
+ * a group is implementation specific, but typically, it represents an identity
+ * created for administrative purposes so as to determine the access rights for
+ * the members of the group. Whether an entity can be a member of multiple
+ * groups, and whether groups can be nested, are implementation specified and
+ * therefore not specified.
+ *
+ * @since 1.7
+ *
+ * @see UserPrincipalLookupService#lookupPrincipalByGroupName
+ */
+
+public interface GroupPrincipal extends UserPrincipal { }
diff --git a/java/nio/file/attribute/PosixFileAttributeView.java b/java/nio/file/attribute/PosixFileAttributeView.java
new file mode 100644
index 0000000..25466f2
--- /dev/null
+++ b/java/nio/file/attribute/PosixFileAttributeView.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.nio.file.*;
+import java.util.Set;
+import java.io.IOException;
+
+/**
+ * A file attribute view that provides a view of the file attributes commonly
+ * associated with files on file systems used by operating systems that implement
+ * the Portable Operating System Interface (POSIX) family of standards.
+ *
+ * <p> Operating systems that implement the <a href="http://www.opengroup.org">
+ * POSIX</a> family of standards commonly use file systems that have a
+ * file <em>owner</em>, <em>group-owner</em>, and related <em>access
+ * permissions</em>. This file attribute view provides read and write access
+ * to these attributes.
+ *
+ * <p> The {@link #readAttributes() readAttributes} method is used to read the
+ * file's attributes. The file {@link PosixFileAttributes#owner() owner} is
+ * represented by a {@link UserPrincipal} that is the identity of the file owner
+ * for the purposes of access control. The {@link PosixFileAttributes#group()
+ * group-owner}, represented by a {@link GroupPrincipal}, is the identity of the
+ * group owner, where a group is an identity created for administrative purposes
+ * so as to determine the access rights for the members of the group.
+ *
+ * <p> The {@link PosixFileAttributes#permissions() permissions} attribute is a
+ * set of access permissions. This file attribute view provides access to the nine
+ * permission defined by the {@link PosixFilePermission} class.
+ * These nine permission bits determine the <em>read</em>, <em>write</em>, and
+ * <em>execute</em> access for the file owner, group, and others (others
+ * meaning identities other than the owner and members of the group). Some
+ * operating systems and file systems may provide additional permission bits
+ * but access to these other bits is not defined by this class in this release.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we need to print out the owner and access permissions of a file:
+ * <pre>
+ * Path file = ...
+ * PosixFileAttributes attrs = Files.getFileAttributeView(file, PosixFileAttributeView.class)
+ * .readAttributes();
+ * System.out.format("%s %s%n",
+ * attrs.owner().getName(),
+ * PosixFilePermissions.toString(attrs.permissions()));
+ * </pre>
+ *
+ * <h2> Dynamic Access </h2>
+ * <p> Where dynamic access to file attributes is required, the attributes
+ * supported by this attribute view are as defined by {@link
+ * BasicFileAttributeView} and {@link FileOwnerAttributeView}, and in addition,
+ * the following attributes are supported:
+ * <blockquote>
+ * <table border="1" cellpadding="8" summary="Supported attributes">
+ * <tr>
+ * <th> Name </th>
+ * <th> Type </th>
+ * </tr>
+ * <tr>
+ * <td> "permissions" </td>
+ * <td> {@link Set}<{@link PosixFilePermission}> </td>
+ * </tr>
+ * <tr>
+ * <td> "group" </td>
+ * <td> {@link GroupPrincipal} </td>
+ * </tr>
+ * </table>
+ * </blockquote>
+ *
+ * <p> The {@link Files#getAttribute getAttribute} method may be used to read
+ * any of these attributes, or any of the attributes defined by {@link
+ * BasicFileAttributeView} as if by invoking the {@link #readAttributes
+ * readAttributes()} method.
+ *
+ * <p> The {@link Files#setAttribute setAttribute} method may be used to update
+ * the file's last modified time, last access time or create time attributes as
+ * defined by {@link BasicFileAttributeView}. It may also be used to update
+ * the permissions, owner, or group-owner as if by invoking the {@link
+ * #setPermissions setPermissions}, {@link #setOwner setOwner}, and {@link
+ * #setGroup setGroup} methods respectively.
+ *
+ * <h2> Setting Initial Permissions </h2>
+ * <p> Implementations supporting this attribute view may also support setting
+ * the initial permissions when creating a file or directory. The
+ * initial permissions are provided to the {@link Files#createFile createFile}
+ * or {@link Files#createDirectory createDirectory} methods as a {@link
+ * FileAttribute} with {@link FileAttribute#name name} {@code "posix:permissions"}
+ * and a {@link FileAttribute#value value} that is the set of permissions. The
+ * following example uses the {@link PosixFilePermissions#asFileAttribute
+ * asFileAttribute} method to construct a {@code FileAttribute} when creating a
+ * file:
+ *
+ * <pre>
+ * Path path = ...
+ * Set<PosixFilePermission> perms =
+ * EnumSet.of(OWNER_READ, OWNER_WRITE, OWNER_EXECUTE, GROUP_READ);
+ * Files.createFile(path, PosixFilePermissions.asFileAttribute(perms));
+ * </pre>
+ *
+ * <p> When the access permissions are set at file creation time then the actual
+ * value of the permissions may differ that the value of the attribute object.
+ * The reasons for this are implementation specific. On UNIX systems, for
+ * example, a process has a <em>umask</em> that impacts the permission bits
+ * of newly created files. Where an implementation supports the setting of
+ * the access permissions, and the underlying file system supports access
+ * permissions, then it is required that the value of the actual access
+ * permissions will be equal or less than the value of the attribute
+ * provided to the {@link Files#createFile createFile} or {@link
+ * Files#createDirectory createDirectory} methods. In other words, the file may
+ * be more secure than requested.
+ *
+ * @since 1.7
+ */
+
+public interface PosixFileAttributeView
+ extends BasicFileAttributeView, FileOwnerAttributeView
+{
+ /**
+ * Returns the name of the attribute view. Attribute views of this type
+ * have the name {@code "posix"}.
+ */
+ @Override
+ String name();
+
+ /**
+ * @throws IOException {@inheritDoc}
+ * @throws SecurityException
+ * In the case of the default provider, a security manager is
+ * installed, and it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+ * or its {@link SecurityManager#checkRead(String) checkRead} method
+ * denies read access to the file.
+ */
+ @Override
+ PosixFileAttributes readAttributes() throws IOException;
+
+ /**
+ * Updates the file permissions.
+ *
+ * @param perms
+ * the new set of permissions
+ *
+ * @throws ClassCastException
+ * if the sets contains elements that are not of type {@code
+ * PosixFilePermission}
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, a security manager is
+ * installed, and it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to the file.
+ */
+ void setPermissions(Set<PosixFilePermission> perms) throws IOException;
+
+ /**
+ * Updates the file group-owner.
+ *
+ * @param group
+ * the new file group-owner
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to the file.
+ */
+ void setGroup(GroupPrincipal group) throws IOException;
+}
diff --git a/java/nio/file/attribute/PosixFileAttributes.java b/java/nio/file/attribute/PosixFileAttributes.java
new file mode 100644
index 0000000..182c422
--- /dev/null
+++ b/java/nio/file/attribute/PosixFileAttributes.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.util.Set;
+
+/**
+ * File attributes associated with files on file systems used by operating systems
+ * that implement the Portable Operating System Interface (POSIX) family of
+ * standards.
+ *
+ * <p> The POSIX attributes of a file are retrieved using a {@link
+ * PosixFileAttributeView} by invoking its {@link
+ * PosixFileAttributeView#readAttributes readAttributes} method.
+ *
+ * @since 1.7
+ */
+
+public interface PosixFileAttributes
+ extends BasicFileAttributes
+{
+ /**
+ * Returns the owner of the file.
+ *
+ * @return the file owner
+ *
+ * @see PosixFileAttributeView#setOwner
+ */
+ UserPrincipal owner();
+
+ /**
+ * Returns the group owner of the file.
+ *
+ * @return the file group owner
+ *
+ * @see PosixFileAttributeView#setGroup
+ */
+ GroupPrincipal group();
+
+ /**
+ * Returns the permissions of the file. The file permissions are returned
+ * as a set of {@link PosixFilePermission} elements. The returned set is a
+ * copy of the file permissions and is modifiable. This allows the result
+ * to be modified and passed to the {@link PosixFileAttributeView#setPermissions
+ * setPermissions} method to update the file's permissions.
+ *
+ * @return the file permissions
+ *
+ * @see PosixFileAttributeView#setPermissions
+ */
+ Set<PosixFilePermission> permissions();
+}
diff --git a/java/nio/file/attribute/PosixFilePermission.java b/java/nio/file/attribute/PosixFilePermission.java
new file mode 100644
index 0000000..03e2209
--- /dev/null
+++ b/java/nio/file/attribute/PosixFilePermission.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file.attribute;
+
+/**
+ * Defines the bits for use with the {@link PosixFileAttributes#permissions()
+ * permissions} attribute.
+ *
+ * <p> The {@link PosixFilePermissions} class defines methods for manipulating
+ * set of permissions.
+ *
+ * @since 1.7
+ */
+
+public enum PosixFilePermission {
+
+ /**
+ * Read permission, owner.
+ */
+ OWNER_READ,
+
+ /**
+ * Write permission, owner.
+ */
+ OWNER_WRITE,
+
+ /**
+ * Execute/search permission, owner.
+ */
+ OWNER_EXECUTE,
+
+ /**
+ * Read permission, group.
+ */
+ GROUP_READ,
+
+ /**
+ * Write permission, group.
+ */
+ GROUP_WRITE,
+
+ /**
+ * Execute/search permission, group.
+ */
+ GROUP_EXECUTE,
+
+ /**
+ * Read permission, others.
+ */
+ OTHERS_READ,
+
+ /**
+ * Write permission, others.
+ */
+ OTHERS_WRITE,
+
+ /**
+ * Execute/search permission, others.
+ */
+ OTHERS_EXECUTE;
+}
diff --git a/java/nio/file/attribute/PosixFilePermissions.java b/java/nio/file/attribute/PosixFilePermissions.java
new file mode 100644
index 0000000..45a866a
--- /dev/null
+++ b/java/nio/file/attribute/PosixFilePermissions.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file.attribute;
+
+import static java.nio.file.attribute.PosixFilePermission.*;
+import java.util.*;
+
+/**
+ * This class consists exclusively of static methods that operate on sets of
+ * {@link PosixFilePermission} objects.
+ *
+ * @since 1.7
+ */
+
+public final class PosixFilePermissions {
+ private PosixFilePermissions() { }
+
+ // Write string representation of permission bits to {@code sb}.
+ private static void writeBits(StringBuilder sb, boolean r, boolean w, boolean x) {
+ if (r) {
+ sb.append('r');
+ } else {
+ sb.append('-');
+ }
+ if (w) {
+ sb.append('w');
+ } else {
+ sb.append('-');
+ }
+ if (x) {
+ sb.append('x');
+ } else {
+ sb.append('-');
+ }
+ }
+
+ /**
+ * Returns the {@code String} representation of a set of permissions. It
+ * is guaranteed that the returned {@code String} can be parsed by the
+ * {@link #fromString} method.
+ *
+ * <p> If the set contains {@code null} or elements that are not of type
+ * {@code PosixFilePermission} then these elements are ignored.
+ *
+ * @param perms
+ * the set of permissions
+ *
+ * @return the string representation of the permission set
+ */
+ public static String toString(Set<PosixFilePermission> perms) {
+ StringBuilder sb = new StringBuilder(9);
+ writeBits(sb, perms.contains(OWNER_READ), perms.contains(OWNER_WRITE),
+ perms.contains(OWNER_EXECUTE));
+ writeBits(sb, perms.contains(GROUP_READ), perms.contains(GROUP_WRITE),
+ perms.contains(GROUP_EXECUTE));
+ writeBits(sb, perms.contains(OTHERS_READ), perms.contains(OTHERS_WRITE),
+ perms.contains(OTHERS_EXECUTE));
+ return sb.toString();
+ }
+
+ private static boolean isSet(char c, char setValue) {
+ if (c == setValue)
+ return true;
+ if (c == '-')
+ return false;
+ throw new IllegalArgumentException("Invalid mode");
+ }
+ private static boolean isR(char c) { return isSet(c, 'r'); }
+ private static boolean isW(char c) { return isSet(c, 'w'); }
+ private static boolean isX(char c) { return isSet(c, 'x'); }
+
+ /**
+ * Returns the set of permissions corresponding to a given {@code String}
+ * representation.
+ *
+ * <p> The {@code perms} parameter is a {@code String} representing the
+ * permissions. It has 9 characters that are interpreted as three sets of
+ * three. The first set refers to the owner's permissions; the next to the
+ * group permissions and the last to others. Within each set, the first
+ * character is {@code 'r'} to indicate permission to read, the second
+ * character is {@code 'w'} to indicate permission to write, and the third
+ * character is {@code 'x'} for execute permission. Where a permission is
+ * not set then the corresponding character is set to {@code '-'}.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we require the set of permissions that indicate the owner has read,
+ * write, and execute permissions, the group has read and execute permissions
+ * and others have none.
+ * <pre>
+ * Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rwxr-x---");
+ * </pre>
+ *
+ * @param perms
+ * string representing a set of permissions
+ *
+ * @return the resulting set of permissions
+ *
+ * @throws IllegalArgumentException
+ * if the string cannot be converted to a set of permissions
+ *
+ * @see #toString(Set)
+ */
+ public static Set<PosixFilePermission> fromString(String perms) {
+ if (perms.length() != 9)
+ throw new IllegalArgumentException("Invalid mode");
+ Set<PosixFilePermission> result = EnumSet.noneOf(PosixFilePermission.class);
+ if (isR(perms.charAt(0))) result.add(OWNER_READ);
+ if (isW(perms.charAt(1))) result.add(OWNER_WRITE);
+ if (isX(perms.charAt(2))) result.add(OWNER_EXECUTE);
+ if (isR(perms.charAt(3))) result.add(GROUP_READ);
+ if (isW(perms.charAt(4))) result.add(GROUP_WRITE);
+ if (isX(perms.charAt(5))) result.add(GROUP_EXECUTE);
+ if (isR(perms.charAt(6))) result.add(OTHERS_READ);
+ if (isW(perms.charAt(7))) result.add(OTHERS_WRITE);
+ if (isX(perms.charAt(8))) result.add(OTHERS_EXECUTE);
+ return result;
+ }
+
+ /**
+ * Creates a {@link FileAttribute}, encapsulating a copy of the given file
+ * permissions, suitable for passing to the {@link java.nio.file.Files#createFile
+ * createFile} or {@link java.nio.file.Files#createDirectory createDirectory}
+ * methods.
+ *
+ * @param perms
+ * the set of permissions
+ *
+ * @return an attribute encapsulating the given file permissions with
+ * {@link FileAttribute#name name} {@code "posix:permissions"}
+ *
+ * @throws ClassCastException
+ * if the set contains elements that are not of type {@code
+ * PosixFilePermission}
+ */
+ public static FileAttribute<Set<PosixFilePermission>>
+ asFileAttribute(Set<PosixFilePermission> perms)
+ {
+ // copy set and check for nulls (CCE will be thrown if an element is not
+ // a PosixFilePermission)
+ perms = new HashSet<PosixFilePermission>(perms);
+ for (PosixFilePermission p: perms) {
+ if (p == null)
+ throw new NullPointerException();
+ }
+ final Set<PosixFilePermission> value = perms;
+ return new FileAttribute<Set<PosixFilePermission>>() {
+ @Override
+ public String name() {
+ return "posix:permissions";
+ }
+ @Override
+ public Set<PosixFilePermission> value() {
+ return Collections.unmodifiableSet(value);
+ }
+ };
+ }
+}
diff --git a/java/nio/file/attribute/UserDefinedFileAttributeView.java b/java/nio/file/attribute/UserDefinedFileAttributeView.java
new file mode 100644
index 0000000..56e7135
--- /dev/null
+++ b/java/nio/file/attribute/UserDefinedFileAttributeView.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.io.IOException;
+
+/**
+ * A file attribute view that provides a view of a file's user-defined
+ * attributes, sometimes known as <em>extended attributes</em>. User-defined
+ * file attributes are used to store metadata with a file that is not meaningful
+ * to the file system. It is primarily intended for file system implementations
+ * that support such a capability directly but may be emulated. The details of
+ * such emulation are highly implementation specific and therefore not specified.
+ *
+ * <p> This {@code FileAttributeView} provides a view of a file's user-defined
+ * attributes as a set of name/value pairs, where the attribute name is
+ * represented by a {@code String}. An implementation may require to encode and
+ * decode from the platform or file system representation when accessing the
+ * attribute. The value has opaque content. This attribute view defines the
+ * {@link #read read} and {@link #write write} methods to read the value into
+ * or write from a {@link ByteBuffer}. This {@code FileAttributeView} is not
+ * intended for use where the size of an attribute value is larger than {@link
+ * Integer#MAX_VALUE}.
+ *
+ * <p> User-defined attributes may be used in some implementations to store
+ * security related attributes so consequently, in the case of the default
+ * provider at least, all methods that access user-defined attributes require the
+ * {@code RuntimePermission("accessUserDefinedAttributes")} permission when a
+ * security manager is installed.
+ *
+ * <p> The {@link java.nio.file.FileStore#supportsFileAttributeView
+ * supportsFileAttributeView} method may be used to test if a specific {@link
+ * java.nio.file.FileStore FileStore} supports the storage of user-defined
+ * attributes.
+ *
+ * <p> Where dynamic access to file attributes is required, the {@link
+ * java.nio.file.Files#getAttribute getAttribute} method may be used to read
+ * the attribute value. The attribute value is returned as a byte array (byte[]).
+ * The {@link java.nio.file.Files#setAttribute setAttribute} method may be used
+ * to write the value of a user-defined attribute from a buffer (as if by
+ * invoking the {@link #write write} method), or byte array (byte[]).
+ *
+ * @since 1.7
+ */
+
+public interface UserDefinedFileAttributeView
+ extends FileAttributeView
+{
+ /**
+ * Returns the name of this attribute view. Attribute views of this type
+ * have the name {@code "user"}.
+ */
+ @Override
+ String name();
+
+ /**
+ * Returns a list containing the names of the user-defined attributes.
+ *
+ * @return An unmodifiable list containing the names of the file's
+ * user-defined
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, a security manager is
+ * installed, and it denies {@link
+ * RuntimePermission}<tt>("accessUserDefinedAttributes")</tt>
+ * or its {@link SecurityManager#checkRead(String) checkRead} method
+ * denies read access to the file.
+ */
+ List<String> list() throws IOException;
+
+ /**
+ * Returns the size of the value of a user-defined attribute.
+ *
+ * @param name
+ * The attribute name
+ *
+ * @return The size of the attribute value, in bytes.
+ *
+ * @throws ArithmeticException
+ * If the size of the attribute is larger than {@link Integer#MAX_VALUE}
+ * @throws IOException
+ * If an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, a security manager is
+ * installed, and it denies {@link
+ * RuntimePermission}<tt>("accessUserDefinedAttributes")</tt>
+ * or its {@link SecurityManager#checkRead(String) checkRead} method
+ * denies read access to the file.
+ */
+ int size(String name) throws IOException;
+
+ /**
+ * Read the value of a user-defined attribute into a buffer.
+ *
+ * <p> This method reads the value of the attribute into the given buffer
+ * as a sequence of bytes, failing if the number of bytes remaining in
+ * the buffer is insufficient to read the complete attribute value. The
+ * number of bytes transferred into the buffer is {@code n}, where {@code n}
+ * is the size of the attribute value. The first byte in the sequence is at
+ * index {@code p} and the last byte is at index {@code p + n - 1}, where
+ * {@code p} is the buffer's position. Upon return the buffer's position
+ * will be equal to {@code p + n}; its limit will not have changed.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to read a file's MIME type that is stored as a user-defined
+ * attribute with the name "{@code user.mimetype}".
+ * <pre>
+ * UserDefinedFileAttributeView view =
+ * Files.getFileAttributeView(path, UserDefinedFileAttributeView.class);
+ * String name = "user.mimetype";
+ * ByteBuffer buf = ByteBuffer.allocate(view.size(name));
+ * view.read(name, buf);
+ * buf.flip();
+ * String value = Charset.defaultCharset().decode(buf).toString();
+ * </pre>
+ *
+ * @param name
+ * The attribute name
+ * @param dst
+ * The destination buffer
+ *
+ * @return The number of bytes read, possibly zero
+ *
+ * @throws IllegalArgumentException
+ * If the destination buffer is read-only
+ * @throws IOException
+ * If an I/O error occurs or there is insufficient space in the
+ * destination buffer for the attribute value
+ * @throws SecurityException
+ * In the case of the default provider, a security manager is
+ * installed, and it denies {@link
+ * RuntimePermission}<tt>("accessUserDefinedAttributes")</tt>
+ * or its {@link SecurityManager#checkRead(String) checkRead} method
+ * denies read access to the file.
+ *
+ * @see #size
+ */
+ int read(String name, ByteBuffer dst) throws IOException;
+
+ /**
+ * Writes the value of a user-defined attribute from a buffer.
+ *
+ * <p> This method writes the value of the attribute from a given buffer as
+ * a sequence of bytes. The size of the value to transfer is {@code r},
+ * where {@code r} is the number of bytes remaining in the buffer, that is
+ * {@code src.remaining()}. The sequence of bytes is transferred from the
+ * buffer starting at index {@code p}, where {@code p} is the buffer's
+ * position. Upon return, the buffer's position will be equal to {@code
+ * p + n}, where {@code n} is the number of bytes transferred; its limit
+ * will not have changed.
+ *
+ * <p> If an attribute of the given name already exists then its value is
+ * replaced. If the attribute does not exist then it is created. If it
+ * implementation specific if a test to check for the existence of the
+ * attribute and the creation of attribute are atomic with respect to other
+ * file system activities.
+ *
+ * <p> Where there is insufficient space to store the attribute, or the
+ * attribute name or value exceed an implementation specific maximum size
+ * then an {@code IOException} is thrown.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we want to write a file's MIME type as a user-defined attribute:
+ * <pre>
+ * UserDefinedFileAttributeView view =
+ * FIles.getFileAttributeView(path, UserDefinedFileAttributeView.class);
+ * view.write("user.mimetype", Charset.defaultCharset().encode("text/html"));
+ * </pre>
+ *
+ * @param name
+ * The attribute name
+ * @param src
+ * The buffer containing the attribute value
+ *
+ * @return The number of bytes written, possibly zero
+ *
+ * @throws IOException
+ * If an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, a security manager is
+ * installed, and it denies {@link
+ * RuntimePermission}<tt>("accessUserDefinedAttributes")</tt>
+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to the file.
+ */
+ int write(String name, ByteBuffer src) throws IOException;
+
+ /**
+ * Deletes a user-defined attribute.
+ *
+ * @param name
+ * The attribute name
+ *
+ * @throws IOException
+ * If an I/O error occurs or the attribute does not exist
+ * @throws SecurityException
+ * In the case of the default provider, a security manager is
+ * installed, and it denies {@link
+ * RuntimePermission}<tt>("accessUserDefinedAttributes")</tt>
+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to the file.
+ */
+ void delete(String name) throws IOException;
+}
diff --git a/java/nio/file/attribute/UserPrincipal.java b/java/nio/file/attribute/UserPrincipal.java
new file mode 100644
index 0000000..01b26bb
--- /dev/null
+++ b/java/nio/file/attribute/UserPrincipal.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.security.Principal;
+
+/**
+ * A {@code Principal} representing an identity used to determine access rights
+ * to objects in a file system.
+ *
+ * <p> On many platforms and file systems an entity requires appropriate access
+ * rights or permissions in order to access objects in a file system. The
+ * access rights are generally performed by checking the identity of the entity.
+ * For example, on implementations that use Access Control Lists (ACLs) to
+ * enforce privilege separation then a file in the file system may have an
+ * associated ACL that determines the access rights of identities specified in
+ * the ACL.
+ *
+ * <p> A {@code UserPrincipal} object is an abstract representation of an
+ * identity. It has a {@link #getName() name} that is typically the username or
+ * account name that it represents. User principal objects may be obtained using
+ * a {@link UserPrincipalLookupService}, or returned by {@link
+ * FileAttributeView} implementations that provide access to identity related
+ * attributes. For example, the {@link AclFileAttributeView} and {@link
+ * PosixFileAttributeView} provide access to a file's {@link
+ * PosixFileAttributes#owner owner}.
+ *
+ * @since 1.7
+ */
+
+public interface UserPrincipal extends Principal { }
diff --git a/java/nio/file/attribute/UserPrincipalLookupService.java b/java/nio/file/attribute/UserPrincipalLookupService.java
new file mode 100644
index 0000000..c3f3bef
--- /dev/null
+++ b/java/nio/file/attribute/UserPrincipalLookupService.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.io.IOException;
+
+/**
+ * An object to lookup user and group principals by name. A {@link UserPrincipal}
+ * represents an identity that may be used to determine access rights to objects
+ * in a file system. A {@link GroupPrincipal} represents a <em>group identity</em>.
+ * A {@code UserPrincipalLookupService} defines methods to lookup identities by
+ * name or group name (which are typically user or account names). Whether names
+ * and group names are case sensitive or not depends on the implementation.
+ * The exact definition of a group is implementation specific but typically a
+ * group represents an identity created for administrative purposes so as to
+ * determine the access rights for the members of the group. In particular it is
+ * implementation specific if the <em>namespace</em> for names and groups is the
+ * same or is distinct. To ensure consistent and correct behavior across
+ * platforms it is recommended that this API be used as if the namespaces are
+ * distinct. In other words, the {@link #lookupPrincipalByName
+ * lookupPrincipalByName} should be used to lookup users, and {@link
+ * #lookupPrincipalByGroupName lookupPrincipalByGroupName} should be used to
+ * lookup groups.
+ *
+ * @since 1.7
+ *
+ * @see java.nio.file.FileSystem#getUserPrincipalLookupService
+ */
+
+public abstract class UserPrincipalLookupService {
+
+ /**
+ * Initializes a new instance of this class.
+ */
+ protected UserPrincipalLookupService() {
+ }
+
+ /**
+ * Lookup a user principal by name.
+ *
+ * @param name
+ * the string representation of the user principal to lookup
+ *
+ * @return a user principal
+ *
+ * @throws UserPrincipalNotFoundException
+ * the principal does not exist
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, it checks {@link RuntimePermission}<tt>("lookupUserInformation")</tt>
+ */
+ public abstract UserPrincipal lookupPrincipalByName(String name)
+ throws IOException;
+
+ /**
+ * Lookup a group principal by group name.
+ *
+ * <p> Where an implementation does not support any notion of group then
+ * this method always throws {@link UserPrincipalNotFoundException}. Where
+ * the namespace for user accounts and groups is the same, then this method
+ * is identical to invoking {@link #lookupPrincipalByName
+ * lookupPrincipalByName}.
+ *
+ * @param group
+ * the string representation of the group to lookup
+ *
+ * @return a group principal
+ *
+ * @throws UserPrincipalNotFoundException
+ * the principal does not exist or is not a group
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, it checks {@link RuntimePermission}<tt>("lookupUserInformation")</tt>
+ */
+ public abstract GroupPrincipal lookupPrincipalByGroupName(String group)
+ throws IOException;
+}
diff --git a/java/nio/file/attribute/UserPrincipalNotFoundException.java b/java/nio/file/attribute/UserPrincipalNotFoundException.java
new file mode 100644
index 0000000..5cf0ab0
--- /dev/null
+++ b/java/nio/file/attribute/UserPrincipalNotFoundException.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file.attribute;
+
+import java.io.IOException;
+
+/**
+ * Checked exception thrown when a lookup of {@link UserPrincipal} fails because
+ * the principal does not exist.
+ *
+ * @since 1.7
+ */
+
+public class UserPrincipalNotFoundException
+ extends IOException
+{
+ static final long serialVersionUID = -5369283889045833024L;
+
+ private final String name;
+
+ /**
+ * Constructs an instance of this class.
+ *
+ * @param name
+ * the principal name; may be {@code null}
+ */
+ public UserPrincipalNotFoundException(String name) {
+ super();
+ this.name = name;
+ }
+
+ /**
+ * Returns the user principal name if this exception was created with the
+ * user principal name that was not found, otherwise <tt>null</tt>.
+ *
+ * @return the user principal name or {@code null}
+ */
+ public String getName() {
+ return name;
+ }
+}
diff --git a/java/nio/file/spi/FileSystemProvider.java b/java/nio/file/spi/FileSystemProvider.java
new file mode 100644
index 0000000..bed8416
--- /dev/null
+++ b/java/nio/file/spi/FileSystemProvider.java
@@ -0,0 +1,1103 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file.spi;
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.nio.channels.*;
+import java.net.URI;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.ExecutorService;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Service-provider class for file systems. The methods defined by the {@link
+ * java.nio.file.Files} class will typically delegate to an instance of this
+ * class.
+ *
+ * <p> A file system provider is a concrete implementation of this class that
+ * implements the abstract methods defined by this class. A provider is
+ * identified by a {@code URI} {@link #getScheme() scheme}. The default provider
+ * is identified by the URI scheme "file". It creates the {@link FileSystem} that
+ * provides access to the file systems accessible to the Java virtual machine.
+ * The {@link FileSystems} class defines how file system providers are located
+ * and loaded. The default provider is typically a system-default provider but
+ * may be overridden if the system property {@code
+ * java.nio.file.spi.DefaultFileSystemProvider} is set. In that case, the
+ * provider has a one argument constructor whose formal parameter type is {@code
+ * FileSystemProvider}. All other providers have a zero argument constructor
+ * that initializes the provider.
+ *
+ * <p> A provider is a factory for one or more {@link FileSystem} instances. Each
+ * file system is identified by a {@code URI} where the URI's scheme matches
+ * the provider's {@link #getScheme scheme}. The default file system, for example,
+ * is identified by the URI {@code "file:///"}. A memory-based file system,
+ * for example, may be identified by a URI such as {@code "memory:///?name=logfs"}.
+ * The {@link #newFileSystem newFileSystem} method may be used to create a file
+ * system, and the {@link #getFileSystem getFileSystem} method may be used to
+ * obtain a reference to an existing file system created by the provider. Where
+ * a provider is the factory for a single file system then it is provider dependent
+ * if the file system is created when the provider is initialized, or later when
+ * the {@code newFileSystem} method is invoked. In the case of the default
+ * provider, the {@code FileSystem} is created when the provider is initialized.
+ *
+ * <p> All of the methods in this class are safe for use by multiple concurrent
+ * threads.
+ *
+ * @since 1.7
+ */
+
+public abstract class FileSystemProvider {
+ // lock using when loading providers
+ private static final Object lock = new Object();
+
+ // installed providers
+ private static volatile List<FileSystemProvider> installedProviders;
+
+ // used to avoid recursive loading of instaled providers
+ private static boolean loadingProviders = false;
+
+ private static Void checkPermission() {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("fileSystemProvider"));
+ return null;
+ }
+ private FileSystemProvider(Void ignore) { }
+
+ /**
+ * Initializes a new instance of this class.
+ *
+ * <p> During construction a provider may safely access files associated
+ * with the default provider but care needs to be taken to avoid circular
+ * loading of other installed providers. If circular loading of installed
+ * providers is detected then an unspecified error is thrown.
+ *
+ * @throws SecurityException
+ * If a security manager has been installed and it denies
+ * {@link RuntimePermission}<tt>("fileSystemProvider")</tt>
+ */
+ protected FileSystemProvider() {
+ this(checkPermission());
+ }
+
+ // loads all installed providers
+ private static List<FileSystemProvider> loadInstalledProviders() {
+ List<FileSystemProvider> list = new ArrayList<FileSystemProvider>();
+
+ ServiceLoader<FileSystemProvider> sl = ServiceLoader
+ .load(FileSystemProvider.class, ClassLoader.getSystemClassLoader());
+
+ // ServiceConfigurationError may be throw here
+ for (FileSystemProvider provider: sl) {
+ String scheme = provider.getScheme();
+
+ // add to list if the provider is not "file" and isn't a duplicate
+ if (!scheme.equalsIgnoreCase("file")) {
+ boolean found = false;
+ for (FileSystemProvider p: list) {
+ if (p.getScheme().equalsIgnoreCase(scheme)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ list.add(provider);
+ }
+ }
+ }
+ return list;
+ }
+
+ /**
+ * Returns a list of the installed file system providers.
+ *
+ * <p> The first invocation of this method causes the default provider to be
+ * initialized (if not already initialized) and loads any other installed
+ * providers as described by the {@link FileSystems} class.
+ *
+ * @return An unmodifiable list of the installed file system providers. The
+ * list contains at least one element, that is the default file
+ * system provider
+ *
+ * @throws ServiceConfigurationError
+ * When an error occurs while loading a service provider
+ */
+ public static List<FileSystemProvider> installedProviders() {
+ if (installedProviders == null) {
+ // ensure default provider is initialized
+ FileSystemProvider defaultProvider = FileSystems.getDefault().provider();
+
+ synchronized (lock) {
+ if (installedProviders == null) {
+ if (loadingProviders) {
+ throw new Error("Circular loading of installed providers detected");
+ }
+ loadingProviders = true;
+
+ List<FileSystemProvider> list = AccessController
+ .doPrivileged(new PrivilegedAction<List<FileSystemProvider>>() {
+ @Override
+ public List<FileSystemProvider> run() {
+ return loadInstalledProviders();
+ }});
+
+ // insert the default provider at the start of the list
+ list.add(0, defaultProvider);
+
+ installedProviders = Collections.unmodifiableList(list);
+ }
+ }
+ }
+ return installedProviders;
+ }
+
+ /**
+ * Returns the URI scheme that identifies this provider.
+ *
+ * @return The URI scheme
+ */
+ public abstract String getScheme();
+
+ /**
+ * Constructs a new {@code FileSystem} object identified by a URI. This
+ * method is invoked by the {@link FileSystems#newFileSystem(URI,Map)}
+ * method to open a new file system identified by a URI.
+ *
+ * <p> The {@code uri} parameter is an absolute, hierarchical URI, with a
+ * scheme equal (without regard to case) to the scheme supported by this
+ * provider. The exact form of the URI is highly provider dependent. The
+ * {@code env} parameter is a map of provider specific properties to configure
+ * the file system.
+ *
+ * <p> This method throws {@link FileSystemAlreadyExistsException} if the
+ * file system already exists because it was previously created by an
+ * invocation of this method. Once a file system is {@link
+ * java.nio.file.FileSystem#close closed} it is provider-dependent if the
+ * provider allows a new file system to be created with the same URI as a
+ * file system it previously created.
+ *
+ * @param uri
+ * URI reference
+ * @param env
+ * A map of provider specific properties to configure the file system;
+ * may be empty
+ *
+ * @return A new file system
+ *
+ * @throws IllegalArgumentException
+ * If the pre-conditions for the {@code uri} parameter aren't met,
+ * or the {@code env} parameter does not contain properties required
+ * by the provider, or a property value is invalid
+ * @throws IOException
+ * An I/O error occurs creating the file system
+ * @throws SecurityException
+ * If a security manager is installed and it denies an unspecified
+ * permission required by the file system provider implementation
+ * @throws FileSystemAlreadyExistsException
+ * If the file system has already been created
+ */
+ public abstract FileSystem newFileSystem(URI uri, Map<String,?> env)
+ throws IOException;
+
+ /**
+ * Returns an existing {@code FileSystem} created by this provider.
+ *
+ * <p> This method returns a reference to a {@code FileSystem} that was
+ * created by invoking the {@link #newFileSystem(URI,Map) newFileSystem(URI,Map)}
+ * method. File systems created the {@link #newFileSystem(Path,Map)
+ * newFileSystem(Path,Map)} method are not returned by this method.
+ * The file system is identified by its {@code URI}. Its exact form
+ * is highly provider dependent. In the case of the default provider the URI's
+ * path component is {@code "/"} and the authority, query and fragment components
+ * are undefined (Undefined components are represented by {@code null}).
+ *
+ * <p> Once a file system created by this provider is {@link
+ * java.nio.file.FileSystem#close closed} it is provider-dependent if this
+ * method returns a reference to the closed file system or throws {@link
+ * FileSystemNotFoundException}. If the provider allows a new file system to
+ * be created with the same URI as a file system it previously created then
+ * this method throws the exception if invoked after the file system is
+ * closed (and before a new instance is created by the {@link #newFileSystem
+ * newFileSystem} method).
+ *
+ * <p> If a security manager is installed then a provider implementation
+ * may require to check a permission before returning a reference to an
+ * existing file system. In the case of the {@link FileSystems#getDefault
+ * default} file system, no permission check is required.
+ *
+ * @param uri
+ * URI reference
+ *
+ * @return The file system
+ *
+ * @throws IllegalArgumentException
+ * If the pre-conditions for the {@code uri} parameter aren't met
+ * @throws FileSystemNotFoundException
+ * If the file system does not exist
+ * @throws SecurityException
+ * If a security manager is installed and it denies an unspecified
+ * permission.
+ */
+ public abstract FileSystem getFileSystem(URI uri);
+
+ /**
+ * Return a {@code Path} object by converting the given {@link URI}. The
+ * resulting {@code Path} is associated with a {@link FileSystem} that
+ * already exists or is constructed automatically.
+ *
+ * <p> The exact form of the URI is file system provider dependent. In the
+ * case of the default provider, the URI scheme is {@code "file"} and the
+ * given URI has a non-empty path component, and undefined query, and
+ * fragment components. The resulting {@code Path} is associated with the
+ * default {@link FileSystems#getDefault default} {@code FileSystem}.
+ *
+ * <p> If a security manager is installed then a provider implementation
+ * may require to check a permission. In the case of the {@link
+ * FileSystems#getDefault default} file system, no permission check is
+ * required.
+ *
+ * @param uri
+ * The URI to convert
+ *
+ * @return The resulting {@code Path}
+ *
+ * @throws IllegalArgumentException
+ * If the URI scheme does not identify this provider or other
+ * preconditions on the uri parameter do not hold
+ * @throws FileSystemNotFoundException
+ * The file system, identified by the URI, does not exist and
+ * cannot be created automatically
+ * @throws SecurityException
+ * If a security manager is installed and it denies an unspecified
+ * permission.
+ */
+ public abstract Path getPath(URI uri);
+
+ /**
+ * Constructs a new {@code FileSystem} to access the contents of a file as a
+ * file system.
+ *
+ * <p> This method is intended for specialized providers of pseudo file
+ * systems where the contents of one or more files is treated as a file
+ * system. The {@code env} parameter is a map of provider specific properties
+ * to configure the file system.
+ *
+ * <p> If this provider does not support the creation of such file systems
+ * or if the provider does not recognize the file type of the given file then
+ * it throws {@code UnsupportedOperationException}. The default implementation
+ * of this method throws {@code UnsupportedOperationException}.
+ *
+ * @param path
+ * The path to the file
+ * @param env
+ * A map of provider specific properties to configure the file system;
+ * may be empty
+ *
+ * @return A new file system
+ *
+ * @throws UnsupportedOperationException
+ * If this provider does not support access to the contents as a
+ * file system or it does not recognize the file type of the
+ * given file
+ * @throws IllegalArgumentException
+ * If the {@code env} parameter does not contain properties required
+ * by the provider, or a property value is invalid
+ * @throws IOException
+ * If an I/O error occurs
+ * @throws SecurityException
+ * If a security manager is installed and it denies an unspecified
+ * permission.
+ */
+ public FileSystem newFileSystem(Path path, Map<String,?> env)
+ throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Opens a file, returning an input stream to read from the file. This
+ * method works in exactly the manner specified by the {@link
+ * Files#newInputStream} method.
+ *
+ * <p> The default implementation of this method opens a channel to the file
+ * as if by invoking the {@link #newByteChannel} method and constructs a
+ * stream that reads bytes from the channel. This method should be overridden
+ * where appropriate.
+ *
+ * @param path
+ * the path to the file to open
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return a new input stream
+ *
+ * @throws IllegalArgumentException
+ * if an invalid combination of options is specified
+ * @throws UnsupportedOperationException
+ * if an unsupported option is specified
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file.
+ */
+ public InputStream newInputStream(Path path, OpenOption... options)
+ throws IOException
+ {
+ if (options.length > 0) {
+ for (OpenOption opt: options) {
+ // All OpenOption values except for APPEND and WRITE are allowed
+ if (opt == StandardOpenOption.APPEND ||
+ opt == StandardOpenOption.WRITE)
+ throw new UnsupportedOperationException("'" + opt + "' not allowed");
+ }
+ }
+ return Channels.newInputStream(Files.newByteChannel(path, options));
+ }
+
+ /**
+ * Opens or creates a file, returning an output stream that may be used to
+ * write bytes to the file. This method works in exactly the manner
+ * specified by the {@link Files#newOutputStream} method.
+ *
+ * <p> The default implementation of this method opens a channel to the file
+ * as if by invoking the {@link #newByteChannel} method and constructs a
+ * stream that writes bytes to the channel. This method should be overridden
+ * where appropriate.
+ *
+ * @param path
+ * the path to the file to open or create
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return a new output stream
+ *
+ * @throws IllegalArgumentException
+ * if {@code options} contains an invalid combination of options
+ * @throws UnsupportedOperationException
+ * if an unsupported option is specified
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to the file. The {@link
+ * SecurityManager#checkDelete(String) checkDelete} method is
+ * invoked to check delete access if the file is opened with the
+ * {@code DELETE_ON_CLOSE} option.
+ */
+ public OutputStream newOutputStream(Path path, OpenOption... options)
+ throws IOException
+ {
+ int len = options.length;
+ Set<OpenOption> opts = new HashSet<OpenOption>(len + 3);
+ if (len == 0) {
+ opts.add(StandardOpenOption.CREATE);
+ opts.add(StandardOpenOption.TRUNCATE_EXISTING);
+ } else {
+ for (OpenOption opt: options) {
+ if (opt == StandardOpenOption.READ)
+ throw new IllegalArgumentException("READ not allowed");
+ opts.add(opt);
+ }
+ }
+ opts.add(StandardOpenOption.WRITE);
+ return Channels.newOutputStream(newByteChannel(path, opts));
+ }
+
+ /**
+ * Opens or creates a file for reading and/or writing, returning a file
+ * channel to access the file. This method works in exactly the manner
+ * specified by the {@link FileChannel#open(Path,Set,FileAttribute[])
+ * FileChannel.open} method. A provider that does not support all the
+ * features required to construct a file channel throws {@code
+ * UnsupportedOperationException}. The default provider is required to
+ * support the creation of file channels. When not overridden, the default
+ * implementation throws {@code UnsupportedOperationException}.
+ *
+ * @param path
+ * the path of the file to open or create
+ * @param options
+ * options specifying how the file is opened
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the file
+ *
+ * @return a new file channel
+ *
+ * @throws IllegalArgumentException
+ * If the set contains an invalid combination of options
+ * @throws UnsupportedOperationException
+ * If this provider that does not support creating file channels,
+ * or an unsupported open option or file attribute is specified
+ * @throws IOException
+ * If an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default file system, the {@link
+ * SecurityManager#checkRead(String)} method is invoked to check
+ * read access if the file is opened for reading. The {@link
+ * SecurityManager#checkWrite(String)} method is invoked to check
+ * write access if the file is opened for writing
+ */
+ public FileChannel newFileChannel(Path path,
+ Set<? extends OpenOption> options,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Opens or creates a file for reading and/or writing, returning an
+ * asynchronous file channel to access the file. This method works in
+ * exactly the manner specified by the {@link
+ * AsynchronousFileChannel#open(Path,Set,ExecutorService,FileAttribute[])
+ * AsynchronousFileChannel.open} method.
+ * A provider that does not support all the features required to construct
+ * an asynchronous file channel throws {@code UnsupportedOperationException}.
+ * The default provider is required to support the creation of asynchronous
+ * file channels. When not overridden, the default implementation of this
+ * method throws {@code UnsupportedOperationException}.
+ *
+ * @param path
+ * the path of the file to open or create
+ * @param options
+ * options specifying how the file is opened
+ * @param executor
+ * the thread pool or {@code null} to associate the channel with
+ * the default thread pool
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the file
+ *
+ * @return a new asynchronous file channel
+ *
+ * @throws IllegalArgumentException
+ * If the set contains an invalid combination of options
+ * @throws UnsupportedOperationException
+ * If this provider that does not support creating asynchronous file
+ * channels, or an unsupported open option or file attribute is
+ * specified
+ * @throws IOException
+ * If an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default file system, the {@link
+ * SecurityManager#checkRead(String)} method is invoked to check
+ * read access if the file is opened for reading. The {@link
+ * SecurityManager#checkWrite(String)} method is invoked to check
+ * write access if the file is opened for writing
+ */
+ public AsynchronousFileChannel newAsynchronousFileChannel(Path path,
+ Set<? extends OpenOption> options,
+ ExecutorService executor,
+ FileAttribute<?>... attrs)
+ throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Opens or creates a file, returning a seekable byte channel to access the
+ * file. This method works in exactly the manner specified by the {@link
+ * Files#newByteChannel(Path,Set,FileAttribute[])} method.
+ *
+ * @param path
+ * the path to the file to open or create
+ * @param options
+ * options specifying how the file is opened
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the file
+ *
+ * @return a new seekable byte channel
+ *
+ * @throws IllegalArgumentException
+ * if the set contains an invalid combination of options
+ * @throws UnsupportedOperationException
+ * if an unsupported open option is specified or the array contains
+ * attributes that cannot be set atomically when creating the file
+ * @throws FileAlreadyExistsException
+ * if a file of that name already exists and the {@link
+ * StandardOpenOption#CREATE_NEW CREATE_NEW} option is specified
+ * <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the path if the file is
+ * opened for reading. The {@link SecurityManager#checkWrite(String)
+ * checkWrite} method is invoked to check write access to the path
+ * if the file is opened for writing. The {@link
+ * SecurityManager#checkDelete(String) checkDelete} method is
+ * invoked to check delete access if the file is opened with the
+ * {@code DELETE_ON_CLOSE} option.
+ */
+ public abstract SeekableByteChannel newByteChannel(Path path,
+ Set<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException;
+
+ /**
+ * Opens a directory, returning a {@code DirectoryStream} to iterate over
+ * the entries in the directory. This method works in exactly the manner
+ * specified by the {@link
+ * Files#newDirectoryStream(java.nio.file.Path, java.nio.file.DirectoryStream.Filter)}
+ * method.
+ *
+ * @param dir
+ * the path to the directory
+ * @param filter
+ * the directory stream filter
+ *
+ * @return a new and open {@code DirectoryStream} object
+ *
+ * @throws NotDirectoryException
+ * if the file could not otherwise be opened because it is not
+ * a directory <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the directory.
+ */
+ public abstract DirectoryStream<Path> newDirectoryStream(Path dir,
+ DirectoryStream.Filter<? super Path> filter) throws IOException;
+
+ /**
+ * Creates a new directory. This method works in exactly the manner
+ * specified by the {@link Files#createDirectory} method.
+ *
+ * @param dir
+ * the directory to create
+ * @param attrs
+ * an optional list of file attributes to set atomically when
+ * creating the directory
+ *
+ * @throws UnsupportedOperationException
+ * if the array contains an attribute that cannot be set atomically
+ * when creating the directory
+ * @throws FileAlreadyExistsException
+ * if a directory could not otherwise be created because a file of
+ * that name already exists <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs or the parent directory does not exist
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to the new directory.
+ */
+ public abstract void createDirectory(Path dir, FileAttribute<?>... attrs)
+ throws IOException;
+
+ /**
+ * Creates a symbolic link to a target. This method works in exactly the
+ * manner specified by the {@link Files#createSymbolicLink} method.
+ *
+ * <p> The default implementation of this method throws {@code
+ * UnsupportedOperationException}.
+ *
+ * @param link
+ * the path of the symbolic link to create
+ * @param target
+ * the target of the symbolic link
+ * @param attrs
+ * the array of attributes to set atomically when creating the
+ * symbolic link
+ *
+ * @throws UnsupportedOperationException
+ * if the implementation does not support symbolic links or the
+ * array contains an attribute that cannot be set atomically when
+ * creating the symbolic link
+ * @throws FileAlreadyExistsException
+ * if a file with the name already exists <i>(optional specific
+ * exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager
+ * is installed, it denies {@link LinkPermission}<tt>("symbolic")</tt>
+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to the path of the symbolic link.
+ */
+ public void createSymbolicLink(Path link, Path target, FileAttribute<?>... attrs)
+ throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Creates a new link (directory entry) for an existing file. This method
+ * works in exactly the manner specified by the {@link Files#createLink}
+ * method.
+ *
+ * <p> The default implementation of this method throws {@code
+ * UnsupportedOperationException}.
+ *
+ * @param link
+ * the link (directory entry) to create
+ * @param existing
+ * a path to an existing file
+ *
+ * @throws UnsupportedOperationException
+ * if the implementation does not support adding an existing file
+ * to a directory
+ * @throws FileAlreadyExistsException
+ * if the entry could not otherwise be created because a file of
+ * that name already exists <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager
+ * is installed, it denies {@link LinkPermission}<tt>("hard")</tt>
+ * or its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to either the link or the
+ * existing file.
+ */
+ public void createLink(Path link, Path existing) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Deletes a file. This method works in exactly the manner specified by the
+ * {@link Files#delete} method.
+ *
+ * @param path
+ * the path to the file to delete
+ *
+ * @throws NoSuchFileException
+ * if the file does not exist <i>(optional specific exception)</i>
+ * @throws DirectoryNotEmptyException
+ * if the file is a directory and could not otherwise be deleted
+ * because the directory is not empty <i>(optional specific
+ * exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkDelete(String)} method
+ * is invoked to check delete access to the file
+ */
+ public abstract void delete(Path path) throws IOException;
+
+ /**
+ * Deletes a file if it exists. This method works in exactly the manner
+ * specified by the {@link Files#deleteIfExists} method.
+ *
+ * <p> The default implementation of this method simply invokes {@link
+ * #delete} ignoring the {@code NoSuchFileException} when the file does not
+ * exist. It may be overridden where appropriate.
+ *
+ * @param path
+ * the path to the file to delete
+ *
+ * @return {@code true} if the file was deleted by this method; {@code
+ * false} if the file could not be deleted because it did not
+ * exist
+ *
+ * @throws DirectoryNotEmptyException
+ * if the file is a directory and could not otherwise be deleted
+ * because the directory is not empty <i>(optional specific
+ * exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkDelete(String)} method
+ * is invoked to check delete access to the file
+ */
+ public boolean deleteIfExists(Path path) throws IOException {
+ try {
+ delete(path);
+ return true;
+ } catch (NoSuchFileException ignore) {
+ return false;
+ }
+ }
+
+ /**
+ * Reads the target of a symbolic link. This method works in exactly the
+ * manner specified by the {@link Files#readSymbolicLink} method.
+ *
+ * <p> The default implementation of this method throws {@code
+ * UnsupportedOperationException}.
+ *
+ * @param link
+ * the path to the symbolic link
+ *
+ * @return The target of the symbolic link
+ *
+ * @throws UnsupportedOperationException
+ * if the implementation does not support symbolic links
+ * @throws NotLinkException
+ * if the target could otherwise not be read because the file
+ * is not a symbolic link <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager
+ * is installed, it checks that {@code FilePermission} has been
+ * granted with the "{@code readlink}" action to read the link.
+ */
+ public Path readSymbolicLink(Path link) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Copy a file to a target file. This method works in exactly the manner
+ * specified by the {@link Files#copy(Path,Path,CopyOption[])} method
+ * except that both the source and target paths must be associated with
+ * this provider.
+ *
+ * @param source
+ * the path to the file to copy
+ * @param target
+ * the path to the target file
+ * @param options
+ * options specifying how the copy should be done
+ *
+ * @throws UnsupportedOperationException
+ * if the array contains a copy option that is not supported
+ * @throws FileAlreadyExistsException
+ * if the target file exists but cannot be replaced because the
+ * {@code REPLACE_EXISTING} option is not specified <i>(optional
+ * specific exception)</i>
+ * @throws DirectoryNotEmptyException
+ * the {@code REPLACE_EXISTING} option is specified but the file
+ * cannot be replaced because it is a non-empty directory
+ * <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the source file, the
+ * {@link SecurityManager#checkWrite(String) checkWrite} is invoked
+ * to check write access to the target file. If a symbolic link is
+ * copied the security manager is invoked to check {@link
+ * LinkPermission}{@code ("symbolic")}.
+ */
+ public abstract void copy(Path source, Path target, CopyOption... options)
+ throws IOException;
+
+ /**
+ * Move or rename a file to a target file. This method works in exactly the
+ * manner specified by the {@link Files#move} method except that both the
+ * source and target paths must be associated with this provider.
+ *
+ * @param source
+ * the path to the file to move
+ * @param target
+ * the path to the target file
+ * @param options
+ * options specifying how the move should be done
+ *
+ * @throws UnsupportedOperationException
+ * if the array contains a copy option that is not supported
+ * @throws FileAlreadyExistsException
+ * if the target file exists but cannot be replaced because the
+ * {@code REPLACE_EXISTING} option is not specified <i>(optional
+ * specific exception)</i>
+ * @throws DirectoryNotEmptyException
+ * the {@code REPLACE_EXISTING} option is specified but the file
+ * cannot be replaced because it is a non-empty directory
+ * <i>(optional specific exception)</i>
+ * @throws AtomicMoveNotSupportedException
+ * if the options array contains the {@code ATOMIC_MOVE} option but
+ * the file cannot be moved as an atomic file system operation.
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to both the source and
+ * target file.
+ */
+ public abstract void move(Path source, Path target, CopyOption... options)
+ throws IOException;
+
+ /**
+ * Tests if two paths locate the same file. This method works in exactly the
+ * manner specified by the {@link Files#isSameFile} method.
+ *
+ * @param path
+ * one path to the file
+ * @param path2
+ * the other path
+ *
+ * @return {@code true} if, and only if, the two paths locate the same file
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to both files.
+ */
+ public abstract boolean isSameFile(Path path, Path path2)
+ throws IOException;
+
+ /**
+ * Tells whether or not a file is considered <em>hidden</em>. This method
+ * works in exactly the manner specified by the {@link Files#isHidden}
+ * method.
+ *
+ * <p> This method is invoked by the {@link Files#isHidden isHidden} method.
+ *
+ * @param path
+ * the path to the file to test
+ *
+ * @return {@code true} if the file is considered hidden
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file.
+ */
+ public abstract boolean isHidden(Path path) throws IOException;
+
+ /**
+ * Returns the {@link FileStore} representing the file store where a file
+ * is located. This method works in exactly the manner specified by the
+ * {@link Files#getFileStore} method.
+ *
+ * @param path
+ * the path to the file
+ *
+ * @return the file store where the file is stored
+ *
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file, and in
+ * addition it checks {@link RuntimePermission}<tt>
+ * ("getFileStoreAttributes")</tt>
+ */
+ public abstract FileStore getFileStore(Path path) throws IOException;
+
+ /**
+ * Checks the existence, and optionally the accessibility, of a file.
+ *
+ * <p> This method may be used by the {@link Files#isReadable isReadable},
+ * {@link Files#isWritable isWritable} and {@link Files#isExecutable
+ * isExecutable} methods to check the accessibility of a file.
+ *
+ * <p> This method checks the existence of a file and that this Java virtual
+ * machine has appropriate privileges that would allow it access the file
+ * according to all of access modes specified in the {@code modes} parameter
+ * as follows:
+ *
+ * <table border=1 cellpadding=5 summary="">
+ * <tr> <th>Value</th> <th>Description</th> </tr>
+ * <tr>
+ * <td> {@link AccessMode#READ READ} </td>
+ * <td> Checks that the file exists and that the Java virtual machine has
+ * permission to read the file. </td>
+ * </tr>
+ * <tr>
+ * <td> {@link AccessMode#WRITE WRITE} </td>
+ * <td> Checks that the file exists and that the Java virtual machine has
+ * permission to write to the file, </td>
+ * </tr>
+ * <tr>
+ * <td> {@link AccessMode#EXECUTE EXECUTE} </td>
+ * <td> Checks that the file exists and that the Java virtual machine has
+ * permission to {@link Runtime#exec execute} the file. The semantics
+ * may differ when checking access to a directory. For example, on UNIX
+ * systems, checking for {@code EXECUTE} access checks that the Java
+ * virtual machine has permission to search the directory in order to
+ * access file or subdirectories. </td>
+ * </tr>
+ * </table>
+ *
+ * <p> If the {@code modes} parameter is of length zero, then the existence
+ * of the file is checked.
+ *
+ * <p> This method follows symbolic links if the file referenced by this
+ * object is a symbolic link. Depending on the implementation, this method
+ * may require to read file permissions, access control lists, or other
+ * file attributes in order to check the effective access to the file. To
+ * determine the effective access to a file may require access to several
+ * attributes and so in some implementations this method may not be atomic
+ * with respect to other file system operations.
+ *
+ * @param path
+ * the path to the file to check
+ * @param modes
+ * The access modes to check; may have zero elements
+ *
+ * @throws UnsupportedOperationException
+ * an implementation is required to support checking for
+ * {@code READ}, {@code WRITE}, and {@code EXECUTE} access. This
+ * exception is specified to allow for the {@code Access} enum to
+ * be extended in future releases.
+ * @throws NoSuchFileException
+ * if a file does not exist <i>(optional specific exception)</i>
+ * @throws AccessDeniedException
+ * the requested access would be denied or the access cannot be
+ * determined because the Java virtual machine has insufficient
+ * privileges or other reasons. <i>(optional specific exception)</i>
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * is invoked when checking read access to the file or only the
+ * existence of the file, the {@link SecurityManager#checkWrite(String)
+ * checkWrite} is invoked when checking write access to the file,
+ * and {@link SecurityManager#checkExec(String) checkExec} is invoked
+ * when checking execute access.
+ */
+ public abstract void checkAccess(Path path, AccessMode... modes)
+ throws IOException;
+
+ /**
+ * Returns a file attribute view of a given type. This method works in
+ * exactly the manner specified by the {@link Files#getFileAttributeView}
+ * method.
+ *
+ * @param <V>
+ * The {@code FileAttributeView} type
+ * @param path
+ * the path to the file
+ * @param type
+ * the {@code Class} object corresponding to the file attribute view
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return a file attribute view of the specified type, or {@code null} if
+ * the attribute view type is not available
+ */
+ public abstract <V extends FileAttributeView> V
+ getFileAttributeView(Path path, Class<V> type, LinkOption... options);
+
+ /**
+ * Reads a file's attributes as a bulk operation. This method works in
+ * exactly the manner specified by the {@link
+ * Files#readAttributes(Path,Class,LinkOption[])} method.
+ *
+ * @param <A>
+ * The {@code BasicFileAttributes} type
+ * @param path
+ * the path to the file
+ * @param type
+ * the {@code Class} of the file attributes required
+ * to read
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return the file attributes
+ *
+ * @throws UnsupportedOperationException
+ * if an attributes of the given type are not supported
+ * @throws IOException
+ * if an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, a security manager is
+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file
+ */
+ public abstract <A extends BasicFileAttributes> A
+ readAttributes(Path path, Class<A> type, LinkOption... options) throws IOException;
+
+ /**
+ * Reads a set of file attributes as a bulk operation. This method works in
+ * exactly the manner specified by the {@link
+ * Files#readAttributes(Path,String,LinkOption[])} method.
+ *
+ * @param path
+ * the path to the file
+ * @param attributes
+ * the attributes to read
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @return a map of the attributes returned; may be empty. The map's keys
+ * are the attribute names, its values are the attribute values
+ *
+ * @throws UnsupportedOperationException
+ * if the attribute view is not available
+ * @throws IllegalArgumentException
+ * if no attributes are specified or an unrecognized attributes is
+ * specified
+ * @throws IOException
+ * If an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, its {@link SecurityManager#checkRead(String) checkRead}
+ * method denies read access to the file. If this method is invoked
+ * to read security sensitive attributes then the security manager
+ * may be invoke to check for additional permissions.
+ */
+ public abstract Map<String,Object> readAttributes(Path path, String attributes,
+ LinkOption... options)
+ throws IOException;
+
+ /**
+ * Sets the value of a file attribute. This method works in exactly the
+ * manner specified by the {@link Files#setAttribute} method.
+ *
+ * @param path
+ * the path to the file
+ * @param attribute
+ * the attribute to set
+ * @param value
+ * the attribute value
+ * @param options
+ * options indicating how symbolic links are handled
+ *
+ * @throws UnsupportedOperationException
+ * if the attribute view is not available
+ * @throws IllegalArgumentException
+ * if the attribute name is not specified, or is not recognized, or
+ * the attribute value is of the correct type but has an
+ * inappropriate value
+ * @throws ClassCastException
+ * If the attribute value is not of the expected type or is a
+ * collection containing elements that are not of the expected
+ * type
+ * @throws IOException
+ * If an I/O error occurs
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, its {@link SecurityManager#checkWrite(String) checkWrite}
+ * method denies write access to the file. If this method is invoked
+ * to set security sensitive attributes then the security manager
+ * may be invoked to check for additional permissions.
+ */
+ public abstract void setAttribute(Path path, String attribute,
+ Object value, LinkOption... options)
+ throws IOException;
+}
diff --git a/java/nio/file/spi/FileTypeDetector.java b/java/nio/file/spi/FileTypeDetector.java
new file mode 100644
index 0000000..ee118d6
--- /dev/null
+++ b/java/nio/file/spi/FileTypeDetector.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file.spi;
+
+import java.nio.file.Path;
+import java.io.IOException;
+
+/**
+ * A file type detector for probing a file to guess its file type.
+ *
+ * <p> A file type detector is a concrete implementation of this class, has a
+ * zero-argument constructor, and implements the abstract methods specified
+ * below.
+ *
+ * <p> The means by which a file type detector determines the file type is
+ * highly implementation specific. A simple implementation might examine the
+ * <em>file extension</em> (a convention used in some platforms) and map it to
+ * a file type. In other cases, the file type may be stored as a file <a
+ * href="../attribute/package-summary.html"> attribute</a> or the bytes in a
+ * file may be examined to guess its file type.
+ *
+ * @see java.nio.file.Files#probeContentType(Path)
+ *
+ * @since 1.7
+ */
+
+public abstract class FileTypeDetector {
+
+ private static Void checkPermission() {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(new RuntimePermission("fileTypeDetector"));
+ return null;
+ }
+ private FileTypeDetector(Void ignore) { }
+
+ /**
+ * Initializes a new instance of this class.
+ *
+ * @throws SecurityException
+ * If a security manager has been installed and it denies
+ * {@link RuntimePermission}<tt>("fileTypeDetector")</tt>
+ */
+ protected FileTypeDetector() {
+ this(checkPermission());
+ }
+
+ /**
+ * Probes the given file to guess its content type.
+ *
+ * <p> The means by which this method determines the file type is highly
+ * implementation specific. It may simply examine the file name, it may use
+ * a file <a href="../attribute/package-summary.html">attribute</a>,
+ * or it may examines bytes in the file.
+ *
+ * <p> The probe result is the string form of the value of a
+ * Multipurpose Internet Mail Extension (MIME) content type as
+ * defined by <a href="http://www.ietf.org/rfc/rfc2045.txt"><i>RFC 2045:
+ * Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet
+ * Message Bodies</i></a>. The string must be parsable according to the
+ * grammar in the RFC 2045.
+ *
+ * @param path
+ * the path to the file to probe
+ *
+ * @return The content type or {@code null} if the file type is not
+ * recognized
+ *
+ * @throws IOException
+ * An I/O error occurs
+ * @throws SecurityException
+ * If the implementation requires to access the file, and a
+ * security manager is installed, and it denies an unspecified
+ * permission required by a file system provider implementation.
+ * If the file reference is associated with the default file system
+ * provider then the {@link SecurityManager#checkRead(String)} method
+ * is invoked to check read access to the file.
+ *
+ * @see java.nio.file.Files#probeContentType
+ */
+ public abstract String probeContentType(Path path)
+ throws IOException;
+}
diff --git a/java/nio/package-info.java b/java/nio/package-info.java
new file mode 100644
index 0000000..b466dc4
--- /dev/null
+++ b/java/nio/package-info.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Defines buffers, which are containers for data, and provides an overview of the
+ * other NIO packages.
+ *
+ *
+ * <p> The central abstractions of the NIO APIs are: </p>
+ *
+ * <ul>
+ *
+ * <li><p> <a href="#buffers"><i>Buffers</i></a>, which are containers for data;
+ * </p></li>
+ *
+ * <li><p> <a href="charset/package-summary.html"><i>Charsets</i></a> and their
+ * associated <i>decoders</i> and <i>encoders</i>, <br> which translate between
+ * bytes and Unicode characters; </p></li>
+ *
+ * <li><p> <a href="channels/package-summary.html"><i>Channels</i></a> of
+ * various types, which represent connections <br> to entities capable of
+ * performing I/O operations; and </p></li>
+ *
+ * <li><p> <i>Selectors</i> and <i>selection keys</i>, which together with <br>
+ * <i>selectable channels</i> define a <a
+ * href="channels/package-summary.html#multiplex">multiplexed, non-blocking <br>
+ * I/O</a> facility. </p></li>
+ *
+ * </ul>
+ *
+ * <p> The <tt>java.nio</tt> package defines the buffer classes, which are used
+ * throughout the NIO APIs. The charset API is defined in the {@link
+ * java.nio.charset} package, and the channel and selector APIs are defined in the
+ * {@link java.nio.channels} package. Each of these subpackages has its own
+ * service-provider (SPI) subpackage, the contents of which can be used to extend
+ * the platform's default implementations or to construct alternative
+ * implementations.
+ *
+ *
+ * <a name="buffers">
+ *
+ * <blockquote><table cellspacing=1 cellpadding=0 summary="Description of the various buffers">
+ * <tr><th><p align="left">Buffers</p></th><th><p align="left">Description</p></th></tr>
+ * <tr><td valign=top><tt>{@link java.nio.Buffer}</tt></td>
+ * <td>Position, limit, and capacity;
+ * <br>clear, flip, rewind, and mark/reset</td></tr>
+ * <tr><td valign=top><tt> {@link java.nio.ByteBuffer}</tt></td>
+ * <td>Get/put, compact, views; allocate, wrap</td></tr>
+ * <tr><td valign=top><tt> {@link java.nio.MappedByteBuffer} </tt></td>
+ * <td>A byte buffer mapped to a file</td></tr>
+ * <tr><td valign=top><tt> {@link java.nio.CharBuffer}</tt></td>
+ * <td>Get/put, compact; allocate, wrap</td></tr>
+ * <tr><td valign=top><tt> {@link java.nio.DoubleBuffer}</tt></td>
+ * <td> ' '</td></tr>
+ * <tr><td valign=top><tt> {@link java.nio.FloatBuffer}</tt></td>
+ * <td> ' '</td></tr>
+ * <tr><td valign=top><tt> {@link java.nio.IntBuffer}</tt></td>
+ * <td> ' '</td></tr>
+ * <tr><td valign=top><tt> {@link java.nio.LongBuffer}</tt></td>
+ * <td> ' '</td></tr>
+ * <tr><td valign=top><tt> {@link java.nio.ShortBuffer}</tt></td>
+ * <td> ' '</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.ByteOrder}</tt></td>
+ * <td>Typesafe enumeration for byte orders</td></tr>
+ * </table></blockquote>
+ *
+ * <p> A <i>buffer</i> is a container for a fixed amount of data of a specific
+ * primitive type. In addition to its content a buffer has a <i>position</i>,
+ * which is the index of the next element to be read or written, and a
+ * <i>limit</i>, which is the index of the first element that should not be read
+ * or written. The base {@link java.nio.Buffer} class defines these properties as
+ * well as methods for <i>clearing</i>, <i>flipping</i>, and <i>rewinding</i>, for
+ * <i>marking</i> the current position, and for <i>resetting</i> the position to
+ * the previous mark.
+ *
+ * <p> There is a buffer class for each non-boolean primitive type. Each class
+ * defines a family of <i>get</i> and <i>put</i> methods for moving data out of
+ * and in to a buffer, methods for <i>compacting</i>, <i>duplicating</i>, and
+ * <i>slicing</i> a buffer, and static methods for <i>allocating</i> a new buffer
+ * as well as for <i>wrapping</i> an existing array into a buffer.
+ *
+ * <p> Byte buffers are distinguished in that they can be used as the sources and
+ * targets of I/O operations. They also support several features not found in the
+ * other buffer classes:
+ *
+ * <ul>
+ *
+ * <li><p> A byte buffer can be allocated as a <a href="ByteBuffer.html#direct">
+ * <i>direct</i></a> buffer, in which case the Java virtual machine will make a
+ * best effort to perform native I/O operations directly upon it. </p></li>
+ *
+ * <li><p> A byte buffer can be created by {@link
+ * java.nio.channels.FileChannel#map </code><i>mapping</i><code>} a region of a
+ * file directly into memory, in which case a few additional file-related
+ * operations defined in the {@link java.nio.MappedByteBuffer} class are
+ * available. </p></li>
+ *
+ * <li><p> A byte buffer provides access to its content as either a heterogeneous
+ * or homogeneous sequence of <a href="ByteBuffer.html#bin">binary data</i></a>
+ * of any non-boolean primitive type, in either big-endian or little-endian <a
+ * href="ByteOrder.html">byte order</a>. </p></li>
+ *
+ * </ul>
+ *
+ * <p> Unless otherwise noted, passing a <tt>null</tt> argument to a constructor
+ * or method in any class or interface in this package will cause a {@link
+ * java.lang.NullPointerException NullPointerException} to be thrown.
+ *
+ * @since 1.4
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ */
+
+package java.nio;