Showing the changes to java/pkg/java/nio (308 of 18352 files). Show all
Unified · Split
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,803 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio; | |
| 27 | + | |
| 28 | +import java.security.AccessController; | |
| 29 | +import sun.misc.Unsafe; | |
| 30 | +import sun.misc.VM; | |
| 31 | + | |
| 32 | +/** | |
| 33 | + * Access to bits, native and otherwise. | |
| 34 | + */ | |
| 35 | + | |
| 36 | +class Bits { // package-private | |
| 37 | + | |
| 38 | + private Bits() { } | |
| 39 | + | |
| 40 | + | |
| 41 | + // -- Swapping -- | |
| 42 | + | |
| 43 | + static short swap(short x) { | |
| 44 | + return Short.reverseBytes(x); | |
| 45 | + } | |
| 46 | + | |
| 47 | + static char swap(char x) { | |
| 48 | + return Character.reverseBytes(x); | |
| 49 | + } | |
| 50 | + | |
| 51 | + static int swap(int x) { | |
| 52 | + return Integer.reverseBytes(x); | |
| 53 | + } | |
| 54 | + | |
| 55 | + static long swap(long x) { | |
| 56 | + return Long.reverseBytes(x); | |
| 57 | + } | |
| 58 | + | |
| 59 | + | |
| 60 | + // -- get/put char -- | |
| 61 | + | |
| 62 | + static private char makeChar(byte b1, byte b0) { | |
| 63 | + return (char)((b1 << 8) | (b0 & 0xff)); | |
| 64 | + } | |
| 65 | + | |
| 66 | + static char getCharL(ByteBuffer bb, int bi) { | |
| 67 | + return makeChar(bb._get(bi + 1), | |
| 68 | + bb._get(bi )); | |
| 69 | + } | |
| 70 | + | |
| 71 | + static char getCharL(long a) { | |
| 72 | + return makeChar(_get(a + 1), | |
| 73 | + _get(a )); | |
| 74 | + } | |
| 75 | + | |
| 76 | + static char getCharB(ByteBuffer bb, int bi) { | |
| 77 | + return makeChar(bb._get(bi ), | |
| 78 | + bb._get(bi + 1)); | |
| 79 | + } | |
| 80 | + | |
| 81 | + static char getCharB(long a) { | |
| 82 | + return makeChar(_get(a ), | |
| 83 | + _get(a + 1)); | |
| 84 | + } | |
| 85 | + | |
| 86 | + static char getChar(ByteBuffer bb, int bi, boolean bigEndian) { | |
| 87 | + return bigEndian ? getCharB(bb, bi) : getCharL(bb, bi); | |
| 88 | + } | |
| 89 | + | |
| 90 | + static char getChar(long a, boolean bigEndian) { | |
| 91 | + return bigEndian ? getCharB(a) : getCharL(a); | |
| 92 | + } | |
| 93 | + | |
| 94 | + private static byte char1(char x) { return (byte)(x >> 8); } | |
| 95 | + private static byte char0(char x) { return (byte)(x ); } | |
| 96 | + | |
| 97 | + static void putCharL(ByteBuffer bb, int bi, char x) { | |
| 98 | + bb._put(bi , char0(x)); | |
| 99 | + bb._put(bi + 1, char1(x)); | |
| 100 | + } | |
| 101 | + | |
| 102 | + static void putCharL(long a, char x) { | |
| 103 | + _put(a , char0(x)); | |
| 104 | + _put(a + 1, char1(x)); | |
| 105 | + } | |
| 106 | + | |
| 107 | + static void putCharB(ByteBuffer bb, int bi, char x) { | |
| 108 | + bb._put(bi , char1(x)); | |
| 109 | + bb._put(bi + 1, char0(x)); | |
| 110 | + } | |
| 111 | + | |
| 112 | + static void putCharB(long a, char x) { | |
| 113 | + _put(a , char1(x)); | |
| 114 | + _put(a + 1, char0(x)); | |
| 115 | + } | |
| 116 | + | |
| 117 | + static void putChar(ByteBuffer bb, int bi, char x, boolean bigEndian) { | |
| 118 | + if (bigEndian) | |
| 119 | + putCharB(bb, bi, x); | |
| 120 | + else | |
| 121 | + putCharL(bb, bi, x); | |
| 122 | + } | |
| 123 | + | |
| 124 | + static void putChar(long a, char x, boolean bigEndian) { | |
| 125 | + if (bigEndian) | |
| 126 | + putCharB(a, x); | |
| 127 | + else | |
| 128 | + putCharL(a, x); | |
| 129 | + } | |
| 130 | + | |
| 131 | + | |
| 132 | + // -- get/put short -- | |
| 133 | + | |
| 134 | + static private short makeShort(byte b1, byte b0) { | |
| 135 | + return (short)((b1 << 8) | (b0 & 0xff)); | |
| 136 | + } | |
| 137 | + | |
| 138 | + static short getShortL(ByteBuffer bb, int bi) { | |
| 139 | + return makeShort(bb._get(bi + 1), | |
| 140 | + bb._get(bi )); | |
| 141 | + } | |
| 142 | + | |
| 143 | + static short getShortL(long a) { | |
| 144 | + return makeShort(_get(a + 1), | |
| 145 | + _get(a )); | |
| 146 | + } | |
| 147 | + | |
| 148 | + static short getShortB(ByteBuffer bb, int bi) { | |
| 149 | + return makeShort(bb._get(bi ), | |
| 150 | + bb._get(bi + 1)); | |
| 151 | + } | |
| 152 | + | |
| 153 | + static short getShortB(long a) { | |
| 154 | + return makeShort(_get(a ), | |
| 155 | + _get(a + 1)); | |
| 156 | + } | |
| 157 | + | |
| 158 | + static short getShort(ByteBuffer bb, int bi, boolean bigEndian) { | |
| 159 | + return bigEndian ? getShortB(bb, bi) : getShortL(bb, bi); | |
| 160 | + } | |
| 161 | + | |
| 162 | + static short getShort(long a, boolean bigEndian) { | |
| 163 | + return bigEndian ? getShortB(a) : getShortL(a); | |
| 164 | + } | |
| 165 | + | |
| 166 | + private static byte short1(short x) { return (byte)(x >> 8); } | |
| 167 | + private static byte short0(short x) { return (byte)(x ); } | |
| 168 | + | |
| 169 | + static void putShortL(ByteBuffer bb, int bi, short x) { | |
| 170 | + bb._put(bi , short0(x)); | |
| 171 | + bb._put(bi + 1, short1(x)); | |
| 172 | + } | |
| 173 | + | |
| 174 | + static void putShortL(long a, short x) { | |
| 175 | + _put(a , short0(x)); | |
| 176 | + _put(a + 1, short1(x)); | |
| 177 | + } | |
| 178 | + | |
| 179 | + static void putShortB(ByteBuffer bb, int bi, short x) { | |
| 180 | + bb._put(bi , short1(x)); | |
| 181 | + bb._put(bi + 1, short0(x)); | |
| 182 | + } | |
| 183 | + | |
| 184 | + static void putShortB(long a, short x) { | |
| 185 | + _put(a , short1(x)); | |
| 186 | + _put(a + 1, short0(x)); | |
| 187 | + } | |
| 188 | + | |
| 189 | + static void putShort(ByteBuffer bb, int bi, short x, boolean bigEndian) { | |
| 190 | + if (bigEndian) | |
| 191 | + putShortB(bb, bi, x); | |
| 192 | + else | |
| 193 | + putShortL(bb, bi, x); | |
| 194 | + } | |
| 195 | + | |
| 196 | + static void putShort(long a, short x, boolean bigEndian) { | |
| 197 | + if (bigEndian) | |
| 198 | + putShortB(a, x); | |
| 199 | + else | |
| 200 | + putShortL(a, x); | |
| 201 | + } | |
| 202 | + | |
| 203 | + | |
| 204 | + // -- get/put int -- | |
| 205 | + | |
| 206 | + static private int makeInt(byte b3, byte b2, byte b1, byte b0) { | |
| 207 | + return (((b3 ) << 24) | | |
| 208 | + ((b2 & 0xff) << 16) | | |
| 209 | + ((b1 & 0xff) << 8) | | |
| 210 | + ((b0 & 0xff) )); | |
| 211 | + } | |
| 212 | + | |
| 213 | + static int getIntL(ByteBuffer bb, int bi) { | |
| 214 | + return makeInt(bb._get(bi + 3), | |
| 215 | + bb._get(bi + 2), | |
| 216 | + bb._get(bi + 1), | |
| 217 | + bb._get(bi )); | |
| 218 | + } | |
| 219 | + | |
| 220 | + static int getIntL(long a) { | |
| 221 | + return makeInt(_get(a + 3), | |
| 222 | + _get(a + 2), | |
| 223 | + _get(a + 1), | |
| 224 | + _get(a )); | |
| 225 | + } | |
| 226 | + | |
| 227 | + static int getIntB(ByteBuffer bb, int bi) { | |
| 228 | + return makeInt(bb._get(bi ), | |
| 229 | + bb._get(bi + 1), | |
| 230 | + bb._get(bi + 2), | |
| 231 | + bb._get(bi + 3)); | |
| 232 | + } | |
| 233 | + | |
| 234 | + static int getIntB(long a) { | |
| 235 | + return makeInt(_get(a ), | |
| 236 | + _get(a + 1), | |
| 237 | + _get(a + 2), | |
| 238 | + _get(a + 3)); | |
| 239 | + } | |
| 240 | + | |
| 241 | + static int getInt(ByteBuffer bb, int bi, boolean bigEndian) { | |
| 242 | + return bigEndian ? getIntB(bb, bi) : getIntL(bb, bi) ; | |
| 243 | + } | |
| 244 | + | |
| 245 | + static int getInt(long a, boolean bigEndian) { | |
| 246 | + return bigEndian ? getIntB(a) : getIntL(a) ; | |
| 247 | + } | |
| 248 | + | |
| 249 | + private static byte int3(int x) { return (byte)(x >> 24); } | |
| 250 | + private static byte int2(int x) { return (byte)(x >> 16); } | |
| 251 | + private static byte int1(int x) { return (byte)(x >> 8); } | |
| 252 | + private static byte int0(int x) { return (byte)(x ); } | |
| 253 | + | |
| 254 | + static void putIntL(ByteBuffer bb, int bi, int x) { | |
| 255 | + bb._put(bi + 3, int3(x)); | |
| 256 | + bb._put(bi + 2, int2(x)); | |
| 257 | + bb._put(bi + 1, int1(x)); | |
| 258 | + bb._put(bi , int0(x)); | |
| 259 | + } | |
| 260 | + | |
| 261 | + static void putIntL(long a, int x) { | |
| 262 | + _put(a + 3, int3(x)); | |
| 263 | + _put(a + 2, int2(x)); | |
| 264 | + _put(a + 1, int1(x)); | |
| 265 | + _put(a , int0(x)); | |
| 266 | + } | |
| 267 | + | |
| 268 | + static void putIntB(ByteBuffer bb, int bi, int x) { | |
| 269 | + bb._put(bi , int3(x)); | |
| 270 | + bb._put(bi + 1, int2(x)); | |
| 271 | + bb._put(bi + 2, int1(x)); | |
| 272 | + bb._put(bi + 3, int0(x)); | |
| 273 | + } | |
| 274 | + | |
| 275 | + static void putIntB(long a, int x) { | |
| 276 | + _put(a , int3(x)); | |
| 277 | + _put(a + 1, int2(x)); | |
| 278 | + _put(a + 2, int1(x)); | |
| 279 | + _put(a + 3, int0(x)); | |
| 280 | + } | |
| 281 | + | |
| 282 | + static void putInt(ByteBuffer bb, int bi, int x, boolean bigEndian) { | |
| 283 | + if (bigEndian) | |
| 284 | + putIntB(bb, bi, x); | |
| 285 | + else | |
| 286 | + putIntL(bb, bi, x); | |
| 287 | + } | |
| 288 | + | |
| 289 | + static void putInt(long a, int x, boolean bigEndian) { | |
| 290 | + if (bigEndian) | |
| 291 | + putIntB(a, x); | |
| 292 | + else | |
| 293 | + putIntL(a, x); | |
| 294 | + } | |
| 295 | + | |
| 296 | + | |
| 297 | + // -- get/put long -- | |
| 298 | + | |
| 299 | + static private long makeLong(byte b7, byte b6, byte b5, byte b4, | |
| 300 | + byte b3, byte b2, byte b1, byte b0) | |
| 301 | + { | |
| 302 | + return ((((long)b7 ) << 56) | | |
| 303 | + (((long)b6 & 0xff) << 48) | | |
| 304 | + (((long)b5 & 0xff) << 40) | | |
| 305 | + (((long)b4 & 0xff) << 32) | | |
| 306 | + (((long)b3 & 0xff) << 24) | | |
| 307 | + (((long)b2 & 0xff) << 16) | | |
| 308 | + (((long)b1 & 0xff) << 8) | | |
| 309 | + (((long)b0 & 0xff) )); | |
| 310 | + } | |
| 311 | + | |
| 312 | + static long getLongL(ByteBuffer bb, int bi) { | |
| 313 | + return makeLong(bb._get(bi + 7), | |
| 314 | + bb._get(bi + 6), | |
| 315 | + bb._get(bi + 5), | |
| 316 | + bb._get(bi + 4), | |
| 317 | + bb._get(bi + 3), | |
| 318 | + bb._get(bi + 2), | |
| 319 | + bb._get(bi + 1), | |
| 320 | + bb._get(bi )); | |
| 321 | + } | |
| 322 | + | |
| 323 | + static long getLongL(long a) { | |
| 324 | + return makeLong(_get(a + 7), | |
| 325 | + _get(a + 6), | |
| 326 | + _get(a + 5), | |
| 327 | + _get(a + 4), | |
| 328 | + _get(a + 3), | |
| 329 | + _get(a + 2), | |
| 330 | + _get(a + 1), | |
| 331 | + _get(a )); | |
| 332 | + } | |
| 333 | + | |
| 334 | + static long getLongB(ByteBuffer bb, int bi) { | |
| 335 | + return makeLong(bb._get(bi ), | |
| 336 | + bb._get(bi + 1), | |
| 337 | + bb._get(bi + 2), | |
| 338 | + bb._get(bi + 3), | |
| 339 | + bb._get(bi + 4), | |
| 340 | + bb._get(bi + 5), | |
| 341 | + bb._get(bi + 6), | |
| 342 | + bb._get(bi + 7)); | |
| 343 | + } | |
| 344 | + | |
| 345 | + static long getLongB(long a) { | |
| 346 | + return makeLong(_get(a ), | |
| 347 | + _get(a + 1), | |
| 348 | + _get(a + 2), | |
| 349 | + _get(a + 3), | |
| 350 | + _get(a + 4), | |
| 351 | + _get(a + 5), | |
| 352 | + _get(a + 6), | |
| 353 | + _get(a + 7)); | |
| 354 | + } | |
| 355 | + | |
| 356 | + static long getLong(ByteBuffer bb, int bi, boolean bigEndian) { | |
| 357 | + return bigEndian ? getLongB(bb, bi) : getLongL(bb, bi); | |
| 358 | + } | |
| 359 | + | |
| 360 | + static long getLong(long a, boolean bigEndian) { | |
| 361 | + return bigEndian ? getLongB(a) : getLongL(a); | |
| 362 | + } | |
| 363 | + | |
| 364 | + private static byte long7(long x) { return (byte)(x >> 56); } | |
| 365 | + private static byte long6(long x) { return (byte)(x >> 48); } | |
| 366 | + private static byte long5(long x) { return (byte)(x >> 40); } | |
| 367 | + private static byte long4(long x) { return (byte)(x >> 32); } | |
| 368 | + private static byte long3(long x) { return (byte)(x >> 24); } | |
| 369 | + private static byte long2(long x) { return (byte)(x >> 16); } | |
| 370 | + private static byte long1(long x) { return (byte)(x >> 8); } | |
| 371 | + private static byte long0(long x) { return (byte)(x ); } | |
| 372 | + | |
| 373 | + static void putLongL(ByteBuffer bb, int bi, long x) { | |
| 374 | + bb._put(bi + 7, long7(x)); | |
| 375 | + bb._put(bi + 6, long6(x)); | |
| 376 | + bb._put(bi + 5, long5(x)); | |
| 377 | + bb._put(bi + 4, long4(x)); | |
| 378 | + bb._put(bi + 3, long3(x)); | |
| 379 | + bb._put(bi + 2, long2(x)); | |
| 380 | + bb._put(bi + 1, long1(x)); | |
| 381 | + bb._put(bi , long0(x)); | |
| 382 | + } | |
| 383 | + | |
| 384 | + static void putLongL(long a, long x) { | |
| 385 | + _put(a + 7, long7(x)); | |
| 386 | + _put(a + 6, long6(x)); | |
| 387 | + _put(a + 5, long5(x)); | |
| 388 | + _put(a + 4, long4(x)); | |
| 389 | + _put(a + 3, long3(x)); | |
| 390 | + _put(a + 2, long2(x)); | |
| 391 | + _put(a + 1, long1(x)); | |
| 392 | + _put(a , long0(x)); | |
| 393 | + } | |
| 394 | + | |
| 395 | + static void putLongB(ByteBuffer bb, int bi, long x) { | |
| 396 | + bb._put(bi , long7(x)); | |
| 397 | + bb._put(bi + 1, long6(x)); | |
| 398 | + bb._put(bi + 2, long5(x)); | |
| 399 | + bb._put(bi + 3, long4(x)); | |
| 400 | + bb._put(bi + 4, long3(x)); | |
| 401 | + bb._put(bi + 5, long2(x)); | |
| 402 | + bb._put(bi + 6, long1(x)); | |
| 403 | + bb._put(bi + 7, long0(x)); | |
| 404 | + } | |
| 405 | + | |
| 406 | + static void putLongB(long a, long x) { | |
| 407 | + _put(a , long7(x)); | |
| 408 | + _put(a + 1, long6(x)); | |
| 409 | + _put(a + 2, long5(x)); | |
| 410 | + _put(a + 3, long4(x)); | |
| 411 | + _put(a + 4, long3(x)); | |
| 412 | + _put(a + 5, long2(x)); | |
| 413 | + _put(a + 6, long1(x)); | |
| 414 | + _put(a + 7, long0(x)); | |
| 415 | + } | |
| 416 | + | |
| 417 | + static void putLong(ByteBuffer bb, int bi, long x, boolean bigEndian) { | |
| 418 | + if (bigEndian) | |
| 419 | + putLongB(bb, bi, x); | |
| 420 | + else | |
| 421 | + putLongL(bb, bi, x); | |
| 422 | + } | |
| 423 | + | |
| 424 | + static void putLong(long a, long x, boolean bigEndian) { | |
| 425 | + if (bigEndian) | |
| 426 | + putLongB(a, x); | |
| 427 | + else | |
| 428 | + putLongL(a, x); | |
| 429 | + } | |
| 430 | + | |
| 431 | + | |
| 432 | + // -- get/put float -- | |
| 433 | + | |
| 434 | + static float getFloatL(ByteBuffer bb, int bi) { | |
| 435 | + return Float.intBitsToFloat(getIntL(bb, bi)); | |
| 436 | + } | |
| 437 | + | |
| 438 | + static float getFloatL(long a) { | |
| 439 | + return Float.intBitsToFloat(getIntL(a)); | |
| 440 | + } | |
| 441 | + | |
| 442 | + static float getFloatB(ByteBuffer bb, int bi) { | |
| 443 | + return Float.intBitsToFloat(getIntB(bb, bi)); | |
| 444 | + } | |
| 445 | + | |
| 446 | + static float getFloatB(long a) { | |
| 447 | + return Float.intBitsToFloat(getIntB(a)); | |
| 448 | + } | |
| 449 | + | |
| 450 | + static float getFloat(ByteBuffer bb, int bi, boolean bigEndian) { | |
| 451 | + return bigEndian ? getFloatB(bb, bi) : getFloatL(bb, bi); | |
| 452 | + } | |
| 453 | + | |
| 454 | + static float getFloat(long a, boolean bigEndian) { | |
| 455 | + return bigEndian ? getFloatB(a) : getFloatL(a); | |
| 456 | + } | |
| 457 | + | |
| 458 | + static void putFloatL(ByteBuffer bb, int bi, float x) { | |
| 459 | + putIntL(bb, bi, Float.floatToRawIntBits(x)); | |
| 460 | + } | |
| 461 | + | |
| 462 | + static void putFloatL(long a, float x) { | |
| 463 | + putIntL(a, Float.floatToRawIntBits(x)); | |
| 464 | + } | |
| 465 | + | |
| 466 | + static void putFloatB(ByteBuffer bb, int bi, float x) { | |
| 467 | + putIntB(bb, bi, Float.floatToRawIntBits(x)); | |
| 468 | + } | |
| 469 | + | |
| 470 | + static void putFloatB(long a, float x) { | |
| 471 | + putIntB(a, Float.floatToRawIntBits(x)); | |
| 472 | + } | |
| 473 | + | |
| 474 | + static void putFloat(ByteBuffer bb, int bi, float x, boolean bigEndian) { | |
| 475 | + if (bigEndian) | |
| 476 | + putFloatB(bb, bi, x); | |
| 477 | + else | |
| 478 | + putFloatL(bb, bi, x); | |
| 479 | + } | |
| 480 | + | |
| 481 | + static void putFloat(long a, float x, boolean bigEndian) { | |
| 482 | + if (bigEndian) | |
| 483 | + putFloatB(a, x); | |
| 484 | + else | |
| 485 | + putFloatL(a, x); | |
| 486 | + } | |
| 487 | + | |
| 488 | + | |
| 489 | + // -- get/put double -- | |
| 490 | + | |
| 491 | + static double getDoubleL(ByteBuffer bb, int bi) { | |
| 492 | + return Double.longBitsToDouble(getLongL(bb, bi)); | |
| 493 | + } | |
| 494 | + | |
| 495 | + static double getDoubleL(long a) { | |
| 496 | + return Double.longBitsToDouble(getLongL(a)); | |
| 497 | + } | |
| 498 | + | |
| 499 | + static double getDoubleB(ByteBuffer bb, int bi) { | |
| 500 | + return Double.longBitsToDouble(getLongB(bb, bi)); | |
| 501 | + } | |
| 502 | + | |
| 503 | + static double getDoubleB(long a) { | |
| 504 | + return Double.longBitsToDouble(getLongB(a)); | |
| 505 | + } | |
| 506 | + | |
| 507 | + static double getDouble(ByteBuffer bb, int bi, boolean bigEndian) { | |
| 508 | + return bigEndian ? getDoubleB(bb, bi) : getDoubleL(bb, bi); | |
| 509 | + } | |
| 510 | + | |
| 511 | + static double getDouble(long a, boolean bigEndian) { | |
| 512 | + return bigEndian ? getDoubleB(a) : getDoubleL(a); | |
| 513 | + } | |
| 514 | + | |
| 515 | + static void putDoubleL(ByteBuffer bb, int bi, double x) { | |
| 516 | + putLongL(bb, bi, Double.doubleToRawLongBits(x)); | |
| 517 | + } | |
| 518 | + | |
| 519 | + static void putDoubleL(long a, double x) { | |
| 520 | + putLongL(a, Double.doubleToRawLongBits(x)); | |
| 521 | + } | |
| 522 | + | |
| 523 | + static void putDoubleB(ByteBuffer bb, int bi, double x) { | |
| 524 | + putLongB(bb, bi, Double.doubleToRawLongBits(x)); | |
| 525 | + } | |
| 526 | + | |
| 527 | + static void putDoubleB(long a, double x) { | |
| 528 | + putLongB(a, Double.doubleToRawLongBits(x)); | |
| 529 | + } | |
| 530 | + | |
| 531 | + static void putDouble(ByteBuffer bb, int bi, double x, boolean bigEndian) { | |
| 532 | + if (bigEndian) | |
| 533 | + putDoubleB(bb, bi, x); | |
| 534 | + else | |
| 535 | + putDoubleL(bb, bi, x); | |
| 536 | + } | |
| 537 | + | |
| 538 | + static void putDouble(long a, double x, boolean bigEndian) { | |
| 539 | + if (bigEndian) | |
| 540 | + putDoubleB(a, x); | |
| 541 | + else | |
| 542 | + putDoubleL(a, x); | |
| 543 | + } | |
| 544 | + | |
| 545 | + | |
| 546 | + // -- Unsafe access -- | |
| 547 | + | |
| 548 | + private static final Unsafe unsafe = Unsafe.getUnsafe(); | |
| 549 | + | |
| 550 | + private static byte _get(long a) { | |
| 551 | + return unsafe.getByte(a); | |
| 552 | + } | |
| 553 | + | |
| 554 | + private static void _put(long a, byte b) { | |
| 555 | + unsafe.putByte(a, b); | |
| 556 | + } | |
| 557 | + | |
| 558 | + static Unsafe unsafe() { | |
| 559 | + return unsafe; | |
| 560 | + } | |
| 561 | + | |
| 562 | + | |
| 563 | + // -- Processor and memory-system properties -- | |
| 564 | + | |
| 565 | + private static final ByteOrder byteOrder; | |
| 566 | + | |
| 567 | + static ByteOrder byteOrder() { | |
| 568 | + if (byteOrder == null) | |
| 569 | + throw new Error("Unknown byte order"); | |
| 570 | + return byteOrder; | |
| 571 | + } | |
| 572 | + | |
| 573 | + static { | |
| 574 | + long a = unsafe.allocateMemory(8); | |
| 575 | + try { | |
| 576 | + unsafe.putLong(a, 0x0102030405060708L); | |
| 577 | + byte b = unsafe.getByte(a); | |
| 578 | + switch (b) { | |
| 579 | + case 0x01: byteOrder = ByteOrder.BIG_ENDIAN; break; | |
| 580 | + case 0x08: byteOrder = ByteOrder.LITTLE_ENDIAN; break; | |
| 581 | + default: | |
| 582 | + assert false; | |
| 583 | + byteOrder = null; | |
| 584 | + } | |
| 585 | + } finally { | |
| 586 | + unsafe.freeMemory(a); | |
| 587 | + } | |
| 588 | + } | |
| 589 | + | |
| 590 | + | |
| 591 | + private static int pageSize = -1; | |
| 592 | + | |
| 593 | + static int pageSize() { | |
| 594 | + if (pageSize == -1) | |
| 595 | + pageSize = unsafe().pageSize(); | |
| 596 | + return pageSize; | |
| 597 | + } | |
| 598 | + | |
| 599 | + static int pageCount(long size) { | |
| 600 | + return (int)(size + (long)pageSize() - 1L) / pageSize(); | |
| 601 | + } | |
| 602 | + | |
| 603 | + private static boolean unaligned; | |
| 604 | + private static boolean unalignedKnown = false; | |
| 605 | + | |
| 606 | + static boolean unaligned() { | |
| 607 | + if (unalignedKnown) | |
| 608 | + return unaligned; | |
| 609 | + String arch = AccessController.doPrivileged( | |
| 610 | + new sun.security.action.GetPropertyAction("os.arch")); | |
| 611 | + unaligned = arch.equals("i386") || arch.equals("x86") | |
| 612 | + || arch.equals("amd64"); | |
| 613 | + unalignedKnown = true; | |
| 614 | + return unaligned; | |
| 615 | + } | |
| 616 | + | |
| 617 | + | |
| 618 | + // -- Direct memory management -- | |
| 619 | + | |
| 620 | + // A user-settable upper limit on the maximum amount of allocatable | |
| 621 | + // direct buffer memory. This value may be changed during VM | |
| 622 | + // initialization if it is launched with "-XX:MaxDirectMemorySize=<size>". | |
| 623 | + private static volatile long maxMemory = VM.maxDirectMemory(); | |
| 624 | + private static volatile long reservedMemory; | |
| 625 | + private static volatile long totalCapacity; | |
| 626 | + private static volatile long count; | |
| 627 | + private static boolean memoryLimitSet = false; | |
| 628 | + | |
| 629 | + // These methods should be called whenever direct memory is allocated or | |
| 630 | + // freed. They allow the user to control the amount of direct memory | |
| 631 | + // which a process may access. All sizes are specified in bytes. | |
| 632 | + static void reserveMemory(long size, int cap) { | |
| 633 | + synchronized (Bits.class) { | |
| 634 | + if (!memoryLimitSet && VM.isBooted()) { | |
| 635 | + maxMemory = VM.maxDirectMemory(); | |
| 636 | + memoryLimitSet = true; | |
| 637 | + } | |
| 638 | + // -XX:MaxDirectMemorySize limits the total capacity rather than the | |
| 639 | + // actual memory usage, which will differ when buffers are page | |
| 640 | + // aligned. | |
| 641 | + if (cap <= maxMemory - totalCapacity) { | |
| 642 | + reservedMemory += size; | |
| 643 | + totalCapacity += cap; | |
| 644 | + count++; | |
| 645 | + return; | |
| 646 | + } | |
| 647 | + } | |
| 648 | + | |
| 649 | + System.gc(); | |
| 650 | + try { | |
| 651 | + Thread.sleep(100); | |
| 652 | + } catch (InterruptedException x) { | |
| 653 | + // Restore interrupt status | |
| 654 | + Thread.currentThread().interrupt(); | |
| 655 | + } | |
| 656 | + synchronized (Bits.class) { | |
| 657 | + if (totalCapacity + cap > maxMemory) | |
| 658 | + throw new OutOfMemoryError("Direct buffer memory"); | |
| 659 | + reservedMemory += size; | |
| 660 | + totalCapacity += cap; | |
| 661 | + count++; | |
| 662 | + } | |
| 663 | + | |
| 664 | + } | |
| 665 | + | |
| 666 | + static synchronized void unreserveMemory(long size, int cap) { | |
| 667 | + if (reservedMemory > 0) { | |
| 668 | + reservedMemory -= size; | |
| 669 | + totalCapacity -= cap; | |
| 670 | + count--; | |
| 671 | + assert (reservedMemory > -1); | |
| 672 | + } | |
| 673 | + } | |
| 674 | + | |
| 675 | + // -- Monitoring of direct buffer usage -- | |
| 676 | + | |
| 677 | + static { | |
| 678 | + // setup access to this package in SharedSecrets | |
| 679 | + sun.misc.SharedSecrets.setJavaNioAccess( | |
| 680 | + new sun.misc.JavaNioAccess() { | |
| 681 | + @Override | |
| 682 | + public sun.misc.JavaNioAccess.BufferPool getDirectBufferPool() { | |
| 683 | + return new sun.misc.JavaNioAccess.BufferPool() { | |
| 684 | + @Override | |
| 685 | + public String getName() { | |
| 686 | + return "direct"; | |
| 687 | + } | |
| 688 | + @Override | |
| 689 | + public long getCount() { | |
| 690 | + return Bits.count; | |
| 691 | + } | |
| 692 | + @Override | |
| 693 | + public long getTotalCapacity() { | |
| 694 | + return Bits.totalCapacity; | |
| 695 | + } | |
| 696 | + @Override | |
| 697 | + public long getMemoryUsed() { | |
| 698 | + return Bits.reservedMemory; | |
| 699 | + } | |
| 700 | + }; | |
| 701 | + } | |
| 702 | + }); | |
| 703 | + } | |
| 704 | + | |
| 705 | + // -- Bulk get/put acceleration -- | |
| 706 | + | |
| 707 | + // These numbers represent the point at which we have empirically | |
| 708 | + // determined that the average cost of a JNI call exceeds the expense | |
| 709 | + // of an element by element copy. These numbers may change over time. | |
| 710 | + static final int JNI_COPY_TO_ARRAY_THRESHOLD = 6; | |
| 711 | + static final int JNI_COPY_FROM_ARRAY_THRESHOLD = 6; | |
| 712 | + | |
| 713 | + // This number limits the number of bytes to copy per call to Unsafe's | |
| 714 | + // copyMemory method. A limit is imposed to allow for safepoint polling | |
| 715 | + // during a large copy | |
| 716 | + static final long UNSAFE_COPY_THRESHOLD = 1024L * 1024L; | |
| 717 | + | |
| 718 | + // These methods do no bounds checking. Verification that the copy will not | |
| 719 | + // result in memory corruption should be done prior to invocation. | |
| 720 | + // All positions and lengths are specified in bytes. | |
| 721 | + | |
| 722 | + /** | |
| 723 | + * Copy from given source array to destination address. | |
| 724 | + * | |
| 725 | + * @param src | |
| 726 | + * source array | |
| 727 | + * @param srcBaseOffset | |
| 728 | + * offset of first element of storage in source array | |
| 729 | + * @param srcPos | |
| 730 | + * offset within source array of the first element to read | |
| 731 | + * @param dstAddr | |
| 732 | + * destination address | |
| 733 | + * @param length | |
| 734 | + * number of bytes to copy | |
| 735 | + */ | |
| 736 | + static void copyFromArray(Object src, long srcBaseOffset, long srcPos, | |
| 737 | + long dstAddr, long length) | |
| 738 | + { | |
| 739 | + long offset = srcBaseOffset + srcPos; | |
| 740 | + while (length > 0) { | |
| 741 | + long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length; | |
| 742 | + unsafe.copyMemory(src, offset, null, dstAddr, size); | |
| 743 | + length -= size; | |
| 744 | + offset += size; | |
| 745 | + dstAddr += size; | |
| 746 | + } | |
| 747 | + } | |
| 748 | + | |
| 749 | + /** | |
| 750 | + * Copy from source address into given destination array. | |
| 751 | + * | |
| 752 | + * @param srcAddr | |
| 753 | + * source address | |
| 754 | + * @param dst | |
| 755 | + * destination array | |
| 756 | + * @param dstBaseOffset | |
| 757 | + * offset of first element of storage in destination array | |
| 758 | + * @param dstPos | |
| 759 | + * offset within destination array of the first element to write | |
| 760 | + * @param length | |
| 761 | + * number of bytes to copy | |
| 762 | + */ | |
| 763 | + static void copyToArray(long srcAddr, Object dst, long dstBaseOffset, long dstPos, | |
| 764 | + long length) | |
| 765 | + { | |
| 766 | + long offset = dstBaseOffset + dstPos; | |
| 767 | + while (length > 0) { | |
| 768 | + long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length; | |
| 769 | + unsafe.copyMemory(null, srcAddr, dst, offset, size); | |
| 770 | + length -= size; | |
| 771 | + srcAddr += size; | |
| 772 | + offset += size; | |
| 773 | + } | |
| 774 | + } | |
| 775 | + | |
| 776 | + static void copyFromCharArray(Object src, long srcPos, long dstAddr, | |
| 777 | + long length) | |
| 778 | + { | |
| 779 | + copyFromShortArray(src, srcPos, dstAddr, length); | |
| 780 | + } | |
| 781 | + | |
| 782 | + static void copyToCharArray(long srcAddr, Object dst, long dstPos, | |
| 783 | + long length) | |
| 784 | + { | |
| 785 | + copyToShortArray(srcAddr, dst, dstPos, length); | |
| 786 | + } | |
| 787 | + | |
| 788 | + static native void copyFromShortArray(Object src, long srcPos, long dstAddr, | |
| 789 | + long length); | |
| 790 | + static native void copyToShortArray(long srcAddr, Object dst, long dstPos, | |
| 791 | + long length); | |
| 792 | + | |
| 793 | + static native void copyFromIntArray(Object src, long srcPos, long dstAddr, | |
| 794 | + long length); | |
| 795 | + static native void copyToIntArray(long srcAddr, Object dst, long dstPos, | |
| 796 | + long length); | |
| 797 | + | |
| 798 | + static native void copyFromLongArray(Object src, long srcPos, long dstAddr, | |
| 799 | + long length); | |
| 800 | + static native void copyToLongArray(long srcAddr, Object dst, long dstPos, | |
| 801 | + long length); | |
| 802 | + | |
| 803 | +} | |
Binary file not shown.
| @@ -0,0 +1,555 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio; | |
| 27 | + | |
| 28 | + | |
| 29 | +/** | |
| 30 | + * A container for data of a specific primitive type. | |
| 31 | + * | |
| 32 | + * <p> A buffer is a linear, finite sequence of elements of a specific | |
| 33 | + * primitive type. Aside from its content, the essential properties of a | |
| 34 | + * buffer are its capacity, limit, and position: </p> | |
| 35 | + * | |
| 36 | + * <blockquote> | |
| 37 | + * | |
| 38 | + * <p> A buffer's <i>capacity</i> is the number of elements it contains. The | |
| 39 | + * capacity of a buffer is never negative and never changes. </p> | |
| 40 | + * | |
| 41 | + * <p> A buffer's <i>limit</i> is the index of the first element that should | |
| 42 | + * not be read or written. A buffer's limit is never negative and is never | |
| 43 | + * greater than its capacity. </p> | |
| 44 | + * | |
| 45 | + * <p> A buffer's <i>position</i> is the index of the next element to be | |
| 46 | + * read or written. A buffer's position is never negative and is never | |
| 47 | + * greater than its limit. </p> | |
| 48 | + * | |
| 49 | + * </blockquote> | |
| 50 | + * | |
| 51 | + * <p> There is one subclass of this class for each non-boolean primitive type. | |
| 52 | + * | |
| 53 | + * | |
| 54 | + * <h4> Transferring data </h4> | |
| 55 | + * | |
| 56 | + * <p> Each subclass of this class defines two categories of <i>get</i> and | |
| 57 | + * <i>put</i> operations: </p> | |
| 58 | + * | |
| 59 | + * <blockquote> | |
| 60 | + * | |
| 61 | + * <p> <i>Relative</i> operations read or write one or more elements starting | |
| 62 | + * at the current position and then increment the position by the number of | |
| 63 | + * elements transferred. If the requested transfer exceeds the limit then a | |
| 64 | + * relative <i>get</i> operation throws a {@link BufferUnderflowException} | |
| 65 | + * and a relative <i>put</i> operation throws a {@link | |
| 66 | + * BufferOverflowException}; in either case, no data is transferred. </p> | |
| 67 | + * | |
| 68 | + * <p> <i>Absolute</i> operations take an explicit element index and do not | |
| 69 | + * affect the position. Absolute <i>get</i> and <i>put</i> operations throw | |
| 70 | + * an {@link IndexOutOfBoundsException} if the index argument exceeds the | |
| 71 | + * limit. </p> | |
| 72 | + * | |
| 73 | + * </blockquote> | |
| 74 | + * | |
| 75 | + * <p> Data may also, of course, be transferred in to or out of a buffer by the | |
| 76 | + * I/O operations of an appropriate channel, which are always relative to the | |
| 77 | + * current position. | |
| 78 | + * | |
| 79 | + * | |
| 80 | + * <h4> Marking and resetting </h4> | |
| 81 | + * | |
| 82 | + * <p> A buffer's <i>mark</i> is the index to which its position will be reset | |
| 83 | + * when the {@link #reset reset} method is invoked. The mark is not always | |
| 84 | + * defined, but when it is defined it is never negative and is never greater | |
| 85 | + * than the position. If the mark is defined then it is discarded when the | |
| 86 | + * position or the limit is adjusted to a value smaller than the mark. If the | |
| 87 | + * mark is not defined then invoking the {@link #reset reset} method causes an | |
| 88 | + * {@link InvalidMarkException} to be thrown. | |
| 89 | + * | |
| 90 | + * | |
| 91 | + * <h4> Invariants </h4> | |
| 92 | + * | |
| 93 | + * <p> The following invariant holds for the mark, position, limit, and | |
| 94 | + * capacity values: | |
| 95 | + * | |
| 96 | + * <blockquote> | |
| 97 | + * <tt>0</tt> <tt><=</tt> | |
| 98 | + * <i>mark</i> <tt><=</tt> | |
| 99 | + * <i>position</i> <tt><=</tt> | |
| 100 | + * <i>limit</i> <tt><=</tt> | |
| 101 | + * <i>capacity</i> | |
| 102 | + * </blockquote> | |
| 103 | + * | |
| 104 | + * <p> A newly-created buffer always has a position of zero and a mark that is | |
| 105 | + * undefined. The initial limit may be zero, or it may be some other value | |
| 106 | + * that depends upon the type of the buffer and the manner in which it is | |
| 107 | + * constructed. Each element of a newly-allocated buffer is initialized | |
| 108 | + * to zero. | |
| 109 | + * | |
| 110 | + * | |
| 111 | + * <h4> Clearing, flipping, and rewinding </h4> | |
| 112 | + * | |
| 113 | + * <p> In addition to methods for accessing the position, limit, and capacity | |
| 114 | + * values and for marking and resetting, this class also defines the following | |
| 115 | + * operations upon buffers: | |
| 116 | + * | |
| 117 | + * <ul> | |
| 118 | + * | |
| 119 | + * <li><p> {@link #clear} makes a buffer ready for a new sequence of | |
| 120 | + * channel-read or relative <i>put</i> operations: It sets the limit to the | |
| 121 | + * capacity and the position to zero. </p></li> | |
| 122 | + * | |
| 123 | + * <li><p> {@link #flip} makes a buffer ready for a new sequence of | |
| 124 | + * channel-write or relative <i>get</i> operations: It sets the limit to the | |
| 125 | + * current position and then sets the position to zero. </p></li> | |
| 126 | + * | |
| 127 | + * <li><p> {@link #rewind} makes a buffer ready for re-reading the data that | |
| 128 | + * it already contains: It leaves the limit unchanged and sets the position | |
| 129 | + * to zero. </p></li> | |
| 130 | + * | |
| 131 | + * </ul> | |
| 132 | + * | |
| 133 | + * | |
| 134 | + * <h4> Read-only buffers </h4> | |
| 135 | + * | |
| 136 | + * <p> Every buffer is readable, but not every buffer is writable. The | |
| 137 | + * mutation methods of each buffer class are specified as <i>optional | |
| 138 | + * operations</i> that will throw a {@link ReadOnlyBufferException} when | |
| 139 | + * invoked upon a read-only buffer. A read-only buffer does not allow its | |
| 140 | + * content to be changed, but its mark, position, and limit values are mutable. | |
| 141 | + * Whether or not a buffer is read-only may be determined by invoking its | |
| 142 | + * {@link #isReadOnly isReadOnly} method. | |
| 143 | + * | |
| 144 | + * | |
| 145 | + * <h4> Thread safety </h4> | |
| 146 | + * | |
| 147 | + * <p> Buffers are not safe for use by multiple concurrent threads. If a | |
| 148 | + * buffer is to be used by more than one thread then access to the buffer | |
| 149 | + * should be controlled by appropriate synchronization. | |
| 150 | + * | |
| 151 | + * | |
| 152 | + * <h4> Invocation chaining </h4> | |
| 153 | + * | |
| 154 | + * <p> Methods in this class that do not otherwise have a value to return are | |
| 155 | + * specified to return the buffer upon which they are invoked. This allows | |
| 156 | + * method invocations to be chained; for example, the sequence of statements | |
| 157 | + * | |
| 158 | + * <blockquote><pre> | |
| 159 | + * b.flip(); | |
| 160 | + * b.position(23); | |
| 161 | + * b.limit(42);</pre></blockquote> | |
| 162 | + * | |
| 163 | + * can be replaced by the single, more compact statement | |
| 164 | + * | |
| 165 | + * <blockquote><pre> | |
| 166 | + * b.flip().position(23).limit(42);</pre></blockquote> | |
| 167 | + * | |
| 168 | + * | |
| 169 | + * @author Mark Reinhold | |
| 170 | + * @author JSR-51 Expert Group | |
| 171 | + * @since 1.4 | |
| 172 | + */ | |
| 173 | + | |
| 174 | +public abstract class Buffer { | |
| 175 | + | |
| 176 | + // Invariants: mark <= position <= limit <= capacity | |
| 177 | + private int mark = -1; | |
| 178 | + private int position = 0; | |
| 179 | + private int limit; | |
| 180 | + private int capacity; | |
| 181 | + | |
| 182 | + // Used only by direct buffers | |
| 183 | + // NOTE: hoisted here for speed in JNI GetDirectBufferAddress | |
| 184 | + long address; | |
| 185 | + | |
| 186 | + // Creates a new buffer with the given mark, position, limit, and capacity, | |
| 187 | + // after checking invariants. | |
| 188 | + // | |
| 189 | + Buffer(int mark, int pos, int lim, int cap) { // package-private | |
| 190 | + if (cap < 0) | |
| 191 | + throw new IllegalArgumentException("Negative capacity: " + cap); | |
| 192 | + this.capacity = cap; | |
| 193 | + limit(lim); | |
| 194 | + position(pos); | |
| 195 | + if (mark >= 0) { | |
| 196 | + if (mark > pos) | |
| 197 | + throw new IllegalArgumentException("mark > position: (" | |
| 198 | + + mark + " > " + pos + ")"); | |
| 199 | + this.mark = mark; | |
| 200 | + } | |
| 201 | + } | |
| 202 | + | |
| 203 | + /** | |
| 204 | + * Returns this buffer's capacity. </p> | |
| 205 | + * | |
| 206 | + * @return The capacity of this buffer | |
| 207 | + */ | |
| 208 | + public final int capacity() { | |
| 209 | + return capacity; | |
| 210 | + } | |
| 211 | + | |
| 212 | + /** | |
| 213 | + * Returns this buffer's position. </p> | |
| 214 | + * | |
| 215 | + * @return The position of this buffer | |
| 216 | + */ | |
| 217 | + public final int position() { | |
| 218 | + return position; | |
| 219 | + } | |
| 220 | + | |
| 221 | + /** | |
| 222 | + * Sets this buffer's position. If the mark is defined and larger than the | |
| 223 | + * new position then it is discarded. </p> | |
| 224 | + * | |
| 225 | + * @param newPosition | |
| 226 | + * The new position value; must be non-negative | |
| 227 | + * and no larger than the current limit | |
| 228 | + * | |
| 229 | + * @return This buffer | |
| 230 | + * | |
| 231 | + * @throws IllegalArgumentException | |
| 232 | + * If the preconditions on <tt>newPosition</tt> do not hold | |
| 233 | + */ | |
| 234 | + public final Buffer position(int newPosition) { | |
| 235 | + if ((newPosition > limit) || (newPosition < 0)) | |
| 236 | + throw new IllegalArgumentException(); | |
| 237 | + position = newPosition; | |
| 238 | + if (mark > position) mark = -1; | |
| 239 | + return this; | |
| 240 | + } | |
| 241 | + | |
| 242 | + /** | |
| 243 | + * Returns this buffer's limit. </p> | |
| 244 | + * | |
| 245 | + * @return The limit of this buffer | |
| 246 | + */ | |
| 247 | + public final int limit() { | |
| 248 | + return limit; | |
| 249 | + } | |
| 250 | + | |
| 251 | + /** | |
| 252 | + * Sets this buffer's limit. If the position is larger than the new limit | |
| 253 | + * then it is set to the new limit. If the mark is defined and larger than | |
| 254 | + * the new limit then it is discarded. </p> | |
| 255 | + * | |
| 256 | + * @param newLimit | |
| 257 | + * The new limit value; must be non-negative | |
| 258 | + * and no larger than this buffer's capacity | |
| 259 | + * | |
| 260 | + * @return This buffer | |
| 261 | + * | |
| 262 | + * @throws IllegalArgumentException | |
| 263 | + * If the preconditions on <tt>newLimit</tt> do not hold | |
| 264 | + */ | |
| 265 | + public final Buffer limit(int newLimit) { | |
| 266 | + if ((newLimit > capacity) || (newLimit < 0)) | |
| 267 | + throw new IllegalArgumentException(); | |
| 268 | + limit = newLimit; | |
| 269 | + if (position > limit) position = limit; | |
| 270 | + if (mark > limit) mark = -1; | |
| 271 | + return this; | |
| 272 | + } | |
| 273 | + | |
| 274 | + /** | |
| 275 | + * Sets this buffer's mark at its position. </p> | |
| 276 | + * | |
| 277 | + * @return This buffer | |
| 278 | + */ | |
| 279 | + public final Buffer mark() { | |
| 280 | + mark = position; | |
| 281 | + return this; | |
| 282 | + } | |
| 283 | + | |
| 284 | + /** | |
| 285 | + * Resets this buffer's position to the previously-marked position. | |
| 286 | + * | |
| 287 | + * <p> Invoking this method neither changes nor discards the mark's | |
| 288 | + * value. </p> | |
| 289 | + * | |
| 290 | + * @return This buffer | |
| 291 | + * | |
| 292 | + * @throws InvalidMarkException | |
| 293 | + * If the mark has not been set | |
| 294 | + */ | |
| 295 | + public final Buffer reset() { | |
| 296 | + int m = mark; | |
| 297 | + if (m < 0) | |
| 298 | + throw new InvalidMarkException(); | |
| 299 | + position = m; | |
| 300 | + return this; | |
| 301 | + } | |
| 302 | + | |
| 303 | + /** | |
| 304 | + * Clears this buffer. The position is set to zero, the limit is set to | |
| 305 | + * the capacity, and the mark is discarded. | |
| 306 | + * | |
| 307 | + * <p> Invoke this method before using a sequence of channel-read or | |
| 308 | + * <i>put</i> operations to fill this buffer. For example: | |
| 309 | + * | |
| 310 | + * <blockquote><pre> | |
| 311 | + * buf.clear(); // Prepare buffer for reading | |
| 312 | + * in.read(buf); // Read data</pre></blockquote> | |
| 313 | + * | |
| 314 | + * <p> This method does not actually erase the data in the buffer, but it | |
| 315 | + * is named as if it did because it will most often be used in situations | |
| 316 | + * in which that might as well be the case. </p> | |
| 317 | + * | |
| 318 | + * @return This buffer | |
| 319 | + */ | |
| 320 | + public final Buffer clear() { | |
| 321 | + position = 0; | |
| 322 | + limit = capacity; | |
| 323 | + mark = -1; | |
| 324 | + return this; | |
| 325 | + } | |
| 326 | + | |
| 327 | + /** | |
| 328 | + * Flips this buffer. The limit is set to the current position and then | |
| 329 | + * the position is set to zero. If the mark is defined then it is | |
| 330 | + * discarded. | |
| 331 | + * | |
| 332 | + * <p> After a sequence of channel-read or <i>put</i> operations, invoke | |
| 333 | + * this method to prepare for a sequence of channel-write or relative | |
| 334 | + * <i>get</i> operations. For example: | |
| 335 | + * | |
| 336 | + * <blockquote><pre> | |
| 337 | + * buf.put(magic); // Prepend header | |
| 338 | + * in.read(buf); // Read data into rest of buffer | |
| 339 | + * buf.flip(); // Flip buffer | |
| 340 | + * out.write(buf); // Write header + data to channel</pre></blockquote> | |
| 341 | + * | |
| 342 | + * <p> This method is often used in conjunction with the {@link | |
| 343 | + * java.nio.ByteBuffer#compact compact} method when transferring data from | |
| 344 | + * one place to another. </p> | |
| 345 | + * | |
| 346 | + * @return This buffer | |
| 347 | + */ | |
| 348 | + public final Buffer flip() { | |
| 349 | + limit = position; | |
| 350 | + position = 0; | |
| 351 | + mark = -1; | |
| 352 | + return this; | |
| 353 | + } | |
| 354 | + | |
| 355 | + /** | |
| 356 | + * Rewinds this buffer. The position is set to zero and the mark is | |
| 357 | + * discarded. | |
| 358 | + * | |
| 359 | + * <p> Invoke this method before a sequence of channel-write or <i>get</i> | |
| 360 | + * operations, assuming that the limit has already been set | |
| 361 | + * appropriately. For example: | |
| 362 | + * | |
| 363 | + * <blockquote><pre> | |
| 364 | + * out.write(buf); // Write remaining data | |
| 365 | + * buf.rewind(); // Rewind buffer | |
| 366 | + * buf.get(array); // Copy data into array</pre></blockquote> | |
| 367 | + * | |
| 368 | + * @return This buffer | |
| 369 | + */ | |
| 370 | + public final Buffer rewind() { | |
| 371 | + position = 0; | |
| 372 | + mark = -1; | |
| 373 | + return this; | |
| 374 | + } | |
| 375 | + | |
| 376 | + /** | |
| 377 | + * Returns the number of elements between the current position and the | |
| 378 | + * limit. </p> | |
| 379 | + * | |
| 380 | + * @return The number of elements remaining in this buffer | |
| 381 | + */ | |
| 382 | + public final int remaining() { | |
| 383 | + return limit - position; | |
| 384 | + } | |
| 385 | + | |
| 386 | + /** | |
| 387 | + * Tells whether there are any elements between the current position and | |
| 388 | + * the limit. </p> | |
| 389 | + * | |
| 390 | + * @return <tt>true</tt> if, and only if, there is at least one element | |
| 391 | + * remaining in this buffer | |
| 392 | + */ | |
| 393 | + public final boolean hasRemaining() { | |
| 394 | + return position < limit; | |
| 395 | + } | |
| 396 | + | |
| 397 | + /** | |
| 398 | + * Tells whether or not this buffer is read-only. </p> | |
| 399 | + * | |
| 400 | + * @return <tt>true</tt> if, and only if, this buffer is read-only | |
| 401 | + */ | |
| 402 | + public abstract boolean isReadOnly(); | |
| 403 | + | |
| 404 | + /** | |
| 405 | + * Tells whether or not this buffer is backed by an accessible | |
| 406 | + * array. | |
| 407 | + * | |
| 408 | + * <p> If this method returns <tt>true</tt> then the {@link #array() array} | |
| 409 | + * and {@link #arrayOffset() arrayOffset} methods may safely be invoked. | |
| 410 | + * </p> | |
| 411 | + * | |
| 412 | + * @return <tt>true</tt> if, and only if, this buffer | |
| 413 | + * is backed by an array and is not read-only | |
| 414 | + * | |
| 415 | + * @since 1.6 | |
| 416 | + */ | |
| 417 | + public abstract boolean hasArray(); | |
| 418 | + | |
| 419 | + /** | |
| 420 | + * Returns the array that backs this | |
| 421 | + * buffer <i>(optional operation)</i>. | |
| 422 | + * | |
| 423 | + * <p> This method is intended to allow array-backed buffers to be | |
| 424 | + * passed to native code more efficiently. Concrete subclasses | |
| 425 | + * provide more strongly-typed return values for this method. | |
| 426 | + * | |
| 427 | + * <p> Modifications to this buffer's content will cause the returned | |
| 428 | + * array's content to be modified, and vice versa. | |
| 429 | + * | |
| 430 | + * <p> Invoke the {@link #hasArray hasArray} method before invoking this | |
| 431 | + * method in order to ensure that this buffer has an accessible backing | |
| 432 | + * array. </p> | |
| 433 | + * | |
| 434 | + * @return The array that backs this buffer | |
| 435 | + * | |
| 436 | + * @throws ReadOnlyBufferException | |
| 437 | + * If this buffer is backed by an array but is read-only | |
| 438 | + * | |
| 439 | + * @throws UnsupportedOperationException | |
| 440 | + * If this buffer is not backed by an accessible array | |
| 441 | + * | |
| 442 | + * @since 1.6 | |
| 443 | + */ | |
| 444 | + public abstract Object array(); | |
| 445 | + | |
| 446 | + /** | |
| 447 | + * Returns the offset within this buffer's backing array of the first | |
| 448 | + * element of the buffer <i>(optional operation)</i>. | |
| 449 | + * | |
| 450 | + * <p> If this buffer is backed by an array then buffer position <i>p</i> | |
| 451 | + * corresponds to array index <i>p</i> + <tt>arrayOffset()</tt>. | |
| 452 | + * | |
| 453 | + * <p> Invoke the {@link #hasArray hasArray} method before invoking this | |
| 454 | + * method in order to ensure that this buffer has an accessible backing | |
| 455 | + * array. </p> | |
| 456 | + * | |
| 457 | + * @return The offset within this buffer's array | |
| 458 | + * of the first element of the buffer | |
| 459 | + * | |
| 460 | + * @throws ReadOnlyBufferException | |
| 461 | + * If this buffer is backed by an array but is read-only | |
| 462 | + * | |
| 463 | + * @throws UnsupportedOperationException | |
| 464 | + * If this buffer is not backed by an accessible array | |
| 465 | + * | |
| 466 | + * @since 1.6 | |
| 467 | + */ | |
| 468 | + public abstract int arrayOffset(); | |
| 469 | + | |
| 470 | + /** | |
| 471 | + * Tells whether or not this buffer is | |
| 472 | + * <a href="ByteBuffer.html#direct"><i>direct</i></a>. </p> | |
| 473 | + * | |
| 474 | + * @return <tt>true</tt> if, and only if, this buffer is direct | |
| 475 | + * | |
| 476 | + * @since 1.6 | |
| 477 | + */ | |
| 478 | + public abstract boolean isDirect(); | |
| 479 | + | |
| 480 | + | |
| 481 | + // -- Package-private methods for bounds checking, etc. -- | |
| 482 | + | |
| 483 | + /** | |
| 484 | + * Checks the current position against the limit, throwing a {@link | |
| 485 | + * BufferUnderflowException} if it is not smaller than the limit, and then | |
| 486 | + * increments the position. </p> | |
| 487 | + * | |
| 488 | + * @return The current position value, before it is incremented | |
| 489 | + */ | |
| 490 | + final int nextGetIndex() { // package-private | |
| 491 | + if (position >= limit) | |
| 492 | + throw new BufferUnderflowException(); | |
| 493 | + return position++; | |
| 494 | + } | |
| 495 | + | |
| 496 | + final int nextGetIndex(int nb) { // package-private | |
| 497 | + if (limit - position < nb) | |
| 498 | + throw new BufferUnderflowException(); | |
| 499 | + int p = position; | |
| 500 | + position += nb; | |
| 501 | + return p; | |
| 502 | + } | |
| 503 | + | |
| 504 | + /** | |
| 505 | + * Checks the current position against the limit, throwing a {@link | |
| 506 | + * BufferOverflowException} if it is not smaller than the limit, and then | |
| 507 | + * increments the position. </p> | |
| 508 | + * | |
| 509 | + * @return The current position value, before it is incremented | |
| 510 | + */ | |
| 511 | + final int nextPutIndex() { // package-private | |
| 512 | + if (position >= limit) | |
| 513 | + throw new BufferOverflowException(); | |
| 514 | + return position++; | |
| 515 | + } | |
| 516 | + | |
| 517 | + final int nextPutIndex(int nb) { // package-private | |
| 518 | + if (limit - position < nb) | |
| 519 | + throw new BufferOverflowException(); | |
| 520 | + int p = position; | |
| 521 | + position += nb; | |
| 522 | + return p; | |
| 523 | + } | |
| 524 | + | |
| 525 | + /** | |
| 526 | + * Checks the given index against the limit, throwing an {@link | |
| 527 | + * IndexOutOfBoundsException} if it is not smaller than the limit | |
| 528 | + * or is smaller than zero. | |
| 529 | + */ | |
| 530 | + final int checkIndex(int i) { // package-private | |
| 531 | + if ((i < 0) || (i >= limit)) | |
| 532 | + throw new IndexOutOfBoundsException(); | |
| 533 | + return i; | |
| 534 | + } | |
| 535 | + | |
| 536 | + final int checkIndex(int i, int nb) { // package-private | |
| 537 | + if ((i < 0) || (nb > limit - i)) | |
| 538 | + throw new IndexOutOfBoundsException(); | |
| 539 | + return i; | |
| 540 | + } | |
| 541 | + | |
| 542 | + final int markValue() { // package-private | |
| 543 | + return mark; | |
| 544 | + } | |
| 545 | + | |
| 546 | + final void discardMark() { // package-private | |
| 547 | + mark = -1; | |
| 548 | + } | |
| 549 | + | |
| 550 | + static void checkBounds(int off, int len, int size) { // package-private | |
| 551 | + if ((off | len | (off + len) | (size - (off + len))) < 0) | |
| 552 | + throw new IndexOutOfBoundsException(); | |
| 553 | + } | |
| 554 | + | |
| 555 | +} | |
| @@ -0,0 +1,219 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +#warn This file is preprocessed before being compiled | |
| 27 | + | |
| 28 | +package java.nio; | |
| 29 | + | |
| 30 | + | |
| 31 | +class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private | |
| 32 | + extends {#if[ro]?ByteBufferAs}$Type$Buffer{#if[ro]?$BO$} | |
| 33 | +{ | |
| 34 | + | |
| 35 | +#if[rw] | |
| 36 | + | |
| 37 | + protected final ByteBuffer bb; | |
| 38 | + protected final int offset; | |
| 39 | + | |
| 40 | +#end[rw] | |
| 41 | + | |
| 42 | + ByteBufferAs$Type$Buffer$RW$$BO$(ByteBuffer bb) { // package-private | |
| 43 | +#if[rw] | |
| 44 | + super(-1, 0, | |
| 45 | + bb.remaining() >> $LG_BYTES_PER_VALUE$, | |
| 46 | + bb.remaining() >> $LG_BYTES_PER_VALUE$); | |
| 47 | + this.bb = bb; | |
| 48 | + // enforce limit == capacity | |
| 49 | + int cap = this.capacity(); | |
| 50 | + this.limit(cap); | |
| 51 | + int pos = this.position(); | |
| 52 | + assert (pos <= cap); | |
| 53 | + offset = pos; | |
| 54 | +#else[rw] | |
| 55 | + super(bb); | |
| 56 | +#end[rw] | |
| 57 | + } | |
| 58 | + | |
| 59 | + ByteBufferAs$Type$Buffer$RW$$BO$(ByteBuffer bb, | |
| 60 | + int mark, int pos, int lim, int cap, | |
| 61 | + int off) | |
| 62 | + { | |
| 63 | +#if[rw] | |
| 64 | + super(mark, pos, lim, cap); | |
| 65 | + this.bb = bb; | |
| 66 | + offset = off; | |
| 67 | +#else[rw] | |
| 68 | + super(bb, mark, pos, lim, cap, off); | |
| 69 | +#end[rw] | |
| 70 | + } | |
| 71 | + | |
| 72 | + public $Type$Buffer slice() { | |
| 73 | + int pos = this.position(); | |
| 74 | + int lim = this.limit(); | |
| 75 | + assert (pos <= lim); | |
| 76 | + int rem = (pos <= lim ? lim - pos : 0); | |
| 77 | + int off = (pos << $LG_BYTES_PER_VALUE$) + offset; | |
| 78 | + assert (off >= 0); | |
| 79 | + return new ByteBufferAs$Type$Buffer$RW$$BO$(bb, -1, 0, rem, rem, off); | |
| 80 | + } | |
| 81 | + | |
| 82 | + public $Type$Buffer duplicate() { | |
| 83 | + return new ByteBufferAs$Type$Buffer$RW$$BO$(bb, | |
| 84 | + this.markValue(), | |
| 85 | + this.position(), | |
| 86 | + this.limit(), | |
| 87 | + this.capacity(), | |
| 88 | + offset); | |
| 89 | + } | |
| 90 | + | |
| 91 | + public $Type$Buffer asReadOnlyBuffer() { | |
| 92 | +#if[rw] | |
| 93 | + return new ByteBufferAs$Type$BufferR$BO$(bb, | |
| 94 | + this.markValue(), | |
| 95 | + this.position(), | |
| 96 | + this.limit(), | |
| 97 | + this.capacity(), | |
| 98 | + offset); | |
| 99 | +#else[rw] | |
| 100 | + return duplicate(); | |
| 101 | +#end[rw] | |
| 102 | + } | |
| 103 | + | |
| 104 | +#if[rw] | |
| 105 | + | |
| 106 | + protected int ix(int i) { | |
| 107 | + return (i << $LG_BYTES_PER_VALUE$) + offset; | |
| 108 | + } | |
| 109 | + | |
| 110 | + public $type$ get() { | |
| 111 | + return Bits.get$Type$$BO$(bb, ix(nextGetIndex())); | |
| 112 | + } | |
| 113 | + | |
| 114 | + public $type$ get(int i) { | |
| 115 | + return Bits.get$Type$$BO$(bb, ix(checkIndex(i))); | |
| 116 | + } | |
| 117 | + | |
| 118 | +#end[rw] | |
| 119 | + | |
| 120 | + public $Type$Buffer put($type$ x) { | |
| 121 | +#if[rw] | |
| 122 | + Bits.put$Type$$BO$(bb, ix(nextPutIndex()), x); | |
| 123 | + return this; | |
| 124 | +#else[rw] | |
| 125 | + throw new ReadOnlyBufferException(); | |
| 126 | +#end[rw] | |
| 127 | + } | |
| 128 | + | |
| 129 | + public $Type$Buffer put(int i, $type$ x) { | |
| 130 | +#if[rw] | |
| 131 | + Bits.put$Type$$BO$(bb, ix(checkIndex(i)), x); | |
| 132 | + return this; | |
| 133 | +#else[rw] | |
| 134 | + throw new ReadOnlyBufferException(); | |
| 135 | +#end[rw] | |
| 136 | + } | |
| 137 | + | |
| 138 | + public $Type$Buffer compact() { | |
| 139 | +#if[rw] | |
| 140 | + int pos = position(); | |
| 141 | + int lim = limit(); | |
| 142 | + assert (pos <= lim); | |
| 143 | + int rem = (pos <= lim ? lim - pos : 0); | |
| 144 | + | |
| 145 | + ByteBuffer db = bb.duplicate(); | |
| 146 | + db.limit(ix(lim)); | |
| 147 | + db.position(ix(0)); | |
| 148 | + ByteBuffer sb = db.slice(); | |
| 149 | + sb.position(pos << $LG_BYTES_PER_VALUE$); | |
| 150 | + sb.compact(); | |
| 151 | + position(rem); | |
| 152 | + limit(capacity()); | |
| 153 | + discardMark(); | |
| 154 | + return this; | |
| 155 | +#else[rw] | |
| 156 | + throw new ReadOnlyBufferException(); | |
| 157 | +#end[rw] | |
| 158 | + } | |
| 159 | + | |
| 160 | + public boolean isDirect() { | |
| 161 | + return bb.isDirect(); | |
| 162 | + } | |
| 163 | + | |
| 164 | + public boolean isReadOnly() { | |
| 165 | + return {#if[rw]?false:true}; | |
| 166 | + } | |
| 167 | + | |
| 168 | +#if[char] | |
| 169 | + | |
| 170 | + public String toString(int start, int end) { | |
| 171 | + if ((end > limit()) || (start > end)) | |
| 172 | + throw new IndexOutOfBoundsException(); | |
| 173 | + try { | |
| 174 | + int len = end - start; | |
| 175 | + char[] ca = new char[len]; | |
| 176 | + CharBuffer cb = CharBuffer.wrap(ca); | |
| 177 | + CharBuffer db = this.duplicate(); | |
| 178 | + db.position(start); | |
| 179 | + db.limit(end); | |
| 180 | + cb.put(db); | |
| 181 | + return new String(ca); | |
| 182 | + } catch (StringIndexOutOfBoundsException x) { | |
| 183 | + throw new IndexOutOfBoundsException(); | |
| 184 | + } | |
| 185 | + } | |
| 186 | + | |
| 187 | + | |
| 188 | + // --- Methods to support CharSequence --- | |
| 189 | + | |
| 190 | + public CharBuffer subSequence(int start, int end) { | |
| 191 | + int pos = position(); | |
| 192 | + int lim = limit(); | |
| 193 | + assert (pos <= lim); | |
| 194 | + pos = (pos <= lim ? pos : lim); | |
| 195 | + int len = lim - pos; | |
| 196 | + | |
| 197 | + if ((start < 0) || (end > len) || (start > end)) | |
| 198 | + throw new IndexOutOfBoundsException(); | |
| 199 | + return new ByteBufferAsCharBuffer$RW$$BO$(bb, | |
| 200 | + -1, | |
| 201 | + pos + start, | |
| 202 | + pos + end, | |
| 203 | + capacity(), | |
| 204 | + offset); | |
| 205 | + } | |
| 206 | + | |
| 207 | +#end[char] | |
| 208 | + | |
| 209 | + | |
| 210 | + public ByteOrder order() { | |
| 211 | +#if[boB] | |
| 212 | + return ByteOrder.BIG_ENDIAN; | |
| 213 | +#end[boB] | |
| 214 | +#if[boL] | |
| 215 | + return ByteOrder.LITTLE_ENDIAN; | |
| 216 | +#end[boL] | |
| 217 | + } | |
| 218 | + | |
| 219 | +} | |
Binary file not shown.
| @@ -0,0 +1,89 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio; | |
| 27 | + | |
| 28 | + | |
| 29 | +/** | |
| 30 | + * A typesafe enumeration for byte orders. | |
| 31 | + * | |
| 32 | + * @author Mark Reinhold | |
| 33 | + * @author JSR-51 Expert Group | |
| 34 | + * @since 1.4 | |
| 35 | + */ | |
| 36 | + | |
| 37 | +public final class ByteOrder { | |
| 38 | + | |
| 39 | + private String name; | |
| 40 | + | |
| 41 | + private ByteOrder(String name) { | |
| 42 | + this.name = name; | |
| 43 | + } | |
| 44 | + | |
| 45 | + /** | |
| 46 | + * Constant denoting big-endian byte order. In this order, the bytes of a | |
| 47 | + * multibyte value are ordered from most significant to least significant. | |
| 48 | + * </p> | |
| 49 | + */ | |
| 50 | + public static final ByteOrder BIG_ENDIAN | |
| 51 | + = new ByteOrder("BIG_ENDIAN"); | |
| 52 | + | |
| 53 | + /** | |
| 54 | + * Constant denoting little-endian byte order. In this order, the bytes of | |
| 55 | + * a multibyte value are ordered from least significant to most | |
| 56 | + * significant. </p> | |
| 57 | + */ | |
| 58 | + public static final ByteOrder LITTLE_ENDIAN | |
| 59 | + = new ByteOrder("LITTLE_ENDIAN"); | |
| 60 | + | |
| 61 | + /** | |
| 62 | + * Retrieves the native byte order of the underlying platform. | |
| 63 | + * | |
| 64 | + * <p> This method is defined so that performance-sensitive Java code can | |
| 65 | + * allocate direct buffers with the same byte order as the hardware. | |
| 66 | + * Native code libraries are often more efficient when such buffers are | |
| 67 | + * used. </p> | |
| 68 | + * | |
| 69 | + * @return The native byte order of the hardware upon which this Java | |
| 70 | + * virtual machine is running | |
| 71 | + */ | |
| 72 | + public static ByteOrder nativeOrder() { | |
| 73 | + return Bits.byteOrder(); | |
| 74 | + } | |
| 75 | + | |
| 76 | + /** | |
| 77 | + * Constructs a string describing this object. | |
| 78 | + * | |
| 79 | + * <p> This method returns the string <tt>"BIG_ENDIAN"</tt> for {@link | |
| 80 | + * #BIG_ENDIAN} and <tt>"LITTLE_ENDIAN"</tt> for {@link #LITTLE_ENDIAN}. | |
| 81 | + * </p> | |
| 82 | + * | |
| 83 | + * @return The specified string | |
| 84 | + */ | |
| 85 | + public String toString() { | |
| 86 | + return name; | |
| 87 | + } | |
| 88 | + | |
| 89 | +} | |
| @@ -0,0 +1,124 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +#warn This file is preprocessed before being compiled | |
| 27 | + | |
| 28 | +class XXX { | |
| 29 | + | |
| 30 | +#begin | |
| 31 | + | |
| 32 | +#if[rw] | |
| 33 | + | |
| 34 | + private $type$ get$Type$(long a) { | |
| 35 | + if (unaligned) { | |
| 36 | + $memtype$ x = unsafe.get$Memtype$(a); | |
| 37 | + return $fromBits$(nativeByteOrder ? x : Bits.swap(x)); | |
| 38 | + } | |
| 39 | + return Bits.get$Type$(a, bigEndian); | |
| 40 | + } | |
| 41 | + | |
| 42 | + public $type$ get$Type$() { | |
| 43 | + return get$Type$(ix(nextGetIndex($BYTES_PER_VALUE$))); | |
| 44 | + } | |
| 45 | + | |
| 46 | + public $type$ get$Type$(int i) { | |
| 47 | + return get$Type$(ix(checkIndex(i, $BYTES_PER_VALUE$))); | |
| 48 | + } | |
| 49 | + | |
| 50 | +#end[rw] | |
| 51 | + | |
| 52 | + private ByteBuffer put$Type$(long a, $type$ x) { | |
| 53 | +#if[rw] | |
| 54 | + if (unaligned) { | |
| 55 | + $memtype$ y = $toBits$(x); | |
| 56 | + unsafe.put$Memtype$(a, (nativeByteOrder ? y : Bits.swap(y))); | |
| 57 | + } else { | |
| 58 | + Bits.put$Type$(a, x, bigEndian); | |
| 59 | + } | |
| 60 | + return this; | |
| 61 | +#else[rw] | |
| 62 | + throw new ReadOnlyBufferException(); | |
| 63 | +#end[rw] | |
| 64 | + } | |
| 65 | + | |
| 66 | + public ByteBuffer put$Type$($type$ x) { | |
| 67 | +#if[rw] | |
| 68 | + put$Type$(ix(nextPutIndex($BYTES_PER_VALUE$)), x); | |
| 69 | + return this; | |
| 70 | +#else[rw] | |
| 71 | + throw new ReadOnlyBufferException(); | |
| 72 | +#end[rw] | |
| 73 | + } | |
| 74 | + | |
| 75 | + public ByteBuffer put$Type$(int i, $type$ x) { | |
| 76 | +#if[rw] | |
| 77 | + put$Type$(ix(checkIndex(i, $BYTES_PER_VALUE$)), x); | |
| 78 | + return this; | |
| 79 | +#else[rw] | |
| 80 | + throw new ReadOnlyBufferException(); | |
| 81 | +#end[rw] | |
| 82 | + } | |
| 83 | + | |
| 84 | + public $Type$Buffer as$Type$Buffer() { | |
| 85 | + int off = this.position(); | |
| 86 | + int lim = this.limit(); | |
| 87 | + assert (off <= lim); | |
| 88 | + int rem = (off <= lim ? lim - off : 0); | |
| 89 | + | |
| 90 | + int size = rem >> $LG_BYTES_PER_VALUE$; | |
| 91 | + if (!unaligned && ((address + off) % $BYTES_PER_VALUE$ != 0)) { | |
| 92 | + return (bigEndian | |
| 93 | + ? ($Type$Buffer)(new ByteBufferAs$Type$Buffer$RW$B(this, | |
| 94 | + -1, | |
| 95 | + 0, | |
| 96 | + size, | |
| 97 | + size, | |
| 98 | + off)) | |
| 99 | + : ($Type$Buffer)(new ByteBufferAs$Type$Buffer$RW$L(this, | |
| 100 | + -1, | |
| 101 | + 0, | |
| 102 | + size, | |
| 103 | + size, | |
| 104 | + off))); | |
| 105 | + } else { | |
| 106 | + return (nativeByteOrder | |
| 107 | + ? ($Type$Buffer)(new Direct$Type$Buffer$RW$U(this, | |
| 108 | + -1, | |
| 109 | + 0, | |
| 110 | + size, | |
| 111 | + size, | |
| 112 | + off)) | |
| 113 | + : ($Type$Buffer)(new Direct$Type$Buffer$RW$S(this, | |
| 114 | + -1, | |
| 115 | + 0, | |
| 116 | + size, | |
| 117 | + size, | |
| 118 | + off))); | |
| 119 | + } | |
| 120 | + } | |
| 121 | + | |
| 122 | +#end | |
| 123 | + | |
| 124 | +} | |
| @@ -0,0 +1,470 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +#warn This file is preprocessed before being compiled | |
| 27 | + | |
| 28 | +package java.nio; | |
| 29 | + | |
| 30 | +import java.io.FileDescriptor; | |
| 31 | +import sun.misc.Cleaner; | |
| 32 | +import sun.misc.Unsafe; | |
| 33 | +import sun.misc.VM; | |
| 34 | +import sun.nio.ch.DirectBuffer; | |
| 35 | + | |
| 36 | + | |
| 37 | +class Direct$Type$Buffer$RW$$BO$ | |
| 38 | +#if[rw] | |
| 39 | + extends {#if[byte]?Mapped$Type$Buffer:$Type$Buffer} | |
| 40 | +#else[rw] | |
| 41 | + extends Direct$Type$Buffer$BO$ | |
| 42 | +#end[rw] | |
| 43 | + implements DirectBuffer | |
| 44 | +{ | |
| 45 | + | |
| 46 | +#if[rw] | |
| 47 | + | |
| 48 | + // Cached unsafe-access object | |
| 49 | + protected static final Unsafe unsafe = Bits.unsafe(); | |
| 50 | + | |
| 51 | + // Cached array base offset | |
| 52 | + private static final long arrayBaseOffset = (long)unsafe.arrayBaseOffset($type$[].class); | |
| 53 | + | |
| 54 | + // Cached unaligned-access capability | |
| 55 | + protected static final boolean unaligned = Bits.unaligned(); | |
| 56 | + | |
| 57 | + // Base address, used in all indexing calculations | |
| 58 | + // NOTE: moved up to Buffer.java for speed in JNI GetDirectBufferAddress | |
| 59 | + // protected long address; | |
| 60 | + | |
| 61 | + // If this buffer is a view of another buffer then we keep a reference to | |
| 62 | + // that buffer so that its memory isn't freed before we're done with it | |
| 63 | + protected Object viewedBuffer = null; | |
| 64 | + | |
| 65 | + public Object viewedBuffer() { | |
| 66 | + return viewedBuffer; | |
| 67 | + } | |
| 68 | + | |
| 69 | +#if[byte] | |
| 70 | + | |
| 71 | + private static class Deallocator | |
| 72 | + implements Runnable | |
| 73 | + { | |
| 74 | + | |
| 75 | + private static Unsafe unsafe = Unsafe.getUnsafe(); | |
| 76 | + | |
| 77 | + private long address; | |
| 78 | + private long size; | |
| 79 | + private int capacity; | |
| 80 | + | |
| 81 | + private Deallocator(long address, long size, int capacity) { | |
| 82 | + assert (address != 0); | |
| 83 | + this.address = address; | |
| 84 | + this.size = size; | |
| 85 | + this.capacity = capacity; | |
| 86 | + } | |
| 87 | + | |
| 88 | + public void run() { | |
| 89 | + if (address == 0) { | |
| 90 | + // Paranoia | |
| 91 | + return; | |
| 92 | + } | |
| 93 | + unsafe.freeMemory(address); | |
| 94 | + address = 0; | |
| 95 | + Bits.unreserveMemory(size, capacity); | |
| 96 | + } | |
| 97 | + | |
| 98 | + } | |
| 99 | + | |
| 100 | + private final Cleaner cleaner; | |
| 101 | + | |
| 102 | + public Cleaner cleaner() { return cleaner; } | |
| 103 | + | |
| 104 | +#else[byte] | |
| 105 | + | |
| 106 | + public Cleaner cleaner() { return null; } | |
| 107 | + | |
| 108 | +#end[byte] | |
| 109 | + | |
| 110 | +#end[rw] | |
| 111 | + | |
| 112 | +#if[byte] | |
| 113 | + | |
| 114 | + // Primary constructor | |
| 115 | + // | |
| 116 | + Direct$Type$Buffer$RW$(int cap) { // package-private | |
| 117 | +#if[rw] | |
| 118 | + super(-1, 0, cap, cap); | |
| 119 | + boolean pa = VM.isDirectMemoryPageAligned(); | |
| 120 | + int ps = Bits.pageSize(); | |
| 121 | + long size = Math.max(1L, (long)cap + (pa ? ps : 0)); | |
| 122 | + Bits.reserveMemory(size, cap); | |
| 123 | + | |
| 124 | + long base = 0; | |
| 125 | + try { | |
| 126 | + base = unsafe.allocateMemory(size); | |
| 127 | + } catch (OutOfMemoryError x) { | |
| 128 | + Bits.unreserveMemory(size, cap); | |
| 129 | + throw x; | |
| 130 | + } | |
| 131 | + unsafe.setMemory(base, size, (byte) 0); | |
| 132 | + if (pa && (base % ps != 0)) { | |
| 133 | + // Round up to page boundary | |
| 134 | + address = base + ps - (base & (ps - 1)); | |
| 135 | + } else { | |
| 136 | + address = base; | |
| 137 | + } | |
| 138 | + cleaner = Cleaner.create(this, new Deallocator(base, size, cap)); | |
| 139 | +#else[rw] | |
| 140 | + super(cap); | |
| 141 | +#end[rw] | |
| 142 | + } | |
| 143 | + | |
| 144 | +#if[rw] | |
| 145 | + | |
| 146 | + // Invoked only by JNI: NewDirectByteBuffer(void*, long) | |
| 147 | + // | |
| 148 | + private Direct$Type$Buffer(long addr, int cap) { | |
| 149 | + super(-1, 0, cap, cap); | |
| 150 | + address = addr; | |
| 151 | + cleaner = null; | |
| 152 | + } | |
| 153 | + | |
| 154 | +#end[rw] | |
| 155 | + | |
| 156 | + // For memory-mapped buffers -- invoked by FileChannelImpl via reflection | |
| 157 | + // | |
| 158 | + protected Direct$Type$Buffer$RW$(int cap, long addr, | |
| 159 | + FileDescriptor fd, | |
| 160 | + Runnable unmapper) | |
| 161 | + { | |
| 162 | +#if[rw] | |
| 163 | + super(-1, 0, cap, cap, fd); | |
| 164 | + address = addr; | |
| 165 | + viewedBuffer = null; | |
| 166 | + cleaner = Cleaner.create(this, unmapper); | |
| 167 | +#else[rw] | |
| 168 | + super(cap, addr, fd, unmapper); | |
| 169 | +#end[rw] | |
| 170 | + } | |
| 171 | + | |
| 172 | +#end[byte] | |
| 173 | + | |
| 174 | + // For duplicates and slices | |
| 175 | + // | |
| 176 | + Direct$Type$Buffer$RW$$BO$(DirectBuffer db, // package-private | |
| 177 | + int mark, int pos, int lim, int cap, | |
| 178 | + int off) | |
| 179 | + { | |
| 180 | +#if[rw] | |
| 181 | + super(mark, pos, lim, cap); | |
| 182 | + address = db.address() + off; | |
| 183 | + viewedBuffer = db; | |
| 184 | +#if[byte] | |
| 185 | + cleaner = null; | |
| 186 | +#end[byte] | |
| 187 | +#else[rw] | |
| 188 | + super(db, mark, pos, lim, cap, off); | |
| 189 | +#end[rw] | |
| 190 | + } | |
| 191 | + | |
| 192 | + public $Type$Buffer slice() { | |
| 193 | + int pos = this.position(); | |
| 194 | + int lim = this.limit(); | |
| 195 | + assert (pos <= lim); | |
| 196 | + int rem = (pos <= lim ? lim - pos : 0); | |
| 197 | + int off = (pos << $LG_BYTES_PER_VALUE$); | |
| 198 | + assert (off >= 0); | |
| 199 | + return new Direct$Type$Buffer$RW$$BO$(this, -1, 0, rem, rem, off); | |
| 200 | + } | |
| 201 | + | |
| 202 | + public $Type$Buffer duplicate() { | |
| 203 | + return new Direct$Type$Buffer$RW$$BO$(this, | |
| 204 | + this.markValue(), | |
| 205 | + this.position(), | |
| 206 | + this.limit(), | |
| 207 | + this.capacity(), | |
| 208 | + 0); | |
| 209 | + } | |
| 210 | + | |
| 211 | + public $Type$Buffer asReadOnlyBuffer() { | |
| 212 | +#if[rw] | |
| 213 | + return new Direct$Type$BufferR$BO$(this, | |
| 214 | + this.markValue(), | |
| 215 | + this.position(), | |
| 216 | + this.limit(), | |
| 217 | + this.capacity(), | |
| 218 | + 0); | |
| 219 | +#else[rw] | |
| 220 | + return duplicate(); | |
| 221 | +#end[rw] | |
| 222 | + } | |
| 223 | + | |
| 224 | +#if[rw] | |
| 225 | + | |
| 226 | + public long address() { | |
| 227 | + return address; | |
| 228 | + } | |
| 229 | + | |
| 230 | + private long ix(int i) { | |
| 231 | + return address + (i << $LG_BYTES_PER_VALUE$); | |
| 232 | + } | |
| 233 | + | |
| 234 | + public $type$ get() { | |
| 235 | + return $fromBits$($swap$(unsafe.get$Swaptype$(ix(nextGetIndex())))); | |
| 236 | + } | |
| 237 | + | |
| 238 | + public $type$ get(int i) { | |
| 239 | + return $fromBits$($swap$(unsafe.get$Swaptype$(ix(checkIndex(i))))); | |
| 240 | + } | |
| 241 | + | |
| 242 | + public $Type$Buffer get($type$[] dst, int offset, int length) { | |
| 243 | +#if[rw] | |
| 244 | + if ((length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_TO_ARRAY_THRESHOLD) { | |
| 245 | + checkBounds(offset, length, dst.length); | |
| 246 | + int pos = position(); | |
| 247 | + int lim = limit(); | |
| 248 | + assert (pos <= lim); | |
| 249 | + int rem = (pos <= lim ? lim - pos : 0); | |
| 250 | + if (length > rem) | |
| 251 | + throw new BufferUnderflowException(); | |
| 252 | + | |
| 253 | +#if[!byte] | |
| 254 | + if (order() != ByteOrder.nativeOrder()) | |
| 255 | + Bits.copyTo$Memtype$Array(ix(pos), dst, | |
| 256 | + offset << $LG_BYTES_PER_VALUE$, | |
| 257 | + length << $LG_BYTES_PER_VALUE$); | |
| 258 | + else | |
| 259 | +#end[!byte] | |
| 260 | + Bits.copyToArray(ix(pos), dst, arrayBaseOffset, | |
| 261 | + offset << $LG_BYTES_PER_VALUE$, | |
| 262 | + length << $LG_BYTES_PER_VALUE$); | |
| 263 | + position(pos + length); | |
| 264 | + } else { | |
| 265 | + super.get(dst, offset, length); | |
| 266 | + } | |
| 267 | + return this; | |
| 268 | +#else[rw] | |
| 269 | + throw new ReadOnlyBufferException(); | |
| 270 | +#end[rw] | |
| 271 | + } | |
| 272 | + | |
| 273 | +#end[rw] | |
| 274 | + | |
| 275 | + public $Type$Buffer put($type$ x) { | |
| 276 | +#if[rw] | |
| 277 | + unsafe.put$Swaptype$(ix(nextPutIndex()), $swap$($toBits$(x))); | |
| 278 | + return this; | |
| 279 | +#else[rw] | |
| 280 | + throw new ReadOnlyBufferException(); | |
| 281 | +#end[rw] | |
| 282 | + } | |
| 283 | + | |
| 284 | + public $Type$Buffer put(int i, $type$ x) { | |
| 285 | +#if[rw] | |
| 286 | + unsafe.put$Swaptype$(ix(checkIndex(i)), $swap$($toBits$(x))); | |
| 287 | + return this; | |
| 288 | +#else[rw] | |
| 289 | + throw new ReadOnlyBufferException(); | |
| 290 | +#end[rw] | |
| 291 | + } | |
| 292 | + | |
| 293 | + public $Type$Buffer put($Type$Buffer src) { | |
| 294 | +#if[rw] | |
| 295 | + if (src instanceof Direct$Type$Buffer$BO$) { | |
| 296 | + if (src == this) | |
| 297 | + throw new IllegalArgumentException(); | |
| 298 | + Direct$Type$Buffer$RW$$BO$ sb = (Direct$Type$Buffer$RW$$BO$)src; | |
| 299 | + | |
| 300 | + int spos = sb.position(); | |
| 301 | + int slim = sb.limit(); | |
| 302 | + assert (spos <= slim); | |
| 303 | + int srem = (spos <= slim ? slim - spos : 0); | |
| 304 | + | |
| 305 | + int pos = position(); | |
| 306 | + int lim = limit(); | |
| 307 | + assert (pos <= lim); | |
| 308 | + int rem = (pos <= lim ? lim - pos : 0); | |
| 309 | + | |
| 310 | + if (srem > rem) | |
| 311 | + throw new BufferOverflowException(); | |
| 312 | + unsafe.copyMemory(sb.ix(spos), ix(pos), srem << $LG_BYTES_PER_VALUE$); | |
| 313 | + sb.position(spos + srem); | |
| 314 | + position(pos + srem); | |
| 315 | + } else if (src.hb != null) { | |
| 316 | + | |
| 317 | + int spos = src.position(); | |
| 318 | + int slim = src.limit(); | |
| 319 | + assert (spos <= slim); | |
| 320 | + int srem = (spos <= slim ? slim - spos : 0); | |
| 321 | + | |
| 322 | + put(src.hb, src.offset + spos, srem); | |
| 323 | + src.position(spos + srem); | |
| 324 | + | |
| 325 | + } else { | |
| 326 | + super.put(src); | |
| 327 | + } | |
| 328 | + return this; | |
| 329 | +#else[rw] | |
| 330 | + throw new ReadOnlyBufferException(); | |
| 331 | +#end[rw] | |
| 332 | + } | |
| 333 | + | |
| 334 | + public $Type$Buffer put($type$[] src, int offset, int length) { | |
| 335 | +#if[rw] | |
| 336 | + if ((length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_FROM_ARRAY_THRESHOLD) { | |
| 337 | + checkBounds(offset, length, src.length); | |
| 338 | + int pos = position(); | |
| 339 | + int lim = limit(); | |
| 340 | + assert (pos <= lim); | |
| 341 | + int rem = (pos <= lim ? lim - pos : 0); | |
| 342 | + if (length > rem) | |
| 343 | + throw new BufferOverflowException(); | |
| 344 | + | |
| 345 | +#if[!byte] | |
| 346 | + if (order() != ByteOrder.nativeOrder()) | |
| 347 | + Bits.copyFrom$Memtype$Array(src, offset << $LG_BYTES_PER_VALUE$, | |
| 348 | + ix(pos), length << $LG_BYTES_PER_VALUE$); | |
| 349 | + else | |
| 350 | +#end[!byte] | |
| 351 | + Bits.copyFromArray(src, arrayBaseOffset, offset << $LG_BYTES_PER_VALUE$, | |
| 352 | + ix(pos), length << $LG_BYTES_PER_VALUE$); | |
| 353 | + position(pos + length); | |
| 354 | + } else { | |
| 355 | + super.put(src, offset, length); | |
| 356 | + } | |
| 357 | + return this; | |
| 358 | +#else[rw] | |
| 359 | + throw new ReadOnlyBufferException(); | |
| 360 | +#end[rw] | |
| 361 | + } | |
| 362 | + | |
| 363 | + public $Type$Buffer compact() { | |
| 364 | +#if[rw] | |
| 365 | + int pos = position(); | |
| 366 | + int lim = limit(); | |
| 367 | + assert (pos <= lim); | |
| 368 | + int rem = (pos <= lim ? lim - pos : 0); | |
| 369 | + | |
| 370 | + unsafe.copyMemory(ix(pos), ix(0), rem << $LG_BYTES_PER_VALUE$); | |
| 371 | + position(rem); | |
| 372 | + limit(capacity()); | |
| 373 | + discardMark(); | |
| 374 | + return this; | |
| 375 | +#else[rw] | |
| 376 | + throw new ReadOnlyBufferException(); | |
| 377 | +#end[rw] | |
| 378 | + } | |
| 379 | + | |
| 380 | + public boolean isDirect() { | |
| 381 | + return true; | |
| 382 | + } | |
| 383 | + | |
| 384 | + public boolean isReadOnly() { | |
| 385 | + return {#if[rw]?false:true}; | |
| 386 | + } | |
| 387 | + | |
| 388 | + | |
| 389 | +#if[char] | |
| 390 | + | |
| 391 | + public String toString(int start, int end) { | |
| 392 | + if ((end > limit()) || (start > end)) | |
| 393 | + throw new IndexOutOfBoundsException(); | |
| 394 | + try { | |
| 395 | + int len = end - start; | |
| 396 | + char[] ca = new char[len]; | |
| 397 | + CharBuffer cb = CharBuffer.wrap(ca); | |
| 398 | + CharBuffer db = this.duplicate(); | |
| 399 | + db.position(start); | |
| 400 | + db.limit(end); | |
| 401 | + cb.put(db); | |
| 402 | + return new String(ca); | |
| 403 | + } catch (StringIndexOutOfBoundsException x) { | |
| 404 | + throw new IndexOutOfBoundsException(); | |
| 405 | + } | |
| 406 | + } | |
| 407 | + | |
| 408 | + | |
| 409 | + // --- Methods to support CharSequence --- | |
| 410 | + | |
| 411 | + public CharBuffer subSequence(int start, int end) { | |
| 412 | + int pos = position(); | |
| 413 | + int lim = limit(); | |
| 414 | + assert (pos <= lim); | |
| 415 | + pos = (pos <= lim ? pos : lim); | |
| 416 | + int len = lim - pos; | |
| 417 | + | |
| 418 | + if ((start < 0) || (end > len) || (start > end)) | |
| 419 | + throw new IndexOutOfBoundsException(); | |
| 420 | + return new DirectCharBuffer$RW$$BO$(this, | |
| 421 | + -1, | |
| 422 | + pos + start, | |
| 423 | + pos + end, | |
| 424 | + capacity(), | |
| 425 | + offset); | |
| 426 | + } | |
| 427 | + | |
| 428 | +#end[char] | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | +#if[!byte] | |
| 433 | + | |
| 434 | + public ByteOrder order() { | |
| 435 | +#if[boS] | |
| 436 | + return ((ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) | |
| 437 | + ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN); | |
| 438 | +#end[boS] | |
| 439 | +#if[boU] | |
| 440 | + return ((ByteOrder.nativeOrder() != ByteOrder.BIG_ENDIAN) | |
| 441 | + ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN); | |
| 442 | +#end[boU] | |
| 443 | + } | |
| 444 | + | |
| 445 | +#end[!byte] | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | +#if[byte] | |
| 450 | + | |
| 451 | + byte _get(int i) { // package-private | |
| 452 | + return unsafe.getByte(address + i); | |
| 453 | + } | |
| 454 | + | |
| 455 | + void _put(int i, byte b) { // package-private | |
| 456 | +#if[rw] | |
| 457 | + unsafe.putByte(address + i, b); | |
| 458 | +#else[rw] | |
| 459 | + throw new ReadOnlyBufferException(); | |
| 460 | +#end[rw] | |
| 461 | + } | |
| 462 | + | |
| 463 | + // #BIN | |
| 464 | + // | |
| 465 | + // Binary-data access methods for short, char, int, long, float, | |
| 466 | + // and double will be inserted here | |
| 467 | + | |
| 468 | +#end[byte] | |
| 469 | + | |
| 470 | +} | |
| @@ -0,0 +1,595 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +#warn This file is preprocessed before being compiled | |
| 27 | + | |
| 28 | +package java.nio; | |
| 29 | + | |
| 30 | + | |
| 31 | +/** | |
| 32 | +#if[rw] | |
| 33 | + * A read/write Heap$Type$Buffer. | |
| 34 | +#else[rw] | |
| 35 | + * A read-only Heap$Type$Buffer. This class extends the corresponding | |
| 36 | + * read/write class, overriding the mutation methods to throw a {@link | |
| 37 | + * ReadOnlyBufferException} and overriding the view-buffer methods to return an | |
| 38 | + * instance of this class rather than of the superclass. | |
| 39 | +#end[rw] | |
| 40 | + */ | |
| 41 | + | |
| 42 | +class Heap$Type$Buffer$RW$ | |
| 43 | + extends {#if[ro]?Heap}$Type$Buffer | |
| 44 | +{ | |
| 45 | + | |
| 46 | + // For speed these fields are actually declared in X-Buffer; | |
| 47 | + // these declarations are here as documentation | |
| 48 | + /* | |
| 49 | +#if[rw] | |
| 50 | + protected final $type$[] hb; | |
| 51 | + protected final int offset; | |
| 52 | +#end[rw] | |
| 53 | + */ | |
| 54 | + | |
| 55 | + Heap$Type$Buffer$RW$(int cap, int lim) { // package-private | |
| 56 | +#if[rw] | |
| 57 | + super(-1, 0, lim, cap, new $type$[cap], 0); | |
| 58 | + /* | |
| 59 | + hb = new $type$[cap]; | |
| 60 | + offset = 0; | |
| 61 | + */ | |
| 62 | +#else[rw] | |
| 63 | + super(cap, lim); | |
| 64 | + this.isReadOnly = true; | |
| 65 | +#end[rw] | |
| 66 | + } | |
| 67 | + | |
| 68 | + Heap$Type$Buffer$RW$($type$[] buf, int off, int len) { // package-private | |
| 69 | +#if[rw] | |
| 70 | + super(-1, off, off + len, buf.length, buf, 0); | |
| 71 | + /* | |
| 72 | + hb = buf; | |
| 73 | + offset = 0; | |
| 74 | + */ | |
| 75 | +#else[rw] | |
| 76 | + super(buf, off, len); | |
| 77 | + this.isReadOnly = true; | |
| 78 | +#end[rw] | |
| 79 | + } | |
| 80 | + | |
| 81 | + protected Heap$Type$Buffer$RW$($type$[] buf, | |
| 82 | + int mark, int pos, int lim, int cap, | |
| 83 | + int off) | |
| 84 | + { | |
| 85 | +#if[rw] | |
| 86 | + super(mark, pos, lim, cap, buf, off); | |
| 87 | + /* | |
| 88 | + hb = buf; | |
| 89 | + offset = off; | |
| 90 | + */ | |
| 91 | +#else[rw] | |
| 92 | + super(buf, mark, pos, lim, cap, off); | |
| 93 | + this.isReadOnly = true; | |
| 94 | +#end[rw] | |
| 95 | + } | |
| 96 | + | |
| 97 | + public $Type$Buffer slice() { | |
| 98 | + return new Heap$Type$Buffer$RW$(hb, | |
| 99 | + -1, | |
| 100 | + 0, | |
| 101 | + this.remaining(), | |
| 102 | + this.remaining(), | |
| 103 | + this.position() + offset); | |
| 104 | + } | |
| 105 | + | |
| 106 | + public $Type$Buffer duplicate() { | |
| 107 | + return new Heap$Type$Buffer$RW$(hb, | |
| 108 | + this.markValue(), | |
| 109 | + this.position(), | |
| 110 | + this.limit(), | |
| 111 | + this.capacity(), | |
| 112 | + offset); | |
| 113 | + } | |
| 114 | + | |
| 115 | + public $Type$Buffer asReadOnlyBuffer() { | |
| 116 | +#if[rw] | |
| 117 | + return new Heap$Type$BufferR(hb, | |
| 118 | + this.markValue(), | |
| 119 | + this.position(), | |
| 120 | + this.limit(), | |
| 121 | + this.capacity(), | |
| 122 | + offset); | |
| 123 | +#else[rw] | |
| 124 | + return duplicate(); | |
| 125 | +#end[rw] | |
| 126 | + } | |
| 127 | + | |
| 128 | +#if[rw] | |
| 129 | + | |
| 130 | + protected int ix(int i) { | |
| 131 | + return i + offset; | |
| 132 | + } | |
| 133 | + | |
| 134 | + public $type$ get() { | |
| 135 | + return hb[ix(nextGetIndex())]; | |
| 136 | + } | |
| 137 | + | |
| 138 | + public $type$ get(int i) { | |
| 139 | + return hb[ix(checkIndex(i))]; | |
| 140 | + } | |
| 141 | + | |
| 142 | + public $Type$Buffer get($type$[] dst, int offset, int length) { | |
| 143 | + checkBounds(offset, length, dst.length); | |
| 144 | + if (length > remaining()) | |
| 145 | + throw new BufferUnderflowException(); | |
| 146 | + System.arraycopy(hb, ix(position()), dst, offset, length); | |
| 147 | + position(position() + length); | |
| 148 | + return this; | |
| 149 | + } | |
| 150 | + | |
| 151 | + public boolean isDirect() { | |
| 152 | + return false; | |
| 153 | + } | |
| 154 | + | |
| 155 | +#end[rw] | |
| 156 | + | |
| 157 | + public boolean isReadOnly() { | |
| 158 | + return {#if[rw]?false:true}; | |
| 159 | + } | |
| 160 | + | |
| 161 | + public $Type$Buffer put($type$ x) { | |
| 162 | +#if[rw] | |
| 163 | + hb[ix(nextPutIndex())] = x; | |
| 164 | + return this; | |
| 165 | +#else[rw] | |
| 166 | + throw new ReadOnlyBufferException(); | |
| 167 | +#end[rw] | |
| 168 | + } | |
| 169 | + | |
| 170 | + public $Type$Buffer put(int i, $type$ x) { | |
| 171 | +#if[rw] | |
| 172 | + hb[ix(checkIndex(i))] = x; | |
| 173 | + return this; | |
| 174 | +#else[rw] | |
| 175 | + throw new ReadOnlyBufferException(); | |
| 176 | +#end[rw] | |
| 177 | + } | |
| 178 | + | |
| 179 | + public $Type$Buffer put($type$[] src, int offset, int length) { | |
| 180 | +#if[rw] | |
| 181 | + checkBounds(offset, length, src.length); | |
| 182 | + if (length > remaining()) | |
| 183 | + throw new BufferOverflowException(); | |
| 184 | + System.arraycopy(src, offset, hb, ix(position()), length); | |
| 185 | + position(position() + length); | |
| 186 | + return this; | |
| 187 | +#else[rw] | |
| 188 | + throw new ReadOnlyBufferException(); | |
| 189 | +#end[rw] | |
| 190 | + } | |
| 191 | + | |
| 192 | + public $Type$Buffer put($Type$Buffer src) { | |
| 193 | +#if[rw] | |
| 194 | + if (src instanceof Heap$Type$Buffer) { | |
| 195 | + if (src == this) | |
| 196 | + throw new IllegalArgumentException(); | |
| 197 | + Heap$Type$Buffer sb = (Heap$Type$Buffer)src; | |
| 198 | + int n = sb.remaining(); | |
| 199 | + if (n > remaining()) | |
| 200 | + throw new BufferOverflowException(); | |
| 201 | + System.arraycopy(sb.hb, sb.ix(sb.position()), | |
| 202 | + hb, ix(position()), n); | |
| 203 | + sb.position(sb.position() + n); | |
| 204 | + position(position() + n); | |
| 205 | + } else if (src.isDirect()) { | |
| 206 | + int n = src.remaining(); | |
| 207 | + if (n > remaining()) | |
| 208 | + throw new BufferOverflowException(); | |
| 209 | + src.get(hb, ix(position()), n); | |
| 210 | + position(position() + n); | |
| 211 | + } else { | |
| 212 | + super.put(src); | |
| 213 | + } | |
| 214 | + return this; | |
| 215 | +#else[rw] | |
| 216 | + throw new ReadOnlyBufferException(); | |
| 217 | +#end[rw] | |
| 218 | + } | |
| 219 | + | |
| 220 | + public $Type$Buffer compact() { | |
| 221 | +#if[rw] | |
| 222 | + System.arraycopy(hb, ix(position()), hb, ix(0), remaining()); | |
| 223 | + position(remaining()); | |
| 224 | + limit(capacity()); | |
| 225 | + discardMark(); | |
| 226 | + return this; | |
| 227 | +#else[rw] | |
| 228 | + throw new ReadOnlyBufferException(); | |
| 229 | +#end[rw] | |
| 230 | + } | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | +#if[byte] | |
| 235 | + | |
| 236 | + byte _get(int i) { // package-private | |
| 237 | + return hb[i]; | |
| 238 | + } | |
| 239 | + | |
| 240 | + void _put(int i, byte b) { // package-private | |
| 241 | +#if[rw] | |
| 242 | + hb[i] = b; | |
| 243 | +#else[rw] | |
| 244 | + throw new ReadOnlyBufferException(); | |
| 245 | +#end[rw] | |
| 246 | + } | |
| 247 | + | |
| 248 | + // char | |
| 249 | + | |
| 250 | +#if[rw] | |
| 251 | + | |
| 252 | + public char getChar() { | |
| 253 | + return Bits.getChar(this, ix(nextGetIndex(2)), bigEndian); | |
| 254 | + } | |
| 255 | + | |
| 256 | + public char getChar(int i) { | |
| 257 | + return Bits.getChar(this, ix(checkIndex(i, 2)), bigEndian); | |
| 258 | + } | |
| 259 | + | |
| 260 | +#end[rw] | |
| 261 | + | |
| 262 | + public $Type$Buffer putChar(char x) { | |
| 263 | +#if[rw] | |
| 264 | + Bits.putChar(this, ix(nextPutIndex(2)), x, bigEndian); | |
| 265 | + return this; | |
| 266 | +#else[rw] | |
| 267 | + throw new ReadOnlyBufferException(); | |
| 268 | +#end[rw] | |
| 269 | + } | |
| 270 | + | |
| 271 | + public $Type$Buffer putChar(int i, char x) { | |
| 272 | +#if[rw] | |
| 273 | + Bits.putChar(this, ix(checkIndex(i, 2)), x, bigEndian); | |
| 274 | + return this; | |
| 275 | +#else[rw] | |
| 276 | + throw new ReadOnlyBufferException(); | |
| 277 | +#end[rw] | |
| 278 | + } | |
| 279 | + | |
| 280 | + public CharBuffer asCharBuffer() { | |
| 281 | + int size = this.remaining() >> 1; | |
| 282 | + int off = offset + position(); | |
| 283 | + return (bigEndian | |
| 284 | + ? (CharBuffer)(new ByteBufferAsCharBuffer$RW$B(this, | |
| 285 | + -1, | |
| 286 | + 0, | |
| 287 | + size, | |
| 288 | + size, | |
| 289 | + off)) | |
| 290 | + : (CharBuffer)(new ByteBufferAsCharBuffer$RW$L(this, | |
| 291 | + -1, | |
| 292 | + 0, | |
| 293 | + size, | |
| 294 | + size, | |
| 295 | + off))); | |
| 296 | + } | |
| 297 | + | |
| 298 | + | |
| 299 | + // short | |
| 300 | + | |
| 301 | +#if[rw] | |
| 302 | + | |
| 303 | + public short getShort() { | |
| 304 | + return Bits.getShort(this, ix(nextGetIndex(2)), bigEndian); | |
| 305 | + } | |
| 306 | + | |
| 307 | + public short getShort(int i) { | |
| 308 | + return Bits.getShort(this, ix(checkIndex(i, 2)), bigEndian); | |
| 309 | + } | |
| 310 | + | |
| 311 | +#end[rw] | |
| 312 | + | |
| 313 | + public $Type$Buffer putShort(short x) { | |
| 314 | +#if[rw] | |
| 315 | + Bits.putShort(this, ix(nextPutIndex(2)), x, bigEndian); | |
| 316 | + return this; | |
| 317 | +#else[rw] | |
| 318 | + throw new ReadOnlyBufferException(); | |
| 319 | +#end[rw] | |
| 320 | + } | |
| 321 | + | |
| 322 | + public $Type$Buffer putShort(int i, short x) { | |
| 323 | +#if[rw] | |
| 324 | + Bits.putShort(this, ix(checkIndex(i, 2)), x, bigEndian); | |
| 325 | + return this; | |
| 326 | +#else[rw] | |
| 327 | + throw new ReadOnlyBufferException(); | |
| 328 | +#end[rw] | |
| 329 | + } | |
| 330 | + | |
| 331 | + public ShortBuffer asShortBuffer() { | |
| 332 | + int size = this.remaining() >> 1; | |
| 333 | + int off = offset + position(); | |
| 334 | + return (bigEndian | |
| 335 | + ? (ShortBuffer)(new ByteBufferAsShortBuffer$RW$B(this, | |
| 336 | + -1, | |
| 337 | + 0, | |
| 338 | + size, | |
| 339 | + size, | |
| 340 | + off)) | |
| 341 | + : (ShortBuffer)(new ByteBufferAsShortBuffer$RW$L(this, | |
| 342 | + -1, | |
| 343 | + 0, | |
| 344 | + size, | |
| 345 | + size, | |
| 346 | + off))); | |
| 347 | + } | |
| 348 | + | |
| 349 | + | |
| 350 | + // int | |
| 351 | + | |
| 352 | +#if[rw] | |
| 353 | + | |
| 354 | + public int getInt() { | |
| 355 | + return Bits.getInt(this, ix(nextGetIndex(4)), bigEndian); | |
| 356 | + } | |
| 357 | + | |
| 358 | + public int getInt(int i) { | |
| 359 | + return Bits.getInt(this, ix(checkIndex(i, 4)), bigEndian); | |
| 360 | + } | |
| 361 | + | |
| 362 | +#end[rw] | |
| 363 | + | |
| 364 | + public $Type$Buffer putInt(int x) { | |
| 365 | +#if[rw] | |
| 366 | + Bits.putInt(this, ix(nextPutIndex(4)), x, bigEndian); | |
| 367 | + return this; | |
| 368 | +#else[rw] | |
| 369 | + throw new ReadOnlyBufferException(); | |
| 370 | +#end[rw] | |
| 371 | + } | |
| 372 | + | |
| 373 | + public $Type$Buffer putInt(int i, int x) { | |
| 374 | +#if[rw] | |
| 375 | + Bits.putInt(this, ix(checkIndex(i, 4)), x, bigEndian); | |
| 376 | + return this; | |
| 377 | +#else[rw] | |
| 378 | + throw new ReadOnlyBufferException(); | |
| 379 | +#end[rw] | |
| 380 | + } | |
| 381 | + | |
| 382 | + public IntBuffer asIntBuffer() { | |
| 383 | + int size = this.remaining() >> 2; | |
| 384 | + int off = offset + position(); | |
| 385 | + return (bigEndian | |
| 386 | + ? (IntBuffer)(new ByteBufferAsIntBuffer$RW$B(this, | |
| 387 | + -1, | |
| 388 | + 0, | |
| 389 | + size, | |
| 390 | + size, | |
| 391 | + off)) | |
| 392 | + : (IntBuffer)(new ByteBufferAsIntBuffer$RW$L(this, | |
| 393 | + -1, | |
| 394 | + 0, | |
| 395 | + size, | |
| 396 | + size, | |
| 397 | + off))); | |
| 398 | + } | |
| 399 | + | |
| 400 | + | |
| 401 | + // long | |
| 402 | + | |
| 403 | +#if[rw] | |
| 404 | + | |
| 405 | + public long getLong() { | |
| 406 | + return Bits.getLong(this, ix(nextGetIndex(8)), bigEndian); | |
| 407 | + } | |
| 408 | + | |
| 409 | + public long getLong(int i) { | |
| 410 | + return Bits.getLong(this, ix(checkIndex(i, 8)), bigEndian); | |
| 411 | + } | |
| 412 | + | |
| 413 | +#end[rw] | |
| 414 | + | |
| 415 | + public $Type$Buffer putLong(long x) { | |
| 416 | +#if[rw] | |
| 417 | + Bits.putLong(this, ix(nextPutIndex(8)), x, bigEndian); | |
| 418 | + return this; | |
| 419 | +#else[rw] | |
| 420 | + throw new ReadOnlyBufferException(); | |
| 421 | +#end[rw] | |
| 422 | + } | |
| 423 | + | |
| 424 | + public $Type$Buffer putLong(int i, long x) { | |
| 425 | +#if[rw] | |
| 426 | + Bits.putLong(this, ix(checkIndex(i, 8)), x, bigEndian); | |
| 427 | + return this; | |
| 428 | +#else[rw] | |
| 429 | + throw new ReadOnlyBufferException(); | |
| 430 | +#end[rw] | |
| 431 | + } | |
| 432 | + | |
| 433 | + public LongBuffer asLongBuffer() { | |
| 434 | + int size = this.remaining() >> 3; | |
| 435 | + int off = offset + position(); | |
| 436 | + return (bigEndian | |
| 437 | + ? (LongBuffer)(new ByteBufferAsLongBuffer$RW$B(this, | |
| 438 | + -1, | |
| 439 | + 0, | |
| 440 | + size, | |
| 441 | + size, | |
| 442 | + off)) | |
| 443 | + : (LongBuffer)(new ByteBufferAsLongBuffer$RW$L(this, | |
| 444 | + -1, | |
| 445 | + 0, | |
| 446 | + size, | |
| 447 | + size, | |
| 448 | + off))); | |
| 449 | + } | |
| 450 | + | |
| 451 | + | |
| 452 | + // float | |
| 453 | + | |
| 454 | +#if[rw] | |
| 455 | + | |
| 456 | + public float getFloat() { | |
| 457 | + return Bits.getFloat(this, ix(nextGetIndex(4)), bigEndian); | |
| 458 | + } | |
| 459 | + | |
| 460 | + public float getFloat(int i) { | |
| 461 | + return Bits.getFloat(this, ix(checkIndex(i, 4)), bigEndian); | |
| 462 | + } | |
| 463 | + | |
| 464 | +#end[rw] | |
| 465 | + | |
| 466 | + public $Type$Buffer putFloat(float x) { | |
| 467 | +#if[rw] | |
| 468 | + Bits.putFloat(this, ix(nextPutIndex(4)), x, bigEndian); | |
| 469 | + return this; | |
| 470 | +#else[rw] | |
| 471 | + throw new ReadOnlyBufferException(); | |
| 472 | +#end[rw] | |
| 473 | + } | |
| 474 | + | |
| 475 | + public $Type$Buffer putFloat(int i, float x) { | |
| 476 | +#if[rw] | |
| 477 | + Bits.putFloat(this, ix(checkIndex(i, 4)), x, bigEndian); | |
| 478 | + return this; | |
| 479 | +#else[rw] | |
| 480 | + throw new ReadOnlyBufferException(); | |
| 481 | +#end[rw] | |
| 482 | + } | |
| 483 | + | |
| 484 | + public FloatBuffer asFloatBuffer() { | |
| 485 | + int size = this.remaining() >> 2; | |
| 486 | + int off = offset + position(); | |
| 487 | + return (bigEndian | |
| 488 | + ? (FloatBuffer)(new ByteBufferAsFloatBuffer$RW$B(this, | |
| 489 | + -1, | |
| 490 | + 0, | |
| 491 | + size, | |
| 492 | + size, | |
| 493 | + off)) | |
| 494 | + : (FloatBuffer)(new ByteBufferAsFloatBuffer$RW$L(this, | |
| 495 | + -1, | |
| 496 | + 0, | |
| 497 | + size, | |
| 498 | + size, | |
| 499 | + off))); | |
| 500 | + } | |
| 501 | + | |
| 502 | + | |
| 503 | + // double | |
| 504 | + | |
| 505 | +#if[rw] | |
| 506 | + | |
| 507 | + public double getDouble() { | |
| 508 | + return Bits.getDouble(this, ix(nextGetIndex(8)), bigEndian); | |
| 509 | + } | |
| 510 | + | |
| 511 | + public double getDouble(int i) { | |
| 512 | + return Bits.getDouble(this, ix(checkIndex(i, 8)), bigEndian); | |
| 513 | + } | |
| 514 | + | |
| 515 | +#end[rw] | |
| 516 | + | |
| 517 | + public $Type$Buffer putDouble(double x) { | |
| 518 | +#if[rw] | |
| 519 | + Bits.putDouble(this, ix(nextPutIndex(8)), x, bigEndian); | |
| 520 | + return this; | |
| 521 | +#else[rw] | |
| 522 | + throw new ReadOnlyBufferException(); | |
| 523 | +#end[rw] | |
| 524 | + } | |
| 525 | + | |
| 526 | + public $Type$Buffer putDouble(int i, double x) { | |
| 527 | +#if[rw] | |
| 528 | + Bits.putDouble(this, ix(checkIndex(i, 8)), x, bigEndian); | |
| 529 | + return this; | |
| 530 | +#else[rw] | |
| 531 | + throw new ReadOnlyBufferException(); | |
| 532 | +#end[rw] | |
| 533 | + } | |
| 534 | + | |
| 535 | + public DoubleBuffer asDoubleBuffer() { | |
| 536 | + int size = this.remaining() >> 3; | |
| 537 | + int off = offset + position(); | |
| 538 | + return (bigEndian | |
| 539 | + ? (DoubleBuffer)(new ByteBufferAsDoubleBuffer$RW$B(this, | |
| 540 | + -1, | |
| 541 | + 0, | |
| 542 | + size, | |
| 543 | + size, | |
| 544 | + off)) | |
| 545 | + : (DoubleBuffer)(new ByteBufferAsDoubleBuffer$RW$L(this, | |
| 546 | + -1, | |
| 547 | + 0, | |
| 548 | + size, | |
| 549 | + size, | |
| 550 | + off))); | |
| 551 | + } | |
| 552 | + | |
| 553 | + | |
| 554 | +#end[byte] | |
| 555 | + | |
| 556 | + | |
| 557 | +#if[char] | |
| 558 | + | |
| 559 | + String toString(int start, int end) { // package-private | |
| 560 | + try { | |
| 561 | + return new String(hb, start + offset, end - start); | |
| 562 | + } catch (StringIndexOutOfBoundsException x) { | |
| 563 | + throw new IndexOutOfBoundsException(); | |
| 564 | + } | |
| 565 | + } | |
| 566 | + | |
| 567 | + | |
| 568 | + // --- Methods to support CharSequence --- | |
| 569 | + | |
| 570 | + public CharBuffer subSequence(int start, int end) { | |
| 571 | + if ((start < 0) | |
| 572 | + || (end > length()) | |
| 573 | + || (start > end)) | |
| 574 | + throw new IndexOutOfBoundsException(); | |
| 575 | + int pos = position(); | |
| 576 | + return new HeapCharBuffer$RW$(hb, | |
| 577 | + -1, | |
| 578 | + pos + start, | |
| 579 | + pos + end, | |
| 580 | + capacity(), | |
| 581 | + offset); | |
| 582 | + } | |
| 583 | + | |
| 584 | +#end[char] | |
| 585 | + | |
| 586 | + | |
| 587 | +#if[!byte] | |
| 588 | + | |
| 589 | + public ByteOrder order() { | |
| 590 | + return ByteOrder.nativeOrder(); | |
| 591 | + } | |
| 592 | + | |
| 593 | +#end[!byte] | |
| 594 | + | |
| 595 | +} | |
Binary file not shown.
| @@ -0,0 +1,203 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio; | |
| 27 | + | |
| 28 | +import java.io.FileDescriptor; | |
| 29 | +import sun.misc.Unsafe; | |
| 30 | + | |
| 31 | + | |
| 32 | +/** | |
| 33 | + * A direct byte buffer whose content is a memory-mapped region of a file. | |
| 34 | + * | |
| 35 | + * <p> Mapped byte buffers are created via the {@link | |
| 36 | + * java.nio.channels.FileChannel#map FileChannel.map} method. This class | |
| 37 | + * extends the {@link ByteBuffer} class with operations that are specific to | |
| 38 | + * memory-mapped file regions. | |
| 39 | + * | |
| 40 | + * <p> A mapped byte buffer and the file mapping that it represents remain | |
| 41 | + * valid until the buffer itself is garbage-collected. | |
| 42 | + * | |
| 43 | + * <p> The content of a mapped byte buffer can change at any time, for example | |
| 44 | + * if the content of the corresponding region of the mapped file is changed by | |
| 45 | + * this program or another. Whether or not such changes occur, and when they | |
| 46 | + * occur, is operating-system dependent and therefore unspecified. | |
| 47 | + * | |
| 48 | + * <a name="inaccess"><p> All or part of a mapped byte buffer may become | |
| 49 | + * inaccessible at any time, for example if the mapped file is truncated. An | |
| 50 | + * attempt to access an inaccessible region of a mapped byte buffer will not | |
| 51 | + * change the buffer's content and will cause an unspecified exception to be | |
| 52 | + * thrown either at the time of the access or at some later time. It is | |
| 53 | + * therefore strongly recommended that appropriate precautions be taken to | |
| 54 | + * avoid the manipulation of a mapped file by this program, or by a | |
| 55 | + * concurrently running program, except to read or write the file's content. | |
| 56 | + * | |
| 57 | + * <p> Mapped byte buffers otherwise behave no differently than ordinary direct | |
| 58 | + * byte buffers. </p> | |
| 59 | + * | |
| 60 | + * | |
| 61 | + * @author Mark Reinhold | |
| 62 | + * @author JSR-51 Expert Group | |
| 63 | + * @since 1.4 | |
| 64 | + */ | |
| 65 | + | |
| 66 | +public abstract class MappedByteBuffer | |
| 67 | + extends ByteBuffer | |
| 68 | +{ | |
| 69 | + | |
| 70 | + // This is a little bit backwards: By rights MappedByteBuffer should be a | |
| 71 | + // subclass of DirectByteBuffer, but to keep the spec clear and simple, and | |
| 72 | + // for optimization purposes, it's easier to do it the other way around. | |
| 73 | + // This works because DirectByteBuffer is a package-private class. | |
| 74 | + | |
| 75 | + // For mapped buffers, a FileDescriptor that may be used for mapping | |
| 76 | + // operations if valid; null if the buffer is not mapped. | |
| 77 | + private final FileDescriptor fd; | |
| 78 | + | |
| 79 | + // This should only be invoked by the DirectByteBuffer constructors | |
| 80 | + // | |
| 81 | + MappedByteBuffer(int mark, int pos, int lim, int cap, // package-private | |
| 82 | + FileDescriptor fd) | |
| 83 | + { | |
| 84 | + super(mark, pos, lim, cap); | |
| 85 | + this.fd = fd; | |
| 86 | + } | |
| 87 | + | |
| 88 | + MappedByteBuffer(int mark, int pos, int lim, int cap) { // package-private | |
| 89 | + super(mark, pos, lim, cap); | |
| 90 | + this.fd = null; | |
| 91 | + } | |
| 92 | + | |
| 93 | + private void checkMapped() { | |
| 94 | + if (fd == null) | |
| 95 | + // Can only happen if a luser explicitly casts a direct byte buffer | |
| 96 | + throw new UnsupportedOperationException(); | |
| 97 | + } | |
| 98 | + | |
| 99 | + // Returns the distance (in bytes) of the buffer from the page aligned address | |
| 100 | + // of the mapping. Computed each time to avoid storing in every direct buffer. | |
| 101 | + private long mappingOffset() { | |
| 102 | + int ps = Bits.pageSize(); | |
| 103 | + long offset = address % ps; | |
| 104 | + return (offset >= 0) ? offset : (ps + offset); | |
| 105 | + } | |
| 106 | + | |
| 107 | + private long mappingAddress(long mappingOffset) { | |
| 108 | + return address - mappingOffset; | |
| 109 | + } | |
| 110 | + | |
| 111 | + private long mappingLength(long mappingOffset) { | |
| 112 | + return (long)capacity() + mappingOffset; | |
| 113 | + } | |
| 114 | + | |
| 115 | + /** | |
| 116 | + * Tells whether or not this buffer's content is resident in physical | |
| 117 | + * memory. | |
| 118 | + * | |
| 119 | + * <p> A return value of <tt>true</tt> implies that it is highly likely | |
| 120 | + * that all of the data in this buffer is resident in physical memory and | |
| 121 | + * may therefore be accessed without incurring any virtual-memory page | |
| 122 | + * faults or I/O operations. A return value of <tt>false</tt> does not | |
| 123 | + * necessarily imply that the buffer's content is not resident in physical | |
| 124 | + * memory. | |
| 125 | + * | |
| 126 | + * <p> The returned value is a hint, rather than a guarantee, because the | |
| 127 | + * underlying operating system may have paged out some of the buffer's data | |
| 128 | + * by the time that an invocation of this method returns. </p> | |
| 129 | + * | |
| 130 | + * @return <tt>true</tt> if it is likely that this buffer's content | |
| 131 | + * is resident in physical memory | |
| 132 | + */ | |
| 133 | + public final boolean isLoaded() { | |
| 134 | + checkMapped(); | |
| 135 | + if ((address == 0) || (capacity() == 0)) | |
| 136 | + return true; | |
| 137 | + long offset = mappingOffset(); | |
| 138 | + long length = mappingLength(offset); | |
| 139 | + return isLoaded0(mappingAddress(offset), length, Bits.pageCount(length)); | |
| 140 | + } | |
| 141 | + | |
| 142 | + /** | |
| 143 | + * Loads this buffer's content into physical memory. | |
| 144 | + * | |
| 145 | + * <p> This method makes a best effort to ensure that, when it returns, | |
| 146 | + * this buffer's content is resident in physical memory. Invoking this | |
| 147 | + * method may cause some number of page faults and I/O operations to | |
| 148 | + * occur. </p> | |
| 149 | + * | |
| 150 | + * @return This buffer | |
| 151 | + */ | |
| 152 | + public final MappedByteBuffer load() { | |
| 153 | + checkMapped(); | |
| 154 | + if ((address == 0) || (capacity() == 0)) | |
| 155 | + return this; | |
| 156 | + long offset = mappingOffset(); | |
| 157 | + long length = mappingLength(offset); | |
| 158 | + load0(mappingAddress(offset), length); | |
| 159 | + | |
| 160 | + // touch each page | |
| 161 | + Unsafe unsafe = Unsafe.getUnsafe(); | |
| 162 | + int ps = Bits.pageSize(); | |
| 163 | + int count = Bits.pageCount(length); | |
| 164 | + long a = mappingAddress(offset); | |
| 165 | + for (int i=0; i<count; i++) { | |
| 166 | + unsafe.getByte(a); | |
| 167 | + a += ps; | |
| 168 | + } | |
| 169 | + | |
| 170 | + return this; | |
| 171 | + } | |
| 172 | + | |
| 173 | + /** | |
| 174 | + * Forces any changes made to this buffer's content to be written to the | |
| 175 | + * storage device containing the mapped file. | |
| 176 | + * | |
| 177 | + * <p> If the file mapped into this buffer resides on a local storage | |
| 178 | + * device then when this method returns it is guaranteed that all changes | |
| 179 | + * made to the buffer since it was created, or since this method was last | |
| 180 | + * invoked, will have been written to that device. | |
| 181 | + * | |
| 182 | + * <p> If the file does not reside on a local device then no such guarantee | |
| 183 | + * is made. | |
| 184 | + * | |
| 185 | + * <p> If this buffer was not mapped in read/write mode ({@link | |
| 186 | + * java.nio.channels.FileChannel.MapMode#READ_WRITE}) then invoking this | |
| 187 | + * method has no effect. </p> | |
| 188 | + * | |
| 189 | + * @return This buffer | |
| 190 | + */ | |
| 191 | + public final MappedByteBuffer force() { | |
| 192 | + checkMapped(); | |
| 193 | + if ((address != 0) && (capacity() != 0)) { | |
| 194 | + long offset = mappingOffset(); | |
| 195 | + force0(fd, mappingAddress(offset), mappingLength(offset)); | |
| 196 | + } | |
| 197 | + return this; | |
| 198 | + } | |
| 199 | + | |
| 200 | + private native boolean isLoaded0(long address, long length, int pageCount); | |
| 201 | + private native void load0(long address, long length); | |
| 202 | + private native void force0(FileDescriptor fd, long address, long length); | |
| 203 | +} | |
Binary file not shown.
| @@ -0,0 +1,124 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio; | |
| 27 | + | |
| 28 | + | |
| 29 | +// ## If the sequence is a string, use reflection to share its array | |
| 30 | + | |
| 31 | +class StringCharBuffer // package-private | |
| 32 | + extends CharBuffer | |
| 33 | +{ | |
| 34 | + CharSequence str; | |
| 35 | + | |
| 36 | + StringCharBuffer(CharSequence s, int start, int end) { // package-private | |
| 37 | + super(-1, start, end, s.length()); | |
| 38 | + int n = s.length(); | |
| 39 | + if ((start < 0) || (start > n) || (end < start) || (end > n)) | |
| 40 | + throw new IndexOutOfBoundsException(); | |
| 41 | + str = s; | |
| 42 | + } | |
| 43 | + | |
| 44 | + public CharBuffer slice() { | |
| 45 | + return new StringCharBuffer(str, | |
| 46 | + -1, | |
| 47 | + 0, | |
| 48 | + this.remaining(), | |
| 49 | + this.remaining(), | |
| 50 | + offset + this.position()); | |
| 51 | + } | |
| 52 | + | |
| 53 | + private StringCharBuffer(CharSequence s, | |
| 54 | + int mark, | |
| 55 | + int pos, | |
| 56 | + int limit, | |
| 57 | + int cap, | |
| 58 | + int offset) { | |
| 59 | + super(mark, pos, limit, cap, null, offset); | |
| 60 | + str = s; | |
| 61 | + } | |
| 62 | + | |
| 63 | + public CharBuffer duplicate() { | |
| 64 | + return new StringCharBuffer(str, markValue(), | |
| 65 | + position(), limit(), capacity(), offset); | |
| 66 | + } | |
| 67 | + | |
| 68 | + public CharBuffer asReadOnlyBuffer() { | |
| 69 | + return duplicate(); | |
| 70 | + } | |
| 71 | + | |
| 72 | + public final char get() { | |
| 73 | + return str.charAt(nextGetIndex() + offset); | |
| 74 | + } | |
| 75 | + | |
| 76 | + public final char get(int index) { | |
| 77 | + return str.charAt(checkIndex(index) + offset); | |
| 78 | + } | |
| 79 | + | |
| 80 | + // ## Override bulk get methods for better performance | |
| 81 | + | |
| 82 | + public final CharBuffer put(char c) { | |
| 83 | + throw new ReadOnlyBufferException(); | |
| 84 | + } | |
| 85 | + | |
| 86 | + public final CharBuffer put(int index, char c) { | |
| 87 | + throw new ReadOnlyBufferException(); | |
| 88 | + } | |
| 89 | + | |
| 90 | + public final CharBuffer compact() { | |
| 91 | + throw new ReadOnlyBufferException(); | |
| 92 | + } | |
| 93 | + | |
| 94 | + public final boolean isReadOnly() { | |
| 95 | + return true; | |
| 96 | + } | |
| 97 | + | |
| 98 | + final String toString(int start, int end) { | |
| 99 | + return str.toString().substring(start + offset, end + offset); | |
| 100 | + } | |
| 101 | + | |
| 102 | + public final CharBuffer subSequence(int start, int end) { | |
| 103 | + try { | |
| 104 | + int pos = position(); | |
| 105 | + return new StringCharBuffer(str, | |
| 106 | + -1, | |
| 107 | + pos + checkIndex(start, pos), | |
| 108 | + pos + checkIndex(end, pos), | |
| 109 | + capacity(), | |
| 110 | + offset); | |
| 111 | + } catch (IllegalArgumentException x) { | |
| 112 | + throw new IndexOutOfBoundsException(); | |
| 113 | + } | |
| 114 | + } | |
| 115 | + | |
| 116 | + public boolean isDirect() { | |
| 117 | + return false; | |
| 118 | + } | |
| 119 | + | |
| 120 | + public ByteOrder order() { | |
| 121 | + return ByteOrder.nativeOrder(); | |
| 122 | + } | |
| 123 | + | |
| 124 | +} | |
| @@ -0,0 +1,132 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +#warn This file is preprocessed before being compiled | |
| 27 | + | |
| 28 | +class XXX { | |
| 29 | + | |
| 30 | +#begin | |
| 31 | + | |
| 32 | + /** | |
| 33 | + * Relative <i>get</i> method for reading $a$ $type$ value. | |
| 34 | + * | |
| 35 | + * <p> Reads the next $nbytes$ bytes at this buffer's current position, | |
| 36 | + * composing them into $a$ $type$ value according to the current byte order, | |
| 37 | + * and then increments the position by $nbytes$. </p> | |
| 38 | + * | |
| 39 | + * @return The $type$ value at the buffer's current position | |
| 40 | + * | |
| 41 | + * @throws BufferUnderflowException | |
| 42 | + * If there are fewer than $nbytes$ bytes | |
| 43 | + * remaining in this buffer | |
| 44 | + */ | |
| 45 | + public abstract $type$ get$Type$(); | |
| 46 | + | |
| 47 | + /** | |
| 48 | + * Relative <i>put</i> method for writing $a$ $type$ | |
| 49 | + * value <i>(optional operation)</i>. | |
| 50 | + * | |
| 51 | + * <p> Writes $nbytes$ bytes containing the given $type$ value, in the | |
| 52 | + * current byte order, into this buffer at the current position, and then | |
| 53 | + * increments the position by $nbytes$. </p> | |
| 54 | + * | |
| 55 | + * @param value | |
| 56 | + * The $type$ value to be written | |
| 57 | + * | |
| 58 | + * @return This buffer | |
| 59 | + * | |
| 60 | + * @throws BufferOverflowException | |
| 61 | + * If there are fewer than $nbytes$ bytes | |
| 62 | + * remaining in this buffer | |
| 63 | + * | |
| 64 | + * @throws ReadOnlyBufferException | |
| 65 | + * If this buffer is read-only | |
| 66 | + */ | |
| 67 | + public abstract ByteBuffer put$Type$($type$ value); | |
| 68 | + | |
| 69 | + /** | |
| 70 | + * Absolute <i>get</i> method for reading $a$ $type$ value. | |
| 71 | + * | |
| 72 | + * <p> Reads $nbytes$ bytes at the given index, composing them into a | |
| 73 | + * $type$ value according to the current byte order. </p> | |
| 74 | + * | |
| 75 | + * @param index | |
| 76 | + * The index from which the bytes will be read | |
| 77 | + * | |
| 78 | + * @return The $type$ value at the given index | |
| 79 | + * | |
| 80 | + * @throws IndexOutOfBoundsException | |
| 81 | + * If <tt>index</tt> is negative | |
| 82 | + * or not smaller than the buffer's limit, | |
| 83 | + * minus $nbytesButOne$ | |
| 84 | + */ | |
| 85 | + public abstract $type$ get$Type$(int index); | |
| 86 | + | |
| 87 | + /** | |
| 88 | + * Absolute <i>put</i> method for writing $a$ $type$ | |
| 89 | + * value <i>(optional operation)</i>. | |
| 90 | + * | |
| 91 | + * <p> Writes $nbytes$ bytes containing the given $type$ value, in the | |
| 92 | + * current byte order, into this buffer at the given index. </p> | |
| 93 | + * | |
| 94 | + * @param index | |
| 95 | + * The index at which the bytes will be written | |
| 96 | + * | |
| 97 | + * @param value | |
| 98 | + * The $type$ value to be written | |
| 99 | + * | |
| 100 | + * @return This buffer | |
| 101 | + * | |
| 102 | + * @throws IndexOutOfBoundsException | |
| 103 | + * If <tt>index</tt> is negative | |
| 104 | + * or not smaller than the buffer's limit, | |
| 105 | + * minus $nbytesButOne$ | |
| 106 | + * | |
| 107 | + * @throws ReadOnlyBufferException | |
| 108 | + * If this buffer is read-only | |
| 109 | + */ | |
| 110 | + public abstract ByteBuffer put$Type$(int index, $type$ value); | |
| 111 | + | |
| 112 | + /** | |
| 113 | + * Creates a view of this byte buffer as $a$ $type$ buffer. | |
| 114 | + * | |
| 115 | + * <p> The content of the new buffer will start at this buffer's current | |
| 116 | + * position. Changes to this buffer's content will be visible in the new | |
| 117 | + * buffer, and vice versa; the two buffers' position, limit, and mark | |
| 118 | + * values will be independent. | |
| 119 | + * | |
| 120 | + * <p> The new buffer's position will be zero, its capacity and its limit | |
| 121 | + * will be the number of bytes remaining in this buffer divided by | |
| 122 | + * $nbytes$, and its mark will be undefined. The new buffer will be direct | |
| 123 | + * if, and only if, this buffer is direct, and it will be read-only if, and | |
| 124 | + * only if, this buffer is read-only. </p> | |
| 125 | + * | |
| 126 | + * @return A new $type$ buffer | |
| 127 | + */ | |
| 128 | + public abstract $Type$Buffer as$Type$Buffer(); | |
| 129 | + | |
| 130 | +#end | |
| 131 | + | |
| 132 | +} | |
| @@ -0,0 +1,1451 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +#warn This file is preprocessed before being compiled | |
| 27 | + | |
| 28 | +package java.nio; | |
| 29 | + | |
| 30 | +#if[char] | |
| 31 | +import java.io.IOException; | |
| 32 | +#end[char] | |
| 33 | + | |
| 34 | +/** | |
| 35 | + * $A$ $type$ buffer. | |
| 36 | + * | |
| 37 | + * <p> This class defines {#if[byte]?six:four} categories of operations upon | |
| 38 | + * $type$ buffers: | |
| 39 | + * | |
| 40 | + * <ul> | |
| 41 | + * | |
| 42 | + * <li><p> Absolute and relative {@link #get() </code><i>get</i><code>} and | |
| 43 | + * {@link #put($type$) </code><i>put</i><code>} methods that read and write | |
| 44 | + * single $type$s; </p></li> | |
| 45 | + * | |
| 46 | + * <li><p> Relative {@link #get($type$[]) </code><i>bulk get</i><code>} | |
| 47 | + * methods that transfer contiguous sequences of $type$s from this buffer | |
| 48 | + * into an array; {#if[!byte]?and}</p></li> | |
| 49 | + * | |
| 50 | + * <li><p> Relative {@link #put($type$[]) </code><i>bulk put</i><code>} | |
| 51 | + * methods that transfer contiguous sequences of $type$s from $a$ | |
| 52 | + * $type$ array{#if[char]?, a string,} or some other $type$ | |
| 53 | + * buffer into this buffer;{#if[!byte]? and} </p></li> | |
| 54 | + * | |
| 55 | +#if[byte] | |
| 56 | + * | |
| 57 | + * <li><p> Absolute and relative {@link #getChar() </code><i>get</i><code>} | |
| 58 | + * and {@link #putChar(char) </code><i>put</i><code>} methods that read and | |
| 59 | + * write values of other primitive types, translating them to and from | |
| 60 | + * sequences of bytes in a particular byte order; </p></li> | |
| 61 | + * | |
| 62 | + * <li><p> Methods for creating <i><a href="#views">view buffers</a></i>, | |
| 63 | + * which allow a byte buffer to be viewed as a buffer containing values of | |
| 64 | + * some other primitive type; and </p></li> | |
| 65 | + * | |
| 66 | +#end[byte] | |
| 67 | + * | |
| 68 | + * <li><p> Methods for {@link #compact </code>compacting<code>}, {@link | |
| 69 | + * #duplicate </code>duplicating<code>}, and {@link #slice | |
| 70 | + * </code>slicing<code>} $a$ $type$ buffer. </p></li> | |
| 71 | + * | |
| 72 | + * </ul> | |
| 73 | + * | |
| 74 | + * <p> $Type$ buffers can be created either by {@link #allocate | |
| 75 | + * </code><i>allocation</i><code>}, which allocates space for the buffer's | |
| 76 | + * | |
| 77 | +#if[byte] | |
| 78 | + * | |
| 79 | + * content, or by {@link #wrap($type$[]) </code><i>wrapping</i><code>} an | |
| 80 | + * existing $type$ array {#if[char]?or string} into a buffer. | |
| 81 | + * | |
| 82 | +#else[byte] | |
| 83 | + * | |
| 84 | + * content, by {@link #wrap($type$[]) </code><i>wrapping</i><code>} an existing | |
| 85 | + * $type$ array {#if[char]?or string} into a buffer, or by creating a | |
| 86 | + * <a href="ByteBuffer.html#views"><i>view</i></a> of an existing byte buffer. | |
| 87 | + * | |
| 88 | +#end[byte] | |
| 89 | + * | |
| 90 | +#if[byte] | |
| 91 | + * | |
| 92 | + * <a name="direct"> | |
| 93 | + * <h4> Direct <i>vs.</i> non-direct buffers </h4> | |
| 94 | + * | |
| 95 | + * <p> A byte buffer is either <i>direct</i> or <i>non-direct</i>. Given a | |
| 96 | + * direct byte buffer, the Java virtual machine will make a best effort to | |
| 97 | + * perform native I/O operations directly upon it. That is, it will attempt to | |
| 98 | + * avoid copying the buffer's content to (or from) an intermediate buffer | |
| 99 | + * before (or after) each invocation of one of the underlying operating | |
| 100 | + * system's native I/O operations. | |
| 101 | + * | |
| 102 | + * <p> A direct byte buffer may be created by invoking the {@link | |
| 103 | + * #allocateDirect(int) allocateDirect} factory method of this class. The | |
| 104 | + * buffers returned by this method typically have somewhat higher allocation | |
| 105 | + * and deallocation costs than non-direct buffers. The contents of direct | |
| 106 | + * buffers may reside outside of the normal garbage-collected heap, and so | |
| 107 | + * their impact upon the memory footprint of an application might not be | |
| 108 | + * obvious. It is therefore recommended that direct buffers be allocated | |
| 109 | + * primarily for large, long-lived buffers that are subject to the underlying | |
| 110 | + * system's native I/O operations. In general it is best to allocate direct | |
| 111 | + * buffers only when they yield a measureable gain in program performance. | |
| 112 | + * | |
| 113 | + * <p> A direct byte buffer may also be created by {@link | |
| 114 | + * java.nio.channels.FileChannel#map </code>mapping<code>} a region of a file | |
| 115 | + * directly into memory. An implementation of the Java platform may optionally | |
| 116 | + * support the creation of direct byte buffers from native code via JNI. If an | |
| 117 | + * instance of one of these kinds of buffers refers to an inaccessible region | |
| 118 | + * of memory then an attempt to access that region will not change the buffer's | |
| 119 | + * content and will cause an unspecified exception to be thrown either at the | |
| 120 | + * time of the access or at some later time. | |
| 121 | + * | |
| 122 | + * <p> Whether a byte buffer is direct or non-direct may be determined by | |
| 123 | + * invoking its {@link #isDirect isDirect} method. This method is provided so | |
| 124 | + * that explicit buffer management can be done in performance-critical code. | |
| 125 | + * | |
| 126 | + * | |
| 127 | + * <a name="bin"> | |
| 128 | + * <h4> Access to binary data </h4> | |
| 129 | + * | |
| 130 | + * <p> This class defines methods for reading and writing values of all other | |
| 131 | + * primitive types, except <tt>boolean</tt>. Primitive values are translated | |
| 132 | + * to (or from) sequences of bytes according to the buffer's current byte | |
| 133 | + * order, which may be retrieved and modified via the {@link #order order} | |
| 134 | + * methods. Specific byte orders are represented by instances of the {@link | |
| 135 | + * ByteOrder} class. The initial order of a byte buffer is always {@link | |
| 136 | + * ByteOrder#BIG_ENDIAN BIG_ENDIAN}. | |
| 137 | + * | |
| 138 | + * <p> For access to heterogeneous binary data, that is, sequences of values of | |
| 139 | + * different types, this class defines a family of absolute and relative | |
| 140 | + * <i>get</i> and <i>put</i> methods for each type. For 32-bit floating-point | |
| 141 | + * values, for example, this class defines: | |
| 142 | + * | |
| 143 | + * <blockquote><pre> | |
| 144 | + * float {@link #getFloat()} | |
| 145 | + * float {@link #getFloat(int) getFloat(int index)} | |
| 146 | + * void {@link #putFloat(float) putFloat(float f)} | |
| 147 | + * void {@link #putFloat(int,float) putFloat(int index, float f)}</pre></blockquote> | |
| 148 | + * | |
| 149 | + * <p> Corresponding methods are defined for the types <tt>char</tt>, | |
| 150 | + * <tt>short</tt>, <tt>int</tt>, <tt>long</tt>, and <tt>double</tt>. The index | |
| 151 | + * parameters of the absolute <i>get</i> and <i>put</i> methods are in terms of | |
| 152 | + * bytes rather than of the type being read or written. | |
| 153 | + * | |
| 154 | + * <a name="views"> | |
| 155 | + * | |
| 156 | + * <p> For access to homogeneous binary data, that is, sequences of values of | |
| 157 | + * the same type, this class defines methods that can create <i>views</i> of a | |
| 158 | + * given byte buffer. A <i>view buffer</i> is simply another buffer whose | |
| 159 | + * content is backed by the byte buffer. Changes to the byte buffer's content | |
| 160 | + * will be visible in the view buffer, and vice versa; the two buffers' | |
| 161 | + * position, limit, and mark values are independent. The {@link | |
| 162 | + * #asFloatBuffer() asFloatBuffer} method, for example, creates an instance of | |
| 163 | + * the {@link FloatBuffer} class that is backed by the byte buffer upon which | |
| 164 | + * the method is invoked. Corresponding view-creation methods are defined for | |
| 165 | + * the types <tt>char</tt>, <tt>short</tt>, <tt>int</tt>, <tt>long</tt>, and | |
| 166 | + * <tt>double</tt>. | |
| 167 | + * | |
| 168 | + * <p> View buffers have three important advantages over the families of | |
| 169 | + * type-specific <i>get</i> and <i>put</i> methods described above: | |
| 170 | + * | |
| 171 | + * <ul> | |
| 172 | + * | |
| 173 | + * <li><p> A view buffer is indexed not in terms of bytes but rather in terms | |
| 174 | + * of the type-specific size of its values; </p></li> | |
| 175 | + * | |
| 176 | + * <li><p> A view buffer provides relative bulk <i>get</i> and <i>put</i> | |
| 177 | + * methods that can transfer contiguous sequences of values between a buffer | |
| 178 | + * and an array or some other buffer of the same type; and </p></li> | |
| 179 | + * | |
| 180 | + * <li><p> A view buffer is potentially much more efficient because it will | |
| 181 | + * be direct if, and only if, its backing byte buffer is direct. </p></li> | |
| 182 | + * | |
| 183 | + * </ul> | |
| 184 | + * | |
| 185 | + * <p> The byte order of a view buffer is fixed to be that of its byte buffer | |
| 186 | + * at the time that the view is created. </p> | |
| 187 | + * | |
| 188 | +#end[byte] | |
| 189 | +* | |
| 190 | +#if[!byte] | |
| 191 | + * | |
| 192 | + * <p> Like a byte buffer, $a$ $type$ buffer is either <a | |
| 193 | + * href="ByteBuffer.html#direct"><i>direct</i> or <i>non-direct</i></a>. A | |
| 194 | + * $type$ buffer created via the <tt>wrap</tt> methods of this class will | |
| 195 | + * be non-direct. $A$ $type$ buffer created as a view of a byte buffer will | |
| 196 | + * be direct if, and only if, the byte buffer itself is direct. Whether or not | |
| 197 | + * $a$ $type$ buffer is direct may be determined by invoking the {@link | |
| 198 | + * #isDirect isDirect} method. </p> | |
| 199 | + * | |
| 200 | +#end[!byte] | |
| 201 | +* | |
| 202 | +#if[char] | |
| 203 | + * | |
| 204 | + * <p> This class implements the {@link CharSequence} interface so that | |
| 205 | + * character buffers may be used wherever character sequences are accepted, for | |
| 206 | + * example in the regular-expression package <tt>{@link java.util.regex}</tt>. | |
| 207 | + * </p> | |
| 208 | + * | |
| 209 | +#end[char] | |
| 210 | + * | |
| 211 | +#if[byte] | |
| 212 | + * <h4> Invocation chaining </h4> | |
| 213 | +#end[byte] | |
| 214 | + * | |
| 215 | + * <p> Methods in this class that do not otherwise have a value to return are | |
| 216 | + * specified to return the buffer upon which they are invoked. This allows | |
| 217 | + * method invocations to be chained. | |
| 218 | + * | |
| 219 | +#if[byte] | |
| 220 | + * | |
| 221 | + * The sequence of statements | |
| 222 | + * | |
| 223 | + * <blockquote><pre> | |
| 224 | + * bb.putInt(0xCAFEBABE); | |
| 225 | + * bb.putShort(3); | |
| 226 | + * bb.putShort(45);</pre></blockquote> | |
| 227 | + * | |
| 228 | + * can, for example, be replaced by the single statement | |
| 229 | + * | |
| 230 | + * <blockquote><pre> | |
| 231 | + * bb.putInt(0xCAFEBABE).putShort(3).putShort(45);</pre></blockquote> | |
| 232 | + * | |
| 233 | +#end[byte] | |
| 234 | +#if[char] | |
| 235 | + * | |
| 236 | + * The sequence of statements | |
| 237 | + * | |
| 238 | + * <blockquote><pre> | |
| 239 | + * cb.put("text/"); | |
| 240 | + * cb.put(subtype); | |
| 241 | + * cb.put("; charset="); | |
| 242 | + * cb.put(enc);</pre></blockquote> | |
| 243 | + * | |
| 244 | + * can, for example, be replaced by the single statement | |
| 245 | + * | |
| 246 | + * <blockquote><pre> | |
| 247 | + * cb.put("text/").put(subtype).put("; charset=").put(enc);</pre></blockquote> | |
| 248 | + * | |
| 249 | +#end[char] | |
| 250 | + * | |
| 251 | + * | |
| 252 | + * @author Mark Reinhold | |
| 253 | + * @author JSR-51 Expert Group | |
| 254 | + * @since 1.4 | |
| 255 | + */ | |
| 256 | + | |
| 257 | +public abstract class $Type$Buffer | |
| 258 | + extends Buffer | |
| 259 | + implements Comparable<$Type$Buffer>{#if[char]?, Appendable, CharSequence, Readable} | |
| 260 | +{ | |
| 261 | + | |
| 262 | + // These fields are declared here rather than in Heap-X-Buffer in order to | |
| 263 | + // reduce the number of virtual method invocations needed to access these | |
| 264 | + // values, which is especially costly when coding small buffers. | |
| 265 | + // | |
| 266 | + final $type$[] hb; // Non-null only for heap buffers | |
| 267 | + final int offset; | |
| 268 | + boolean isReadOnly; // Valid only for heap buffers | |
| 269 | + | |
| 270 | + // Creates a new buffer with the given mark, position, limit, capacity, | |
| 271 | + // backing array, and array offset | |
| 272 | + // | |
| 273 | + $Type$Buffer(int mark, int pos, int lim, int cap, // package-private | |
| 274 | + $type$[] hb, int offset) | |
| 275 | + { | |
| 276 | + super(mark, pos, lim, cap); | |
| 277 | + this.hb = hb; | |
| 278 | + this.offset = offset; | |
| 279 | + } | |
| 280 | + | |
| 281 | + // Creates a new buffer with the given mark, position, limit, and capacity | |
| 282 | + // | |
| 283 | + $Type$Buffer(int mark, int pos, int lim, int cap) { // package-private | |
| 284 | + this(mark, pos, lim, cap, null, 0); | |
| 285 | + } | |
| 286 | + | |
| 287 | +#if[byte] | |
| 288 | + | |
| 289 | + /** | |
| 290 | + * Allocates a new direct $type$ buffer. | |
| 291 | + * | |
| 292 | + * <p> The new buffer's position will be zero, its limit will be its | |
| 293 | + * capacity, its mark will be undefined, and each of its elements will be | |
| 294 | + * initialized to zero. Whether or not it has a | |
| 295 | + * {@link #hasArray </code>backing array<code>} is unspecified. | |
| 296 | + * | |
| 297 | + * @param capacity | |
| 298 | + * The new buffer's capacity, in $type$s | |
| 299 | + * | |
| 300 | + * @return The new $type$ buffer | |
| 301 | + * | |
| 302 | + * @throws IllegalArgumentException | |
| 303 | + * If the <tt>capacity</tt> is a negative integer | |
| 304 | + */ | |
| 305 | + public static $Type$Buffer allocateDirect(int capacity) { | |
| 306 | + return new Direct$Type$Buffer(capacity); | |
| 307 | + } | |
| 308 | + | |
| 309 | +#end[byte] | |
| 310 | + | |
| 311 | + /** | |
| 312 | + * Allocates a new $type$ buffer. | |
| 313 | + * | |
| 314 | + * <p> The new buffer's position will be zero, its limit will be its | |
| 315 | + * capacity, its mark will be undefined, and each of its elements will be | |
| 316 | + * initialized to zero. It will have a {@link #array | |
| 317 | + * </code>backing array<code>}, and its {@link #arrayOffset </code>array | |
| 318 | + * offset<code>} will be zero. | |
| 319 | + * | |
| 320 | + * @param capacity | |
| 321 | + * The new buffer's capacity, in $type$s | |
| 322 | + * | |
| 323 | + * @return The new $type$ buffer | |
| 324 | + * | |
| 325 | + * @throws IllegalArgumentException | |
| 326 | + * If the <tt>capacity</tt> is a negative integer | |
| 327 | + */ | |
| 328 | + public static $Type$Buffer allocate(int capacity) { | |
| 329 | + if (capacity < 0) | |
| 330 | + throw new IllegalArgumentException(); | |
| 331 | + return new Heap$Type$Buffer(capacity, capacity); | |
| 332 | + } | |
| 333 | + | |
| 334 | + /** | |
| 335 | + * Wraps $a$ $type$ array into a buffer. | |
| 336 | + * | |
| 337 | + * <p> The new buffer will be backed by the given $type$ array; | |
| 338 | + * that is, modifications to the buffer will cause the array to be modified | |
| 339 | + * and vice versa. The new buffer's capacity will be | |
| 340 | + * <tt>array.length</tt>, its position will be <tt>offset</tt>, its limit | |
| 341 | + * will be <tt>offset + length</tt>, and its mark will be undefined. Its | |
| 342 | + * {@link #array </code>backing array<code>} will be the given array, and | |
| 343 | + * its {@link #arrayOffset </code>array offset<code>} will be zero. </p> | |
| 344 | + * | |
| 345 | + * @param array | |
| 346 | + * The array that will back the new buffer | |
| 347 | + * | |
| 348 | + * @param offset | |
| 349 | + * The offset of the subarray to be used; must be non-negative and | |
| 350 | + * no larger than <tt>array.length</tt>. The new buffer's position | |
| 351 | + * will be set to this value. | |
| 352 | + * | |
| 353 | + * @param length | |
| 354 | + * The length of the subarray to be used; | |
| 355 | + * must be non-negative and no larger than | |
| 356 | + * <tt>array.length - offset</tt>. | |
| 357 | + * The new buffer's limit will be set to <tt>offset + length</tt>. | |
| 358 | + * | |
| 359 | + * @return The new $type$ buffer | |
| 360 | + * | |
| 361 | + * @throws IndexOutOfBoundsException | |
| 362 | + * If the preconditions on the <tt>offset</tt> and <tt>length</tt> | |
| 363 | + * parameters do not hold | |
| 364 | + */ | |
| 365 | + public static $Type$Buffer wrap($type$[] array, | |
| 366 | + int offset, int length) | |
| 367 | + { | |
| 368 | + try { | |
| 369 | + return new Heap$Type$Buffer(array, offset, length); | |
| 370 | + } catch (IllegalArgumentException x) { | |
| 371 | + throw new IndexOutOfBoundsException(); | |
| 372 | + } | |
| 373 | + } | |
| 374 | + | |
| 375 | + /** | |
| 376 | + * Wraps $a$ $type$ array into a buffer. | |
| 377 | + * | |
| 378 | + * <p> The new buffer will be backed by the given $type$ array; | |
| 379 | + * that is, modifications to the buffer will cause the array to be modified | |
| 380 | + * and vice versa. The new buffer's capacity and limit will be | |
| 381 | + * <tt>array.length</tt>, its position will be zero, and its mark will be | |
| 382 | + * undefined. Its {@link #array </code>backing array<code>} will be the | |
| 383 | + * given array, and its {@link #arrayOffset </code>array offset<code>} will | |
| 384 | + * be zero. </p> | |
| 385 | + * | |
| 386 | + * @param array | |
| 387 | + * The array that will back this buffer | |
| 388 | + * | |
| 389 | + * @return The new $type$ buffer | |
| 390 | + */ | |
| 391 | + public static $Type$Buffer wrap($type$[] array) { | |
| 392 | + return wrap(array, 0, array.length); | |
| 393 | + } | |
| 394 | + | |
| 395 | +#if[char] | |
| 396 | + | |
| 397 | + /** | |
| 398 | + * Attempts to read characters into the specified character buffer. | |
| 399 | + * The buffer is used as a repository of characters as-is: the only | |
| 400 | + * changes made are the results of a put operation. No flipping or | |
| 401 | + * rewinding of the buffer is performed. | |
| 402 | + * | |
| 403 | + * @param target the buffer to read characters into | |
| 404 | + * @return The number of characters added to the buffer, or | |
| 405 | + * -1 if this source of characters is at its end | |
| 406 | + * @throws IOException if an I/O error occurs | |
| 407 | + * @throws NullPointerException if target is null | |
| 408 | + * @throws ReadOnlyBufferException if target is a read only buffer | |
| 409 | + * @since 1.5 | |
| 410 | + */ | |
| 411 | + public int read(CharBuffer target) throws IOException { | |
| 412 | + // Determine the number of bytes n that can be transferred | |
| 413 | + int targetRemaining = target.remaining(); | |
| 414 | + int remaining = remaining(); | |
| 415 | + if (remaining == 0) | |
| 416 | + return -1; | |
| 417 | + int n = Math.min(remaining, targetRemaining); | |
| 418 | + int limit = limit(); | |
| 419 | + // Set source limit to prevent target overflow | |
| 420 | + if (targetRemaining < remaining) | |
| 421 | + limit(position() + n); | |
| 422 | + try { | |
| 423 | + if (n > 0) | |
| 424 | + target.put(this); | |
| 425 | + } finally { | |
| 426 | + limit(limit); // restore real limit | |
| 427 | + } | |
| 428 | + return n; | |
| 429 | + } | |
| 430 | + | |
| 431 | + /** | |
| 432 | + * Wraps a character sequence into a buffer. | |
| 433 | + * | |
| 434 | + * <p> The content of the new, read-only buffer will be the content of the | |
| 435 | + * given character sequence. The buffer's capacity will be | |
| 436 | + * <tt>csq.length()</tt>, its position will be <tt>start</tt>, its limit | |
| 437 | + * will be <tt>end</tt>, and its mark will be undefined. </p> | |
| 438 | + * | |
| 439 | + * @param csq | |
| 440 | + * The character sequence from which the new character buffer is to | |
| 441 | + * be created | |
| 442 | + * | |
| 443 | + * @param start | |
| 444 | + * The index of the first character to be used; | |
| 445 | + * must be non-negative and no larger than <tt>csq.length()</tt>. | |
| 446 | + * The new buffer's position will be set to this value. | |
| 447 | + * | |
| 448 | + * @param end | |
| 449 | + * The index of the character following the last character to be | |
| 450 | + * used; must be no smaller than <tt>start</tt> and no larger | |
| 451 | + * than <tt>csq.length()</tt>. | |
| 452 | + * The new buffer's limit will be set to this value. | |
| 453 | + * | |
| 454 | + * @return The new character buffer | |
| 455 | + * | |
| 456 | + * @throws IndexOutOfBoundsException | |
| 457 | + * If the preconditions on the <tt>start</tt> and <tt>end</tt> | |
| 458 | + * parameters do not hold | |
| 459 | + */ | |
| 460 | + public static CharBuffer wrap(CharSequence csq, int start, int end) { | |
| 461 | + try { | |
| 462 | + return new StringCharBuffer(csq, start, end); | |
| 463 | + } catch (IllegalArgumentException x) { | |
| 464 | + throw new IndexOutOfBoundsException(); | |
| 465 | + } | |
| 466 | + } | |
| 467 | + | |
| 468 | + /** | |
| 469 | + * Wraps a character sequence into a buffer. | |
| 470 | + * | |
| 471 | + * <p> The content of the new, read-only buffer will be the content of the | |
| 472 | + * given character sequence. The new buffer's capacity and limit will be | |
| 473 | + * <tt>csq.length()</tt>, its position will be zero, and its mark will be | |
| 474 | + * undefined. </p> | |
| 475 | + * | |
| 476 | + * @param csq | |
| 477 | + * The character sequence from which the new character buffer is to | |
| 478 | + * be created | |
| 479 | + * | |
| 480 | + * @return The new character buffer | |
| 481 | + */ | |
| 482 | + public static CharBuffer wrap(CharSequence csq) { | |
| 483 | + return wrap(csq, 0, csq.length()); | |
| 484 | + } | |
| 485 | + | |
| 486 | +#end[char] | |
| 487 | + | |
| 488 | + /** | |
| 489 | + * Creates a new $type$ buffer whose content is a shared subsequence of | |
| 490 | + * this buffer's content. | |
| 491 | + * | |
| 492 | + * <p> The content of the new buffer will start at this buffer's current | |
| 493 | + * position. Changes to this buffer's content will be visible in the new | |
| 494 | + * buffer, and vice versa; the two buffers' position, limit, and mark | |
| 495 | + * values will be independent. | |
| 496 | + * | |
| 497 | + * <p> The new buffer's position will be zero, its capacity and its limit | |
| 498 | + * will be the number of $type$s remaining in this buffer, and its mark | |
| 499 | + * will be undefined. The new buffer will be direct if, and only if, this | |
| 500 | + * buffer is direct, and it will be read-only if, and only if, this buffer | |
| 501 | + * is read-only. </p> | |
| 502 | + * | |
| 503 | + * @return The new $type$ buffer | |
| 504 | + */ | |
| 505 | + public abstract $Type$Buffer slice(); | |
| 506 | + | |
| 507 | + /** | |
| 508 | + * Creates a new $type$ buffer that shares this buffer's content. | |
| 509 | + * | |
| 510 | + * <p> The content of the new buffer will be that of this buffer. Changes | |
| 511 | + * to this buffer's content will be visible in the new buffer, and vice | |
| 512 | + * versa; the two buffers' position, limit, and mark values will be | |
| 513 | + * independent. | |
| 514 | + * | |
| 515 | + * <p> The new buffer's capacity, limit, position, and mark values will be | |
| 516 | + * identical to those of this buffer. The new buffer will be direct if, | |
| 517 | + * and only if, this buffer is direct, and it will be read-only if, and | |
| 518 | + * only if, this buffer is read-only. </p> | |
| 519 | + * | |
| 520 | + * @return The new $type$ buffer | |
| 521 | + */ | |
| 522 | + public abstract $Type$Buffer duplicate(); | |
| 523 | + | |
| 524 | + /** | |
| 525 | + * Creates a new, read-only $type$ buffer that shares this buffer's | |
| 526 | + * content. | |
| 527 | + * | |
| 528 | + * <p> The content of the new buffer will be that of this buffer. Changes | |
| 529 | + * to this buffer's content will be visible in the new buffer; the new | |
| 530 | + * buffer itself, however, will be read-only and will not allow the shared | |
| 531 | + * content to be modified. The two buffers' position, limit, and mark | |
| 532 | + * values will be independent. | |
| 533 | + * | |
| 534 | + * <p> The new buffer's capacity, limit, position, and mark values will be | |
| 535 | + * identical to those of this buffer. | |
| 536 | + * | |
| 537 | + * <p> If this buffer is itself read-only then this method behaves in | |
| 538 | + * exactly the same way as the {@link #duplicate duplicate} method. </p> | |
| 539 | + * | |
| 540 | + * @return The new, read-only $type$ buffer | |
| 541 | + */ | |
| 542 | + public abstract $Type$Buffer asReadOnlyBuffer(); | |
| 543 | + | |
| 544 | + | |
| 545 | + // -- Singleton get/put methods -- | |
| 546 | + | |
| 547 | + /** | |
| 548 | + * Relative <i>get</i> method. Reads the $type$ at this buffer's | |
| 549 | + * current position, and then increments the position. </p> | |
| 550 | + * | |
| 551 | + * @return The $type$ at the buffer's current position | |
| 552 | + * | |
| 553 | + * @throws BufferUnderflowException | |
| 554 | + * If the buffer's current position is not smaller than its limit | |
| 555 | + */ | |
| 556 | + public abstract $type$ get(); | |
| 557 | + | |
| 558 | + /** | |
| 559 | + * Relative <i>put</i> method <i>(optional operation)</i>. | |
| 560 | + * | |
| 561 | + * <p> Writes the given $type$ into this buffer at the current | |
| 562 | + * position, and then increments the position. </p> | |
| 563 | + * | |
| 564 | + * @param $x$ | |
| 565 | + * The $type$ to be written | |
| 566 | + * | |
| 567 | + * @return This buffer | |
| 568 | + * | |
| 569 | + * @throws BufferOverflowException | |
| 570 | + * If this buffer's current position is not smaller than its limit | |
| 571 | + * | |
| 572 | + * @throws ReadOnlyBufferException | |
| 573 | + * If this buffer is read-only | |
| 574 | + */ | |
| 575 | + public abstract $Type$Buffer put($type$ $x$); | |
| 576 | + | |
| 577 | + /** | |
| 578 | + * Absolute <i>get</i> method. Reads the $type$ at the given | |
| 579 | + * index. </p> | |
| 580 | + * | |
| 581 | + * @param index | |
| 582 | + * The index from which the $type$ will be read | |
| 583 | + * | |
| 584 | + * @return The $type$ at the given index | |
| 585 | + * | |
| 586 | + * @throws IndexOutOfBoundsException | |
| 587 | + * If <tt>index</tt> is negative | |
| 588 | + * or not smaller than the buffer's limit | |
| 589 | + */ | |
| 590 | + public abstract $type$ get(int index); | |
| 591 | + | |
| 592 | + /** | |
| 593 | + * Absolute <i>put</i> method <i>(optional operation)</i>. | |
| 594 | + * | |
| 595 | + * <p> Writes the given $type$ into this buffer at the given | |
| 596 | + * index. </p> | |
| 597 | + * | |
| 598 | + * @param index | |
| 599 | + * The index at which the $type$ will be written | |
| 600 | + * | |
| 601 | + * @param $x$ | |
| 602 | + * The $type$ value to be written | |
| 603 | + * | |
| 604 | + * @return This buffer | |
| 605 | + * | |
| 606 | + * @throws IndexOutOfBoundsException | |
| 607 | + * If <tt>index</tt> is negative | |
| 608 | + * or not smaller than the buffer's limit | |
| 609 | + * | |
| 610 | + * @throws ReadOnlyBufferException | |
| 611 | + * If this buffer is read-only | |
| 612 | + */ | |
| 613 | + public abstract $Type$Buffer put(int index, $type$ $x$); | |
| 614 | + | |
| 615 | + | |
| 616 | + // -- Bulk get operations -- | |
| 617 | + | |
| 618 | + /** | |
| 619 | + * Relative bulk <i>get</i> method. | |
| 620 | + * | |
| 621 | + * <p> This method transfers $type$s from this buffer into the given | |
| 622 | + * destination array. If there are fewer $type$s remaining in the | |
| 623 | + * buffer than are required to satisfy the request, that is, if | |
| 624 | + * <tt>length</tt> <tt>></tt> <tt>remaining()</tt>, then no | |
| 625 | + * $type$s are transferred and a {@link BufferUnderflowException} is | |
| 626 | + * thrown. | |
| 627 | + * | |
| 628 | + * <p> Otherwise, this method copies <tt>length</tt> $type$s from this | |
| 629 | + * buffer into the given array, starting at the current position of this | |
| 630 | + * buffer and at the given offset in the array. The position of this | |
| 631 | + * buffer is then incremented by <tt>length</tt>. | |
| 632 | + * | |
| 633 | + * <p> In other words, an invocation of this method of the form | |
| 634 | + * <tt>src.get(dst, off, len)</tt> has exactly the same effect as | |
| 635 | + * the loop | |
| 636 | + * | |
| 637 | + * <pre> | |
| 638 | + * for (int i = off; i < off + len; i++) | |
| 639 | + * dst[i] = src.get(); </pre> | |
| 640 | + * | |
| 641 | + * except that it first checks that there are sufficient $type$s in | |
| 642 | + * this buffer and it is potentially much more efficient. </p> | |
| 643 | + * | |
| 644 | + * @param dst | |
| 645 | + * The array into which $type$s are to be written | |
| 646 | + * | |
| 647 | + * @param offset | |
| 648 | + * The offset within the array of the first $type$ to be | |
| 649 | + * written; must be non-negative and no larger than | |
| 650 | + * <tt>dst.length</tt> | |
| 651 | + * | |
| 652 | + * @param length | |
| 653 | + * The maximum number of $type$s to be written to the given | |
| 654 | + * array; must be non-negative and no larger than | |
| 655 | + * <tt>dst.length - offset</tt> | |
| 656 | + * | |
| 657 | + * @return This buffer | |
| 658 | + * | |
| 659 | + * @throws BufferUnderflowException | |
| 660 | + * If there are fewer than <tt>length</tt> $type$s | |
| 661 | + * remaining in this buffer | |
| 662 | + * | |
| 663 | + * @throws IndexOutOfBoundsException | |
| 664 | + * If the preconditions on the <tt>offset</tt> and <tt>length</tt> | |
| 665 | + * parameters do not hold | |
| 666 | + */ | |
| 667 | + public $Type$Buffer get($type$[] dst, int offset, int length) { | |
| 668 | + checkBounds(offset, length, dst.length); | |
| 669 | + if (length > remaining()) | |
| 670 | + throw new BufferUnderflowException(); | |
| 671 | + int end = offset + length; | |
| 672 | + for (int i = offset; i < end; i++) | |
| 673 | + dst[i] = get(); | |
| 674 | + return this; | |
| 675 | + } | |
| 676 | + | |
| 677 | + /** | |
| 678 | + * Relative bulk <i>get</i> method. | |
| 679 | + * | |
| 680 | + * <p> This method transfers $type$s from this buffer into the given | |
| 681 | + * destination array. An invocation of this method of the form | |
| 682 | + * <tt>src.get(a)</tt> behaves in exactly the same way as the invocation | |
| 683 | + * | |
| 684 | + * <pre> | |
| 685 | + * src.get(a, 0, a.length) </pre> | |
| 686 | + * | |
| 687 | + * @return This buffer | |
| 688 | + * | |
| 689 | + * @throws BufferUnderflowException | |
| 690 | + * If there are fewer than <tt>length</tt> $type$s | |
| 691 | + * remaining in this buffer | |
| 692 | + */ | |
| 693 | + public $Type$Buffer get($type$[] dst) { | |
| 694 | + return get(dst, 0, dst.length); | |
| 695 | + } | |
| 696 | + | |
| 697 | + | |
| 698 | + // -- Bulk put operations -- | |
| 699 | + | |
| 700 | + /** | |
| 701 | + * Relative bulk <i>put</i> method <i>(optional operation)</i>. | |
| 702 | + * | |
| 703 | + * <p> This method transfers the $type$s remaining in the given source | |
| 704 | + * buffer into this buffer. If there are more $type$s remaining in the | |
| 705 | + * source buffer than in this buffer, that is, if | |
| 706 | + * <tt>src.remaining()</tt> <tt>></tt> <tt>remaining()</tt>, | |
| 707 | + * then no $type$s are transferred and a {@link | |
| 708 | + * BufferOverflowException} is thrown. | |
| 709 | + * | |
| 710 | + * <p> Otherwise, this method copies | |
| 711 | + * <i>n</i> = <tt>src.remaining()</tt> $type$s from the given | |
| 712 | + * buffer into this buffer, starting at each buffer's current position. | |
| 713 | + * The positions of both buffers are then incremented by <i>n</i>. | |
| 714 | + * | |
| 715 | + * <p> In other words, an invocation of this method of the form | |
| 716 | + * <tt>dst.put(src)</tt> has exactly the same effect as the loop | |
| 717 | + * | |
| 718 | + * <pre> | |
| 719 | + * while (src.hasRemaining()) | |
| 720 | + * dst.put(src.get()); </pre> | |
| 721 | + * | |
| 722 | + * except that it first checks that there is sufficient space in this | |
| 723 | + * buffer and it is potentially much more efficient. </p> | |
| 724 | + * | |
| 725 | + * @param src | |
| 726 | + * The source buffer from which $type$s are to be read; | |
| 727 | + * must not be this buffer | |
| 728 | + * | |
| 729 | + * @return This buffer | |
| 730 | + * | |
| 731 | + * @throws BufferOverflowException | |
| 732 | + * If there is insufficient space in this buffer | |
| 733 | + * for the remaining $type$s in the source buffer | |
| 734 | + * | |
| 735 | + * @throws IllegalArgumentException | |
| 736 | + * If the source buffer is this buffer | |
| 737 | + * | |
| 738 | + * @throws ReadOnlyBufferException | |
| 739 | + * If this buffer is read-only | |
| 740 | + */ | |
| 741 | + public $Type$Buffer put($Type$Buffer src) { | |
| 742 | + if (src == this) | |
| 743 | + throw new IllegalArgumentException(); | |
| 744 | + int n = src.remaining(); | |
| 745 | + if (n > remaining()) | |
| 746 | + throw new BufferOverflowException(); | |
| 747 | + for (int i = 0; i < n; i++) | |
| 748 | + put(src.get()); | |
| 749 | + return this; | |
| 750 | + } | |
| 751 | + | |
| 752 | + /** | |
| 753 | + * Relative bulk <i>put</i> method <i>(optional operation)</i>. | |
| 754 | + * | |
| 755 | + * <p> This method transfers $type$s into this buffer from the given | |
| 756 | + * source array. If there are more $type$s to be copied from the array | |
| 757 | + * than remain in this buffer, that is, if | |
| 758 | + * <tt>length</tt> <tt>></tt> <tt>remaining()</tt>, then no | |
| 759 | + * $type$s are transferred and a {@link BufferOverflowException} is | |
| 760 | + * thrown. | |
| 761 | + * | |
| 762 | + * <p> Otherwise, this method copies <tt>length</tt> $type$s from the | |
| 763 | + * given array into this buffer, starting at the given offset in the array | |
| 764 | + * and at the current position of this buffer. The position of this buffer | |
| 765 | + * is then incremented by <tt>length</tt>. | |
| 766 | + * | |
| 767 | + * <p> In other words, an invocation of this method of the form | |
| 768 | + * <tt>dst.put(src, off, len)</tt> has exactly the same effect as | |
| 769 | + * the loop | |
| 770 | + * | |
| 771 | + * <pre> | |
| 772 | + * for (int i = off; i < off + len; i++) | |
| 773 | + * dst.put(a[i]); </pre> | |
| 774 | + * | |
| 775 | + * except that it first checks that there is sufficient space in this | |
| 776 | + * buffer and it is potentially much more efficient. </p> | |
| 777 | + * | |
| 778 | + * @param src | |
| 779 | + * The array from which $type$s are to be read | |
| 780 | + * | |
| 781 | + * @param offset | |
| 782 | + * The offset within the array of the first $type$ to be read; | |
| 783 | + * must be non-negative and no larger than <tt>array.length</tt> | |
| 784 | + * | |
| 785 | + * @param length | |
| 786 | + * The number of $type$s to be read from the given array; | |
| 787 | + * must be non-negative and no larger than | |
| 788 | + * <tt>array.length - offset</tt> | |
| 789 | + * | |
| 790 | + * @return This buffer | |
| 791 | + * | |
| 792 | + * @throws BufferOverflowException | |
| 793 | + * If there is insufficient space in this buffer | |
| 794 | + * | |
| 795 | + * @throws IndexOutOfBoundsException | |
| 796 | + * If the preconditions on the <tt>offset</tt> and <tt>length</tt> | |
| 797 | + * parameters do not hold | |
| 798 | + * | |
| 799 | + * @throws ReadOnlyBufferException | |
| 800 | + * If this buffer is read-only | |
| 801 | + */ | |
| 802 | + public $Type$Buffer put($type$[] src, int offset, int length) { | |
| 803 | + checkBounds(offset, length, src.length); | |
| 804 | + if (length > remaining()) | |
| 805 | + throw new BufferOverflowException(); | |
| 806 | + int end = offset + length; | |
| 807 | + for (int i = offset; i < end; i++) | |
| 808 | + this.put(src[i]); | |
| 809 | + return this; | |
| 810 | + } | |
| 811 | + | |
| 812 | + /** | |
| 813 | + * Relative bulk <i>put</i> method <i>(optional operation)</i>. | |
| 814 | + * | |
| 815 | + * <p> This method transfers the entire content of the given source | |
| 816 | + * $type$ array into this buffer. An invocation of this method of the | |
| 817 | + * form <tt>dst.put(a)</tt> behaves in exactly the same way as the | |
| 818 | + * invocation | |
| 819 | + * | |
| 820 | + * <pre> | |
| 821 | + * dst.put(a, 0, a.length) </pre> | |
| 822 | + * | |
| 823 | + * @return This buffer | |
| 824 | + * | |
| 825 | + * @throws BufferOverflowException | |
| 826 | + * If there is insufficient space in this buffer | |
| 827 | + * | |
| 828 | + * @throws ReadOnlyBufferException | |
| 829 | + * If this buffer is read-only | |
| 830 | + */ | |
| 831 | + public final $Type$Buffer put($type$[] src) { | |
| 832 | + return put(src, 0, src.length); | |
| 833 | + } | |
| 834 | + | |
| 835 | +#if[char] | |
| 836 | + | |
| 837 | + /** | |
| 838 | + * Relative bulk <i>put</i> method <i>(optional operation)</i>. | |
| 839 | + * | |
| 840 | + * <p> This method transfers $type$s from the given string into this | |
| 841 | + * buffer. If there are more $type$s to be copied from the string than | |
| 842 | + * remain in this buffer, that is, if | |
| 843 | + * <tt>end - start</tt> <tt>></tt> <tt>remaining()</tt>, | |
| 844 | + * then no $type$s are transferred and a {@link | |
| 845 | + * BufferOverflowException} is thrown. | |
| 846 | + * | |
| 847 | + * <p> Otherwise, this method copies | |
| 848 | + * <i>n</i> = <tt>end</tt> - <tt>start</tt> $type$s | |
| 849 | + * from the given string into this buffer, starting at the given | |
| 850 | + * <tt>start</tt> index and at the current position of this buffer. The | |
| 851 | + * position of this buffer is then incremented by <i>n</i>. | |
| 852 | + * | |
| 853 | + * <p> In other words, an invocation of this method of the form | |
| 854 | + * <tt>dst.put(src, start, end)</tt> has exactly the same effect | |
| 855 | + * as the loop | |
| 856 | + * | |
| 857 | + * <pre> | |
| 858 | + * for (int i = start; i < end; i++) | |
| 859 | + * dst.put(src.charAt(i)); </pre> | |
| 860 | + * | |
| 861 | + * except that it first checks that there is sufficient space in this | |
| 862 | + * buffer and it is potentially much more efficient. </p> | |
| 863 | + * | |
| 864 | + * @param src | |
| 865 | + * The string from which $type$s are to be read | |
| 866 | + * | |
| 867 | + * @param start | |
| 868 | + * The offset within the string of the first $type$ to be read; | |
| 869 | + * must be non-negative and no larger than | |
| 870 | + * <tt>string.length()</tt> | |
| 871 | + * | |
| 872 | + * @param end | |
| 873 | + * The offset within the string of the last $type$ to be read, | |
| 874 | + * plus one; must be non-negative and no larger than | |
| 875 | + * <tt>string.length()</tt> | |
| 876 | + * | |
| 877 | + * @return This buffer | |
| 878 | + * | |
| 879 | + * @throws BufferOverflowException | |
| 880 | + * If there is insufficient space in this buffer | |
| 881 | + * | |
| 882 | + * @throws IndexOutOfBoundsException | |
| 883 | + * If the preconditions on the <tt>start</tt> and <tt>end</tt> | |
| 884 | + * parameters do not hold | |
| 885 | + * | |
| 886 | + * @throws ReadOnlyBufferException | |
| 887 | + * If this buffer is read-only | |
| 888 | + */ | |
| 889 | + public $Type$Buffer put(String src, int start, int end) { | |
| 890 | + checkBounds(start, end - start, src.length()); | |
| 891 | + for (int i = start; i < end; i++) | |
| 892 | + this.put(src.charAt(i)); | |
| 893 | + return this; | |
| 894 | + } | |
| 895 | + | |
| 896 | + /** | |
| 897 | + * Relative bulk <i>put</i> method <i>(optional operation)</i>. | |
| 898 | + * | |
| 899 | + * <p> This method transfers the entire content of the given source string | |
| 900 | + * into this buffer. An invocation of this method of the form | |
| 901 | + * <tt>dst.put(s)</tt> behaves in exactly the same way as the invocation | |
| 902 | + * | |
| 903 | + * <pre> | |
| 904 | + * dst.put(s, 0, s.length()) </pre> | |
| 905 | + * | |
| 906 | + * @return This buffer | |
| 907 | + * | |
| 908 | + * @throws BufferOverflowException | |
| 909 | + * If there is insufficient space in this buffer | |
| 910 | + * | |
| 911 | + * @throws ReadOnlyBufferException | |
| 912 | + * If this buffer is read-only | |
| 913 | + */ | |
| 914 | + public final $Type$Buffer put(String src) { | |
| 915 | + return put(src, 0, src.length()); | |
| 916 | + } | |
| 917 | + | |
| 918 | +#end[char] | |
| 919 | + | |
| 920 | + | |
| 921 | + // -- Other stuff -- | |
| 922 | + | |
| 923 | + /** | |
| 924 | + * Tells whether or not this buffer is backed by an accessible $type$ | |
| 925 | + * array. | |
| 926 | + * | |
| 927 | + * <p> If this method returns <tt>true</tt> then the {@link #array() array} | |
| 928 | + * and {@link #arrayOffset() arrayOffset} methods may safely be invoked. | |
| 929 | + * </p> | |
| 930 | + * | |
| 931 | + * @return <tt>true</tt> if, and only if, this buffer | |
| 932 | + * is backed by an array and is not read-only | |
| 933 | + */ | |
| 934 | + public final boolean hasArray() { | |
| 935 | + return (hb != null) && !isReadOnly; | |
| 936 | + } | |
| 937 | + | |
| 938 | + /** | |
| 939 | + * Returns the $type$ array that backs this | |
| 940 | + * buffer <i>(optional operation)</i>. | |
| 941 | + * | |
| 942 | + * <p> Modifications to this buffer's content will cause the returned | |
| 943 | + * array's content to be modified, and vice versa. | |
| 944 | + * | |
| 945 | + * <p> Invoke the {@link #hasArray hasArray} method before invoking this | |
| 946 | + * method in order to ensure that this buffer has an accessible backing | |
| 947 | + * array. </p> | |
| 948 | + * | |
| 949 | + * @return The array that backs this buffer | |
| 950 | + * | |
| 951 | + * @throws ReadOnlyBufferException | |
| 952 | + * If this buffer is backed by an array but is read-only | |
| 953 | + * | |
| 954 | + * @throws UnsupportedOperationException | |
| 955 | + * If this buffer is not backed by an accessible array | |
| 956 | + */ | |
| 957 | + public final $type$[] array() { | |
| 958 | + if (hb == null) | |
| 959 | + throw new UnsupportedOperationException(); | |
| 960 | + if (isReadOnly) | |
| 961 | + throw new ReadOnlyBufferException(); | |
| 962 | + return hb; | |
| 963 | + } | |
| 964 | + | |
| 965 | + /** | |
| 966 | + * Returns the offset within this buffer's backing array of the first | |
| 967 | + * element of the buffer <i>(optional operation)</i>. | |
| 968 | + * | |
| 969 | + * <p> If this buffer is backed by an array then buffer position <i>p</i> | |
| 970 | + * corresponds to array index <i>p</i> + <tt>arrayOffset()</tt>. | |
| 971 | + * | |
| 972 | + * <p> Invoke the {@link #hasArray hasArray} method before invoking this | |
| 973 | + * method in order to ensure that this buffer has an accessible backing | |
| 974 | + * array. </p> | |
| 975 | + * | |
| 976 | + * @return The offset within this buffer's array | |
| 977 | + * of the first element of the buffer | |
| 978 | + * | |
| 979 | + * @throws ReadOnlyBufferException | |
| 980 | + * If this buffer is backed by an array but is read-only | |
| 981 | + * | |
| 982 | + * @throws UnsupportedOperationException | |
| 983 | + * If this buffer is not backed by an accessible array | |
| 984 | + */ | |
| 985 | + public final int arrayOffset() { | |
| 986 | + if (hb == null) | |
| 987 | + throw new UnsupportedOperationException(); | |
| 988 | + if (isReadOnly) | |
| 989 | + throw new ReadOnlyBufferException(); | |
| 990 | + return offset; | |
| 991 | + } | |
| 992 | + | |
| 993 | + /** | |
| 994 | + * Compacts this buffer <i>(optional operation)</i>. | |
| 995 | + * | |
| 996 | + * <p> The $type$s between the buffer's current position and its limit, | |
| 997 | + * if any, are copied to the beginning of the buffer. That is, the | |
| 998 | + * $type$ at index <i>p</i> = <tt>position()</tt> is copied | |
| 999 | + * to index zero, the $type$ at index <i>p</i> + 1 is copied | |
| 1000 | + * to index one, and so forth until the $type$ at index | |
| 1001 | + * <tt>limit()</tt> - 1 is copied to index | |
| 1002 | + * <i>n</i> = <tt>limit()</tt> - <tt>1</tt> - <i>p</i>. | |
| 1003 | + * The buffer's position is then set to <i>n+1</i> and its limit is set to | |
| 1004 | + * its capacity. The mark, if defined, is discarded. | |
| 1005 | + * | |
| 1006 | + * <p> The buffer's position is set to the number of $type$s copied, | |
| 1007 | + * rather than to zero, so that an invocation of this method can be | |
| 1008 | + * followed immediately by an invocation of another relative <i>put</i> | |
| 1009 | + * method. </p> | |
| 1010 | + * | |
| 1011 | +#if[byte] | |
| 1012 | + * | |
| 1013 | + * <p> Invoke this method after writing data from a buffer in case the | |
| 1014 | + * write was incomplete. The following loop, for example, copies bytes | |
| 1015 | + * from one channel to another via the buffer <tt>buf</tt>: | |
| 1016 | + * | |
| 1017 | + * <blockquote><pre> | |
| 1018 | + * buf.clear(); // Prepare buffer for use | |
| 1019 | + * while (in.read(buf) >= 0 || buf.position != 0) { | |
| 1020 | + * buf.flip(); | |
| 1021 | + * out.write(buf); | |
| 1022 | + * buf.compact(); // In case of partial write | |
| 1023 | + * }</pre></blockquote> | |
| 1024 | + * | |
| 1025 | +#end[byte] | |
| 1026 | + * | |
| 1027 | + * @return This buffer | |
| 1028 | + * | |
| 1029 | + * @throws ReadOnlyBufferException | |
| 1030 | + * If this buffer is read-only | |
| 1031 | + */ | |
| 1032 | + public abstract $Type$Buffer compact(); | |
| 1033 | + | |
| 1034 | + /** | |
| 1035 | + * Tells whether or not this $type$ buffer is direct. </p> | |
| 1036 | + * | |
| 1037 | + * @return <tt>true</tt> if, and only if, this buffer is direct | |
| 1038 | + */ | |
| 1039 | + public abstract boolean isDirect(); | |
| 1040 | + | |
| 1041 | +#if[!char] | |
| 1042 | + | |
| 1043 | + /** | |
| 1044 | + * Returns a string summarizing the state of this buffer. </p> | |
| 1045 | + * | |
| 1046 | + * @return A summary string | |
| 1047 | + */ | |
| 1048 | + public String toString() { | |
| 1049 | + StringBuffer sb = new StringBuffer(); | |
| 1050 | + sb.append(getClass().getName()); | |
| 1051 | + sb.append("[pos="); | |
| 1052 | + sb.append(position()); | |
| 1053 | + sb.append(" lim="); | |
| 1054 | + sb.append(limit()); | |
| 1055 | + sb.append(" cap="); | |
| 1056 | + sb.append(capacity()); | |
| 1057 | + sb.append("]"); | |
| 1058 | + return sb.toString(); | |
| 1059 | + } | |
| 1060 | + | |
| 1061 | +#end[!char] | |
| 1062 | + | |
| 1063 | + | |
| 1064 | + // ## Should really use unchecked accessors here for speed | |
| 1065 | + | |
| 1066 | + /** | |
| 1067 | + * Returns the current hash code of this buffer. | |
| 1068 | + * | |
| 1069 | + * <p> The hash code of a $type$ buffer depends only upon its remaining | |
| 1070 | + * elements; that is, upon the elements from <tt>position()</tt> up to, and | |
| 1071 | + * including, the element at <tt>limit()</tt> - <tt>1</tt>. | |
| 1072 | + * | |
| 1073 | + * <p> Because buffer hash codes are content-dependent, it is inadvisable | |
| 1074 | + * to use buffers as keys in hash maps or similar data structures unless it | |
| 1075 | + * is known that their contents will not change. </p> | |
| 1076 | + * | |
| 1077 | + * @return The current hash code of this buffer | |
| 1078 | + */ | |
| 1079 | + public int hashCode() { | |
| 1080 | + int h = 1; | |
| 1081 | + int p = position(); | |
| 1082 | + for (int i = limit() - 1; i >= p; i--) | |
| 1083 | + h = 31 * h + (int)get(i); | |
| 1084 | + return h; | |
| 1085 | + } | |
| 1086 | + | |
| 1087 | + /** | |
| 1088 | + * Tells whether or not this buffer is equal to another object. | |
| 1089 | + * | |
| 1090 | + * <p> Two $type$ buffers are equal if, and only if, | |
| 1091 | + * | |
| 1092 | + * <p><ol> | |
| 1093 | + * | |
| 1094 | + * <li><p> They have the same element type, </p></li> | |
| 1095 | + * | |
| 1096 | + * <li><p> They have the same number of remaining elements, and | |
| 1097 | + * </p></li> | |
| 1098 | + * | |
| 1099 | + * <li><p> The two sequences of remaining elements, considered | |
| 1100 | + * independently of their starting positions, are pointwise equal. | |
| 1101 | +#if[floatingPointType] | |
| 1102 | + * This method considers two $type$ elements {@code a} and {@code b} | |
| 1103 | + * to be equal if | |
| 1104 | + * {@code (a == b) || ($Fulltype$.isNaN(a) && $Fulltype$.isNaN(b))}. | |
| 1105 | + * The values {@code -0.0} and {@code +0.0} are considered to be | |
| 1106 | + * equal, unlike {@link $Fulltype$#equals(Object)}. | |
| 1107 | +#end[floatingPointType] | |
| 1108 | + * </p></li> | |
| 1109 | + * | |
| 1110 | + * </ol> | |
| 1111 | + * | |
| 1112 | + * <p> A $type$ buffer is not equal to any other type of object. </p> | |
| 1113 | + * | |
| 1114 | + * @param ob The object to which this buffer is to be compared | |
| 1115 | + * | |
| 1116 | + * @return <tt>true</tt> if, and only if, this buffer is equal to the | |
| 1117 | + * given object | |
| 1118 | + */ | |
| 1119 | + public boolean equals(Object ob) { | |
| 1120 | + if (this == ob) | |
| 1121 | + return true; | |
| 1122 | + if (!(ob instanceof $Type$Buffer)) | |
| 1123 | + return false; | |
| 1124 | + $Type$Buffer that = ($Type$Buffer)ob; | |
| 1125 | + if (this.remaining() != that.remaining()) | |
| 1126 | + return false; | |
| 1127 | + int p = this.position(); | |
| 1128 | + for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--) | |
| 1129 | + if (!equals(this.get(i), that.get(j))) | |
| 1130 | + return false; | |
| 1131 | + return true; | |
| 1132 | + } | |
| 1133 | + | |
| 1134 | + private static boolean equals($type$ x, $type$ y) { | |
| 1135 | +#if[floatingPointType] | |
| 1136 | + return (x == y) || ($Fulltype$.isNaN(x) && $Fulltype$.isNaN(y)); | |
| 1137 | +#else[floatingPointType] | |
| 1138 | + return x == y; | |
| 1139 | +#end[floatingPointType] | |
| 1140 | + } | |
| 1141 | + | |
| 1142 | + /** | |
| 1143 | + * Compares this buffer to another. | |
| 1144 | + * | |
| 1145 | + * <p> Two $type$ buffers are compared by comparing their sequences of | |
| 1146 | + * remaining elements lexicographically, without regard to the starting | |
| 1147 | + * position of each sequence within its corresponding buffer. | |
| 1148 | +#if[floatingPointType] | |
| 1149 | + * Pairs of {@code $type$} elements are compared as if by invoking | |
| 1150 | + * {@link $Fulltype$#compare($type$,$type$)}, except that | |
| 1151 | + * {@code -0.0} and {@code 0.0} are considered to be equal. | |
| 1152 | + * {@code $Fulltype$.NaN} is considered by this method to be equal | |
| 1153 | + * to itself and greater than all other {@code $type$} values | |
| 1154 | + * (including {@code $Fulltype$.POSITIVE_INFINITY}). | |
| 1155 | +#else[floatingPointType] | |
| 1156 | + * Pairs of {@code $type$} elements are compared as if by invoking | |
| 1157 | + * {@link $Fulltype$#compare($type$,$type$)}. | |
| 1158 | +#end[floatingPointType] | |
| 1159 | + * | |
| 1160 | + * <p> A $type$ buffer is not comparable to any other type of object. | |
| 1161 | + * | |
| 1162 | + * @return A negative integer, zero, or a positive integer as this buffer | |
| 1163 | + * is less than, equal to, or greater than the given buffer | |
| 1164 | + */ | |
| 1165 | + public int compareTo($Type$Buffer that) { | |
| 1166 | + int n = this.position() + Math.min(this.remaining(), that.remaining()); | |
| 1167 | + for (int i = this.position(), j = that.position(); i < n; i++, j++) { | |
| 1168 | + int cmp = compare(this.get(i), that.get(j)); | |
| 1169 | + if (cmp != 0) | |
| 1170 | + return cmp; | |
| 1171 | + } | |
| 1172 | + return this.remaining() - that.remaining(); | |
| 1173 | + } | |
| 1174 | + | |
| 1175 | + private static int compare($type$ x, $type$ y) { | |
| 1176 | +#if[floatingPointType] | |
| 1177 | + return ((x < y) ? -1 : | |
| 1178 | + (x > y) ? +1 : | |
| 1179 | + (x == y) ? 0 : | |
| 1180 | + $Fulltype$.isNaN(x) ? ($Fulltype$.isNaN(y) ? 0 : +1) : -1); | |
| 1181 | +#else[floatingPointType] | |
| 1182 | + return $Fulltype$.compare(x, y); | |
| 1183 | +#end[floatingPointType] | |
| 1184 | + } | |
| 1185 | + | |
| 1186 | + // -- Other char stuff -- | |
| 1187 | + | |
| 1188 | +#if[char] | |
| 1189 | + | |
| 1190 | + /** | |
| 1191 | + * Returns a string containing the characters in this buffer. | |
| 1192 | + * | |
| 1193 | + * <p> The first character of the resulting string will be the character at | |
| 1194 | + * this buffer's position, while the last character will be the character | |
| 1195 | + * at index <tt>limit()</tt> - 1. Invoking this method does not | |
| 1196 | + * change the buffer's position. </p> | |
| 1197 | + * | |
| 1198 | + * @return The specified string | |
| 1199 | + */ | |
| 1200 | + public String toString() { | |
| 1201 | + return toString(position(), limit()); | |
| 1202 | + } | |
| 1203 | + | |
| 1204 | + abstract String toString(int start, int end); // package-private | |
| 1205 | + | |
| 1206 | + | |
| 1207 | + // --- Methods to support CharSequence --- | |
| 1208 | + | |
| 1209 | + /** | |
| 1210 | + * Returns the length of this character buffer. | |
| 1211 | + * | |
| 1212 | + * <p> When viewed as a character sequence, the length of a character | |
| 1213 | + * buffer is simply the number of characters between the position | |
| 1214 | + * (inclusive) and the limit (exclusive); that is, it is equivalent to | |
| 1215 | + * <tt>remaining()</tt>. </p> | |
| 1216 | + * | |
| 1217 | + * @return The length of this character buffer | |
| 1218 | + */ | |
| 1219 | + public final int length() { | |
| 1220 | + return remaining(); | |
| 1221 | + } | |
| 1222 | + | |
| 1223 | + /** | |
| 1224 | + * Reads the character at the given index relative to the current | |
| 1225 | + * position. </p> | |
| 1226 | + * | |
| 1227 | + * @param index | |
| 1228 | + * The index of the character to be read, relative to the position; | |
| 1229 | + * must be non-negative and smaller than <tt>remaining()</tt> | |
| 1230 | + * | |
| 1231 | + * @return The character at index | |
| 1232 | + * <tt>position() + index</tt> | |
| 1233 | + * | |
| 1234 | + * @throws IndexOutOfBoundsException | |
| 1235 | + * If the preconditions on <tt>index</tt> do not hold | |
| 1236 | + */ | |
| 1237 | + public final char charAt(int index) { | |
| 1238 | + return get(position() + checkIndex(index, 1)); | |
| 1239 | + } | |
| 1240 | + | |
| 1241 | + /** | |
| 1242 | + * Creates a new character buffer that represents the specified subsequence | |
| 1243 | + * of this buffer, relative to the current position. | |
| 1244 | + * | |
| 1245 | + * <p> The new buffer will share this buffer's content; that is, if the | |
| 1246 | + * content of this buffer is mutable then modifications to one buffer will | |
| 1247 | + * cause the other to be modified. The new buffer's capacity will be that | |
| 1248 | + * of this buffer, its position will be | |
| 1249 | + * <tt>position()</tt> + <tt>start</tt>, and its limit will be | |
| 1250 | + * <tt>position()</tt> + <tt>end</tt>. The new buffer will be | |
| 1251 | + * direct if, and only if, this buffer is direct, and it will be read-only | |
| 1252 | + * if, and only if, this buffer is read-only. </p> | |
| 1253 | + * | |
| 1254 | + * @param start | |
| 1255 | + * The index, relative to the current position, of the first | |
| 1256 | + * character in the subsequence; must be non-negative and no larger | |
| 1257 | + * than <tt>remaining()</tt> | |
| 1258 | + * | |
| 1259 | + * @param end | |
| 1260 | + * The index, relative to the current position, of the character | |
| 1261 | + * following the last character in the subsequence; must be no | |
| 1262 | + * smaller than <tt>start</tt> and no larger than | |
| 1263 | + * <tt>remaining()</tt> | |
| 1264 | + * | |
| 1265 | + * @return The new character buffer | |
| 1266 | + * | |
| 1267 | + * @throws IndexOutOfBoundsException | |
| 1268 | + * If the preconditions on <tt>start</tt> and <tt>end</tt> | |
| 1269 | + * do not hold | |
| 1270 | + */ | |
| 1271 | + public abstract CharBuffer subSequence(int start, int end); | |
| 1272 | + | |
| 1273 | + | |
| 1274 | + // --- Methods to support Appendable --- | |
| 1275 | + | |
| 1276 | + /** | |
| 1277 | + * Appends the specified character sequence to this | |
| 1278 | + * buffer <i>(optional operation)</i>. | |
| 1279 | + * | |
| 1280 | + * <p> An invocation of this method of the form <tt>dst.append(csq)</tt> | |
| 1281 | + * behaves in exactly the same way as the invocation | |
| 1282 | + * | |
| 1283 | + * <pre> | |
| 1284 | + * dst.put(csq.toString()) </pre> | |
| 1285 | + * | |
| 1286 | + * <p> Depending on the specification of <tt>toString</tt> for the | |
| 1287 | + * character sequence <tt>csq</tt>, the entire sequence may not be | |
| 1288 | + * appended. For instance, invoking the {@link $Type$Buffer#toString() | |
| 1289 | + * toString} method of a character buffer will return a subsequence whose | |
| 1290 | + * content depends upon the buffer's position and limit. | |
| 1291 | + * | |
| 1292 | + * @param csq | |
| 1293 | + * The character sequence to append. If <tt>csq</tt> is | |
| 1294 | + * <tt>null</tt>, then the four characters <tt>"null"</tt> are | |
| 1295 | + * appended to this character buffer. | |
| 1296 | + * | |
| 1297 | + * @return This buffer | |
| 1298 | + * | |
| 1299 | + * @throws BufferOverflowException | |
| 1300 | + * If there is insufficient space in this buffer | |
| 1301 | + * | |
| 1302 | + * @throws ReadOnlyBufferException | |
| 1303 | + * If this buffer is read-only | |
| 1304 | + * | |
| 1305 | + * @since 1.5 | |
| 1306 | + */ | |
| 1307 | + public $Type$Buffer append(CharSequence csq) { | |
| 1308 | + if (csq == null) | |
| 1309 | + return put("null"); | |
| 1310 | + else | |
| 1311 | + return put(csq.toString()); | |
| 1312 | + } | |
| 1313 | + | |
| 1314 | + /** | |
| 1315 | + * Appends a subsequence of the specified character sequence to this | |
| 1316 | + * buffer <i>(optional operation)</i>. | |
| 1317 | + * | |
| 1318 | + * <p> An invocation of this method of the form <tt>dst.append(csq, start, | |
| 1319 | + * end)</tt> when <tt>csq</tt> is not <tt>null</tt>, behaves in exactly the | |
| 1320 | + * same way as the invocation | |
| 1321 | + * | |
| 1322 | + * <pre> | |
| 1323 | + * dst.put(csq.subSequence(start, end).toString()) </pre> | |
| 1324 | + * | |
| 1325 | + * @param csq | |
| 1326 | + * The character sequence from which a subsequence will be | |
| 1327 | + * appended. If <tt>csq</tt> is <tt>null</tt>, then characters | |
| 1328 | + * will be appended as if <tt>csq</tt> contained the four | |
| 1329 | + * characters <tt>"null"</tt>. | |
| 1330 | + * | |
| 1331 | + * @return This buffer | |
| 1332 | + * | |
| 1333 | + * @throws BufferOverflowException | |
| 1334 | + * If there is insufficient space in this buffer | |
| 1335 | + * | |
| 1336 | + * @throws IndexOutOfBoundsException | |
| 1337 | + * If <tt>start</tt> or <tt>end</tt> are negative, <tt>start</tt> | |
| 1338 | + * is greater than <tt>end</tt>, or <tt>end</tt> is greater than | |
| 1339 | + * <tt>csq.length()</tt> | |
| 1340 | + * | |
| 1341 | + * @throws ReadOnlyBufferException | |
| 1342 | + * If this buffer is read-only | |
| 1343 | + * | |
| 1344 | + * @since 1.5 | |
| 1345 | + */ | |
| 1346 | + public $Type$Buffer append(CharSequence csq, int start, int end) { | |
| 1347 | + CharSequence cs = (csq == null ? "null" : csq); | |
| 1348 | + return put(cs.subSequence(start, end).toString()); | |
| 1349 | + } | |
| 1350 | + | |
| 1351 | + /** | |
| 1352 | + * Appends the specified $type$ to this | |
| 1353 | + * buffer <i>(optional operation)</i>. | |
| 1354 | + * | |
| 1355 | + * <p> An invocation of this method of the form <tt>dst.append($x$)</tt> | |
| 1356 | + * behaves in exactly the same way as the invocation | |
| 1357 | + * | |
| 1358 | + * <pre> | |
| 1359 | + * dst.put($x$) </pre> | |
| 1360 | + * | |
| 1361 | + * @param $x$ | |
| 1362 | + * The 16-bit $type$ to append | |
| 1363 | + * | |
| 1364 | + * @return This buffer | |
| 1365 | + * | |
| 1366 | + * @throws BufferOverflowException | |
| 1367 | + * If there is insufficient space in this buffer | |
| 1368 | + * | |
| 1369 | + * @throws ReadOnlyBufferException | |
| 1370 | + * If this buffer is read-only | |
| 1371 | + * | |
| 1372 | + * @since 1.5 | |
| 1373 | + */ | |
| 1374 | + public $Type$Buffer append($type$ $x$) { | |
| 1375 | + return put($x$); | |
| 1376 | + } | |
| 1377 | + | |
| 1378 | +#end[char] | |
| 1379 | + | |
| 1380 | + | |
| 1381 | + // -- Other byte stuff: Access to binary data -- | |
| 1382 | + | |
| 1383 | +#if[!byte] | |
| 1384 | + | |
| 1385 | + /** | |
| 1386 | + * Retrieves this buffer's byte order. | |
| 1387 | + * | |
| 1388 | + * <p> The byte order of $a$ $type$ buffer created by allocation or by | |
| 1389 | + * wrapping an existing <tt>$type$</tt> array is the {@link | |
| 1390 | + * ByteOrder#nativeOrder </code>native order<code>} of the underlying | |
| 1391 | + * hardware. The byte order of $a$ $type$ buffer created as a <a | |
| 1392 | + * href="ByteBuffer.html#views">view</a> of a byte buffer is that of the | |
| 1393 | + * byte buffer at the moment that the view is created. </p> | |
| 1394 | + * | |
| 1395 | + * @return This buffer's byte order | |
| 1396 | + */ | |
| 1397 | + public abstract ByteOrder order(); | |
| 1398 | + | |
| 1399 | +#end[!byte] | |
| 1400 | + | |
| 1401 | +#if[byte] | |
| 1402 | + | |
| 1403 | + boolean bigEndian // package-private | |
| 1404 | + = true; | |
| 1405 | + boolean nativeByteOrder // package-private | |
| 1406 | + = (Bits.byteOrder() == ByteOrder.BIG_ENDIAN); | |
| 1407 | + | |
| 1408 | + /** | |
| 1409 | + * Retrieves this buffer's byte order. | |
| 1410 | + * | |
| 1411 | + * <p> The byte order is used when reading or writing multibyte values, and | |
| 1412 | + * when creating buffers that are views of this byte buffer. The order of | |
| 1413 | + * a newly-created byte buffer is always {@link ByteOrder#BIG_ENDIAN | |
| 1414 | + * BIG_ENDIAN}. </p> | |
| 1415 | + * | |
| 1416 | + * @return This buffer's byte order | |
| 1417 | + */ | |
| 1418 | + public final ByteOrder order() { | |
| 1419 | + return bigEndian ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN; | |
| 1420 | + } | |
| 1421 | + | |
| 1422 | + /** | |
| 1423 | + * Modifies this buffer's byte order. </p> | |
| 1424 | + * | |
| 1425 | + * @param bo | |
| 1426 | + * The new byte order, | |
| 1427 | + * either {@link ByteOrder#BIG_ENDIAN BIG_ENDIAN} | |
| 1428 | + * or {@link ByteOrder#LITTLE_ENDIAN LITTLE_ENDIAN} | |
| 1429 | + * | |
| 1430 | + * @return This buffer | |
| 1431 | + */ | |
| 1432 | + public final $Type$Buffer order(ByteOrder bo) { | |
| 1433 | + bigEndian = (bo == ByteOrder.BIG_ENDIAN); | |
| 1434 | + nativeByteOrder = | |
| 1435 | + (bigEndian == (Bits.byteOrder() == ByteOrder.BIG_ENDIAN)); | |
| 1436 | + return this; | |
| 1437 | + } | |
| 1438 | + | |
| 1439 | + // Unchecked accessors, for use by ByteBufferAs-X-Buffer classes | |
| 1440 | + // | |
| 1441 | + abstract byte _get(int i); // package-private | |
| 1442 | + abstract void _put(int i, byte b); // package-private | |
| 1443 | + | |
| 1444 | + // #BIN | |
| 1445 | + // | |
| 1446 | + // Binary-data access methods for short, char, int, long, float, | |
| 1447 | + // and double will be inserted here | |
| 1448 | + | |
| 1449 | +#end[byte] | |
| 1450 | + | |
| 1451 | +} | |
Binary file not shown.
| @@ -0,0 +1,209 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels; | |
| 27 | + | |
| 28 | +import java.nio.ByteBuffer; | |
| 29 | +import java.util.concurrent.Future; | |
| 30 | + | |
| 31 | +/** | |
| 32 | + * An asynchronous channel that can read and write bytes. | |
| 33 | + * | |
| 34 | + * <p> Some channels may not allow more than one read or write to be outstanding | |
| 35 | + * at any given time. If a thread invokes a read method before a previous read | |
| 36 | + * operation has completed then a {@link ReadPendingException} will be thrown. | |
| 37 | + * Similarly, if a write method is invoked before a previous write has completed | |
| 38 | + * then {@link WritePendingException} is thrown. Whether or not other kinds of | |
| 39 | + * I/O operations may proceed concurrently with a read operation depends upon | |
| 40 | + * the type of the channel. | |
| 41 | + * | |
| 42 | + * <p> Note that {@link java.nio.ByteBuffer ByteBuffers} are not safe for use by | |
| 43 | + * multiple concurrent threads. When a read or write operation is initiated then | |
| 44 | + * care must be taken to ensure that the buffer is not accessed until the | |
| 45 | + * operation completes. | |
| 46 | + * | |
| 47 | + * @see Channels#newInputStream(AsynchronousByteChannel) | |
| 48 | + * @see Channels#newOutputStream(AsynchronousByteChannel) | |
| 49 | + * | |
| 50 | + * @since 1.7 | |
| 51 | + */ | |
| 52 | + | |
| 53 | +public interface AsynchronousByteChannel | |
| 54 | + extends AsynchronousChannel | |
| 55 | +{ | |
| 56 | + /** | |
| 57 | + * Reads a sequence of bytes from this channel into the given buffer. | |
| 58 | + * | |
| 59 | + * <p> This method initiates an asynchronous read operation to read a | |
| 60 | + * sequence of bytes from this channel into the given buffer. The {@code | |
| 61 | + * handler} parameter is a completion handler that is invoked when the read | |
| 62 | + * operation completes (or fails). The result passed to the completion | |
| 63 | + * handler is the number of bytes read or {@code -1} if no bytes could be | |
| 64 | + * read because the channel has reached end-of-stream. | |
| 65 | + * | |
| 66 | + * <p> The read operation may read up to <i>r</i> bytes from the channel, | |
| 67 | + * where <i>r</i> is the number of bytes remaining in the buffer, that is, | |
| 68 | + * {@code dst.remaining()} at the time that the read is attempted. Where | |
| 69 | + * <i>r</i> is 0, the read operation completes immediately with a result of | |
| 70 | + * {@code 0} without initiating an I/O operation. | |
| 71 | + * | |
| 72 | + * <p> Suppose that a byte sequence of length <i>n</i> is read, where | |
| 73 | + * <tt>0</tt> <tt><</tt> <i>n</i> <tt><=</tt> <i>r</i>. | |
| 74 | + * This byte sequence will be transferred into the buffer so that the first | |
| 75 | + * byte in the sequence is at index <i>p</i> and the last byte is at index | |
| 76 | + * <i>p</i> <tt>+</tt> <i>n</i> <tt>-</tt> <tt>1</tt>, | |
| 77 | + * where <i>p</i> is the buffer's position at the moment the read is | |
| 78 | + * performed. Upon completion the buffer's position will be equal to | |
| 79 | + * <i>p</i> <tt>+</tt> <i>n</i>; its limit will not have changed. | |
| 80 | + * | |
| 81 | + * <p> Buffers are not safe for use by multiple concurrent threads so care | |
| 82 | + * should be taken to not access the buffer until the operation has | |
| 83 | + * completed. | |
| 84 | + * | |
| 85 | + * <p> This method may be invoked at any time. Some channel types may not | |
| 86 | + * allow more than one read to be outstanding at any given time. If a thread | |
| 87 | + * initiates a read operation before a previous read operation has | |
| 88 | + * completed then a {@link ReadPendingException} will be thrown. | |
| 89 | + * | |
| 90 | + * @param dst | |
| 91 | + * The buffer into which bytes are to be transferred | |
| 92 | + * @param attachment | |
| 93 | + * The object to attach to the I/O operation; can be {@code null} | |
| 94 | + * @param handler | |
| 95 | + * The completion handler | |
| 96 | + * | |
| 97 | + * @throws IllegalArgumentException | |
| 98 | + * If the buffer is read-only | |
| 99 | + * @throws ReadPendingException | |
| 100 | + * If the channel does not allow more than one read to be outstanding | |
| 101 | + * and a previous read has not completed | |
| 102 | + * @throws ShutdownChannelGroupException | |
| 103 | + * If the channel is associated with a {@link AsynchronousChannelGroup | |
| 104 | + * group} that has terminated | |
| 105 | + */ | |
| 106 | + <A> void read(ByteBuffer dst, | |
| 107 | + A attachment, | |
| 108 | + CompletionHandler<Integer,? super A> handler); | |
| 109 | + | |
| 110 | + /** | |
| 111 | + * Reads a sequence of bytes from this channel into the given buffer. | |
| 112 | + * | |
| 113 | + * <p> This method initiates an asynchronous read operation to read a | |
| 114 | + * sequence of bytes from this channel into the given buffer. The method | |
| 115 | + * behaves in exactly the same manner as the {@link | |
| 116 | + * #read(ByteBuffer,Object,CompletionHandler) | |
| 117 | + * read(ByteBuffer,Object,CompletionHandler)} method except that instead | |
| 118 | + * of specifying a completion handler, this method returns a {@code Future} | |
| 119 | + * representing the pending result. The {@code Future}'s {@link Future#get() | |
| 120 | + * get} method returns the number of bytes read or {@code -1} if no bytes | |
| 121 | + * could be read because the channel has reached end-of-stream. | |
| 122 | + * | |
| 123 | + * @param dst | |
| 124 | + * The buffer into which bytes are to be transferred | |
| 125 | + * | |
| 126 | + * @return A Future representing the result of the operation | |
| 127 | + * | |
| 128 | + * @throws IllegalArgumentException | |
| 129 | + * If the buffer is read-only | |
| 130 | + * @throws ReadPendingException | |
| 131 | + * If the channel does not allow more than one read to be outstanding | |
| 132 | + * and a previous read has not completed | |
| 133 | + */ | |
| 134 | + Future<Integer> read(ByteBuffer dst); | |
| 135 | + | |
| 136 | + /** | |
| 137 | + * Writes a sequence of bytes to this channel from the given buffer. | |
| 138 | + * | |
| 139 | + * <p> This method initiates an asynchronous write operation to write a | |
| 140 | + * sequence of bytes to this channel from the given buffer. The {@code | |
| 141 | + * handler} parameter is a completion handler that is invoked when the write | |
| 142 | + * operation completes (or fails). The result passed to the completion | |
| 143 | + * handler is the number of bytes written. | |
| 144 | + * | |
| 145 | + * <p> The write operation may write up to <i>r</i> bytes to the channel, | |
| 146 | + * where <i>r</i> is the number of bytes remaining in the buffer, that is, | |
| 147 | + * {@code src.remaining()} at the time that the write is attempted. Where | |
| 148 | + * <i>r</i> is 0, the write operation completes immediately with a result of | |
| 149 | + * {@code 0} without initiating an I/O operation. | |
| 150 | + * | |
| 151 | + * <p> Suppose that a byte sequence of length <i>n</i> is written, where | |
| 152 | + * <tt>0</tt> <tt><</tt> <i>n</i> <tt><=</tt> <i>r</i>. | |
| 153 | + * This byte sequence will be transferred from the buffer starting at index | |
| 154 | + * <i>p</i>, where <i>p</i> is the buffer's position at the moment the | |
| 155 | + * write is performed; the index of the last byte written will be | |
| 156 | + * <i>p</i> <tt>+</tt> <i>n</i> <tt>-</tt> <tt>1</tt>. | |
| 157 | + * Upon completion the buffer's position will be equal to | |
| 158 | + * <i>p</i> <tt>+</tt> <i>n</i>; its limit will not have changed. | |
| 159 | + * | |
| 160 | + * <p> Buffers are not safe for use by multiple concurrent threads so care | |
| 161 | + * should be taken to not access the buffer until the operation has | |
| 162 | + * completed. | |
| 163 | + * | |
| 164 | + * <p> This method may be invoked at any time. Some channel types may not | |
| 165 | + * allow more than one write to be outstanding at any given time. If a thread | |
| 166 | + * initiates a write operation before a previous write operation has | |
| 167 | + * completed then a {@link WritePendingException} will be thrown. | |
| 168 | + * | |
| 169 | + * @param src | |
| 170 | + * The buffer from which bytes are to be retrieved | |
| 171 | + * @param attachment | |
| 172 | + * The object to attach to the I/O operation; can be {@code null} | |
| 173 | + * @param handler | |
| 174 | + * The completion handler object | |
| 175 | + * | |
| 176 | + * @throws WritePendingException | |
| 177 | + * If the channel does not allow more than one write to be outstanding | |
| 178 | + * and a previous write has not completed | |
| 179 | + * @throws ShutdownChannelGroupException | |
| 180 | + * If the channel is associated with a {@link AsynchronousChannelGroup | |
| 181 | + * group} that has terminated | |
| 182 | + */ | |
| 183 | + <A> void write(ByteBuffer src, | |
| 184 | + A attachment, | |
| 185 | + CompletionHandler<Integer,? super A> handler); | |
| 186 | + | |
| 187 | + /** | |
| 188 | + * Writes a sequence of bytes to this channel from the given buffer. | |
| 189 | + * | |
| 190 | + * <p> This method initiates an asynchronous write operation to write a | |
| 191 | + * sequence of bytes to this channel from the given buffer. The method | |
| 192 | + * behaves in exactly the same manner as the {@link | |
| 193 | + * #write(ByteBuffer,Object,CompletionHandler) | |
| 194 | + * write(ByteBuffer,Object,CompletionHandler)} method except that instead | |
| 195 | + * of specifying a completion handler, this method returns a {@code Future} | |
| 196 | + * representing the pending result. The {@code Future}'s {@link Future#get() | |
| 197 | + * get} method returns the number of bytes written. | |
| 198 | + * | |
| 199 | + * @param src | |
| 200 | + * The buffer from which bytes are to be retrieved | |
| 201 | + * | |
| 202 | + * @return A Future representing the result of the operation | |
| 203 | + * | |
| 204 | + * @throws WritePendingException | |
| 205 | + * If the channel does not allow more than one write to be outstanding | |
| 206 | + * and a previous write has not completed | |
| 207 | + */ | |
| 208 | + Future<Integer> write(ByteBuffer src); | |
| 209 | +} | |
Binary file not shown.
| @@ -0,0 +1,117 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels; | |
| 27 | + | |
| 28 | +import java.io.IOException; | |
| 29 | +import java.util.concurrent.Future; // javadoc | |
| 30 | + | |
| 31 | +/** | |
| 32 | + * A channel that supports asynchronous I/O operations. Asynchronous I/O | |
| 33 | + * operations will usually take one of two forms: | |
| 34 | + * | |
| 35 | + * <ol> | |
| 36 | + * <li><pre>{@link Future}<V> <em>operation</em>(<em>...</em>)</pre></li> | |
| 37 | + * <li><pre>void <em>operation</em>(<em>...</em> A attachment, {@link | |
| 38 | + * CompletionHandler}<V,? super A> handler)</pre></li> | |
| 39 | + * </ol> | |
| 40 | + * | |
| 41 | + * where <i>operation</i> is the name of the I/O operation (read or write for | |
| 42 | + * example), <i>V</i> is the result type of the I/O operation, and <i>A</i> is | |
| 43 | + * the type of an object attached to the I/O operation to provide context when | |
| 44 | + * consuming the result. The attachment is important for cases where a | |
| 45 | + * <em>state-less</em> {@code CompletionHandler} is used to consume the result | |
| 46 | + * of many I/O operations. | |
| 47 | + * | |
| 48 | + * <p> In the first form, the methods defined by the {@link Future Future} | |
| 49 | + * interface may be used to check if the operation has completed, wait for its | |
| 50 | + * completion, and to retrieve the result. In the second form, a {@link | |
| 51 | + * CompletionHandler} is invoked to consume the result of the I/O operation when | |
| 52 | + * it completes or fails. | |
| 53 | + * | |
| 54 | + * <p> A channel that implements this interface is <em>asynchronously | |
| 55 | + * closeable</em>: If an I/O operation is outstanding on the channel and the | |
| 56 | + * channel's {@link #close close} method is invoked, then the I/O operation | |
| 57 | + * fails with the exception {@link AsynchronousCloseException}. | |
| 58 | + * | |
| 59 | + * <p> Asynchronous channels are safe for use by multiple concurrent threads. | |
| 60 | + * Some channel implementations may support concurrent reading and writing, but | |
| 61 | + * may not allow more than one read and one write operation to be outstanding at | |
| 62 | + * any given time. | |
| 63 | + * | |
| 64 | + * <h4>Cancellation</h4> | |
| 65 | + * | |
| 66 | + * <p> The {@code Future} interface defines the {@link Future#cancel cancel} | |
| 67 | + * method to cancel execution. This causes all threads waiting on the result of | |
| 68 | + * the I/O operation to throw {@link java.util.concurrent.CancellationException}. | |
| 69 | + * Whether the underlying I/O operation can be cancelled is highly implementation | |
| 70 | + * specific and therefore not specified. Where cancellation leaves the channel, | |
| 71 | + * or the entity to which it is connected, in an inconsistent state, then the | |
| 72 | + * channel is put into an implementation specific <em>error state</em> that | |
| 73 | + * prevents further attempts to initiate I/O operations that are <i>similar</i> | |
| 74 | + * to the operation that was cancelled. For example, if a read operation is | |
| 75 | + * cancelled but the implementation cannot guarantee that bytes have not been | |
| 76 | + * read from the channel then it puts the channel into an error state; further | |
| 77 | + * attempts to initiate a {@code read} operation cause an unspecified runtime | |
| 78 | + * exception to be thrown. Similarly, if a write operation is cancelled but the | |
| 79 | + * implementation cannot guarantee that bytes have not been written to the | |
| 80 | + * channel then subsequent attempts to initiate a {@code write} will fail with | |
| 81 | + * an unspecified runtime exception. | |
| 82 | + * | |
| 83 | + * <p> Where the {@link Future#cancel cancel} method is invoked with the {@code | |
| 84 | + * mayInterruptIfRunning} parameter set to {@code true} then the I/O operation | |
| 85 | + * may be interrupted by closing the channel. In that case all threads waiting | |
| 86 | + * on the result of the I/O operation throw {@code CancellationException} and | |
| 87 | + * any other I/O operations outstanding on the channel complete with the | |
| 88 | + * exception {@link AsynchronousCloseException}. | |
| 89 | + * | |
| 90 | + * <p> Where the {@code cancel} method is invoked to cancel read or write | |
| 91 | + * operations then it is recommended that all buffers used in the I/O operations | |
| 92 | + * be discarded or care taken to ensure that the buffers are not accessed while | |
| 93 | + * the channel remains open. | |
| 94 | + * | |
| 95 | + * @since 1.7 | |
| 96 | + */ | |
| 97 | + | |
| 98 | +public interface AsynchronousChannel | |
| 99 | + extends Channel | |
| 100 | +{ | |
| 101 | + /** | |
| 102 | + * Closes this channel. | |
| 103 | + * | |
| 104 | + * <p> Any outstanding asynchronous operations upon this channel will | |
| 105 | + * complete with the exception {@link AsynchronousCloseException}. After a | |
| 106 | + * channel is closed, further attempts to initiate asynchronous I/O | |
| 107 | + * operations complete immediately with cause {@link ClosedChannelException}. | |
| 108 | + * | |
| 109 | + * <p> This method otherwise behaves exactly as specified by the {@link | |
| 110 | + * Channel} interface. | |
| 111 | + * | |
| 112 | + * @throws IOException | |
| 113 | + * If an I/O error occurs | |
| 114 | + */ | |
| 115 | + @Override | |
| 116 | + void close() throws IOException; | |
| 117 | +} | |
Binary file not shown.
| @@ -0,0 +1,344 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels; | |
| 27 | + | |
| 28 | +import java.nio.channels.spi.AsynchronousChannelProvider; | |
| 29 | +import java.io.IOException; | |
| 30 | +import java.util.concurrent.ExecutorService; | |
| 31 | +import java.util.concurrent.ThreadFactory; | |
| 32 | +import java.util.concurrent.TimeUnit; | |
| 33 | + | |
| 34 | +/** | |
| 35 | + * A grouping of asynchronous channels for the purpose of resource sharing. | |
| 36 | + * | |
| 37 | + * <p> An asynchronous channel group encapsulates the mechanics required to | |
| 38 | + * handle the completion of I/O operations initiated by {@link AsynchronousChannel | |
| 39 | + * asynchronous channels} that are bound to the group. A group has an associated | |
| 40 | + * thread pool to which tasks are submitted to handle I/O events and dispatch to | |
| 41 | + * {@link CompletionHandler completion-handlers} that consume the result of | |
| 42 | + * asynchronous operations performed on channels in the group. In addition to | |
| 43 | + * handling I/O events, the pooled threads may also execute other tasks required | |
| 44 | + * to support the execution of asynchronous I/O operations. | |
| 45 | + * | |
| 46 | + * <p> An asynchronous channel group is created by invoking the {@link | |
| 47 | + * #withFixedThreadPool withFixedThreadPool} or {@link #withCachedThreadPool | |
| 48 | + * withCachedThreadPool} methods defined here. Channels are bound to a group by | |
| 49 | + * specifying the group when constructing the channel. The associated thread | |
| 50 | + * pool is <em>owned</em> by the group; termination of the group results in the | |
| 51 | + * shutdown of the associated thread pool. | |
| 52 | + * | |
| 53 | + * <p> In addition to groups created explicitly, the Java virtual machine | |
| 54 | + * maintains a system-wide <em>default group</em> that is constructed | |
| 55 | + * automatically. Asynchronous channels that do not specify a group at | |
| 56 | + * construction time are bound to the default group. The default group has an | |
| 57 | + * associated thread pool that creates new threads as needed. The default group | |
| 58 | + * may be configured by means of system properties defined in the table below. | |
| 59 | + * Where the {@link java.util.concurrent.ThreadFactory ThreadFactory} for the | |
| 60 | + * default group is not configured then the pooled threads of the default group | |
| 61 | + * are {@link Thread#isDaemon daemon} threads. | |
| 62 | + * | |
| 63 | + * <table border> | |
| 64 | + * <tr> | |
| 65 | + * <th>System property</th> | |
| 66 | + * <th>Description</th> | |
| 67 | + * </tr> | |
| 68 | + * <tr> | |
| 69 | + * <tr> | |
| 70 | + * <td> {@code java.nio.channels.DefaultThreadPool.threadFactory} </td> | |
| 71 | + * <td> The value of this property is taken to be the fully-qualified name | |
| 72 | + * of a concrete {@link java.util.concurrent.ThreadFactory ThreadFactory} | |
| 73 | + * class. The class is loaded using the system class loader and instantiated. | |
| 74 | + * The factory's {@link java.util.concurrent.ThreadFactory#newThread | |
| 75 | + * newThread} method is invoked to create each thread for the default | |
| 76 | + * group's thread pool. If the process to load and instantiate the value | |
| 77 | + * of the property fails then an unspecified error is thrown during the | |
| 78 | + * construction of the default group. </td> | |
| 79 | + * </tr> | |
| 80 | + * <tr> | |
| 81 | + * <td> {@code java.nio.channels.DefaultThreadPool.initialSize} </td> | |
| 82 | + * <td> The value of the {@code initialSize} parameter for the default | |
| 83 | + * group (see {@link #withCachedThreadPool withCachedThreadPool}). | |
| 84 | + * The value of the property is taken to be the {@code String} | |
| 85 | + * representation of an {@code Integer} that is the initial size parameter. | |
| 86 | + * If the value cannot be parsed as an {@code Integer} it causes an | |
| 87 | + * unspecified error to be thrown during the construction of the default | |
| 88 | + * group. </td> | |
| 89 | + * </tr> | |
| 90 | + * </table> | |
| 91 | + * | |
| 92 | + * <a name="threading"><h4>Threading</h4></a> | |
| 93 | + * | |
| 94 | + * <p> The completion handler for an I/O operation initiated on a channel bound | |
| 95 | + * to a group is guaranteed to be invoked by one of the pooled threads in the | |
| 96 | + * group. This ensures that the completion handler is run by a thread with the | |
| 97 | + * expected <em>identity</em>. | |
| 98 | + * | |
| 99 | + * <p> Where an I/O operation completes immediately, and the initiating thread | |
| 100 | + * is one of the pooled threads in the group then the completion handler may | |
| 101 | + * be invoked directly by the initiating thread. To avoid stack overflow, an | |
| 102 | + * implementation may impose a limit as to the number of activations on the | |
| 103 | + * thread stack. Some I/O operations may prohibit invoking the completion | |
| 104 | + * handler directly by the initiating thread (see {@link | |
| 105 | + * AsynchronousServerSocketChannel#accept(Object,CompletionHandler) accept}). | |
| 106 | + * | |
| 107 | + * <a name="shutdown"><h4>Shutdown and Termination</h4></a> | |
| 108 | + * | |
| 109 | + * <p> The {@link #shutdown() shutdown} method is used to initiate an <em>orderly | |
| 110 | + * shutdown</em> of a group. An orderly shutdown marks the group as shutdown; | |
| 111 | + * further attempts to construct a channel that binds to the group will throw | |
| 112 | + * {@link ShutdownChannelGroupException}. Whether or not a group is shutdown can | |
| 113 | + * be tested using the {@link #isShutdown() isShutdown} method. Once shutdown, | |
| 114 | + * the group <em>terminates</em> when all asynchronous channels that are bound to | |
| 115 | + * the group are closed, all actively executing completion handlers have run to | |
| 116 | + * completion, and resources used by the group are released. No attempt is made | |
| 117 | + * to stop or interrupt threads that are executing completion handlers. The | |
| 118 | + * {@link #isTerminated() isTerminated} method is used to test if the group has | |
| 119 | + * terminated, and the {@link #awaitTermination awaitTermination} method can be | |
| 120 | + * used to block until the group has terminated. | |
| 121 | + * | |
| 122 | + * <p> The {@link #shutdownNow() shutdownNow} method can be used to initiate a | |
| 123 | + * <em>forceful shutdown</em> of the group. In addition to the actions performed | |
| 124 | + * by an orderly shutdown, the {@code shutdownNow} method closes all open channels | |
| 125 | + * in the group as if by invoking the {@link AsynchronousChannel#close close} | |
| 126 | + * method. | |
| 127 | + * | |
| 128 | + * @since 1.7 | |
| 129 | + * | |
| 130 | + * @see AsynchronousSocketChannel#open(AsynchronousChannelGroup) | |
| 131 | + * @see AsynchronousServerSocketChannel#open(AsynchronousChannelGroup) | |
| 132 | + */ | |
| 133 | + | |
| 134 | +public abstract class AsynchronousChannelGroup { | |
| 135 | + private final AsynchronousChannelProvider provider; | |
| 136 | + | |
| 137 | + /** | |
| 138 | + * Initialize a new instance of this class. | |
| 139 | + * | |
| 140 | + * @param provider | |
| 141 | + * The asynchronous channel provider for this group | |
| 142 | + */ | |
| 143 | + protected AsynchronousChannelGroup(AsynchronousChannelProvider provider) { | |
| 144 | + this.provider = provider; | |
| 145 | + } | |
| 146 | + | |
| 147 | + /** | |
| 148 | + * Returns the provider that created this channel group. | |
| 149 | + * | |
| 150 | + * @return The provider that created this channel group | |
| 151 | + */ | |
| 152 | + public final AsynchronousChannelProvider provider() { | |
| 153 | + return provider; | |
| 154 | + } | |
| 155 | + | |
| 156 | + /** | |
| 157 | + * Creates an asynchronous channel group with a fixed thread pool. | |
| 158 | + * | |
| 159 | + * <p> The resulting asynchronous channel group reuses a fixed number of | |
| 160 | + * threads. At any point, at most {@code nThreads} threads will be active | |
| 161 | + * processing tasks that are submitted to handle I/O events and dispatch | |
| 162 | + * completion results for operations initiated on asynchronous channels in | |
| 163 | + * the group. | |
| 164 | + * | |
| 165 | + * <p> The group is created by invoking the {@link | |
| 166 | + * AsynchronousChannelProvider#openAsynchronousChannelGroup(int,ThreadFactory) | |
| 167 | + * openAsynchronousChannelGroup(int,ThreadFactory)} method of the system-wide | |
| 168 | + * default {@link AsynchronousChannelProvider} object. | |
| 169 | + * | |
| 170 | + * @param nThreads | |
| 171 | + * The number of threads in the pool | |
| 172 | + * @param threadFactory | |
| 173 | + * The factory to use when creating new threads | |
| 174 | + * | |
| 175 | + * @return A new asynchronous channel group | |
| 176 | + * | |
| 177 | + * @throws IllegalArgumentException | |
| 178 | + * If {@code nThreads <= 0} | |
| 179 | + * @throws IOException | |
| 180 | + * If an I/O error occurs | |
| 181 | + */ | |
| 182 | + public static AsynchronousChannelGroup withFixedThreadPool(int nThreads, | |
| 183 | + ThreadFactory threadFactory) | |
| 184 | + throws IOException | |
| 185 | + { | |
| 186 | + return AsynchronousChannelProvider.provider() | |
| 187 | + .openAsynchronousChannelGroup(nThreads, threadFactory); | |
| 188 | + } | |
| 189 | + | |
| 190 | + /** | |
| 191 | + * Creates an asynchronous channel group with a given thread pool that | |
| 192 | + * creates new threads as needed. | |
| 193 | + * | |
| 194 | + * <p> The {@code executor} parameter is an {@code ExecutorService} that | |
| 195 | + * creates new threads as needed to execute tasks that are submitted to | |
| 196 | + * handle I/O events and dispatch completion results for operations initiated | |
| 197 | + * on asynchronous channels in the group. It may reuse previously constructed | |
| 198 | + * threads when they are available. | |
| 199 | + * | |
| 200 | + * <p> The {@code initialSize} parameter may be used by the implementation | |
| 201 | + * as a <em>hint</em> as to the initial number of tasks it may submit. For | |
| 202 | + * example, it may be used to indictae the initial number of threads that | |
| 203 | + * wait on I/O events. | |
| 204 | + * | |
| 205 | + * <p> The executor is intended to be used exclusively by the resulting | |
| 206 | + * asynchronous channel group. Termination of the group results in the | |
| 207 | + * orderly {@link ExecutorService#shutdown shutdown} of the executor | |
| 208 | + * service. Shutting down the executor service by other means results in | |
| 209 | + * unspecified behavior. | |
| 210 | + * | |
| 211 | + * <p> The group is created by invoking the {@link | |
| 212 | + * AsynchronousChannelProvider#openAsynchronousChannelGroup(ExecutorService,int) | |
| 213 | + * openAsynchronousChannelGroup(ExecutorService,int)} method of the system-wide | |
| 214 | + * default {@link AsynchronousChannelProvider} object. | |
| 215 | + * | |
| 216 | + * @param executor | |
| 217 | + * The thread pool for the resulting group | |
| 218 | + * @param initialSize | |
| 219 | + * A value {@code >=0} or a negative value for implementation | |
| 220 | + * specific default | |
| 221 | + * | |
| 222 | + * @return A new asynchronous channel group | |
| 223 | + * | |
| 224 | + * @throws IOException | |
| 225 | + * If an I/O error occurs | |
| 226 | + * | |
| 227 | + * @see java.util.concurrent.Executors#newCachedThreadPool | |
| 228 | + */ | |
| 229 | + public static AsynchronousChannelGroup withCachedThreadPool(ExecutorService executor, | |
| 230 | + int initialSize) | |
| 231 | + throws IOException | |
| 232 | + { | |
| 233 | + return AsynchronousChannelProvider.provider() | |
| 234 | + .openAsynchronousChannelGroup(executor, initialSize); | |
| 235 | + } | |
| 236 | + | |
| 237 | + /** | |
| 238 | + * Creates an asynchronous channel group with a given thread pool. | |
| 239 | + * | |
| 240 | + * <p> The {@code executor} parameter is an {@code ExecutorService} that | |
| 241 | + * executes tasks submitted to dispatch completion results for operations | |
| 242 | + * initiated on asynchronous channels in the group. | |
| 243 | + * | |
| 244 | + * <p> Care should be taken when configuring the executor service. It | |
| 245 | + * should support <em>direct handoff</em> or <em>unbounded queuing</em> of | |
| 246 | + * submitted tasks, and the thread that invokes the {@link | |
| 247 | + * ExecutorService#execute execute} method should never invoke the task | |
| 248 | + * directly. An implementation may mandate additional constraints. | |
| 249 | + * | |
| 250 | + * <p> The executor is intended to be used exclusively by the resulting | |
| 251 | + * asynchronous channel group. Termination of the group results in the | |
| 252 | + * orderly {@link ExecutorService#shutdown shutdown} of the executor | |
| 253 | + * service. Shutting down the executor service by other means results in | |
| 254 | + * unspecified behavior. | |
| 255 | + * | |
| 256 | + * <p> The group is created by invoking the {@link | |
| 257 | + * AsynchronousChannelProvider#openAsynchronousChannelGroup(ExecutorService,int) | |
| 258 | + * openAsynchronousChannelGroup(ExecutorService,int)} method of the system-wide | |
| 259 | + * default {@link AsynchronousChannelProvider} object with an {@code | |
| 260 | + * initialSize} of {@code 0}. | |
| 261 | + * | |
| 262 | + * @param executor | |
| 263 | + * The thread pool for the resulting group | |
| 264 | + * | |
| 265 | + * @return A new asynchronous channel group | |
| 266 | + * | |
| 267 | + * @throws IOException | |
| 268 | + * If an I/O error occurs | |
| 269 | + */ | |
| 270 | + public static AsynchronousChannelGroup withThreadPool(ExecutorService executor) | |
| 271 | + throws IOException | |
| 272 | + { | |
| 273 | + return AsynchronousChannelProvider.provider() | |
| 274 | + .openAsynchronousChannelGroup(executor, 0); | |
| 275 | + } | |
| 276 | + | |
| 277 | + /** | |
| 278 | + * Tells whether or not this asynchronous channel group is shutdown. | |
| 279 | + * | |
| 280 | + * @return {@code true} if this asynchronous channel group is shutdown or | |
| 281 | + * has been marked for shutdown. | |
| 282 | + */ | |
| 283 | + public abstract boolean isShutdown(); | |
| 284 | + | |
| 285 | + /** | |
| 286 | + * Tells whether or not this group has terminated. | |
| 287 | + * | |
| 288 | + * <p> Where this method returns {@code true}, then the associated thread | |
| 289 | + * pool has also {@link ExecutorService#isTerminated terminated}. | |
| 290 | + * | |
| 291 | + * @return {@code true} if this group has terminated | |
| 292 | + */ | |
| 293 | + public abstract boolean isTerminated(); | |
| 294 | + | |
| 295 | + /** | |
| 296 | + * Initiates an orderly shutdown of the group. | |
| 297 | + * | |
| 298 | + * <p> This method marks the group as shutdown. Further attempts to construct | |
| 299 | + * channel that binds to this group will throw {@link ShutdownChannelGroupException}. | |
| 300 | + * The group terminates when all asynchronous channels in the group are | |
| 301 | + * closed, all actively executing completion handlers have run to completion, | |
| 302 | + * and all resources have been released. This method has no effect if the | |
| 303 | + * group is already shutdown. | |
| 304 | + */ | |
| 305 | + public abstract void shutdown(); | |
| 306 | + | |
| 307 | + /** | |
| 308 | + * Shuts down the group and closes all open channels in the group. | |
| 309 | + * | |
| 310 | + * <p> In addition to the actions performed by the {@link #shutdown() shutdown} | |
| 311 | + * method, this method invokes the {@link AsynchronousChannel#close close} | |
| 312 | + * method on all open channels in the group. This method does not attempt to | |
| 313 | + * stop or interrupt threads that are executing completion handlers. The | |
| 314 | + * group terminates when all actively executing completion handlers have run | |
| 315 | + * to completion and all resources have been released. This method may be | |
| 316 | + * invoked at any time. If some other thread has already invoked it, then | |
| 317 | + * another invocation will block until the first invocation is complete, | |
| 318 | + * after which it will return without effect. | |
| 319 | + * | |
| 320 | + * @throws IOException | |
| 321 | + * If an I/O error occurs | |
| 322 | + */ | |
| 323 | + public abstract void shutdownNow() throws IOException; | |
| 324 | + | |
| 325 | + /** | |
| 326 | + * Awaits termination of the group. | |
| 327 | + | |
| 328 | + * <p> This method blocks until the group has terminated, or the timeout | |
| 329 | + * occurs, or the current thread is interrupted, whichever happens first. | |
| 330 | + * | |
| 331 | + * @param timeout | |
| 332 | + * The maximum time to wait, or zero or less to not wait | |
| 333 | + * @param unit | |
| 334 | + * The time unit of the timeout argument | |
| 335 | + * | |
| 336 | + * @return {@code true} if the group has terminated; {@code false} if the | |
| 337 | + * timeout elapsed before termination | |
| 338 | + * | |
| 339 | + * @throws InterruptedException | |
| 340 | + * If interrupted while waiting | |
| 341 | + */ | |
| 342 | + public abstract boolean awaitTermination(long timeout, TimeUnit unit) | |
| 343 | + throws InterruptedException; | |
| 344 | +} | |
Binary file not shown.
| @@ -0,0 +1,770 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels; | |
| 27 | + | |
| 28 | +import java.nio.file.*; | |
| 29 | +import java.nio.file.attribute.FileAttribute; | |
| 30 | +import java.nio.file.spi.*; | |
| 31 | +import java.nio.ByteBuffer; | |
| 32 | +import java.io.IOException; | |
| 33 | +import java.util.concurrent.Future; | |
| 34 | +import java.util.concurrent.ExecutorService; | |
| 35 | +import java.util.Set; | |
| 36 | +import java.util.HashSet; | |
| 37 | +import java.util.Collections; | |
| 38 | + | |
| 39 | +/** | |
| 40 | + * An asynchronous channel for reading, writing, and manipulating a file. | |
| 41 | + * | |
| 42 | + * <p> An asynchronous file channel is created when a file is opened by invoking | |
| 43 | + * one of the {@link #open open} methods defined by this class. The file contains | |
| 44 | + * a variable-length sequence of bytes that can be read and written and whose | |
| 45 | + * current size can be {@link #size() queried}. The size of the file increases | |
| 46 | + * when bytes are written beyond its current size; the size of the file decreases | |
| 47 | + * when it is {@link #truncate truncated}. | |
| 48 | + * | |
| 49 | + * <p> An asynchronous file channel does not have a <i>current position</i> | |
| 50 | + * within the file. Instead, the file position is specified to each read and | |
| 51 | + * write method that initiates asynchronous operations. A {@link CompletionHandler} | |
| 52 | + * is specified as a parameter and is invoked to consume the result of the I/O | |
| 53 | + * operation. This class also defines read and write methods that initiate | |
| 54 | + * asynchronous operations, returning a {@link Future} to represent the pending | |
| 55 | + * result of the operation. The {@code Future} may be used to check if the | |
| 56 | + * operation has completed, wait for its completion, and retrieve the result. | |
| 57 | + * | |
| 58 | + * <p> In addition to read and write operations, this class defines the | |
| 59 | + * following operations: </p> | |
| 60 | + * | |
| 61 | + * <ul> | |
| 62 | + * | |
| 63 | + * <li><p> Updates made to a file may be {@link #force <i>forced | |
| 64 | + * out</i>} to the underlying storage device, ensuring that data are not | |
| 65 | + * lost in the event of a system crash. </p></li> | |
| 66 | + * | |
| 67 | + * <li><p> A region of a file may be {@link #lock <i>locked</i>} against | |
| 68 | + * access by other programs. </p></li> | |
| 69 | + * | |
| 70 | + * </ul> | |
| 71 | + * | |
| 72 | + * <p> An {@code AsynchronousFileChannel} is associated with a thread pool to | |
| 73 | + * which tasks are submitted to handle I/O events and dispatch to completion | |
| 74 | + * handlers that consume the results of I/O operations on the channel. The | |
| 75 | + * completion handler for an I/O operation initiated on a channel is guaranteed | |
| 76 | + * to be invoked by one of the threads in the thread pool (This ensures that the | |
| 77 | + * completion handler is run by a thread with the expected <em>identity</em>). | |
| 78 | + * Where an I/O operation completes immediately, and the initiating thread is | |
| 79 | + * itself a thread in the thread pool, then the completion handler may be invoked | |
| 80 | + * directly by the initiating thread. When an {@code AsynchronousFileChannel} is | |
| 81 | + * created without specifying a thread pool then the channel is associated with | |
| 82 | + * a system-dependent default thread pool that may be shared with other | |
| 83 | + * channels. The default thread pool is configured by the system properties | |
| 84 | + * defined by the {@link AsynchronousChannelGroup} class. | |
| 85 | + * | |
| 86 | + * <p> Channels of this type are safe for use by multiple concurrent threads. The | |
| 87 | + * {@link Channel#close close} method may be invoked at any time, as specified | |
| 88 | + * by the {@link Channel} interface. This causes all outstanding asynchronous | |
| 89 | + * operations on the channel to complete with the exception {@link | |
| 90 | + * AsynchronousCloseException}. Multiple read and write operations may be | |
| 91 | + * outstanding at the same time. When multiple read and write operations are | |
| 92 | + * outstanding then the ordering of the I/O operations, and the order that the | |
| 93 | + * completion handlers are invoked, is not specified; they are not, in particular, | |
| 94 | + * guaranteed to execute in the order that the operations were initiated. The | |
| 95 | + * {@link java.nio.ByteBuffer ByteBuffers} used when reading or writing are not | |
| 96 | + * safe for use by multiple concurrent I/O operations. Furthermore, after an I/O | |
| 97 | + * operation is initiated then care should be taken to ensure that the buffer is | |
| 98 | + * not accessed until after the operation has completed. | |
| 99 | + * | |
| 100 | + * <p> As with {@link FileChannel}, the view of a file provided by an instance of | |
| 101 | + * this class is guaranteed to be consistent with other views of the same file | |
| 102 | + * provided by other instances in the same program. The view provided by an | |
| 103 | + * instance of this class may or may not, however, be consistent with the views | |
| 104 | + * seen by other concurrently-running programs due to caching performed by the | |
| 105 | + * underlying operating system and delays induced by network-filesystem protocols. | |
| 106 | + * This is true regardless of the language in which these other programs are | |
| 107 | + * written, and whether they are running on the same machine or on some other | |
| 108 | + * machine. The exact nature of any such inconsistencies are system-dependent | |
| 109 | + * and are therefore unspecified. | |
| 110 | + * | |
| 111 | + * @since 1.7 | |
| 112 | + */ | |
| 113 | + | |
| 114 | +public abstract class AsynchronousFileChannel | |
| 115 | + implements AsynchronousChannel | |
| 116 | +{ | |
| 117 | + /** | |
| 118 | + * Initializes a new instance of this class. | |
| 119 | + */ | |
| 120 | + protected AsynchronousFileChannel() { | |
| 121 | + } | |
| 122 | + | |
| 123 | + /** | |
| 124 | + * Opens or creates a file for reading and/or writing, returning an | |
| 125 | + * asynchronous file channel to access the file. | |
| 126 | + * | |
| 127 | + * <p> The {@code options} parameter determines how the file is opened. | |
| 128 | + * The {@link StandardOpenOption#READ READ} and {@link StandardOpenOption#WRITE | |
| 129 | + * WRITE} options determines if the file should be opened for reading and/or | |
| 130 | + * writing. If neither option is contained in the array then an existing file | |
| 131 | + * is opened for reading. | |
| 132 | + * | |
| 133 | + * <p> In addition to {@code READ} and {@code WRITE}, the following options | |
| 134 | + * may be present: | |
| 135 | + * | |
| 136 | + * <table border=1 cellpadding=5 summary=""> | |
| 137 | + * <tr> <th>Option</th> <th>Description</th> </tr> | |
| 138 | + * <tr> | |
| 139 | + * <td> {@link StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING} </td> | |
| 140 | + * <td> When opening an existing file, the file is first truncated to a | |
| 141 | + * size of 0 bytes. This option is ignored when the file is opened only | |
| 142 | + * for reading.</td> | |
| 143 | + * </tr> | |
| 144 | + * <tr> | |
| 145 | + * <td> {@link StandardOpenOption#CREATE_NEW CREATE_NEW} </td> | |
| 146 | + * <td> If this option is present then a new file is created, failing if | |
| 147 | + * the file already exists. When creating a file the check for the | |
| 148 | + * existence of the file and the creation of the file if it does not exist | |
| 149 | + * is atomic with respect to other file system operations. This option is | |
| 150 | + * ignored when the file is opened only for reading. </td> | |
| 151 | + * </tr> | |
| 152 | + * <tr> | |
| 153 | + * <td > {@link StandardOpenOption#CREATE CREATE} </td> | |
| 154 | + * <td> If this option is present then an existing file is opened if it | |
| 155 | + * exists, otherwise a new file is created. When creating a file the check | |
| 156 | + * for the existence of the file and the creation of the file if it does | |
| 157 | + * not exist is atomic with respect to other file system operations. This | |
| 158 | + * option is ignored if the {@code CREATE_NEW} option is also present or | |
| 159 | + * the file is opened only for reading. </td> | |
| 160 | + * </tr> | |
| 161 | + * <tr> | |
| 162 | + * <td > {@link StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} </td> | |
| 163 | + * <td> When this option is present then the implementation makes a | |
| 164 | + * <em>best effort</em> attempt to delete the file when closed by the | |
| 165 | + * the {@link #close close} method. If the {@code close} method is not | |
| 166 | + * invoked then a <em>best effort</em> attempt is made to delete the file | |
| 167 | + * when the Java virtual machine terminates. </td> | |
| 168 | + * </tr> | |
| 169 | + * <tr> | |
| 170 | + * <td>{@link StandardOpenOption#SPARSE SPARSE} </td> | |
| 171 | + * <td> When creating a new file this option is a <em>hint</em> that the | |
| 172 | + * new file will be sparse. This option is ignored when not creating | |
| 173 | + * a new file. </td> | |
| 174 | + * </tr> | |
| 175 | + * <tr> | |
| 176 | + * <td> {@link StandardOpenOption#SYNC SYNC} </td> | |
| 177 | + * <td> Requires that every update to the file's content or metadata be | |
| 178 | + * written synchronously to the underlying storage device. (see <a | |
| 179 | + * href="../file/package-summary.html#integrity"> Synchronized I/O file | |
| 180 | + * integrity</a>). </td> | |
| 181 | + * <tr> | |
| 182 | + * <tr> | |
| 183 | + * <td> {@link StandardOpenOption#DSYNC DSYNC} </td> | |
| 184 | + * <td> Requires that every update to the file's content be written | |
| 185 | + * synchronously to the underlying storage device. (see <a | |
| 186 | + * href="../file/package-summary.html#integrity"> Synchronized I/O file | |
| 187 | + * integrity</a>). </td> | |
| 188 | + * </tr> | |
| 189 | + * </table> | |
| 190 | + * | |
| 191 | + * <p> An implementation may also support additional options. | |
| 192 | + * | |
| 193 | + * <p> The {@code executor} parameter is the {@link ExecutorService} to | |
| 194 | + * which tasks are submitted to handle I/O events and dispatch completion | |
| 195 | + * results for operations initiated on resulting channel. | |
| 196 | + * The nature of these tasks is highly implementation specific and so care | |
| 197 | + * should be taken when configuring the {@code Executor}. Minimally it | |
| 198 | + * should support an unbounded work queue and should not run tasks on the | |
| 199 | + * caller thread of the {@link ExecutorService#execute execute} method. | |
| 200 | + * Shutting down the executor service while the channel is open results in | |
| 201 | + * unspecified behavior. | |
| 202 | + * | |
| 203 | + * <p> The {@code attrs} parameter is an optional array of file {@link | |
| 204 | + * FileAttribute file-attributes} to set atomically when creating the file. | |
| 205 | + * | |
| 206 | + * <p> The new channel is created by invoking the {@link | |
| 207 | + * FileSystemProvider#newFileChannel newFileChannel} method on the | |
| 208 | + * provider that created the {@code Path}. | |
| 209 | + * | |
| 210 | + * @param file | |
| 211 | + * The path of the file to open or create | |
| 212 | + * @param options | |
| 213 | + * Options specifying how the file is opened | |
| 214 | + * @param executor | |
| 215 | + * The thread pool or {@code null} to associate the channel with | |
| 216 | + * the default thread pool | |
| 217 | + * @param attrs | |
| 218 | + * An optional list of file attributes to set atomically when | |
| 219 | + * creating the file | |
| 220 | + * | |
| 221 | + * @return A new asynchronous file channel | |
| 222 | + * | |
| 223 | + * @throws IllegalArgumentException | |
| 224 | + * If the set contains an invalid combination of options | |
| 225 | + * @throws UnsupportedOperationException | |
| 226 | + * If the {@code file} is associated with a provider that does not | |
| 227 | + * support creating asynchronous file channels, or an unsupported | |
| 228 | + * open option is specified, or the array contains an attribute that | |
| 229 | + * cannot be set atomically when creating the file | |
| 230 | + * @throws IOException | |
| 231 | + * If an I/O error occurs | |
| 232 | + * @throws SecurityException | |
| 233 | + * If a security manager is installed and it denies an | |
| 234 | + * unspecified permission required by the implementation. | |
| 235 | + * In the case of the default provider, the {@link | |
| 236 | + * SecurityManager#checkRead(String)} method is invoked to check | |
| 237 | + * read access if the file is opened for reading. The {@link | |
| 238 | + * SecurityManager#checkWrite(String)} method is invoked to check | |
| 239 | + * write access if the file is opened for writing | |
| 240 | + */ | |
| 241 | + public static AsynchronousFileChannel open(Path file, | |
| 242 | + Set<? extends OpenOption> options, | |
| 243 | + ExecutorService executor, | |
| 244 | + FileAttribute<?>... attrs) | |
| 245 | + throws IOException | |
| 246 | + { | |
| 247 | + FileSystemProvider provider = file.getFileSystem().provider(); | |
| 248 | + return provider.newAsynchronousFileChannel(file, options, executor, attrs); | |
| 249 | + } | |
| 250 | + | |
| 251 | + private static final FileAttribute<?>[] NO_ATTRIBUTES = new FileAttribute[0]; | |
| 252 | + | |
| 253 | + /** | |
| 254 | + * Opens or creates a file for reading and/or writing, returning an | |
| 255 | + * asynchronous file channel to access the file. | |
| 256 | + * | |
| 257 | + * <p> An invocation of this method behaves in exactly the same way as the | |
| 258 | + * invocation | |
| 259 | + * <pre> | |
| 260 | + * ch.{@link #open(Path,Set,ExecutorService,FileAttribute[]) | |
| 261 | + * open}(file, opts, null, new FileAttribute<?>[0]); | |
| 262 | + * </pre> | |
| 263 | + * where {@code opts} is a {@code Set} containing the options specified to | |
| 264 | + * this method. | |
| 265 | + * | |
| 266 | + * <p> The resulting channel is associated with default thread pool to which | |
| 267 | + * tasks are submitted to handle I/O events and dispatch to completion | |
| 268 | + * handlers that consume the result of asynchronous operations performed on | |
| 269 | + * the resulting channel. | |
| 270 | + * | |
| 271 | + * @param file | |
| 272 | + * The path of the file to open or create | |
| 273 | + * @param options | |
| 274 | + * Options specifying how the file is opened | |
| 275 | + * | |
| 276 | + * @return A new asynchronous file channel | |
| 277 | + * | |
| 278 | + * @throws IllegalArgumentException | |
| 279 | + * If the set contains an invalid combination of options | |
| 280 | + * @throws UnsupportedOperationException | |
| 281 | + * If the {@code file} is associated with a provider that does not | |
| 282 | + * support creating file channels, or an unsupported open option is | |
| 283 | + * specified | |
| 284 | + * @throws IOException | |
| 285 | + * If an I/O error occurs | |
| 286 | + * @throws SecurityException | |
| 287 | + * If a security manager is installed and it denies an | |
| 288 | + * unspecified permission required by the implementation. | |
| 289 | + * In the case of the default provider, the {@link | |
| 290 | + * SecurityManager#checkRead(String)} method is invoked to check | |
| 291 | + * read access if the file is opened for reading. The {@link | |
| 292 | + * SecurityManager#checkWrite(String)} method is invoked to check | |
| 293 | + * write access if the file is opened for writing | |
| 294 | + */ | |
| 295 | + public static AsynchronousFileChannel open(Path file, OpenOption... options) | |
| 296 | + throws IOException | |
| 297 | + { | |
| 298 | + Set<OpenOption> set = new HashSet<OpenOption>(options.length); | |
| 299 | + Collections.addAll(set, options); | |
| 300 | + return open(file, set, null, NO_ATTRIBUTES); | |
| 301 | + } | |
| 302 | + | |
| 303 | + /** | |
| 304 | + * Returns the current size of this channel's file. | |
| 305 | + * | |
| 306 | + * @return The current size of this channel's file, measured in bytes | |
| 307 | + * | |
| 308 | + * @throws ClosedChannelException | |
| 309 | + * If this channel is closed | |
| 310 | + * @throws IOException | |
| 311 | + * If some other I/O error occurs | |
| 312 | + */ | |
| 313 | + public abstract long size() throws IOException; | |
| 314 | + | |
| 315 | + /** | |
| 316 | + * Truncates this channel's file to the given size. | |
| 317 | + * | |
| 318 | + * <p> If the given size is less than the file's current size then the file | |
| 319 | + * is truncated, discarding any bytes beyond the new end of the file. If | |
| 320 | + * the given size is greater than or equal to the file's current size then | |
| 321 | + * the file is not modified. </p> | |
| 322 | + * | |
| 323 | + * @param size | |
| 324 | + * The new size, a non-negative byte count | |
| 325 | + * | |
| 326 | + * @return This file channel | |
| 327 | + * | |
| 328 | + * @throws NonWritableChannelException | |
| 329 | + * If this channel was not opened for writing | |
| 330 | + * | |
| 331 | + * @throws ClosedChannelException | |
| 332 | + * If this channel is closed | |
| 333 | + * | |
| 334 | + * @throws IllegalArgumentException | |
| 335 | + * If the new size is negative | |
| 336 | + * | |
| 337 | + * @throws IOException | |
| 338 | + * If some other I/O error occurs | |
| 339 | + */ | |
| 340 | + public abstract AsynchronousFileChannel truncate(long size) throws IOException; | |
| 341 | + | |
| 342 | + /** | |
| 343 | + * Forces any updates to this channel's file to be written to the storage | |
| 344 | + * device that contains it. | |
| 345 | + * | |
| 346 | + * <p> If this channel's file resides on a local storage device then when | |
| 347 | + * this method returns it is guaranteed that all changes made to the file | |
| 348 | + * since this channel was created, or since this method was last invoked, | |
| 349 | + * will have been written to that device. This is useful for ensuring that | |
| 350 | + * critical information is not lost in the event of a system crash. | |
| 351 | + * | |
| 352 | + * <p> If the file does not reside on a local device then no such guarantee | |
| 353 | + * is made. | |
| 354 | + * | |
| 355 | + * <p> The {@code metaData} parameter can be used to limit the number of | |
| 356 | + * I/O operations that this method is required to perform. Passing | |
| 357 | + * {@code false} for this parameter indicates that only updates to the | |
| 358 | + * file's content need be written to storage; passing {@code true} | |
| 359 | + * indicates that updates to both the file's content and metadata must be | |
| 360 | + * written, which generally requires at least one more I/O operation. | |
| 361 | + * Whether this parameter actually has any effect is dependent upon the | |
| 362 | + * underlying operating system and is therefore unspecified. | |
| 363 | + * | |
| 364 | + * <p> Invoking this method may cause an I/O operation to occur even if the | |
| 365 | + * channel was only opened for reading. Some operating systems, for | |
| 366 | + * example, maintain a last-access time as part of a file's metadata, and | |
| 367 | + * this time is updated whenever the file is read. Whether or not this is | |
| 368 | + * actually done is system-dependent and is therefore unspecified. | |
| 369 | + * | |
| 370 | + * <p> This method is only guaranteed to force changes that were made to | |
| 371 | + * this channel's file via the methods defined in this class. | |
| 372 | + * | |
| 373 | + * @param metaData | |
| 374 | + * If {@code true} then this method is required to force changes | |
| 375 | + * to both the file's content and metadata to be written to | |
| 376 | + * storage; otherwise, it need only force content changes to be | |
| 377 | + * written | |
| 378 | + * | |
| 379 | + * @throws ClosedChannelException | |
| 380 | + * If this channel is closed | |
| 381 | + * | |
| 382 | + * @throws IOException | |
| 383 | + * If some other I/O error occurs | |
| 384 | + */ | |
| 385 | + public abstract void force(boolean metaData) throws IOException; | |
| 386 | + | |
| 387 | + /** | |
| 388 | + * Acquires a lock on the given region of this channel's file. | |
| 389 | + * | |
| 390 | + * <p> This method initiates an operation to acquire a lock on the given | |
| 391 | + * region of this channel's file. The {@code handler} parameter is a | |
| 392 | + * completion handler that is invoked when the lock is acquired (or the | |
| 393 | + * operation fails). The result passed to the completion handler is the | |
| 394 | + * resulting {@code FileLock}. | |
| 395 | + * | |
| 396 | + * <p> The region specified by the {@code position} and {@code size} | |
| 397 | + * parameters need not be contained within, or even overlap, the actual | |
| 398 | + * underlying file. Lock regions are fixed in size; if a locked region | |
| 399 | + * initially contains the end of the file and the file grows beyond the | |
| 400 | + * region then the new portion of the file will not be covered by the lock. | |
| 401 | + * If a file is expected to grow in size and a lock on the entire file is | |
| 402 | + * required then a region starting at zero, and no smaller than the | |
| 403 | + * expected maximum size of the file, should be locked. The two-argument | |
| 404 | + * {@link #lock(Object,CompletionHandler)} method simply locks a region | |
| 405 | + * of size {@link Long#MAX_VALUE}. If a lock that overlaps the requested | |
| 406 | + * region is already held by this Java virtual machine, or this method has | |
| 407 | + * been invoked to lock an overlapping region and that operation has not | |
| 408 | + * completed, then this method throws {@link OverlappingFileLockException}. | |
| 409 | + * | |
| 410 | + * <p> Some operating systems do not support a mechanism to acquire a file | |
| 411 | + * lock in an asynchronous manner. Consequently an implementation may | |
| 412 | + * acquire the file lock in a background thread or from a task executed by | |
| 413 | + * a thread in the associated thread pool. If there are many lock operations | |
| 414 | + * outstanding then it may consume threads in the Java virtual machine for | |
| 415 | + * indefinite periods. | |
| 416 | + * | |
| 417 | + * <p> Some operating systems do not support shared locks, in which case a | |
| 418 | + * request for a shared lock is automatically converted into a request for | |
| 419 | + * an exclusive lock. Whether the newly-acquired lock is shared or | |
| 420 | + * exclusive may be tested by invoking the resulting lock object's {@link | |
| 421 | + * FileLock#isShared() isShared} method. | |
| 422 | + * | |
| 423 | + * <p> File locks are held on behalf of the entire Java virtual machine. | |
| 424 | + * They are not suitable for controlling access to a file by multiple | |
| 425 | + * threads within the same virtual machine. | |
| 426 | + * | |
| 427 | + * @param position | |
| 428 | + * The position at which the locked region is to start; must be | |
| 429 | + * non-negative | |
| 430 | + * @param size | |
| 431 | + * The size of the locked region; must be non-negative, and the sum | |
| 432 | + * {@code position} + {@code size} must be non-negative | |
| 433 | + * @param shared | |
| 434 | + * {@code true} to request a shared lock, in which case this | |
| 435 | + * channel must be open for reading (and possibly writing); | |
| 436 | + * {@code false} to request an exclusive lock, in which case this | |
| 437 | + * channel must be open for writing (and possibly reading) | |
| 438 | + * @param attachment | |
| 439 | + * The object to attach to the I/O operation; can be {@code null} | |
| 440 | + * @param handler | |
| 441 | + * The handler for consuming the result | |
| 442 | + * | |
| 443 | + * @throws OverlappingFileLockException | |
| 444 | + * If a lock that overlaps the requested region is already held by | |
| 445 | + * this Java virtual machine, or there is already a pending attempt | |
| 446 | + * to lock an overlapping region | |
| 447 | + * @throws IllegalArgumentException | |
| 448 | + * If the preconditions on the parameters do not hold | |
| 449 | + * @throws NonReadableChannelException | |
| 450 | + * If {@code shared} is true but this channel was not opened for reading | |
| 451 | + * @throws NonWritableChannelException | |
| 452 | + * If {@code shared} is false but this channel was not opened for writing | |
| 453 | + */ | |
| 454 | + public abstract <A> void lock(long position, | |
| 455 | + long size, | |
| 456 | + boolean shared, | |
| 457 | + A attachment, | |
| 458 | + CompletionHandler<FileLock,? super A> handler); | |
| 459 | + | |
| 460 | + /** | |
| 461 | + * Acquires an exclusive lock on this channel's file. | |
| 462 | + * | |
| 463 | + * <p> This method initiates an operation to acquire a lock on the given | |
| 464 | + * region of this channel's file. The {@code handler} parameter is a | |
| 465 | + * completion handler that is invoked when the lock is acquired (or the | |
| 466 | + * operation fails). The result passed to the completion handler is the | |
| 467 | + * resulting {@code FileLock}. | |
| 468 | + * | |
| 469 | + * <p> An invocation of this method of the form {@code ch.lock(att,handler)} | |
| 470 | + * behaves in exactly the same way as the invocation | |
| 471 | + * <pre> | |
| 472 | + * ch.{@link #lock(long,long,boolean,Object,CompletionHandler) lock}(0L, Long.MAX_VALUE, false, att, handler) | |
| 473 | + * </pre> | |
| 474 | + * | |
| 475 | + * @param attachment | |
| 476 | + * The object to attach to the I/O operation; can be {@code null} | |
| 477 | + * @param handler | |
| 478 | + * The handler for consuming the result | |
| 479 | + * | |
| 480 | + * @throws OverlappingFileLockException | |
| 481 | + * If a lock is already held by this Java virtual machine, or there | |
| 482 | + * is already a pending attempt to lock a region | |
| 483 | + * @throws NonWritableChannelException | |
| 484 | + * If this channel was not opened for writing | |
| 485 | + */ | |
| 486 | + public final <A> void lock(A attachment, | |
| 487 | + CompletionHandler<FileLock,? super A> handler) | |
| 488 | + { | |
| 489 | + lock(0L, Long.MAX_VALUE, false, attachment, handler); | |
| 490 | + } | |
| 491 | + | |
| 492 | + /** | |
| 493 | + * Acquires a lock on the given region of this channel's file. | |
| 494 | + * | |
| 495 | + * <p> This method initiates an operation to acquire a lock on the given | |
| 496 | + * region of this channel's file. The method behaves in exactly the same | |
| 497 | + * manner as the {@link #lock(long, long, boolean, Object, CompletionHandler)} | |
| 498 | + * method except that instead of specifying a completion handler, this | |
| 499 | + * method returns a {@code Future} representing the pending result. The | |
| 500 | + * {@code Future}'s {@link Future#get() get} method returns the {@link | |
| 501 | + * FileLock} on successful completion. | |
| 502 | + * | |
| 503 | + * @param position | |
| 504 | + * The position at which the locked region is to start; must be | |
| 505 | + * non-negative | |
| 506 | + * @param size | |
| 507 | + * The size of the locked region; must be non-negative, and the sum | |
| 508 | + * {@code position} + {@code size} must be non-negative | |
| 509 | + * @param shared | |
| 510 | + * {@code true} to request a shared lock, in which case this | |
| 511 | + * channel must be open for reading (and possibly writing); | |
| 512 | + * {@code false} to request an exclusive lock, in which case this | |
| 513 | + * channel must be open for writing (and possibly reading) | |
| 514 | + * | |
| 515 | + * @return a {@code Future} object representing the pending result | |
| 516 | + * | |
| 517 | + * @throws OverlappingFileLockException | |
| 518 | + * If a lock is already held by this Java virtual machine, or there | |
| 519 | + * is already a pending attempt to lock a region | |
| 520 | + * @throws IllegalArgumentException | |
| 521 | + * If the preconditions on the parameters do not hold | |
| 522 | + * @throws NonReadableChannelException | |
| 523 | + * If {@code shared} is true but this channel was not opened for reading | |
| 524 | + * @throws NonWritableChannelException | |
| 525 | + * If {@code shared} is false but this channel was not opened for writing | |
| 526 | + */ | |
| 527 | + public abstract Future<FileLock> lock(long position, long size, boolean shared); | |
| 528 | + | |
| 529 | + /** | |
| 530 | + * Acquires an exclusive lock on this channel's file. | |
| 531 | + * | |
| 532 | + * <p> This method initiates an operation to acquire an exclusive lock on this | |
| 533 | + * channel's file. The method returns a {@code Future} representing the | |
| 534 | + * pending result of the operation. The {@code Future}'s {@link Future#get() | |
| 535 | + * get} method returns the {@link FileLock} on successful completion. | |
| 536 | + * | |
| 537 | + * <p> An invocation of this method behaves in exactly the same way as the | |
| 538 | + * invocation | |
| 539 | + * <pre> | |
| 540 | + * ch.{@link #lock(long,long,boolean) lock}(0L, Long.MAX_VALUE, false) | |
| 541 | + * </pre> | |
| 542 | + * | |
| 543 | + * @return a {@code Future} object representing the pending result | |
| 544 | + * | |
| 545 | + * @throws OverlappingFileLockException | |
| 546 | + * If a lock is already held by this Java virtual machine, or there | |
| 547 | + * is already a pending attempt to lock a region | |
| 548 | + * @throws NonWritableChannelException | |
| 549 | + * If this channel was not opened for writing | |
| 550 | + */ | |
| 551 | + public final Future<FileLock> lock() { | |
| 552 | + return lock(0L, Long.MAX_VALUE, false); | |
| 553 | + } | |
| 554 | + | |
| 555 | + /** | |
| 556 | + * Attempts to acquire a lock on the given region of this channel's file. | |
| 557 | + * | |
| 558 | + * <p> This method does not block. An invocation always returns immediately, | |
| 559 | + * either having acquired a lock on the requested region or having failed to | |
| 560 | + * do so. If it fails to acquire a lock because an overlapping lock is held | |
| 561 | + * by another program then it returns {@code null}. If it fails to acquire | |
| 562 | + * a lock for any other reason then an appropriate exception is thrown. | |
| 563 | + * | |
| 564 | + * @param position | |
| 565 | + * The position at which the locked region is to start; must be | |
| 566 | + * non-negative | |
| 567 | + * | |
| 568 | + * @param size | |
| 569 | + * The size of the locked region; must be non-negative, and the sum | |
| 570 | + * {@code position} + {@code size} must be non-negative | |
| 571 | + * | |
| 572 | + * @param shared | |
| 573 | + * {@code true} to request a shared lock, | |
| 574 | + * {@code false} to request an exclusive lock | |
| 575 | + * | |
| 576 | + * @return A lock object representing the newly-acquired lock, | |
| 577 | + * or {@code null} if the lock could not be acquired | |
| 578 | + * because another program holds an overlapping lock | |
| 579 | + * | |
| 580 | + * @throws IllegalArgumentException | |
| 581 | + * If the preconditions on the parameters do not hold | |
| 582 | + * @throws ClosedChannelException | |
| 583 | + * If this channel is closed | |
| 584 | + * @throws OverlappingFileLockException | |
| 585 | + * If a lock that overlaps the requested region is already held by | |
| 586 | + * this Java virtual machine, or if another thread is already | |
| 587 | + * blocked in this method and is attempting to lock an overlapping | |
| 588 | + * region of the same file | |
| 589 | + * @throws NonReadableChannelException | |
| 590 | + * If {@code shared} is true but this channel was not opened for reading | |
| 591 | + * @throws NonWritableChannelException | |
| 592 | + * If {@code shared} is false but this channel was not opened for writing | |
| 593 | + * | |
| 594 | + * @throws IOException | |
| 595 | + * If some other I/O error occurs | |
| 596 | + * | |
| 597 | + * @see #lock(Object,CompletionHandler) | |
| 598 | + * @see #lock(long,long,boolean,Object,CompletionHandler) | |
| 599 | + * @see #tryLock() | |
| 600 | + */ | |
| 601 | + public abstract FileLock tryLock(long position, long size, boolean shared) | |
| 602 | + throws IOException; | |
| 603 | + | |
| 604 | + /** | |
| 605 | + * Attempts to acquire an exclusive lock on this channel's file. | |
| 606 | + * | |
| 607 | + * <p> An invocation of this method of the form {@code ch.tryLock()} | |
| 608 | + * behaves in exactly the same way as the invocation | |
| 609 | + * | |
| 610 | + * <pre> | |
| 611 | + * ch.{@link #tryLock(long,long,boolean) tryLock}(0L, Long.MAX_VALUE, false) </pre> | |
| 612 | + * | |
| 613 | + * @return A lock object representing the newly-acquired lock, | |
| 614 | + * or {@code null} if the lock could not be acquired | |
| 615 | + * because another program holds an overlapping lock | |
| 616 | + * | |
| 617 | + * @throws ClosedChannelException | |
| 618 | + * If this channel is closed | |
| 619 | + * @throws OverlappingFileLockException | |
| 620 | + * If a lock that overlaps the requested region is already held by | |
| 621 | + * this Java virtual machine, or if another thread is already | |
| 622 | + * blocked in this method and is attempting to lock an overlapping | |
| 623 | + * region | |
| 624 | + * @throws NonWritableChannelException | |
| 625 | + * If {@code shared} is false but this channel was not opened for writing | |
| 626 | + * | |
| 627 | + * @throws IOException | |
| 628 | + * If some other I/O error occurs | |
| 629 | + * | |
| 630 | + * @see #lock(Object,CompletionHandler) | |
| 631 | + * @see #lock(long,long,boolean,Object,CompletionHandler) | |
| 632 | + * @see #tryLock(long,long,boolean) | |
| 633 | + */ | |
| 634 | + public final FileLock tryLock() throws IOException { | |
| 635 | + return tryLock(0L, Long.MAX_VALUE, false); | |
| 636 | + } | |
| 637 | + | |
| 638 | + /** | |
| 639 | + * Reads a sequence of bytes from this channel into the given buffer, | |
| 640 | + * starting at the given file position. | |
| 641 | + * | |
| 642 | + * <p> This method initiates the reading of a sequence of bytes from this | |
| 643 | + * channel into the given buffer, starting at the given file position. The | |
| 644 | + * result of the read is the number of bytes read or {@code -1} if the given | |
| 645 | + * position is greater than or equal to the file's size at the time that the | |
| 646 | + * read is attempted. | |
| 647 | + * | |
| 648 | + * <p> This method works in the same manner as the {@link | |
| 649 | + * AsynchronousByteChannel#read(ByteBuffer,Object,CompletionHandler)} | |
| 650 | + * method, except that bytes are read starting at the given file position. | |
| 651 | + * If the given file position is greater than the file's size at the time | |
| 652 | + * that the read is attempted then no bytes are read. | |
| 653 | + * | |
| 654 | + * @param dst | |
| 655 | + * The buffer into which bytes are to be transferred | |
| 656 | + * @param position | |
| 657 | + * The file position at which the transfer is to begin; | |
| 658 | + * must be non-negative | |
| 659 | + * @param attachment | |
| 660 | + * The object to attach to the I/O operation; can be {@code null} | |
| 661 | + * @param handler | |
| 662 | + * The handler for consuming the result | |
| 663 | + * | |
| 664 | + * @throws IllegalArgumentException | |
| 665 | + * If the position is negative or the buffer is read-only | |
| 666 | + * @throws NonReadableChannelException | |
| 667 | + * If this channel was not opened for reading | |
| 668 | + */ | |
| 669 | + public abstract <A> void read(ByteBuffer dst, | |
| 670 | + long position, | |
| 671 | + A attachment, | |
| 672 | + CompletionHandler<Integer,? super A> handler); | |
| 673 | + | |
| 674 | + /** | |
| 675 | + * Reads a sequence of bytes from this channel into the given buffer, | |
| 676 | + * starting at the given file position. | |
| 677 | + * | |
| 678 | + * <p> This method initiates the reading of a sequence of bytes from this | |
| 679 | + * channel into the given buffer, starting at the given file position. This | |
| 680 | + * method returns a {@code Future} representing the pending result of the | |
| 681 | + * operation. The {@code Future}'s {@link Future#get() get} method returns | |
| 682 | + * the number of bytes read or {@code -1} if the given position is greater | |
| 683 | + * than or equal to the file's size at the time that the read is attempted. | |
| 684 | + * | |
| 685 | + * <p> This method works in the same manner as the {@link | |
| 686 | + * AsynchronousByteChannel#read(ByteBuffer)} method, except that bytes are | |
| 687 | + * read starting at the given file position. If the given file position is | |
| 688 | + * greater than the file's size at the time that the read is attempted then | |
| 689 | + * no bytes are read. | |
| 690 | + * | |
| 691 | + * @param dst | |
| 692 | + * The buffer into which bytes are to be transferred | |
| 693 | + * @param position | |
| 694 | + * The file position at which the transfer is to begin; | |
| 695 | + * must be non-negative | |
| 696 | + * | |
| 697 | + * @return A {@code Future} object representing the pending result | |
| 698 | + * | |
| 699 | + * @throws IllegalArgumentException | |
| 700 | + * If the position is negative or the buffer is read-only | |
| 701 | + * @throws NonReadableChannelException | |
| 702 | + * If this channel was not opened for reading | |
| 703 | + */ | |
| 704 | + public abstract Future<Integer> read(ByteBuffer dst, long position); | |
| 705 | + | |
| 706 | + /** | |
| 707 | + * Writes a sequence of bytes to this channel from the given buffer, starting | |
| 708 | + * at the given file position. | |
| 709 | + * | |
| 710 | + * <p> This method works in the same manner as the {@link | |
| 711 | + * AsynchronousByteChannel#write(ByteBuffer,Object,CompletionHandler)} | |
| 712 | + * method, except that bytes are written starting at the given file position. | |
| 713 | + * If the given position is greater than the file's size, at the time that | |
| 714 | + * the write is attempted, then the file will be grown to accommodate the new | |
| 715 | + * bytes; the values of any bytes between the previous end-of-file and the | |
| 716 | + * newly-written bytes are unspecified. | |
| 717 | + * | |
| 718 | + * @param src | |
| 719 | + * The buffer from which bytes are to be transferred | |
| 720 | + * @param position | |
| 721 | + * The file position at which the transfer is to begin; | |
| 722 | + * must be non-negative | |
| 723 | + * @param attachment | |
| 724 | + * The object to attach to the I/O operation; can be {@code null} | |
| 725 | + * @param handler | |
| 726 | + * The handler for consuming the result | |
| 727 | + * | |
| 728 | + * @throws IllegalArgumentException | |
| 729 | + * If the position is negative | |
| 730 | + * @throws NonWritableChannelException | |
| 731 | + * If this channel was not opened for writing | |
| 732 | + */ | |
| 733 | + public abstract <A> void write(ByteBuffer src, | |
| 734 | + long position, | |
| 735 | + A attachment, | |
| 736 | + CompletionHandler<Integer,? super A> handler); | |
| 737 | + | |
| 738 | + /** | |
| 739 | + * Writes a sequence of bytes to this channel from the given buffer, starting | |
| 740 | + * at the given file position. | |
| 741 | + * | |
| 742 | + * <p> This method initiates the writing of a sequence of bytes to this | |
| 743 | + * channel from the given buffer, starting at the given file position. The | |
| 744 | + * method returns a {@code Future} representing the pending result of the | |
| 745 | + * write operation. The {@code Future}'s {@link Future#get() get} method | |
| 746 | + * returns the number of bytes written. | |
| 747 | + * | |
| 748 | + * <p> This method works in the same manner as the {@link | |
| 749 | + * AsynchronousByteChannel#write(ByteBuffer)} method, except that bytes are | |
| 750 | + * written starting at the given file position. If the given position is | |
| 751 | + * greater than the file's size, at the time that the write is attempted, | |
| 752 | + * then the file will be grown to accommodate the new bytes; the values of | |
| 753 | + * any bytes between the previous end-of-file and the newly-written bytes | |
| 754 | + * are unspecified. | |
| 755 | + * | |
| 756 | + * @param src | |
| 757 | + * The buffer from which bytes are to be transferred | |
| 758 | + * @param position | |
| 759 | + * The file position at which the transfer is to begin; | |
| 760 | + * must be non-negative | |
| 761 | + * | |
| 762 | + * @return A {@code Future} object representing the pending result | |
| 763 | + * | |
| 764 | + * @throws IllegalArgumentException | |
| 765 | + * If the position is negative | |
| 766 | + * @throws NonWritableChannelException | |
| 767 | + * If this channel was not opened for writing | |
| 768 | + */ | |
| 769 | + public abstract Future<Integer> write(ByteBuffer src, long position); | |
| 770 | +} | |
Binary file not shown.
| @@ -0,0 +1,300 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels; | |
| 27 | + | |
| 28 | +import java.nio.channels.spi.*; | |
| 29 | +import java.net.SocketOption; | |
| 30 | +import java.net.SocketAddress; | |
| 31 | +import java.util.concurrent.Future; | |
| 32 | +import java.io.IOException; | |
| 33 | + | |
| 34 | +/** | |
| 35 | + * An asynchronous channel for stream-oriented listening sockets. | |
| 36 | + * | |
| 37 | + * <p> An asynchronous server-socket channel is created by invoking the | |
| 38 | + * {@link #open open} method of this class. | |
| 39 | + * A newly-created asynchronous server-socket channel is open but not yet bound. | |
| 40 | + * It can be bound to a local address and configured to listen for connections | |
| 41 | + * by invoking the {@link #bind(SocketAddress,int) bind} method. Once bound, | |
| 42 | + * the {@link #accept(Object,CompletionHandler) accept} method | |
| 43 | + * is used to initiate the accepting of connections to the channel's socket. | |
| 44 | + * An attempt to invoke the <tt>accept</tt> method on an unbound channel will | |
| 45 | + * cause a {@link NotYetBoundException} to be thrown. | |
| 46 | + * | |
| 47 | + * <p> Channels of this type are safe for use by multiple concurrent threads | |
| 48 | + * though at most one accept operation can be outstanding at any time. | |
| 49 | + * If a thread initiates an accept operation before a previous accept operation | |
| 50 | + * has completed then an {@link AcceptPendingException} will be thrown. | |
| 51 | + * | |
| 52 | + * <p> Socket options are configured using the {@link #setOption(SocketOption,Object) | |
| 53 | + * setOption} method. Channels of this type support the following options: | |
| 54 | + * <blockquote> | |
| 55 | + * <table border> | |
| 56 | + * <tr> | |
| 57 | + * <th>Option Name</th> | |
| 58 | + * <th>Description</th> | |
| 59 | + * </tr> | |
| 60 | + * <tr> | |
| 61 | + * <td> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </td> | |
| 62 | + * <td> The size of the socket receive buffer </td> | |
| 63 | + * </tr> | |
| 64 | + * <tr> | |
| 65 | + * <td> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </td> | |
| 66 | + * <td> Re-use address </td> | |
| 67 | + * </tr> | |
| 68 | + * </table> | |
| 69 | + * </blockquote> | |
| 70 | + * Additional (implementation specific) options may also be supported. | |
| 71 | + * | |
| 72 | + * <p> <b>Usage Example:</b> | |
| 73 | + * <pre> | |
| 74 | + * final AsynchronousServerSocketChannel listener = | |
| 75 | + * AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(5000)); | |
| 76 | + * | |
| 77 | + * listener.accept(null, new CompletionHandler<AsynchronousSocketChannel,Void>() { | |
| 78 | + * public void completed(AsynchronousSocketChannel ch, Void att) { | |
| 79 | + * // accept the next connection | |
| 80 | + * listener.accept(null, this); | |
| 81 | + * | |
| 82 | + * // handle this connection | |
| 83 | + * handle(ch); | |
| 84 | + * } | |
| 85 | + * public void failed(Throwable exc, Void att) { | |
| 86 | + * ... | |
| 87 | + * } | |
| 88 | + * }); | |
| 89 | + * </pre> | |
| 90 | + * | |
| 91 | + * @since 1.7 | |
| 92 | + */ | |
| 93 | + | |
| 94 | +public abstract class AsynchronousServerSocketChannel | |
| 95 | + implements AsynchronousChannel, NetworkChannel | |
| 96 | +{ | |
| 97 | + private final AsynchronousChannelProvider provider; | |
| 98 | + | |
| 99 | + /** | |
| 100 | + * Initializes a new instance of this class. | |
| 101 | + */ | |
| 102 | + protected AsynchronousServerSocketChannel(AsynchronousChannelProvider provider) { | |
| 103 | + this.provider = provider; | |
| 104 | + } | |
| 105 | + | |
| 106 | + /** | |
| 107 | + * Returns the provider that created this channel. | |
| 108 | + */ | |
| 109 | + public final AsynchronousChannelProvider provider() { | |
| 110 | + return provider; | |
| 111 | + } | |
| 112 | + | |
| 113 | + /** | |
| 114 | + * Opens an asynchronous server-socket channel. | |
| 115 | + * | |
| 116 | + * <p> The new channel is created by invoking the {@link | |
| 117 | + * java.nio.channels.spi.AsynchronousChannelProvider#openAsynchronousServerSocketChannel | |
| 118 | + * openAsynchronousServerSocketChannel} method on the {@link | |
| 119 | + * java.nio.channels.spi.AsynchronousChannelProvider} object that created | |
| 120 | + * the given group. If the group parameter is <tt>null</tt> then the | |
| 121 | + * resulting channel is created by the system-wide default provider, and | |
| 122 | + * bound to the <em>default group</em>. | |
| 123 | + * | |
| 124 | + * @param group | |
| 125 | + * The group to which the newly constructed channel should be bound, | |
| 126 | + * or <tt>null</tt> for the default group | |
| 127 | + * | |
| 128 | + * @return A new asynchronous server socket channel | |
| 129 | + * | |
| 130 | + * @throws ShutdownChannelGroupException | |
| 131 | + * If the channel group is shutdown | |
| 132 | + * @throws IOException | |
| 133 | + * If an I/O error occurs | |
| 134 | + */ | |
| 135 | + public static AsynchronousServerSocketChannel open(AsynchronousChannelGroup group) | |
| 136 | + throws IOException | |
| 137 | + { | |
| 138 | + AsynchronousChannelProvider provider = (group == null) ? | |
| 139 | + AsynchronousChannelProvider.provider() : group.provider(); | |
| 140 | + return provider.openAsynchronousServerSocketChannel(group); | |
| 141 | + } | |
| 142 | + | |
| 143 | + /** | |
| 144 | + * Opens an asynchronous server-socket channel. | |
| 145 | + * | |
| 146 | + * <p> This method returns an asynchronous server socket channel that is | |
| 147 | + * bound to the <em>default group</em>. This method is equivalent to evaluating | |
| 148 | + * the expression: | |
| 149 | + * <blockquote><pre> | |
| 150 | + * open((AsynchronousChannelGroup)null); | |
| 151 | + * </pre></blockquote> | |
| 152 | + * | |
| 153 | + * @return A new asynchronous server socket channel | |
| 154 | + * | |
| 155 | + * @throws IOException | |
| 156 | + * If an I/O error occurs | |
| 157 | + */ | |
| 158 | + public static AsynchronousServerSocketChannel open() | |
| 159 | + throws IOException | |
| 160 | + { | |
| 161 | + return open(null); | |
| 162 | + } | |
| 163 | + | |
| 164 | + /** | |
| 165 | + * Binds the channel's socket to a local address and configures the socket to | |
| 166 | + * listen for connections. | |
| 167 | + * | |
| 168 | + * <p> An invocation of this method is equivalent to the following: | |
| 169 | + * <blockquote><pre> | |
| 170 | + * bind(local, 0); | |
| 171 | + * </pre></blockquote> | |
| 172 | + * | |
| 173 | + * @param local | |
| 174 | + * The local address to bind the socket, or <tt>null</tt> to bind | |
| 175 | + * to an automatically assigned socket address | |
| 176 | + * | |
| 177 | + * @return This channel | |
| 178 | + * | |
| 179 | + * @throws AlreadyBoundException {@inheritDoc} | |
| 180 | + * @throws UnsupportedAddressTypeException {@inheritDoc} | |
| 181 | + * @throws SecurityException {@inheritDoc} | |
| 182 | + * @throws ClosedChannelException {@inheritDoc} | |
| 183 | + * @throws IOException {@inheritDoc} | |
| 184 | + */ | |
| 185 | + public final AsynchronousServerSocketChannel bind(SocketAddress local) | |
| 186 | + throws IOException | |
| 187 | + { | |
| 188 | + return bind(local, 0); | |
| 189 | + } | |
| 190 | + | |
| 191 | + /** | |
| 192 | + * Binds the channel's socket to a local address and configures the socket to | |
| 193 | + * listen for connections. | |
| 194 | + * | |
| 195 | + * <p> This method is used to establish an association between the socket and | |
| 196 | + * a local address. Once an association is established then the socket remains | |
| 197 | + * bound until the associated channel is closed. | |
| 198 | + * | |
| 199 | + * <p> The {@code backlog} parameter is the maximum number of pending | |
| 200 | + * connections on the socket. Its exact semantics are implementation specific. | |
| 201 | + * In particular, an implementation may impose a maximum length or may choose | |
| 202 | + * to ignore the parameter altogther. If the {@code backlog} parameter has | |
| 203 | + * the value {@code 0}, or a negative value, then an implementation specific | |
| 204 | + * default is used. | |
| 205 | + * | |
| 206 | + * @param local | |
| 207 | + * The local address to bind the socket, or {@code null} to bind | |
| 208 | + * to an automatically assigned socket address | |
| 209 | + * @param backlog | |
| 210 | + * The maximum number of pending connections | |
| 211 | + * | |
| 212 | + * @return This channel | |
| 213 | + * | |
| 214 | + * @throws AlreadyBoundException | |
| 215 | + * If the socket is already bound | |
| 216 | + * @throws UnsupportedAddressTypeException | |
| 217 | + * If the type of the given address is not supported | |
| 218 | + * @throws SecurityException | |
| 219 | + * If a security manager has been installed and its {@link | |
| 220 | + * SecurityManager#checkListen checkListen} method denies the operation | |
| 221 | + * @throws ClosedChannelException | |
| 222 | + * If the channel is closed | |
| 223 | + * @throws IOException | |
| 224 | + * If some other I/O error occurs | |
| 225 | + */ | |
| 226 | + public abstract AsynchronousServerSocketChannel bind(SocketAddress local, int backlog) | |
| 227 | + throws IOException; | |
| 228 | + | |
| 229 | + /** | |
| 230 | + * @throws IllegalArgumentException {@inheritDoc} | |
| 231 | + * @throws ClosedChannelException {@inheritDoc} | |
| 232 | + * @throws IOException {@inheritDoc} | |
| 233 | + */ | |
| 234 | + public abstract <T> AsynchronousServerSocketChannel setOption(SocketOption<T> name, T value) | |
| 235 | + throws IOException; | |
| 236 | + | |
| 237 | + /** | |
| 238 | + * Accepts a connection. | |
| 239 | + * | |
| 240 | + * <p> This method initiates an asynchronous operation to accept a | |
| 241 | + * connection made to this channel's socket. The {@code handler} parameter is | |
| 242 | + * a completion handler that is invoked when a connection is accepted (or | |
| 243 | + * the operation fails). The result passed to the completion handler is | |
| 244 | + * the {@link AsynchronousSocketChannel} to the new connection. | |
| 245 | + * | |
| 246 | + * <p> When a new connection is accepted then the resulting {@code | |
| 247 | + * AsynchronousSocketChannel} will be bound to the same {@link | |
| 248 | + * AsynchronousChannelGroup} as this channel. If the group is {@link | |
| 249 | + * AsynchronousChannelGroup#isShutdown shutdown} and a connection is accepted, | |
| 250 | + * then the connection is closed, and the operation completes with an {@code | |
| 251 | + * IOException} and cause {@link ShutdownChannelGroupException}. | |
| 252 | + * | |
| 253 | + * <p> To allow for concurrent handling of new connections, the completion | |
| 254 | + * handler is not invoked directly by the initiating thread when a new | |
| 255 | + * connection is accepted immediately (see <a | |
| 256 | + * href="AsynchronousChannelGroup.html#threading">Threading<a>). | |
| 257 | + * | |
| 258 | + * <p> If a security manager has been installed then it verifies that the | |
| 259 | + * address and port number of the connection's remote endpoint are permitted | |
| 260 | + * by the security manager's {@link SecurityManager#checkAccept checkAccept} | |
| 261 | + * method. The permission check is performed with privileges that are restricted | |
| 262 | + * by the calling context of this method. If the permission check fails then | |
| 263 | + * the connection is closed and the operation completes with a {@link | |
| 264 | + * SecurityException}. | |
| 265 | + * | |
| 266 | + * @param attachment | |
| 267 | + * The object to attach to the I/O operation; can be {@code null} | |
| 268 | + * @param handler | |
| 269 | + * The handler for consuming the result | |
| 270 | + * | |
| 271 | + * @throws AcceptPendingException | |
| 272 | + * If an accept operation is already in progress on this channel | |
| 273 | + * @throws NotYetBoundException | |
| 274 | + * If this channel's socket has not yet been bound | |
| 275 | + * @throws ShutdownChannelGroupException | |
| 276 | + * If the channel group has terminated | |
| 277 | + */ | |
| 278 | + public abstract <A> void accept(A attachment, | |
| 279 | + CompletionHandler<AsynchronousSocketChannel,? super A> handler); | |
| 280 | + | |
| 281 | + /** | |
| 282 | + * Accepts a connection. | |
| 283 | + * | |
| 284 | + * <p> This method initiates an asynchronous operation to accept a | |
| 285 | + * connection made to this channel's socket. The method behaves in exactly | |
| 286 | + * the same manner as the {@link #accept(Object, CompletionHandler)} method | |
| 287 | + * except that instead of specifying a completion handler, this method | |
| 288 | + * returns a {@code Future} representing the pending result. The {@code | |
| 289 | + * Future}'s {@link Future#get() get} method returns the {@link | |
| 290 | + * AsynchronousSocketChannel} to the new connection on successful completion. | |
| 291 | + * | |
| 292 | + * @return a {@code Future} object representing the pending result | |
| 293 | + * | |
| 294 | + * @throws AcceptPendingException | |
| 295 | + * If an accept operation is already in progress on this channel | |
| 296 | + * @throws NotYetBoundException | |
| 297 | + * If this channel's socket has not yet been bound | |
| 298 | + */ | |
| 299 | + public abstract Future<AsynchronousSocketChannel> accept(); | |
| 300 | +} | |
Binary file not shown.
| @@ -0,0 +1,648 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels; | |
| 27 | + | |
| 28 | +import java.nio.channels.spi.*; | |
| 29 | +import java.util.concurrent.TimeUnit; | |
| 30 | +import java.util.concurrent.Future; | |
| 31 | +import java.io.IOException; | |
| 32 | +import java.net.SocketOption; | |
| 33 | +import java.net.SocketAddress; | |
| 34 | +import java.nio.ByteBuffer; | |
| 35 | + | |
| 36 | +/** | |
| 37 | + * An asynchronous channel for stream-oriented connecting sockets. | |
| 38 | + * | |
| 39 | + * <p> Asynchronous socket channels are created in one of two ways. A newly-created | |
| 40 | + * {@code AsynchronousSocketChannel} is created by invoking one of the {@link | |
| 41 | + * #open open} methods defined by this class. A newly-created channel is open but | |
| 42 | + * not yet connected. A connected {@code AsynchronousSocketChannel} is created | |
| 43 | + * when a connection is made to the socket of an {@link AsynchronousServerSocketChannel}. | |
| 44 | + * It is not possible to create an asynchronous socket channel for an arbitrary, | |
| 45 | + * pre-existing {@link java.net.Socket socket}. | |
| 46 | + * | |
| 47 | + * <p> A newly-created channel is connected by invoking its {@link #connect connect} | |
| 48 | + * method; once connected, a channel remains connected until it is closed. Whether | |
| 49 | + * or not a socket channel is connected may be determined by invoking its {@link | |
| 50 | + * #getRemoteAddress getRemoteAddress} method. An attempt to invoke an I/O | |
| 51 | + * operation upon an unconnected channel will cause a {@link NotYetConnectedException} | |
| 52 | + * to be thrown. | |
| 53 | + * | |
| 54 | + * <p> Channels of this type are safe for use by multiple concurrent threads. | |
| 55 | + * They support concurrent reading and writing, though at most one read operation | |
| 56 | + * and one write operation can be outstanding at any time. | |
| 57 | + * If a thread initiates a read operation before a previous read operation has | |
| 58 | + * completed then a {@link ReadPendingException} will be thrown. Similarly, an | |
| 59 | + * attempt to initiate a write operation before a previous write has completed | |
| 60 | + * will throw a {@link WritePendingException}. | |
| 61 | + * | |
| 62 | + * <p> Socket options are configured using the {@link #setOption(SocketOption,Object) | |
| 63 | + * setOption} method. Asynchronous socket channels support the following options: | |
| 64 | + * <blockquote> | |
| 65 | + * <table border> | |
| 66 | + * <tr> | |
| 67 | + * <th>Option Name</th> | |
| 68 | + * <th>Description</th> | |
| 69 | + * </tr> | |
| 70 | + * <tr> | |
| 71 | + * <td> {@link java.net.StandardSocketOptions#SO_SNDBUF SO_SNDBUF} </td> | |
| 72 | + * <td> The size of the socket send buffer </td> | |
| 73 | + * </tr> | |
| 74 | + * <tr> | |
| 75 | + * <td> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </td> | |
| 76 | + * <td> The size of the socket receive buffer </td> | |
| 77 | + * </tr> | |
| 78 | + * <tr> | |
| 79 | + * <td> {@link java.net.StandardSocketOptions#SO_KEEPALIVE SO_KEEPALIVE} </td> | |
| 80 | + * <td> Keep connection alive </td> | |
| 81 | + * </tr> | |
| 82 | + * <tr> | |
| 83 | + * <td> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </td> | |
| 84 | + * <td> Re-use address </td> | |
| 85 | + * </tr> | |
| 86 | + * <tr> | |
| 87 | + * <td> {@link java.net.StandardSocketOptions#TCP_NODELAY TCP_NODELAY} </td> | |
| 88 | + * <td> Disable the Nagle algorithm </td> | |
| 89 | + * </tr> | |
| 90 | + * </table> | |
| 91 | + * </blockquote> | |
| 92 | + * Additional (implementation specific) options may also be supported. | |
| 93 | + * | |
| 94 | + * <h4>Timeouts</h4> | |
| 95 | + * | |
| 96 | + * <p> The {@link #read(ByteBuffer,long,TimeUnit,Object,CompletionHandler) read} | |
| 97 | + * and {@link #write(ByteBuffer,long,TimeUnit,Object,CompletionHandler) write} | |
| 98 | + * methods defined by this class allow a timeout to be specified when initiating | |
| 99 | + * a read or write operation. If the timeout elapses before an operation completes | |
| 100 | + * then the operation completes with the exception {@link | |
| 101 | + * InterruptedByTimeoutException}. A timeout may leave the channel, or the | |
| 102 | + * underlying connection, in an inconsistent state. Where the implementation | |
| 103 | + * cannot guarantee that bytes have not been read from the channel then it puts | |
| 104 | + * the channel into an implementation specific <em>error state</em>. A subsequent | |
| 105 | + * attempt to initiate a {@code read} operation causes an unspecified runtime | |
| 106 | + * exception to be thrown. Similarly if a {@code write} operation times out and | |
| 107 | + * the implementation cannot guarantee bytes have not been written to the | |
| 108 | + * channel then further attempts to {@code write} to the channel cause an | |
| 109 | + * unspecified runtime exception to be thrown. When a timeout elapses then the | |
| 110 | + * state of the {@link ByteBuffer}, or the sequence of buffers, for the I/O | |
| 111 | + * operation is not defined. Buffers should be discarded or at least care must | |
| 112 | + * be taken to ensure that the buffers are not accessed while the channel remains | |
| 113 | + * open. All methods that accept timeout parameters treat values less than or | |
| 114 | + * equal to zero to mean that the I/O operation does not timeout. | |
| 115 | + * | |
| 116 | + * @since 1.7 | |
| 117 | + */ | |
| 118 | + | |
| 119 | +public abstract class AsynchronousSocketChannel | |
| 120 | + implements AsynchronousByteChannel, NetworkChannel | |
| 121 | +{ | |
| 122 | + private final AsynchronousChannelProvider provider; | |
| 123 | + | |
| 124 | + /** | |
| 125 | + * Initializes a new instance of this class. | |
| 126 | + */ | |
| 127 | + protected AsynchronousSocketChannel(AsynchronousChannelProvider provider) { | |
| 128 | + this.provider = provider; | |
| 129 | + } | |
| 130 | + | |
| 131 | + /** | |
| 132 | + * Returns the provider that created this channel. | |
| 133 | + */ | |
| 134 | + public final AsynchronousChannelProvider provider() { | |
| 135 | + return provider; | |
| 136 | + } | |
| 137 | + | |
| 138 | + /** | |
| 139 | + * Opens an asynchronous socket channel. | |
| 140 | + * | |
| 141 | + * <p> The new channel is created by invoking the {@link | |
| 142 | + * AsynchronousChannelProvider#openAsynchronousSocketChannel | |
| 143 | + * openAsynchronousSocketChannel} method on the {@link | |
| 144 | + * AsynchronousChannelProvider} that created the group. If the group parameter | |
| 145 | + * is {@code null} then the resulting channel is created by the system-wide | |
| 146 | + * default provider, and bound to the <em>default group</em>. | |
| 147 | + * | |
| 148 | + * @param group | |
| 149 | + * The group to which the newly constructed channel should be bound, | |
| 150 | + * or {@code null} for the default group | |
| 151 | + * | |
| 152 | + * @return A new asynchronous socket channel | |
| 153 | + * | |
| 154 | + * @throws ShutdownChannelGroupException | |
| 155 | + * If the channel group is shutdown | |
| 156 | + * @throws IOException | |
| 157 | + * If an I/O error occurs | |
| 158 | + */ | |
| 159 | + public static AsynchronousSocketChannel open(AsynchronousChannelGroup group) | |
| 160 | + throws IOException | |
| 161 | + { | |
| 162 | + AsynchronousChannelProvider provider = (group == null) ? | |
| 163 | + AsynchronousChannelProvider.provider() : group.provider(); | |
| 164 | + return provider.openAsynchronousSocketChannel(group); | |
| 165 | + } | |
| 166 | + | |
| 167 | + /** | |
| 168 | + * Opens an asynchronous socket channel. | |
| 169 | + * | |
| 170 | + * <p> This method returns an asynchronous socket channel that is bound to | |
| 171 | + * the <em>default group</em>.This method is equivalent to evaluating the | |
| 172 | + * expression: | |
| 173 | + * <blockquote><pre> | |
| 174 | + * open((AsynchronousChannelGroup)null); | |
| 175 | + * </pre></blockquote> | |
| 176 | + * | |
| 177 | + * @return A new asynchronous socket channel | |
| 178 | + * | |
| 179 | + * @throws IOException | |
| 180 | + * If an I/O error occurs | |
| 181 | + */ | |
| 182 | + public static AsynchronousSocketChannel open() | |
| 183 | + throws IOException | |
| 184 | + { | |
| 185 | + return open(null); | |
| 186 | + } | |
| 187 | + | |
| 188 | + | |
| 189 | + // -- socket options and related -- | |
| 190 | + | |
| 191 | + /** | |
| 192 | + * @throws ConnectionPendingException | |
| 193 | + * If a connection operation is already in progress on this channel | |
| 194 | + * @throws AlreadyBoundException {@inheritDoc} | |
| 195 | + * @throws UnsupportedAddressTypeException {@inheritDoc} | |
| 196 | + * @throws ClosedChannelException {@inheritDoc} | |
| 197 | + * @throws IOException {@inheritDoc} | |
| 198 | + */ | |
| 199 | + @Override | |
| 200 | + public abstract AsynchronousSocketChannel bind(SocketAddress local) | |
| 201 | + throws IOException; | |
| 202 | + | |
| 203 | + /** | |
| 204 | + * @throws IllegalArgumentException {@inheritDoc} | |
| 205 | + * @throws ClosedChannelException {@inheritDoc} | |
| 206 | + * @throws IOException {@inheritDoc} | |
| 207 | + */ | |
| 208 | + @Override | |
| 209 | + public abstract <T> AsynchronousSocketChannel setOption(SocketOption<T> name, T value) | |
| 210 | + throws IOException; | |
| 211 | + | |
| 212 | + /** | |
| 213 | + * Shutdown the connection for reading without closing the channel. | |
| 214 | + * | |
| 215 | + * <p> Once shutdown for reading then further reads on the channel will | |
| 216 | + * return {@code -1}, the end-of-stream indication. If the input side of the | |
| 217 | + * connection is already shutdown then invoking this method has no effect. | |
| 218 | + * The effect on an outstanding read operation is system dependent and | |
| 219 | + * therefore not specified. The effect, if any, when there is data in the | |
| 220 | + * socket receive buffer that has not been read, or data arrives subsequently, | |
| 221 | + * is also system dependent. | |
| 222 | + * | |
| 223 | + * @return The channel | |
| 224 | + * | |
| 225 | + * @throws NotYetConnectedException | |
| 226 | + * If this channel is not yet connected | |
| 227 | + * @throws ClosedChannelException | |
| 228 | + * If this channel is closed | |
| 229 | + * @throws IOException | |
| 230 | + * If some other I/O error occurs | |
| 231 | + */ | |
| 232 | + public abstract AsynchronousSocketChannel shutdownInput() throws IOException; | |
| 233 | + | |
| 234 | + /** | |
| 235 | + * Shutdown the connection for writing without closing the channel. | |
| 236 | + * | |
| 237 | + * <p> Once shutdown for writing then further attempts to write to the | |
| 238 | + * channel will throw {@link ClosedChannelException}. If the output side of | |
| 239 | + * the connection is already shutdown then invoking this method has no | |
| 240 | + * effect. The effect on an outstanding write operation is system dependent | |
| 241 | + * and therefore not specified. | |
| 242 | + * | |
| 243 | + * @return The channel | |
| 244 | + * | |
| 245 | + * @throws NotYetConnectedException | |
| 246 | + * If this channel is not yet connected | |
| 247 | + * @throws ClosedChannelException | |
| 248 | + * If this channel is closed | |
| 249 | + * @throws IOException | |
| 250 | + * If some other I/O error occurs | |
| 251 | + */ | |
| 252 | + public abstract AsynchronousSocketChannel shutdownOutput() throws IOException; | |
| 253 | + | |
| 254 | + // -- state -- | |
| 255 | + | |
| 256 | + /** | |
| 257 | + * Returns the remote address to which this channel's socket is connected. | |
| 258 | + * | |
| 259 | + * <p> Where the channel is bound and connected to an Internet Protocol | |
| 260 | + * socket address then the return value from this method is of type {@link | |
| 261 | + * java.net.InetSocketAddress}. | |
| 262 | + * | |
| 263 | + * @return The remote address; {@code null} if the channel's socket is not | |
| 264 | + * connected | |
| 265 | + * | |
| 266 | + * @throws ClosedChannelException | |
| 267 | + * If the channel is closed | |
| 268 | + * @throws IOException | |
| 269 | + * If an I/O error occurs | |
| 270 | + */ | |
| 271 | + public abstract SocketAddress getRemoteAddress() throws IOException; | |
| 272 | + | |
| 273 | + // -- asynchronous operations -- | |
| 274 | + | |
| 275 | + /** | |
| 276 | + * Connects this channel. | |
| 277 | + * | |
| 278 | + * <p> This method initiates an operation to connect this channel. The | |
| 279 | + * {@code handler} parameter is a completion handler that is invoked when | |
| 280 | + * the connection is successfully established or connection cannot be | |
| 281 | + * established. If the connection cannot be established then the channel is | |
| 282 | + * closed. | |
| 283 | + * | |
| 284 | + * <p> This method performs exactly the same security checks as the {@link | |
| 285 | + * java.net.Socket} class. That is, if a security manager has been | |
| 286 | + * installed then this method verifies that its {@link | |
| 287 | + * java.lang.SecurityManager#checkConnect checkConnect} method permits | |
| 288 | + * connecting to the address and port number of the given remote endpoint. | |
| 289 | + * | |
| 290 | + * @param remote | |
| 291 | + * The remote address to which this channel is to be connected | |
| 292 | + * @param attachment | |
| 293 | + * The object to attach to the I/O operation; can be {@code null} | |
| 294 | + * @param handler | |
| 295 | + * The handler for consuming the result | |
| 296 | + * | |
| 297 | + * @throws UnresolvedAddressException | |
| 298 | + * If the given remote address is not fully resolved | |
| 299 | + * @throws UnsupportedAddressTypeException | |
| 300 | + * If the type of the given remote address is not supported | |
| 301 | + * @throws AlreadyConnectedException | |
| 302 | + * If this channel is already connected | |
| 303 | + * @throws ConnectionPendingException | |
| 304 | + * If a connection operation is already in progress on this channel | |
| 305 | + * @throws ShutdownChannelGroupException | |
| 306 | + * If the channel group has terminated | |
| 307 | + * @throws SecurityException | |
| 308 | + * If a security manager has been installed | |
| 309 | + * and it does not permit access to the given remote endpoint | |
| 310 | + * | |
| 311 | + * @see #getRemoteAddress | |
| 312 | + */ | |
| 313 | + public abstract <A> void connect(SocketAddress remote, | |
| 314 | + A attachment, | |
| 315 | + CompletionHandler<Void,? super A> handler); | |
| 316 | + | |
| 317 | + /** | |
| 318 | + * Connects this channel. | |
| 319 | + * | |
| 320 | + * <p> This method initiates an operation to connect this channel. This | |
| 321 | + * method behaves in exactly the same manner as the {@link | |
| 322 | + * #connect(SocketAddress, Object, CompletionHandler)} method except that | |
| 323 | + * instead of specifying a completion handler, this method returns a {@code | |
| 324 | + * Future} representing the pending result. The {@code Future}'s {@link | |
| 325 | + * Future#get() get} method returns {@code null} on successful completion. | |
| 326 | + * | |
| 327 | + * @param remote | |
| 328 | + * The remote address to which this channel is to be connected | |
| 329 | + * | |
| 330 | + * @return A {@code Future} object representing the pending result | |
| 331 | + * | |
| 332 | + * @throws UnresolvedAddressException | |
| 333 | + * If the given remote address is not fully resolved | |
| 334 | + * @throws UnsupportedAddressTypeException | |
| 335 | + * If the type of the given remote address is not supported | |
| 336 | + * @throws AlreadyConnectedException | |
| 337 | + * If this channel is already connected | |
| 338 | + * @throws ConnectionPendingException | |
| 339 | + * If a connection operation is already in progress on this channel | |
| 340 | + * @throws SecurityException | |
| 341 | + * If a security manager has been installed | |
| 342 | + * and it does not permit access to the given remote endpoint | |
| 343 | + */ | |
| 344 | + public abstract Future<Void> connect(SocketAddress remote); | |
| 345 | + | |
| 346 | + /** | |
| 347 | + * Reads a sequence of bytes from this channel into the given buffer. | |
| 348 | + * | |
| 349 | + * <p> This method initiates an asynchronous read operation to read a | |
| 350 | + * sequence of bytes from this channel into the given buffer. The {@code | |
| 351 | + * handler} parameter is a completion handler that is invoked when the read | |
| 352 | + * operation completes (or fails). The result passed to the completion | |
| 353 | + * handler is the number of bytes read or {@code -1} if no bytes could be | |
| 354 | + * read because the channel has reached end-of-stream. | |
| 355 | + * | |
| 356 | + * <p> If a timeout is specified and the timeout elapses before the operation | |
| 357 | + * completes then the operation completes with the exception {@link | |
| 358 | + * InterruptedByTimeoutException}. Where a timeout occurs, and the | |
| 359 | + * implementation cannot guarantee that bytes have not been read, or will not | |
| 360 | + * be read from the channel into the given buffer, then further attempts to | |
| 361 | + * read from the channel will cause an unspecific runtime exception to be | |
| 362 | + * thrown. | |
| 363 | + * | |
| 364 | + * <p> Otherwise this method works in the same manner as the {@link | |
| 365 | + * AsynchronousByteChannel#read(ByteBuffer,Object,CompletionHandler)} | |
| 366 | + * method. | |
| 367 | + * | |
| 368 | + * @param dst | |
| 369 | + * The buffer into which bytes are to be transferred | |
| 370 | + * @param timeout | |
| 371 | + * The maximum time for the I/O operation to complete | |
| 372 | + * @param unit | |
| 373 | + * The time unit of the {@code timeout} argument | |
| 374 | + * @param attachment | |
| 375 | + * The object to attach to the I/O operation; can be {@code null} | |
| 376 | + * @param handler | |
| 377 | + * The handler for consuming the result | |
| 378 | + * | |
| 379 | + * @throws IllegalArgumentException | |
| 380 | + * If the buffer is read-only | |
| 381 | + * @throws ReadPendingException | |
| 382 | + * If a read operation is already in progress on this channel | |
| 383 | + * @throws NotYetConnectedException | |
| 384 | + * If this channel is not yet connected | |
| 385 | + * @throws ShutdownChannelGroupException | |
| 386 | + * If the channel group has terminated | |
| 387 | + */ | |
| 388 | + public abstract <A> void read(ByteBuffer dst, | |
| 389 | + long timeout, | |
| 390 | + TimeUnit unit, | |
| 391 | + A attachment, | |
| 392 | + CompletionHandler<Integer,? super A> handler); | |
| 393 | + | |
| 394 | + /** | |
| 395 | + * @throws IllegalArgumentException {@inheritDoc} | |
| 396 | + * @throws ReadPendingException {@inheritDoc} | |
| 397 | + * @throws NotYetConnectedException | |
| 398 | + * If this channel is not yet connected | |
| 399 | + * @throws ShutdownChannelGroupException | |
| 400 | + * If the channel group has terminated | |
| 401 | + */ | |
| 402 | + @Override | |
| 403 | + public final <A> void read(ByteBuffer dst, | |
| 404 | + A attachment, | |
| 405 | + CompletionHandler<Integer,? super A> handler) | |
| 406 | + { | |
| 407 | + read(dst, 0L, TimeUnit.MILLISECONDS, attachment, handler); | |
| 408 | + } | |
| 409 | + | |
| 410 | + /** | |
| 411 | + * @throws IllegalArgumentException {@inheritDoc} | |
| 412 | + * @throws ReadPendingException {@inheritDoc} | |
| 413 | + * @throws NotYetConnectedException | |
| 414 | + * If this channel is not yet connected | |
| 415 | + */ | |
| 416 | + @Override | |
| 417 | + public abstract Future<Integer> read(ByteBuffer dst); | |
| 418 | + | |
| 419 | + /** | |
| 420 | + * Reads a sequence of bytes from this channel into a subsequence of the | |
| 421 | + * given buffers. This operation, sometimes called a <em>scattering read</em>, | |
| 422 | + * is often useful when implementing network protocols that group data into | |
| 423 | + * segments consisting of one or more fixed-length headers followed by a | |
| 424 | + * variable-length body. The {@code handler} parameter is a completion | |
| 425 | + * handler that is invoked when the read operation completes (or fails). The | |
| 426 | + * result passed to the completion handler is the number of bytes read or | |
| 427 | + * {@code -1} if no bytes could be read because the channel has reached | |
| 428 | + * end-of-stream. | |
| 429 | + * | |
| 430 | + * <p> This method initiates a read of up to <i>r</i> bytes from this channel, | |
| 431 | + * where <i>r</i> is the total number of bytes remaining in the specified | |
| 432 | + * subsequence of the given buffer array, that is, | |
| 433 | + * | |
| 434 | + * <blockquote><pre> | |
| 435 | + * dsts[offset].remaining() | |
| 436 | + * + dsts[offset+1].remaining() | |
| 437 | + * + ... + dsts[offset+length-1].remaining()</pre></blockquote> | |
| 438 | + * | |
| 439 | + * at the moment that the read is attempted. | |
| 440 | + * | |
| 441 | + * <p> Suppose that a byte sequence of length <i>n</i> is read, where | |
| 442 | + * <tt>0</tt> <tt><</tt> <i>n</i> <tt><=</tt> <i>r</i>. | |
| 443 | + * Up to the first <tt>dsts[offset].remaining()</tt> bytes of this sequence | |
| 444 | + * are transferred into buffer <tt>dsts[offset]</tt>, up to the next | |
| 445 | + * <tt>dsts[offset+1].remaining()</tt> bytes are transferred into buffer | |
| 446 | + * <tt>dsts[offset+1]</tt>, and so forth, until the entire byte sequence | |
| 447 | + * is transferred into the given buffers. As many bytes as possible are | |
| 448 | + * transferred into each buffer, hence the final position of each updated | |
| 449 | + * buffer, except the last updated buffer, is guaranteed to be equal to | |
| 450 | + * that buffer's limit. The underlying operating system may impose a limit | |
| 451 | + * on the number of buffers that may be used in an I/O operation. Where the | |
| 452 | + * number of buffers (with bytes remaining), exceeds this limit, then the | |
| 453 | + * I/O operation is performed with the maximum number of buffers allowed by | |
| 454 | + * the operating system. | |
| 455 | + * | |
| 456 | + * <p> If a timeout is specified and the timeout elapses before the operation | |
| 457 | + * completes then it completes with the exception {@link | |
| 458 | + * InterruptedByTimeoutException}. Where a timeout occurs, and the | |
| 459 | + * implementation cannot guarantee that bytes have not been read, or will not | |
| 460 | + * be read from the channel into the given buffers, then further attempts to | |
| 461 | + * read from the channel will cause an unspecific runtime exception to be | |
| 462 | + * thrown. | |
| 463 | + * | |
| 464 | + * @param dsts | |
| 465 | + * The buffers into which bytes are to be transferred | |
| 466 | + * @param offset | |
| 467 | + * The offset within the buffer array of the first buffer into which | |
| 468 | + * bytes are to be transferred; must be non-negative and no larger than | |
| 469 | + * {@code dsts.length} | |
| 470 | + * @param length | |
| 471 | + * The maximum number of buffers to be accessed; must be non-negative | |
| 472 | + * and no larger than {@code dsts.length - offset} | |
| 473 | + * @param timeout | |
| 474 | + * The maximum time for the I/O operation to complete | |
| 475 | + * @param unit | |
| 476 | + * The time unit of the {@code timeout} argument | |
| 477 | + * @param attachment | |
| 478 | + * The object to attach to the I/O operation; can be {@code null} | |
| 479 | + * @param handler | |
| 480 | + * The handler for consuming the result | |
| 481 | + * | |
| 482 | + * @throws IndexOutOfBoundsException | |
| 483 | + * If the pre-conditions for the {@code offset} and {@code length} | |
| 484 | + * parameter aren't met | |
| 485 | + * @throws IllegalArgumentException | |
| 486 | + * If the buffer is read-only | |
| 487 | + * @throws ReadPendingException | |
| 488 | + * If a read operation is already in progress on this channel | |
| 489 | + * @throws NotYetConnectedException | |
| 490 | + * If this channel is not yet connected | |
| 491 | + * @throws ShutdownChannelGroupException | |
| 492 | + * If the channel group has terminated | |
| 493 | + */ | |
| 494 | + public abstract <A> void read(ByteBuffer[] dsts, | |
| 495 | + int offset, | |
| 496 | + int length, | |
| 497 | + long timeout, | |
| 498 | + TimeUnit unit, | |
| 499 | + A attachment, | |
| 500 | + CompletionHandler<Long,? super A> handler); | |
| 501 | + | |
| 502 | + /** | |
| 503 | + * Writes a sequence of bytes to this channel from the given buffer. | |
| 504 | + * | |
| 505 | + * <p> This method initiates an asynchronous write operation to write a | |
| 506 | + * sequence of bytes to this channel from the given buffer. The {@code | |
| 507 | + * handler} parameter is a completion handler that is invoked when the write | |
| 508 | + * operation completes (or fails). The result passed to the completion | |
| 509 | + * handler is the number of bytes written. | |
| 510 | + * | |
| 511 | + * <p> If a timeout is specified and the timeout elapses before the operation | |
| 512 | + * completes then it completes with the exception {@link | |
| 513 | + * InterruptedByTimeoutException}. Where a timeout occurs, and the | |
| 514 | + * implementation cannot guarantee that bytes have not been written, or will | |
| 515 | + * not be written to the channel from the given buffer, then further attempts | |
| 516 | + * to write to the channel will cause an unspecific runtime exception to be | |
| 517 | + * thrown. | |
| 518 | + * | |
| 519 | + * <p> Otherwise this method works in the same manner as the {@link | |
| 520 | + * AsynchronousByteChannel#write(ByteBuffer,Object,CompletionHandler)} | |
| 521 | + * method. | |
| 522 | + * | |
| 523 | + * @param src | |
| 524 | + * The buffer from which bytes are to be retrieved | |
| 525 | + * @param timeout | |
| 526 | + * The maximum time for the I/O operation to complete | |
| 527 | + * @param unit | |
| 528 | + * The time unit of the {@code timeout} argument | |
| 529 | + * @param attachment | |
| 530 | + * The object to attach to the I/O operation; can be {@code null} | |
| 531 | + * @param handler | |
| 532 | + * The handler for consuming the result | |
| 533 | + * | |
| 534 | + * @throws WritePendingException | |
| 535 | + * If a write operation is already in progress on this channel | |
| 536 | + * @throws NotYetConnectedException | |
| 537 | + * If this channel is not yet connected | |
| 538 | + * @throws ShutdownChannelGroupException | |
| 539 | + * If the channel group has terminated | |
| 540 | + */ | |
| 541 | + public abstract <A> void write(ByteBuffer src, | |
| 542 | + long timeout, | |
| 543 | + TimeUnit unit, | |
| 544 | + A attachment, | |
| 545 | + CompletionHandler<Integer,? super A> handler); | |
| 546 | + | |
| 547 | + /** | |
| 548 | + * @throws WritePendingException {@inheritDoc} | |
| 549 | + * @throws NotYetConnectedException | |
| 550 | + * If this channel is not yet connected | |
| 551 | + * @throws ShutdownChannelGroupException | |
| 552 | + * If the channel group has terminated | |
| 553 | + */ | |
| 554 | + @Override | |
| 555 | + public final <A> void write(ByteBuffer src, | |
| 556 | + A attachment, | |
| 557 | + CompletionHandler<Integer,? super A> handler) | |
| 558 | + | |
| 559 | + { | |
| 560 | + write(src, 0L, TimeUnit.MILLISECONDS, attachment, handler); | |
| 561 | + } | |
| 562 | + | |
| 563 | + /** | |
| 564 | + * @throws WritePendingException {@inheritDoc} | |
| 565 | + * @throws NotYetConnectedException | |
| 566 | + * If this channel is not yet connected | |
| 567 | + */ | |
| 568 | + @Override | |
| 569 | + public abstract Future<Integer> write(ByteBuffer src); | |
| 570 | + | |
| 571 | + /** | |
| 572 | + * Writes a sequence of bytes to this channel from a subsequence of the given | |
| 573 | + * buffers. This operation, sometimes called a <em>gathering write</em>, is | |
| 574 | + * often useful when implementing network protocols that group data into | |
| 575 | + * segments consisting of one or more fixed-length headers followed by a | |
| 576 | + * variable-length body. The {@code handler} parameter is a completion | |
| 577 | + * handler that is invoked when the write operation completes (or fails). | |
| 578 | + * The result passed to the completion handler is the number of bytes written. | |
| 579 | + * | |
| 580 | + * <p> This method initiates a write of up to <i>r</i> bytes to this channel, | |
| 581 | + * where <i>r</i> is the total number of bytes remaining in the specified | |
| 582 | + * subsequence of the given buffer array, that is, | |
| 583 | + * | |
| 584 | + * <blockquote><pre> | |
| 585 | + * srcs[offset].remaining() | |
| 586 | + * + srcs[offset+1].remaining() | |
| 587 | + * + ... + srcs[offset+length-1].remaining()</pre></blockquote> | |
| 588 | + * | |
| 589 | + * at the moment that the write is attempted. | |
| 590 | + * | |
| 591 | + * <p> Suppose that a byte sequence of length <i>n</i> is written, where | |
| 592 | + * <tt>0</tt> <tt><</tt> <i>n</i> <tt><=</tt> <i>r</i>. | |
| 593 | + * Up to the first <tt>srcs[offset].remaining()</tt> bytes of this sequence | |
| 594 | + * are written from buffer <tt>srcs[offset]</tt>, up to the next | |
| 595 | + * <tt>srcs[offset+1].remaining()</tt> bytes are written from buffer | |
| 596 | + * <tt>srcs[offset+1]</tt>, and so forth, until the entire byte sequence is | |
| 597 | + * written. As many bytes as possible are written from each buffer, hence | |
| 598 | + * the final position of each updated buffer, except the last updated | |
| 599 | + * buffer, is guaranteed to be equal to that buffer's limit. The underlying | |
| 600 | + * operating system may impose a limit on the number of buffers that may be | |
| 601 | + * used in an I/O operation. Where the number of buffers (with bytes | |
| 602 | + * remaining), exceeds this limit, then the I/O operation is performed with | |
| 603 | + * the maximum number of buffers allowed by the operating system. | |
| 604 | + * | |
| 605 | + * <p> If a timeout is specified and the timeout elapses before the operation | |
| 606 | + * completes then it completes with the exception {@link | |
| 607 | + * InterruptedByTimeoutException}. Where a timeout occurs, and the | |
| 608 | + * implementation cannot guarantee that bytes have not been written, or will | |
| 609 | + * not be written to the channel from the given buffers, then further attempts | |
| 610 | + * to write to the channel will cause an unspecific runtime exception to be | |
| 611 | + * thrown. | |
| 612 | + * | |
| 613 | + * @param srcs | |
| 614 | + * The buffers from which bytes are to be retrieved | |
| 615 | + * @param offset | |
| 616 | + * The offset within the buffer array of the first buffer from which | |
| 617 | + * bytes are to be retrieved; must be non-negative and no larger | |
| 618 | + * than {@code srcs.length} | |
| 619 | + * @param length | |
| 620 | + * The maximum number of buffers to be accessed; must be non-negative | |
| 621 | + * and no larger than {@code srcs.length - offset} | |
| 622 | + * @param timeout | |
| 623 | + * The maximum time for the I/O operation to complete | |
| 624 | + * @param unit | |
| 625 | + * The time unit of the {@code timeout} argument | |
| 626 | + * @param attachment | |
| 627 | + * The object to attach to the I/O operation; can be {@code null} | |
| 628 | + * @param handler | |
| 629 | + * The handler for consuming the result | |
| 630 | + * | |
| 631 | + * @throws IndexOutOfBoundsException | |
| 632 | + * If the pre-conditions for the {@code offset} and {@code length} | |
| 633 | + * parameter aren't met | |
| 634 | + * @throws WritePendingException | |
| 635 | + * If a write operation is already in progress on this channel | |
| 636 | + * @throws NotYetConnectedException | |
| 637 | + * If this channel is not yet connected | |
| 638 | + * @throws ShutdownChannelGroupException | |
| 639 | + * If the channel group has terminated | |
| 640 | + */ | |
| 641 | + public abstract <A> void write(ByteBuffer[] srcs, | |
| 642 | + int offset, | |
| 643 | + int length, | |
| 644 | + long timeout, | |
| 645 | + TimeUnit unit, | |
| 646 | + A attachment, | |
| 647 | + CompletionHandler<Long,? super A> handler); | |
| 648 | +} | |
Binary file not shown.
| @@ -0,0 +1,45 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels; | |
| 27 | + | |
| 28 | +import java.io.IOException; | |
| 29 | + | |
| 30 | + | |
| 31 | +/** | |
| 32 | + * A channel that can read and write bytes. This interface simply unifies | |
| 33 | + * {@link ReadableByteChannel} and {@link WritableByteChannel}; it does not | |
| 34 | + * specify any new operations. | |
| 35 | + * | |
| 36 | + * @author Mark Reinhold | |
| 37 | + * @author JSR-51 Expert Group | |
| 38 | + * @since 1.4 | |
| 39 | + */ | |
| 40 | + | |
| 41 | +public interface ByteChannel | |
| 42 | + extends ReadableByteChannel, WritableByteChannel | |
| 43 | +{ | |
| 44 | + | |
| 45 | +} | |
Binary file not shown.
| @@ -0,0 +1,84 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels; | |
| 27 | + | |
| 28 | +import java.io.IOException; | |
| 29 | +import java.io.Closeable; | |
| 30 | + | |
| 31 | + | |
| 32 | +/** | |
| 33 | + * A nexus for I/O operations. | |
| 34 | + * | |
| 35 | + * <p> A channel represents an open connection to an entity such as a hardware | |
| 36 | + * device, a file, a network socket, or a program component that is capable of | |
| 37 | + * performing one or more distinct I/O operations, for example reading or | |
| 38 | + * writing. | |
| 39 | + * | |
| 40 | + * <p> A channel is either open or closed. A channel is open upon creation, | |
| 41 | + * and once closed it remains closed. Once a channel is closed, any attempt to | |
| 42 | + * invoke an I/O operation upon it will cause a {@link ClosedChannelException} | |
| 43 | + * to be thrown. Whether or not a channel is open may be tested by invoking | |
| 44 | + * its {@link #isOpen isOpen} method. | |
| 45 | + * | |
| 46 | + * <p> Channels are, in general, intended to be safe for multithreaded access | |
| 47 | + * as described in the specifications of the interfaces and classes that extend | |
| 48 | + * and implement this interface. | |
| 49 | + * | |
| 50 | + * | |
| 51 | + * @author Mark Reinhold | |
| 52 | + * @author JSR-51 Expert Group | |
| 53 | + * @since 1.4 | |
| 54 | + */ | |
| 55 | + | |
| 56 | +public interface Channel extends Closeable { | |
| 57 | + | |
| 58 | + /** | |
| 59 | + * Tells whether or not this channel is open. </p> | |
| 60 | + * | |
| 61 | + * @return <tt>true</tt> if, and only if, this channel is open | |
| 62 | + */ | |
| 63 | + public boolean isOpen(); | |
| 64 | + | |
| 65 | + /** | |
| 66 | + * Closes this channel. | |
| 67 | + * | |
| 68 | + * <p> After a channel is closed, any further attempt to invoke I/O | |
| 69 | + * operations upon it will cause a {@link ClosedChannelException} to be | |
| 70 | + * thrown. | |
| 71 | + * | |
| 72 | + * <p> If this channel is already closed then invoking this method has no | |
| 73 | + * effect. | |
| 74 | + * | |
| 75 | + * <p> This method may be invoked at any time. If some other thread has | |
| 76 | + * already invoked it, however, then another invocation will block until | |
| 77 | + * the first invocation is complete, after which it will return without | |
| 78 | + * effect. </p> | |
| 79 | + * | |
| 80 | + * @throws IOException If an I/O error occurs | |
| 81 | + */ | |
| 82 | + public void close() throws IOException; | |
| 83 | + | |
| 84 | +} | |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,615 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels; | |
| 27 | + | |
| 28 | +import java.io.FileInputStream; | |
| 29 | +import java.io.FileOutputStream; | |
| 30 | +import java.io.InputStream; | |
| 31 | +import java.io.OutputStream; | |
| 32 | +import java.io.Reader; | |
| 33 | +import java.io.Writer; | |
| 34 | +import java.io.IOException; | |
| 35 | +import java.nio.ByteBuffer; | |
| 36 | +import java.nio.charset.Charset; | |
| 37 | +import java.nio.charset.CharsetDecoder; | |
| 38 | +import java.nio.charset.CharsetEncoder; | |
| 39 | +import java.nio.charset.UnsupportedCharsetException; | |
| 40 | +import java.nio.channels.spi.AbstractInterruptibleChannel; | |
| 41 | +import java.util.concurrent.ExecutionException; | |
| 42 | +import sun.nio.ch.ChannelInputStream; | |
| 43 | +import sun.nio.cs.StreamDecoder; | |
| 44 | +import sun.nio.cs.StreamEncoder; | |
| 45 | + | |
| 46 | + | |
| 47 | +/** | |
| 48 | + * Utility methods for channels and streams. | |
| 49 | + * | |
| 50 | + * <p> This class defines static methods that support the interoperation of the | |
| 51 | + * stream classes of the <tt>{@link java.io}</tt> package with the channel | |
| 52 | + * classes of this package. </p> | |
| 53 | + * | |
| 54 | + * | |
| 55 | + * @author Mark Reinhold | |
| 56 | + * @author Mike McCloskey | |
| 57 | + * @author JSR-51 Expert Group | |
| 58 | + * @since 1.4 | |
| 59 | + */ | |
| 60 | + | |
| 61 | +public final class Channels { | |
| 62 | + | |
| 63 | + private Channels() { } // No instantiation | |
| 64 | + | |
| 65 | + private static void checkNotNull(Object o, String name) { | |
| 66 | + if (o == null) | |
| 67 | + throw new NullPointerException("\"" + name + "\" is null!"); | |
| 68 | + } | |
| 69 | + | |
| 70 | + /** | |
| 71 | + * Write all remaining bytes in buffer to the given channel. | |
| 72 | + * If the channel is selectable then it must be configured blocking. | |
| 73 | + */ | |
| 74 | + private static void writeFullyImpl(WritableByteChannel ch, ByteBuffer bb) | |
| 75 | + throws IOException | |
| 76 | + { | |
| 77 | + while (bb.remaining() > 0) { | |
| 78 | + int n = ch.write(bb); | |
| 79 | + if (n <= 0) | |
| 80 | + throw new RuntimeException("no bytes written"); | |
| 81 | + } | |
| 82 | + } | |
| 83 | + | |
| 84 | + /** | |
| 85 | + * Write all remaining bytes in buffer to the given channel. | |
| 86 | + * | |
| 87 | + * @throws IllegalBlockingException | |
| 88 | + * If the channel is selectable and configured non-blocking. | |
| 89 | + */ | |
| 90 | + private static void writeFully(WritableByteChannel ch, ByteBuffer bb) | |
| 91 | + throws IOException | |
| 92 | + { | |
| 93 | + if (ch instanceof SelectableChannel) { | |
| 94 | + SelectableChannel sc = (SelectableChannel)ch; | |
| 95 | + synchronized (sc.blockingLock()) { | |
| 96 | + if (!sc.isBlocking()) | |
| 97 | + throw new IllegalBlockingModeException(); | |
| 98 | + writeFullyImpl(ch, bb); | |
| 99 | + } | |
| 100 | + } else { | |
| 101 | + writeFullyImpl(ch, bb); | |
| 102 | + } | |
| 103 | + } | |
| 104 | + | |
| 105 | + // -- Byte streams from channels -- | |
| 106 | + | |
| 107 | + /** | |
| 108 | + * Constructs a stream that reads bytes from the given channel. | |
| 109 | + * | |
| 110 | + * <p> The <tt>read</tt> methods of the resulting stream will throw an | |
| 111 | + * {@link IllegalBlockingModeException} if invoked while the underlying | |
| 112 | + * channel is in non-blocking mode. The stream will not be buffered, and | |
| 113 | + * it will not support the {@link InputStream#mark mark} or {@link | |
| 114 | + * InputStream#reset reset} methods. The stream will be safe for access by | |
| 115 | + * multiple concurrent threads. Closing the stream will in turn cause the | |
| 116 | + * channel to be closed. </p> | |
| 117 | + * | |
| 118 | + * @param ch | |
| 119 | + * The channel from which bytes will be read | |
| 120 | + * | |
| 121 | + * @return A new input stream | |
| 122 | + */ | |
| 123 | + public static InputStream newInputStream(ReadableByteChannel ch) { | |
| 124 | + checkNotNull(ch, "ch"); | |
| 125 | + return new sun.nio.ch.ChannelInputStream(ch); | |
| 126 | + } | |
| 127 | + | |
| 128 | + /** | |
| 129 | + * Constructs a stream that writes bytes to the given channel. | |
| 130 | + * | |
| 131 | + * <p> The <tt>write</tt> methods of the resulting stream will throw an | |
| 132 | + * {@link IllegalBlockingModeException} if invoked while the underlying | |
| 133 | + * channel is in non-blocking mode. The stream will not be buffered. The | |
| 134 | + * stream will be safe for access by multiple concurrent threads. Closing | |
| 135 | + * the stream will in turn cause the channel to be closed. </p> | |
| 136 | + * | |
| 137 | + * @param ch | |
| 138 | + * The channel to which bytes will be written | |
| 139 | + * | |
| 140 | + * @return A new output stream | |
| 141 | + */ | |
| 142 | + public static OutputStream newOutputStream(final WritableByteChannel ch) { | |
| 143 | + checkNotNull(ch, "ch"); | |
| 144 | + | |
| 145 | + return new OutputStream() { | |
| 146 | + | |
| 147 | + private ByteBuffer bb = null; | |
| 148 | + private byte[] bs = null; // Invoker's previous array | |
| 149 | + private byte[] b1 = null; | |
| 150 | + | |
| 151 | + public synchronized void write(int b) throws IOException { | |
| 152 | + if (b1 == null) | |
| 153 | + b1 = new byte[1]; | |
| 154 | + b1[0] = (byte)b; | |
| 155 | + this.write(b1); | |
| 156 | + } | |
| 157 | + | |
| 158 | + public synchronized void write(byte[] bs, int off, int len) | |
| 159 | + throws IOException | |
| 160 | + { | |
| 161 | + if ((off < 0) || (off > bs.length) || (len < 0) || | |
| 162 | + ((off + len) > bs.length) || ((off + len) < 0)) { | |
| 163 | + throw new IndexOutOfBoundsException(); | |
| 164 | + } else if (len == 0) { | |
| 165 | + return; | |
| 166 | + } | |
| 167 | + ByteBuffer bb = ((this.bs == bs) | |
| 168 | + ? this.bb | |
| 169 | + : ByteBuffer.wrap(bs)); | |
| 170 | + bb.limit(Math.min(off + len, bb.capacity())); | |
| 171 | + bb.position(off); | |
| 172 | + this.bb = bb; | |
| 173 | + this.bs = bs; | |
| 174 | + Channels.writeFully(ch, bb); | |
| 175 | + } | |
| 176 | + | |
| 177 | + public void close() throws IOException { | |
| 178 | + ch.close(); | |
| 179 | + } | |
| 180 | + | |
| 181 | + }; | |
| 182 | + } | |
| 183 | + | |
| 184 | + /** | |
| 185 | + * Constructs a stream that reads bytes from the given channel. | |
| 186 | + * | |
| 187 | + * <p> The stream will not be buffered, and it will not support the {@link | |
| 188 | + * InputStream#mark mark} or {@link InputStream#reset reset} methods. The | |
| 189 | + * stream will be safe for access by multiple concurrent threads. Closing | |
| 190 | + * the stream will in turn cause the channel to be closed. </p> | |
| 191 | + * | |
| 192 | + * @param ch | |
| 193 | + * The channel from which bytes will be read | |
| 194 | + * | |
| 195 | + * @return A new input stream | |
| 196 | + * | |
| 197 | + * @since 1.7 | |
| 198 | + */ | |
| 199 | + public static InputStream newInputStream(final AsynchronousByteChannel ch) { | |
| 200 | + checkNotNull(ch, "ch"); | |
| 201 | + return new InputStream() { | |
| 202 | + | |
| 203 | + private ByteBuffer bb = null; | |
| 204 | + private byte[] bs = null; // Invoker's previous array | |
| 205 | + private byte[] b1 = null; | |
| 206 | + | |
| 207 | + @Override | |
| 208 | + public synchronized int read() throws IOException { | |
| 209 | + if (b1 == null) | |
| 210 | + b1 = new byte[1]; | |
| 211 | + int n = this.read(b1); | |
| 212 | + if (n == 1) | |
| 213 | + return b1[0] & 0xff; | |
| 214 | + return -1; | |
| 215 | + } | |
| 216 | + | |
| 217 | + @Override | |
| 218 | + public synchronized int read(byte[] bs, int off, int len) | |
| 219 | + throws IOException | |
| 220 | + { | |
| 221 | + if ((off < 0) || (off > bs.length) || (len < 0) || | |
| 222 | + ((off + len) > bs.length) || ((off + len) < 0)) { | |
| 223 | + throw new IndexOutOfBoundsException(); | |
| 224 | + } else if (len == 0) | |
| 225 | + return 0; | |
| 226 | + | |
| 227 | + ByteBuffer bb = ((this.bs == bs) | |
| 228 | + ? this.bb | |
| 229 | + : ByteBuffer.wrap(bs)); | |
| 230 | + bb.position(off); | |
| 231 | + bb.limit(Math.min(off + len, bb.capacity())); | |
| 232 | + this.bb = bb; | |
| 233 | + this.bs = bs; | |
| 234 | + | |
| 235 | + boolean interrupted = false; | |
| 236 | + try { | |
| 237 | + for (;;) { | |
| 238 | + try { | |
| 239 | + return ch.read(bb).get(); | |
| 240 | + } catch (ExecutionException ee) { | |
| 241 | + throw new IOException(ee.getCause()); | |
| 242 | + } catch (InterruptedException ie) { | |
| 243 | + interrupted = true; | |
| 244 | + } | |
| 245 | + } | |
| 246 | + } finally { | |
| 247 | + if (interrupted) | |
| 248 | + Thread.currentThread().interrupt(); | |
| 249 | + } | |
| 250 | + } | |
| 251 | + | |
| 252 | + @Override | |
| 253 | + public void close() throws IOException { | |
| 254 | + ch.close(); | |
| 255 | + } | |
| 256 | + }; | |
| 257 | + } | |
| 258 | + | |
| 259 | + /** | |
| 260 | + * Constructs a stream that writes bytes to the given channel. | |
| 261 | + * | |
| 262 | + * <p> The stream will not be buffered. The stream will be safe for access | |
| 263 | + * by multiple concurrent threads. Closing the stream will in turn cause | |
| 264 | + * the channel to be closed. </p> | |
| 265 | + * | |
| 266 | + * @param ch | |
| 267 | + * The channel to which bytes will be written | |
| 268 | + * | |
| 269 | + * @return A new output stream | |
| 270 | + * | |
| 271 | + * @since 1.7 | |
| 272 | + */ | |
| 273 | + public static OutputStream newOutputStream(final AsynchronousByteChannel ch) { | |
| 274 | + checkNotNull(ch, "ch"); | |
| 275 | + return new OutputStream() { | |
| 276 | + | |
| 277 | + private ByteBuffer bb = null; | |
| 278 | + private byte[] bs = null; // Invoker's previous array | |
| 279 | + private byte[] b1 = null; | |
| 280 | + | |
| 281 | + @Override | |
| 282 | + public synchronized void write(int b) throws IOException { | |
| 283 | + if (b1 == null) | |
| 284 | + b1 = new byte[1]; | |
| 285 | + b1[0] = (byte)b; | |
| 286 | + this.write(b1); | |
| 287 | + } | |
| 288 | + | |
| 289 | + @Override | |
| 290 | + public synchronized void write(byte[] bs, int off, int len) | |
| 291 | + throws IOException | |
| 292 | + { | |
| 293 | + if ((off < 0) || (off > bs.length) || (len < 0) || | |
| 294 | + ((off + len) > bs.length) || ((off + len) < 0)) { | |
| 295 | + throw new IndexOutOfBoundsException(); | |
| 296 | + } else if (len == 0) { | |
| 297 | + return; | |
| 298 | + } | |
| 299 | + ByteBuffer bb = ((this.bs == bs) | |
| 300 | + ? this.bb | |
| 301 | + : ByteBuffer.wrap(bs)); | |
| 302 | + bb.limit(Math.min(off + len, bb.capacity())); | |
| 303 | + bb.position(off); | |
| 304 | + this.bb = bb; | |
| 305 | + this.bs = bs; | |
| 306 | + | |
| 307 | + boolean interrupted = false; | |
| 308 | + try { | |
| 309 | + while (bb.remaining() > 0) { | |
| 310 | + try { | |
| 311 | + ch.write(bb).get(); | |
| 312 | + } catch (ExecutionException ee) { | |
| 313 | + throw new IOException(ee.getCause()); | |
| 314 | + } catch (InterruptedException ie) { | |
| 315 | + interrupted = true; | |
| 316 | + } | |
| 317 | + } | |
| 318 | + } finally { | |
| 319 | + if (interrupted) | |
| 320 | + Thread.currentThread().interrupt(); | |
| 321 | + } | |
| 322 | + } | |
| 323 | + | |
| 324 | + @Override | |
| 325 | + public void close() throws IOException { | |
| 326 | + ch.close(); | |
| 327 | + } | |
| 328 | + }; | |
| 329 | + } | |
| 330 | + | |
| 331 | + | |
| 332 | + // -- Channels from streams -- | |
| 333 | + | |
| 334 | + /** | |
| 335 | + * Constructs a channel that reads bytes from the given stream. | |
| 336 | + * | |
| 337 | + * <p> The resulting channel will not be buffered; it will simply redirect | |
| 338 | + * its I/O operations to the given stream. Closing the channel will in | |
| 339 | + * turn cause the stream to be closed. </p> | |
| 340 | + * | |
| 341 | + * @param in | |
| 342 | + * The stream from which bytes are to be read | |
| 343 | + * | |
| 344 | + * @return A new readable byte channel | |
| 345 | + */ | |
| 346 | + public static ReadableByteChannel newChannel(final InputStream in) { | |
| 347 | + checkNotNull(in, "in"); | |
| 348 | + | |
| 349 | + if (in instanceof FileInputStream && | |
| 350 | + FileInputStream.class.equals(in.getClass())) { | |
| 351 | + return ((FileInputStream)in).getChannel(); | |
| 352 | + } | |
| 353 | + | |
| 354 | + return new ReadableByteChannelImpl(in); | |
| 355 | + } | |
| 356 | + | |
| 357 | + private static class ReadableByteChannelImpl | |
| 358 | + extends AbstractInterruptibleChannel // Not really interruptible | |
| 359 | + implements ReadableByteChannel | |
| 360 | + { | |
| 361 | + InputStream in; | |
| 362 | + private static final int TRANSFER_SIZE = 8192; | |
| 363 | + private byte buf[] = new byte[0]; | |
| 364 | + private boolean open = true; | |
| 365 | + private Object readLock = new Object(); | |
| 366 | + | |
| 367 | + ReadableByteChannelImpl(InputStream in) { | |
| 368 | + this.in = in; | |
| 369 | + } | |
| 370 | + | |
| 371 | + public int read(ByteBuffer dst) throws IOException { | |
| 372 | + int len = dst.remaining(); | |
| 373 | + int totalRead = 0; | |
| 374 | + int bytesRead = 0; | |
| 375 | + synchronized (readLock) { | |
| 376 | + while (totalRead < len) { | |
| 377 | + int bytesToRead = Math.min((len - totalRead), | |
| 378 | + TRANSFER_SIZE); | |
| 379 | + if (buf.length < bytesToRead) | |
| 380 | + buf = new byte[bytesToRead]; | |
| 381 | + if ((totalRead > 0) && !(in.available() > 0)) | |
| 382 | + break; // block at most once | |
| 383 | + try { | |
| 384 | + begin(); | |
| 385 | + bytesRead = in.read(buf, 0, bytesToRead); | |
| 386 | + } finally { | |
| 387 | + end(bytesRead > 0); | |
| 388 | + } | |
| 389 | + if (bytesRead < 0) | |
| 390 | + break; | |
| 391 | + else | |
| 392 | + totalRead += bytesRead; | |
| 393 | + dst.put(buf, 0, bytesRead); | |
| 394 | + } | |
| 395 | + if ((bytesRead < 0) && (totalRead == 0)) | |
| 396 | + return -1; | |
| 397 | + | |
| 398 | + return totalRead; | |
| 399 | + } | |
| 400 | + } | |
| 401 | + | |
| 402 | + protected void implCloseChannel() throws IOException { | |
| 403 | + in.close(); | |
| 404 | + open = false; | |
| 405 | + } | |
| 406 | + } | |
| 407 | + | |
| 408 | + | |
| 409 | + /** | |
| 410 | + * Constructs a channel that writes bytes to the given stream. | |
| 411 | + * | |
| 412 | + * <p> The resulting channel will not be buffered; it will simply redirect | |
| 413 | + * its I/O operations to the given stream. Closing the channel will in | |
| 414 | + * turn cause the stream to be closed. </p> | |
| 415 | + * | |
| 416 | + * @param out | |
| 417 | + * The stream to which bytes are to be written | |
| 418 | + * | |
| 419 | + * @return A new writable byte channel | |
| 420 | + */ | |
| 421 | + public static WritableByteChannel newChannel(final OutputStream out) { | |
| 422 | + checkNotNull(out, "out"); | |
| 423 | + | |
| 424 | + if (out instanceof FileOutputStream && | |
| 425 | + FileOutputStream.class.equals(out.getClass())) { | |
| 426 | + return ((FileOutputStream)out).getChannel(); | |
| 427 | + } | |
| 428 | + | |
| 429 | + return new WritableByteChannelImpl(out); | |
| 430 | + } | |
| 431 | + | |
| 432 | + private static class WritableByteChannelImpl | |
| 433 | + extends AbstractInterruptibleChannel // Not really interruptible | |
| 434 | + implements WritableByteChannel | |
| 435 | + { | |
| 436 | + OutputStream out; | |
| 437 | + private static final int TRANSFER_SIZE = 8192; | |
| 438 | + private byte buf[] = new byte[0]; | |
| 439 | + private boolean open = true; | |
| 440 | + private Object writeLock = new Object(); | |
| 441 | + | |
| 442 | + WritableByteChannelImpl(OutputStream out) { | |
| 443 | + this.out = out; | |
| 444 | + } | |
| 445 | + | |
| 446 | + public int write(ByteBuffer src) throws IOException { | |
| 447 | + int len = src.remaining(); | |
| 448 | + int totalWritten = 0; | |
| 449 | + synchronized (writeLock) { | |
| 450 | + while (totalWritten < len) { | |
| 451 | + int bytesToWrite = Math.min((len - totalWritten), | |
| 452 | + TRANSFER_SIZE); | |
| 453 | + if (buf.length < bytesToWrite) | |
| 454 | + buf = new byte[bytesToWrite]; | |
| 455 | + src.get(buf, 0, bytesToWrite); | |
| 456 | + try { | |
| 457 | + begin(); | |
| 458 | + out.write(buf, 0, bytesToWrite); | |
| 459 | + } finally { | |
| 460 | + end(bytesToWrite > 0); | |
| 461 | + } | |
| 462 | + totalWritten += bytesToWrite; | |
| 463 | + } | |
| 464 | + return totalWritten; | |
| 465 | + } | |
| 466 | + } | |
| 467 | + | |
| 468 | + protected void implCloseChannel() throws IOException { | |
| 469 | + out.close(); | |
| 470 | + open = false; | |
| 471 | + } | |
| 472 | + } | |
| 473 | + | |
| 474 | + | |
| 475 | + // -- Character streams from channels -- | |
| 476 | + | |
| 477 | + /** | |
| 478 | + * Constructs a reader that decodes bytes from the given channel using the | |
| 479 | + * given decoder. | |
| 480 | + * | |
| 481 | + * <p> The resulting stream will contain an internal input buffer of at | |
| 482 | + * least <tt>minBufferCap</tt> bytes. The stream's <tt>read</tt> methods | |
| 483 | + * will, as needed, fill the buffer by reading bytes from the underlying | |
| 484 | + * channel; if the channel is in non-blocking mode when bytes are to be | |
| 485 | + * read then an {@link IllegalBlockingModeException} will be thrown. The | |
| 486 | + * resulting stream will not otherwise be buffered, and it will not support | |
| 487 | + * the {@link Reader#mark mark} or {@link Reader#reset reset} methods. | |
| 488 | + * Closing the stream will in turn cause the channel to be closed. </p> | |
| 489 | + * | |
| 490 | + * @param ch | |
| 491 | + * The channel from which bytes will be read | |
| 492 | + * | |
| 493 | + * @param dec | |
| 494 | + * The charset decoder to be used | |
| 495 | + * | |
| 496 | + * @param minBufferCap | |
| 497 | + * The minimum capacity of the internal byte buffer, | |
| 498 | + * or <tt>-1</tt> if an implementation-dependent | |
| 499 | + * default capacity is to be used | |
| 500 | + * | |
| 501 | + * @return A new reader | |
| 502 | + */ | |
| 503 | + public static Reader newReader(ReadableByteChannel ch, | |
| 504 | + CharsetDecoder dec, | |
| 505 | + int minBufferCap) | |
| 506 | + { | |
| 507 | + checkNotNull(ch, "ch"); | |
| 508 | + return StreamDecoder.forDecoder(ch, dec.reset(), minBufferCap); | |
| 509 | + } | |
| 510 | + | |
| 511 | + /** | |
| 512 | + * Constructs a reader that decodes bytes from the given channel according | |
| 513 | + * to the named charset. | |
| 514 | + * | |
| 515 | + * <p> An invocation of this method of the form | |
| 516 | + * | |
| 517 | + * <blockquote><pre> | |
| 518 | + * Channels.newReader(ch, csname)</pre></blockquote> | |
| 519 | + * | |
| 520 | + * behaves in exactly the same way as the expression | |
| 521 | + * | |
| 522 | + * <blockquote><pre> | |
| 523 | + * Channels.newReader(ch, | |
| 524 | + * Charset.forName(csName) | |
| 525 | + * .newDecoder(), | |
| 526 | + * -1);</pre></blockquote> | |
| 527 | + * | |
| 528 | + * @param ch | |
| 529 | + * The channel from which bytes will be read | |
| 530 | + * | |
| 531 | + * @param csName | |
| 532 | + * The name of the charset to be used | |
| 533 | + * | |
| 534 | + * @return A new reader | |
| 535 | + * | |
| 536 | + * @throws UnsupportedCharsetException | |
| 537 | + * If no support for the named charset is available | |
| 538 | + * in this instance of the Java virtual machine | |
| 539 | + */ | |
| 540 | + public static Reader newReader(ReadableByteChannel ch, | |
| 541 | + String csName) | |
| 542 | + { | |
| 543 | + checkNotNull(csName, "csName"); | |
| 544 | + return newReader(ch, Charset.forName(csName).newDecoder(), -1); | |
| 545 | + } | |
| 546 | + | |
| 547 | + /** | |
| 548 | + * Constructs a writer that encodes characters using the given encoder and | |
| 549 | + * writes the resulting bytes to the given channel. | |
| 550 | + * | |
| 551 | + * <p> The resulting stream will contain an internal output buffer of at | |
| 552 | + * least <tt>minBufferCap</tt> bytes. The stream's <tt>write</tt> methods | |
| 553 | + * will, as needed, flush the buffer by writing bytes to the underlying | |
| 554 | + * channel; if the channel is in non-blocking mode when bytes are to be | |
| 555 | + * written then an {@link IllegalBlockingModeException} will be thrown. | |
| 556 | + * The resulting stream will not otherwise be buffered. Closing the stream | |
| 557 | + * will in turn cause the channel to be closed. </p> | |
| 558 | + * | |
| 559 | + * @param ch | |
| 560 | + * The channel to which bytes will be written | |
| 561 | + * | |
| 562 | + * @param enc | |
| 563 | + * The charset encoder to be used | |
| 564 | + * | |
| 565 | + * @param minBufferCap | |
| 566 | + * The minimum capacity of the internal byte buffer, | |
| 567 | + * or <tt>-1</tt> if an implementation-dependent | |
| 568 | + * default capacity is to be used | |
| 569 | + * | |
| 570 | + * @return A new writer | |
| 571 | + */ | |
| 572 | + public static Writer newWriter(final WritableByteChannel ch, | |
| 573 | + final CharsetEncoder enc, | |
| 574 | + final int minBufferCap) | |
| 575 | + { | |
| 576 | + checkNotNull(ch, "ch"); | |
| 577 | + return StreamEncoder.forEncoder(ch, enc.reset(), minBufferCap); | |
| 578 | + } | |
| 579 | + | |
| 580 | + /** | |
| 581 | + * Constructs a writer that encodes characters according to the named | |
| 582 | + * charset and writes the resulting bytes to the given channel. | |
| 583 | + * | |
| 584 | + * <p> An invocation of this method of the form | |
| 585 | + * | |
| 586 | + * <blockquote><pre> | |
| 587 | + * Channels.newWriter(ch, csname)</pre></blockquote> | |
| 588 | + * | |
| 589 | + * behaves in exactly the same way as the expression | |
| 590 | + * | |
| 591 | + * <blockquote><pre> | |
| 592 | + * Channels.newWriter(ch, | |
| 593 | + * Charset.forName(csName) | |
| 594 | + * .newEncoder(), | |
| 595 | + * -1);</pre></blockquote> | |
| 596 | + * | |
| 597 | + * @param ch | |
| 598 | + * The channel to which bytes will be written | |
| 599 | + * | |
| 600 | + * @param csName | |
| 601 | + * The name of the charset to be used | |
| 602 | + * | |
| 603 | + * @return A new writer | |
| 604 | + * | |
| 605 | + * @throws UnsupportedCharsetException | |
| 606 | + * If no support for the named charset is available | |
| 607 | + * in this instance of the Java virtual machine | |
| 608 | + */ | |
| 609 | + public static Writer newWriter(WritableByteChannel ch, | |
| 610 | + String csName) | |
| 611 | + { | |
| 612 | + checkNotNull(csName, "csName"); | |
| 613 | + return newWriter(ch, Charset.forName(csName).newEncoder(), -1); | |
| 614 | + } | |
| 615 | +} | |
Binary file not shown.
| @@ -0,0 +1,66 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * A handler for consuming the result of an asynchronous I/O operation. | |
| 30 | + * | |
| 31 | + * <p> The asynchronous channels defined in this package allow a completion | |
| 32 | + * handler to be specified to consume the result of an asynchronous operation. | |
| 33 | + * The {@link #completed completed} method is invoked when the I/O operation | |
| 34 | + * completes successfully. The {@link #failed failed} method is invoked if the | |
| 35 | + * I/O operations fails. The implementations of these methods should complete | |
| 36 | + * in a timely manner so as to avoid keeping the invoking thread from dispatching | |
| 37 | + * to other completion handlers. | |
| 38 | + * | |
| 39 | + * @param <V> The result type of the I/O operation | |
| 40 | + * @param <A> The type of the object attached to the I/O operation | |
| 41 | + * | |
| 42 | + * @since 1.7 | |
| 43 | + */ | |
| 44 | + | |
| 45 | +public interface CompletionHandler<V,A> { | |
| 46 | + | |
| 47 | + /** | |
| 48 | + * Invoked when an operation has completed. | |
| 49 | + * | |
| 50 | + * @param result | |
| 51 | + * The result of the I/O operation. | |
| 52 | + * @param attachment | |
| 53 | + * The object attached to the I/O operation when it was initiated. | |
| 54 | + */ | |
| 55 | + void completed(V result, A attachment); | |
| 56 | + | |
| 57 | + /** | |
| 58 | + * Invoked when an operation fails. | |
| 59 | + * | |
| 60 | + * @param exc | |
| 61 | + * The exception to indicate why the I/O operation failed | |
| 62 | + * @param attachment | |
| 63 | + * The object attached to the I/O operation when it was initiated. | |
| 64 | + */ | |
| 65 | + void failed(Throwable exc, A attachment); | |
| 66 | +} | |
Binary file not shown.
| @@ -0,0 +1,568 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels; | |
| 27 | + | |
| 28 | +import java.io.IOException; | |
| 29 | +import java.net.ProtocolFamily; | |
| 30 | +import java.net.DatagramSocket; | |
| 31 | +import java.net.SocketOption; | |
| 32 | +import java.net.SocketAddress; | |
| 33 | +import java.nio.ByteBuffer; | |
| 34 | +import java.nio.channels.spi.AbstractSelectableChannel; | |
| 35 | +import java.nio.channels.spi.SelectorProvider; | |
| 36 | + | |
| 37 | +/** | |
| 38 | + * A selectable channel for datagram-oriented sockets. | |
| 39 | + * | |
| 40 | + * <p> A datagram channel is created by invoking one of the {@link #open open} methods | |
| 41 | + * of this class. It is not possible to create a channel for an arbitrary, | |
| 42 | + * pre-existing datagram socket. A newly-created datagram channel is open but not | |
| 43 | + * connected. A datagram channel need not be connected in order for the {@link #send | |
| 44 | + * send} and {@link #receive receive} methods to be used. A datagram channel may be | |
| 45 | + * connected, by invoking its {@link #connect connect} method, in order to | |
| 46 | + * avoid the overhead of the security checks are otherwise performed as part of | |
| 47 | + * every send and receive operation. A datagram channel must be connected in | |
| 48 | + * order to use the {@link #read(java.nio.ByteBuffer) read} and {@link | |
| 49 | + * #write(java.nio.ByteBuffer) write} methods, since those methods do not | |
| 50 | + * accept or return socket addresses. | |
| 51 | + * | |
| 52 | + * <p> Once connected, a datagram channel remains connected until it is | |
| 53 | + * disconnected or closed. Whether or not a datagram channel is connected may | |
| 54 | + * be determined by invoking its {@link #isConnected isConnected} method. | |
| 55 | + * | |
| 56 | + * <p> Socket options are configured using the {@link #setOption(SocketOption,Object) | |
| 57 | + * setOption} method. A datagram channel to an Internet Protocol socket supports | |
| 58 | + * the following options: | |
| 59 | + * <blockquote> | |
| 60 | + * <table border> | |
| 61 | + * <tr> | |
| 62 | + * <th>Option Name</th> | |
| 63 | + * <th>Description</th> | |
| 64 | + * </tr> | |
| 65 | + * <tr> | |
| 66 | + * <td> {@link java.net.StandardSocketOptions#SO_SNDBUF SO_SNDBUF} </td> | |
| 67 | + * <td> The size of the socket send buffer </td> | |
| 68 | + * </tr> | |
| 69 | + * <tr> | |
| 70 | + * <td> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </td> | |
| 71 | + * <td> The size of the socket receive buffer </td> | |
| 72 | + * </tr> | |
| 73 | + * <tr> | |
| 74 | + * <td> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </td> | |
| 75 | + * <td> Re-use address </td> | |
| 76 | + * </tr> | |
| 77 | + * <tr> | |
| 78 | + * <td> {@link java.net.StandardSocketOptions#SO_BROADCAST SO_BROADCAST} </td> | |
| 79 | + * <td> Allow transmission of broadcast datagrams </td> | |
| 80 | + * </tr> | |
| 81 | + * <tr> | |
| 82 | + * <td> {@link java.net.StandardSocketOptions#IP_TOS IP_TOS} </td> | |
| 83 | + * <td> The Type of Service (ToS) octet in the Internet Protocol (IP) header </td> | |
| 84 | + * </tr> | |
| 85 | + * <tr> | |
| 86 | + * <td> {@link java.net.StandardSocketOptions#IP_MULTICAST_IF IP_MULTICAST_IF} </td> | |
| 87 | + * <td> The network interface for Internet Protocol (IP) multicast datagrams </td> | |
| 88 | + * </tr> | |
| 89 | + * <tr> | |
| 90 | + * <td> {@link java.net.StandardSocketOptions#IP_MULTICAST_TTL | |
| 91 | + * IP_MULTICAST_TTL} </td> | |
| 92 | + * <td> The <em>time-to-live</em> for Internet Protocol (IP) multicast | |
| 93 | + * datagrams </td> | |
| 94 | + * </tr> | |
| 95 | + * <tr> | |
| 96 | + * <td> {@link java.net.StandardSocketOptions#IP_MULTICAST_LOOP | |
| 97 | + * IP_MULTICAST_LOOP} </td> | |
| 98 | + * <td> Loopback for Internet Protocol (IP) multicast datagrams </td> | |
| 99 | + * </tr> | |
| 100 | + * </table> | |
| 101 | + * </blockquote> | |
| 102 | + * Additional (implementation specific) options may also be supported. | |
| 103 | + * | |
| 104 | + * <p> Datagram channels are safe for use by multiple concurrent threads. They | |
| 105 | + * support concurrent reading and writing, though at most one thread may be | |
| 106 | + * reading and at most one thread may be writing at any given time. </p> | |
| 107 | + * | |
| 108 | + * @author Mark Reinhold | |
| 109 | + * @author JSR-51 Expert Group | |
| 110 | + * @since 1.4 | |
| 111 | + */ | |
| 112 | + | |
| 113 | +public abstract class DatagramChannel | |
| 114 | + extends AbstractSelectableChannel | |
| 115 | + implements ByteChannel, ScatteringByteChannel, GatheringByteChannel, MulticastChannel | |
| 116 | +{ | |
| 117 | + | |
| 118 | + /** | |
| 119 | + * Initializes a new instance of this class. | |
| 120 | + */ | |
| 121 | + protected DatagramChannel(SelectorProvider provider) { | |
| 122 | + super(provider); | |
| 123 | + } | |
| 124 | + | |
| 125 | + /** | |
| 126 | + * Opens a datagram channel. | |
| 127 | + * | |
| 128 | + * <p> The new channel is created by invoking the {@link | |
| 129 | + * java.nio.channels.spi.SelectorProvider#openDatagramChannel() | |
| 130 | + * openDatagramChannel} method of the system-wide default {@link | |
| 131 | + * java.nio.channels.spi.SelectorProvider} object. The channel will not be | |
| 132 | + * connected. | |
| 133 | + * | |
| 134 | + * <p> The {@link ProtocolFamily ProtocolFamily} of the channel's socket | |
| 135 | + * is platform (and possibly configuration) dependent and therefore unspecified. | |
| 136 | + * The {@link #open(ProtocolFamily) open} allows the protocol family to be | |
| 137 | + * selected when opening a datagram channel, and should be used to open | |
| 138 | + * datagram channels that are intended for Internet Protocol multicasting. | |
| 139 | + * | |
| 140 | + * @return A new datagram channel | |
| 141 | + * | |
| 142 | + * @throws IOException | |
| 143 | + * If an I/O error occurs | |
| 144 | + */ | |
| 145 | + public static DatagramChannel open() throws IOException { | |
| 146 | + return SelectorProvider.provider().openDatagramChannel(); | |
| 147 | + } | |
| 148 | + | |
| 149 | + /** | |
| 150 | + * Opens a datagram channel. | |
| 151 | + * | |
| 152 | + * <p> The {@code family} parameter is used to specify the {@link | |
| 153 | + * ProtocolFamily}. If the datagram channel is to be used for IP multicasing | |
| 154 | + * then this should correspond to the address type of the multicast groups | |
| 155 | + * that this channel will join. | |
| 156 | + * | |
| 157 | + * <p> The new channel is created by invoking the {@link | |
| 158 | + * java.nio.channels.spi.SelectorProvider#openDatagramChannel(ProtocolFamily) | |
| 159 | + * openDatagramChannel} method of the system-wide default {@link | |
| 160 | + * java.nio.channels.spi.SelectorProvider} object. The channel will not be | |
| 161 | + * connected. | |
| 162 | + * | |
| 163 | + * @param family | |
| 164 | + * The protocol family | |
| 165 | + * | |
| 166 | + * @return A new datagram channel | |
| 167 | + * | |
| 168 | + * @throws UnsupportedOperationException | |
| 169 | + * If the specified protocol family is not supported. For example, | |
| 170 | + * suppose the parameter is specified as {@link | |
| 171 | + * java.net.StandardProtocolFamily#INET6 StandardProtocolFamily.INET6} | |
| 172 | + * but IPv6 is not enabled on the platform. | |
| 173 | + * @throws IOException | |
| 174 | + * If an I/O error occurs | |
| 175 | + * | |
| 176 | + * @since 1.7 | |
| 177 | + */ | |
| 178 | + public static DatagramChannel open(ProtocolFamily family) throws IOException { | |
| 179 | + return SelectorProvider.provider().openDatagramChannel(family); | |
| 180 | + } | |
| 181 | + | |
| 182 | + /** | |
| 183 | + * Returns an operation set identifying this channel's supported | |
| 184 | + * operations. | |
| 185 | + * | |
| 186 | + * <p> Datagram channels support reading and writing, so this method | |
| 187 | + * returns <tt>(</tt>{@link SelectionKey#OP_READ} <tt>|</tt> {@link | |
| 188 | + * SelectionKey#OP_WRITE}<tt>)</tt>. </p> | |
| 189 | + * | |
| 190 | + * @return The valid-operation set | |
| 191 | + */ | |
| 192 | + public final int validOps() { | |
| 193 | + return (SelectionKey.OP_READ | |
| 194 | + | SelectionKey.OP_WRITE); | |
| 195 | + } | |
| 196 | + | |
| 197 | + | |
| 198 | + // -- Socket-specific operations -- | |
| 199 | + | |
| 200 | + /** | |
| 201 | + * @throws AlreadyBoundException {@inheritDoc} | |
| 202 | + * @throws UnsupportedAddressTypeException {@inheritDoc} | |
| 203 | + * @throws ClosedChannelException {@inheritDoc} | |
| 204 | + * @throws IOException {@inheritDoc} | |
| 205 | + * @throws SecurityException | |
| 206 | + * If a security manager has been installed and its {@link | |
| 207 | + * SecurityManager#checkListen checkListen} method denies the | |
| 208 | + * operation | |
| 209 | + * | |
| 210 | + * @since 1.7 | |
| 211 | + */ | |
| 212 | + public abstract DatagramChannel bind(SocketAddress local) | |
| 213 | + throws IOException; | |
| 214 | + | |
| 215 | + /** | |
| 216 | + * @throws UnsupportedOperationException {@inheritDoc} | |
| 217 | + * @throws IllegalArgumentException {@inheritDoc} | |
| 218 | + * @throws ClosedChannelException {@inheritDoc} | |
| 219 | + * @throws IOException {@inheritDoc} | |
| 220 | + * | |
| 221 | + * @since 1.7 | |
| 222 | + */ | |
| 223 | + public abstract <T> DatagramChannel setOption(SocketOption<T> name, T value) | |
| 224 | + throws IOException; | |
| 225 | + | |
| 226 | + /** | |
| 227 | + * Retrieves a datagram socket associated with this channel. | |
| 228 | + * | |
| 229 | + * <p> The returned object will not declare any public methods that are not | |
| 230 | + * declared in the {@link java.net.DatagramSocket} class. </p> | |
| 231 | + * | |
| 232 | + * @return A datagram socket associated with this channel | |
| 233 | + */ | |
| 234 | + public abstract DatagramSocket socket(); | |
| 235 | + | |
| 236 | + /** | |
| 237 | + * Tells whether or not this channel's socket is connected. | |
| 238 | + * | |
| 239 | + * @return {@code true} if, and only if, this channel's socket | |
| 240 | + * is {@link #isOpen open} and connected | |
| 241 | + */ | |
| 242 | + public abstract boolean isConnected(); | |
| 243 | + | |
| 244 | + /** | |
| 245 | + * Connects this channel's socket. | |
| 246 | + * | |
| 247 | + * <p> The channel's socket is configured so that it only receives | |
| 248 | + * datagrams from, and sends datagrams to, the given remote <i>peer</i> | |
| 249 | + * address. Once connected, datagrams may not be received from or sent to | |
| 250 | + * any other address. A datagram socket remains connected until it is | |
| 251 | + * explicitly disconnected or until it is closed. | |
| 252 | + * | |
| 253 | + * <p> This method performs exactly the same security checks as the {@link | |
| 254 | + * java.net.DatagramSocket#connect connect} method of the {@link | |
| 255 | + * java.net.DatagramSocket} class. That is, if a security manager has been | |
| 256 | + * installed then this method verifies that its {@link | |
| 257 | + * java.lang.SecurityManager#checkAccept checkAccept} and {@link | |
| 258 | + * java.lang.SecurityManager#checkConnect checkConnect} methods permit | |
| 259 | + * datagrams to be received from and sent to, respectively, the given | |
| 260 | + * remote address. | |
| 261 | + * | |
| 262 | + * <p> This method may be invoked at any time. It will not have any effect | |
| 263 | + * on read or write operations that are already in progress at the moment | |
| 264 | + * that it is invoked. If this channel's socket is not bound then this method | |
| 265 | + * will first cause the socket to be bound to an address that is assigned | |
| 266 | + * automatically, as if invoking the {@link #bind bind} method with a | |
| 267 | + * parameter of {@code null}. </p> | |
| 268 | + * | |
| 269 | + * @param remote | |
| 270 | + * The remote address to which this channel is to be connected | |
| 271 | + * | |
| 272 | + * @return This datagram channel | |
| 273 | + * | |
| 274 | + * @throws ClosedChannelException | |
| 275 | + * If this channel is closed | |
| 276 | + * | |
| 277 | + * @throws AsynchronousCloseException | |
| 278 | + * If another thread closes this channel | |
| 279 | + * while the connect operation is in progress | |
| 280 | + * | |
| 281 | + * @throws ClosedByInterruptException | |
| 282 | + * If another thread interrupts the current thread | |
| 283 | + * while the connect operation is in progress, thereby | |
| 284 | + * closing the channel and setting the current thread's | |
| 285 | + * interrupt status | |
| 286 | + * | |
| 287 | + * @throws SecurityException | |
| 288 | + * If a security manager has been installed | |
| 289 | + * and it does not permit access to the given remote address | |
| 290 | + * | |
| 291 | + * @throws IOException | |
| 292 | + * If some other I/O error occurs | |
| 293 | + */ | |
| 294 | + public abstract DatagramChannel connect(SocketAddress remote) | |
| 295 | + throws IOException; | |
| 296 | + | |
| 297 | + /** | |
| 298 | + * Disconnects this channel's socket. | |
| 299 | + * | |
| 300 | + * <p> The channel's socket is configured so that it can receive datagrams | |
| 301 | + * from, and sends datagrams to, any remote address so long as the security | |
| 302 | + * manager, if installed, permits it. | |
| 303 | + * | |
| 304 | + * <p> This method may be invoked at any time. It will not have any effect | |
| 305 | + * on read or write operations that are already in progress at the moment | |
| 306 | + * that it is invoked. | |
| 307 | + * | |
| 308 | + * <p> If this channel's socket is not connected, or if the channel is | |
| 309 | + * closed, then invoking this method has no effect. </p> | |
| 310 | + * | |
| 311 | + * @return This datagram channel | |
| 312 | + * | |
| 313 | + * @throws IOException | |
| 314 | + * If some other I/O error occurs | |
| 315 | + */ | |
| 316 | + public abstract DatagramChannel disconnect() throws IOException; | |
| 317 | + | |
| 318 | + /** | |
| 319 | + * Returns the remote address to which this channel's socket is connected. | |
| 320 | + * | |
| 321 | + * @return The remote address; {@code null} if the channel's socket is not | |
| 322 | + * connected | |
| 323 | + * | |
| 324 | + * @throws ClosedChannelException | |
| 325 | + * If the channel is closed | |
| 326 | + * @throws IOException | |
| 327 | + * If an I/O error occurs | |
| 328 | + * | |
| 329 | + * @since 1.7 | |
| 330 | + */ | |
| 331 | + public abstract SocketAddress getRemoteAddress() throws IOException; | |
| 332 | + | |
| 333 | + /** | |
| 334 | + * Receives a datagram via this channel. | |
| 335 | + * | |
| 336 | + * <p> If a datagram is immediately available, or if this channel is in | |
| 337 | + * blocking mode and one eventually becomes available, then the datagram is | |
| 338 | + * copied into the given byte buffer and its source address is returned. | |
| 339 | + * If this channel is in non-blocking mode and a datagram is not | |
| 340 | + * immediately available then this method immediately returns | |
| 341 | + * <tt>null</tt>. | |
| 342 | + * | |
| 343 | + * <p> The datagram is transferred into the given byte buffer starting at | |
| 344 | + * its current position, as if by a regular {@link | |
| 345 | + * ReadableByteChannel#read(java.nio.ByteBuffer) read} operation. If there | |
| 346 | + * are fewer bytes remaining in the buffer than are required to hold the | |
| 347 | + * datagram then the remainder of the datagram is silently discarded. | |
| 348 | + * | |
| 349 | + * <p> This method performs exactly the same security checks as the {@link | |
| 350 | + * java.net.DatagramSocket#receive receive} method of the {@link | |
| 351 | + * java.net.DatagramSocket} class. That is, if the socket is not connected | |
| 352 | + * to a specific remote address and a security manager has been installed | |
| 353 | + * then for each datagram received this method verifies that the source's | |
| 354 | + * address and port number are permitted by the security manager's {@link | |
| 355 | + * java.lang.SecurityManager#checkAccept checkAccept} method. The overhead | |
| 356 | + * of this security check can be avoided by first connecting the socket via | |
| 357 | + * the {@link #connect connect} method. | |
| 358 | + * | |
| 359 | + * <p> This method may be invoked at any time. If another thread has | |
| 360 | + * already initiated a read operation upon this channel, however, then an | |
| 361 | + * invocation of this method will block until the first operation is | |
| 362 | + * complete. If this channel's socket is not bound then this method will | |
| 363 | + * first cause the socket to be bound to an address that is assigned | |
| 364 | + * automatically, as if invoking the {@link #bind bind} method with a | |
| 365 | + * parameter of {@code null}. </p> | |
| 366 | + * | |
| 367 | + * @param dst | |
| 368 | + * The buffer into which the datagram is to be transferred | |
| 369 | + * | |
| 370 | + * @return The datagram's source address, | |
| 371 | + * or <tt>null</tt> if this channel is in non-blocking mode | |
| 372 | + * and no datagram was immediately available | |
| 373 | + * | |
| 374 | + * @throws ClosedChannelException | |
| 375 | + * If this channel is closed | |
| 376 | + * | |
| 377 | + * @throws AsynchronousCloseException | |
| 378 | + * If another thread closes this channel | |
| 379 | + * while the read operation is in progress | |
| 380 | + * | |
| 381 | + * @throws ClosedByInterruptException | |
| 382 | + * If another thread interrupts the current thread | |
| 383 | + * while the read operation is in progress, thereby | |
| 384 | + * closing the channel and setting the current thread's | |
| 385 | + * interrupt status | |
| 386 | + * | |
| 387 | + * @throws SecurityException | |
| 388 | + * If a security manager has been installed | |
| 389 | + * and it does not permit datagrams to be accepted | |
| 390 | + * from the datagram's sender | |
| 391 | + * | |
| 392 | + * @throws IOException | |
| 393 | + * If some other I/O error occurs | |
| 394 | + */ | |
| 395 | + public abstract SocketAddress receive(ByteBuffer dst) throws IOException; | |
| 396 | + | |
| 397 | + /** | |
| 398 | + * Sends a datagram via this channel. | |
| 399 | + * | |
| 400 | + * <p> If this channel is in non-blocking mode and there is sufficient room | |
| 401 | + * in the underlying output buffer, or if this channel is in blocking mode | |
| 402 | + * and sufficient room becomes available, then the remaining bytes in the | |
| 403 | + * given buffer are transmitted as a single datagram to the given target | |
| 404 | + * address. | |
| 405 | + * | |
| 406 | + * <p> The datagram is transferred from the byte buffer as if by a regular | |
| 407 | + * {@link WritableByteChannel#write(java.nio.ByteBuffer) write} operation. | |
| 408 | + * | |
| 409 | + * <p> This method performs exactly the same security checks as the {@link | |
| 410 | + * java.net.DatagramSocket#send send} method of the {@link | |
| 411 | + * java.net.DatagramSocket} class. That is, if the socket is not connected | |
| 412 | + * to a specific remote address and a security manager has been installed | |
| 413 | + * then for each datagram sent this method verifies that the target address | |
| 414 | + * and port number are permitted by the security manager's {@link | |
| 415 | + * java.lang.SecurityManager#checkConnect checkConnect} method. The | |
| 416 | + * overhead of this security check can be avoided by first connecting the | |
| 417 | + * socket via the {@link #connect connect} method. | |
| 418 | + * | |
| 419 | + * <p> This method may be invoked at any time. If another thread has | |
| 420 | + * already initiated a write operation upon this channel, however, then an | |
| 421 | + * invocation of this method will block until the first operation is | |
| 422 | + * complete. If this channel's socket is not bound then this method will | |
| 423 | + * first cause the socket to be bound to an address that is assigned | |
| 424 | + * automatically, as if by invoking the {@link #bind bind} method with a | |
| 425 | + * parameter of {@code null}. </p> | |
| 426 | + * | |
| 427 | + * @param src | |
| 428 | + * The buffer containing the datagram to be sent | |
| 429 | + * | |
| 430 | + * @param target | |
| 431 | + * The address to which the datagram is to be sent | |
| 432 | + * | |
| 433 | + * @return The number of bytes sent, which will be either the number | |
| 434 | + * of bytes that were remaining in the source buffer when this | |
| 435 | + * method was invoked or, if this channel is non-blocking, may be | |
| 436 | + * zero if there was insufficient room for the datagram in the | |
| 437 | + * underlying output buffer | |
| 438 | + * | |
| 439 | + * @throws ClosedChannelException | |
| 440 | + * If this channel is closed | |
| 441 | + * | |
| 442 | + * @throws AsynchronousCloseException | |
| 443 | + * If another thread closes this channel | |
| 444 | + * while the read operation is in progress | |
| 445 | + * | |
| 446 | + * @throws ClosedByInterruptException | |
| 447 | + * If another thread interrupts the current thread | |
| 448 | + * while the read operation is in progress, thereby | |
| 449 | + * closing the channel and setting the current thread's | |
| 450 | + * interrupt status | |
| 451 | + * | |
| 452 | + * @throws SecurityException | |
| 453 | + * If a security manager has been installed | |
| 454 | + * and it does not permit datagrams to be sent | |
| 455 | + * to the given address | |
| 456 | + * | |
| 457 | + * @throws IOException | |
| 458 | + * If some other I/O error occurs | |
| 459 | + */ | |
| 460 | + public abstract int send(ByteBuffer src, SocketAddress target) | |
| 461 | + throws IOException; | |
| 462 | + | |
| 463 | + | |
| 464 | + // -- ByteChannel operations -- | |
| 465 | + | |
| 466 | + /** | |
| 467 | + * Reads a datagram from this channel. | |
| 468 | + * | |
| 469 | + * <p> This method may only be invoked if this channel's socket is | |
| 470 | + * connected, and it only accepts datagrams from the socket's peer. If | |
| 471 | + * there are more bytes in the datagram than remain in the given buffer | |
| 472 | + * then the remainder of the datagram is silently discarded. Otherwise | |
| 473 | + * this method behaves exactly as specified in the {@link | |
| 474 | + * ReadableByteChannel} interface. </p> | |
| 475 | + * | |
| 476 | + * @throws NotYetConnectedException | |
| 477 | + * If this channel's socket is not connected | |
| 478 | + */ | |
| 479 | + public abstract int read(ByteBuffer dst) throws IOException; | |
| 480 | + | |
| 481 | + /** | |
| 482 | + * Reads a datagram from this channel. | |
| 483 | + * | |
| 484 | + * <p> This method may only be invoked if this channel's socket is | |
| 485 | + * connected, and it only accepts datagrams from the socket's peer. If | |
| 486 | + * there are more bytes in the datagram than remain in the given buffers | |
| 487 | + * then the remainder of the datagram is silently discarded. Otherwise | |
| 488 | + * this method behaves exactly as specified in the {@link | |
| 489 | + * ScatteringByteChannel} interface. </p> | |
| 490 | + * | |
| 491 | + * @throws NotYetConnectedException | |
| 492 | + * If this channel's socket is not connected | |
| 493 | + */ | |
| 494 | + public abstract long read(ByteBuffer[] dsts, int offset, int length) | |
| 495 | + throws IOException; | |
| 496 | + | |
| 497 | + /** | |
| 498 | + * Reads a datagram from this channel. | |
| 499 | + * | |
| 500 | + * <p> This method may only be invoked if this channel's socket is | |
| 501 | + * connected, and it only accepts datagrams from the socket's peer. If | |
| 502 | + * there are more bytes in the datagram than remain in the given buffers | |
| 503 | + * then the remainder of the datagram is silently discarded. Otherwise | |
| 504 | + * this method behaves exactly as specified in the {@link | |
| 505 | + * ScatteringByteChannel} interface. </p> | |
| 506 | + * | |
| 507 | + * @throws NotYetConnectedException | |
| 508 | + * If this channel's socket is not connected | |
| 509 | + */ | |
| 510 | + public final long read(ByteBuffer[] dsts) throws IOException { | |
| 511 | + return read(dsts, 0, dsts.length); | |
| 512 | + } | |
| 513 | + | |
| 514 | + /** | |
| 515 | + * Writes a datagram to this channel. | |
| 516 | + * | |
| 517 | + * <p> This method may only be invoked if this channel's socket is | |
| 518 | + * connected, in which case it sends datagrams directly to the socket's | |
| 519 | + * peer. Otherwise it behaves exactly as specified in the {@link | |
| 520 | + * WritableByteChannel} interface. </p> | |
| 521 | + * | |
| 522 | + * @throws NotYetConnectedException | |
| 523 | + * If this channel's socket is not connected | |
| 524 | + */ | |
| 525 | + public abstract int write(ByteBuffer src) throws IOException; | |
| 526 | + | |
| 527 | + /** | |
| 528 | + * Writes a datagram to this channel. | |
| 529 | + * | |
| 530 | + * <p> This method may only be invoked if this channel's socket is | |
| 531 | + * connected, in which case it sends datagrams directly to the socket's | |
| 532 | + * peer. Otherwise it behaves exactly as specified in the {@link | |
| 533 | + * GatheringByteChannel} interface. </p> | |
| 534 | + * | |
| 535 | + * @return The number of bytes sent, which will be either the number | |
| 536 | + * of bytes that were remaining in the source buffer when this | |
| 537 | + * method was invoked or, if this channel is non-blocking, may be | |
| 538 | + * zero if there was insufficient room for the datagram in the | |
| 539 | + * underlying output buffer | |
| 540 | + * | |
| 541 | + * @throws NotYetConnectedException | |
| 542 | + * If this channel's socket is not connected | |
| 543 | + */ | |
| 544 | + public abstract long write(ByteBuffer[] srcs, int offset, int length) | |
| 545 | + throws IOException; | |
| 546 | + | |
| 547 | + /** | |
| 548 | + * Writes a datagram to this channel. | |
| 549 | + * | |
| 550 | + * <p> This method may only be invoked if this channel's socket is | |
| 551 | + * connected, in which case it sends datagrams directly to the socket's | |
| 552 | + * peer. Otherwise it behaves exactly as specified in the {@link | |
| 553 | + * GatheringByteChannel} interface. </p> | |
| 554 | + * | |
| 555 | + * @return The number of bytes sent, which will be either the number | |
| 556 | + * of bytes that were remaining in the source buffer when this | |
| 557 | + * method was invoked or, if this channel is non-blocking, may be | |
| 558 | + * zero if there was insufficient room for the datagram in the | |
| 559 | + * underlying output buffer | |
| 560 | + * | |
| 561 | + * @throws NotYetConnectedException | |
| 562 | + * If this channel's socket is not connected | |
| 563 | + */ | |
| 564 | + public final long write(ByteBuffer[] srcs) throws IOException { | |
| 565 | + return write(srcs, 0, srcs.length); | |
| 566 | + } | |
| 567 | + | |
| 568 | +} | |
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,1157 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels; | |
| 27 | + | |
| 28 | +import java.io.*; | |
| 29 | +import java.nio.ByteBuffer; | |
| 30 | +import java.nio.MappedByteBuffer; | |
| 31 | +import java.nio.channels.spi.AbstractInterruptibleChannel; | |
| 32 | +import java.nio.file.*; | |
| 33 | +import java.nio.file.attribute.FileAttribute; | |
| 34 | +import java.nio.file.spi.*; | |
| 35 | +import java.util.Set; | |
| 36 | +import java.util.HashSet; | |
| 37 | +import java.util.Collections; | |
| 38 | + | |
| 39 | +/** | |
| 40 | + * A channel for reading, writing, mapping, and manipulating a file. | |
| 41 | + * | |
| 42 | + * <p> A file channel is a {@link SeekableByteChannel} that is connected to | |
| 43 | + * a file. It has a current <i>position</i> within its file which can | |
| 44 | + * be both {@link #position() <i>queried</i>} and {@link #position(long) | |
| 45 | + * <i>modified</i>}. The file itself contains a variable-length sequence | |
| 46 | + * of bytes that can be read and written and whose current {@link #size | |
| 47 | + * <i>size</i>} can be queried. The size of the file increases | |
| 48 | + * when bytes are written beyond its current size; the size of the file | |
| 49 | + * decreases when it is {@link #truncate </code><i>truncated</i><code>}. The | |
| 50 | + * file may also have some associated <i>metadata</i> such as access | |
| 51 | + * permissions, content type, and last-modification time; this class does not | |
| 52 | + * define methods for metadata access. | |
| 53 | + * | |
| 54 | + * <p> In addition to the familiar read, write, and close operations of byte | |
| 55 | + * channels, this class defines the following file-specific operations: </p> | |
| 56 | + * | |
| 57 | + * <ul> | |
| 58 | + * | |
| 59 | + * <li><p> Bytes may be {@link #read(ByteBuffer, long) read} or | |
| 60 | + * {@link #write(ByteBuffer, long) <i>written</i>} at an absolute | |
| 61 | + * position in a file in a way that does not affect the channel's current | |
| 62 | + * position. </p></li> | |
| 63 | + * | |
| 64 | + * <li><p> A region of a file may be {@link #map <i>mapped</i>} | |
| 65 | + * directly into memory; for large files this is often much more efficient | |
| 66 | + * than invoking the usual <tt>read</tt> or <tt>write</tt> methods. | |
| 67 | + * </p></li> | |
| 68 | + * | |
| 69 | + * <li><p> Updates made to a file may be {@link #force <i>forced | |
| 70 | + * out</i>} to the underlying storage device, ensuring that data are not | |
| 71 | + * lost in the event of a system crash. </p></li> | |
| 72 | + * | |
| 73 | + * <li><p> Bytes can be transferred from a file {@link #transferTo <i>to | |
| 74 | + * some other channel</i>}, and {@link #transferFrom <i>vice | |
| 75 | + * versa</i>}, in a way that can be optimized by many operating systems | |
| 76 | + * into a very fast transfer directly to or from the filesystem cache. | |
| 77 | + * </p></li> | |
| 78 | + * | |
| 79 | + * <li><p> A region of a file may be {@link FileLock <i>locked</i>} | |
| 80 | + * against access by other programs. </p></li> | |
| 81 | + * | |
| 82 | + * </ul> | |
| 83 | + * | |
| 84 | + * <p> File channels are safe for use by multiple concurrent threads. The | |
| 85 | + * {@link Channel#close close} method may be invoked at any time, as specified | |
| 86 | + * by the {@link Channel} interface. Only one operation that involves the | |
| 87 | + * channel's position or can change its file's size may be in progress at any | |
| 88 | + * given time; attempts to initiate a second such operation while the first is | |
| 89 | + * still in progress will block until the first operation completes. Other | |
| 90 | + * operations, in particular those that take an explicit position, may proceed | |
| 91 | + * concurrently; whether they in fact do so is dependent upon the underlying | |
| 92 | + * implementation and is therefore unspecified. | |
| 93 | + * | |
| 94 | + * <p> The view of a file provided by an instance of this class is guaranteed | |
| 95 | + * to be consistent with other views of the same file provided by other | |
| 96 | + * instances in the same program. The view provided by an instance of this | |
| 97 | + * class may or may not, however, be consistent with the views seen by other | |
| 98 | + * concurrently-running programs due to caching performed by the underlying | |
| 99 | + * operating system and delays induced by network-filesystem protocols. This | |
| 100 | + * is true regardless of the language in which these other programs are | |
| 101 | + * written, and whether they are running on the same machine or on some other | |
| 102 | + * machine. The exact nature of any such inconsistencies are system-dependent | |
| 103 | + * and are therefore unspecified. | |
| 104 | + * | |
| 105 | + * <p> A file channel is created by invoking one of the {@link #open open} | |
| 106 | + * methods defined by this class. A file channel can also be obtained from an | |
| 107 | + * existing {@link java.io.FileInputStream#getChannel FileInputStream}, {@link | |
| 108 | + * java.io.FileOutputStream#getChannel FileOutputStream}, or {@link | |
| 109 | + * java.io.RandomAccessFile#getChannel RandomAccessFile} object by invoking | |
| 110 | + * that object's <tt>getChannel</tt> method, which returns a file channel that | |
| 111 | + * is connected to the same underlying file. Where the file channel is obtained | |
| 112 | + * from an existing stream or random access file then the state of the file | |
| 113 | + * channel is intimately connected to that of the object whose <tt>getChannel</tt> | |
| 114 | + * method returned the channel. Changing the channel's position, whether | |
| 115 | + * explicitly or by reading or writing bytes, will change the file position of | |
| 116 | + * the originating object, and vice versa. Changing the file's length via the | |
| 117 | + * file channel will change the length seen via the originating object, and vice | |
| 118 | + * versa. Changing the file's content by writing bytes will change the content | |
| 119 | + * seen by the originating object, and vice versa. | |
| 120 | + * | |
| 121 | + * <a name="open-mode"></a> <p> At various points this class specifies that an | |
| 122 | + * instance that is "open for reading," "open for writing," or "open for | |
| 123 | + * reading and writing" is required. A channel obtained via the {@link | |
| 124 | + * java.io.FileInputStream#getChannel getChannel} method of a {@link | |
| 125 | + * java.io.FileInputStream} instance will be open for reading. A channel | |
| 126 | + * obtained via the {@link java.io.FileOutputStream#getChannel getChannel} | |
| 127 | + * method of a {@link java.io.FileOutputStream} instance will be open for | |
| 128 | + * writing. Finally, a channel obtained via the {@link | |
| 129 | + * java.io.RandomAccessFile#getChannel getChannel} method of a {@link | |
| 130 | + * java.io.RandomAccessFile} instance will be open for reading if the instance | |
| 131 | + * was created with mode <tt>"r"</tt> and will be open for reading and writing | |
| 132 | + * if the instance was created with mode <tt>"rw"</tt>. | |
| 133 | + * | |
| 134 | + * <a name="append-mode"></a><p> A file channel that is open for writing may be in | |
| 135 | + * <i>append mode</i>, for example if it was obtained from a file-output stream | |
| 136 | + * that was created by invoking the {@link | |
| 137 | + * java.io.FileOutputStream#FileOutputStream(java.io.File,boolean) | |
| 138 | + * FileOutputStream(File,boolean)} constructor and passing <tt>true</tt> for | |
| 139 | + * the second parameter. In this mode each invocation of a relative write | |
| 140 | + * operation first advances the position to the end of the file and then writes | |
| 141 | + * the requested data. Whether the advancement of the position and the writing | |
| 142 | + * of the data are done in a single atomic operation is system-dependent and | |
| 143 | + * therefore unspecified. | |
| 144 | + * | |
| 145 | + * @see java.io.FileInputStream#getChannel() | |
| 146 | + * @see java.io.FileOutputStream#getChannel() | |
| 147 | + * @see java.io.RandomAccessFile#getChannel() | |
| 148 | + * | |
| 149 | + * @author Mark Reinhold | |
| 150 | + * @author Mike McCloskey | |
| 151 | + * @author JSR-51 Expert Group | |
| 152 | + * @since 1.4 | |
| 153 | + */ | |
| 154 | + | |
| 155 | +public abstract class FileChannel | |
| 156 | + extends AbstractInterruptibleChannel | |
| 157 | + implements SeekableByteChannel, GatheringByteChannel, ScatteringByteChannel | |
| 158 | +{ | |
| 159 | + /** | |
| 160 | + * Initializes a new instance of this class. | |
| 161 | + */ | |
| 162 | + protected FileChannel() { } | |
| 163 | + | |
| 164 | + /** | |
| 165 | + * Opens or creates a file, returning a file channel to access the file. | |
| 166 | + * | |
| 167 | + * <p> The {@code options} parameter determines how the file is opened. | |
| 168 | + * The {@link StandardOpenOption#READ READ} and {@link StandardOpenOption#WRITE | |
| 169 | + * WRITE} options determine if the file should be opened for reading and/or | |
| 170 | + * writing. If neither option (or the {@link StandardOpenOption#APPEND APPEND} | |
| 171 | + * option) is contained in the array then the file is opened for reading. | |
| 172 | + * By default reading or writing commences at the beginning of the file. | |
| 173 | + * | |
| 174 | + * <p> In the addition to {@code READ} and {@code WRITE}, the following | |
| 175 | + * options may be present: | |
| 176 | + * | |
| 177 | + * <table border=1 cellpadding=5 summary=""> | |
| 178 | + * <tr> <th>Option</th> <th>Description</th> </tr> | |
| 179 | + * <tr> | |
| 180 | + * <td> {@link StandardOpenOption#APPEND APPEND} </td> | |
| 181 | + * <td> If this option is present then the file is opened for writing and | |
| 182 | + * each invocation of the channel's {@code write} method first advances | |
| 183 | + * the position to the end of the file and then writes the requested | |
| 184 | + * data. Whether the advancement of the position and the writing of the | |
| 185 | + * data are done in a single atomic operation is system-dependent and | |
| 186 | + * therefore unspecified. This option may not be used in conjunction | |
| 187 | + * with the {@code READ} or {@code TRUNCATE_EXISTING} options. </td> | |
| 188 | + * </tr> | |
| 189 | + * <tr> | |
| 190 | + * <td> {@link StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING} </td> | |
| 191 | + * <td> If this option is present then the existing file is truncated to | |
| 192 | + * a size of 0 bytes. This option is ignored when the file is opened only | |
| 193 | + * for reading. </td> | |
| 194 | + * </tr> | |
| 195 | + * <tr> | |
| 196 | + * <td> {@link StandardOpenOption#CREATE_NEW CREATE_NEW} </td> | |
| 197 | + * <td> If this option is present then a new file is created, failing if | |
| 198 | + * the file already exists. When creating a file the check for the | |
| 199 | + * existence of the file and the creation of the file if it does not exist | |
| 200 | + * is atomic with respect to other file system operations. This option is | |
| 201 | + * ignored when the file is opened only for reading. </td> | |
| 202 | + * </tr> | |
| 203 | + * <tr> | |
| 204 | + * <td > {@link StandardOpenOption#CREATE CREATE} </td> | |
| 205 | + * <td> If this option is present then an existing file is opened if it | |
| 206 | + * exists, otherwise a new file is created. When creating a file the check | |
| 207 | + * for the existence of the file and the creation of the file if it does | |
| 208 | + * not exist is atomic with respect to other file system operations. This | |
| 209 | + * option is ignored if the {@code CREATE_NEW} option is also present or | |
| 210 | + * the file is opened only for reading. </td> | |
| 211 | + * </tr> | |
| 212 | + * <tr> | |
| 213 | + * <td > {@link StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} </td> | |
| 214 | + * <td> When this option is present then the implementation makes a | |
| 215 | + * <em>best effort</em> attempt to delete the file when closed by the | |
| 216 | + * the {@link #close close} method. If the {@code close} method is not | |
| 217 | + * invoked then a <em>best effort</em> attempt is made to delete the file | |
| 218 | + * when the Java virtual machine terminates. </td> | |
| 219 | + * </tr> | |
| 220 | + * <tr> | |
| 221 | + * <td>{@link StandardOpenOption#SPARSE SPARSE} </td> | |
| 222 | + * <td> When creating a new file this option is a <em>hint</em> that the | |
| 223 | + * new file will be sparse. This option is ignored when not creating | |
| 224 | + * a new file. </td> | |
| 225 | + * </tr> | |
| 226 | + * <tr> | |
| 227 | + * <td> {@link StandardOpenOption#SYNC SYNC} </td> | |
| 228 | + * <td> Requires that every update to the file's content or metadata be | |
| 229 | + * written synchronously to the underlying storage device. (see <a | |
| 230 | + * href="../file/package-summary.html#integrity"> Synchronized I/O file | |
| 231 | + * integrity</a>). </td> | |
| 232 | + * <tr> | |
| 233 | + * <tr> | |
| 234 | + * <td> {@link StandardOpenOption#DSYNC DSYNC} </td> | |
| 235 | + * <td> Requires that every update to the file's content be written | |
| 236 | + * synchronously to the underlying storage device. (see <a | |
| 237 | + * href="../file/package-summary.html#integrity"> Synchronized I/O file | |
| 238 | + * integrity</a>). </td> | |
| 239 | + * </tr> | |
| 240 | + * </table> | |
| 241 | + * | |
| 242 | + * <p> An implementation may also support additional options. | |
| 243 | + * | |
| 244 | + * <p> The {@code attrs} parameter is an optional array of file {@link | |
| 245 | + * FileAttribute file-attributes} to set atomically when creating the file. | |
| 246 | + * | |
| 247 | + * <p> The new channel is created by invoking the {@link | |
| 248 | + * FileSystemProvider#newFileChannel newFileChannel} method on the | |
| 249 | + * provider that created the {@code Path}. | |
| 250 | + * | |
| 251 | + * @param path | |
| 252 | + * The path of the file to open or create | |
| 253 | + * @param options | |
| 254 | + * Options specifying how the file is opened | |
| 255 | + * @param attrs | |
| 256 | + * An optional list of file attributes to set atomically when | |
| 257 | + * creating the file | |
| 258 | + * | |
| 259 | + * @return A new file channel | |
| 260 | + * | |
| 261 | + * @throws IllegalArgumentException | |
| 262 | + * If the set contains an invalid combination of options | |
| 263 | + * @throws UnsupportedOperationException | |
| 264 | + * If the {@code path} is associated with a provider that does not | |
| 265 | + * support creating file channels, or an unsupported open option is | |
| 266 | + * specified, or the array contains an attribute that cannot be set | |
| 267 | + * atomically when creating the file | |
| 268 | + * @throws IOException | |
| 269 | + * If an I/O error occurs | |
| 270 | + * @throws SecurityException | |
| 271 | + * If a security manager is installed and it denies an | |
| 272 | + * unspecified permission required by the implementation. | |
| 273 | + * In the case of the default provider, the {@link | |
| 274 | + * SecurityManager#checkRead(String)} method is invoked to check | |
| 275 | + * read access if the file is opened for reading. The {@link | |
| 276 | + * SecurityManager#checkWrite(String)} method is invoked to check | |
| 277 | + * write access if the file is opened for writing | |
| 278 | + * | |
| 279 | + * @since 1.7 | |
| 280 | + */ | |
| 281 | + public static FileChannel open(Path path, | |
| 282 | + Set<? extends OpenOption> options, | |
| 283 | + FileAttribute<?>... attrs) | |
| 284 | + throws IOException | |
| 285 | + { | |
| 286 | + FileSystemProvider provider = path.getFileSystem().provider(); | |
| 287 | + return provider.newFileChannel(path, options, attrs); | |
| 288 | + } | |
| 289 | + | |
| 290 | + private static final FileAttribute<?>[] NO_ATTRIBUTES = new FileAttribute[0]; | |
| 291 | + | |
| 292 | + /** | |
| 293 | + * Opens or creates a file, returning a file channel to access the file. | |
| 294 | + * | |
| 295 | + * <p> An invocation of this method behaves in exactly the same way as the | |
| 296 | + * invocation | |
| 297 | + * <pre> | |
| 298 | + * fc.{@link #open(Path,Set,FileAttribute[]) open}(file, opts, new FileAttribute<?>[0]); | |
| 299 | + * </pre> | |
| 300 | + * where {@code opts} is a set of the options specified in the {@code | |
| 301 | + * options} array. | |
| 302 | + * | |
| 303 | + * @param path | |
| 304 | + * The path of the file to open or create | |
| 305 | + * @param options | |
| 306 | + * Options specifying how the file is opened | |
| 307 | + * | |
| 308 | + * @return A new file channel | |
| 309 | + * | |
| 310 | + * @throws IllegalArgumentException | |
| 311 | + * If the set contains an invalid combination of options | |
| 312 | + * @throws UnsupportedOperationException | |
| 313 | + * If the {@code path} is associated with a provider that does not | |
| 314 | + * support creating file channels, or an unsupported open option is | |
| 315 | + * specified | |
| 316 | + * @throws IOException | |
| 317 | + * If an I/O error occurs | |
| 318 | + * @throws SecurityException | |
| 319 | + * If a security manager is installed and it denies an | |
| 320 | + * unspecified permission required by the implementation. | |
| 321 | + * In the case of the default provider, the {@link | |
| 322 | + * SecurityManager#checkRead(String)} method is invoked to check | |
| 323 | + * read access if the file is opened for reading. The {@link | |
| 324 | + * SecurityManager#checkWrite(String)} method is invoked to check | |
| 325 | + * write access if the file is opened for writing | |
| 326 | + * | |
| 327 | + * @since 1.7 | |
| 328 | + */ | |
| 329 | + public static FileChannel open(Path path, OpenOption... options) | |
| 330 | + throws IOException | |
| 331 | + { | |
| 332 | + Set<OpenOption> set = new HashSet<OpenOption>(options.length); | |
| 333 | + Collections.addAll(set, options); | |
| 334 | + return open(path, set, NO_ATTRIBUTES); | |
| 335 | + } | |
| 336 | + | |
| 337 | + // -- Channel operations -- | |
| 338 | + | |
| 339 | + /** | |
| 340 | + * Reads a sequence of bytes from this channel into the given buffer. | |
| 341 | + * | |
| 342 | + * <p> Bytes are read starting at this channel's current file position, and | |
| 343 | + * then the file position is updated with the number of bytes actually | |
| 344 | + * read. Otherwise this method behaves exactly as specified in the {@link | |
| 345 | + * ReadableByteChannel} interface. </p> | |
| 346 | + */ | |
| 347 | + public abstract int read(ByteBuffer dst) throws IOException; | |
| 348 | + | |
| 349 | + /** | |
| 350 | + * Reads a sequence of bytes from this channel into a subsequence of the | |
| 351 | + * given buffers. | |
| 352 | + * | |
| 353 | + * <p> Bytes are read starting at this channel's current file position, and | |
| 354 | + * then the file position is updated with the number of bytes actually | |
| 355 | + * read. Otherwise this method behaves exactly as specified in the {@link | |
| 356 | + * ScatteringByteChannel} interface. </p> | |
| 357 | + */ | |
| 358 | + public abstract long read(ByteBuffer[] dsts, int offset, int length) | |
| 359 | + throws IOException; | |
| 360 | + | |
| 361 | + /** | |
| 362 | + * Reads a sequence of bytes from this channel into the given buffers. | |
| 363 | + * | |
| 364 | + * <p> Bytes are read starting at this channel's current file position, and | |
| 365 | + * then the file position is updated with the number of bytes actually | |
| 366 | + * read. Otherwise this method behaves exactly as specified in the {@link | |
| 367 | + * ScatteringByteChannel} interface. </p> | |
| 368 | + */ | |
| 369 | + public final long read(ByteBuffer[] dsts) throws IOException { | |
| 370 | + return read(dsts, 0, dsts.length); | |
| 371 | + } | |
| 372 | + | |
| 373 | + /** | |
| 374 | + * Writes a sequence of bytes to this channel from the given buffer. | |
| 375 | + * | |
| 376 | + * <p> Bytes are written starting at this channel's current file position | |
| 377 | + * unless the channel is in append mode, in which case the position is | |
| 378 | + * first advanced to the end of the file. The file is grown, if necessary, | |
| 379 | + * to accommodate the written bytes, and then the file position is updated | |
| 380 | + * with the number of bytes actually written. Otherwise this method | |
| 381 | + * behaves exactly as specified by the {@link WritableByteChannel} | |
| 382 | + * interface. </p> | |
| 383 | + */ | |
| 384 | + public abstract int write(ByteBuffer src) throws IOException; | |
| 385 | + | |
| 386 | + /** | |
| 387 | + * Writes a sequence of bytes to this channel from a subsequence of the | |
| 388 | + * given buffers. | |
| 389 | + * | |
| 390 | + * <p> Bytes are written starting at this channel's current file position | |
| 391 | + * unless the channel is in append mode, in which case the position is | |
| 392 | + * first advanced to the end of the file. The file is grown, if necessary, | |
| 393 | + * to accommodate the written bytes, and then the file position is updated | |
| 394 | + * with the number of bytes actually written. Otherwise this method | |
| 395 | + * behaves exactly as specified in the {@link GatheringByteChannel} | |
| 396 | + * interface. </p> | |
| 397 | + */ | |
| 398 | + public abstract long write(ByteBuffer[] srcs, int offset, int length) | |
| 399 | + throws IOException; | |
| 400 | + | |
| 401 | + /** | |
| 402 | + * Writes a sequence of bytes to this channel from the given buffers. | |
| 403 | + * | |
| 404 | + * <p> Bytes are written starting at this channel's current file position | |
| 405 | + * unless the channel is in append mode, in which case the position is | |
| 406 | + * first advanced to the end of the file. The file is grown, if necessary, | |
| 407 | + * to accommodate the written bytes, and then the file position is updated | |
| 408 | + * with the number of bytes actually written. Otherwise this method | |
| 409 | + * behaves exactly as specified in the {@link GatheringByteChannel} | |
| 410 | + * interface. </p> | |
| 411 | + */ | |
| 412 | + public final long write(ByteBuffer[] srcs) throws IOException { | |
| 413 | + return write(srcs, 0, srcs.length); | |
| 414 | + } | |
| 415 | + | |
| 416 | + | |
| 417 | + // -- Other operations -- | |
| 418 | + | |
| 419 | + /** | |
| 420 | + * Returns this channel's file position. </p> | |
| 421 | + * | |
| 422 | + * @return This channel's file position, | |
| 423 | + * a non-negative integer counting the number of bytes | |
| 424 | + * from the beginning of the file to the current position | |
| 425 | + * | |
| 426 | + * @throws ClosedChannelException | |
| 427 | + * If this channel is closed | |
| 428 | + * | |
| 429 | + * @throws IOException | |
| 430 | + * If some other I/O error occurs | |
| 431 | + */ | |
| 432 | + public abstract long position() throws IOException; | |
| 433 | + | |
| 434 | + /** | |
| 435 | + * Sets this channel's file position. | |
| 436 | + * | |
| 437 | + * <p> Setting the position to a value that is greater than the file's | |
| 438 | + * current size is legal but does not change the size of the file. A later | |
| 439 | + * attempt to read bytes at such a position will immediately return an | |
| 440 | + * end-of-file indication. A later attempt to write bytes at such a | |
| 441 | + * position will cause the file to be grown to accommodate the new bytes; | |
| 442 | + * the values of any bytes between the previous end-of-file and the | |
| 443 | + * newly-written bytes are unspecified. </p> | |
| 444 | + * | |
| 445 | + * @param newPosition | |
| 446 | + * The new position, a non-negative integer counting | |
| 447 | + * the number of bytes from the beginning of the file | |
| 448 | + * | |
| 449 | + * @return This file channel | |
| 450 | + * | |
| 451 | + * @throws ClosedChannelException | |
| 452 | + * If this channel is closed | |
| 453 | + * | |
| 454 | + * @throws IllegalArgumentException | |
| 455 | + * If the new position is negative | |
| 456 | + * | |
| 457 | + * @throws IOException | |
| 458 | + * If some other I/O error occurs | |
| 459 | + */ | |
| 460 | + public abstract FileChannel position(long newPosition) throws IOException; | |
| 461 | + | |
| 462 | + /** | |
| 463 | + * Returns the current size of this channel's file. </p> | |
| 464 | + * | |
| 465 | + * @return The current size of this channel's file, | |
| 466 | + * measured in bytes | |
| 467 | + * | |
| 468 | + * @throws ClosedChannelException | |
| 469 | + * If this channel is closed | |
| 470 | + * | |
| 471 | + * @throws IOException | |
| 472 | + * If some other I/O error occurs | |
| 473 | + */ | |
| 474 | + public abstract long size() throws IOException; | |
| 475 | + | |
| 476 | + /** | |
| 477 | + * Truncates this channel's file to the given size. | |
| 478 | + * | |
| 479 | + * <p> If the given size is less than the file's current size then the file | |
| 480 | + * is truncated, discarding any bytes beyond the new end of the file. If | |
| 481 | + * the given size is greater than or equal to the file's current size then | |
| 482 | + * the file is not modified. In either case, if this channel's file | |
| 483 | + * position is greater than the given size then it is set to that size. | |
| 484 | + * </p> | |
| 485 | + * | |
| 486 | + * @param size | |
| 487 | + * The new size, a non-negative byte count | |
| 488 | + * | |
| 489 | + * @return This file channel | |
| 490 | + * | |
| 491 | + * @throws NonWritableChannelException | |
| 492 | + * If this channel was not opened for writing | |
| 493 | + * | |
| 494 | + * @throws ClosedChannelException | |
| 495 | + * If this channel is closed | |
| 496 | + * | |
| 497 | + * @throws IllegalArgumentException | |
| 498 | + * If the new size is negative | |
| 499 | + * | |
| 500 | + * @throws IOException | |
| 501 | + * If some other I/O error occurs | |
| 502 | + */ | |
| 503 | + public abstract FileChannel truncate(long size) throws IOException; | |
| 504 | + | |
| 505 | + /** | |
| 506 | + * Forces any updates to this channel's file to be written to the storage | |
| 507 | + * device that contains it. | |
| 508 | + * | |
| 509 | + * <p> If this channel's file resides on a local storage device then when | |
| 510 | + * this method returns it is guaranteed that all changes made to the file | |
| 511 | + * since this channel was created, or since this method was last invoked, | |
| 512 | + * will have been written to that device. This is useful for ensuring that | |
| 513 | + * critical information is not lost in the event of a system crash. | |
| 514 | + * | |
| 515 | + * <p> If the file does not reside on a local device then no such guarantee | |
| 516 | + * is made. | |
| 517 | + * | |
| 518 | + * <p> The <tt>metaData</tt> parameter can be used to limit the number of | |
| 519 | + * I/O operations that this method is required to perform. Passing | |
| 520 | + * <tt>false</tt> for this parameter indicates that only updates to the | |
| 521 | + * file's content need be written to storage; passing <tt>true</tt> | |
| 522 | + * indicates that updates to both the file's content and metadata must be | |
| 523 | + * written, which generally requires at least one more I/O operation. | |
| 524 | + * Whether this parameter actually has any effect is dependent upon the | |
| 525 | + * underlying operating system and is therefore unspecified. | |
| 526 | + * | |
| 527 | + * <p> Invoking this method may cause an I/O operation to occur even if the | |
| 528 | + * channel was only opened for reading. Some operating systems, for | |
| 529 | + * example, maintain a last-access time as part of a file's metadata, and | |
| 530 | + * this time is updated whenever the file is read. Whether or not this is | |
| 531 | + * actually done is system-dependent and is therefore unspecified. | |
| 532 | + * | |
| 533 | + * <p> This method is only guaranteed to force changes that were made to | |
| 534 | + * this channel's file via the methods defined in this class. It may or | |
| 535 | + * may not force changes that were made by modifying the content of a | |
| 536 | + * {@link MappedByteBuffer <i>mapped byte buffer</i>} obtained by | |
| 537 | + * invoking the {@link #map map} method. Invoking the {@link | |
| 538 | + * MappedByteBuffer#force force} method of the mapped byte buffer will | |
| 539 | + * force changes made to the buffer's content to be written. </p> | |
| 540 | + * | |
| 541 | + * @param metaData | |
| 542 | + * If <tt>true</tt> then this method is required to force changes | |
| 543 | + * to both the file's content and metadata to be written to | |
| 544 | + * storage; otherwise, it need only force content changes to be | |
| 545 | + * written | |
| 546 | + * | |
| 547 | + * @throws ClosedChannelException | |
| 548 | + * If this channel is closed | |
| 549 | + * | |
| 550 | + * @throws IOException | |
| 551 | + * If some other I/O error occurs | |
| 552 | + */ | |
| 553 | + public abstract void force(boolean metaData) throws IOException; | |
| 554 | + | |
| 555 | + /** | |
| 556 | + * Transfers bytes from this channel's file to the given writable byte | |
| 557 | + * channel. | |
| 558 | + * | |
| 559 | + * <p> An attempt is made to read up to <tt>count</tt> bytes starting at | |
| 560 | + * the given <tt>position</tt> in this channel's file and write them to the | |
| 561 | + * target channel. An invocation of this method may or may not transfer | |
| 562 | + * all of the requested bytes; whether or not it does so depends upon the | |
| 563 | + * natures and states of the channels. Fewer than the requested number of | |
| 564 | + * bytes are transferred if this channel's file contains fewer than | |
| 565 | + * <tt>count</tt> bytes starting at the given <tt>position</tt>, or if the | |
| 566 | + * target channel is non-blocking and it has fewer than <tt>count</tt> | |
| 567 | + * bytes free in its output buffer. | |
| 568 | + * | |
| 569 | + * <p> This method does not modify this channel's position. If the given | |
| 570 | + * position is greater than the file's current size then no bytes are | |
| 571 | + * transferred. If the target channel has a position then bytes are | |
| 572 | + * written starting at that position and then the position is incremented | |
| 573 | + * by the number of bytes written. | |
| 574 | + * | |
| 575 | + * <p> This method is potentially much more efficient than a simple loop | |
| 576 | + * that reads from this channel and writes to the target channel. Many | |
| 577 | + * operating systems can transfer bytes directly from the filesystem cache | |
| 578 | + * to the target channel without actually copying them. </p> | |
| 579 | + * | |
| 580 | + * @param position | |
| 581 | + * The position within the file at which the transfer is to begin; | |
| 582 | + * must be non-negative | |
| 583 | + * | |
| 584 | + * @param count | |
| 585 | + * The maximum number of bytes to be transferred; must be | |
| 586 | + * non-negative | |
| 587 | + * | |
| 588 | + * @param target | |
| 589 | + * The target channel | |
| 590 | + * | |
| 591 | + * @return The number of bytes, possibly zero, | |
| 592 | + * that were actually transferred | |
| 593 | + * | |
| 594 | + * @throws IllegalArgumentException | |
| 595 | + * If the preconditions on the parameters do not hold | |
| 596 | + * | |
| 597 | + * @throws NonReadableChannelException | |
| 598 | + * If this channel was not opened for reading | |
| 599 | + * | |
| 600 | + * @throws NonWritableChannelException | |
| 601 | + * If the target channel was not opened for writing | |
| 602 | + * | |
| 603 | + * @throws ClosedChannelException | |
| 604 | + * If either this channel or the target channel is closed | |
| 605 | + * | |
| 606 | + * @throws AsynchronousCloseException | |
| 607 | + * If another thread closes either channel | |
| 608 | + * while the transfer is in progress | |
| 609 | + * | |
| 610 | + * @throws ClosedByInterruptException | |
| 611 | + * If another thread interrupts the current thread while the | |
| 612 | + * transfer is in progress, thereby closing both channels and | |
| 613 | + * setting the current thread's interrupt status | |
| 614 | + * | |
| 615 | + * @throws IOException | |
| 616 | + * If some other I/O error occurs | |
| 617 | + */ | |
| 618 | + public abstract long transferTo(long position, long count, | |
| 619 | + WritableByteChannel target) | |
| 620 | + throws IOException; | |
| 621 | + | |
| 622 | + /** | |
| 623 | + * Transfers bytes into this channel's file from the given readable byte | |
| 624 | + * channel. | |
| 625 | + * | |
| 626 | + * <p> An attempt is made to read up to <tt>count</tt> bytes from the | |
| 627 | + * source channel and write them to this channel's file starting at the | |
| 628 | + * given <tt>position</tt>. An invocation of this method may or may not | |
| 629 | + * transfer all of the requested bytes; whether or not it does so depends | |
| 630 | + * upon the natures and states of the channels. Fewer than the requested | |
| 631 | + * number of bytes will be transferred if the source channel has fewer than | |
| 632 | + * <tt>count</tt> bytes remaining, or if the source channel is non-blocking | |
| 633 | + * and has fewer than <tt>count</tt> bytes immediately available in its | |
| 634 | + * input buffer. | |
| 635 | + * | |
| 636 | + * <p> This method does not modify this channel's position. If the given | |
| 637 | + * position is greater than the file's current size then no bytes are | |
| 638 | + * transferred. If the source channel has a position then bytes are read | |
| 639 | + * starting at that position and then the position is incremented by the | |
| 640 | + * number of bytes read. | |
| 641 | + * | |
| 642 | + * <p> This method is potentially much more efficient than a simple loop | |
| 643 | + * that reads from the source channel and writes to this channel. Many | |
| 644 | + * operating systems can transfer bytes directly from the source channel | |
| 645 | + * into the filesystem cache without actually copying them. </p> | |
| 646 | + * | |
| 647 | + * @param src | |
| 648 | + * The source channel | |
| 649 | + * | |
| 650 | + * @param position | |
| 651 | + * The position within the file at which the transfer is to begin; | |
| 652 | + * must be non-negative | |
| 653 | + * | |
| 654 | + * @param count | |
| 655 | + * The maximum number of bytes to be transferred; must be | |
| 656 | + * non-negative | |
| 657 | + * | |
| 658 | + * @return The number of bytes, possibly zero, | |
| 659 | + * that were actually transferred | |
| 660 | + * | |
| 661 | + * @throws IllegalArgumentException | |
| 662 | + * If the preconditions on the parameters do not hold | |
| 663 | + * | |
| 664 | + * @throws NonReadableChannelException | |
| 665 | + * If the source channel was not opened for reading | |
| 666 | + * | |
| 667 | + * @throws NonWritableChannelException | |
| 668 | + * If this channel was not opened for writing | |
| 669 | + * | |
| 670 | + * @throws ClosedChannelException | |
| 671 | + * If either this channel or the source channel is closed | |
| 672 | + * | |
| 673 | + * @throws AsynchronousCloseException | |
| 674 | + * If another thread closes either channel | |
| 675 | + * while the transfer is in progress | |
| 676 | + * | |
| 677 | + * @throws ClosedByInterruptException | |
| 678 | + * If another thread interrupts the current thread while the | |
| 679 | + * transfer is in progress, thereby closing both channels and | |
| 680 | + * setting the current thread's interrupt status | |
| 681 | + * | |
| 682 | + * @throws IOException | |
| 683 | + * If some other I/O error occurs | |
| 684 | + */ | |
| 685 | + public abstract long transferFrom(ReadableByteChannel src, | |
| 686 | + long position, long count) | |
| 687 | + throws IOException; | |
| 688 | + | |
| 689 | + /** | |
| 690 | + * Reads a sequence of bytes from this channel into the given buffer, | |
| 691 | + * starting at the given file position. | |
| 692 | + * | |
| 693 | + * <p> This method works in the same manner as the {@link | |
| 694 | + * #read(ByteBuffer)} method, except that bytes are read starting at the | |
| 695 | + * given file position rather than at the channel's current position. This | |
| 696 | + * method does not modify this channel's position. If the given position | |
| 697 | + * is greater than the file's current size then no bytes are read. </p> | |
| 698 | + * | |
| 699 | + * @param dst | |
| 700 | + * The buffer into which bytes are to be transferred | |
| 701 | + * | |
| 702 | + * @param position | |
| 703 | + * The file position at which the transfer is to begin; | |
| 704 | + * must be non-negative | |
| 705 | + * | |
| 706 | + * @return The number of bytes read, possibly zero, or <tt>-1</tt> if the | |
| 707 | + * given position is greater than or equal to the file's current | |
| 708 | + * size | |
| 709 | + * | |
| 710 | + * @throws IllegalArgumentException | |
| 711 | + * If the position is negative | |
| 712 | + * | |
| 713 | + * @throws NonReadableChannelException | |
| 714 | + * If this channel was not opened for reading | |
| 715 | + * | |
| 716 | + * @throws ClosedChannelException | |
| 717 | + * If this channel is closed | |
| 718 | + * | |
| 719 | + * @throws AsynchronousCloseException | |
| 720 | + * If another thread closes this channel | |
| 721 | + * while the read operation is in progress | |
| 722 | + * | |
| 723 | + * @throws ClosedByInterruptException | |
| 724 | + * If another thread interrupts the current thread | |
| 725 | + * while the read operation is in progress, thereby | |
| 726 | + * closing the channel and setting the current thread's | |
| 727 | + * interrupt status | |
| 728 | + * | |
| 729 | + * @throws IOException | |
| 730 | + * If some other I/O error occurs | |
| 731 | + */ | |
| 732 | + public abstract int read(ByteBuffer dst, long position) throws IOException; | |
| 733 | + | |
| 734 | + /** | |
| 735 | + * Writes a sequence of bytes to this channel from the given buffer, | |
| 736 | + * starting at the given file position. | |
| 737 | + * | |
| 738 | + * <p> This method works in the same manner as the {@link | |
| 739 | + * #write(ByteBuffer)} method, except that bytes are written starting at | |
| 740 | + * the given file position rather than at the channel's current position. | |
| 741 | + * This method does not modify this channel's position. If the given | |
| 742 | + * position is greater than the file's current size then the file will be | |
| 743 | + * grown to accommodate the new bytes; the values of any bytes between the | |
| 744 | + * previous end-of-file and the newly-written bytes are unspecified. </p> | |
| 745 | + * | |
| 746 | + * @param src | |
| 747 | + * The buffer from which bytes are to be transferred | |
| 748 | + * | |
| 749 | + * @param position | |
| 750 | + * The file position at which the transfer is to begin; | |
| 751 | + * must be non-negative | |
| 752 | + * | |
| 753 | + * @return The number of bytes written, possibly zero | |
| 754 | + * | |
| 755 | + * @throws IllegalArgumentException | |
| 756 | + * If the position is negative | |
| 757 | + * | |
| 758 | + * @throws NonWritableChannelException | |
| 759 | + * If this channel was not opened for writing | |
| 760 | + * | |
| 761 | + * @throws ClosedChannelException | |
| 762 | + * If this channel is closed | |
| 763 | + * | |
| 764 | + * @throws AsynchronousCloseException | |
| 765 | + * If another thread closes this channel | |
| 766 | + * while the write operation is in progress | |
| 767 | + * | |
| 768 | + * @throws ClosedByInterruptException | |
| 769 | + * If another thread interrupts the current thread | |
| 770 | + * while the write operation is in progress, thereby | |
| 771 | + * closing the channel and setting the current thread's | |
| 772 | + * interrupt status | |
| 773 | + * | |
| 774 | + * @throws IOException | |
| 775 | + * If some other I/O error occurs | |
| 776 | + */ | |
| 777 | + public abstract int write(ByteBuffer src, long position) throws IOException; | |
| 778 | + | |
| 779 | + | |
| 780 | + // -- Memory-mapped buffers -- | |
| 781 | + | |
| 782 | + /** | |
| 783 | + * A typesafe enumeration for file-mapping modes. | |
| 784 | + * | |
| 785 | + * @since 1.4 | |
| 786 | + * | |
| 787 | + * @see java.nio.channels.FileChannel#map | |
| 788 | + */ | |
| 789 | + public static class MapMode { | |
| 790 | + | |
| 791 | + /** | |
| 792 | + * Mode for a read-only mapping. | |
| 793 | + */ | |
| 794 | + public static final MapMode READ_ONLY | |
| 795 | + = new MapMode("READ_ONLY"); | |
| 796 | + | |
| 797 | + /** | |
| 798 | + * Mode for a read/write mapping. | |
| 799 | + */ | |
| 800 | + public static final MapMode READ_WRITE | |
| 801 | + = new MapMode("READ_WRITE"); | |
| 802 | + | |
| 803 | + /** | |
| 804 | + * Mode for a private (copy-on-write) mapping. | |
| 805 | + */ | |
| 806 | + public static final MapMode PRIVATE | |
| 807 | + = new MapMode("PRIVATE"); | |
| 808 | + | |
| 809 | + private final String name; | |
| 810 | + | |
| 811 | + private MapMode(String name) { | |
| 812 | + this.name = name; | |
| 813 | + } | |
| 814 | + | |
| 815 | + /** | |
| 816 | + * Returns a string describing this file-mapping mode. | |
| 817 | + * | |
| 818 | + * @return A descriptive string | |
| 819 | + */ | |
| 820 | + public String toString() { | |
| 821 | + return name; | |
| 822 | + } | |
| 823 | + | |
| 824 | + } | |
| 825 | + | |
| 826 | + /** | |
| 827 | + * Maps a region of this channel's file directly into memory. | |
| 828 | + * | |
| 829 | + * <p> A region of a file may be mapped into memory in one of three modes: | |
| 830 | + * </p> | |
| 831 | + * | |
| 832 | + * <ul type=disc> | |
| 833 | + * | |
| 834 | + * <li><p> <i>Read-only:</i> Any attempt to modify the resulting buffer | |
| 835 | + * will cause a {@link java.nio.ReadOnlyBufferException} to be thrown. | |
| 836 | + * ({@link MapMode#READ_ONLY MapMode.READ_ONLY}) </p></li> | |
| 837 | + * | |
| 838 | + * <li><p> <i>Read/write:</i> Changes made to the resulting buffer will | |
| 839 | + * eventually be propagated to the file; they may or may not be made | |
| 840 | + * visible to other programs that have mapped the same file. ({@link | |
| 841 | + * MapMode#READ_WRITE MapMode.READ_WRITE}) </p></li> | |
| 842 | + * | |
| 843 | + * <li><p> <i>Private:</i> Changes made to the resulting buffer will not | |
| 844 | + * be propagated to the file and will not be visible to other programs | |
| 845 | + * that have mapped the same file; instead, they will cause private | |
| 846 | + * copies of the modified portions of the buffer to be created. ({@link | |
| 847 | + * MapMode#PRIVATE MapMode.PRIVATE}) </p></li> | |
| 848 | + * | |
| 849 | + * </ul> | |
| 850 | + * | |
| 851 | + * <p> For a read-only mapping, this channel must have been opened for | |
| 852 | + * reading; for a read/write or private mapping, this channel must have | |
| 853 | + * been opened for both reading and writing. | |
| 854 | + * | |
| 855 | + * <p> The {@link MappedByteBuffer <i>mapped byte buffer</i>} | |
| 856 | + * returned by this method will have a position of zero and a limit and | |
| 857 | + * capacity of <tt>size</tt>; its mark will be undefined. The buffer and | |
| 858 | + * the mapping that it represents will remain valid until the buffer itself | |
| 859 | + * is garbage-collected. | |
| 860 | + * | |
| 861 | + * <p> A mapping, once established, is not dependent upon the file channel | |
| 862 | + * that was used to create it. Closing the channel, in particular, has no | |
| 863 | + * effect upon the validity of the mapping. | |
| 864 | + * | |
| 865 | + * <p> Many of the details of memory-mapped files are inherently dependent | |
| 866 | + * upon the underlying operating system and are therefore unspecified. The | |
| 867 | + * behavior of this method when the requested region is not completely | |
| 868 | + * contained within this channel's file is unspecified. Whether changes | |
| 869 | + * made to the content or size of the underlying file, by this program or | |
| 870 | + * another, are propagated to the buffer is unspecified. The rate at which | |
| 871 | + * changes to the buffer are propagated to the file is unspecified. | |
| 872 | + * | |
| 873 | + * <p> For most operating systems, mapping a file into memory is more | |
| 874 | + * expensive than reading or writing a few tens of kilobytes of data via | |
| 875 | + * the usual {@link #read read} and {@link #write write} methods. From the | |
| 876 | + * standpoint of performance it is generally only worth mapping relatively | |
| 877 | + * large files into memory. </p> | |
| 878 | + * | |
| 879 | + * @param mode | |
| 880 | + * One of the constants {@link MapMode#READ_ONLY READ_ONLY}, {@link | |
| 881 | + * MapMode#READ_WRITE READ_WRITE}, or {@link MapMode#PRIVATE | |
| 882 | + * PRIVATE} defined in the {@link MapMode} class, according to | |
| 883 | + * whether the file is to be mapped read-only, read/write, or | |
| 884 | + * privately (copy-on-write), respectively | |
| 885 | + * | |
| 886 | + * @param position | |
| 887 | + * The position within the file at which the mapped region | |
| 888 | + * is to start; must be non-negative | |
| 889 | + * | |
| 890 | + * @param size | |
| 891 | + * The size of the region to be mapped; must be non-negative and | |
| 892 | + * no greater than {@link java.lang.Integer#MAX_VALUE} | |
| 893 | + * | |
| 894 | + * @return The mapped byte buffer | |
| 895 | + * | |
| 896 | + * @throws NonReadableChannelException | |
| 897 | + * If the <tt>mode</tt> is {@link MapMode#READ_ONLY READ_ONLY} but | |
| 898 | + * this channel was not opened for reading | |
| 899 | + * | |
| 900 | + * @throws NonWritableChannelException | |
| 901 | + * If the <tt>mode</tt> is {@link MapMode#READ_WRITE READ_WRITE} or | |
| 902 | + * {@link MapMode#PRIVATE PRIVATE} but this channel was not opened | |
| 903 | + * for both reading and writing | |
| 904 | + * | |
| 905 | + * @throws IllegalArgumentException | |
| 906 | + * If the preconditions on the parameters do not hold | |
| 907 | + * | |
| 908 | + * @throws IOException | |
| 909 | + * If some other I/O error occurs | |
| 910 | + * | |
| 911 | + * @see java.nio.channels.FileChannel.MapMode | |
| 912 | + * @see java.nio.MappedByteBuffer | |
| 913 | + */ | |
| 914 | + public abstract MappedByteBuffer map(MapMode mode, | |
| 915 | + long position, long size) | |
| 916 | + throws IOException; | |
| 917 | + | |
| 918 | + | |
| 919 | + // -- Locks -- | |
| 920 | + | |
| 921 | + /** | |
| 922 | + * Acquires a lock on the given region of this channel's file. | |
| 923 | + * | |
| 924 | + * <p> An invocation of this method will block until the region can be | |
| 925 | + * locked, this channel is closed, or the invoking thread is interrupted, | |
| 926 | + * whichever comes first. | |
| 927 | + * | |
| 928 | + * <p> If this channel is closed by another thread during an invocation of | |
| 929 | + * this method then an {@link AsynchronousCloseException} will be thrown. | |
| 930 | + * | |
| 931 | + * <p> If the invoking thread is interrupted while waiting to acquire the | |
| 932 | + * lock then its interrupt status will be set and a {@link | |
| 933 | + * FileLockInterruptionException} will be thrown. If the invoker's | |
| 934 | + * interrupt status is set when this method is invoked then that exception | |
| 935 | + * will be thrown immediately; the thread's interrupt status will not be | |
| 936 | + * changed. | |
| 937 | + * | |
| 938 | + * <p> The region specified by the <tt>position</tt> and <tt>size</tt> | |
| 939 | + * parameters need not be contained within, or even overlap, the actual | |
| 940 | + * underlying file. Lock regions are fixed in size; if a locked region | |
| 941 | + * initially contains the end of the file and the file grows beyond the | |
| 942 | + * region then the new portion of the file will not be covered by the lock. | |
| 943 | + * If a file is expected to grow in size and a lock on the entire file is | |
| 944 | + * required then a region starting at zero, and no smaller than the | |
| 945 | + * expected maximum size of the file, should be locked. The zero-argument | |
| 946 | + * {@link #lock()} method simply locks a region of size {@link | |
| 947 | + * Long#MAX_VALUE}. | |
| 948 | + * | |
| 949 | + * <p> Some operating systems do not support shared locks, in which case a | |
| 950 | + * request for a shared lock is automatically converted into a request for | |
| 951 | + * an exclusive lock. Whether the newly-acquired lock is shared or | |
| 952 | + * exclusive may be tested by invoking the resulting lock object's {@link | |
| 953 | + * FileLock#isShared() isShared} method. | |
| 954 | + * | |
| 955 | + * <p> File locks are held on behalf of the entire Java virtual machine. | |
| 956 | + * They are not suitable for controlling access to a file by multiple | |
| 957 | + * threads within the same virtual machine. </p> | |
| 958 | + * | |
| 959 | + * @param position | |
| 960 | + * The position at which the locked region is to start; must be | |
| 961 | + * non-negative | |
| 962 | + * | |
| 963 | + * @param size | |
| 964 | + * The size of the locked region; must be non-negative, and the sum | |
| 965 | + * <tt>position</tt> + <tt>size</tt> must be non-negative | |
| 966 | + * | |
| 967 | + * @param shared | |
| 968 | + * <tt>true</tt> to request a shared lock, in which case this | |
| 969 | + * channel must be open for reading (and possibly writing); | |
| 970 | + * <tt>false</tt> to request an exclusive lock, in which case this | |
| 971 | + * channel must be open for writing (and possibly reading) | |
| 972 | + * | |
| 973 | + * @return A lock object representing the newly-acquired lock | |
| 974 | + * | |
| 975 | + * @throws IllegalArgumentException | |
| 976 | + * If the preconditions on the parameters do not hold | |
| 977 | + * | |
| 978 | + * @throws ClosedChannelException | |
| 979 | + * If this channel is closed | |
| 980 | + * | |
| 981 | + * @throws AsynchronousCloseException | |
| 982 | + * If another thread closes this channel while the invoking | |
| 983 | + * thread is blocked in this method | |
| 984 | + * | |
| 985 | + * @throws FileLockInterruptionException | |
| 986 | + * If the invoking thread is interrupted while blocked in this | |
| 987 | + * method | |
| 988 | + * | |
| 989 | + * @throws OverlappingFileLockException | |
| 990 | + * If a lock that overlaps the requested region is already held by | |
| 991 | + * this Java virtual machine, or if another thread is already | |
| 992 | + * blocked in this method and is attempting to lock an overlapping | |
| 993 | + * region | |
| 994 | + * | |
| 995 | + * @throws NonReadableChannelException | |
| 996 | + * If <tt>shared</tt> is <tt>true</tt> this channel was not | |
| 997 | + * opened for reading | |
| 998 | + * | |
| 999 | + * @throws NonWritableChannelException | |
| 1000 | + * If <tt>shared</tt> is <tt>false</tt> but this channel was not | |
| 1001 | + * opened for writing | |
| 1002 | + * | |
| 1003 | + * @throws IOException | |
| 1004 | + * If some other I/O error occurs | |
| 1005 | + * | |
| 1006 | + * @see #lock() | |
| 1007 | + * @see #tryLock() | |
| 1008 | + * @see #tryLock(long,long,boolean) | |
| 1009 | + */ | |
| 1010 | + public abstract FileLock lock(long position, long size, boolean shared) | |
| 1011 | + throws IOException; | |
| 1012 | + | |
| 1013 | + /** | |
| 1014 | + * Acquires an exclusive lock on this channel's file. | |
| 1015 | + * | |
| 1016 | + * <p> An invocation of this method of the form <tt>fc.lock()</tt> behaves | |
| 1017 | + * in exactly the same way as the invocation | |
| 1018 | + * | |
| 1019 | + * <pre> | |
| 1020 | + * fc.{@link #lock(long,long,boolean) lock}(0L, Long.MAX_VALUE, false) </pre> | |
| 1021 | + * | |
| 1022 | + * @return A lock object representing the newly-acquired lock | |
| 1023 | + * | |
| 1024 | + * @throws ClosedChannelException | |
| 1025 | + * If this channel is closed | |
| 1026 | + * | |
| 1027 | + * @throws AsynchronousCloseException | |
| 1028 | + * If another thread closes this channel while the invoking | |
| 1029 | + * thread is blocked in this method | |
| 1030 | + * | |
| 1031 | + * @throws FileLockInterruptionException | |
| 1032 | + * If the invoking thread is interrupted while blocked in this | |
| 1033 | + * method | |
| 1034 | + * | |
| 1035 | + * @throws OverlappingFileLockException | |
| 1036 | + * If a lock that overlaps the requested region is already held by | |
| 1037 | + * this Java virtual machine, or if another thread is already | |
| 1038 | + * blocked in this method and is attempting to lock an overlapping | |
| 1039 | + * region of the same file | |
| 1040 | + * | |
| 1041 | + * @throws NonWritableChannelException | |
| 1042 | + * If this channel was not opened for writing | |
| 1043 | + * | |
| 1044 | + * @throws IOException | |
| 1045 | + * If some other I/O error occurs | |
| 1046 | + * | |
| 1047 | + * @see #lock(long,long,boolean) | |
| 1048 | + * @see #tryLock() | |
| 1049 | + * @see #tryLock(long,long,boolean) | |
| 1050 | + */ | |
| 1051 | + public final FileLock lock() throws IOException { | |
| 1052 | + return lock(0L, Long.MAX_VALUE, false); | |
| 1053 | + } | |
| 1054 | + | |
| 1055 | + /** | |
| 1056 | + * Attempts to acquire a lock on the given region of this channel's file. | |
| 1057 | + * | |
| 1058 | + * <p> This method does not block. An invocation always returns | |
| 1059 | + * immediately, either having acquired a lock on the requested region or | |
| 1060 | + * having failed to do so. If it fails to acquire a lock because an | |
| 1061 | + * overlapping lock is held by another program then it returns | |
| 1062 | + * <tt>null</tt>. If it fails to acquire a lock for any other reason then | |
| 1063 | + * an appropriate exception is thrown. | |
| 1064 | + * | |
| 1065 | + * <p> The region specified by the <tt>position</tt> and <tt>size</tt> | |
| 1066 | + * parameters need not be contained within, or even overlap, the actual | |
| 1067 | + * underlying file. Lock regions are fixed in size; if a locked region | |
| 1068 | + * initially contains the end of the file and the file grows beyond the | |
| 1069 | + * region then the new portion of the file will not be covered by the lock. | |
| 1070 | + * If a file is expected to grow in size and a lock on the entire file is | |
| 1071 | + * required then a region starting at zero, and no smaller than the | |
| 1072 | + * expected maximum size of the file, should be locked. The zero-argument | |
| 1073 | + * {@link #tryLock()} method simply locks a region of size {@link | |
| 1074 | + * Long#MAX_VALUE}. | |
| 1075 | + * | |
| 1076 | + * <p> Some operating systems do not support shared locks, in which case a | |
| 1077 | + * request for a shared lock is automatically converted into a request for | |
| 1078 | + * an exclusive lock. Whether the newly-acquired lock is shared or | |
| 1079 | + * exclusive may be tested by invoking the resulting lock object's {@link | |
| 1080 | + * FileLock#isShared() isShared} method. | |
| 1081 | + * | |
| 1082 | + * <p> File locks are held on behalf of the entire Java virtual machine. | |
| 1083 | + * They are not suitable for controlling access to a file by multiple | |
| 1084 | + * threads within the same virtual machine. </p> | |
| 1085 | + * | |
| 1086 | + * @param position | |
| 1087 | + * The position at which the locked region is to start; must be | |
| 1088 | + * non-negative | |
| 1089 | + * | |
| 1090 | + * @param size | |
| 1091 | + * The size of the locked region; must be non-negative, and the sum | |
| 1092 | + * <tt>position</tt> + <tt>size</tt> must be non-negative | |
| 1093 | + * | |
| 1094 | + * @param shared | |
| 1095 | + * <tt>true</tt> to request a shared lock, | |
| 1096 | + * <tt>false</tt> to request an exclusive lock | |
| 1097 | + * | |
| 1098 | + * @return A lock object representing the newly-acquired lock, | |
| 1099 | + * or <tt>null</tt> if the lock could not be acquired | |
| 1100 | + * because another program holds an overlapping lock | |
| 1101 | + * | |
| 1102 | + * @throws IllegalArgumentException | |
| 1103 | + * If the preconditions on the parameters do not hold | |
| 1104 | + * | |
| 1105 | + * @throws ClosedChannelException | |
| 1106 | + * If this channel is closed | |
| 1107 | + * | |
| 1108 | + * @throws OverlappingFileLockException | |
| 1109 | + * If a lock that overlaps the requested region is already held by | |
| 1110 | + * this Java virtual machine, or if another thread is already | |
| 1111 | + * blocked in this method and is attempting to lock an overlapping | |
| 1112 | + * region of the same file | |
| 1113 | + * | |
| 1114 | + * @throws IOException | |
| 1115 | + * If some other I/O error occurs | |
| 1116 | + * | |
| 1117 | + * @see #lock() | |
| 1118 | + * @see #lock(long,long,boolean) | |
| 1119 | + * @see #tryLock() | |
| 1120 | + */ | |
| 1121 | + public abstract FileLock tryLock(long position, long size, boolean shared) | |
| 1122 | + throws IOException; | |
| 1123 | + | |
| 1124 | + /** | |
| 1125 | + * Attempts to acquire an exclusive lock on this channel's file. | |
| 1126 | + * | |
| 1127 | + * <p> An invocation of this method of the form <tt>fc.tryLock()</tt> | |
| 1128 | + * behaves in exactly the same way as the invocation | |
| 1129 | + * | |
| 1130 | + * <pre> | |
| 1131 | + * fc.{@link #tryLock(long,long,boolean) tryLock}(0L, Long.MAX_VALUE, false) </pre> | |
| 1132 | + * | |
| 1133 | + * @return A lock object representing the newly-acquired lock, | |
| 1134 | + * or <tt>null</tt> if the lock could not be acquired | |
| 1135 | + * because another program holds an overlapping lock | |
| 1136 | + * | |
| 1137 | + * @throws ClosedChannelException | |
| 1138 | + * If this channel is closed | |
| 1139 | + * | |
| 1140 | + * @throws OverlappingFileLockException | |
| 1141 | + * If a lock that overlaps the requested region is already held by | |
| 1142 | + * this Java virtual machine, or if another thread is already | |
| 1143 | + * blocked in this method and is attempting to lock an overlapping | |
| 1144 | + * region | |
| 1145 | + * | |
| 1146 | + * @throws IOException | |
| 1147 | + * If some other I/O error occurs | |
| 1148 | + * | |
| 1149 | + * @see #lock() | |
| 1150 | + * @see #lock(long,long,boolean) | |
| 1151 | + * @see #tryLock(long,long,boolean) | |
| 1152 | + */ | |
| 1153 | + public final FileLock tryLock() throws IOException { | |
| 1154 | + return tryLock(0L, Long.MAX_VALUE, false); | |
| 1155 | + } | |
| 1156 | + | |
| 1157 | +} | |
Binary file not shown.
| @@ -0,0 +1,326 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels; | |
| 27 | + | |
| 28 | +import java.io.IOException; | |
| 29 | + | |
| 30 | +/** | |
| 31 | + * A token representing a lock on a region of a file. | |
| 32 | + * | |
| 33 | + * <p> A file-lock object is created each time a lock is acquired on a file via | |
| 34 | + * one of the {@link FileChannel#lock(long,long,boolean) lock} or {@link | |
| 35 | + * FileChannel#tryLock(long,long,boolean) tryLock} methods of the | |
| 36 | + * {@link FileChannel} class, or the {@link | |
| 37 | + * AsynchronousFileChannel#lock(long,long,boolean,Object,CompletionHandler) lock} | |
| 38 | + * or {@link AsynchronousFileChannel#tryLock(long,long,boolean) tryLock} | |
| 39 | + * methods of the {@link AsynchronousFileChannel} class. | |
| 40 | + * | |
| 41 | + * <p> A file-lock object is initially valid. It remains valid until the lock | |
| 42 | + * is released by invoking the {@link #release release} method, by closing the | |
| 43 | + * channel that was used to acquire it, or by the termination of the Java | |
| 44 | + * virtual machine, whichever comes first. The validity of a lock may be | |
| 45 | + * tested by invoking its {@link #isValid isValid} method. | |
| 46 | + * | |
| 47 | + * <p> A file lock is either <i>exclusive</i> or <i>shared</i>. A shared lock | |
| 48 | + * prevents other concurrently-running programs from acquiring an overlapping | |
| 49 | + * exclusive lock, but does allow them to acquire overlapping shared locks. An | |
| 50 | + * exclusive lock prevents other programs from acquiring an overlapping lock of | |
| 51 | + * either type. Once it is released, a lock has no further effect on the locks | |
| 52 | + * that may be acquired by other programs. | |
| 53 | + * | |
| 54 | + * <p> Whether a lock is exclusive or shared may be determined by invoking its | |
| 55 | + * {@link #isShared isShared} method. Some platforms do not support shared | |
| 56 | + * locks, in which case a request for a shared lock is automatically converted | |
| 57 | + * into a request for an exclusive lock. | |
| 58 | + * | |
| 59 | + * <p> The locks held on a particular file by a single Java virtual machine do | |
| 60 | + * not overlap. The {@link #overlaps overlaps} method may be used to test | |
| 61 | + * whether a candidate lock range overlaps an existing lock. | |
| 62 | + * | |
| 63 | + * <p> A file-lock object records the file channel upon whose file the lock is | |
| 64 | + * held, the type and validity of the lock, and the position and size of the | |
| 65 | + * locked region. Only the validity of a lock is subject to change over time; | |
| 66 | + * all other aspects of a lock's state are immutable. | |
| 67 | + * | |
| 68 | + * <p> File locks are held on behalf of the entire Java virtual machine. | |
| 69 | + * They are not suitable for controlling access to a file by multiple | |
| 70 | + * threads within the same virtual machine. | |
| 71 | + * | |
| 72 | + * <p> File-lock objects are safe for use by multiple concurrent threads. | |
| 73 | + * | |
| 74 | + * | |
| 75 | + * <a name="pdep"><h4> Platform dependencies </h4></a> | |
| 76 | + * | |
| 77 | + * <p> This file-locking API is intended to map directly to the native locking | |
| 78 | + * facility of the underlying operating system. Thus the locks held on a file | |
| 79 | + * should be visible to all programs that have access to the file, regardless | |
| 80 | + * of the language in which those programs are written. | |
| 81 | + * | |
| 82 | + * <p> Whether or not a lock actually prevents another program from accessing | |
| 83 | + * the content of the locked region is system-dependent and therefore | |
| 84 | + * unspecified. The native file-locking facilities of some systems are merely | |
| 85 | + * <i>advisory</i>, meaning that programs must cooperatively observe a known | |
| 86 | + * locking protocol in order to guarantee data integrity. On other systems | |
| 87 | + * native file locks are <i>mandatory</i>, meaning that if one program locks a | |
| 88 | + * region of a file then other programs are actually prevented from accessing | |
| 89 | + * that region in a way that would violate the lock. On yet other systems, | |
| 90 | + * whether native file locks are advisory or mandatory is configurable on a | |
| 91 | + * per-file basis. To ensure consistent and correct behavior across platforms, | |
| 92 | + * it is strongly recommended that the locks provided by this API be used as if | |
| 93 | + * they were advisory locks. | |
| 94 | + * | |
| 95 | + * <p> On some systems, acquiring a mandatory lock on a region of a file | |
| 96 | + * prevents that region from being {@link java.nio.channels.FileChannel#map | |
| 97 | + * <i>mapped into memory</i>}, and vice versa. Programs that combine | |
| 98 | + * locking and mapping should be prepared for this combination to fail. | |
| 99 | + * | |
| 100 | + * <p> On some systems, closing a channel releases all locks held by the Java | |
| 101 | + * virtual machine on the underlying file regardless of whether the locks were | |
| 102 | + * acquired via that channel or via another channel open on the same file. It | |
| 103 | + * is strongly recommended that, within a program, a unique channel be used to | |
| 104 | + * acquire all locks on any given file. | |
| 105 | + * | |
| 106 | + * <p> Some network filesystems permit file locking to be used with | |
| 107 | + * memory-mapped files only when the locked regions are page-aligned and a | |
| 108 | + * whole multiple of the underlying hardware's page size. Some network | |
| 109 | + * filesystems do not implement file locks on regions that extend past a | |
| 110 | + * certain position, often 2<sup>30</sup> or 2<sup>31</sup>. In general, great | |
| 111 | + * care should be taken when locking files that reside on network filesystems. | |
| 112 | + * | |
| 113 | + * | |
| 114 | + * @author Mark Reinhold | |
| 115 | + * @author JSR-51 Expert Group | |
| 116 | + * @since 1.4 | |
| 117 | + */ | |
| 118 | + | |
| 119 | +public abstract class FileLock implements AutoCloseable { | |
| 120 | + | |
| 121 | + private final Channel channel; | |
| 122 | + private final long position; | |
| 123 | + private final long size; | |
| 124 | + private final boolean shared; | |
| 125 | + | |
| 126 | + /** | |
| 127 | + * Initializes a new instance of this class. </p> | |
| 128 | + * | |
| 129 | + * @param channel | |
| 130 | + * The file channel upon whose file this lock is held | |
| 131 | + * | |
| 132 | + * @param position | |
| 133 | + * The position within the file at which the locked region starts; | |
| 134 | + * must be non-negative | |
| 135 | + * | |
| 136 | + * @param size | |
| 137 | + * The size of the locked region; must be non-negative, and the sum | |
| 138 | + * <tt>position</tt> + <tt>size</tt> must be non-negative | |
| 139 | + * | |
| 140 | + * @param shared | |
| 141 | + * <tt>true</tt> if this lock is shared, | |
| 142 | + * <tt>false</tt> if it is exclusive | |
| 143 | + * | |
| 144 | + * @throws IllegalArgumentException | |
| 145 | + * If the preconditions on the parameters do not hold | |
| 146 | + */ | |
| 147 | + protected FileLock(FileChannel channel, | |
| 148 | + long position, long size, boolean shared) | |
| 149 | + { | |
| 150 | + if (position < 0) | |
| 151 | + throw new IllegalArgumentException("Negative position"); | |
| 152 | + if (size < 0) | |
| 153 | + throw new IllegalArgumentException("Negative size"); | |
| 154 | + if (position + size < 0) | |
| 155 | + throw new IllegalArgumentException("Negative position + size"); | |
| 156 | + this.channel = channel; | |
| 157 | + this.position = position; | |
| 158 | + this.size = size; | |
| 159 | + this.shared = shared; | |
| 160 | + } | |
| 161 | + | |
| 162 | + /** | |
| 163 | + * Initializes a new instance of this class. | |
| 164 | + * | |
| 165 | + * @param channel | |
| 166 | + * The channel upon whose file this lock is held | |
| 167 | + * | |
| 168 | + * @param position | |
| 169 | + * The position within the file at which the locked region starts; | |
| 170 | + * must be non-negative | |
| 171 | + * | |
| 172 | + * @param size | |
| 173 | + * The size of the locked region; must be non-negative, and the sum | |
| 174 | + * <tt>position</tt> + <tt>size</tt> must be non-negative | |
| 175 | + * | |
| 176 | + * @param shared | |
| 177 | + * <tt>true</tt> if this lock is shared, | |
| 178 | + * <tt>false</tt> if it is exclusive | |
| 179 | + * | |
| 180 | + * @throws IllegalArgumentException | |
| 181 | + * If the preconditions on the parameters do not hold | |
| 182 | + * | |
| 183 | + * @since 1.7 | |
| 184 | + */ | |
| 185 | + protected FileLock(AsynchronousFileChannel channel, | |
| 186 | + long position, long size, boolean shared) | |
| 187 | + { | |
| 188 | + if (position < 0) | |
| 189 | + throw new IllegalArgumentException("Negative position"); | |
| 190 | + if (size < 0) | |
| 191 | + throw new IllegalArgumentException("Negative size"); | |
| 192 | + if (position + size < 0) | |
| 193 | + throw new IllegalArgumentException("Negative position + size"); | |
| 194 | + this.channel = channel; | |
| 195 | + this.position = position; | |
| 196 | + this.size = size; | |
| 197 | + this.shared = shared; | |
| 198 | + } | |
| 199 | + | |
| 200 | + /** | |
| 201 | + * Returns the file channel upon whose file this lock was acquired. | |
| 202 | + * | |
| 203 | + * <p> This method has been superseded by the {@link #acquiredBy acquiredBy} | |
| 204 | + * method. | |
| 205 | + * | |
| 206 | + * @return The file channel, or {@code null} if the file lock was not | |
| 207 | + * acquired by a file channel. | |
| 208 | + */ | |
| 209 | + public final FileChannel channel() { | |
| 210 | + return (channel instanceof FileChannel) ? (FileChannel)channel : null; | |
| 211 | + } | |
| 212 | + | |
| 213 | + /** | |
| 214 | + * Returns the channel upon whose file this lock was acquired. | |
| 215 | + * | |
| 216 | + * @return The channel upon whose file this lock was acquired. | |
| 217 | + * | |
| 218 | + * @since 1.7 | |
| 219 | + */ | |
| 220 | + public Channel acquiredBy() { | |
| 221 | + return channel; | |
| 222 | + } | |
| 223 | + | |
| 224 | + /** | |
| 225 | + * Returns the position within the file of the first byte of the locked | |
| 226 | + * region. | |
| 227 | + * | |
| 228 | + * <p> A locked region need not be contained within, or even overlap, the | |
| 229 | + * actual underlying file, so the value returned by this method may exceed | |
| 230 | + * the file's current size. </p> | |
| 231 | + * | |
| 232 | + * @return The position | |
| 233 | + */ | |
| 234 | + public final long position() { | |
| 235 | + return position; | |
| 236 | + } | |
| 237 | + | |
| 238 | + /** | |
| 239 | + * Returns the size of the locked region in bytes. | |
| 240 | + * | |
| 241 | + * <p> A locked region need not be contained within, or even overlap, the | |
| 242 | + * actual underlying file, so the value returned by this method may exceed | |
| 243 | + * the file's current size. </p> | |
| 244 | + * | |
| 245 | + * @return The size of the locked region | |
| 246 | + */ | |
| 247 | + public final long size() { | |
| 248 | + return size; | |
| 249 | + } | |
| 250 | + | |
| 251 | + /** | |
| 252 | + * Tells whether this lock is shared. </p> | |
| 253 | + * | |
| 254 | + * @return <tt>true</tt> if lock is shared, | |
| 255 | + * <tt>false</tt> if it is exclusive | |
| 256 | + */ | |
| 257 | + public final boolean isShared() { | |
| 258 | + return shared; | |
| 259 | + } | |
| 260 | + | |
| 261 | + /** | |
| 262 | + * Tells whether or not this lock overlaps the given lock range. </p> | |
| 263 | + * | |
| 264 | + * @return <tt>true</tt> if, and only if, this lock and the given lock | |
| 265 | + * range overlap by at least one byte | |
| 266 | + */ | |
| 267 | + public final boolean overlaps(long position, long size) { | |
| 268 | + if (position + size <= this.position) | |
| 269 | + return false; // That is below this | |
| 270 | + if (this.position + this.size <= position) | |
| 271 | + return false; // This is below that | |
| 272 | + return true; | |
| 273 | + } | |
| 274 | + | |
| 275 | + /** | |
| 276 | + * Tells whether or not this lock is valid. | |
| 277 | + * | |
| 278 | + * <p> A lock object remains valid until it is released or the associated | |
| 279 | + * file channel is closed, whichever comes first. </p> | |
| 280 | + * | |
| 281 | + * @return <tt>true</tt> if, and only if, this lock is valid | |
| 282 | + */ | |
| 283 | + public abstract boolean isValid(); | |
| 284 | + | |
| 285 | + /** | |
| 286 | + * Releases this lock. | |
| 287 | + * | |
| 288 | + * <p> If this lock object is valid then invoking this method releases the | |
| 289 | + * lock and renders the object invalid. If this lock object is invalid | |
| 290 | + * then invoking this method has no effect. </p> | |
| 291 | + * | |
| 292 | + * @throws ClosedChannelException | |
| 293 | + * If the channel that was used to acquire this lock | |
| 294 | + * is no longer open | |
| 295 | + * | |
| 296 | + * @throws IOException | |
| 297 | + * If an I/O error occurs | |
| 298 | + */ | |
| 299 | + public abstract void release() throws IOException; | |
| 300 | + | |
| 301 | + /** | |
| 302 | + * This method invokes the {@link #release} method. It was added | |
| 303 | + * to the class so that it could be used in conjunction with the | |
| 304 | + * automatic resource management block construct. | |
| 305 | + * | |
| 306 | + * @since 1.7 | |
| 307 | + */ | |
| 308 | + public final void close() throws IOException { | |
| 309 | + release(); | |
| 310 | + } | |
| 311 | + | |
| 312 | + /** | |
| 313 | + * Returns a string describing the range, type, and validity of this lock. | |
| 314 | + * | |
| 315 | + * @return A descriptive string | |
| 316 | + */ | |
| 317 | + public final String toString() { | |
| 318 | + return (this.getClass().getName() | |
| 319 | + + "[" + position | |
| 320 | + + ":" + size | |
| 321 | + + " " + (shared ? "shared" : "exclusive") | |
| 322 | + + " " + (isValid() ? "valid" : "invalid") | |
| 323 | + + "]"); | |
| 324 | + } | |
| 325 | + | |
| 326 | +} | |
Binary file not shown.
| @@ -0,0 +1,166 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels; | |
| 27 | + | |
| 28 | +import java.io.IOException; | |
| 29 | +import java.nio.ByteBuffer; | |
| 30 | + | |
| 31 | + | |
| 32 | +/** | |
| 33 | + * A channel that can write bytes from a sequence of buffers. | |
| 34 | + * | |
| 35 | + * <p> A <i>gathering</i> write operation writes, in a single invocation, a | |
| 36 | + * sequence of bytes from one or more of a given sequence of buffers. | |
| 37 | + * Gathering writes are often useful when implementing network protocols or | |
| 38 | + * file formats that, for example, group data into segments consisting of one | |
| 39 | + * or more fixed-length headers followed by a variable-length body. Similar | |
| 40 | + * <i>scattering</i> read operations are defined in the {@link | |
| 41 | + * ScatteringByteChannel} interface. </p> | |
| 42 | + * | |
| 43 | + * | |
| 44 | + * @author Mark Reinhold | |
| 45 | + * @author JSR-51 Expert Group | |
| 46 | + * @since 1.4 | |
| 47 | + */ | |
| 48 | + | |
| 49 | +public interface GatheringByteChannel | |
| 50 | + extends WritableByteChannel | |
| 51 | +{ | |
| 52 | + | |
| 53 | + /** | |
| 54 | + * Writes a sequence of bytes to this channel from a subsequence of the | |
| 55 | + * given buffers. | |
| 56 | + * | |
| 57 | + * <p> An attempt is made to write up to <i>r</i> bytes to this channel, | |
| 58 | + * where <i>r</i> is the total number of bytes remaining in the specified | |
| 59 | + * subsequence of the given buffer array, that is, | |
| 60 | + * | |
| 61 | + * <blockquote><pre> | |
| 62 | + * srcs[offset].remaining() | |
| 63 | + * + srcs[offset+1].remaining() | |
| 64 | + * + ... + srcs[offset+length-1].remaining()</pre></blockquote> | |
| 65 | + * | |
| 66 | + * at the moment that this method is invoked. | |
| 67 | + * | |
| 68 | + * <p> Suppose that a byte sequence of length <i>n</i> is written, where | |
| 69 | + * <tt>0</tt> <tt><=</tt> <i>n</i> <tt><=</tt> <i>r</i>. | |
| 70 | + * Up to the first <tt>srcs[offset].remaining()</tt> bytes of this sequence | |
| 71 | + * are written from buffer <tt>srcs[offset]</tt>, up to the next | |
| 72 | + * <tt>srcs[offset+1].remaining()</tt> bytes are written from buffer | |
| 73 | + * <tt>srcs[offset+1]</tt>, and so forth, until the entire byte sequence is | |
| 74 | + * written. As many bytes as possible are written from each buffer, hence | |
| 75 | + * the final position of each updated buffer, except the last updated | |
| 76 | + * buffer, is guaranteed to be equal to that buffer's limit. | |
| 77 | + * | |
| 78 | + * <p> Unless otherwise specified, a write operation will return only after | |
| 79 | + * writing all of the <i>r</i> requested bytes. Some types of channels, | |
| 80 | + * depending upon their state, may write only some of the bytes or possibly | |
| 81 | + * none at all. A socket channel in non-blocking mode, for example, cannot | |
| 82 | + * write any more bytes than are free in the socket's output buffer. | |
| 83 | + * | |
| 84 | + * <p> This method may be invoked at any time. If another thread has | |
| 85 | + * already initiated a write operation upon this channel, however, then an | |
| 86 | + * invocation of this method will block until the first operation is | |
| 87 | + * complete. </p> | |
| 88 | + * | |
| 89 | + * @param srcs | |
| 90 | + * The buffers from which bytes are to be retrieved | |
| 91 | + * | |
| 92 | + * @param offset | |
| 93 | + * The offset within the buffer array of the first buffer from | |
| 94 | + * which bytes are to be retrieved; must be non-negative and no | |
| 95 | + * larger than <tt>srcs.length</tt> | |
| 96 | + * | |
| 97 | + * @param length | |
| 98 | + * The maximum number of buffers to be accessed; must be | |
| 99 | + * non-negative and no larger than | |
| 100 | + * <tt>srcs.length</tt> - <tt>offset</tt> | |
| 101 | + * | |
| 102 | + * @return The number of bytes written, possibly zero | |
| 103 | + * | |
| 104 | + * @throws IndexOutOfBoundsException | |
| 105 | + * If the preconditions on the <tt>offset</tt> and <tt>length</tt> | |
| 106 | + * parameters do not hold | |
| 107 | + * | |
| 108 | + * @throws NonWritableChannelException | |
| 109 | + * If this channel was not opened for writing | |
| 110 | + * | |
| 111 | + * @throws ClosedChannelException | |
| 112 | + * If this channel is closed | |
| 113 | + * | |
| 114 | + * @throws AsynchronousCloseException | |
| 115 | + * If another thread closes this channel | |
| 116 | + * while the write operation is in progress | |
| 117 | + * | |
| 118 | + * @throws ClosedByInterruptException | |
| 119 | + * If another thread interrupts the current thread | |
| 120 | + * while the write operation is in progress, thereby | |
| 121 | + * closing the channel and setting the current thread's | |
| 122 | + * interrupt status | |
| 123 | + * | |
| 124 | + * @throws IOException | |
| 125 | + * If some other I/O error occurs | |
| 126 | + */ | |
| 127 | + public long write(ByteBuffer[] srcs, int offset, int length) | |
| 128 | + throws IOException; | |
| 129 | + | |
| 130 | + | |
| 131 | + /** | |
| 132 | + * Writes a sequence of bytes to this channel from the given buffers. | |
| 133 | + * | |
| 134 | + * <p> An invocation of this method of the form <tt>c.write(srcs)</tt> | |
| 135 | + * behaves in exactly the same manner as the invocation | |
| 136 | + * | |
| 137 | + * <blockquote><pre> | |
| 138 | + * c.write(srcs, 0, srcs.length);</pre></blockquote> | |
| 139 | + * | |
| 140 | + * @param srcs | |
| 141 | + * The buffers from which bytes are to be retrieved | |
| 142 | + * | |
| 143 | + * @return The number of bytes written, possibly zero | |
| 144 | + * | |
| 145 | + * @throws NonWritableChannelException | |
| 146 | + * If this channel was not opened for writing | |
| 147 | + * | |
| 148 | + * @throws ClosedChannelException | |
| 149 | + * If this channel is closed | |
| 150 | + * | |
| 151 | + * @throws AsynchronousCloseException | |
| 152 | + * If another thread closes this channel | |
| 153 | + * while the write operation is in progress | |
| 154 | + * | |
| 155 | + * @throws ClosedByInterruptException | |
| 156 | + * If another thread interrupts the current thread | |
| 157 | + * while the write operation is in progress, thereby | |
| 158 | + * closing the channel and setting the current thread's | |
| 159 | + * interrupt status | |
| 160 | + * | |
| 161 | + * @throws IOException | |
| 162 | + * If some other I/O error occurs | |
| 163 | + */ | |
| 164 | + public long write(ByteBuffer[] srcs) throws IOException; | |
| 165 | + | |
| 166 | +} | |
Binary file not shown.
| @@ -0,0 +1,82 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +/* | |
| 27 | + */ | |
| 28 | + | |
| 29 | +package java.nio.channels; | |
| 30 | + | |
| 31 | +import java.io.IOException; | |
| 32 | + | |
| 33 | + | |
| 34 | +/** | |
| 35 | + * A channel that can be asynchronously closed and interrupted. | |
| 36 | + * | |
| 37 | + * <p> A channel that implements this interface is <i>asynchronously | |
| 38 | + * closeable:</i> If a thread is blocked in an I/O operation on an | |
| 39 | + * interruptible channel then another thread may invoke the channel's {@link | |
| 40 | + * #close close} method. This will cause the blocked thread to receive an | |
| 41 | + * {@link AsynchronousCloseException}. | |
| 42 | + * | |
| 43 | + * <p> A channel that implements this interface is also <i>interruptible:</i> | |
| 44 | + * If a thread is blocked in an I/O operation on an interruptible channel then | |
| 45 | + * another thread may invoke the blocked thread's {@link Thread#interrupt() | |
| 46 | + * interrupt} method. This will cause the channel to be closed, the blocked | |
| 47 | + * thread to receive a {@link ClosedByInterruptException}, and the blocked | |
| 48 | + * thread's interrupt status to be set. | |
| 49 | + * | |
| 50 | + * <p> If a thread's interrupt status is already set and it invokes a blocking | |
| 51 | + * I/O operation upon a channel then the channel will be closed and the thread | |
| 52 | + * will immediately receive a {@link ClosedByInterruptException}; its interrupt | |
| 53 | + * status will remain set. | |
| 54 | + * | |
| 55 | + * <p> A channel supports asynchronous closing and interruption if, and only | |
| 56 | + * if, it implements this interface. This can be tested at runtime, if | |
| 57 | + * necessary, via the <tt>instanceof</tt> operator. | |
| 58 | + * | |
| 59 | + * | |
| 60 | + * @author Mark Reinhold | |
| 61 | + * @author JSR-51 Expert Group | |
| 62 | + * @since 1.4 | |
| 63 | + */ | |
| 64 | + | |
| 65 | +public interface InterruptibleChannel | |
| 66 | + extends Channel | |
| 67 | +{ | |
| 68 | + | |
| 69 | + /** | |
| 70 | + * Closes this channel. | |
| 71 | + * | |
| 72 | + * <p> Any thread currently blocked in an I/O operation upon this channel | |
| 73 | + * will receive an {@link AsynchronousCloseException}. | |
| 74 | + * | |
| 75 | + * <p> This method otherwise behaves exactly as specified by the {@link | |
| 76 | + * Channel#close Channel} interface. </p> | |
| 77 | + * | |
| 78 | + * @throws IOException If an I/O error occurs | |
| 79 | + */ | |
| 80 | + public void close() throws IOException; | |
| 81 | + | |
| 82 | +} | |
Binary file not shown.
| @@ -0,0 +1,177 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels; | |
| 27 | + | |
| 28 | +import java.net.InetAddress; | |
| 29 | +import java.net.NetworkInterface; | |
| 30 | +import java.io.IOException; | |
| 31 | + | |
| 32 | +/** | |
| 33 | + * A token representing the membership of an Internet Protocol (IP) multicast | |
| 34 | + * group. | |
| 35 | + * | |
| 36 | + * <p> A membership key may represent a membership to receive all datagrams sent | |
| 37 | + * to the group, or it may be <em>source-specific</em>, meaning that it | |
| 38 | + * represents a membership that receives only datagrams from a specific source | |
| 39 | + * address. Whether or not a membership key is source-specific may be determined | |
| 40 | + * by invoking its {@link #sourceAddress() sourceAddress} method. | |
| 41 | + * | |
| 42 | + * <p> A membership key is valid upon creation and remains valid until the | |
| 43 | + * membership is dropped by invoking the {@link #drop() drop} method, or | |
| 44 | + * the channel is closed. The validity of the membership key may be tested | |
| 45 | + * by invoking its {@link #isValid() isValid} method. | |
| 46 | + * | |
| 47 | + * <p> Where a membership key is not source-specific and the underlying operation | |
| 48 | + * system supports source filtering, then the {@link #block block} and {@link | |
| 49 | + * #unblock unblock} methods can be used to block or unblock multicast datagrams | |
| 50 | + * from particular source addresses. | |
| 51 | + * | |
| 52 | + * @see MulticastChannel | |
| 53 | + * | |
| 54 | + * @since 1.7 | |
| 55 | + */ | |
| 56 | +public abstract class MembershipKey { | |
| 57 | + | |
| 58 | + /** | |
| 59 | + * Initializes a new instance of this class. | |
| 60 | + */ | |
| 61 | + protected MembershipKey() { | |
| 62 | + } | |
| 63 | + | |
| 64 | + /** | |
| 65 | + * Tells whether or not this membership is valid. | |
| 66 | + * | |
| 67 | + * <p> A multicast group membership is valid upon creation and remains | |
| 68 | + * valid until the membership is dropped by invoking the {@link #drop() drop} | |
| 69 | + * method, or the channel is closed. | |
| 70 | + * | |
| 71 | + * @return {@code true} if this membership key is valid, {@code false} | |
| 72 | + * otherwise | |
| 73 | + */ | |
| 74 | + public abstract boolean isValid(); | |
| 75 | + | |
| 76 | + /** | |
| 77 | + * Drop membership. | |
| 78 | + * | |
| 79 | + * <p> If the membership key represents a membership to receive all datagrams | |
| 80 | + * then the membership is dropped and the channel will no longer receive any | |
| 81 | + * datagrams sent to the group. If the membership key is source-specific | |
| 82 | + * then the channel will no longer receive datagrams sent to the group from | |
| 83 | + * that source address. | |
| 84 | + * | |
| 85 | + * <p> After membership is dropped it may still be possible to receive | |
| 86 | + * datagrams sent to the group. This can arise when datagrams are waiting to | |
| 87 | + * be received in the socket's receive buffer. After membership is dropped | |
| 88 | + * then the channel may {@link MulticastChannel#join join} the group again | |
| 89 | + * in which case a new membership key is returned. | |
| 90 | + * | |
| 91 | + * <p> Upon return, this membership object will be {@link #isValid() invalid}. | |
| 92 | + * If the multicast group membership is already invalid then invoking this | |
| 93 | + * method has no effect. Once a multicast group membership is invalid, | |
| 94 | + * it remains invalid forever. | |
| 95 | + */ | |
| 96 | + public abstract void drop(); | |
| 97 | + | |
| 98 | + /** | |
| 99 | + * Block multicast datagrams from the given source address. | |
| 100 | + * | |
| 101 | + * <p> If this membership key is not source-specific, and the underlying | |
| 102 | + * operating system supports source filtering, then this method blocks | |
| 103 | + * multicast datagrams from the given source address. If the given source | |
| 104 | + * address is already blocked then this method has no effect. | |
| 105 | + * After a source address is blocked it may still be possible to receive | |
| 106 | + * datagams from that source. This can arise when datagrams are waiting to | |
| 107 | + * be received in the socket's receive buffer. | |
| 108 | + * | |
| 109 | + * @param source | |
| 110 | + * The source address to block | |
| 111 | + * | |
| 112 | + * @return This membership key | |
| 113 | + * | |
| 114 | + * @throws IllegalArgumentException | |
| 115 | + * If the {@code source} parameter is not a unicast address or | |
| 116 | + * is not the same address type as the multicast group | |
| 117 | + * @throws IllegalStateException | |
| 118 | + * If this membership key is source-specific or is no longer valid | |
| 119 | + * @throws UnsupportedOperationException | |
| 120 | + * If the underlying operating system does not support source | |
| 121 | + * filtering | |
| 122 | + * @throws IOException | |
| 123 | + * If an I/O error occurs | |
| 124 | + */ | |
| 125 | + public abstract MembershipKey block(InetAddress source) throws IOException; | |
| 126 | + | |
| 127 | + /** | |
| 128 | + * Unblock multicast datagrams from the given source address that was | |
| 129 | + * previously blocked using the {@link #block(InetAddress) block} method. | |
| 130 | + * | |
| 131 | + * @param source | |
| 132 | + * The source address to unblock | |
| 133 | + * | |
| 134 | + * @return This membership key | |
| 135 | + * | |
| 136 | + * @throws IllegalStateException | |
| 137 | + * If the given source address is not currently blocked or the | |
| 138 | + * membership key is no longer valid | |
| 139 | + */ | |
| 140 | + public abstract MembershipKey unblock(InetAddress source); | |
| 141 | + | |
| 142 | + /** | |
| 143 | + * Returns the channel for which this membership key was created. This | |
| 144 | + * method will continue to return the channel even after the membership | |
| 145 | + * becomes {@link #isValid invalid}. | |
| 146 | + * | |
| 147 | + * @return the channel | |
| 148 | + */ | |
| 149 | + public abstract MulticastChannel channel(); | |
| 150 | + | |
| 151 | + /** | |
| 152 | + * Returns the multicast group for which this membership key was created. | |
| 153 | + * This method will continue to return the group even after the membership | |
| 154 | + * becomes {@link #isValid invalid}. | |
| 155 | + * | |
| 156 | + * @return the multicast group | |
| 157 | + */ | |
| 158 | + public abstract InetAddress group(); | |
| 159 | + | |
| 160 | + /** | |
| 161 | + * Returns the network interface for which this membership key was created. | |
| 162 | + * This method will continue to return the network interface even after the | |
| 163 | + * membership becomes {@link #isValid invalid}. | |
| 164 | + * | |
| 165 | + * @return the network interface | |
| 166 | + */ | |
| 167 | + public abstract NetworkInterface networkInterface(); | |
| 168 | + | |
| 169 | + /** | |
| 170 | + * Returns the source address if this membership key is source-specific, | |
| 171 | + * or {@code null} if this membership is not source-specific. | |
| 172 | + * | |
| 173 | + * @return The source address if this membership key is source-specific, | |
| 174 | + * otherwise {@code null} | |
| 175 | + */ | |
| 176 | + public abstract InetAddress sourceAddress(); | |
| 177 | +} | |
Binary file not shown.
| @@ -0,0 +1,230 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels; | |
| 27 | + | |
| 28 | +import java.net.InetAddress; | |
| 29 | +import java.net.NetworkInterface; | |
| 30 | +import java.io.IOException; | |
| 31 | +import java.net.ProtocolFamily; // javadoc | |
| 32 | +import java.net.StandardProtocolFamily; // javadoc | |
| 33 | +import java.net.StandardSocketOptions; // javadoc | |
| 34 | + | |
| 35 | +/** | |
| 36 | + * A network channel that supports Internet Protocol (IP) multicasting. | |
| 37 | + * | |
| 38 | + * <p> IP multicasting is the transmission of IP datagrams to members of | |
| 39 | + * a <em>group</em> that is zero or more hosts identified by a single destination | |
| 40 | + * address. | |
| 41 | + * | |
| 42 | + * <p> In the case of a channel to an {@link StandardProtocolFamily#INET IPv4} socket, | |
| 43 | + * the underlying operating system supports <a href="http://www.ietf.org/rfc/rfc2236.txt"> | |
| 44 | + * <i>RFC 2236: Internet Group Management Protocol, Version 2 (IGMPv2)</i></a>. | |
| 45 | + * It may optionally support source filtering as specified by <a | |
| 46 | + * href="http://www.ietf.org/rfc/rfc3376.txt"> <i>RFC 3376: Internet Group | |
| 47 | + * Management Protocol, Version 3 (IGMPv3)</i></a>. | |
| 48 | + * For channels to an {@link StandardProtocolFamily#INET6 IPv6} socket, the equivalent | |
| 49 | + * standards are <a href="http://www.ietf.org/rfc/rfc2710.txt"> <i>RFC 2710: | |
| 50 | + * Multicast Listener Discovery (MLD) for IPv6</i></a> and <a | |
| 51 | + * href="http://www.ietf.org/rfc/rfc3810.txt"> <i>RFC 3810: Multicast Listener | |
| 52 | + * Discovery Version 2 (MLDv2) for IPv6</i></a>. | |
| 53 | + * | |
| 54 | + * <p> The {@link #join(InetAddress,NetworkInterface)} method is used to | |
| 55 | + * join a group and receive all multicast datagrams sent to the group. A channel | |
| 56 | + * may join several multicast groups and may join the same group on several | |
| 57 | + * {@link NetworkInterface interfaces}. Membership is dropped by invoking the {@link | |
| 58 | + * MembershipKey#drop drop} method on the returned {@link MembershipKey}. If the | |
| 59 | + * underlying platform supports source filtering then the {@link MembershipKey#block | |
| 60 | + * block} and {@link MembershipKey#unblock unblock} methods can be used to block or | |
| 61 | + * unblock multicast datagrams from particular source addresses. | |
| 62 | + * | |
| 63 | + * <p> The {@link #join(InetAddress,NetworkInterface,InetAddress)} method | |
| 64 | + * is used to begin receiving datagrams sent to a group whose source address matches | |
| 65 | + * a given source address. This method throws {@link UnsupportedOperationException} | |
| 66 | + * if the underlying platform does not support source filtering. Membership is | |
| 67 | + * <em>cumulative</em> and this method may be invoked again with the same group | |
| 68 | + * and interface to allow receiving datagrams from other source addresses. The | |
| 69 | + * method returns a {@link MembershipKey} that represents membership to receive | |
| 70 | + * datagrams from the given source address. Invoking the key's {@link | |
| 71 | + * MembershipKey#drop drop} method drops membership so that datagrams from the | |
| 72 | + * source address can no longer be received. | |
| 73 | + * | |
| 74 | + * <h4>Platform dependencies</h4> | |
| 75 | + * | |
| 76 | + * The multicast implementation is intended to map directly to the native | |
| 77 | + * multicasting facility. Consequently, the following items should be considered | |
| 78 | + * when developing an application that receives IP multicast datagrams: | |
| 79 | + * | |
| 80 | + * <ol> | |
| 81 | + * | |
| 82 | + * <li><p> The creation of the channel should specify the {@link ProtocolFamily} | |
| 83 | + * that corresponds to the address type of the multicast groups that the channel | |
| 84 | + * will join. There is no guarantee that a channel to a socket in one protocol | |
| 85 | + * family can join and receive multicast datagrams when the address of the | |
| 86 | + * multicast group corresponds to another protocol family. For example, it is | |
| 87 | + * implementation specific if a channel to an {@link StandardProtocolFamily#INET6 IPv6} | |
| 88 | + * socket can join an {@link StandardProtocolFamily#INET IPv4} multicast group and receive | |
| 89 | + * multicast datagrams sent to the group. </p></li> | |
| 90 | + * | |
| 91 | + * <li><p> The channel's socket should be bound to the {@link | |
| 92 | + * InetAddress#isAnyLocalAddress wildcard} address. If the socket is bound to | |
| 93 | + * a specific address, rather than the wildcard address then it is implementation | |
| 94 | + * specific if multicast datagrams are received by the socket. </p></li> | |
| 95 | + * | |
| 96 | + * <li><p> The {@link StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} option should be | |
| 97 | + * enabled prior to {@link NetworkChannel#bind binding} the socket. This is | |
| 98 | + * required to allow multiple members of the group to bind to the same | |
| 99 | + * address. </p></li> | |
| 100 | + * | |
| 101 | + * </ol> | |
| 102 | + * | |
| 103 | + * <p> <b>Usage Example:</b> | |
| 104 | + * <pre> | |
| 105 | + * // join multicast group on this interface, and also use this | |
| 106 | + * // interface for outgoing multicast datagrams | |
| 107 | + * NetworkInterface ni = NetworkInterface.getByName("hme0"); | |
| 108 | + * | |
| 109 | + * DatagramChannel dc = DatagramChannel.open(StandardProtocolFamily.INET) | |
| 110 | + * .setOption(StandardSocketOptions.SO_REUSEADDR, true) | |
| 111 | + * .bind(new InetSocketAddress(5000)) | |
| 112 | + * .setOption(StandardSocketOptions.IP_MULTICAST_IF, ni); | |
| 113 | + * | |
| 114 | + * InetAddress group = InetAddress.getByName("225.4.5.6"); | |
| 115 | + * | |
| 116 | + * MembershipKey key = dc.join(group, ni); | |
| 117 | + * </pre> | |
| 118 | + * | |
| 119 | + * @since 1.7 | |
| 120 | + */ | |
| 121 | + | |
| 122 | +public interface MulticastChannel | |
| 123 | + extends NetworkChannel | |
| 124 | +{ | |
| 125 | + /** | |
| 126 | + * Closes this channel. | |
| 127 | + * | |
| 128 | + * <p> If the channel is a member of a multicast group then the membership | |
| 129 | + * is {@link MembershipKey#drop dropped}. Upon return, the {@link | |
| 130 | + * MembershipKey membership-key} will be {@link MembershipKey#isValid | |
| 131 | + * invalid}. | |
| 132 | + * | |
| 133 | + * <p> This method otherwise behaves exactly as specified by the {@link | |
| 134 | + * Channel} interface. | |
| 135 | + * | |
| 136 | + * @throws IOException | |
| 137 | + * If an I/O error occurs | |
| 138 | + */ | |
| 139 | + @Override void close() throws IOException; | |
| 140 | + | |
| 141 | + /** | |
| 142 | + * Joins a multicast group to begin receiving all datagrams sent to the group, | |
| 143 | + * returning a membership key. | |
| 144 | + * | |
| 145 | + * <p> If this channel is currently a member of the group on the given | |
| 146 | + * interface to receive all datagrams then the membership key, representing | |
| 147 | + * that membership, is returned. Otherwise this channel joins the group and | |
| 148 | + * the resulting new membership key is returned. The resulting membership key | |
| 149 | + * is not {@link MembershipKey#sourceAddress source-specific}. | |
| 150 | + * | |
| 151 | + * <p> A multicast channel may join several multicast groups, including | |
| 152 | + * the same group on more than one interface. An implementation may impose a | |
| 153 | + * limit on the number of groups that may be joined at the same time. | |
| 154 | + * | |
| 155 | + * @param group | |
| 156 | + * The multicast address to join | |
| 157 | + * @param interf | |
| 158 | + * The network interface on which to join the group | |
| 159 | + * | |
| 160 | + * @return The membership key | |
| 161 | + * | |
| 162 | + * @throws IllegalArgumentException | |
| 163 | + * If the group parameter is not a {@link InetAddress#isMulticastAddress | |
| 164 | + * multicast} address, or the group parameter is an address type | |
| 165 | + * that is not supported by this channel | |
| 166 | + * @throws IllegalStateException | |
| 167 | + * If the channel already has source-specific membership of the | |
| 168 | + * group on the interface | |
| 169 | + * @throws UnsupportedOperationException | |
| 170 | + * If the channel's socket is not an Internet Protocol socket | |
| 171 | + * @throws ClosedChannelException | |
| 172 | + * If this channel is closed | |
| 173 | + * @throws IOException | |
| 174 | + * If an I/O error occurs | |
| 175 | + * @throws SecurityException | |
| 176 | + * If a security manager is set, and its | |
| 177 | + * {@link SecurityManager#checkMulticast(InetAddress) checkMulticast} | |
| 178 | + * method denies access to the multiast group | |
| 179 | + */ | |
| 180 | + MembershipKey join(InetAddress group, NetworkInterface interf) | |
| 181 | + throws IOException; | |
| 182 | + | |
| 183 | + /** | |
| 184 | + * Joins a multicast group to begin receiving datagrams sent to the group | |
| 185 | + * from a given source address. | |
| 186 | + * | |
| 187 | + * <p> If this channel is currently a member of the group on the given | |
| 188 | + * interface to receive datagrams from the given source address then the | |
| 189 | + * membership key, representing that membership, is returned. Otherwise this | |
| 190 | + * channel joins the group and the resulting new membership key is returned. | |
| 191 | + * The resulting membership key is {@link MembershipKey#sourceAddress | |
| 192 | + * source-specific}. | |
| 193 | + * | |
| 194 | + * <p> Membership is <em>cumulative</em> and this method may be invoked | |
| 195 | + * again with the same group and interface to allow receiving datagrams sent | |
| 196 | + * by other source addresses to the group. | |
| 197 | + * | |
| 198 | + * @param group | |
| 199 | + * The multicast address to join | |
| 200 | + * @param interf | |
| 201 | + * The network interface on which to join the group | |
| 202 | + * @param source | |
| 203 | + * The source address | |
| 204 | + * | |
| 205 | + * @return The membership key | |
| 206 | + * | |
| 207 | + * @throws IllegalArgumentException | |
| 208 | + * If the group parameter is not a {@link | |
| 209 | + * InetAddress#isMulticastAddress multicast} address, the | |
| 210 | + * source parameter is not a unicast address, the group | |
| 211 | + * parameter is an address type that is not supported by this channel, | |
| 212 | + * or the source parameter is not the same address type as the group | |
| 213 | + * @throws IllegalStateException | |
| 214 | + * If the channel is currently a member of the group on the given | |
| 215 | + * interface to receive all datagrams | |
| 216 | + * @throws UnsupportedOperationException | |
| 217 | + * If the channel's socket is not an Internet Protocol socket or | |
| 218 | + * source filtering is not supported | |
| 219 | + * @throws ClosedChannelException | |
| 220 | + * If this channel is closed | |
| 221 | + * @throws IOException | |
| 222 | + * If an I/O error occurs | |
| 223 | + * @throws SecurityException | |
| 224 | + * If a security manager is set, and its | |
| 225 | + * {@link SecurityManager#checkMulticast(InetAddress) checkMulticast} | |
| 226 | + * method denies access to the multiast group | |
| 227 | + */ | |
| 228 | + MembershipKey join(InetAddress group, NetworkInterface interf, InetAddress source) | |
| 229 | + throws IOException; | |
| 230 | +} | |
Binary file not shown.
| @@ -0,0 +1,160 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels; | |
| 27 | + | |
| 28 | +import java.net.SocketOption; | |
| 29 | +import java.net.SocketAddress; | |
| 30 | +import java.util.Set; | |
| 31 | +import java.io.IOException; | |
| 32 | + | |
| 33 | +/** | |
| 34 | + * A channel to a network socket. | |
| 35 | + * | |
| 36 | + * <p> A channel that implements this interface is a channel to a network | |
| 37 | + * socket. The {@link #bind(SocketAddress) bind} method is used to bind the | |
| 38 | + * socket to a local {@link SocketAddress address}, the {@link #getLocalAddress() | |
| 39 | + * getLocalAddress} method returns the address that the socket is bound to, and | |
| 40 | + * the {@link #setOption(SocketOption,Object) setOption} and {@link | |
| 41 | + * #getOption(SocketOption) getOption} methods are used to set and query socket | |
| 42 | + * options. An implementation of this interface should specify the socket options | |
| 43 | + * that it supports. | |
| 44 | + * | |
| 45 | + * <p> The {@link #bind bind} and {@link #setOption setOption} methods that do | |
| 46 | + * not otherwise have a value to return are specified to return the network | |
| 47 | + * channel upon which they are invoked. This allows method invocations to be | |
| 48 | + * chained. Implementations of this interface should specialize the return type | |
| 49 | + * so that method invocations on the implementation class can be chained. | |
| 50 | + * | |
| 51 | + * @since 1.7 | |
| 52 | + */ | |
| 53 | + | |
| 54 | +public interface NetworkChannel | |
| 55 | + extends Channel | |
| 56 | +{ | |
| 57 | + /** | |
| 58 | + * Binds the channel's socket to a local address. | |
| 59 | + * | |
| 60 | + * <p> This method is used to establish an association between the socket and | |
| 61 | + * a local address. Once an association is established then the socket remains | |
| 62 | + * bound until the channel is closed. If the {@code local} parameter has the | |
| 63 | + * value {@code null} then the socket will be bound to an address that is | |
| 64 | + * assigned automatically. | |
| 65 | + * | |
| 66 | + * @param local | |
| 67 | + * The address to bind the socket, or {@code null} to bind the socket | |
| 68 | + * to an automatically assigned socket address | |
| 69 | + * | |
| 70 | + * @return This channel | |
| 71 | + * | |
| 72 | + * @throws AlreadyBoundException | |
| 73 | + * If the socket is already bound | |
| 74 | + * @throws UnsupportedAddressTypeException | |
| 75 | + * If the type of the given address is not supported | |
| 76 | + * @throws ClosedChannelException | |
| 77 | + * If the channel is closed | |
| 78 | + * @throws IOException | |
| 79 | + * If some other I/O error occurs | |
| 80 | + * @throws SecurityException | |
| 81 | + * If a security manager is installed and it denies an unspecified | |
| 82 | + * permission. An implementation of this interface should specify | |
| 83 | + * any required permissions. | |
| 84 | + * | |
| 85 | + * @see #getLocalAddress | |
| 86 | + */ | |
| 87 | + NetworkChannel bind(SocketAddress local) throws IOException; | |
| 88 | + | |
| 89 | + /** | |
| 90 | + * Returns the socket address that this channel's socket is bound to, or | |
| 91 | + * {@code null} if the socket is not bound. | |
| 92 | + * | |
| 93 | + * <p> Where the channel is {@link #bind bound} to an Internet Protocol | |
| 94 | + * socket address then the return value from this method is of type {@link | |
| 95 | + * java.net.InetSocketAddress}. | |
| 96 | + * | |
| 97 | + * @return The socket address that the socket is bound to, or {@code null} | |
| 98 | + * if the channel's socket is not bound | |
| 99 | + * | |
| 100 | + * @throws ClosedChannelException | |
| 101 | + * If the channel is closed | |
| 102 | + * @throws IOException | |
| 103 | + * If an I/O error occurs | |
| 104 | + */ | |
| 105 | + SocketAddress getLocalAddress() throws IOException; | |
| 106 | + | |
| 107 | + /** | |
| 108 | + * Sets the value of a socket option. | |
| 109 | + * | |
| 110 | + * @param name | |
| 111 | + * The socket option | |
| 112 | + * @param value | |
| 113 | + * The value of the socket option. A value of {@code null} may be | |
| 114 | + * a valid value for some socket options. | |
| 115 | + * | |
| 116 | + * @return This channel | |
| 117 | + * | |
| 118 | + * @throws UnsupportedOperationException | |
| 119 | + * If the socket option is not supported by this channel | |
| 120 | + * @throws IllegalArgumentException | |
| 121 | + * If the value is not a valid value for this socket option | |
| 122 | + * @throws ClosedChannelException | |
| 123 | + * If this channel is closed | |
| 124 | + * @throws IOException | |
| 125 | + * If an I/O error occurs | |
| 126 | + * | |
| 127 | + * @see java.net.StandardSocketOptions | |
| 128 | + */ | |
| 129 | + <T> NetworkChannel setOption(SocketOption<T> name, T value) throws IOException; | |
| 130 | + | |
| 131 | + /** | |
| 132 | + * Returns the value of a socket option. | |
| 133 | + * | |
| 134 | + * @param name | |
| 135 | + * The socket option | |
| 136 | + * | |
| 137 | + * @return The value of the socket option. A value of {@code null} may be | |
| 138 | + * a valid value for some socket options. | |
| 139 | + * | |
| 140 | + * @throws UnsupportedOperationException | |
| 141 | + * If the socket option is not supported by this channel | |
| 142 | + * @throws ClosedChannelException | |
| 143 | + * If this channel is closed | |
| 144 | + * @throws IOException | |
| 145 | + * If an I/O error occurs | |
| 146 | + * | |
| 147 | + * @see java.net.StandardSocketOptions | |
| 148 | + */ | |
| 149 | + <T> T getOption(SocketOption<T> name) throws IOException; | |
| 150 | + | |
| 151 | + /** | |
| 152 | + * Returns a set of the socket options supported by this channel. | |
| 153 | + * | |
| 154 | + * <p> This method will continue to return the set of options even after the | |
| 155 | + * channel has been closed. | |
| 156 | + * | |
| 157 | + * @return A set of the socket options supported by this channel | |
| 158 | + */ | |
| 159 | + Set<SocketOption<?>> supportedOptions(); | |
| 160 | +} | |
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,153 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels; | |
| 27 | + | |
| 28 | +import java.io.IOException; | |
| 29 | +import java.nio.channels.spi.*; | |
| 30 | + | |
| 31 | + | |
| 32 | +/** | |
| 33 | + * A pair of channels that implements a unidirectional pipe. | |
| 34 | + * | |
| 35 | + * <p> A pipe consists of a pair of channels: A writable {@link | |
| 36 | + * Pipe.SinkChannel </code>sink<code>} channel and a readable {@link | |
| 37 | + * Pipe.SourceChannel </code>source<code>} channel. Once some bytes are | |
| 38 | + * written to the sink channel they can be read from source channel in exactly | |
| 39 | + * the order in which they were written. | |
| 40 | + * | |
| 41 | + * <p> Whether or not a thread writing bytes to a pipe will block until another | |
| 42 | + * thread reads those bytes, or some previously-written bytes, from the pipe is | |
| 43 | + * system-dependent and therefore unspecified. Many pipe implementations will | |
| 44 | + * buffer up to a certain number of bytes between the sink and source channels, | |
| 45 | + * but such buffering should not be assumed. </p> | |
| 46 | + * | |
| 47 | + * | |
| 48 | + * @author Mark Reinhold | |
| 49 | + * @author JSR-51 Expert Group | |
| 50 | + * @since 1.4 | |
| 51 | + */ | |
| 52 | + | |
| 53 | +public abstract class Pipe { | |
| 54 | + | |
| 55 | + /** | |
| 56 | + * A channel representing the readable end of a {@link Pipe}. </p> | |
| 57 | + * | |
| 58 | + * @since 1.4 | |
| 59 | + */ | |
| 60 | + public static abstract class SourceChannel | |
| 61 | + extends AbstractSelectableChannel | |
| 62 | + implements ReadableByteChannel, ScatteringByteChannel | |
| 63 | + { | |
| 64 | + /** | |
| 65 | + * Constructs a new instance of this class. | |
| 66 | + */ | |
| 67 | + protected SourceChannel(SelectorProvider provider) { | |
| 68 | + super(provider); | |
| 69 | + } | |
| 70 | + | |
| 71 | + /** | |
| 72 | + * Returns an operation set identifying this channel's supported | |
| 73 | + * operations. | |
| 74 | + * | |
| 75 | + * <p> Pipe-source channels only support reading, so this method | |
| 76 | + * returns {@link SelectionKey#OP_READ}. </p> | |
| 77 | + * | |
| 78 | + * @return The valid-operation set | |
| 79 | + */ | |
| 80 | + public final int validOps() { | |
| 81 | + return SelectionKey.OP_READ; | |
| 82 | + } | |
| 83 | + | |
| 84 | + } | |
| 85 | + | |
| 86 | + /** | |
| 87 | + * A channel representing the writable end of a {@link Pipe}. </p> | |
| 88 | + * | |
| 89 | + * @since 1.4 | |
| 90 | + */ | |
| 91 | + public static abstract class SinkChannel | |
| 92 | + extends AbstractSelectableChannel | |
| 93 | + implements WritableByteChannel, GatheringByteChannel | |
| 94 | + { | |
| 95 | + /** | |
| 96 | + * Initializes a new instance of this class. | |
| 97 | + */ | |
| 98 | + protected SinkChannel(SelectorProvider provider) { | |
| 99 | + super(provider); | |
| 100 | + } | |
| 101 | + | |
| 102 | + /** | |
| 103 | + * Returns an operation set identifying this channel's supported | |
| 104 | + * operations. | |
| 105 | + * | |
| 106 | + * <p> Pipe-sink channels only support writing, so this method returns | |
| 107 | + * {@link SelectionKey#OP_WRITE}. </p> | |
| 108 | + * | |
| 109 | + * @return The valid-operation set | |
| 110 | + */ | |
| 111 | + public final int validOps() { | |
| 112 | + return SelectionKey.OP_WRITE; | |
| 113 | + } | |
| 114 | + | |
| 115 | + } | |
| 116 | + | |
| 117 | + /** | |
| 118 | + * Initializes a new instance of this class. | |
| 119 | + */ | |
| 120 | + protected Pipe() { } | |
| 121 | + | |
| 122 | + /** | |
| 123 | + * Returns this pipe's source channel. </p> | |
| 124 | + * | |
| 125 | + * @return This pipe's source channel | |
| 126 | + */ | |
| 127 | + public abstract SourceChannel source(); | |
| 128 | + | |
| 129 | + /** | |
| 130 | + * Returns this pipe's sink channel. </p> | |
| 131 | + * | |
| 132 | + * @return This pipe's sink channel | |
| 133 | + */ | |
| 134 | + public abstract SinkChannel sink(); | |
| 135 | + | |
| 136 | + /** | |
| 137 | + * Opens a pipe. | |
| 138 | + * | |
| 139 | + * <p> The new pipe is created by invoking the {@link | |
| 140 | + * java.nio.channels.spi.SelectorProvider#openPipe openPipe} method of the | |
| 141 | + * system-wide default {@link java.nio.channels.spi.SelectorProvider} | |
| 142 | + * object. </p> | |
| 143 | + * | |
| 144 | + * @return A new pipe | |
| 145 | + * | |
| 146 | + * @throws IOException | |
| 147 | + * If an I/O error occurs | |
| 148 | + */ | |
| 149 | + public static Pipe open() throws IOException { | |
| 150 | + return SelectorProvider.provider().openPipe(); | |
| 151 | + } | |
| 152 | + | |
| 153 | +} | |
Binary file not shown.
| @@ -0,0 +1,108 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels; | |
| 27 | + | |
| 28 | +import java.io.IOException; | |
| 29 | +import java.nio.ByteBuffer; | |
| 30 | + | |
| 31 | + | |
| 32 | +/** | |
| 33 | + * A channel that can read bytes. | |
| 34 | + * | |
| 35 | + * <p> Only one read operation upon a readable channel may be in progress at | |
| 36 | + * any given time. If one thread initiates a read operation upon a channel | |
| 37 | + * then any other thread that attempts to initiate another read operation will | |
| 38 | + * block until the first operation is complete. Whether or not other kinds of | |
| 39 | + * I/O operations may proceed concurrently with a read operation depends upon | |
| 40 | + * the type of the channel. </p> | |
| 41 | + * | |
| 42 | + * | |
| 43 | + * @author Mark Reinhold | |
| 44 | + * @author JSR-51 Expert Group | |
| 45 | + * @since 1.4 | |
| 46 | + */ | |
| 47 | + | |
| 48 | +public interface ReadableByteChannel extends Channel { | |
| 49 | + | |
| 50 | + /** | |
| 51 | + * Reads a sequence of bytes from this channel into the given buffer. | |
| 52 | + * | |
| 53 | + * <p> An attempt is made to read up to <i>r</i> bytes from the channel, | |
| 54 | + * where <i>r</i> is the number of bytes remaining in the buffer, that is, | |
| 55 | + * <tt>dst.remaining()</tt>, at the moment this method is invoked. | |
| 56 | + * | |
| 57 | + * <p> Suppose that a byte sequence of length <i>n</i> is read, where | |
| 58 | + * <tt>0</tt> <tt><=</tt> <i>n</i> <tt><=</tt> <i>r</i>. | |
| 59 | + * This byte sequence will be transferred into the buffer so that the first | |
| 60 | + * byte in the sequence is at index <i>p</i> and the last byte is at index | |
| 61 | + * <i>p</i> <tt>+</tt> <i>n</i> <tt>-</tt> <tt>1</tt>, | |
| 62 | + * where <i>p</i> is the buffer's position at the moment this method is | |
| 63 | + * invoked. Upon return the buffer's position will be equal to | |
| 64 | + * <i>p</i> <tt>+</tt> <i>n</i>; its limit will not have changed. | |
| 65 | + * | |
| 66 | + * <p> A read operation might not fill the buffer, and in fact it might not | |
| 67 | + * read any bytes at all. Whether or not it does so depends upon the | |
| 68 | + * nature and state of the channel. A socket channel in non-blocking mode, | |
| 69 | + * for example, cannot read any more bytes than are immediately available | |
| 70 | + * from the socket's input buffer; similarly, a file channel cannot read | |
| 71 | + * any more bytes than remain in the file. It is guaranteed, however, that | |
| 72 | + * if a channel is in blocking mode and there is at least one byte | |
| 73 | + * remaining in the buffer then this method will block until at least one | |
| 74 | + * byte is read. | |
| 75 | + * | |
| 76 | + * <p> This method may be invoked at any time. If another thread has | |
| 77 | + * already initiated a read operation upon this channel, however, then an | |
| 78 | + * invocation of this method will block until the first operation is | |
| 79 | + * complete. </p> | |
| 80 | + * | |
| 81 | + * @param dst | |
| 82 | + * The buffer into which bytes are to be transferred | |
| 83 | + * | |
| 84 | + * @return The number of bytes read, possibly zero, or <tt>-1</tt> if the | |
| 85 | + * channel has reached end-of-stream | |
| 86 | + * | |
| 87 | + * @throws NonReadableChannelException | |
| 88 | + * If this channel was not opened for reading | |
| 89 | + * | |
| 90 | + * @throws ClosedChannelException | |
| 91 | + * If this channel is closed | |
| 92 | + * | |
| 93 | + * @throws AsynchronousCloseException | |
| 94 | + * If another thread closes this channel | |
| 95 | + * while the read operation is in progress | |
| 96 | + * | |
| 97 | + * @throws ClosedByInterruptException | |
| 98 | + * If another thread interrupts the current thread | |
| 99 | + * while the read operation is in progress, thereby | |
| 100 | + * closing the channel and setting the current thread's | |
| 101 | + * interrupt status | |
| 102 | + * | |
| 103 | + * @throws IOException | |
| 104 | + * If some other I/O error occurs | |
| 105 | + */ | |
| 106 | + public int read(ByteBuffer dst) throws IOException; | |
| 107 | + | |
| 108 | +} | |
Binary file not shown.
| @@ -0,0 +1,162 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels; | |
| 27 | + | |
| 28 | +import java.io.IOException; | |
| 29 | +import java.nio.ByteBuffer; | |
| 30 | + | |
| 31 | + | |
| 32 | +/** | |
| 33 | + * A channel that can read bytes into a sequence of buffers. | |
| 34 | + * | |
| 35 | + * <p> A <i>scattering</i> read operation reads, in a single invocation, a | |
| 36 | + * sequence of bytes into one or more of a given sequence of buffers. | |
| 37 | + * Scattering reads are often useful when implementing network protocols or | |
| 38 | + * file formats that, for example, group data into segments consisting of one | |
| 39 | + * or more fixed-length headers followed by a variable-length body. Similar | |
| 40 | + * <i>gathering</i> write operations are defined in the {@link | |
| 41 | + * GatheringByteChannel} interface. </p> | |
| 42 | + * | |
| 43 | + * | |
| 44 | + * @author Mark Reinhold | |
| 45 | + * @author JSR-51 Expert Group | |
| 46 | + * @since 1.4 | |
| 47 | + */ | |
| 48 | + | |
| 49 | +public interface ScatteringByteChannel | |
| 50 | + extends ReadableByteChannel | |
| 51 | +{ | |
| 52 | + | |
| 53 | + /** | |
| 54 | + * Reads a sequence of bytes from this channel into a subsequence of the | |
| 55 | + * given buffers. | |
| 56 | + * | |
| 57 | + * <p> An invocation of this method attempts to read up to <i>r</i> bytes | |
| 58 | + * from this channel, where <i>r</i> is the total number of bytes remaining | |
| 59 | + * the specified subsequence of the given buffer array, that is, | |
| 60 | + * | |
| 61 | + * <blockquote><pre> | |
| 62 | + * dsts[offset].remaining() | |
| 63 | + * + dsts[offset+1].remaining() | |
| 64 | + * + ... + dsts[offset+length-1].remaining()</pre></blockquote> | |
| 65 | + * | |
| 66 | + * at the moment that this method is invoked. | |
| 67 | + * | |
| 68 | + * <p> Suppose that a byte sequence of length <i>n</i> is read, where | |
| 69 | + * <tt>0</tt> <tt><=</tt> <i>n</i> <tt><=</tt> <i>r</i>. | |
| 70 | + * Up to the first <tt>dsts[offset].remaining()</tt> bytes of this sequence | |
| 71 | + * are transferred into buffer <tt>dsts[offset]</tt>, up to the next | |
| 72 | + * <tt>dsts[offset+1].remaining()</tt> bytes are transferred into buffer | |
| 73 | + * <tt>dsts[offset+1]</tt>, and so forth, until the entire byte sequence | |
| 74 | + * is transferred into the given buffers. As many bytes as possible are | |
| 75 | + * transferred into each buffer, hence the final position of each updated | |
| 76 | + * buffer, except the last updated buffer, is guaranteed to be equal to | |
| 77 | + * that buffer's limit. | |
| 78 | + * | |
| 79 | + * <p> This method may be invoked at any time. If another thread has | |
| 80 | + * already initiated a read operation upon this channel, however, then an | |
| 81 | + * invocation of this method will block until the first operation is | |
| 82 | + * complete. </p> | |
| 83 | + * | |
| 84 | + * @param dsts | |
| 85 | + * The buffers into which bytes are to be transferred | |
| 86 | + * | |
| 87 | + * @param offset | |
| 88 | + * The offset within the buffer array of the first buffer into | |
| 89 | + * which bytes are to be transferred; must be non-negative and no | |
| 90 | + * larger than <tt>dsts.length</tt> | |
| 91 | + * | |
| 92 | + * @param length | |
| 93 | + * The maximum number of buffers to be accessed; must be | |
| 94 | + * non-negative and no larger than | |
| 95 | + * <tt>dsts.length</tt> - <tt>offset</tt> | |
| 96 | + * | |
| 97 | + * @return The number of bytes read, possibly zero, | |
| 98 | + * or <tt>-1</tt> if the channel has reached end-of-stream | |
| 99 | + * | |
| 100 | + * @throws IndexOutOfBoundsException | |
| 101 | + * If the preconditions on the <tt>offset</tt> and <tt>length</tt> | |
| 102 | + * parameters do not hold | |
| 103 | + * | |
| 104 | + * @throws NonReadableChannelException | |
| 105 | + * If this channel was not opened for reading | |
| 106 | + * | |
| 107 | + * @throws ClosedChannelException | |
| 108 | + * If this channel is closed | |
| 109 | + * | |
| 110 | + * @throws AsynchronousCloseException | |
| 111 | + * If another thread closes this channel | |
| 112 | + * while the read operation is in progress | |
| 113 | + * | |
| 114 | + * @throws ClosedByInterruptException | |
| 115 | + * If another thread interrupts the current thread | |
| 116 | + * while the read operation is in progress, thereby | |
| 117 | + * closing the channel and setting the current thread's | |
| 118 | + * interrupt status | |
| 119 | + * | |
| 120 | + * @throws IOException | |
| 121 | + * If some other I/O error occurs | |
| 122 | + */ | |
| 123 | + public long read(ByteBuffer[] dsts, int offset, int length) | |
| 124 | + throws IOException; | |
| 125 | + | |
| 126 | + /** | |
| 127 | + * Reads a sequence of bytes from this channel into the given buffers. | |
| 128 | + * | |
| 129 | + * <p> An invocation of this method of the form <tt>c.read(dsts)</tt> | |
| 130 | + * behaves in exactly the same manner as the invocation | |
| 131 | + * | |
| 132 | + * <blockquote><pre> | |
| 133 | + * c.read(dsts, 0, dsts.length);</pre></blockquote> | |
| 134 | + * | |
| 135 | + * @param dsts | |
| 136 | + * The buffers into which bytes are to be transferred | |
| 137 | + * | |
| 138 | + * @return The number of bytes read, possibly zero, | |
| 139 | + * or <tt>-1</tt> if the channel has reached end-of-stream | |
| 140 | + * | |
| 141 | + * @throws NonReadableChannelException | |
| 142 | + * If this channel was not opened for reading | |
| 143 | + * | |
| 144 | + * @throws ClosedChannelException | |
| 145 | + * If this channel is closed | |
| 146 | + * | |
| 147 | + * @throws AsynchronousCloseException | |
| 148 | + * If another thread closes this channel | |
| 149 | + * while the read operation is in progress | |
| 150 | + * | |
| 151 | + * @throws ClosedByInterruptException | |
| 152 | + * If another thread interrupts the current thread | |
| 153 | + * while the read operation is in progress, thereby | |
| 154 | + * closing the channel and setting the current thread's | |
| 155 | + * interrupt status | |
| 156 | + * | |
| 157 | + * @throws IOException | |
| 158 | + * If some other I/O error occurs | |
| 159 | + */ | |
| 160 | + public long read(ByteBuffer[] dsts) throws IOException; | |
| 161 | + | |
| 162 | +} | |
Binary file not shown.
| @@ -0,0 +1,168 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels; | |
| 27 | + | |
| 28 | +import java.nio.ByteBuffer; | |
| 29 | +import java.io.IOException; | |
| 30 | + | |
| 31 | +/** | |
| 32 | + * A byte channel that maintains a current <i>position</i> and allows the | |
| 33 | + * position to be changed. | |
| 34 | + * | |
| 35 | + * <p> A seekable byte channel is connected to an entity, typically a file, | |
| 36 | + * that contains a variable-length sequence of bytes that can be read and | |
| 37 | + * written. The current position can be {@link #position() <i>queried</i>} and | |
| 38 | + * {@link #position(long) <i>modified</i>}. The channel also provides access to | |
| 39 | + * the current <i>size</i> of the entity to which the channel is connected. The | |
| 40 | + * size increases when bytes are written beyond its current size; the size | |
| 41 | + * decreases when it is {@link #truncate <i>truncated</i>}. | |
| 42 | + * | |
| 43 | + * <p> The {@link #position(long) position} and {@link #truncate truncate} methods | |
| 44 | + * which do not otherwise have a value to return are specified to return the | |
| 45 | + * channel upon which they are invoked. This allows method invocations to be | |
| 46 | + * chained. Implementations of this interface should specialize the return type | |
| 47 | + * so that method invocations on the implementation class can be chained. | |
| 48 | + * | |
| 49 | + * @since 1.7 | |
| 50 | + * @see java.nio.file.Files#newByteChannel | |
| 51 | + */ | |
| 52 | + | |
| 53 | +public interface SeekableByteChannel | |
| 54 | + extends ByteChannel | |
| 55 | +{ | |
| 56 | + /** | |
| 57 | + * Reads a sequence of bytes from this channel into the given buffer. | |
| 58 | + * | |
| 59 | + * <p> Bytes are read starting at this channel's current position, and | |
| 60 | + * then the position is updated with the number of bytes actually read. | |
| 61 | + * Otherwise this method behaves exactly as specified in the {@link | |
| 62 | + * ReadableByteChannel} interface. | |
| 63 | + */ | |
| 64 | + @Override | |
| 65 | + int read(ByteBuffer dst) throws IOException; | |
| 66 | + | |
| 67 | + /** | |
| 68 | + * Writes a sequence of bytes to this channel from the given buffer. | |
| 69 | + * | |
| 70 | + * <p> Bytes are written starting at this channel's current position, unless | |
| 71 | + * the channel is connected to an entity such as a file that is opened with | |
| 72 | + * the {@link java.nio.file.StandardOpenOption#APPEND APPEND} option, in | |
| 73 | + * which case the position is first advanced to the end. The entity to which | |
| 74 | + * the channel is connected is grown, if necessary, to accommodate the | |
| 75 | + * written bytes, and then the position is updated with the number of bytes | |
| 76 | + * actually written. Otherwise this method behaves exactly as specified by | |
| 77 | + * the {@link WritableByteChannel} interface. | |
| 78 | + */ | |
| 79 | + @Override | |
| 80 | + int write(ByteBuffer src) throws IOException; | |
| 81 | + | |
| 82 | + /** | |
| 83 | + * Returns this channel's position. | |
| 84 | + * | |
| 85 | + * @return This channel's position, | |
| 86 | + * a non-negative integer counting the number of bytes | |
| 87 | + * from the beginning of the entity to the current position | |
| 88 | + * | |
| 89 | + * @throws ClosedChannelException | |
| 90 | + * If this channel is closed | |
| 91 | + * @throws IOException | |
| 92 | + * If some other I/O error occurs | |
| 93 | + */ | |
| 94 | + long position() throws IOException; | |
| 95 | + | |
| 96 | + /** | |
| 97 | + * Sets this channel's position. | |
| 98 | + * | |
| 99 | + * <p> Setting the position to a value that is greater than the current size | |
| 100 | + * is legal but does not change the size of the entity. A later attempt to | |
| 101 | + * read bytes at such a position will immediately return an end-of-file | |
| 102 | + * indication. A later attempt to write bytes at such a position will cause | |
| 103 | + * the entity to grow to accommodate the new bytes; the values of any bytes | |
| 104 | + * between the previous end-of-file and the newly-written bytes are | |
| 105 | + * unspecified. | |
| 106 | + * | |
| 107 | + * <p> Setting the channel's position is not recommended when connected to | |
| 108 | + * an entity, typically a file, that is opened with the {@link | |
| 109 | + * java.nio.file.StandardOpenOption#APPEND APPEND} option. When opened for | |
| 110 | + * append, the position is first advanced to the end before writing. | |
| 111 | + * | |
| 112 | + * @param newPosition | |
| 113 | + * The new position, a non-negative integer counting | |
| 114 | + * the number of bytes from the beginning of the entity | |
| 115 | + * | |
| 116 | + * @return This channel | |
| 117 | + * | |
| 118 | + * @throws ClosedChannelException | |
| 119 | + * If this channel is closed | |
| 120 | + * @throws IllegalArgumentException | |
| 121 | + * If the new position is negative | |
| 122 | + * @throws IOException | |
| 123 | + * If some other I/O error occurs | |
| 124 | + */ | |
| 125 | + SeekableByteChannel position(long newPosition) throws IOException; | |
| 126 | + | |
| 127 | + /** | |
| 128 | + * Returns the current size of entity to which this channel is connected. | |
| 129 | + * | |
| 130 | + * @return The current size, measured in bytes | |
| 131 | + * | |
| 132 | + * @throws ClosedChannelException | |
| 133 | + * If this channel is closed | |
| 134 | + * @throws IOException | |
| 135 | + * If some other I/O error occurs | |
| 136 | + */ | |
| 137 | + long size() throws IOException; | |
| 138 | + | |
| 139 | + /** | |
| 140 | + * Truncates the entity, to which this channel is connected, to the given | |
| 141 | + * size. | |
| 142 | + * | |
| 143 | + * <p> If the given size is less than the current size then the entity is | |
| 144 | + * truncated, discarding any bytes beyond the new end. If the given size is | |
| 145 | + * greater than or equal to the current size then the entity is not modified. | |
| 146 | + * In either case, if the current position is greater than the given size | |
| 147 | + * then it is set to that size. | |
| 148 | + * | |
| 149 | + * <p> An implementation of this interface may prohibit truncation when | |
| 150 | + * connected to an entity, typically a file, opened with the {@link | |
| 151 | + * java.nio.file.StandardOpenOption#APPEND APPEND} option. | |
| 152 | + * | |
| 153 | + * @param size | |
| 154 | + * The new size, a non-negative byte count | |
| 155 | + * | |
| 156 | + * @return This channel | |
| 157 | + * | |
| 158 | + * @throws NonWritableChannelException | |
| 159 | + * If this channel was not opened for writing | |
| 160 | + * @throws ClosedChannelException | |
| 161 | + * If this channel is closed | |
| 162 | + * @throws IllegalArgumentException | |
| 163 | + * If the new size is negative | |
| 164 | + * @throws IOException | |
| 165 | + * If some other I/O error occurs | |
| 166 | + */ | |
| 167 | + SeekableByteChannel truncate(long size) throws IOException; | |
| 168 | +} | |
Binary file not shown.
| @@ -0,0 +1,342 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels; | |
| 27 | + | |
| 28 | +import java.io.IOException; | |
| 29 | +import java.nio.channels.spi.AbstractInterruptibleChannel; | |
| 30 | +import java.nio.channels.spi.SelectorProvider; | |
| 31 | + | |
| 32 | + | |
| 33 | +/** | |
| 34 | + * A channel that can be multiplexed via a {@link Selector}. | |
| 35 | + * | |
| 36 | + * <p> In order to be used with a selector, an instance of this class must | |
| 37 | + * first be <i>registered</i> via the {@link #register(Selector,int,Object) | |
| 38 | + * register} method. This method returns a new {@link SelectionKey} object | |
| 39 | + * that represents the channel's registration with the selector. | |
| 40 | + * | |
| 41 | + * <p> Once registered with a selector, a channel remains registered until it | |
| 42 | + * is <i>deregistered</i>. This involves deallocating whatever resources were | |
| 43 | + * allocated to the channel by the selector. | |
| 44 | + * | |
| 45 | + * <p> A channel cannot be deregistered directly; instead, the key representing | |
| 46 | + * its registration must be <i>cancelled</i>. Cancelling a key requests that | |
| 47 | + * the channel be deregistered during the selector's next selection operation. | |
| 48 | + * A key may be cancelled explicitly by invoking its {@link | |
| 49 | + * SelectionKey#cancel() cancel} method. All of a channel's keys are cancelled | |
| 50 | + * implicitly when the channel is closed, whether by invoking its {@link | |
| 51 | + * Channel#close close} method or by interrupting a thread blocked in an I/O | |
| 52 | + * operation upon the channel. | |
| 53 | + * | |
| 54 | + * <p> If the selector itself is closed then the channel will be deregistered, | |
| 55 | + * and the key representing its registration will be invalidated, without | |
| 56 | + * further delay. | |
| 57 | + * | |
| 58 | + * <p> A channel may be registered at most once with any particular selector. | |
| 59 | + * | |
| 60 | + * <p> Whether or not a channel is registered with one or more selectors may be | |
| 61 | + * determined by invoking the {@link #isRegistered isRegistered} method. | |
| 62 | + * | |
| 63 | + * <p> Selectable channels are safe for use by multiple concurrent | |
| 64 | + * threads. </p> | |
| 65 | + * | |
| 66 | + * | |
| 67 | + * <a name="bm"> | |
| 68 | + * <h4>Blocking mode</h4> | |
| 69 | + * | |
| 70 | + * A selectable channel is either in <i>blocking</i> mode or in | |
| 71 | + * <i>non-blocking</i> mode. In blocking mode, every I/O operation invoked | |
| 72 | + * upon the channel will block until it completes. In non-blocking mode an I/O | |
| 73 | + * operation will never block and may transfer fewer bytes than were requested | |
| 74 | + * or possibly no bytes at all. The blocking mode of a selectable channel may | |
| 75 | + * be determined by invoking its {@link #isBlocking isBlocking} method. | |
| 76 | + * | |
| 77 | + * <p> Newly-created selectable channels are always in blocking mode. | |
| 78 | + * Non-blocking mode is most useful in conjunction with selector-based | |
| 79 | + * multiplexing. A channel must be placed into non-blocking mode before being | |
| 80 | + * registered with a selector, and may not be returned to blocking mode until | |
| 81 | + * it has been deregistered. | |
| 82 | + * | |
| 83 | + * | |
| 84 | + * @author Mark Reinhold | |
| 85 | + * @author JSR-51 Expert Group | |
| 86 | + * @since 1.4 | |
| 87 | + * | |
| 88 | + * @see SelectionKey | |
| 89 | + * @see Selector | |
| 90 | + */ | |
| 91 | + | |
| 92 | +public abstract class SelectableChannel | |
| 93 | + extends AbstractInterruptibleChannel | |
| 94 | + implements Channel | |
| 95 | +{ | |
| 96 | + | |
| 97 | + /** | |
| 98 | + * Initializes a new instance of this class. | |
| 99 | + */ | |
| 100 | + protected SelectableChannel() { } | |
| 101 | + | |
| 102 | + /** | |
| 103 | + * Returns the provider that created this channel. | |
| 104 | + * | |
| 105 | + * @return The provider that created this channel | |
| 106 | + */ | |
| 107 | + public abstract SelectorProvider provider(); | |
| 108 | + | |
| 109 | + /** | |
| 110 | + * Returns an <a href="SelectionKey.html#opsets">operation set</a> | |
| 111 | + * identifying this channel's supported operations. The bits that are set | |
| 112 | + * in this integer value denote exactly the operations that are valid for | |
| 113 | + * this channel. This method always returns the same value for a given | |
| 114 | + * concrete channel class. </p> | |
| 115 | + * | |
| 116 | + * @return The valid-operation set | |
| 117 | + */ | |
| 118 | + public abstract int validOps(); | |
| 119 | + | |
| 120 | + // Internal state: | |
| 121 | + // keySet, may be empty but is never null, typ. a tiny array | |
| 122 | + // boolean isRegistered, protected by key set | |
| 123 | + // regLock, lock object to prevent duplicate registrations | |
| 124 | + // boolean isBlocking, protected by regLock | |
| 125 | + | |
| 126 | + /** | |
| 127 | + * Tells whether or not this channel is currently registered with any | |
| 128 | + * selectors. A newly-created channel is not registered. | |
| 129 | + * | |
| 130 | + * <p> Due to the inherent delay between key cancellation and channel | |
| 131 | + * deregistration, a channel may remain registered for some time after all | |
| 132 | + * of its keys have been cancelled. A channel may also remain registered | |
| 133 | + * for some time after it is closed. </p> | |
| 134 | + * | |
| 135 | + * @return <tt>true</tt> if, and only if, this channel is registered | |
| 136 | + */ | |
| 137 | + public abstract boolean isRegistered(); | |
| 138 | + // | |
| 139 | + // sync(keySet) { return isRegistered; } | |
| 140 | + | |
| 141 | + /** | |
| 142 | + * Retrieves the key representing the channel's registration with the given | |
| 143 | + * selector. </p> | |
| 144 | + * | |
| 145 | + * @return The key returned when this channel was last registered with the | |
| 146 | + * given selector, or <tt>null</tt> if this channel is not | |
| 147 | + * currently registered with that selector | |
| 148 | + */ | |
| 149 | + public abstract SelectionKey keyFor(Selector sel); | |
| 150 | + // | |
| 151 | + // sync(keySet) { return findKey(sel); } | |
| 152 | + | |
| 153 | + /** | |
| 154 | + * Registers this channel with the given selector, returning a selection | |
| 155 | + * key. | |
| 156 | + * | |
| 157 | + * <p> If this channel is currently registered with the given selector then | |
| 158 | + * the selection key representing that registration is returned. The key's | |
| 159 | + * interest set will have been changed to <tt>ops</tt>, as if by invoking | |
| 160 | + * the {@link SelectionKey#interestOps(int) interestOps(int)} method. If | |
| 161 | + * the <tt>att</tt> argument is not <tt>null</tt> then the key's attachment | |
| 162 | + * will have been set to that value. A {@link CancelledKeyException} will | |
| 163 | + * be thrown if the key has already been cancelled. | |
| 164 | + * | |
| 165 | + * <p> Otherwise this channel has not yet been registered with the given | |
| 166 | + * selector, so it is registered and the resulting new key is returned. | |
| 167 | + * The key's initial interest set will be <tt>ops</tt> and its attachment | |
| 168 | + * will be <tt>att</tt>. | |
| 169 | + * | |
| 170 | + * <p> This method may be invoked at any time. If this method is invoked | |
| 171 | + * while another invocation of this method or of the {@link | |
| 172 | + * #configureBlocking(boolean) configureBlocking} method is in progress | |
| 173 | + * then it will first block until the other operation is complete. This | |
| 174 | + * method will then synchronize on the selector's key set and therefore may | |
| 175 | + * block if invoked concurrently with another registration or selection | |
| 176 | + * operation involving the same selector. </p> | |
| 177 | + * | |
| 178 | + * <p> If this channel is closed while this operation is in progress then | |
| 179 | + * the key returned by this method will have been cancelled and will | |
| 180 | + * therefore be invalid. </p> | |
| 181 | + * | |
| 182 | + * @param sel | |
| 183 | + * The selector with which this channel is to be registered | |
| 184 | + * | |
| 185 | + * @param ops | |
| 186 | + * The interest set for the resulting key | |
| 187 | + * | |
| 188 | + * @param att | |
| 189 | + * The attachment for the resulting key; may be <tt>null</tt> | |
| 190 | + * | |
| 191 | + * @throws ClosedChannelException | |
| 192 | + * If this channel is closed | |
| 193 | + * | |
| 194 | + * @throws ClosedSelectorException | |
| 195 | + * If the selector is closed | |
| 196 | + * | |
| 197 | + * @throws IllegalBlockingModeException | |
| 198 | + * If this channel is in blocking mode | |
| 199 | + * | |
| 200 | + * @throws IllegalSelectorException | |
| 201 | + * If this channel was not created by the same provider | |
| 202 | + * as the given selector | |
| 203 | + * | |
| 204 | + * @throws CancelledKeyException | |
| 205 | + * If this channel is currently registered with the given selector | |
| 206 | + * but the corresponding key has already been cancelled | |
| 207 | + * | |
| 208 | + * @throws IllegalArgumentException | |
| 209 | + * If a bit in the <tt>ops</tt> set does not correspond to an | |
| 210 | + * operation that is supported by this channel, that is, if | |
| 211 | + * <tt>set & ~validOps() != 0</tt> | |
| 212 | + * | |
| 213 | + * @return A key representing the registration of this channel with | |
| 214 | + * the given selector | |
| 215 | + */ | |
| 216 | + public abstract SelectionKey register(Selector sel, int ops, Object att) | |
| 217 | + throws ClosedChannelException; | |
| 218 | + // | |
| 219 | + // sync(regLock) { | |
| 220 | + // sync(keySet) { look for selector } | |
| 221 | + // if (channel found) { set interest ops -- may block in selector; | |
| 222 | + // return key; } | |
| 223 | + // create new key -- may block somewhere in selector; | |
| 224 | + // sync(keySet) { add key; } | |
| 225 | + // attach(attachment); | |
| 226 | + // return key; | |
| 227 | + // } | |
| 228 | + | |
| 229 | + /** | |
| 230 | + * Registers this channel with the given selector, returning a selection | |
| 231 | + * key. | |
| 232 | + * | |
| 233 | + * <p> An invocation of this convenience method of the form | |
| 234 | + * | |
| 235 | + * <blockquote><tt>sc.register(sel, ops)</tt></blockquote> | |
| 236 | + * | |
| 237 | + * behaves in exactly the same way as the invocation | |
| 238 | + * | |
| 239 | + * <blockquote><tt>sc.{@link | |
| 240 | + * #register(java.nio.channels.Selector,int,java.lang.Object) | |
| 241 | + * register}(sel, ops, null)</tt></blockquote> | |
| 242 | + * | |
| 243 | + * @param sel | |
| 244 | + * The selector with which this channel is to be registered | |
| 245 | + * | |
| 246 | + * @param ops | |
| 247 | + * The interest set for the resulting key | |
| 248 | + * | |
| 249 | + * @throws ClosedChannelException | |
| 250 | + * If this channel is closed | |
| 251 | + * | |
| 252 | + * @throws ClosedSelectorException | |
| 253 | + * If the selector is closed | |
| 254 | + * | |
| 255 | + * @throws IllegalBlockingModeException | |
| 256 | + * If this channel is in blocking mode | |
| 257 | + * | |
| 258 | + * @throws IllegalSelectorException | |
| 259 | + * If this channel was not created by the same provider | |
| 260 | + * as the given selector | |
| 261 | + * | |
| 262 | + * @throws CancelledKeyException | |
| 263 | + * If this channel is currently registered with the given selector | |
| 264 | + * but the corresponding key has already been cancelled | |
| 265 | + * | |
| 266 | + * @throws IllegalArgumentException | |
| 267 | + * If a bit in <tt>ops</tt> does not correspond to an operation | |
| 268 | + * that is supported by this channel, that is, if <tt>set & | |
| 269 | + * ~validOps() != 0</tt> | |
| 270 | + * | |
| 271 | + * @return A key representing the registration of this channel with | |
| 272 | + * the given selector | |
| 273 | + */ | |
| 274 | + public final SelectionKey register(Selector sel, int ops) | |
| 275 | + throws ClosedChannelException | |
| 276 | + { | |
| 277 | + return register(sel, ops, null); | |
| 278 | + } | |
| 279 | + | |
| 280 | + /** | |
| 281 | + * Adjusts this channel's blocking mode. | |
| 282 | + * | |
| 283 | + * <p> If this channel is registered with one or more selectors then an | |
| 284 | + * attempt to place it into blocking mode will cause an {@link | |
| 285 | + * IllegalBlockingModeException} to be thrown. | |
| 286 | + * | |
| 287 | + * <p> This method may be invoked at any time. The new blocking mode will | |
| 288 | + * only affect I/O operations that are initiated after this method returns. | |
| 289 | + * For some implementations this may require blocking until all pending I/O | |
| 290 | + * operations are complete. | |
| 291 | + * | |
| 292 | + * <p> If this method is invoked while another invocation of this method or | |
| 293 | + * of the {@link #register(Selector, int) register} method is in progress | |
| 294 | + * then it will first block until the other operation is complete. </p> | |
| 295 | + * | |
| 296 | + * @param block If <tt>true</tt> then this channel will be placed in | |
| 297 | + * blocking mode; if <tt>false</tt> then it will be placed | |
| 298 | + * non-blocking mode | |
| 299 | + * | |
| 300 | + * @return This selectable channel | |
| 301 | + * | |
| 302 | + * @throws ClosedChannelException | |
| 303 | + * If this channel is closed | |
| 304 | + * | |
| 305 | + * @throws IllegalBlockingModeException | |
| 306 | + * If <tt>block</tt> is <tt>true</tt> and this channel is | |
| 307 | + * registered with one or more selectors | |
| 308 | + * | |
| 309 | + * @throws IOException | |
| 310 | + * If an I/O error occurs | |
| 311 | + */ | |
| 312 | + public abstract SelectableChannel configureBlocking(boolean block) | |
| 313 | + throws IOException; | |
| 314 | + // | |
| 315 | + // sync(regLock) { | |
| 316 | + // sync(keySet) { throw IBME if block && isRegistered; } | |
| 317 | + // change mode; | |
| 318 | + // } | |
| 319 | + | |
| 320 | + /** | |
| 321 | + * Tells whether or not every I/O operation on this channel will block | |
| 322 | + * until it completes. A newly-created channel is always in blocking mode. | |
| 323 | + * | |
| 324 | + * <p> If this channel is closed then the value returned by this method is | |
| 325 | + * not specified. </p> | |
| 326 | + * | |
| 327 | + * @return <tt>true</tt> if, and only if, this channel is in blocking mode | |
| 328 | + */ | |
| 329 | + public abstract boolean isBlocking(); | |
| 330 | + | |
| 331 | + /** | |
| 332 | + * Retrieves the object upon which the {@link #configureBlocking | |
| 333 | + * configureBlocking} and {@link #register register} methods synchronize. | |
| 334 | + * This is often useful in the implementation of adaptors that require a | |
| 335 | + * specific blocking mode to be maintained for a short period of time. | |
| 336 | + * </p> | |
| 337 | + * | |
| 338 | + * @return The blocking-mode lock object | |
| 339 | + */ | |
| 340 | + public abstract Object blockingLock(); | |
| 341 | + | |
| 342 | +} | |
Binary file not shown.
| @@ -0,0 +1,401 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels; | |
| 27 | + | |
| 28 | +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; | |
| 29 | +import java.io.IOException; | |
| 30 | + | |
| 31 | + | |
| 32 | +/** | |
| 33 | + * A token representing the registration of a {@link SelectableChannel} with a | |
| 34 | + * {@link Selector}. | |
| 35 | + * | |
| 36 | + * <p> A selection key is created each time a channel is registered with a | |
| 37 | + * selector. A key remains valid until it is <i>cancelled</i> by invoking its | |
| 38 | + * {@link #cancel cancel} method, by closing its channel, or by closing its | |
| 39 | + * selector. Cancelling a key does not immediately remove it from its | |
| 40 | + * selector; it is instead added to the selector's <a | |
| 41 | + * href="Selector.html#ks"><i>cancelled-key set</i></a> for removal during the | |
| 42 | + * next selection operation. The validity of a key may be tested by invoking | |
| 43 | + * its {@link #isValid isValid} method. | |
| 44 | + * | |
| 45 | + * <a name="opsets"> | |
| 46 | + * | |
| 47 | + * <p> A selection key contains two <i>operation sets</i> represented as | |
| 48 | + * integer values. Each bit of an operation set denotes a category of | |
| 49 | + * selectable operations that are supported by the key's channel. | |
| 50 | + * | |
| 51 | + * <ul> | |
| 52 | + * | |
| 53 | + * <li><p> The <i>interest set</i> determines which operation categories will | |
| 54 | + * be tested for readiness the next time one of the selector's selection | |
| 55 | + * methods is invoked. The interest set is initialized with the value given | |
| 56 | + * when the key is created; it may later be changed via the {@link | |
| 57 | + * #interestOps(int)} method. </p></li> | |
| 58 | + * | |
| 59 | + * <li><p> The <i>ready set</i> identifies the operation categories for which | |
| 60 | + * the key's channel has been detected to be ready by the key's selector. | |
| 61 | + * The ready set is initialized to zero when the key is created; it may later | |
| 62 | + * be updated by the selector during a selection operation, but it cannot be | |
| 63 | + * updated directly. </p></li> | |
| 64 | + * | |
| 65 | + * </ul> | |
| 66 | + * | |
| 67 | + * <p> That a selection key's ready set indicates that its channel is ready for | |
| 68 | + * some operation category is a hint, but not a guarantee, that an operation in | |
| 69 | + * such a category may be performed by a thread without causing the thread to | |
| 70 | + * block. A ready set is most likely to be accurate immediately after the | |
| 71 | + * completion of a selection operation. It is likely to be made inaccurate by | |
| 72 | + * external events and by I/O operations that are invoked upon the | |
| 73 | + * corresponding channel. | |
| 74 | + * | |
| 75 | + * <p> This class defines all known operation-set bits, but precisely which | |
| 76 | + * bits are supported by a given channel depends upon the type of the channel. | |
| 77 | + * Each subclass of {@link SelectableChannel} defines an {@link | |
| 78 | + * SelectableChannel#validOps() validOps()} method which returns a set | |
| 79 | + * identifying just those operations that are supported by the channel. An | |
| 80 | + * attempt to set or test an operation-set bit that is not supported by a key's | |
| 81 | + * channel will result in an appropriate run-time exception. | |
| 82 | + * | |
| 83 | + * <p> It is often necessary to associate some application-specific data with a | |
| 84 | + * selection key, for example an object that represents the state of a | |
| 85 | + * higher-level protocol and handles readiness notifications in order to | |
| 86 | + * implement that protocol. Selection keys therefore support the | |
| 87 | + * <i>attachment</i> of a single arbitrary object to a key. An object can be | |
| 88 | + * attached via the {@link #attach attach} method and then later retrieved via | |
| 89 | + * the {@link #attachment() attachment} method. | |
| 90 | + * | |
| 91 | + * <p> Selection keys are safe for use by multiple concurrent threads. The | |
| 92 | + * operations of reading and writing the interest set will, in general, be | |
| 93 | + * synchronized with certain operations of the selector. Exactly how this | |
| 94 | + * synchronization is performed is implementation-dependent: In a naive | |
| 95 | + * implementation, reading or writing the interest set may block indefinitely | |
| 96 | + * if a selection operation is already in progress; in a high-performance | |
| 97 | + * implementation, reading or writing the interest set may block briefly, if at | |
| 98 | + * all. In any case, a selection operation will always use the interest-set | |
| 99 | + * value that was current at the moment that the operation began. </p> | |
| 100 | + * | |
| 101 | + * | |
| 102 | + * @author Mark Reinhold | |
| 103 | + * @author JSR-51 Expert Group | |
| 104 | + * @since 1.4 | |
| 105 | + * | |
| 106 | + * @see SelectableChannel | |
| 107 | + * @see Selector | |
| 108 | + */ | |
| 109 | + | |
| 110 | +public abstract class SelectionKey { | |
| 111 | + | |
| 112 | + /** | |
| 113 | + * Constructs an instance of this class. | |
| 114 | + */ | |
| 115 | + protected SelectionKey() { } | |
| 116 | + | |
| 117 | + | |
| 118 | + // -- Channel and selector operations -- | |
| 119 | + | |
| 120 | + /** | |
| 121 | + * Returns the channel for which this key was created. This method will | |
| 122 | + * continue to return the channel even after the key is cancelled. </p> | |
| 123 | + * | |
| 124 | + * @return This key's channel | |
| 125 | + */ | |
| 126 | + public abstract SelectableChannel channel(); | |
| 127 | + | |
| 128 | + /** | |
| 129 | + * Returns the selector for which this key was created. This method will | |
| 130 | + * continue to return the selector even after the key is cancelled. </p> | |
| 131 | + * | |
| 132 | + * @return This key's selector | |
| 133 | + */ | |
| 134 | + public abstract Selector selector(); | |
| 135 | + | |
| 136 | + /** | |
| 137 | + * Tells whether or not this key is valid. | |
| 138 | + * | |
| 139 | + * <p> A key is valid upon creation and remains so until it is cancelled, | |
| 140 | + * its channel is closed, or its selector is closed. </p> | |
| 141 | + * | |
| 142 | + * @return <tt>true</tt> if, and only if, this key is valid | |
| 143 | + */ | |
| 144 | + public abstract boolean isValid(); | |
| 145 | + | |
| 146 | + /** | |
| 147 | + * Requests that the registration of this key's channel with its selector | |
| 148 | + * be cancelled. Upon return the key will be invalid and will have been | |
| 149 | + * added to its selector's cancelled-key set. The key will be removed from | |
| 150 | + * all of the selector's key sets during the next selection operation. | |
| 151 | + * | |
| 152 | + * <p> If this key has already been cancelled then invoking this method has | |
| 153 | + * no effect. Once cancelled, a key remains forever invalid. </p> | |
| 154 | + * | |
| 155 | + * <p> This method may be invoked at any time. It synchronizes on the | |
| 156 | + * selector's cancelled-key set, and therefore may block briefly if invoked | |
| 157 | + * concurrently with a cancellation or selection operation involving the | |
| 158 | + * same selector. </p> | |
| 159 | + */ | |
| 160 | + public abstract void cancel(); | |
| 161 | + | |
| 162 | + | |
| 163 | + // -- Operation-set accessors -- | |
| 164 | + | |
| 165 | + /** | |
| 166 | + * Retrieves this key's interest set. | |
| 167 | + * | |
| 168 | + * <p> It is guaranteed that the returned set will only contain operation | |
| 169 | + * bits that are valid for this key's channel. | |
| 170 | + * | |
| 171 | + * <p> This method may be invoked at any time. Whether or not it blocks, | |
| 172 | + * and for how long, is implementation-dependent. </p> | |
| 173 | + * | |
| 174 | + * @return This key's interest set | |
| 175 | + * | |
| 176 | + * @throws CancelledKeyException | |
| 177 | + * If this key has been cancelled | |
| 178 | + */ | |
| 179 | + public abstract int interestOps(); | |
| 180 | + | |
| 181 | + /** | |
| 182 | + * Sets this key's interest set to the given value. | |
| 183 | + * | |
| 184 | + * <p> This method may be invoked at any time. Whether or not it blocks, | |
| 185 | + * and for how long, is implementation-dependent. </p> | |
| 186 | + * | |
| 187 | + * @param ops The new interest set | |
| 188 | + * | |
| 189 | + * @return This selection key | |
| 190 | + * | |
| 191 | + * @throws IllegalArgumentException | |
| 192 | + * If a bit in the set does not correspond to an operation that | |
| 193 | + * is supported by this key's channel, that is, if | |
| 194 | + * <tt>(ops & ~channel().validOps()) != 0</tt> | |
| 195 | + * | |
| 196 | + * @throws CancelledKeyException | |
| 197 | + * If this key has been cancelled | |
| 198 | + */ | |
| 199 | + public abstract SelectionKey interestOps(int ops); | |
| 200 | + | |
| 201 | + /** | |
| 202 | + * Retrieves this key's ready-operation set. | |
| 203 | + * | |
| 204 | + * <p> It is guaranteed that the returned set will only contain operation | |
| 205 | + * bits that are valid for this key's channel. </p> | |
| 206 | + * | |
| 207 | + * @return This key's ready-operation set | |
| 208 | + * | |
| 209 | + * @throws CancelledKeyException | |
| 210 | + * If this key has been cancelled | |
| 211 | + */ | |
| 212 | + public abstract int readyOps(); | |
| 213 | + | |
| 214 | + | |
| 215 | + // -- Operation bits and bit-testing convenience methods -- | |
| 216 | + | |
| 217 | + /** | |
| 218 | + * Operation-set bit for read operations. | |
| 219 | + * | |
| 220 | + * <p> Suppose that a selection key's interest set contains | |
| 221 | + * <tt>OP_READ</tt> at the start of a <a | |
| 222 | + * href="Selector.html#selop">selection operation</a>. If the selector | |
| 223 | + * detects that the corresponding channel is ready for reading, has reached | |
| 224 | + * end-of-stream, has been remotely shut down for further reading, or has | |
| 225 | + * an error pending, then it will add <tt>OP_READ</tt> to the key's | |
| 226 | + * ready-operation set and add the key to its selected-key set. </p> | |
| 227 | + */ | |
| 228 | + public static final int OP_READ = 1 << 0; | |
| 229 | + | |
| 230 | + /** | |
| 231 | + * Operation-set bit for write operations. </p> | |
| 232 | + * | |
| 233 | + * <p> Suppose that a selection key's interest set contains | |
| 234 | + * <tt>OP_WRITE</tt> at the start of a <a | |
| 235 | + * href="Selector.html#selop">selection operation</a>. If the selector | |
| 236 | + * detects that the corresponding channel is ready for writing, has been | |
| 237 | + * remotely shut down for further writing, or has an error pending, then it | |
| 238 | + * will add <tt>OP_WRITE</tt> to the key's ready set and add the key to its | |
| 239 | + * selected-key set. </p> | |
| 240 | + */ | |
| 241 | + public static final int OP_WRITE = 1 << 2; | |
| 242 | + | |
| 243 | + /** | |
| 244 | + * Operation-set bit for socket-connect operations. </p> | |
| 245 | + * | |
| 246 | + * <p> Suppose that a selection key's interest set contains | |
| 247 | + * <tt>OP_CONNECT</tt> at the start of a <a | |
| 248 | + * href="Selector.html#selop">selection operation</a>. If the selector | |
| 249 | + * detects that the corresponding socket channel is ready to complete its | |
| 250 | + * connection sequence, or has an error pending, then it will add | |
| 251 | + * <tt>OP_CONNECT</tt> to the key's ready set and add the key to its | |
| 252 | + * selected-key set. </p> | |
| 253 | + */ | |
| 254 | + public static final int OP_CONNECT = 1 << 3; | |
| 255 | + | |
| 256 | + /** | |
| 257 | + * Operation-set bit for socket-accept operations. </p> | |
| 258 | + * | |
| 259 | + * <p> Suppose that a selection key's interest set contains | |
| 260 | + * <tt>OP_ACCEPT</tt> at the start of a <a | |
| 261 | + * href="Selector.html#selop">selection operation</a>. If the selector | |
| 262 | + * detects that the corresponding server-socket channel is ready to accept | |
| 263 | + * another connection, or has an error pending, then it will add | |
| 264 | + * <tt>OP_ACCEPT</tt> to the key's ready set and add the key to its | |
| 265 | + * selected-key set. </p> | |
| 266 | + */ | |
| 267 | + public static final int OP_ACCEPT = 1 << 4; | |
| 268 | + | |
| 269 | + /** | |
| 270 | + * Tests whether this key's channel is ready for reading. | |
| 271 | + * | |
| 272 | + * <p> An invocation of this method of the form <tt>k.isReadable()</tt> | |
| 273 | + * behaves in exactly the same way as the expression | |
| 274 | + * | |
| 275 | + * <blockquote><pre> | |
| 276 | + * k.readyOps() & OP_READ != 0</pre></blockquote> | |
| 277 | + * | |
| 278 | + * <p> If this key's channel does not support read operations then this | |
| 279 | + * method always returns <tt>false</tt>. </p> | |
| 280 | + * | |
| 281 | + * @return <tt>true</tt> if, and only if, | |
| 282 | + * <tt>readyOps()</tt> <tt>&</tt> <tt>OP_READ</tt> is | |
| 283 | + * nonzero | |
| 284 | + * | |
| 285 | + * @throws CancelledKeyException | |
| 286 | + * If this key has been cancelled | |
| 287 | + */ | |
| 288 | + public final boolean isReadable() { | |
| 289 | + return (readyOps() & OP_READ) != 0; | |
| 290 | + } | |
| 291 | + | |
| 292 | + /** | |
| 293 | + * Tests whether this key's channel is ready for writing. | |
| 294 | + * | |
| 295 | + * <p> An invocation of this method of the form <tt>k.isWritable()</tt> | |
| 296 | + * behaves in exactly the same way as the expression | |
| 297 | + * | |
| 298 | + * <blockquote><pre> | |
| 299 | + * k.readyOps() & OP_WRITE != 0</pre></blockquote> | |
| 300 | + * | |
| 301 | + * <p> If this key's channel does not support write operations then this | |
| 302 | + * method always returns <tt>false</tt>. </p> | |
| 303 | + * | |
| 304 | + * @return <tt>true</tt> if, and only if, | |
| 305 | + * <tt>readyOps()</tt> <tt>&</tt> <tt>OP_WRITE</tt> | |
| 306 | + * is nonzero | |
| 307 | + * | |
| 308 | + * @throws CancelledKeyException | |
| 309 | + * If this key has been cancelled | |
| 310 | + */ | |
| 311 | + public final boolean isWritable() { | |
| 312 | + return (readyOps() & OP_WRITE) != 0; | |
| 313 | + } | |
| 314 | + | |
| 315 | + /** | |
| 316 | + * Tests whether this key's channel has either finished, or failed to | |
| 317 | + * finish, its socket-connection operation. | |
| 318 | + * | |
| 319 | + * <p> An invocation of this method of the form <tt>k.isConnectable()</tt> | |
| 320 | + * behaves in exactly the same way as the expression | |
| 321 | + * | |
| 322 | + * <blockquote><pre> | |
| 323 | + * k.readyOps() & OP_CONNECT != 0</pre></blockquote> | |
| 324 | + * | |
| 325 | + * <p> If this key's channel does not support socket-connect operations | |
| 326 | + * then this method always returns <tt>false</tt>. </p> | |
| 327 | + * | |
| 328 | + * @return <tt>true</tt> if, and only if, | |
| 329 | + * <tt>readyOps()</tt> <tt>&</tt> <tt>OP_CONNECT</tt> | |
| 330 | + * is nonzero | |
| 331 | + * | |
| 332 | + * @throws CancelledKeyException | |
| 333 | + * If this key has been cancelled | |
| 334 | + */ | |
| 335 | + public final boolean isConnectable() { | |
| 336 | + return (readyOps() & OP_CONNECT) != 0; | |
| 337 | + } | |
| 338 | + | |
| 339 | + /** | |
| 340 | + * Tests whether this key's channel is ready to accept a new socket | |
| 341 | + * connection. | |
| 342 | + * | |
| 343 | + * <p> An invocation of this method of the form <tt>k.isAcceptable()</tt> | |
| 344 | + * behaves in exactly the same way as the expression | |
| 345 | + * | |
| 346 | + * <blockquote><pre> | |
| 347 | + * k.readyOps() & OP_ACCEPT != 0</pre></blockquote> | |
| 348 | + * | |
| 349 | + * <p> If this key's channel does not support socket-accept operations then | |
| 350 | + * this method always returns <tt>false</tt>. </p> | |
| 351 | + * | |
| 352 | + * @return <tt>true</tt> if, and only if, | |
| 353 | + * <tt>readyOps()</tt> <tt>&</tt> <tt>OP_ACCEPT</tt> | |
| 354 | + * is nonzero | |
| 355 | + * | |
| 356 | + * @throws CancelledKeyException | |
| 357 | + * If this key has been cancelled | |
| 358 | + */ | |
| 359 | + public final boolean isAcceptable() { | |
| 360 | + return (readyOps() & OP_ACCEPT) != 0; | |
| 361 | + } | |
| 362 | + | |
| 363 | + | |
| 364 | + // -- Attachments -- | |
| 365 | + | |
| 366 | + private volatile Object attachment = null; | |
| 367 | + | |
| 368 | + private static final AtomicReferenceFieldUpdater<SelectionKey,Object> | |
| 369 | + attachmentUpdater = AtomicReferenceFieldUpdater.newUpdater( | |
| 370 | + SelectionKey.class, Object.class, "attachment" | |
| 371 | + ); | |
| 372 | + | |
| 373 | + /** | |
| 374 | + * Attaches the given object to this key. | |
| 375 | + * | |
| 376 | + * <p> An attached object may later be retrieved via the {@link #attachment() | |
| 377 | + * attachment} method. Only one object may be attached at a time; invoking | |
| 378 | + * this method causes any previous attachment to be discarded. The current | |
| 379 | + * attachment may be discarded by attaching <tt>null</tt>. </p> | |
| 380 | + * | |
| 381 | + * @param ob | |
| 382 | + * The object to be attached; may be <tt>null</tt> | |
| 383 | + * | |
| 384 | + * @return The previously-attached object, if any, | |
| 385 | + * otherwise <tt>null</tt> | |
| 386 | + */ | |
| 387 | + public final Object attach(Object ob) { | |
| 388 | + return attachmentUpdater.getAndSet(this, ob); | |
| 389 | + } | |
| 390 | + | |
| 391 | + /** | |
| 392 | + * Retrieves the current attachment. </p> | |
| 393 | + * | |
| 394 | + * @return The object currently attached to this key, | |
| 395 | + * or <tt>null</tt> if there is no attachment | |
| 396 | + */ | |
| 397 | + public final Object attachment() { | |
| 398 | + return attachment; | |
| 399 | + } | |
| 400 | + | |
| 401 | +} | |
Binary file not shown.
| @@ -0,0 +1,396 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels; | |
| 27 | + | |
| 28 | +import java.io.Closeable; | |
| 29 | +import java.io.IOException; | |
| 30 | +import java.nio.channels.spi.SelectorProvider; | |
| 31 | +import java.util.Set; | |
| 32 | + | |
| 33 | + | |
| 34 | +/** | |
| 35 | + * A multiplexor of {@link SelectableChannel} objects. | |
| 36 | + * | |
| 37 | + * <p> A selector may be created by invoking the {@link #open open} method of | |
| 38 | + * this class, which will use the system's default {@link | |
| 39 | + * java.nio.channels.spi.SelectorProvider </code>selector provider<code>} to | |
| 40 | + * create a new selector. A selector may also be created by invoking the | |
| 41 | + * {@link java.nio.channels.spi.SelectorProvider#openSelector openSelector} | |
| 42 | + * method of a custom selector provider. A selector remains open until it is | |
| 43 | + * closed via its {@link #close close} method. | |
| 44 | + * | |
| 45 | + * <a name="ks"> | |
| 46 | + * | |
| 47 | + * <p> A selectable channel's registration with a selector is represented by a | |
| 48 | + * {@link SelectionKey} object. A selector maintains three sets of selection | |
| 49 | + * keys: | |
| 50 | + * | |
| 51 | + * <ul> | |
| 52 | + * | |
| 53 | + * <li><p> The <i>key set</i> contains the keys representing the current | |
| 54 | + * channel registrations of this selector. This set is returned by the | |
| 55 | + * {@link #keys() keys} method. </p></li> | |
| 56 | + * | |
| 57 | + * <li><p> The <i>selected-key set</i> is the set of keys such that each | |
| 58 | + * key's channel was detected to be ready for at least one of the operations | |
| 59 | + * identified in the key's interest set during a prior selection operation. | |
| 60 | + * This set is returned by the {@link #selectedKeys() selectedKeys} method. | |
| 61 | + * The selected-key set is always a subset of the key set. </p></li> | |
| 62 | + * | |
| 63 | + * <li><p> The <i>cancelled-key</i> set is the set of keys that have been | |
| 64 | + * cancelled but whose channels have not yet been deregistered. This set is | |
| 65 | + * not directly accessible. The cancelled-key set is always a subset of the | |
| 66 | + * key set. </p></li> | |
| 67 | + * | |
| 68 | + * </ul> | |
| 69 | + * | |
| 70 | + * <p> All three sets are empty in a newly-created selector. | |
| 71 | + * | |
| 72 | + * <p> A key is added to a selector's key set as a side effect of registering a | |
| 73 | + * channel via the channel's {@link SelectableChannel#register(Selector,int) | |
| 74 | + * register} method. Cancelled keys are removed from the key set during | |
| 75 | + * selection operations. The key set itself is not directly modifiable. | |
| 76 | + * | |
| 77 | + * <p> A key is added to its selector's cancelled-key set when it is cancelled, | |
| 78 | + * whether by closing its channel or by invoking its {@link SelectionKey#cancel | |
| 79 | + * cancel} method. Cancelling a key will cause its channel to be deregistered | |
| 80 | + * during the next selection operation, at which time the key will removed from | |
| 81 | + * all of the selector's key sets. | |
| 82 | + * | |
| 83 | + * <a name="sks"><p> Keys are added to the selected-key set by selection | |
| 84 | + * operations. A key may be removed directly from the selected-key set by | |
| 85 | + * invoking the set's {@link java.util.Set#remove(java.lang.Object) remove} | |
| 86 | + * method or by invoking the {@link java.util.Iterator#remove() remove} method | |
| 87 | + * of an {@link java.util.Iterator </code>iterator<code>} obtained from the | |
| 88 | + * set. Keys are never removed from the selected-key set in any other way; | |
| 89 | + * they are not, in particular, removed as a side effect of selection | |
| 90 | + * operations. Keys may not be added directly to the selected-key set. </p> | |
| 91 | + * | |
| 92 | + * | |
| 93 | + * <a name="selop"> | |
| 94 | + * <h4>Selection</h4> | |
| 95 | + * | |
| 96 | + * <p> During each selection operation, keys may be added to and removed from a | |
| 97 | + * selector's selected-key set and may be removed from its key and | |
| 98 | + * cancelled-key sets. Selection is performed by the {@link #select()}, {@link | |
| 99 | + * #select(long)}, and {@link #selectNow()} methods, and involves three steps: | |
| 100 | + * </p> | |
| 101 | + * | |
| 102 | + * <ol> | |
| 103 | + * | |
| 104 | + * <li><p> Each key in the cancelled-key set is removed from each key set of | |
| 105 | + * which it is a member, and its channel is deregistered. This step leaves | |
| 106 | + * the cancelled-key set empty. </p></li> | |
| 107 | + * | |
| 108 | + * <li><p> The underlying operating system is queried for an update as to the | |
| 109 | + * readiness of each remaining channel to perform any of the operations | |
| 110 | + * identified by its key's interest set as of the moment that the selection | |
| 111 | + * operation began. For a channel that is ready for at least one such | |
| 112 | + * operation, one of the following two actions is performed: </p> | |
| 113 | + * | |
| 114 | + * <ol type=a> | |
| 115 | + * | |
| 116 | + * <li><p> If the channel's key is not already in the selected-key set then | |
| 117 | + * it is added to that set and its ready-operation set is modified to | |
| 118 | + * identify exactly those operations for which the channel is now reported | |
| 119 | + * to be ready. Any readiness information previously recorded in the ready | |
| 120 | + * set is discarded. </p></li> | |
| 121 | + * | |
| 122 | + * <li><p> Otherwise the channel's key is already in the selected-key set, | |
| 123 | + * so its ready-operation set is modified to identify any new operations | |
| 124 | + * for which the channel is reported to be ready. Any readiness | |
| 125 | + * information previously recorded in the ready set is preserved; in other | |
| 126 | + * words, the ready set returned by the underlying system is | |
| 127 | + * bitwise-disjoined into the key's current ready set. </p></li> | |
| 128 | + * | |
| 129 | + * </ol></li> | |
| 130 | + * | |
| 131 | + * If all of the keys in the key set at the start of this step have empty | |
| 132 | + * interest sets then neither the selected-key set nor any of the keys' | |
| 133 | + * ready-operation sets will be updated. | |
| 134 | + * | |
| 135 | + * <li><p> If any keys were added to the cancelled-key set while step (2) was | |
| 136 | + * in progress then they are processed as in step (1). </p></li> | |
| 137 | + * | |
| 138 | + * </ol> | |
| 139 | + * | |
| 140 | + * <p> Whether or not a selection operation blocks to wait for one or more | |
| 141 | + * channels to become ready, and if so for how long, is the only essential | |
| 142 | + * difference between the three selection methods. </p> | |
| 143 | + * | |
| 144 | + * | |
| 145 | + * <h4>Concurrency</h4> | |
| 146 | + * | |
| 147 | + * <p> Selectors are themselves safe for use by multiple concurrent threads; | |
| 148 | + * their key sets, however, are not. | |
| 149 | + * | |
| 150 | + * <p> The selection operations synchronize on the selector itself, on the key | |
| 151 | + * set, and on the selected-key set, in that order. They also synchronize on | |
| 152 | + * the cancelled-key set during steps (1) and (3) above. | |
| 153 | + * | |
| 154 | + * <p> Changes made to the interest sets of a selector's keys while a | |
| 155 | + * selection operation is in progress have no effect upon that operation; they | |
| 156 | + * will be seen by the next selection operation. | |
| 157 | + * | |
| 158 | + * <p> Keys may be cancelled and channels may be closed at any time. Hence the | |
| 159 | + * presence of a key in one or more of a selector's key sets does not imply | |
| 160 | + * that the key is valid or that its channel is open. Application code should | |
| 161 | + * be careful to synchronize and check these conditions as necessary if there | |
| 162 | + * is any possibility that another thread will cancel a key or close a channel. | |
| 163 | + * | |
| 164 | + * <p> A thread blocked in one of the {@link #select()} or {@link | |
| 165 | + * #select(long)} methods may be interrupted by some other thread in one of | |
| 166 | + * three ways: | |
| 167 | + * | |
| 168 | + * <ul> | |
| 169 | + * | |
| 170 | + * <li><p> By invoking the selector's {@link #wakeup wakeup} method, | |
| 171 | + * </p></li> | |
| 172 | + * | |
| 173 | + * <li><p> By invoking the selector's {@link #close close} method, or | |
| 174 | + * </p></li> | |
| 175 | + * | |
| 176 | + * <li><p> By invoking the blocked thread's {@link | |
| 177 | + * java.lang.Thread#interrupt() interrupt} method, in which case its | |
| 178 | + * interrupt status will be set and the selector's {@link #wakeup wakeup} | |
| 179 | + * method will be invoked. </p></li> | |
| 180 | + * | |
| 181 | + * </ul> | |
| 182 | + * | |
| 183 | + * <p> The {@link #close close} method synchronizes on the selector and all | |
| 184 | + * three key sets in the same order as in a selection operation. | |
| 185 | + * | |
| 186 | + * <a name="ksc"> | |
| 187 | + * | |
| 188 | + * <p> A selector's key and selected-key sets are not, in general, safe for use | |
| 189 | + * by multiple concurrent threads. If such a thread might modify one of these | |
| 190 | + * sets directly then access should be controlled by synchronizing on the set | |
| 191 | + * itself. The iterators returned by these sets' {@link | |
| 192 | + * java.util.Set#iterator() iterator} methods are <i>fail-fast:</i> If the set | |
| 193 | + * is modified after the iterator is created, in any way except by invoking the | |
| 194 | + * iterator's own {@link java.util.Iterator#remove() remove} method, then a | |
| 195 | + * {@link java.util.ConcurrentModificationException} will be thrown. </p> | |
| 196 | + * | |
| 197 | + * | |
| 198 | + * @author Mark Reinhold | |
| 199 | + * @author JSR-51 Expert Group | |
| 200 | + * @since 1.4 | |
| 201 | + * | |
| 202 | + * @see SelectableChannel | |
| 203 | + * @see SelectionKey | |
| 204 | + */ | |
| 205 | + | |
| 206 | +public abstract class Selector implements Closeable { | |
| 207 | + | |
| 208 | + /** | |
| 209 | + * Initializes a new instance of this class. | |
| 210 | + */ | |
| 211 | + protected Selector() { } | |
| 212 | + | |
| 213 | + /** | |
| 214 | + * Opens a selector. | |
| 215 | + * | |
| 216 | + * <p> The new selector is created by invoking the {@link | |
| 217 | + * java.nio.channels.spi.SelectorProvider#openSelector openSelector} method | |
| 218 | + * of the system-wide default {@link | |
| 219 | + * java.nio.channels.spi.SelectorProvider} object. </p> | |
| 220 | + * | |
| 221 | + * @return A new selector | |
| 222 | + * | |
| 223 | + * @throws IOException | |
| 224 | + * If an I/O error occurs | |
| 225 | + */ | |
| 226 | + public static Selector open() throws IOException { | |
| 227 | + return SelectorProvider.provider().openSelector(); | |
| 228 | + } | |
| 229 | + | |
| 230 | + /** | |
| 231 | + * Tells whether or not this selector is open. </p> | |
| 232 | + * | |
| 233 | + * @return <tt>true</tt> if, and only if, this selector is open | |
| 234 | + */ | |
| 235 | + public abstract boolean isOpen(); | |
| 236 | + | |
| 237 | + /** | |
| 238 | + * Returns the provider that created this channel. </p> | |
| 239 | + * | |
| 240 | + * @return The provider that created this channel | |
| 241 | + */ | |
| 242 | + public abstract SelectorProvider provider(); | |
| 243 | + | |
| 244 | + /** | |
| 245 | + * Returns this selector's key set. | |
| 246 | + * | |
| 247 | + * <p> The key set is not directly modifiable. A key is removed only after | |
| 248 | + * it has been cancelled and its channel has been deregistered. Any | |
| 249 | + * attempt to modify the key set will cause an {@link | |
| 250 | + * UnsupportedOperationException} to be thrown. | |
| 251 | + * | |
| 252 | + * <p> The key set is <a href="#ksc">not thread-safe</a>. </p> | |
| 253 | + * | |
| 254 | + * @return This selector's key set | |
| 255 | + * | |
| 256 | + * @throws ClosedSelectorException | |
| 257 | + * If this selector is closed | |
| 258 | + */ | |
| 259 | + public abstract Set<SelectionKey> keys(); | |
| 260 | + | |
| 261 | + /** | |
| 262 | + * Returns this selector's selected-key set. | |
| 263 | + * | |
| 264 | + * <p> Keys may be removed from, but not directly added to, the | |
| 265 | + * selected-key set. Any attempt to add an object to the key set will | |
| 266 | + * cause an {@link UnsupportedOperationException} to be thrown. | |
| 267 | + * | |
| 268 | + * <p> The selected-key set is <a href="#ksc">not thread-safe</a>. </p> | |
| 269 | + * | |
| 270 | + * @return This selector's selected-key set | |
| 271 | + * | |
| 272 | + * @throws ClosedSelectorException | |
| 273 | + * If this selector is closed | |
| 274 | + */ | |
| 275 | + public abstract Set<SelectionKey> selectedKeys(); | |
| 276 | + | |
| 277 | + /** | |
| 278 | + * Selects a set of keys whose corresponding channels are ready for I/O | |
| 279 | + * operations. | |
| 280 | + * | |
| 281 | + * <p> This method performs a non-blocking <a href="#selop">selection | |
| 282 | + * operation</a>. If no channels have become selectable since the previous | |
| 283 | + * selection operation then this method immediately returns zero. | |
| 284 | + * | |
| 285 | + * <p> Invoking this method clears the effect of any previous invocations | |
| 286 | + * of the {@link #wakeup wakeup} method. </p> | |
| 287 | + * | |
| 288 | + * @return The number of keys, possibly zero, whose ready-operation sets | |
| 289 | + * were updated by the selection operation | |
| 290 | + * | |
| 291 | + * @throws IOException | |
| 292 | + * If an I/O error occurs | |
| 293 | + * | |
| 294 | + * @throws ClosedSelectorException | |
| 295 | + * If this selector is closed | |
| 296 | + */ | |
| 297 | + public abstract int selectNow() throws IOException; | |
| 298 | + | |
| 299 | + /** | |
| 300 | + * Selects a set of keys whose corresponding channels are ready for I/O | |
| 301 | + * operations. | |
| 302 | + * | |
| 303 | + * <p> This method performs a blocking <a href="#selop">selection | |
| 304 | + * operation</a>. It returns only after at least one channel is selected, | |
| 305 | + * this selector's {@link #wakeup wakeup} method is invoked, the current | |
| 306 | + * thread is interrupted, or the given timeout period expires, whichever | |
| 307 | + * comes first. | |
| 308 | + * | |
| 309 | + * <p> This method does not offer real-time guarantees: It schedules the | |
| 310 | + * timeout as if by invoking the {@link Object#wait(long)} method. </p> | |
| 311 | + * | |
| 312 | + * @param timeout If positive, block for up to <tt>timeout</tt> | |
| 313 | + * milliseconds, more or less, while waiting for a | |
| 314 | + * channel to become ready; if zero, block indefinitely; | |
| 315 | + * must not be negative | |
| 316 | + * | |
| 317 | + * @return The number of keys, possibly zero, | |
| 318 | + * whose ready-operation sets were updated | |
| 319 | + * | |
| 320 | + * @throws IOException | |
| 321 | + * If an I/O error occurs | |
| 322 | + * | |
| 323 | + * @throws ClosedSelectorException | |
| 324 | + * If this selector is closed | |
| 325 | + * | |
| 326 | + * @throws IllegalArgumentException | |
| 327 | + * If the value of the timeout argument is negative | |
| 328 | + */ | |
| 329 | + public abstract int select(long timeout) | |
| 330 | + throws IOException; | |
| 331 | + | |
| 332 | + /** | |
| 333 | + * Selects a set of keys whose corresponding channels are ready for I/O | |
| 334 | + * operations. | |
| 335 | + * | |
| 336 | + * <p> This method performs a blocking <a href="#selop">selection | |
| 337 | + * operation</a>. It returns only after at least one channel is selected, | |
| 338 | + * this selector's {@link #wakeup wakeup} method is invoked, or the current | |
| 339 | + * thread is interrupted, whichever comes first. </p> | |
| 340 | + * | |
| 341 | + * @return The number of keys, possibly zero, | |
| 342 | + * whose ready-operation sets were updated | |
| 343 | + * | |
| 344 | + * @throws IOException | |
| 345 | + * If an I/O error occurs | |
| 346 | + * | |
| 347 | + * @throws ClosedSelectorException | |
| 348 | + * If this selector is closed | |
| 349 | + */ | |
| 350 | + public abstract int select() throws IOException; | |
| 351 | + | |
| 352 | + /** | |
| 353 | + * Causes the first selection operation that has not yet returned to return | |
| 354 | + * immediately. | |
| 355 | + * | |
| 356 | + * <p> If another thread is currently blocked in an invocation of the | |
| 357 | + * {@link #select()} or {@link #select(long)} methods then that invocation | |
| 358 | + * will return immediately. If no selection operation is currently in | |
| 359 | + * progress then the next invocation of one of these methods will return | |
| 360 | + * immediately unless the {@link #selectNow()} method is invoked in the | |
| 361 | + * meantime. In any case the value returned by that invocation may be | |
| 362 | + * non-zero. Subsequent invocations of the {@link #select()} or {@link | |
| 363 | + * #select(long)} methods will block as usual unless this method is invoked | |
| 364 | + * again in the meantime. | |
| 365 | + * | |
| 366 | + * <p> Invoking this method more than once between two successive selection | |
| 367 | + * operations has the same effect as invoking it just once. </p> | |
| 368 | + * | |
| 369 | + * @return This selector | |
| 370 | + */ | |
| 371 | + public abstract Selector wakeup(); | |
| 372 | + | |
| 373 | + /** | |
| 374 | + * Closes this selector. | |
| 375 | + * | |
| 376 | + * <p> If a thread is currently blocked in one of this selector's selection | |
| 377 | + * methods then it is interrupted as if by invoking the selector's {@link | |
| 378 | + * #wakeup wakeup} method. | |
| 379 | + * | |
| 380 | + * <p> Any uncancelled keys still associated with this selector are | |
| 381 | + * invalidated, their channels are deregistered, and any other resources | |
| 382 | + * associated with this selector are released. | |
| 383 | + * | |
| 384 | + * <p> If this selector is already closed then invoking this method has no | |
| 385 | + * effect. | |
| 386 | + * | |
| 387 | + * <p> After a selector is closed, any further attempt to use it, except by | |
| 388 | + * invoking this method or the {@link #wakeup wakeup} method, will cause a | |
| 389 | + * {@link ClosedSelectorException} to be thrown. </p> | |
| 390 | + * | |
| 391 | + * @throws IOException | |
| 392 | + * If an I/O error occurs | |
| 393 | + */ | |
| 394 | + public abstract void close() throws IOException; | |
| 395 | + | |
| 396 | +} | |
Binary file not shown.
| @@ -0,0 +1,268 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels; | |
| 27 | + | |
| 28 | +import java.io.IOException; | |
| 29 | +import java.net.ServerSocket; | |
| 30 | +import java.net.SocketOption; | |
| 31 | +import java.net.SocketAddress; | |
| 32 | +import java.nio.channels.spi.AbstractSelectableChannel; | |
| 33 | +import java.nio.channels.spi.SelectorProvider; | |
| 34 | + | |
| 35 | +/** | |
| 36 | + * A selectable channel for stream-oriented listening sockets. | |
| 37 | + * | |
| 38 | + * <p> A server-socket channel is created by invoking the {@link #open() open} | |
| 39 | + * method of this class. It is not possible to create a channel for an arbitrary, | |
| 40 | + * pre-existing {@link ServerSocket}. A newly-created server-socket channel is | |
| 41 | + * open but not yet bound. An attempt to invoke the {@link #accept() accept} | |
| 42 | + * method of an unbound server-socket channel will cause a {@link NotYetBoundException} | |
| 43 | + * to be thrown. A server-socket channel can be bound by invoking one of the | |
| 44 | + * {@link #bind(java.net.SocketAddress,int) bind} methods defined by this class. | |
| 45 | + * | |
| 46 | + * <p> Socket options are configured using the {@link #setOption(SocketOption,Object) | |
| 47 | + * setOption} method. Server-socket channels support the following options: | |
| 48 | + * <blockquote> | |
| 49 | + * <table border> | |
| 50 | + * <tr> | |
| 51 | + * <th>Option Name</th> | |
| 52 | + * <th>Description</th> | |
| 53 | + * </tr> | |
| 54 | + * <tr> | |
| 55 | + * <td> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </td> | |
| 56 | + * <td> The size of the socket receive buffer </td> | |
| 57 | + * </tr> | |
| 58 | + * <tr> | |
| 59 | + * <td> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </td> | |
| 60 | + * <td> Re-use address </td> | |
| 61 | + * </tr> | |
| 62 | + * </table> | |
| 63 | + * </blockquote> | |
| 64 | + * Additional (implementation specific) options may also be supported. | |
| 65 | + * | |
| 66 | + * <p> Server-socket channels are safe for use by multiple concurrent threads. | |
| 67 | + * </p> | |
| 68 | + * | |
| 69 | + * @author Mark Reinhold | |
| 70 | + * @author JSR-51 Expert Group | |
| 71 | + * @since 1.4 | |
| 72 | + */ | |
| 73 | + | |
| 74 | +public abstract class ServerSocketChannel | |
| 75 | + extends AbstractSelectableChannel | |
| 76 | + implements NetworkChannel | |
| 77 | +{ | |
| 78 | + | |
| 79 | + /** | |
| 80 | + * Initializes a new instance of this class. | |
| 81 | + */ | |
| 82 | + protected ServerSocketChannel(SelectorProvider provider) { | |
| 83 | + super(provider); | |
| 84 | + } | |
| 85 | + | |
| 86 | + /** | |
| 87 | + * Opens a server-socket channel. | |
| 88 | + * | |
| 89 | + * <p> The new channel is created by invoking the {@link | |
| 90 | + * java.nio.channels.spi.SelectorProvider#openServerSocketChannel | |
| 91 | + * openServerSocketChannel} method of the system-wide default {@link | |
| 92 | + * java.nio.channels.spi.SelectorProvider} object. | |
| 93 | + * | |
| 94 | + * <p> The new channel's socket is initially unbound; it must be bound to a | |
| 95 | + * specific address via one of its socket's {@link | |
| 96 | + * java.net.ServerSocket#bind(SocketAddress) bind} methods before | |
| 97 | + * connections can be accepted. </p> | |
| 98 | + * | |
| 99 | + * @return A new socket channel | |
| 100 | + * | |
| 101 | + * @throws IOException | |
| 102 | + * If an I/O error occurs | |
| 103 | + */ | |
| 104 | + public static ServerSocketChannel open() throws IOException { | |
| 105 | + return SelectorProvider.provider().openServerSocketChannel(); | |
| 106 | + } | |
| 107 | + | |
| 108 | + /** | |
| 109 | + * Returns an operation set identifying this channel's supported | |
| 110 | + * operations. | |
| 111 | + * | |
| 112 | + * <p> Server-socket channels only support the accepting of new | |
| 113 | + * connections, so this method returns {@link SelectionKey#OP_ACCEPT}. | |
| 114 | + * </p> | |
| 115 | + * | |
| 116 | + * @return The valid-operation set | |
| 117 | + */ | |
| 118 | + public final int validOps() { | |
| 119 | + return SelectionKey.OP_ACCEPT; | |
| 120 | + } | |
| 121 | + | |
| 122 | + | |
| 123 | + // -- ServerSocket-specific operations -- | |
| 124 | + | |
| 125 | + /** | |
| 126 | + * Binds the channel's socket to a local address and configures the socket | |
| 127 | + * to listen for connections. | |
| 128 | + * | |
| 129 | + * <p> An invocation of this method is equivalent to the following: | |
| 130 | + * <blockquote><pre> | |
| 131 | + * bind(local, 0); | |
| 132 | + * </pre></blockquote> | |
| 133 | + * | |
| 134 | + * @param local | |
| 135 | + * The local address to bind the socket, or {@code null} to bind | |
| 136 | + * to an automatically assigned socket address | |
| 137 | + * | |
| 138 | + * @return This channel | |
| 139 | + * | |
| 140 | + * @throws AlreadyBoundException {@inheritDoc} | |
| 141 | + * @throws UnsupportedAddressTypeException {@inheritDoc} | |
| 142 | + * @throws ClosedChannelException {@inheritDoc} | |
| 143 | + * @throws IOException {@inheritDoc} | |
| 144 | + * @throws SecurityException | |
| 145 | + * If a security manager has been installed and its {@link | |
| 146 | + * SecurityManager#checkListen checkListen} method denies the | |
| 147 | + * operation | |
| 148 | + * | |
| 149 | + * @since 1.7 | |
| 150 | + */ | |
| 151 | + public final ServerSocketChannel bind(SocketAddress local) | |
| 152 | + throws IOException | |
| 153 | + { | |
| 154 | + return bind(local, 0); | |
| 155 | + } | |
| 156 | + | |
| 157 | + /** | |
| 158 | + * Binds the channel's socket to a local address and configures the socket to | |
| 159 | + * listen for connections. | |
| 160 | + * | |
| 161 | + * <p> This method is used to establish an association between the socket and | |
| 162 | + * a local address. Once an association is established then the socket remains | |
| 163 | + * bound until the channel is closed. | |
| 164 | + * | |
| 165 | + * <p> The {@code backlog} parameter is the maximum number of pending | |
| 166 | + * connections on the socket. Its exact semantics are implementation specific. | |
| 167 | + * In particular, an implementation may impose a maximum length or may choose | |
| 168 | + * to ignore the parameter altogther. If the {@code backlog} parameter has | |
| 169 | + * the value {@code 0}, or a negative value, then an implementation specific | |
| 170 | + * default is used. | |
| 171 | + * | |
| 172 | + * @param local | |
| 173 | + * The address to bind the socket, or {@code null} to bind to an | |
| 174 | + * automatically assigned socket address | |
| 175 | + * @param backlog | |
| 176 | + * The maximum number of pending connections | |
| 177 | + * | |
| 178 | + * @return This channel | |
| 179 | + * | |
| 180 | + * @throws AlreadyBoundException | |
| 181 | + * If the socket is already bound | |
| 182 | + * @throws UnsupportedAddressTypeException | |
| 183 | + * If the type of the given address is not supported | |
| 184 | + * @throws ClosedChannelException | |
| 185 | + * If this channel is closed | |
| 186 | + * @throws IOException | |
| 187 | + * If some other I/O error occurs | |
| 188 | + * @throws SecurityException | |
| 189 | + * If a security manager has been installed and its {@link | |
| 190 | + * SecurityManager#checkListen checkListen} method denies the | |
| 191 | + * operation | |
| 192 | + * | |
| 193 | + * @since 1.7 | |
| 194 | + */ | |
| 195 | + public abstract ServerSocketChannel bind(SocketAddress local, int backlog) | |
| 196 | + throws IOException; | |
| 197 | + | |
| 198 | + /** | |
| 199 | + * @throws UnsupportedOperationException {@inheritDoc} | |
| 200 | + * @throws IllegalArgumentException {@inheritDoc} | |
| 201 | + * @throws ClosedChannelException {@inheritDoc} | |
| 202 | + * @throws IOException {@inheritDoc} | |
| 203 | + * | |
| 204 | + * @since 1.7 | |
| 205 | + */ | |
| 206 | + public abstract <T> ServerSocketChannel setOption(SocketOption<T> name, T value) | |
| 207 | + throws IOException; | |
| 208 | + | |
| 209 | + /** | |
| 210 | + * Retrieves a server socket associated with this channel. | |
| 211 | + * | |
| 212 | + * <p> The returned object will not declare any public methods that are not | |
| 213 | + * declared in the {@link java.net.ServerSocket} class. </p> | |
| 214 | + * | |
| 215 | + * @return A server socket associated with this channel | |
| 216 | + */ | |
| 217 | + public abstract ServerSocket socket(); | |
| 218 | + | |
| 219 | + /** | |
| 220 | + * Accepts a connection made to this channel's socket. | |
| 221 | + * | |
| 222 | + * <p> If this channel is in non-blocking mode then this method will | |
| 223 | + * immediately return <tt>null</tt> if there are no pending connections. | |
| 224 | + * Otherwise it will block indefinitely until a new connection is available | |
| 225 | + * or an I/O error occurs. | |
| 226 | + * | |
| 227 | + * <p> The socket channel returned by this method, if any, will be in | |
| 228 | + * blocking mode regardless of the blocking mode of this channel. | |
| 229 | + * | |
| 230 | + * <p> This method performs exactly the same security checks as the {@link | |
| 231 | + * java.net.ServerSocket#accept accept} method of the {@link | |
| 232 | + * java.net.ServerSocket} class. That is, if a security manager has been | |
| 233 | + * installed then for each new connection this method verifies that the | |
| 234 | + * address and port number of the connection's remote endpoint are | |
| 235 | + * permitted by the security manager's {@link | |
| 236 | + * java.lang.SecurityManager#checkAccept checkAccept} method. </p> | |
| 237 | + * | |
| 238 | + * @return The socket channel for the new connection, | |
| 239 | + * or <tt>null</tt> if this channel is in non-blocking mode | |
| 240 | + * and no connection is available to be accepted | |
| 241 | + * | |
| 242 | + * @throws ClosedChannelException | |
| 243 | + * If this channel is closed | |
| 244 | + * | |
| 245 | + * @throws AsynchronousCloseException | |
| 246 | + * If another thread closes this channel | |
| 247 | + * while the accept operation is in progress | |
| 248 | + * | |
| 249 | + * @throws ClosedByInterruptException | |
| 250 | + * If another thread interrupts the current thread | |
| 251 | + * while the accept operation is in progress, thereby | |
| 252 | + * closing the channel and setting the current thread's | |
| 253 | + * interrupt status | |
| 254 | + * | |
| 255 | + * @throws NotYetBoundException | |
| 256 | + * If this channel's socket has not yet been bound | |
| 257 | + * | |
| 258 | + * @throws SecurityException | |
| 259 | + * If a security manager has been installed | |
| 260 | + * and it does not permit access to the remote endpoint | |
| 261 | + * of the new connection | |
| 262 | + * | |
| 263 | + * @throws IOException | |
| 264 | + * If some other I/O error occurs | |
| 265 | + */ | |
| 266 | + public abstract SocketChannel accept() throws IOException; | |
| 267 | + | |
| 268 | +} | |
Binary file not shown.
| @@ -0,0 +1,496 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels; | |
| 27 | + | |
| 28 | +import java.io.IOException; | |
| 29 | +import java.net.Socket; | |
| 30 | +import java.net.SocketOption; | |
| 31 | +import java.net.SocketAddress; | |
| 32 | +import java.nio.ByteBuffer; | |
| 33 | +import java.nio.channels.spi.AbstractSelectableChannel; | |
| 34 | +import java.nio.channels.spi.SelectorProvider; | |
| 35 | + | |
| 36 | +/** | |
| 37 | + * A selectable channel for stream-oriented connecting sockets. | |
| 38 | + * | |
| 39 | + * <p> A socket channel is created by invoking one of the {@link #open open} | |
| 40 | + * methods of this class. It is not possible to create a channel for an arbitrary, | |
| 41 | + * pre-existing socket. A newly-created socket channel is open but not yet | |
| 42 | + * connected. An attempt to invoke an I/O operation upon an unconnected | |
| 43 | + * channel will cause a {@link NotYetConnectedException} to be thrown. A | |
| 44 | + * socket channel can be connected by invoking its {@link #connect connect} | |
| 45 | + * method; once connected, a socket channel remains connected until it is | |
| 46 | + * closed. Whether or not a socket channel is connected may be determined by | |
| 47 | + * invoking its {@link #isConnected isConnected} method. | |
| 48 | + * | |
| 49 | + * <p> Socket channels support <i>non-blocking connection:</i> A socket | |
| 50 | + * channel may be created and the process of establishing the link to the | |
| 51 | + * remote socket may be initiated via the {@link #connect connect} method for | |
| 52 | + * later completion by the {@link #finishConnect finishConnect} method. | |
| 53 | + * Whether or not a connection operation is in progress may be determined by | |
| 54 | + * invoking the {@link #isConnectionPending isConnectionPending} method. | |
| 55 | + * | |
| 56 | + * <p> Socket channels support <i>asynchronous shutdown,</i> which is similar | |
| 57 | + * to the asynchronous close operation specified in the {@link Channel} class. | |
| 58 | + * If the input side of a socket is shut down by one thread while another | |
| 59 | + * thread is blocked in a read operation on the socket's channel, then the read | |
| 60 | + * operation in the blocked thread will complete without reading any bytes and | |
| 61 | + * will return <tt>-1</tt>. If the output side of a socket is shut down by one | |
| 62 | + * thread while another thread is blocked in a write operation on the socket's | |
| 63 | + * channel, then the blocked thread will receive an {@link | |
| 64 | + * AsynchronousCloseException}. | |
| 65 | + * | |
| 66 | + * <p> Socket options are configured using the {@link #setOption(SocketOption,Object) | |
| 67 | + * setOption} method. Socket channels support the following options: | |
| 68 | + * <blockquote> | |
| 69 | + * <table border> | |
| 70 | + * <tr> | |
| 71 | + * <th>Option Name</th> | |
| 72 | + * <th>Description</th> | |
| 73 | + * </tr> | |
| 74 | + * <tr> | |
| 75 | + * <td> {@link java.net.StandardSocketOptions#SO_SNDBUF SO_SNDBUF} </td> | |
| 76 | + * <td> The size of the socket send buffer </td> | |
| 77 | + * </tr> | |
| 78 | + * <tr> | |
| 79 | + * <td> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </td> | |
| 80 | + * <td> The size of the socket receive buffer </td> | |
| 81 | + * </tr> | |
| 82 | + * <tr> | |
| 83 | + * <td> {@link java.net.StandardSocketOptions#SO_KEEPALIVE SO_KEEPALIVE} </td> | |
| 84 | + * <td> Keep connection alive </td> | |
| 85 | + * </tr> | |
| 86 | + * <tr> | |
| 87 | + * <td> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </td> | |
| 88 | + * <td> Re-use address </td> | |
| 89 | + * </tr> | |
| 90 | + * <tr> | |
| 91 | + * <td> {@link java.net.StandardSocketOptions#SO_LINGER SO_LINGER} </td> | |
| 92 | + * <td> Linger on close if data is present (when configured in blocking mode | |
| 93 | + * only) </td> | |
| 94 | + * </tr> | |
| 95 | + * <tr> | |
| 96 | + * <td> {@link java.net.StandardSocketOptions#TCP_NODELAY TCP_NODELAY} </td> | |
| 97 | + * <td> Disable the Nagle algorithm </td> | |
| 98 | + * </tr> | |
| 99 | + * </table> | |
| 100 | + * </blockquote> | |
| 101 | + * Additional (implementation specific) options may also be supported. | |
| 102 | + * | |
| 103 | + * <p> Socket channels are safe for use by multiple concurrent threads. They | |
| 104 | + * support concurrent reading and writing, though at most one thread may be | |
| 105 | + * reading and at most one thread may be writing at any given time. The {@link | |
| 106 | + * #connect connect} and {@link #finishConnect finishConnect} methods are | |
| 107 | + * mutually synchronized against each other, and an attempt to initiate a read | |
| 108 | + * or write operation while an invocation of one of these methods is in | |
| 109 | + * progress will block until that invocation is complete. </p> | |
| 110 | + * | |
| 111 | + * @author Mark Reinhold | |
| 112 | + * @author JSR-51 Expert Group | |
| 113 | + * @since 1.4 | |
| 114 | + */ | |
| 115 | + | |
| 116 | +public abstract class SocketChannel | |
| 117 | + extends AbstractSelectableChannel | |
| 118 | + implements ByteChannel, ScatteringByteChannel, GatheringByteChannel, NetworkChannel | |
| 119 | +{ | |
| 120 | + | |
| 121 | + /** | |
| 122 | + * Initializes a new instance of this class. | |
| 123 | + */ | |
| 124 | + protected SocketChannel(SelectorProvider provider) { | |
| 125 | + super(provider); | |
| 126 | + } | |
| 127 | + | |
| 128 | + /** | |
| 129 | + * Opens a socket channel. | |
| 130 | + * | |
| 131 | + * <p> The new channel is created by invoking the {@link | |
| 132 | + * java.nio.channels.spi.SelectorProvider#openSocketChannel | |
| 133 | + * openSocketChannel} method of the system-wide default {@link | |
| 134 | + * java.nio.channels.spi.SelectorProvider} object. </p> | |
| 135 | + * | |
| 136 | + * @return A new socket channel | |
| 137 | + * | |
| 138 | + * @throws IOException | |
| 139 | + * If an I/O error occurs | |
| 140 | + */ | |
| 141 | + public static SocketChannel open() throws IOException { | |
| 142 | + return SelectorProvider.provider().openSocketChannel(); | |
| 143 | + } | |
| 144 | + | |
| 145 | + /** | |
| 146 | + * Opens a socket channel and connects it to a remote address. | |
| 147 | + * | |
| 148 | + * <p> This convenience method works as if by invoking the {@link #open()} | |
| 149 | + * method, invoking the {@link #connect(SocketAddress) connect} method upon | |
| 150 | + * the resulting socket channel, passing it <tt>remote</tt>, and then | |
| 151 | + * returning that channel. </p> | |
| 152 | + * | |
| 153 | + * @param remote | |
| 154 | + * The remote address to which the new channel is to be connected | |
| 155 | + * | |
| 156 | + * @throws AsynchronousCloseException | |
| 157 | + * If another thread closes this channel | |
| 158 | + * while the connect operation is in progress | |
| 159 | + * | |
| 160 | + * @throws ClosedByInterruptException | |
| 161 | + * If another thread interrupts the current thread | |
| 162 | + * while the connect operation is in progress, thereby | |
| 163 | + * closing the channel and setting the current thread's | |
| 164 | + * interrupt status | |
| 165 | + * | |
| 166 | + * @throws UnresolvedAddressException | |
| 167 | + * If the given remote address is not fully resolved | |
| 168 | + * | |
| 169 | + * @throws UnsupportedAddressTypeException | |
| 170 | + * If the type of the given remote address is not supported | |
| 171 | + * | |
| 172 | + * @throws SecurityException | |
| 173 | + * If a security manager has been installed | |
| 174 | + * and it does not permit access to the given remote endpoint | |
| 175 | + * | |
| 176 | + * @throws IOException | |
| 177 | + * If some other I/O error occurs | |
| 178 | + */ | |
| 179 | + public static SocketChannel open(SocketAddress remote) | |
| 180 | + throws IOException | |
| 181 | + { | |
| 182 | + SocketChannel sc = open(); | |
| 183 | + try { | |
| 184 | + sc.connect(remote); | |
| 185 | + } catch (Throwable x) { | |
| 186 | + try { | |
| 187 | + sc.close(); | |
| 188 | + } catch (Throwable suppressed) { | |
| 189 | + x.addSuppressed(suppressed); | |
| 190 | + } | |
| 191 | + throw x; | |
| 192 | + } | |
| 193 | + assert sc.isConnected(); | |
| 194 | + return sc; | |
| 195 | + } | |
| 196 | + | |
| 197 | + /** | |
| 198 | + * Returns an operation set identifying this channel's supported | |
| 199 | + * operations. | |
| 200 | + * | |
| 201 | + * <p> Socket channels support connecting, reading, and writing, so this | |
| 202 | + * method returns <tt>(</tt>{@link SelectionKey#OP_CONNECT} | |
| 203 | + * <tt>|</tt> {@link SelectionKey#OP_READ} <tt>|</tt> {@link | |
| 204 | + * SelectionKey#OP_WRITE}<tt>)</tt>. </p> | |
| 205 | + * | |
| 206 | + * @return The valid-operation set | |
| 207 | + */ | |
| 208 | + public final int validOps() { | |
| 209 | + return (SelectionKey.OP_READ | |
| 210 | + | SelectionKey.OP_WRITE | |
| 211 | + | SelectionKey.OP_CONNECT); | |
| 212 | + } | |
| 213 | + | |
| 214 | + | |
| 215 | + // -- Socket-specific operations -- | |
| 216 | + | |
| 217 | + /** | |
| 218 | + * @throws ConnectionPendingException | |
| 219 | + * If a non-blocking connect operation is already in progress on | |
| 220 | + * this channel | |
| 221 | + * @throws AlreadyBoundException {@inheritDoc} | |
| 222 | + * @throws UnsupportedAddressTypeException {@inheritDoc} | |
| 223 | + * @throws ClosedChannelException {@inheritDoc} | |
| 224 | + * @throws IOException {@inheritDoc} | |
| 225 | + * | |
| 226 | + * @since 1.7 | |
| 227 | + */ | |
| 228 | + @Override | |
| 229 | + public abstract SocketChannel bind(SocketAddress local) | |
| 230 | + throws IOException; | |
| 231 | + | |
| 232 | + /** | |
| 233 | + * @throws UnsupportedOperationException {@inheritDoc} | |
| 234 | + * @throws IllegalArgumentException {@inheritDoc} | |
| 235 | + * @throws ClosedChannelException {@inheritDoc} | |
| 236 | + * @throws IOException {@inheritDoc} | |
| 237 | + * | |
| 238 | + * @since 1.7 | |
| 239 | + */ | |
| 240 | + @Override | |
| 241 | + public abstract <T> SocketChannel setOption(SocketOption<T> name, T value) | |
| 242 | + throws IOException; | |
| 243 | + | |
| 244 | + /** | |
| 245 | + * Shutdown the connection for reading without closing the channel. | |
| 246 | + * | |
| 247 | + * <p> Once shutdown for reading then further reads on the channel will | |
| 248 | + * return {@code -1}, the end-of-stream indication. If the input side of the | |
| 249 | + * connection is already shutdown then invoking this method has no effect. | |
| 250 | + * | |
| 251 | + * @return The channel | |
| 252 | + * | |
| 253 | + * @throws NotYetConnectedException | |
| 254 | + * If this channel is not yet connected | |
| 255 | + * @throws ClosedChannelException | |
| 256 | + * If this channel is closed | |
| 257 | + * @throws IOException | |
| 258 | + * If some other I/O error occurs | |
| 259 | + * | |
| 260 | + * @since 1.7 | |
| 261 | + */ | |
| 262 | + public abstract SocketChannel shutdownInput() throws IOException; | |
| 263 | + | |
| 264 | + /** | |
| 265 | + * Shutdown the connection for writing without closing the channel. | |
| 266 | + * | |
| 267 | + * <p> Once shutdown for writing then further attempts to write to the | |
| 268 | + * channel will throw {@link ClosedChannelException}. If the output side of | |
| 269 | + * the connection is already shutdown then invoking this method has no | |
| 270 | + * effect. | |
| 271 | + * | |
| 272 | + * @return The channel | |
| 273 | + * | |
| 274 | + * @throws NotYetConnectedException | |
| 275 | + * If this channel is not yet connected | |
| 276 | + * @throws ClosedChannelException | |
| 277 | + * If this channel is closed | |
| 278 | + * @throws IOException | |
| 279 | + * If some other I/O error occurs | |
| 280 | + * | |
| 281 | + * @since 1.7 | |
| 282 | + */ | |
| 283 | + public abstract SocketChannel shutdownOutput() throws IOException; | |
| 284 | + | |
| 285 | + /** | |
| 286 | + * Retrieves a socket associated with this channel. | |
| 287 | + * | |
| 288 | + * <p> The returned object will not declare any public methods that are not | |
| 289 | + * declared in the {@link java.net.Socket} class. </p> | |
| 290 | + * | |
| 291 | + * @return A socket associated with this channel | |
| 292 | + */ | |
| 293 | + public abstract Socket socket(); | |
| 294 | + | |
| 295 | + /** | |
| 296 | + * Tells whether or not this channel's network socket is connected. | |
| 297 | + * | |
| 298 | + * @return <tt>true</tt> if, and only if, this channel's network socket | |
| 299 | + * is {@link #isOpen open} and connected | |
| 300 | + */ | |
| 301 | + public abstract boolean isConnected(); | |
| 302 | + | |
| 303 | + /** | |
| 304 | + * Tells whether or not a connection operation is in progress on this | |
| 305 | + * channel. </p> | |
| 306 | + * | |
| 307 | + * @return <tt>true</tt> if, and only if, a connection operation has been | |
| 308 | + * initiated on this channel but not yet completed by invoking the | |
| 309 | + * {@link #finishConnect finishConnect} method | |
| 310 | + */ | |
| 311 | + public abstract boolean isConnectionPending(); | |
| 312 | + | |
| 313 | + /** | |
| 314 | + * Connects this channel's socket. | |
| 315 | + * | |
| 316 | + * <p> If this channel is in non-blocking mode then an invocation of this | |
| 317 | + * method initiates a non-blocking connection operation. If the connection | |
| 318 | + * is established immediately, as can happen with a local connection, then | |
| 319 | + * this method returns <tt>true</tt>. Otherwise this method returns | |
| 320 | + * <tt>false</tt> and the connection operation must later be completed by | |
| 321 | + * invoking the {@link #finishConnect finishConnect} method. | |
| 322 | + * | |
| 323 | + * <p> If this channel is in blocking mode then an invocation of this | |
| 324 | + * method will block until the connection is established or an I/O error | |
| 325 | + * occurs. | |
| 326 | + * | |
| 327 | + * <p> This method performs exactly the same security checks as the {@link | |
| 328 | + * java.net.Socket} class. That is, if a security manager has been | |
| 329 | + * installed then this method verifies that its {@link | |
| 330 | + * java.lang.SecurityManager#checkConnect checkConnect} method permits | |
| 331 | + * connecting to the address and port number of the given remote endpoint. | |
| 332 | + * | |
| 333 | + * <p> This method may be invoked at any time. If a read or write | |
| 334 | + * operation upon this channel is invoked while an invocation of this | |
| 335 | + * method is in progress then that operation will first block until this | |
| 336 | + * invocation is complete. If a connection attempt is initiated but fails, | |
| 337 | + * that is, if an invocation of this method throws a checked exception, | |
| 338 | + * then the channel will be closed. </p> | |
| 339 | + * | |
| 340 | + * @param remote | |
| 341 | + * The remote address to which this channel is to be connected | |
| 342 | + * | |
| 343 | + * @return <tt>true</tt> if a connection was established, | |
| 344 | + * <tt>false</tt> if this channel is in non-blocking mode | |
| 345 | + * and the connection operation is in progress | |
| 346 | + * | |
| 347 | + * @throws AlreadyConnectedException | |
| 348 | + * If this channel is already connected | |
| 349 | + * | |
| 350 | + * @throws ConnectionPendingException | |
| 351 | + * If a non-blocking connection operation is already in progress | |
| 352 | + * on this channel | |
| 353 | + * | |
| 354 | + * @throws ClosedChannelException | |
| 355 | + * If this channel is closed | |
| 356 | + * | |
| 357 | + * @throws AsynchronousCloseException | |
| 358 | + * If another thread closes this channel | |
| 359 | + * while the connect operation is in progress | |
| 360 | + * | |
| 361 | + * @throws ClosedByInterruptException | |
| 362 | + * If another thread interrupts the current thread | |
| 363 | + * while the connect operation is in progress, thereby | |
| 364 | + * closing the channel and setting the current thread's | |
| 365 | + * interrupt status | |
| 366 | + * | |
| 367 | + * @throws UnresolvedAddressException | |
| 368 | + * If the given remote address is not fully resolved | |
| 369 | + * | |
| 370 | + * @throws UnsupportedAddressTypeException | |
| 371 | + * If the type of the given remote address is not supported | |
| 372 | + * | |
| 373 | + * @throws SecurityException | |
| 374 | + * If a security manager has been installed | |
| 375 | + * and it does not permit access to the given remote endpoint | |
| 376 | + * | |
| 377 | + * @throws IOException | |
| 378 | + * If some other I/O error occurs | |
| 379 | + */ | |
| 380 | + public abstract boolean connect(SocketAddress remote) throws IOException; | |
| 381 | + | |
| 382 | + /** | |
| 383 | + * Finishes the process of connecting a socket channel. | |
| 384 | + * | |
| 385 | + * <p> A non-blocking connection operation is initiated by placing a socket | |
| 386 | + * channel in non-blocking mode and then invoking its {@link #connect | |
| 387 | + * connect} method. Once the connection is established, or the attempt has | |
| 388 | + * failed, the socket channel will become connectable and this method may | |
| 389 | + * be invoked to complete the connection sequence. If the connection | |
| 390 | + * operation failed then invoking this method will cause an appropriate | |
| 391 | + * {@link java.io.IOException} to be thrown. | |
| 392 | + * | |
| 393 | + * <p> If this channel is already connected then this method will not block | |
| 394 | + * and will immediately return <tt>true</tt>. If this channel is in | |
| 395 | + * non-blocking mode then this method will return <tt>false</tt> if the | |
| 396 | + * connection process is not yet complete. If this channel is in blocking | |
| 397 | + * mode then this method will block until the connection either completes | |
| 398 | + * or fails, and will always either return <tt>true</tt> or throw a checked | |
| 399 | + * exception describing the failure. | |
| 400 | + * | |
| 401 | + * <p> This method may be invoked at any time. If a read or write | |
| 402 | + * operation upon this channel is invoked while an invocation of this | |
| 403 | + * method is in progress then that operation will first block until this | |
| 404 | + * invocation is complete. If a connection attempt fails, that is, if an | |
| 405 | + * invocation of this method throws a checked exception, then the channel | |
| 406 | + * will be closed. </p> | |
| 407 | + * | |
| 408 | + * @return <tt>true</tt> if, and only if, this channel's socket is now | |
| 409 | + * connected | |
| 410 | + * | |
| 411 | + * @throws NoConnectionPendingException | |
| 412 | + * If this channel is not connected and a connection operation | |
| 413 | + * has not been initiated | |
| 414 | + * | |
| 415 | + * @throws ClosedChannelException | |
| 416 | + * If this channel is closed | |
| 417 | + * | |
| 418 | + * @throws AsynchronousCloseException | |
| 419 | + * If another thread closes this channel | |
| 420 | + * while the connect operation is in progress | |
| 421 | + * | |
| 422 | + * @throws ClosedByInterruptException | |
| 423 | + * If another thread interrupts the current thread | |
| 424 | + * while the connect operation is in progress, thereby | |
| 425 | + * closing the channel and setting the current thread's | |
| 426 | + * interrupt status | |
| 427 | + * | |
| 428 | + * @throws IOException | |
| 429 | + * If some other I/O error occurs | |
| 430 | + */ | |
| 431 | + public abstract boolean finishConnect() throws IOException; | |
| 432 | + | |
| 433 | + /** | |
| 434 | + * Returns the remote address to which this channel's socket is connected. | |
| 435 | + * | |
| 436 | + * <p> Where the channel is bound and connected to an Internet Protocol | |
| 437 | + * socket address then the return value from this method is of type {@link | |
| 438 | + * java.net.InetSocketAddress}. | |
| 439 | + * | |
| 440 | + * @return The remote address; {@code null} if the channel's socket is not | |
| 441 | + * connected | |
| 442 | + * | |
| 443 | + * @throws ClosedChannelException | |
| 444 | + * If the channel is closed | |
| 445 | + * @throws IOException | |
| 446 | + * If an I/O error occurs | |
| 447 | + * | |
| 448 | + * @since 1.7 | |
| 449 | + */ | |
| 450 | + public abstract SocketAddress getRemoteAddress() throws IOException; | |
| 451 | + | |
| 452 | + // -- ByteChannel operations -- | |
| 453 | + | |
| 454 | + /** | |
| 455 | + * @throws NotYetConnectedException | |
| 456 | + * If this channel is not yet connected | |
| 457 | + */ | |
| 458 | + public abstract int read(ByteBuffer dst) throws IOException; | |
| 459 | + | |
| 460 | + /** | |
| 461 | + * @throws NotYetConnectedException | |
| 462 | + * If this channel is not yet connected | |
| 463 | + */ | |
| 464 | + public abstract long read(ByteBuffer[] dsts, int offset, int length) | |
| 465 | + throws IOException; | |
| 466 | + | |
| 467 | + /** | |
| 468 | + * @throws NotYetConnectedException | |
| 469 | + * If this channel is not yet connected | |
| 470 | + */ | |
| 471 | + public final long read(ByteBuffer[] dsts) throws IOException { | |
| 472 | + return read(dsts, 0, dsts.length); | |
| 473 | + } | |
| 474 | + | |
| 475 | + /** | |
| 476 | + * @throws NotYetConnectedException | |
| 477 | + * If this channel is not yet connected | |
| 478 | + */ | |
| 479 | + public abstract int write(ByteBuffer src) throws IOException; | |
| 480 | + | |
| 481 | + /** | |
| 482 | + * @throws NotYetConnectedException | |
| 483 | + * If this channel is not yet connected | |
| 484 | + */ | |
| 485 | + public abstract long write(ByteBuffer[] srcs, int offset, int length) | |
| 486 | + throws IOException; | |
| 487 | + | |
| 488 | + /** | |
| 489 | + * @throws NotYetConnectedException | |
| 490 | + * If this channel is not yet connected | |
| 491 | + */ | |
| 492 | + public final long write(ByteBuffer[] srcs) throws IOException { | |
| 493 | + return write(srcs, 0, srcs.length); | |
| 494 | + } | |
| 495 | + | |
| 496 | +} | |
Binary file not shown.
| @@ -0,0 +1,105 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels; | |
| 27 | + | |
| 28 | +import java.io.IOException; | |
| 29 | +import java.nio.ByteBuffer; | |
| 30 | + | |
| 31 | + | |
| 32 | +/** | |
| 33 | + * A channel that can write bytes. | |
| 34 | + * | |
| 35 | + * <p> Only one write operation upon a writable channel may be in progress at | |
| 36 | + * any given time. If one thread initiates a write operation upon a channel | |
| 37 | + * then any other thread that attempts to initiate another write operation will | |
| 38 | + * block until the first operation is complete. Whether or not other kinds of | |
| 39 | + * I/O operations may proceed concurrently with a write operation depends upon | |
| 40 | + * the type of the channel. </p> | |
| 41 | + * | |
| 42 | + * | |
| 43 | + * @author Mark Reinhold | |
| 44 | + * @author JSR-51 Expert Group | |
| 45 | + * @since 1.4 | |
| 46 | + */ | |
| 47 | + | |
| 48 | +public interface WritableByteChannel | |
| 49 | + extends Channel | |
| 50 | +{ | |
| 51 | + | |
| 52 | + /** | |
| 53 | + * Writes a sequence of bytes to this channel from the given buffer. | |
| 54 | + * | |
| 55 | + * <p> An attempt is made to write up to <i>r</i> bytes to the channel, | |
| 56 | + * where <i>r</i> is the number of bytes remaining in the buffer, that is, | |
| 57 | + * <tt>src.remaining()</tt>, at the moment this method is invoked. | |
| 58 | + * | |
| 59 | + * <p> Suppose that a byte sequence of length <i>n</i> is written, where | |
| 60 | + * <tt>0</tt> <tt><=</tt> <i>n</i> <tt><=</tt> <i>r</i>. | |
| 61 | + * This byte sequence will be transferred from the buffer starting at index | |
| 62 | + * <i>p</i>, where <i>p</i> is the buffer's position at the moment this | |
| 63 | + * method is invoked; the index of the last byte written will be | |
| 64 | + * <i>p</i> <tt>+</tt> <i>n</i> <tt>-</tt> <tt>1</tt>. | |
| 65 | + * Upon return the buffer's position will be equal to | |
| 66 | + * <i>p</i> <tt>+</tt> <i>n</i>; its limit will not have changed. | |
| 67 | + * | |
| 68 | + * <p> Unless otherwise specified, a write operation will return only after | |
| 69 | + * writing all of the <i>r</i> requested bytes. Some types of channels, | |
| 70 | + * depending upon their state, may write only some of the bytes or possibly | |
| 71 | + * none at all. A socket channel in non-blocking mode, for example, cannot | |
| 72 | + * write any more bytes than are free in the socket's output buffer. | |
| 73 | + * | |
| 74 | + * <p> This method may be invoked at any time. If another thread has | |
| 75 | + * already initiated a write operation upon this channel, however, then an | |
| 76 | + * invocation of this method will block until the first operation is | |
| 77 | + * complete. </p> | |
| 78 | + * | |
| 79 | + * @param src | |
| 80 | + * The buffer from which bytes are to be retrieved | |
| 81 | + * | |
| 82 | + * @return The number of bytes written, possibly zero | |
| 83 | + * | |
| 84 | + * @throws NonWritableChannelException | |
| 85 | + * If this channel was not opened for writing | |
| 86 | + * | |
| 87 | + * @throws ClosedChannelException | |
| 88 | + * If this channel is closed | |
| 89 | + * | |
| 90 | + * @throws AsynchronousCloseException | |
| 91 | + * If another thread closes this channel | |
| 92 | + * while the write operation is in progress | |
| 93 | + * | |
| 94 | + * @throws ClosedByInterruptException | |
| 95 | + * If another thread interrupts the current thread | |
| 96 | + * while the write operation is in progress, thereby | |
| 97 | + * closing the channel and setting the current thread's | |
| 98 | + * interrupt status | |
| 99 | + * | |
| 100 | + * @throws IOException | |
| 101 | + * If some other I/O error occurs | |
| 102 | + */ | |
| 103 | + public int write(ByteBuffer src) throws IOException; | |
| 104 | + | |
| 105 | +} | |
| @@ -0,0 +1,194 @@ | ||
| 1 | +# | |
| 2 | +# Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved. | |
| 3 | +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | +# | |
| 5 | +# This code is free software; you can redistribute it and/or modify it | |
| 6 | +# under the terms of the GNU General Public License version 2 only, as | |
| 7 | +# published by the Free Software Foundation. Oracle designates this | |
| 8 | +# particular file as subject to the "Classpath" exception as provided | |
| 9 | +# by Oracle in the LICENSE file that accompanied this code. | |
| 10 | +# | |
| 11 | +# This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | +# version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | +# accompanied this code). | |
| 16 | +# | |
| 17 | +# You should have received a copy of the GNU General Public License version | |
| 18 | +# 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | +# | |
| 21 | +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | +# or visit www.oracle.com if you need additional information or have any | |
| 23 | +# questions. | |
| 24 | +# | |
| 25 | + | |
| 26 | +# Generated exception classes for java.nio.channels | |
| 27 | + | |
| 28 | +SINCE=1.4 | |
| 29 | +PACKAGE=java.nio.channels | |
| 30 | +# This year should only change if the generated source is modified. | |
| 31 | +COPYRIGHT_YEARS="2000, 2007," | |
| 32 | + | |
| 33 | + | |
| 34 | +SUPER=java.io.IOException | |
| 35 | + | |
| 36 | +gen ClosedChannelException " | |
| 37 | + * Checked exception thrown when an attempt is made to invoke or complete an | |
| 38 | + * I/O operation upon channel that is closed, or at least closed to that | |
| 39 | + * operation. That this exception is thrown does not necessarily imply that | |
| 40 | + * the channel is completely closed. A socket channel whose write half has | |
| 41 | + * been shut down, for example, may still be open for reading." \ | |
| 42 | + 882777185433553857L | |
| 43 | + | |
| 44 | +gen FileLockInterruptionException " | |
| 45 | + * Checked exception received by a thread when another thread interrupts it | |
| 46 | + * while it is waiting to acquire a file lock. Before this exception is thrown | |
| 47 | + * the interrupt status of the previously-blocked thread will have been set." \ | |
| 48 | + 7104080643653532383L | |
| 49 | + | |
| 50 | + | |
| 51 | +SUPER=ClosedChannelException | |
| 52 | + | |
| 53 | +gen AsynchronousCloseException " | |
| 54 | + * Checked exception received by a thread when another thread closes the | |
| 55 | + * channel or the part of the channel upon which it is blocked in an I/O | |
| 56 | + * operation." \ | |
| 57 | + 6891178312432313966L | |
| 58 | + | |
| 59 | + | |
| 60 | +SUPER=AsynchronousCloseException | |
| 61 | + | |
| 62 | +gen ClosedByInterruptException " | |
| 63 | + * Checked exception received by a thread when another thread interrupts it | |
| 64 | + * while it is blocked in an I/O operation upon a channel. Before this | |
| 65 | + * exception is thrown the channel will have been closed and the interrupt | |
| 66 | + * status of the previously-blocked thread will have been set." \ | |
| 67 | + -4488191543534286750L | |
| 68 | + | |
| 69 | + | |
| 70 | +SUPER=IllegalArgumentException | |
| 71 | + | |
| 72 | +gen IllegalSelectorException " | |
| 73 | + * Unchecked exception thrown when an attempt is made to register a channel | |
| 74 | + * with a selector that was not created by the provider that created the | |
| 75 | + * channel." \ | |
| 76 | + -8406323347253320987L | |
| 77 | + | |
| 78 | +gen UnresolvedAddressException " | |
| 79 | + * Unchecked exception thrown when an attempt is made to invoke a network | |
| 80 | + * operation upon an unresolved socket address." \ | |
| 81 | + 6136959093620794148L | |
| 82 | + | |
| 83 | +gen UnsupportedAddressTypeException " | |
| 84 | + * Unchecked exception thrown when an attempt is made to bind or connect | |
| 85 | + * to a socket address of a type that is not supported." \ | |
| 86 | + -2964323842829700493L | |
| 87 | + | |
| 88 | + | |
| 89 | +SUPER=IllegalStateException | |
| 90 | + | |
| 91 | +gen AlreadyConnectedException " | |
| 92 | + * Unchecked exception thrown when an attempt is made to connect a {@link | |
| 93 | + * SocketChannel} that is already connected." \ | |
| 94 | + -7331895245053773357L | |
| 95 | + | |
| 96 | +gen ConnectionPendingException " | |
| 97 | + * Unchecked exception thrown when an attempt is made to connect a {@link | |
| 98 | + * SocketChannel} for which a non-blocking connection operation is already in | |
| 99 | + * progress." \ | |
| 100 | + 2008393366501760879L | |
| 101 | + | |
| 102 | +gen ClosedSelectorException " | |
| 103 | + * Unchecked exception thrown when an attempt is made to invoke an I/O | |
| 104 | + * operation upon a closed selector." \ | |
| 105 | + 6466297122317847835L | |
| 106 | + | |
| 107 | +gen CancelledKeyException " | |
| 108 | + * Unchecked exception thrown when an attempt is made to use | |
| 109 | + * a selection key that is no longer valid." \ | |
| 110 | + -8438032138028814268L | |
| 111 | + | |
| 112 | +gen IllegalBlockingModeException " | |
| 113 | + * Unchecked exception thrown when a blocking-mode-specific operation | |
| 114 | + * is invoked upon a channel in the incorrect blocking mode." \ | |
| 115 | + -3335774961855590474L | |
| 116 | + | |
| 117 | +gen NoConnectionPendingException " | |
| 118 | + * Unchecked exception thrown when the {@link SocketChannel#finishConnect | |
| 119 | + * finishConnect} method of a {@link SocketChannel} is invoked without first | |
| 120 | + * successfully invoking its {@link SocketChannel#connect connect} method." \ | |
| 121 | + -8296561183633134743L | |
| 122 | + | |
| 123 | +gen NonReadableChannelException " | |
| 124 | + * Unchecked exception thrown when an attempt is made to read | |
| 125 | + * from a channel that was not originally opened for reading." \ | |
| 126 | + -3200915679294993514L | |
| 127 | + | |
| 128 | +gen NonWritableChannelException " | |
| 129 | + * Unchecked exception thrown when an attempt is made to write | |
| 130 | + * to a channel that was not originally opened for writing." \ | |
| 131 | + -7071230488279011621L | |
| 132 | + | |
| 133 | +gen NotYetBoundException " | |
| 134 | + * Unchecked exception thrown when an attempt is made to invoke an I/O | |
| 135 | + * operation upon a server socket channel that is not yet bound." \ | |
| 136 | + 4640999303950202242L | |
| 137 | + | |
| 138 | +gen NotYetConnectedException " | |
| 139 | + * Unchecked exception thrown when an attempt is made to invoke an I/O | |
| 140 | + * operation upon a socket channel that is not yet connected." \ | |
| 141 | + 4697316551909513464L | |
| 142 | + | |
| 143 | +gen OverlappingFileLockException " | |
| 144 | + * Unchecked exception thrown when an attempt is made to acquire a lock on a | |
| 145 | + * region of a file that overlaps a region already locked by the same Java | |
| 146 | + * virtual machine, or when another thread is already waiting to lock an | |
| 147 | + * overlapping region of the same file." \ | |
| 148 | + 2047812138163068433L | |
| 149 | + | |
| 150 | + | |
| 151 | +SINCE=1.7 | |
| 152 | + | |
| 153 | +SUPER=java.io.IOException | |
| 154 | + | |
| 155 | +gen InterruptedByTimeoutException " | |
| 156 | + * Checked exception received by a thread when a timeout elapses before an | |
| 157 | + * asynchronous operation completes." \ | |
| 158 | + -4268008601014042947L | |
| 159 | + | |
| 160 | +SUPER=IllegalArgumentException | |
| 161 | + | |
| 162 | +gen IllegalChannelGroupException " | |
| 163 | + * Unchecked exception thrown when an attempt is made to open a channel | |
| 164 | + * in a group that was not created by the same provider. " \ | |
| 165 | + -2495041211157744253L | |
| 166 | + | |
| 167 | + | |
| 168 | +SUPER=IllegalStateException | |
| 169 | + | |
| 170 | +gen AlreadyBoundException " | |
| 171 | + * Unchecked exception thrown when an attempt is made to bind the socket a | |
| 172 | + * network oriented channel that is already bound." \ | |
| 173 | + 6796072983322737592L | |
| 174 | + | |
| 175 | +gen AcceptPendingException " | |
| 176 | + * Unchecked exception thrown when an attempt is made to initiate an accept | |
| 177 | + * operation on a channel and a previous accept operation has not completed." \ | |
| 178 | + 2721339977965416421L | |
| 179 | + | |
| 180 | +gen ReadPendingException " | |
| 181 | + * Unchecked exception thrown when an attempt is made to read from an | |
| 182 | + * asynchronous socket channel and a previous read has not completed." \ | |
| 183 | + 1986315242191227217L | |
| 184 | + | |
| 185 | +gen WritePendingException " | |
| 186 | + * Unchecked exception thrown when an attempt is made to write to an | |
| 187 | + * asynchronous socket channel and a previous write has not completed." \ | |
| 188 | + 7031871839266032276L | |
| 189 | + | |
| 190 | +gen ShutdownChannelGroupException " | |
| 191 | + * Unchecked exception thrown when an attempt is made to construct a channel in | |
| 192 | + * a group that is shutdown or the completion handler for an I/O operation | |
| 193 | + * cannot be invoked because the channel group has terminated." \ | |
| 194 | + -3903801676350154157L | |
| @@ -0,0 +1,40 @@ | ||
| 1 | +<../../../../../mkconfig | |
| 2 | + | |
| 3 | +DIRS=\ | |
| 4 | + spi\ | |
| 5 | + | |
| 6 | +TARG=\ | |
| 7 | + AsynchronousByteChannel.dis\ | |
| 8 | + AsynchronousChannel.dis\ | |
| 9 | + AsynchronousChannelGroup.dis\ | |
| 10 | + AsynchronousFileChannel.dis\ | |
| 11 | + AsynchronousServerSocketChannel.dis\ | |
| 12 | + AsynchronousSocketChannel.dis\ | |
| 13 | + ByteChannel.dis\ | |
| 14 | + Channel.dis\ | |
| 15 | + Channels.dis\ | |
| 16 | + CompletionHandler.dis\ | |
| 17 | + DatagramChannel.dis\ | |
| 18 | + FileChannel.dis\ | |
| 19 | + FileLock.dis\ | |
| 20 | + GatheringByteChannel.dis\ | |
| 21 | + InterruptibleChannel.dis\ | |
| 22 | + MembershipKey.dis\ | |
| 23 | + MulticastChannel.dis\ | |
| 24 | + NetworkChannel.dis\ | |
| 25 | + package-info.dis\ | |
| 26 | + Pipe.dis\ | |
| 27 | + ReadableByteChannel.dis\ | |
| 28 | + ScatteringByteChannel.dis\ | |
| 29 | + SeekableByteChannel.dis\ | |
| 30 | + SelectableChannel.dis\ | |
| 31 | + SelectionKey.dis\ | |
| 32 | + Selector.dis\ | |
| 33 | + ServerSocketChannel.dis\ | |
| 34 | + SocketChannel.dis\ | |
| 35 | + WritableByteChannel.dis\ | |
| 36 | + | |
| 37 | +DISBIN=$ROOT/java/dis/java/java/java/nio/channels | |
| 38 | + | |
| 39 | +<$ROOT/mkfiles/mkjava | |
| 40 | +<$ROOT/mkfiles/mksubdirs | |
| @@ -0,0 +1,290 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +/** | |
| 27 | + * Defines channels, which represent connections to entities that are capable of | |
| 28 | + * performing I/O operations, such as files and sockets; defines selectors, for | |
| 29 | + * multiplexed, non-blocking I/O operations. | |
| 30 | + * | |
| 31 | + * <a name="channels"></a> | |
| 32 | + * | |
| 33 | + * <blockquote><table cellspacing=1 cellpadding=0 summary="Lists channels and their descriptions"> | |
| 34 | + * <tr><th><p align="left">Channels</p></th><th><p align="left">Description</p></th></tr> | |
| 35 | + * <tr><td valign=top><tt><i>{@link java.nio.channels.Channel}</i></tt></td> | |
| 36 | + * <td>A nexus for I/O operations</td></tr> | |
| 37 | + * <tr><td valign=top><tt> <i>{@link java.nio.channels.ReadableByteChannel}</i></tt></td> | |
| 38 | + * <td>Can read into a buffer</td></tr> | |
| 39 | + * <tr><td valign=top><tt> <i>{@link java.nio.channels.ScatteringByteChannel} </i></tt></td> | |
| 40 | + * <td>Can read into a sequence of buffers</td></tr> | |
| 41 | + * <tr><td valign=top><tt> <i>{@link java.nio.channels.WritableByteChannel}</i></tt></td> | |
| 42 | + * <td>Can write from a buffer</td></tr> | |
| 43 | + * <tr><td valign=top><tt> <i>{@link java.nio.channels.GatheringByteChannel}</i></tt></td> | |
| 44 | + * <td>Can write from a sequence of buffers</td></tr> | |
| 45 | + * <tr><td valign=top><tt> <i>{@link java.nio.channels.ByteChannel}</i></tt></td> | |
| 46 | + * <td>Can read/write to/from a buffer</td></tr> | |
| 47 | + * <tr><td valign=top><tt> <i>{@link java.nio.channels.SeekableByteChannel}</i></tt></td> | |
| 48 | + * <td>A {@code ByteChannel} connected to an entity that contains a variable-length sequence of bytes</td></tr> | |
| 49 | + * <tr><td valign=top><tt> <i>{@link java.nio.channels.AsynchronousChannel}</i></tt></td> | |
| 50 | + * <td>Supports asynchronous I/O operations.</td></tr> | |
| 51 | + * <tr><td valign=top><tt> <i>{@link java.nio.channels.AsynchronousByteChannel}</i></tt></td> | |
| 52 | + * <td>Can read and write bytes asynchronously</td></tr> | |
| 53 | + * <tr><td valign=top><tt> <i>{@link java.nio.channels.NetworkChannel}</i></tt></td> | |
| 54 | + * <td>A channel to a network socket</td></tr> | |
| 55 | + * <tr><td valign=top><tt> <i>{@link java.nio.channels.MulticastChannel}</i></tt></td> | |
| 56 | + * <td>Can join Internet Protocol (IP) multicast groups</td></tr> | |
| 57 | + * <tr><td valign=top><tt>{@link java.nio.channels.Channels}</tt></td> | |
| 58 | + * <td>Utility methods for channel/stream interoperation</td></tr> | |
| 59 | + * </table></blockquote> | |
| 60 | + * | |
| 61 | + * <p> A <i>channel</i> represents an open connection to an entity such as a | |
| 62 | + * hardware device, a file, a network socket, or a program component that is | |
| 63 | + * capable of performing one or more distinct I/O operations, for example reading | |
| 64 | + * or writing. As specified in the {@link java.nio.channels.Channel} interface, | |
| 65 | + * channels are either open or closed, and they are both <i>asynchronously | |
| 66 | + * closeable</i> and <i>interruptible</i>. | |
| 67 | + * | |
| 68 | + * <p> The {@link java.nio.channels.Channel} interface is extended by several | |
| 69 | + * other interfaces. | |
| 70 | + * | |
| 71 | + * <p> The {@link java.nio.channels.ReadableByteChannel} interface specifies a | |
| 72 | + * {@link java.nio.channels.ReadableByteChannel#read read} method that reads bytes | |
| 73 | + * from the channel into a buffer; similarly, the {@link | |
| 74 | + * java.nio.channels.WritableByteChannel} interface specifies a {@link | |
| 75 | + * java.nio.channels.WritableByteChannel#write write} method that writes bytes | |
| 76 | + * from a buffer to the channel. The {@link java.nio.channels.ByteChannel} | |
| 77 | + * interface unifies these two interfaces for the common case of channels that can | |
| 78 | + * both read and write bytes. The {@link java.nio.channels.SeekableByteChannel} | |
| 79 | + * interface extends the {@code ByteChannel} interface with methods to {@link | |
| 80 | + * java.nio.channels.SeekableByteChannel#position() query} and {@link | |
| 81 | + * java.nio.channels.SeekableByteChannel#position(long) modify} the channel's | |
| 82 | + * current position, and its {@link java.nio.channels.SeekableByteChannel#size | |
| 83 | + * size}. | |
| 84 | + * | |
| 85 | + * <p> The {@link java.nio.channels.ScatteringByteChannel} and {@link | |
| 86 | + * java.nio.channels.GatheringByteChannel} interfaces extend the {@link | |
| 87 | + * java.nio.channels.ReadableByteChannel} and {@link | |
| 88 | + * java.nio.channels.WritableByteChannel} interfaces, respectively, adding {@link | |
| 89 | + * java.nio.channels.ScatteringByteChannel#read read} and {@link | |
| 90 | + * java.nio.channels.GatheringByteChannel#write write} methods that take a | |
| 91 | + * sequence of buffers rather than a single buffer. | |
| 92 | + * | |
| 93 | + * <p> The {@link java.nio.channels.NetworkChannel} interface specifies methods | |
| 94 | + * to {@link java.nio.channels.NetworkChannel#bind bind} the channel's socket, | |
| 95 | + * obtain the address to which the socket is bound, and methods to {@link | |
| 96 | + * java.nio.channels.NetworkChannel#getOption get} and {@link | |
| 97 | + * java.nio.channels.NetworkChannel#setOption set} socket options. The {@link | |
| 98 | + * java.nio.channels.MulticastChannel} interface specifies methods to join | |
| 99 | + * Internet Protocol (IP) multicast groups. | |
| 100 | + * | |
| 101 | + * <p> The {@link java.nio.channels.Channels} utility class defines static methods | |
| 102 | + * that support the interoperation of the stream classes of the <tt>{@link | |
| 103 | + * java.io}</tt> package with the channel classes of this package. An appropriate | |
| 104 | + * channel can be constructed from an {@link java.io.InputStream} or an {@link | |
| 105 | + * java.io.OutputStream}, and conversely an {@link java.io.InputStream} or an | |
| 106 | + * {@link java.io.OutputStream} can be constructed from a channel. A {@link | |
| 107 | + * java.io.Reader} can be constructed that uses a given charset to decode bytes | |
| 108 | + * from a given readable byte channel, and conversely a {@link java.io.Writer} can | |
| 109 | + * be constructed that uses a given charset to encode characters into bytes and | |
| 110 | + * write them to a given writable byte channel. | |
| 111 | + * | |
| 112 | + * <blockquote><table cellspacing=1 cellpadding=0 summary="Lists file channels and their descriptions"> | |
| 113 | + * <tr><th><p align="left">File channels</p></th><th><p align="left">Description</p></th></tr> | |
| 114 | + * <tr><td valign=top><tt>{@link java.nio.channels.FileChannel}</tt></td> | |
| 115 | + * <td>Reads, writes, maps, and manipulates files</td></tr> | |
| 116 | + * <tr><td valign=top><tt>{@link java.nio.channels.FileLock}</tt></td> | |
| 117 | + * <td>A lock on a (region of a) file</td></tr> | |
| 118 | + * <tr><td valign=top><tt>{@link java.nio.MappedByteBuffer} </tt></td> | |
| 119 | + * <td>A direct byte buffer mapped to a region of a file</td></tr> | |
| 120 | + * </table></blockquote> | |
| 121 | + * | |
| 122 | + * <p> The {@link java.nio.channels.FileChannel} class supports the usual | |
| 123 | + * operations of reading bytes from, and writing bytes to, a channel connected to | |
| 124 | + * a file, as well as those of querying and modifying the current file position | |
| 125 | + * and truncating the file to a specific size. It defines methods for acquiring | |
| 126 | + * locks on the whole file or on a specific region of a file; these methods return | |
| 127 | + * instances of the {@link java.nio.channels.FileLock} class. Finally, it defines | |
| 128 | + * methods for forcing updates to the file to be written to the storage device that | |
| 129 | + * contains it, for efficiently transferring bytes between the file and other | |
| 130 | + * channels, and for mapping a region of the file directly into memory. | |
| 131 | + * | |
| 132 | + * <p> A {@code FileChannel} is created by invoking one of its static {@link | |
| 133 | + * java.nio.channels.FileChannel#open open} methods, or by invoking the {@code | |
| 134 | + * getChannel} method of a {@link java.io.FileInputStream}, {@link | |
| 135 | + * java.io.FileOutputStream}, or {@link java.io.RandomAccessFile} to return a | |
| 136 | + * file channel connected to the same underlying file as the <tt>{@link java.io}</tt> | |
| 137 | + * class. | |
| 138 | + * | |
| 139 | + * <a name="multiplex"></a> | |
| 140 | + * <blockquote><table cellspacing=1 cellpadding=0 summary="Lists multiplexed, non-blocking channels and their descriptions"> | |
| 141 | + * <tr><th><p align="left">Multiplexed, non-blocking I/O</p></th><th><p align="left">Description</p></th></tr> | |
| 142 | + * <tr><td valign=top><tt>{@link java.nio.channels.SelectableChannel}</tt></td> | |
| 143 | + * <td>A channel that can be multiplexed</td></tr> | |
| 144 | + * <tr><td valign=top><tt> {@link java.nio.channels.DatagramChannel}</tt></td> | |
| 145 | + * <td>A channel to a datagram-oriented socket</td></tr> | |
| 146 | + * <tr><td valign=top><tt> {@link java.nio.channels.Pipe.SinkChannel}</tt></td> | |
| 147 | + * <td>The write end of a pipe</td></tr> | |
| 148 | + * <tr><td valign=top><tt> {@link java.nio.channels.Pipe.SourceChannel}</tt></td> | |
| 149 | + * <td>The read end of a pipe</td></tr> | |
| 150 | + * <tr><td valign=top><tt> {@link java.nio.channels.ServerSocketChannel} </tt></td> | |
| 151 | + * <td>A channel to a stream-oriented listening socket</td></tr> | |
| 152 | + * <tr><td valign=top><tt> {@link java.nio.channels.SocketChannel}</tt></td> | |
| 153 | + * <td>A channel for a stream-oriented connecting socket</td></tr> | |
| 154 | + * <tr><td valign=top><tt>{@link java.nio.channels.Selector}</tt></td> | |
| 155 | + * <td>A multiplexor of selectable channels</td></tr> | |
| 156 | + * <tr><td valign=top><tt>{@link java.nio.channels.SelectionKey}</tt></td> | |
| 157 | + * <td>A token representing the registration <br> of a channel | |
| 158 | + * with a selector</td></tr> | |
| 159 | + * <tr><td valign=top><tt>{@link java.nio.channels.Pipe}</tt></td> | |
| 160 | + * <td>Two channels that form a unidirectional pipe</td></tr> | |
| 161 | + * </table></blockquote> | |
| 162 | + * | |
| 163 | + * <p> Multiplexed, non-blocking I/O, which is much more scalable than | |
| 164 | + * thread-oriented, blocking I/O, is provided by <i>selectors</i>, <i>selectable | |
| 165 | + * channels</i>, and <i>selection keys</i>. | |
| 166 | + * | |
| 167 | + * <p> A <a href="Selector.html"><i>selector</i></a> is a multiplexor of <a | |
| 168 | + * href="SelectableChannel.html"><i>selectable channels</i></a>, which in turn are | |
| 169 | + * a special type of channel that can be put into <a | |
| 170 | + * href="SelectableChannel.html#bm"><i>non-blocking mode</i></a>. To perform | |
| 171 | + * multiplexed I/O operations, one or more selectable channels are first created, | |
| 172 | + * put into non-blocking mode, and {@link | |
| 173 | + * java.nio.channels.SelectableChannel#register <i>registered</i>} | |
| 174 | + * with a selector. Registering a channel specifies the set of I/O operations | |
| 175 | + * that will be tested for readiness by the selector, and returns a <a | |
| 176 | + * href="SelectionKey.html"><i>selection key</i></a> that represents the | |
| 177 | + * registration. | |
| 178 | + * | |
| 179 | + * <p> Once some channels have been registered with a selector, a <a | |
| 180 | + * href="Selector.html#selop"><i>selection operation</i></a> can be performed in | |
| 181 | + * order to discover which channels, if any, have become ready to perform one or | |
| 182 | + * more of the operations in which interest was previously declared. If a channel | |
| 183 | + * is ready then the key returned when it was registered will be added to the | |
| 184 | + * selector's <i>selected-key set</i>. The key set, and the keys within it, can | |
| 185 | + * be examined in order to determine the operations for which each channel is | |
| 186 | + * ready. From each key one can retrieve the corresponding channel in order to | |
| 187 | + * perform whatever I/O operations are required. | |
| 188 | + * | |
| 189 | + * <p> That a selection key indicates that its channel is ready for some operation | |
| 190 | + * is a hint, but not a guarantee, that such an operation can be performed by a | |
| 191 | + * thread without causing the thread to block. It is imperative that code that | |
| 192 | + * performs multiplexed I/O be written so as to ignore these hints when they prove | |
| 193 | + * to be incorrect. | |
| 194 | + * | |
| 195 | + * <p> This package defines selectable-channel classes corresponding to the {@link | |
| 196 | + * java.net.DatagramSocket}, {@link java.net.ServerSocket}, and {@link | |
| 197 | + * java.net.Socket} classes defined in the <tt>{@link java.net}</tt> package. | |
| 198 | + * Minor changes to these classes have been made in order to support sockets that | |
| 199 | + * are associated with channels. This package also defines a simple class that | |
| 200 | + * implements unidirectional pipes. In all cases, a new selectable channel is | |
| 201 | + * created by invoking the static <tt>open</tt> method of the corresponding class. | |
| 202 | + * If a channel needs an associated socket then a socket will be created as a side | |
| 203 | + * effect of this operation. | |
| 204 | + * | |
| 205 | + * <p> The implementation of selectors, selectable channels, and selection keys | |
| 206 | + * can be replaced by "plugging in" an alternative definition or instance of the | |
| 207 | + * {@link java.nio.channels.spi.SelectorProvider} class defined in the <tt>{@link | |
| 208 | + * java.nio.channels.spi}</tt> package. It is not expected that many developers | |
| 209 | + * will actually make use of this facility; it is provided primarily so that | |
| 210 | + * sophisticated users can take advantage of operating-system-specific | |
| 211 | + * I/O-multiplexing mechanisms when very high performance is required. | |
| 212 | + * | |
| 213 | + * <p> Much of the bookkeeping and synchronization required to implement the | |
| 214 | + * multiplexed-I/O abstractions is performed by the {@link | |
| 215 | + * java.nio.channels.spi.AbstractInterruptibleChannel}, {@link | |
| 216 | + * java.nio.channels.spi.AbstractSelectableChannel}, {@link | |
| 217 | + * java.nio.channels.spi.AbstractSelectionKey}, and {@link | |
| 218 | + * java.nio.channels.spi.AbstractSelector} classes in the <tt>{@link | |
| 219 | + * java.nio.channels.spi}</tt> package. When defining a custom selector provider, | |
| 220 | + * only the {@link java.nio.channels.spi.AbstractSelector} and {@link | |
| 221 | + * java.nio.channels.spi.AbstractSelectionKey} classes should be subclassed | |
| 222 | + * directly; custom channel classes should extend the appropriate {@link | |
| 223 | + * java.nio.channels.SelectableChannel} subclasses defined in this package. | |
| 224 | + * | |
| 225 | + * <a name="async"></a> | |
| 226 | + * | |
| 227 | + * <blockquote><table cellspacing=1 cellpadding=0 summary="Lists asynchronous channels and their descriptions"> | |
| 228 | + * <tr><th><p align="left">Asynchronous I/O</p></th><th><p align="left">Description</p></th></tr> | |
| 229 | + * <tr><td valign=top><tt>{@link java.nio.channels.AsynchronousFileChannel}</tt></td> | |
| 230 | + * <td>An asynchronous channel for reading, writing, and manipulating a file</td></tr> | |
| 231 | + * <tr><td valign=top><tt>{@link java.nio.channels.AsynchronousSocketChannel}</tt></td> | |
| 232 | + * <td>An asynchronous channel to a stream-oriented connecting socket</td></tr> | |
| 233 | + * <tr><td valign=top><tt>{@link java.nio.channels.AsynchronousServerSocketChannel} </tt></td> | |
| 234 | + * <td>An asynchronous channel to a stream-oriented listening socket</td></tr> | |
| 235 | + * <tr><td valign=top><tt>{@link java.nio.channels.CompletionHandler}</tt></td> | |
| 236 | + * <td>A handler for consuming the result of an asynchronous operation</td></tr> | |
| 237 | + * <tr><td valign=top><tt>{@link java.nio.channels.AsynchronousChannelGroup}</tt></td> | |
| 238 | + * <td>A grouping of asynchronous channels for the purpose of resource sharing</td></tr> | |
| 239 | + * </table></blockquote> | |
| 240 | + * | |
| 241 | + * <p> {@link java.nio.channels.AsynchronousChannel Asynchronous channels} are a | |
| 242 | + * special type of channel capable of asynchronous I/O operations. Asynchronous | |
| 243 | + * channels are non-blocking and define methods to initiate asynchronous | |
| 244 | + * operations, returning a {@link java.util.concurrent.Future} representing the | |
| 245 | + * pending result of each operation. The {@code Future} can be used to poll or | |
| 246 | + * wait for the result of the operation. Asynchronous I/O operations can also | |
| 247 | + * specify a {@link java.nio.channels.CompletionHandler} to invoke when the | |
| 248 | + * operation completes. A completion handler is user provided code that is executed | |
| 249 | + * to consume the result of I/O operation. | |
| 250 | + * | |
| 251 | + * <p> This package defines asynchronous-channel classes that are connected to | |
| 252 | + * a stream-oriented connecting or listening socket, or a datagram-oriented socket. | |
| 253 | + * It also defines the {@link java.nio.channels.AsynchronousFileChannel} class | |
| 254 | + * for asynchronous reading, writing, and manipulating a file. As with the {@link | |
| 255 | + * java.nio.channels.FileChannel} it supports operations to truncate the file | |
| 256 | + * to a specific size, force updates to the file to be written to the storage | |
| 257 | + * device, or acquire locks on the whole file or on a specific region of the file. | |
| 258 | + * Unlike the {@code FileChannel} it does not define methods for mapping a | |
| 259 | + * region of the file directly into memory. Where memory mapped I/O is required, | |
| 260 | + * then a {@code FileChannel} can be used. | |
| 261 | + * | |
| 262 | + * <p> Asynchronous channels are bound to an asynchronous channel group for the | |
| 263 | + * purpose of resource sharing. A group has an associated {@link | |
| 264 | + * java.util.concurrent.ExecutorService} to which tasks are submitted to handle | |
| 265 | + * I/O events and dispatch to completion handlers that consume the result of | |
| 266 | + * asynchronous operations performed on channels in the group. The group can | |
| 267 | + * optionally be specified when creating the channel or the channel can be bound | |
| 268 | + * to a <em>default group</em>. Sophisticated users may wish to create their | |
| 269 | + * own asynchronous channel groups or configure the {@code ExecutorService} | |
| 270 | + * that will be used for the default group. | |
| 271 | + * | |
| 272 | + * <p> As with selectors, the implementatin of asynchronous channels can be | |
| 273 | + * replaced by "plugging in" an alternative definition or instance of the {@link | |
| 274 | + * java.nio.channels.spi.AsynchronousChannelProvider} class defined in the | |
| 275 | + * <tt>{@link java.nio.channels.spi}</tt> package. It is not expected that many | |
| 276 | + * developers will actually make use of this facility; it is provided primarily | |
| 277 | + * so that sophisticated users can take advantage of operating-system-specific | |
| 278 | + * asynchronous I/O mechanisms when very high performance is required. | |
| 279 | + * | |
| 280 | + * <hr width="80%"> | |
| 281 | + * <p> Unless otherwise noted, passing a <tt>null</tt> argument to a constructor | |
| 282 | + * or method in any class or interface in this package will cause a {@link | |
| 283 | + * java.lang.NullPointerException NullPointerException} to be thrown. | |
| 284 | + * | |
| 285 | + * @since 1.4 | |
| 286 | + * @author Mark Reinhold | |
| 287 | + * @author JSR-51 Expert Group | |
| 288 | + */ | |
| 289 | + | |
| 290 | +package java.nio.channels; | |
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,214 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +/* | |
| 27 | + */ | |
| 28 | + | |
| 29 | +package java.nio.channels.spi; | |
| 30 | + | |
| 31 | +import java.io.IOException; | |
| 32 | +import java.lang.reflect.Method; | |
| 33 | +import java.lang.reflect.InvocationTargetException; | |
| 34 | +import java.nio.channels.*; | |
| 35 | +import java.security.AccessController; | |
| 36 | +import java.security.PrivilegedAction; | |
| 37 | +import sun.nio.ch.Interruptible; | |
| 38 | + | |
| 39 | + | |
| 40 | +/** | |
| 41 | + * Base implementation class for interruptible channels. | |
| 42 | + * | |
| 43 | + * <p> This class encapsulates the low-level machinery required to implement | |
| 44 | + * the asynchronous closing and interruption of channels. A concrete channel | |
| 45 | + * class must invoke the {@link #begin begin} and {@link #end end} methods | |
| 46 | + * before and after, respectively, invoking an I/O operation that might block | |
| 47 | + * indefinitely. In order to ensure that the {@link #end end} method is always | |
| 48 | + * invoked, these methods should be used within a | |
| 49 | + * <tt>try</tt> ... <tt>finally</tt> block: <a name="be"> | |
| 50 | + * | |
| 51 | + * <blockquote><pre> | |
| 52 | + * boolean completed = false; | |
| 53 | + * try { | |
| 54 | + * begin(); | |
| 55 | + * completed = ...; // Perform blocking I/O operation | |
| 56 | + * return ...; // Return result | |
| 57 | + * } finally { | |
| 58 | + * end(completed); | |
| 59 | + * }</pre></blockquote> | |
| 60 | + * | |
| 61 | + * <p> The <tt>completed</tt> argument to the {@link #end end} method tells | |
| 62 | + * whether or not the I/O operation actually completed, that is, whether it had | |
| 63 | + * any effect that would be visible to the invoker. In the case of an | |
| 64 | + * operation that reads bytes, for example, this argument should be | |
| 65 | + * <tt>true</tt> if, and only if, some bytes were actually transferred into the | |
| 66 | + * invoker's target buffer. | |
| 67 | + * | |
| 68 | + * <p> A concrete channel class must also implement the {@link | |
| 69 | + * #implCloseChannel implCloseChannel} method in such a way that if it is | |
| 70 | + * invoked while another thread is blocked in a native I/O operation upon the | |
| 71 | + * channel then that operation will immediately return, either by throwing an | |
| 72 | + * exception or by returning normally. If a thread is interrupted or the | |
| 73 | + * channel upon which it is blocked is asynchronously closed then the channel's | |
| 74 | + * {@link #end end} method will throw the appropriate exception. | |
| 75 | + * | |
| 76 | + * <p> This class performs the synchronization required to implement the {@link | |
| 77 | + * java.nio.channels.Channel} specification. Implementations of the {@link | |
| 78 | + * #implCloseChannel implCloseChannel} method need not synchronize against | |
| 79 | + * other threads that might be attempting to close the channel. </p> | |
| 80 | + * | |
| 81 | + * | |
| 82 | + * @author Mark Reinhold | |
| 83 | + * @author JSR-51 Expert Group | |
| 84 | + * @since 1.4 | |
| 85 | + */ | |
| 86 | + | |
| 87 | +public abstract class AbstractInterruptibleChannel | |
| 88 | + implements Channel, InterruptibleChannel | |
| 89 | +{ | |
| 90 | + | |
| 91 | + private final Object closeLock = new Object(); | |
| 92 | + private volatile boolean open = true; | |
| 93 | + | |
| 94 | + /** | |
| 95 | + * Initializes a new instance of this class. | |
| 96 | + */ | |
| 97 | + protected AbstractInterruptibleChannel() { } | |
| 98 | + | |
| 99 | + /** | |
| 100 | + * Closes this channel. | |
| 101 | + * | |
| 102 | + * <p> If the channel has already been closed then this method returns | |
| 103 | + * immediately. Otherwise it marks the channel as closed and then invokes | |
| 104 | + * the {@link #implCloseChannel implCloseChannel} method in order to | |
| 105 | + * complete the close operation. </p> | |
| 106 | + * | |
| 107 | + * @throws IOException | |
| 108 | + * If an I/O error occurs | |
| 109 | + */ | |
| 110 | + public final void close() throws IOException { | |
| 111 | + synchronized (closeLock) { | |
| 112 | + if (!open) | |
| 113 | + return; | |
| 114 | + open = false; | |
| 115 | + implCloseChannel(); | |
| 116 | + } | |
| 117 | + } | |
| 118 | + | |
| 119 | + /** | |
| 120 | + * Closes this channel. | |
| 121 | + * | |
| 122 | + * <p> This method is invoked by the {@link #close close} method in order | |
| 123 | + * to perform the actual work of closing the channel. This method is only | |
| 124 | + * invoked if the channel has not yet been closed, and it is never invoked | |
| 125 | + * more than once. | |
| 126 | + * | |
| 127 | + * <p> An implementation of this method must arrange for any other thread | |
| 128 | + * that is blocked in an I/O operation upon this channel to return | |
| 129 | + * immediately, either by throwing an exception or by returning normally. | |
| 130 | + * </p> | |
| 131 | + * | |
| 132 | + * @throws IOException | |
| 133 | + * If an I/O error occurs while closing the channel | |
| 134 | + */ | |
| 135 | + protected abstract void implCloseChannel() throws IOException; | |
| 136 | + | |
| 137 | + public final boolean isOpen() { | |
| 138 | + return open; | |
| 139 | + } | |
| 140 | + | |
| 141 | + | |
| 142 | + // -- Interruption machinery -- | |
| 143 | + | |
| 144 | + private Interruptible interruptor; | |
| 145 | + private volatile Thread interrupted; | |
| 146 | + | |
| 147 | + /** | |
| 148 | + * Marks the beginning of an I/O operation that might block indefinitely. | |
| 149 | + * | |
| 150 | + * <p> This method should be invoked in tandem with the {@link #end end} | |
| 151 | + * method, using a <tt>try</tt> ... <tt>finally</tt> block as | |
| 152 | + * shown <a href="#be">above</a>, in order to implement asynchronous | |
| 153 | + * closing and interruption for this channel. </p> | |
| 154 | + */ | |
| 155 | + protected final void begin() { | |
| 156 | + if (interruptor == null) { | |
| 157 | + interruptor = new Interruptible() { | |
| 158 | + public void interrupt(Thread target) { | |
| 159 | + synchronized (closeLock) { | |
| 160 | + if (!open) | |
| 161 | + return; | |
| 162 | + open = false; | |
| 163 | + interrupted = target; | |
| 164 | + try { | |
| 165 | + AbstractInterruptibleChannel.this.implCloseChannel(); | |
| 166 | + } catch (IOException x) { } | |
| 167 | + } | |
| 168 | + }}; | |
| 169 | + } | |
| 170 | + blockedOn(interruptor); | |
| 171 | + Thread me = Thread.currentThread(); | |
| 172 | + if (me.isInterrupted()) | |
| 173 | + interruptor.interrupt(me); | |
| 174 | + } | |
| 175 | + | |
| 176 | + /** | |
| 177 | + * Marks the end of an I/O operation that might block indefinitely. | |
| 178 | + * | |
| 179 | + * <p> This method should be invoked in tandem with the {@link #begin | |
| 180 | + * begin} method, using a <tt>try</tt> ... <tt>finally</tt> block | |
| 181 | + * as shown <a href="#be">above</a>, in order to implement asynchronous | |
| 182 | + * closing and interruption for this channel. </p> | |
| 183 | + * | |
| 184 | + * @param completed | |
| 185 | + * <tt>true</tt> if, and only if, the I/O operation completed | |
| 186 | + * successfully, that is, had some effect that would be visible to | |
| 187 | + * the operation's invoker | |
| 188 | + * | |
| 189 | + * @throws AsynchronousCloseException | |
| 190 | + * If the channel was asynchronously closed | |
| 191 | + * | |
| 192 | + * @throws ClosedByInterruptException | |
| 193 | + * If the thread blocked in the I/O operation was interrupted | |
| 194 | + */ | |
| 195 | + protected final void end(boolean completed) | |
| 196 | + throws AsynchronousCloseException | |
| 197 | + { | |
| 198 | + blockedOn(null); | |
| 199 | + Thread interrupted = this.interrupted; | |
| 200 | + if (interrupted != null && interrupted == Thread.currentThread()) { | |
| 201 | + interrupted = null; | |
| 202 | + throw new ClosedByInterruptException(); | |
| 203 | + } | |
| 204 | + if (!completed && !open) | |
| 205 | + throw new AsynchronousCloseException(); | |
| 206 | + } | |
| 207 | + | |
| 208 | + | |
| 209 | + // -- sun.misc.SharedSecrets -- | |
| 210 | + static void blockedOn(Interruptible intr) { // package-private | |
| 211 | + sun.misc.SharedSecrets.getJavaLangAccess().blockedOn(Thread.currentThread(), | |
| 212 | + intr); | |
| 213 | + } | |
| 214 | +} | |
Binary file not shown.
| @@ -0,0 +1,305 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels.spi; | |
| 27 | + | |
| 28 | +import java.io.IOException; | |
| 29 | +import java.nio.channels.*; | |
| 30 | + | |
| 31 | + | |
| 32 | +/** | |
| 33 | + * Base implementation class for selectable channels. | |
| 34 | + * | |
| 35 | + * <p> This class defines methods that handle the mechanics of channel | |
| 36 | + * registration, deregistration, and closing. It maintains the current | |
| 37 | + * blocking mode of this channel as well as its current set of selection keys. | |
| 38 | + * It performs all of the synchronization required to implement the {@link | |
| 39 | + * java.nio.channels.SelectableChannel} specification. Implementations of the | |
| 40 | + * abstract protected methods defined in this class need not synchronize | |
| 41 | + * against other threads that might be engaged in the same operations. </p> | |
| 42 | + * | |
| 43 | + * | |
| 44 | + * @author Mark Reinhold | |
| 45 | + * @author Mike McCloskey | |
| 46 | + * @author JSR-51 Expert Group | |
| 47 | + * @since 1.4 | |
| 48 | + */ | |
| 49 | + | |
| 50 | +public abstract class AbstractSelectableChannel | |
| 51 | + extends SelectableChannel | |
| 52 | +{ | |
| 53 | + | |
| 54 | + // The provider that created this channel | |
| 55 | + private final SelectorProvider provider; | |
| 56 | + | |
| 57 | + // Keys that have been created by registering this channel with selectors. | |
| 58 | + // They are saved because if this channel is closed the keys must be | |
| 59 | + // deregistered. Protected by keyLock. | |
| 60 | + // | |
| 61 | + private SelectionKey[] keys = null; | |
| 62 | + private int keyCount = 0; | |
| 63 | + | |
| 64 | + // Lock for key set and count | |
| 65 | + private final Object keyLock = new Object(); | |
| 66 | + | |
| 67 | + // Lock for registration and configureBlocking operations | |
| 68 | + private final Object regLock = new Object(); | |
| 69 | + | |
| 70 | + // Blocking mode, protected by regLock | |
| 71 | + boolean blocking = true; | |
| 72 | + | |
| 73 | + /** | |
| 74 | + * Initializes a new instance of this class. | |
| 75 | + */ | |
| 76 | + protected AbstractSelectableChannel(SelectorProvider provider) { | |
| 77 | + this.provider = provider; | |
| 78 | + } | |
| 79 | + | |
| 80 | + /** | |
| 81 | + * Returns the provider that created this channel. | |
| 82 | + * | |
| 83 | + * @return The provider that created this channel | |
| 84 | + */ | |
| 85 | + public final SelectorProvider provider() { | |
| 86 | + return provider; | |
| 87 | + } | |
| 88 | + | |
| 89 | + | |
| 90 | + // -- Utility methods for the key set -- | |
| 91 | + | |
| 92 | + private void addKey(SelectionKey k) { | |
| 93 | + synchronized (keyLock) { | |
| 94 | + int i = 0; | |
| 95 | + if ((keys != null) && (keyCount < keys.length)) { | |
| 96 | + // Find empty element of key array | |
| 97 | + for (i = 0; i < keys.length; i++) | |
| 98 | + if (keys[i] == null) | |
| 99 | + break; | |
| 100 | + } else if (keys == null) { | |
| 101 | + keys = new SelectionKey[3]; | |
| 102 | + } else { | |
| 103 | + // Grow key array | |
| 104 | + int n = keys.length * 2; | |
| 105 | + SelectionKey[] ks = new SelectionKey[n]; | |
| 106 | + for (i = 0; i < keys.length; i++) | |
| 107 | + ks[i] = keys[i]; | |
| 108 | + keys = ks; | |
| 109 | + i = keyCount; | |
| 110 | + } | |
| 111 | + keys[i] = k; | |
| 112 | + keyCount++; | |
| 113 | + } | |
| 114 | + } | |
| 115 | + | |
| 116 | + private SelectionKey findKey(Selector sel) { | |
| 117 | + synchronized (keyLock) { | |
| 118 | + if (keys == null) | |
| 119 | + return null; | |
| 120 | + for (int i = 0; i < keys.length; i++) | |
| 121 | + if ((keys[i] != null) && (keys[i].selector() == sel)) | |
| 122 | + return keys[i]; | |
| 123 | + return null; | |
| 124 | + } | |
| 125 | + } | |
| 126 | + | |
| 127 | + void removeKey(SelectionKey k) { // package-private | |
| 128 | + synchronized (keyLock) { | |
| 129 | + for (int i = 0; i < keys.length; i++) | |
| 130 | + if (keys[i] == k) { | |
| 131 | + keys[i] = null; | |
| 132 | + keyCount--; | |
| 133 | + } | |
| 134 | + ((AbstractSelectionKey)k).invalidate(); | |
| 135 | + } | |
| 136 | + } | |
| 137 | + | |
| 138 | + private boolean haveValidKeys() { | |
| 139 | + synchronized (keyLock) { | |
| 140 | + if (keyCount == 0) | |
| 141 | + return false; | |
| 142 | + for (int i = 0; i < keys.length; i++) { | |
| 143 | + if ((keys[i] != null) && keys[i].isValid()) | |
| 144 | + return true; | |
| 145 | + } | |
| 146 | + return false; | |
| 147 | + } | |
| 148 | + } | |
| 149 | + | |
| 150 | + | |
| 151 | + // -- Registration -- | |
| 152 | + | |
| 153 | + public final boolean isRegistered() { | |
| 154 | + synchronized (keyLock) { | |
| 155 | + return keyCount != 0; | |
| 156 | + } | |
| 157 | + } | |
| 158 | + | |
| 159 | + public final SelectionKey keyFor(Selector sel) { | |
| 160 | + return findKey(sel); | |
| 161 | + } | |
| 162 | + | |
| 163 | + /** | |
| 164 | + * Registers this channel with the given selector, returning a selection key. | |
| 165 | + * | |
| 166 | + * <p> This method first verifies that this channel is open and that the | |
| 167 | + * given initial interest set is valid. | |
| 168 | + * | |
| 169 | + * <p> If this channel is already registered with the given selector then | |
| 170 | + * the selection key representing that registration is returned after | |
| 171 | + * setting its interest set to the given value. | |
| 172 | + * | |
| 173 | + * <p> Otherwise this channel has not yet been registered with the given | |
| 174 | + * selector, so the {@link AbstractSelector#register register} method of | |
| 175 | + * the selector is invoked while holding the appropriate locks. The | |
| 176 | + * resulting key is added to this channel's key set before being returned. | |
| 177 | + * </p> | |
| 178 | + * | |
| 179 | + * @throws ClosedSelectorException {@inheritDoc} | |
| 180 | + * | |
| 181 | + * @throws IllegalBlockingModeException {@inheritDoc} | |
| 182 | + * | |
| 183 | + * @throws IllegalSelectorException {@inheritDoc} | |
| 184 | + * | |
| 185 | + * @throws CancelledKeyException {@inheritDoc} | |
| 186 | + * | |
| 187 | + * @throws IllegalArgumentException {@inheritDoc} | |
| 188 | + */ | |
| 189 | + public final SelectionKey register(Selector sel, int ops, | |
| 190 | + Object att) | |
| 191 | + throws ClosedChannelException | |
| 192 | + { | |
| 193 | + if (!isOpen()) | |
| 194 | + throw new ClosedChannelException(); | |
| 195 | + if ((ops & ~validOps()) != 0) | |
| 196 | + throw new IllegalArgumentException(); | |
| 197 | + synchronized (regLock) { | |
| 198 | + if (blocking) | |
| 199 | + throw new IllegalBlockingModeException(); | |
| 200 | + SelectionKey k = findKey(sel); | |
| 201 | + if (k != null) { | |
| 202 | + k.interestOps(ops); | |
| 203 | + k.attach(att); | |
| 204 | + } | |
| 205 | + if (k == null) { | |
| 206 | + // New registration | |
| 207 | + k = ((AbstractSelector)sel).register(this, ops, att); | |
| 208 | + addKey(k); | |
| 209 | + } | |
| 210 | + return k; | |
| 211 | + } | |
| 212 | + } | |
| 213 | + | |
| 214 | + | |
| 215 | + // -- Closing -- | |
| 216 | + | |
| 217 | + /** | |
| 218 | + * Closes this channel. | |
| 219 | + * | |
| 220 | + * <p> This method, which is specified in the {@link | |
| 221 | + * AbstractInterruptibleChannel} class and is invoked by the {@link | |
| 222 | + * java.nio.channels.Channel#close close} method, in turn invokes the | |
| 223 | + * {@link #implCloseSelectableChannel implCloseSelectableChannel} method in | |
| 224 | + * order to perform the actual work of closing this channel. It then | |
| 225 | + * cancels all of this channel's keys. </p> | |
| 226 | + */ | |
| 227 | + protected final void implCloseChannel() throws IOException { | |
| 228 | + implCloseSelectableChannel(); | |
| 229 | + synchronized (keyLock) { | |
| 230 | + int count = (keys == null) ? 0 : keys.length; | |
| 231 | + for (int i = 0; i < count; i++) { | |
| 232 | + SelectionKey k = keys[i]; | |
| 233 | + if (k != null) | |
| 234 | + k.cancel(); | |
| 235 | + } | |
| 236 | + } | |
| 237 | + } | |
| 238 | + | |
| 239 | + /** | |
| 240 | + * Closes this selectable channel. | |
| 241 | + * | |
| 242 | + * <p> This method is invoked by the {@link java.nio.channels.Channel#close | |
| 243 | + * close} method in order to perform the actual work of closing the | |
| 244 | + * channel. This method is only invoked if the channel has not yet been | |
| 245 | + * closed, and it is never invoked more than once. | |
| 246 | + * | |
| 247 | + * <p> An implementation of this method must arrange for any other thread | |
| 248 | + * that is blocked in an I/O operation upon this channel to return | |
| 249 | + * immediately, either by throwing an exception or by returning normally. | |
| 250 | + * </p> | |
| 251 | + */ | |
| 252 | + protected abstract void implCloseSelectableChannel() throws IOException; | |
| 253 | + | |
| 254 | + | |
| 255 | + // -- Blocking -- | |
| 256 | + | |
| 257 | + public final boolean isBlocking() { | |
| 258 | + synchronized (regLock) { | |
| 259 | + return blocking; | |
| 260 | + } | |
| 261 | + } | |
| 262 | + | |
| 263 | + public final Object blockingLock() { | |
| 264 | + return regLock; | |
| 265 | + } | |
| 266 | + | |
| 267 | + /** | |
| 268 | + * Adjusts this channel's blocking mode. | |
| 269 | + * | |
| 270 | + * <p> If the given blocking mode is different from the current blocking | |
| 271 | + * mode then this method invokes the {@link #implConfigureBlocking | |
| 272 | + * implConfigureBlocking} method, while holding the appropriate locks, in | |
| 273 | + * order to change the mode. </p> | |
| 274 | + */ | |
| 275 | + public final SelectableChannel configureBlocking(boolean block) | |
| 276 | + throws IOException | |
| 277 | + { | |
| 278 | + if (!isOpen()) | |
| 279 | + throw new ClosedChannelException(); | |
| 280 | + synchronized (regLock) { | |
| 281 | + if (blocking == block) | |
| 282 | + return this; | |
| 283 | + if (block && haveValidKeys()) | |
| 284 | + throw new IllegalBlockingModeException(); | |
| 285 | + implConfigureBlocking(block); | |
| 286 | + blocking = block; | |
| 287 | + } | |
| 288 | + return this; | |
| 289 | + } | |
| 290 | + | |
| 291 | + /** | |
| 292 | + * Adjusts this channel's blocking mode. | |
| 293 | + * | |
| 294 | + * <p> This method is invoked by the {@link #configureBlocking | |
| 295 | + * configureBlocking} method in order to perform the actual work of | |
| 296 | + * changing the blocking mode. This method is only invoked if the new mode | |
| 297 | + * is different from the current mode. </p> | |
| 298 | + * | |
| 299 | + * @throws IOException | |
| 300 | + * If an I/O error occurs | |
| 301 | + */ | |
| 302 | + protected abstract void implConfigureBlocking(boolean block) | |
| 303 | + throws IOException; | |
| 304 | + | |
| 305 | +} | |
Binary file not shown.
| @@ -0,0 +1,77 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels.spi; | |
| 27 | + | |
| 28 | +import java.nio.channels.*; | |
| 29 | + | |
| 30 | + | |
| 31 | +/** | |
| 32 | + * Base implementation class for selection keys. | |
| 33 | + * | |
| 34 | + * <p> This class tracks the validity of the key and implements cancellation. | |
| 35 | + * | |
| 36 | + * @author Mark Reinhold | |
| 37 | + * @author JSR-51 Expert Group | |
| 38 | + * @since 1.4 | |
| 39 | + */ | |
| 40 | + | |
| 41 | +public abstract class AbstractSelectionKey | |
| 42 | + extends SelectionKey | |
| 43 | +{ | |
| 44 | + | |
| 45 | + /** | |
| 46 | + * Initializes a new instance of this class. </p> | |
| 47 | + */ | |
| 48 | + protected AbstractSelectionKey() { } | |
| 49 | + | |
| 50 | + private volatile boolean valid = true; | |
| 51 | + | |
| 52 | + public final boolean isValid() { | |
| 53 | + return valid; | |
| 54 | + } | |
| 55 | + | |
| 56 | + void invalidate() { // package-private | |
| 57 | + valid = false; | |
| 58 | + } | |
| 59 | + | |
| 60 | + /** | |
| 61 | + * Cancels this key. | |
| 62 | + * | |
| 63 | + * <p> If this key has not yet been cancelled then it is added to its | |
| 64 | + * selector's cancelled-key set while synchronized on that set. </p> | |
| 65 | + */ | |
| 66 | + public final void cancel() { | |
| 67 | + // Synchronizing "this" to prevent this key from getting canceled | |
| 68 | + // multiple times by different threads, which might cause race | |
| 69 | + // condition between selector's select() and channel's close(). | |
| 70 | + synchronized (this) { | |
| 71 | + if (valid) { | |
| 72 | + valid = false; | |
| 73 | + ((AbstractSelector)selector()).cancel(this); | |
| 74 | + } | |
| 75 | + } | |
| 76 | + } | |
| 77 | +} | |
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,231 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels.spi; | |
| 27 | + | |
| 28 | +import java.io.IOException; | |
| 29 | +import java.nio.channels.SelectionKey; | |
| 30 | +import java.nio.channels.Selector; | |
| 31 | +import java.util.HashSet; | |
| 32 | +import java.util.Set; | |
| 33 | +import sun.nio.ch.Interruptible; | |
| 34 | +import java.util.concurrent.atomic.AtomicBoolean; | |
| 35 | + | |
| 36 | + | |
| 37 | +/** | |
| 38 | + * Base implementation class for selectors. | |
| 39 | + * | |
| 40 | + * <p> This class encapsulates the low-level machinery required to implement | |
| 41 | + * the interruption of selection operations. A concrete selector class must | |
| 42 | + * invoke the {@link #begin begin} and {@link #end end} methods before and | |
| 43 | + * after, respectively, invoking an I/O operation that might block | |
| 44 | + * indefinitely. In order to ensure that the {@link #end end} method is always | |
| 45 | + * invoked, these methods should be used within a | |
| 46 | + * <tt>try</tt> ... <tt>finally</tt> block: <a name="be"> | |
| 47 | + * | |
| 48 | + * <blockquote><pre> | |
| 49 | + * try { | |
| 50 | + * begin(); | |
| 51 | + * // Perform blocking I/O operation here | |
| 52 | + * ... | |
| 53 | + * } finally { | |
| 54 | + * end(); | |
| 55 | + * }</pre></blockquote> | |
| 56 | + * | |
| 57 | + * <p> This class also defines methods for maintaining a selector's | |
| 58 | + * cancelled-key set and for removing a key from its channel's key set, and | |
| 59 | + * declares the abstract {@link #register register} method that is invoked by a | |
| 60 | + * selectable channel's {@link AbstractSelectableChannel#register register} | |
| 61 | + * method in order to perform the actual work of registering a channel. </p> | |
| 62 | + * | |
| 63 | + * | |
| 64 | + * @author Mark Reinhold | |
| 65 | + * @author JSR-51 Expert Group | |
| 66 | + * @since 1.4 | |
| 67 | + */ | |
| 68 | + | |
| 69 | +public abstract class AbstractSelector | |
| 70 | + extends Selector | |
| 71 | +{ | |
| 72 | + | |
| 73 | + private AtomicBoolean selectorOpen = new AtomicBoolean(true); | |
| 74 | + | |
| 75 | + // The provider that created this selector | |
| 76 | + private final SelectorProvider provider; | |
| 77 | + | |
| 78 | + /** | |
| 79 | + * Initializes a new instance of this class. </p> | |
| 80 | + */ | |
| 81 | + protected AbstractSelector(SelectorProvider provider) { | |
| 82 | + this.provider = provider; | |
| 83 | + } | |
| 84 | + | |
| 85 | + private final Set<SelectionKey> cancelledKeys = new HashSet<SelectionKey>(); | |
| 86 | + | |
| 87 | + void cancel(SelectionKey k) { // package-private | |
| 88 | + synchronized (cancelledKeys) { | |
| 89 | + cancelledKeys.add(k); | |
| 90 | + } | |
| 91 | + } | |
| 92 | + | |
| 93 | + /** | |
| 94 | + * Closes this selector. | |
| 95 | + * | |
| 96 | + * <p> If the selector has already been closed then this method returns | |
| 97 | + * immediately. Otherwise it marks the selector as closed and then invokes | |
| 98 | + * the {@link #implCloseSelector implCloseSelector} method in order to | |
| 99 | + * complete the close operation. </p> | |
| 100 | + * | |
| 101 | + * @throws IOException | |
| 102 | + * If an I/O error occurs | |
| 103 | + */ | |
| 104 | + public final void close() throws IOException { | |
| 105 | + boolean open = selectorOpen.getAndSet(false); | |
| 106 | + if (!open) | |
| 107 | + return; | |
| 108 | + implCloseSelector(); | |
| 109 | + } | |
| 110 | + | |
| 111 | + /** | |
| 112 | + * Closes this selector. | |
| 113 | + * | |
| 114 | + * <p> This method is invoked by the {@link #close close} method in order | |
| 115 | + * to perform the actual work of closing the selector. This method is only | |
| 116 | + * invoked if the selector has not yet been closed, and it is never invoked | |
| 117 | + * more than once. | |
| 118 | + * | |
| 119 | + * <p> An implementation of this method must arrange for any other thread | |
| 120 | + * that is blocked in a selection operation upon this selector to return | |
| 121 | + * immediately as if by invoking the {@link | |
| 122 | + * java.nio.channels.Selector#wakeup wakeup} method. </p> | |
| 123 | + * | |
| 124 | + * @throws IOException | |
| 125 | + * If an I/O error occurs while closing the selector | |
| 126 | + */ | |
| 127 | + protected abstract void implCloseSelector() throws IOException; | |
| 128 | + | |
| 129 | + public final boolean isOpen() { | |
| 130 | + return selectorOpen.get(); | |
| 131 | + } | |
| 132 | + | |
| 133 | + /** | |
| 134 | + * Returns the provider that created this channel. | |
| 135 | + * | |
| 136 | + * @return The provider that created this channel | |
| 137 | + */ | |
| 138 | + public final SelectorProvider provider() { | |
| 139 | + return provider; | |
| 140 | + } | |
| 141 | + | |
| 142 | + /** | |
| 143 | + * Retrieves this selector's cancelled-key set. | |
| 144 | + * | |
| 145 | + * <p> This set should only be used while synchronized upon it. </p> | |
| 146 | + * | |
| 147 | + * @return The cancelled-key set | |
| 148 | + */ | |
| 149 | + protected final Set<SelectionKey> cancelledKeys() { | |
| 150 | + return cancelledKeys; | |
| 151 | + } | |
| 152 | + | |
| 153 | + /** | |
| 154 | + * Registers the given channel with this selector. | |
| 155 | + * | |
| 156 | + * <p> This method is invoked by a channel's {@link | |
| 157 | + * AbstractSelectableChannel#register register} method in order to perform | |
| 158 | + * the actual work of registering the channel with this selector. </p> | |
| 159 | + * | |
| 160 | + * @param ch | |
| 161 | + * The channel to be registered | |
| 162 | + * | |
| 163 | + * @param ops | |
| 164 | + * The initial interest set, which must be valid | |
| 165 | + * | |
| 166 | + * @param att | |
| 167 | + * The initial attachment for the resulting key | |
| 168 | + * | |
| 169 | + * @return A new key representing the registration of the given channel | |
| 170 | + * with this selector | |
| 171 | + */ | |
| 172 | + protected abstract SelectionKey register(AbstractSelectableChannel ch, | |
| 173 | + int ops, Object att); | |
| 174 | + | |
| 175 | + /** | |
| 176 | + * Removes the given key from its channel's key set. | |
| 177 | + * | |
| 178 | + * <p> This method must be invoked by the selector for each channel that it | |
| 179 | + * deregisters. </p> | |
| 180 | + * | |
| 181 | + * @param key | |
| 182 | + * The selection key to be removed | |
| 183 | + */ | |
| 184 | + protected final void deregister(AbstractSelectionKey key) { | |
| 185 | + ((AbstractSelectableChannel)key.channel()).removeKey(key); | |
| 186 | + } | |
| 187 | + | |
| 188 | + | |
| 189 | + // -- Interruption machinery -- | |
| 190 | + | |
| 191 | + private Interruptible interruptor = null; | |
| 192 | + | |
| 193 | + /** | |
| 194 | + * Marks the beginning of an I/O operation that might block indefinitely. | |
| 195 | + * | |
| 196 | + * <p> This method should be invoked in tandem with the {@link #end end} | |
| 197 | + * method, using a <tt>try</tt> ... <tt>finally</tt> block as | |
| 198 | + * shown <a href="#be">above</a>, in order to implement interruption for | |
| 199 | + * this selector. | |
| 200 | + * | |
| 201 | + * <p> Invoking this method arranges for the selector's {@link | |
| 202 | + * Selector#wakeup wakeup} method to be invoked if a thread's {@link | |
| 203 | + * Thread#interrupt interrupt} method is invoked while the thread is | |
| 204 | + * blocked in an I/O operation upon the selector. </p> | |
| 205 | + */ | |
| 206 | + protected final void begin() { | |
| 207 | + if (interruptor == null) { | |
| 208 | + interruptor = new Interruptible() { | |
| 209 | + public void interrupt(Thread ignore) { | |
| 210 | + AbstractSelector.this.wakeup(); | |
| 211 | + }}; | |
| 212 | + } | |
| 213 | + AbstractInterruptibleChannel.blockedOn(interruptor); | |
| 214 | + Thread me = Thread.currentThread(); | |
| 215 | + if (me.isInterrupted()) | |
| 216 | + interruptor.interrupt(me); | |
| 217 | + } | |
| 218 | + | |
| 219 | + /** | |
| 220 | + * Marks the end of an I/O operation that might block indefinitely. | |
| 221 | + * | |
| 222 | + * <p> This method should be invoked in tandem with the {@link #begin begin} | |
| 223 | + * method, using a <tt>try</tt> ... <tt>finally</tt> block as | |
| 224 | + * shown <a href="#be">above</a>, in order to implement interruption for | |
| 225 | + * this selector. </p> | |
| 226 | + */ | |
| 227 | + protected final void end() { | |
| 228 | + AbstractInterruptibleChannel.blockedOn(null); | |
| 229 | + } | |
| 230 | + | |
| 231 | +} | |
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,241 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels.spi; | |
| 27 | + | |
| 28 | +import java.nio.channels.*; | |
| 29 | +import java.io.IOException; | |
| 30 | +import java.util.Iterator; | |
| 31 | +import java.util.ServiceLoader; | |
| 32 | +import java.util.ServiceConfigurationError; | |
| 33 | +import java.util.concurrent.*; | |
| 34 | +import java.security.AccessController; | |
| 35 | +import java.security.PrivilegedAction; | |
| 36 | + | |
| 37 | +/** | |
| 38 | + * Service-provider class for asynchronous channels. | |
| 39 | + * | |
| 40 | + * <p> An asynchronous channel provider is a concrete subclass of this class that | |
| 41 | + * has a zero-argument constructor and implements the abstract methods specified | |
| 42 | + * below. A given invocation of the Java virtual machine maintains a single | |
| 43 | + * system-wide default provider instance, which is returned by the {@link | |
| 44 | + * #provider() provider} method. The first invocation of that method will locate | |
| 45 | + * the default provider as specified below. | |
| 46 | + * | |
| 47 | + * <p> All of the methods in this class are safe for use by multiple concurrent | |
| 48 | + * threads. </p> | |
| 49 | + * | |
| 50 | + * @since 1.7 | |
| 51 | + */ | |
| 52 | + | |
| 53 | +public abstract class AsynchronousChannelProvider { | |
| 54 | + private static Void checkPermission() { | |
| 55 | + SecurityManager sm = System.getSecurityManager(); | |
| 56 | + if (sm != null) | |
| 57 | + sm.checkPermission(new RuntimePermission("asynchronousChannelProvider")); | |
| 58 | + return null; | |
| 59 | + } | |
| 60 | + private AsynchronousChannelProvider(Void ignore) { } | |
| 61 | + | |
| 62 | + /** | |
| 63 | + * Initializes a new instance of this class. | |
| 64 | + * | |
| 65 | + * @throws SecurityException | |
| 66 | + * If a security manager has been installed and it denies | |
| 67 | + * {@link RuntimePermission}<tt>("asynchronousChannelProvider")</tt> | |
| 68 | + */ | |
| 69 | + protected AsynchronousChannelProvider() { | |
| 70 | + this(checkPermission()); | |
| 71 | + } | |
| 72 | + | |
| 73 | + // lazy initialization of default provider | |
| 74 | + private static class ProviderHolder { | |
| 75 | + static final AsynchronousChannelProvider provider = load(); | |
| 76 | + | |
| 77 | + private static AsynchronousChannelProvider load() { | |
| 78 | + return AccessController | |
| 79 | + .doPrivileged(new PrivilegedAction<AsynchronousChannelProvider>() { | |
| 80 | + public AsynchronousChannelProvider run() { | |
| 81 | + AsynchronousChannelProvider p; | |
| 82 | + p = loadProviderFromProperty(); | |
| 83 | + if (p != null) | |
| 84 | + return p; | |
| 85 | + p = loadProviderAsService(); | |
| 86 | + if (p != null) | |
| 87 | + return p; | |
| 88 | + return sun.nio.ch.DefaultAsynchronousChannelProvider.create(); | |
| 89 | + }}); | |
| 90 | + } | |
| 91 | + | |
| 92 | + private static AsynchronousChannelProvider loadProviderFromProperty() { | |
| 93 | + String cn = System.getProperty("java.nio.channels.spi.AsynchronousChannelProvider"); | |
| 94 | + if (cn == null) | |
| 95 | + return null; | |
| 96 | + try { | |
| 97 | + Class<?> c = Class.forName(cn, true, | |
| 98 | + ClassLoader.getSystemClassLoader()); | |
| 99 | + return (AsynchronousChannelProvider)c.newInstance(); | |
| 100 | + } catch (ClassNotFoundException x) { | |
| 101 | + throw new ServiceConfigurationError(null, x); | |
| 102 | + } catch (IllegalAccessException x) { | |
| 103 | + throw new ServiceConfigurationError(null, x); | |
| 104 | + } catch (InstantiationException x) { | |
| 105 | + throw new ServiceConfigurationError(null, x); | |
| 106 | + } catch (SecurityException x) { | |
| 107 | + throw new ServiceConfigurationError(null, x); | |
| 108 | + } | |
| 109 | + } | |
| 110 | + | |
| 111 | + private static AsynchronousChannelProvider loadProviderAsService() { | |
| 112 | + ServiceLoader<AsynchronousChannelProvider> sl = | |
| 113 | + ServiceLoader.load(AsynchronousChannelProvider.class, | |
| 114 | + ClassLoader.getSystemClassLoader()); | |
| 115 | + Iterator<AsynchronousChannelProvider> i = sl.iterator(); | |
| 116 | + for (;;) { | |
| 117 | + try { | |
| 118 | + return (i.hasNext()) ? i.next() : null; | |
| 119 | + } catch (ServiceConfigurationError sce) { | |
| 120 | + if (sce.getCause() instanceof SecurityException) { | |
| 121 | + // Ignore the security exception, try the next provider | |
| 122 | + continue; | |
| 123 | + } | |
| 124 | + throw sce; | |
| 125 | + } | |
| 126 | + } | |
| 127 | + } | |
| 128 | + } | |
| 129 | + | |
| 130 | + /** | |
| 131 | + * Returns the system-wide default asynchronous channel provider for this | |
| 132 | + * invocation of the Java virtual machine. | |
| 133 | + * | |
| 134 | + * <p> The first invocation of this method locates the default provider | |
| 135 | + * object as follows: </p> | |
| 136 | + * | |
| 137 | + * <ol> | |
| 138 | + * | |
| 139 | + * <li><p> If the system property | |
| 140 | + * <tt>java.nio.channels.spi.AsynchronousChannelProvider</tt> is defined | |
| 141 | + * then it is taken to be the fully-qualified name of a concrete provider class. | |
| 142 | + * The class is loaded and instantiated; if this process fails then an | |
| 143 | + * unspecified error is thrown. </p></li> | |
| 144 | + * | |
| 145 | + * <li><p> If a provider class has been installed in a jar file that is | |
| 146 | + * visible to the system class loader, and that jar file contains a | |
| 147 | + * provider-configuration file named | |
| 148 | + * <tt>java.nio.channels.spi.AsynchronousChannelProvider</tt> in the resource | |
| 149 | + * directory <tt>META-INF/services</tt>, then the first class name | |
| 150 | + * specified in that file is taken. The class is loaded and | |
| 151 | + * instantiated; if this process fails then an unspecified error is | |
| 152 | + * thrown. </p></li> | |
| 153 | + * | |
| 154 | + * <li><p> Finally, if no provider has been specified by any of the above | |
| 155 | + * means then the system-default provider class is instantiated and the | |
| 156 | + * result is returned. </p></li> | |
| 157 | + * | |
| 158 | + * </ol> | |
| 159 | + * | |
| 160 | + * <p> Subsequent invocations of this method return the provider that was | |
| 161 | + * returned by the first invocation. </p> | |
| 162 | + * | |
| 163 | + * @return The system-wide default AsynchronousChannel provider | |
| 164 | + */ | |
| 165 | + public static AsynchronousChannelProvider provider() { | |
| 166 | + return ProviderHolder.provider; | |
| 167 | + } | |
| 168 | + | |
| 169 | + /** | |
| 170 | + * Constructs a new asynchronous channel group with a fixed thread pool. | |
| 171 | + * | |
| 172 | + * @param nThreads | |
| 173 | + * The number of threads in the pool | |
| 174 | + * @param threadFactory | |
| 175 | + * The factory to use when creating new threads | |
| 176 | + * | |
| 177 | + * @throws IllegalArgumentException | |
| 178 | + * If {@code nThreads <= 0} | |
| 179 | + * @throws IOException | |
| 180 | + * If an I/O error occurs | |
| 181 | + * | |
| 182 | + * @see AsynchronousChannelGroup#withFixedThreadPool | |
| 183 | + */ | |
| 184 | + public abstract AsynchronousChannelGroup | |
| 185 | + openAsynchronousChannelGroup(int nThreads, ThreadFactory threadFactory) throws IOException; | |
| 186 | + | |
| 187 | + /** | |
| 188 | + * Constructs a new asynchronous channel group with the given thread pool. | |
| 189 | + * | |
| 190 | + * @param executor | |
| 191 | + * The thread pool | |
| 192 | + * @param initialSize | |
| 193 | + * A value {@code >=0} or a negative value for implementation | |
| 194 | + * specific default | |
| 195 | + * | |
| 196 | + * @throws IOException | |
| 197 | + * If an I/O error occurs | |
| 198 | + * | |
| 199 | + * @see AsynchronousChannelGroup#withCachedThreadPool | |
| 200 | + */ | |
| 201 | + public abstract AsynchronousChannelGroup | |
| 202 | + openAsynchronousChannelGroup(ExecutorService executor, int initialSize) throws IOException; | |
| 203 | + | |
| 204 | + /** | |
| 205 | + * Opens an asynchronous server-socket channel. | |
| 206 | + * | |
| 207 | + * @param group | |
| 208 | + * The group to which the channel is bound, or {@code null} to | |
| 209 | + * bind to the default group | |
| 210 | + * | |
| 211 | + * @return The new channel | |
| 212 | + * | |
| 213 | + * @throws IllegalChannelGroupException | |
| 214 | + * If the provider that created the group differs from this provider | |
| 215 | + * @throws ShutdownChannelGroupException | |
| 216 | + * The group is shutdown | |
| 217 | + * @throws IOException | |
| 218 | + * If an I/O error occurs | |
| 219 | + */ | |
| 220 | + public abstract AsynchronousServerSocketChannel openAsynchronousServerSocketChannel | |
| 221 | + (AsynchronousChannelGroup group) throws IOException; | |
| 222 | + | |
| 223 | + /** | |
| 224 | + * Opens an asynchronous socket channel. | |
| 225 | + * | |
| 226 | + * @param group | |
| 227 | + * The group to which the channel is bound, or {@code null} to | |
| 228 | + * bind to the default group | |
| 229 | + * | |
| 230 | + * @return The new channel | |
| 231 | + * | |
| 232 | + * @throws IllegalChannelGroupException | |
| 233 | + * If the provider that created the group differs from this provider | |
| 234 | + * @throws ShutdownChannelGroupException | |
| 235 | + * The group is shutdown | |
| 236 | + * @throws IOException | |
| 237 | + * If an I/O error occurs | |
| 238 | + */ | |
| 239 | + public abstract AsynchronousSocketChannel openAsynchronousSocketChannel | |
| 240 | + (AsynchronousChannelGroup group) throws IOException; | |
| 241 | +} | |
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,302 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.channels.spi; | |
| 27 | + | |
| 28 | +import java.io.IOException; | |
| 29 | +import java.net.ProtocolFamily; | |
| 30 | +import java.nio.channels.*; | |
| 31 | +import java.security.AccessController; | |
| 32 | +import java.security.PrivilegedAction; | |
| 33 | +import java.util.Iterator; | |
| 34 | +import java.util.ServiceLoader; | |
| 35 | +import java.util.ServiceConfigurationError; | |
| 36 | +import sun.security.action.GetPropertyAction; | |
| 37 | + | |
| 38 | + | |
| 39 | +/** | |
| 40 | + * Service-provider class for selectors and selectable channels. | |
| 41 | + * | |
| 42 | + * <p> A selector provider is a concrete subclass of this class that has a | |
| 43 | + * zero-argument constructor and implements the abstract methods specified | |
| 44 | + * below. A given invocation of the Java virtual machine maintains a single | |
| 45 | + * system-wide default provider instance, which is returned by the {@link | |
| 46 | + * #provider() provider} method. The first invocation of that method will locate | |
| 47 | + * the default provider as specified below. | |
| 48 | + * | |
| 49 | + * <p> The system-wide default provider is used by the static <tt>open</tt> | |
| 50 | + * methods of the {@link java.nio.channels.DatagramChannel#open | |
| 51 | + * DatagramChannel}, {@link java.nio.channels.Pipe#open Pipe}, {@link | |
| 52 | + * java.nio.channels.Selector#open Selector}, {@link | |
| 53 | + * java.nio.channels.ServerSocketChannel#open ServerSocketChannel}, and {@link | |
| 54 | + * java.nio.channels.SocketChannel#open SocketChannel} classes. It is also | |
| 55 | + * used by the {@link java.lang.System#inheritedChannel System.inheritedChannel()} | |
| 56 | + * method. A program may make use of a provider other than the default provider | |
| 57 | + * by instantiating that provider and then directly invoking the <tt>open</tt> | |
| 58 | + * methods defined in this class. | |
| 59 | + * | |
| 60 | + * <p> All of the methods in this class are safe for use by multiple concurrent | |
| 61 | + * threads. </p> | |
| 62 | + * | |
| 63 | + * | |
| 64 | + * @author Mark Reinhold | |
| 65 | + * @author JSR-51 Expert Group | |
| 66 | + * @since 1.4 | |
| 67 | + */ | |
| 68 | + | |
| 69 | +public abstract class SelectorProvider { | |
| 70 | + | |
| 71 | + private static final Object lock = new Object(); | |
| 72 | + private static SelectorProvider provider = null; | |
| 73 | + | |
| 74 | + /** | |
| 75 | + * Initializes a new instance of this class. </p> | |
| 76 | + * | |
| 77 | + * @throws SecurityException | |
| 78 | + * If a security manager has been installed and it denies | |
| 79 | + * {@link RuntimePermission}<tt>("selectorProvider")</tt> | |
| 80 | + */ | |
| 81 | + protected SelectorProvider() { | |
| 82 | + SecurityManager sm = System.getSecurityManager(); | |
| 83 | + if (sm != null) | |
| 84 | + sm.checkPermission(new RuntimePermission("selectorProvider")); | |
| 85 | + } | |
| 86 | + | |
| 87 | + private static boolean loadProviderFromProperty() { | |
| 88 | + String cn = System.getProperty("java.nio.channels.spi.SelectorProvider"); | |
| 89 | + if (cn == null) | |
| 90 | + return false; | |
| 91 | + try { | |
| 92 | + Class<?> c = Class.forName(cn, true, | |
| 93 | + ClassLoader.getSystemClassLoader()); | |
| 94 | + provider = (SelectorProvider)c.newInstance(); | |
| 95 | + return true; | |
| 96 | + } catch (ClassNotFoundException x) { | |
| 97 | + throw new ServiceConfigurationError(null, x); | |
| 98 | + } catch (IllegalAccessException x) { | |
| 99 | + throw new ServiceConfigurationError(null, x); | |
| 100 | + } catch (InstantiationException x) { | |
| 101 | + throw new ServiceConfigurationError(null, x); | |
| 102 | + } catch (SecurityException x) { | |
| 103 | + throw new ServiceConfigurationError(null, x); | |
| 104 | + } | |
| 105 | + } | |
| 106 | + | |
| 107 | + private static boolean loadProviderAsService() { | |
| 108 | + | |
| 109 | + ServiceLoader<SelectorProvider> sl = | |
| 110 | + ServiceLoader.load(SelectorProvider.class, | |
| 111 | + ClassLoader.getSystemClassLoader()); | |
| 112 | + Iterator<SelectorProvider> i = sl.iterator(); | |
| 113 | + for (;;) { | |
| 114 | + try { | |
| 115 | + if (!i.hasNext()) | |
| 116 | + return false; | |
| 117 | + provider = i.next(); | |
| 118 | + return true; | |
| 119 | + } catch (ServiceConfigurationError sce) { | |
| 120 | + if (sce.getCause() instanceof SecurityException) { | |
| 121 | + // Ignore the security exception, try the next provider | |
| 122 | + continue; | |
| 123 | + } | |
| 124 | + throw sce; | |
| 125 | + } | |
| 126 | + } | |
| 127 | + } | |
| 128 | + | |
| 129 | + /** | |
| 130 | + * Returns the system-wide default selector provider for this invocation of | |
| 131 | + * the Java virtual machine. | |
| 132 | + * | |
| 133 | + * <p> The first invocation of this method locates the default provider | |
| 134 | + * object as follows: </p> | |
| 135 | + * | |
| 136 | + * <ol> | |
| 137 | + * | |
| 138 | + * <li><p> If the system property | |
| 139 | + * <tt>java.nio.channels.spi.SelectorProvider</tt> is defined then it is | |
| 140 | + * taken to be the fully-qualified name of a concrete provider class. | |
| 141 | + * The class is loaded and instantiated; if this process fails then an | |
| 142 | + * unspecified error is thrown. </p></li> | |
| 143 | + * | |
| 144 | + * <li><p> If a provider class has been installed in a jar file that is | |
| 145 | + * visible to the system class loader, and that jar file contains a | |
| 146 | + * provider-configuration file named | |
| 147 | + * <tt>java.nio.channels.spi.SelectorProvider</tt> in the resource | |
| 148 | + * directory <tt>META-INF/services</tt>, then the first class name | |
| 149 | + * specified in that file is taken. The class is loaded and | |
| 150 | + * instantiated; if this process fails then an unspecified error is | |
| 151 | + * thrown. </p></li> | |
| 152 | + * | |
| 153 | + * <li><p> Finally, if no provider has been specified by any of the above | |
| 154 | + * means then the system-default provider class is instantiated and the | |
| 155 | + * result is returned. </p></li> | |
| 156 | + * | |
| 157 | + * </ol> | |
| 158 | + * | |
| 159 | + * <p> Subsequent invocations of this method return the provider that was | |
| 160 | + * returned by the first invocation. </p> | |
| 161 | + * | |
| 162 | + * @return The system-wide default selector provider | |
| 163 | + */ | |
| 164 | + public static SelectorProvider provider() { | |
| 165 | + synchronized (lock) { | |
| 166 | + if (provider != null) | |
| 167 | + return provider; | |
| 168 | + return AccessController.doPrivileged( | |
| 169 | + new PrivilegedAction<SelectorProvider>() { | |
| 170 | + public SelectorProvider run() { | |
| 171 | + if (loadProviderFromProperty()) | |
| 172 | + return provider; | |
| 173 | + if (loadProviderAsService()) | |
| 174 | + return provider; | |
| 175 | + provider = sun.nio.ch.DefaultSelectorProvider.create(); | |
| 176 | + return provider; | |
| 177 | + } | |
| 178 | + }); | |
| 179 | + } | |
| 180 | + } | |
| 181 | + | |
| 182 | + /** | |
| 183 | + * Opens a datagram channel. </p> | |
| 184 | + * | |
| 185 | + * @return The new channel | |
| 186 | + */ | |
| 187 | + public abstract DatagramChannel openDatagramChannel() | |
| 188 | + throws IOException; | |
| 189 | + | |
| 190 | + /** | |
| 191 | + * Opens a datagram channel. | |
| 192 | + * | |
| 193 | + * @param family | |
| 194 | + * The protocol family | |
| 195 | + * | |
| 196 | + * @return A new datagram channel | |
| 197 | + * | |
| 198 | + * @throws UnsupportedOperationException | |
| 199 | + * If the specified protocol family is not supported | |
| 200 | + * @throws IOException | |
| 201 | + * If an I/O error occurs | |
| 202 | + * | |
| 203 | + * @since 1.7 | |
| 204 | + */ | |
| 205 | + public abstract DatagramChannel openDatagramChannel(ProtocolFamily family) | |
| 206 | + throws IOException; | |
| 207 | + | |
| 208 | + /** | |
| 209 | + * Opens a pipe. </p> | |
| 210 | + * | |
| 211 | + * @return The new pipe | |
| 212 | + */ | |
| 213 | + public abstract Pipe openPipe() | |
| 214 | + throws IOException; | |
| 215 | + | |
| 216 | + /** | |
| 217 | + * Opens a selector. </p> | |
| 218 | + * | |
| 219 | + * @return The new selector | |
| 220 | + */ | |
| 221 | + public abstract AbstractSelector openSelector() | |
| 222 | + throws IOException; | |
| 223 | + | |
| 224 | + /** | |
| 225 | + * Opens a server-socket channel. </p> | |
| 226 | + * | |
| 227 | + * @return The new channel | |
| 228 | + */ | |
| 229 | + public abstract ServerSocketChannel openServerSocketChannel() | |
| 230 | + throws IOException; | |
| 231 | + | |
| 232 | + /** | |
| 233 | + * Opens a socket channel. </p> | |
| 234 | + * | |
| 235 | + * @return The new channel | |
| 236 | + */ | |
| 237 | + public abstract SocketChannel openSocketChannel() | |
| 238 | + throws IOException; | |
| 239 | + | |
| 240 | + /** | |
| 241 | + * Returns the channel inherited from the entity that created this | |
| 242 | + * Java virtual machine. | |
| 243 | + * | |
| 244 | + * <p> On many operating systems a process, such as a Java virtual | |
| 245 | + * machine, can be started in a manner that allows the process to | |
| 246 | + * inherit a channel from the entity that created the process. The | |
| 247 | + * manner in which this is done is system dependent, as are the | |
| 248 | + * possible entities to which the channel may be connected. For example, | |
| 249 | + * on UNIX systems, the Internet services daemon (<i>inetd</i>) is used to | |
| 250 | + * start programs to service requests when a request arrives on an | |
| 251 | + * associated network port. In this example, the process that is started, | |
| 252 | + * inherits a channel representing a network socket. | |
| 253 | + * | |
| 254 | + * <p> In cases where the inherited channel represents a network socket | |
| 255 | + * then the {@link java.nio.channels.Channel Channel} type returned | |
| 256 | + * by this method is determined as follows: | |
| 257 | + * | |
| 258 | + * <ul> | |
| 259 | + * | |
| 260 | + * <li><p> If the inherited channel represents a stream-oriented connected | |
| 261 | + * socket then a {@link java.nio.channels.SocketChannel SocketChannel} is | |
| 262 | + * returned. The socket channel is, at least initially, in blocking | |
| 263 | + * mode, bound to a socket address, and connected to a peer. | |
| 264 | + * </p></li> | |
| 265 | + * | |
| 266 | + * <li><p> If the inherited channel represents a stream-oriented listening | |
| 267 | + * socket then a {@link java.nio.channels.ServerSocketChannel | |
| 268 | + * ServerSocketChannel} is returned. The server-socket channel is, at | |
| 269 | + * least initially, in blocking mode, and bound to a socket address. | |
| 270 | + * </p></li> | |
| 271 | + * | |
| 272 | + * <li><p> If the inherited channel is a datagram-oriented socket | |
| 273 | + * then a {@link java.nio.channels.DatagramChannel DatagramChannel} is | |
| 274 | + * returned. The datagram channel is, at least initially, in blocking | |
| 275 | + * mode, and bound to a socket address. | |
| 276 | + * </p></li> | |
| 277 | + * | |
| 278 | + * </ul> | |
| 279 | + * | |
| 280 | + * <p> In addition to the network-oriented channels described, this method | |
| 281 | + * may return other kinds of channels in the future. | |
| 282 | + * | |
| 283 | + * <p> The first invocation of this method creates the channel that is | |
| 284 | + * returned. Subsequent invocations of this method return the same | |
| 285 | + * channel. </p> | |
| 286 | + * | |
| 287 | + * @return The inherited channel, if any, otherwise <tt>null</tt>. | |
| 288 | + * | |
| 289 | + * @throws IOException | |
| 290 | + * If an I/O error occurs | |
| 291 | + * | |
| 292 | + * @throws SecurityException | |
| 293 | + * If a security manager has been installed and it denies | |
| 294 | + * {@link RuntimePermission}<tt>("inheritedChannel")</tt> | |
| 295 | + * | |
| 296 | + * @since 1.5 | |
| 297 | + */ | |
| 298 | + public Channel inheritedChannel() throws IOException { | |
| 299 | + return null; | |
| 300 | + } | |
| 301 | + | |
| 302 | +} | |
| @@ -0,0 +1,13 @@ | ||
| 1 | +<../../../../../../mkconfig | |
| 2 | + | |
| 3 | +TARG=\ | |
| 4 | + AbstractInterruptibleChannel.dis\ | |
| 5 | + AbstractSelectableChannel.dis\ | |
| 6 | + AbstractSelectionKey.dis\ | |
| 7 | + AbstractSelector.dis\ | |
| 8 | + AsynchronousChannelProvider.dis\ | |
| 9 | + SelectorProvider.dis\ | |
| 10 | + | |
| 11 | +DISBIN=$ROOT/java/dis/java/java/java/nio/channels/spi | |
| 12 | + | |
| 13 | +<$ROOT/mkfiles/mkjava | |
| @@ -0,0 +1,45 @@ | ||
| 1 | +<!-- | |
| 2 | + Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + | |
| 5 | + This code is free software; you can redistribute it and/or modify it | |
| 6 | + under the terms of the GNU General Public License version 2 only, as | |
| 7 | + published by the Free Software Foundation. Oracle designates this | |
| 8 | + particular file as subject to the "Classpath" exception as provided | |
| 9 | + by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + | |
| 11 | + This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + accompanied this code). | |
| 16 | + | |
| 17 | + You should have received a copy of the GNU General Public License version | |
| 18 | + 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + | |
| 21 | + Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + or visit www.oracle.com if you need additional information or have any | |
| 23 | + questions. | |
| 24 | +--> | |
| 25 | + | |
| 26 | +<!doctype html public "-//IETF//DTD HTML//EN"> | |
| 27 | +<html> | |
| 28 | +<body bgcolor="white"> | |
| 29 | + | |
| 30 | +Service-provider classes for the <tt>{@link java.nio.channels}</tt> package. | |
| 31 | + | |
| 32 | +<p> Only developers who are defining new selector providers or asynchronous | |
| 33 | +channel providers should need to make direct use of this package. </p> | |
| 34 | + | |
| 35 | +<p> Unless otherwise noted, passing a <tt>null</tt> argument to a constructor | |
| 36 | +or method in any class or interface in this package will cause a {@link | |
| 37 | +java.lang.NullPointerException NullPointerException} to be thrown. | |
| 38 | + | |
| 39 | + | |
| 40 | +@since 1.4 | |
| 41 | +@author Mark Reinhold | |
| 42 | +@author JSR-51 Expert Group | |
| 43 | + | |
| 44 | +</body> | |
| 45 | +</html> | |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,972 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +#warn This file is preprocessed before being compiled | |
| 27 | + | |
| 28 | +package java.nio.charset; | |
| 29 | + | |
| 30 | +import java.nio.Buffer; | |
| 31 | +import java.nio.ByteBuffer; | |
| 32 | +import java.nio.CharBuffer; | |
| 33 | +import java.nio.BufferOverflowException; | |
| 34 | +import java.nio.BufferUnderflowException; | |
| 35 | +import java.lang.ref.WeakReference; | |
| 36 | +import java.nio.charset.CoderMalfunctionError; // javadoc | |
| 37 | + | |
| 38 | + | |
| 39 | +/** | |
| 40 | + * An engine that can transform a sequence of $itypesPhrase$ into a sequence of | |
| 41 | + * $otypesPhrase$. | |
| 42 | + * | |
| 43 | + * <a name="steps"> | |
| 44 | + * | |
| 45 | + * <p> The input $itype$ sequence is provided in a $itype$ buffer or a series | |
| 46 | + * of such buffers. The output $otype$ sequence is written to a $otype$ buffer | |
| 47 | + * or a series of such buffers. $A$ $coder$ should always be used by making | |
| 48 | + * the following sequence of method invocations, hereinafter referred to as $a$ | |
| 49 | + * <i>$coding$ operation</i>: | |
| 50 | + * | |
| 51 | + * <ol> | |
| 52 | + * | |
| 53 | + * <li><p> Reset the $coder$ via the {@link #reset reset} method, unless it | |
| 54 | + * has not been used before; </p></li> | |
| 55 | + * | |
| 56 | + * <li><p> Invoke the {@link #$code$ $code$} method zero or more times, as | |
| 57 | + * long as additional input may be available, passing <tt>false</tt> for the | |
| 58 | + * <tt>endOfInput</tt> argument and filling the input buffer and flushing the | |
| 59 | + * output buffer between invocations; </p></li> | |
| 60 | + * | |
| 61 | + * <li><p> Invoke the {@link #$code$ $code$} method one final time, passing | |
| 62 | + * <tt>true</tt> for the <tt>endOfInput</tt> argument; and then </p></li> | |
| 63 | + * | |
| 64 | + * <li><p> Invoke the {@link #flush flush} method so that the $coder$ can | |
| 65 | + * flush any internal state to the output buffer. </p></li> | |
| 66 | + * | |
| 67 | + * </ol> | |
| 68 | + * | |
| 69 | + * Each invocation of the {@link #$code$ $code$} method will $code$ as many | |
| 70 | + * $itype$s as possible from the input buffer, writing the resulting $otype$s | |
| 71 | + * to the output buffer. The {@link #$code$ $code$} method returns when more | |
| 72 | + * input is required, when there is not enough room in the output buffer, or | |
| 73 | + * when $a$ $coding$ error has occurred. In each case a {@link CoderResult} | |
| 74 | + * object is returned to describe the reason for termination. An invoker can | |
| 75 | + * examine this object and fill the input buffer, flush the output buffer, or | |
| 76 | + * attempt to recover from $a$ $coding$ error, as appropriate, and try again. | |
| 77 | + * | |
| 78 | + * <a name="ce"> | |
| 79 | + * | |
| 80 | + * <p> There are two general types of $coding$ errors. If the input $itype$ | |
| 81 | + * sequence is $notLegal$ then the input is considered <i>malformed</i>. If | |
| 82 | + * the input $itype$ sequence is legal but cannot be mapped to a valid | |
| 83 | + * $outSequence$ then an <i>unmappable character</i> has been encountered. | |
| 84 | + * | |
| 85 | + * <a name="cae"> | |
| 86 | + * | |
| 87 | + * <p> How $a$ $coding$ error is handled depends upon the action requested for | |
| 88 | + * that type of error, which is described by an instance of the {@link | |
| 89 | + * CodingErrorAction} class. The possible error actions are to {@link | |
| 90 | + * CodingErrorAction#IGNORE </code>ignore<code>} the erroneous input, {@link | |
| 91 | + * CodingErrorAction#REPORT </code>report<code>} the error to the invoker via | |
| 92 | + * the returned {@link CoderResult} object, or {@link CodingErrorAction#REPLACE | |
| 93 | + * </code>replace<code>} the erroneous input with the current value of the | |
| 94 | + * replacement $replTypeName$. The replacement | |
| 95 | + * | |
| 96 | +#if[encoder] | |
| 97 | + * is initially set to the $coder$'s default replacement, which often | |
| 98 | + * (but not always) has the initial value $defaultReplName$; | |
| 99 | +#end[encoder] | |
| 100 | +#if[decoder] | |
| 101 | + * has the initial value $defaultReplName$; | |
| 102 | +#end[decoder] | |
| 103 | + * | |
| 104 | + * its value may be changed via the {@link #replaceWith($replFQType$) | |
| 105 | + * replaceWith} method. | |
| 106 | + * | |
| 107 | + * <p> The default action for malformed-input and unmappable-character errors | |
| 108 | + * is to {@link CodingErrorAction#REPORT </code>report<code>} them. The | |
| 109 | + * malformed-input error action may be changed via the {@link | |
| 110 | + * #onMalformedInput(CodingErrorAction) onMalformedInput} method; the | |
| 111 | + * unmappable-character action may be changed via the {@link | |
| 112 | + * #onUnmappableCharacter(CodingErrorAction) onUnmappableCharacter} method. | |
| 113 | + * | |
| 114 | + * <p> This class is designed to handle many of the details of the $coding$ | |
| 115 | + * process, including the implementation of error actions. $A$ $coder$ for a | |
| 116 | + * specific charset, which is a concrete subclass of this class, need only | |
| 117 | + * implement the abstract {@link #$code$Loop $code$Loop} method, which | |
| 118 | + * encapsulates the basic $coding$ loop. A subclass that maintains internal | |
| 119 | + * state should, additionally, override the {@link #implFlush implFlush} and | |
| 120 | + * {@link #implReset implReset} methods. | |
| 121 | + * | |
| 122 | + * <p> Instances of this class are not safe for use by multiple concurrent | |
| 123 | + * threads. </p> | |
| 124 | + * | |
| 125 | + * | |
| 126 | + * @author Mark Reinhold | |
| 127 | + * @author JSR-51 Expert Group | |
| 128 | + * @since 1.4 | |
| 129 | + * | |
| 130 | + * @see ByteBuffer | |
| 131 | + * @see CharBuffer | |
| 132 | + * @see Charset | |
| 133 | + * @see Charset$OtherCoder$ | |
| 134 | + */ | |
| 135 | + | |
| 136 | +public abstract class Charset$Coder$ { | |
| 137 | + | |
| 138 | + private final Charset charset; | |
| 139 | + private final float average$ItypesPerOtype$; | |
| 140 | + private final float max$ItypesPerOtype$; | |
| 141 | + | |
| 142 | + private $replType$ replacement; | |
| 143 | + private CodingErrorAction malformedInputAction | |
| 144 | + = CodingErrorAction.REPORT; | |
| 145 | + private CodingErrorAction unmappableCharacterAction | |
| 146 | + = CodingErrorAction.REPORT; | |
| 147 | + | |
| 148 | + // Internal states | |
| 149 | + // | |
| 150 | + private static final int ST_RESET = 0; | |
| 151 | + private static final int ST_CODING = 1; | |
| 152 | + private static final int ST_END = 2; | |
| 153 | + private static final int ST_FLUSHED = 3; | |
| 154 | + | |
| 155 | + private int state = ST_RESET; | |
| 156 | + | |
| 157 | + private static String stateNames[] | |
| 158 | + = { "RESET", "CODING", "CODING_END", "FLUSHED" }; | |
| 159 | + | |
| 160 | + | |
| 161 | + /** | |
| 162 | + * Initializes a new $coder$. The new $coder$ will have the given | |
| 163 | + * $otypes-per-itype$ and replacement values. </p> | |
| 164 | + * | |
| 165 | + * @param average$ItypesPerOtype$ | |
| 166 | + * A positive float value indicating the expected number of | |
| 167 | + * $otype$s that will be produced for each input $itype$ | |
| 168 | + * | |
| 169 | + * @param max$ItypesPerOtype$ | |
| 170 | + * A positive float value indicating the maximum number of | |
| 171 | + * $otype$s that will be produced for each input $itype$ | |
| 172 | + * | |
| 173 | + * @param replacement | |
| 174 | + * The initial replacement; must not be <tt>null</tt>, must have | |
| 175 | + * non-zero length, must not be longer than max$ItypesPerOtype$, | |
| 176 | + * and must be {@link #isLegalReplacement </code>legal<code>} | |
| 177 | + * | |
| 178 | + * @throws IllegalArgumentException | |
| 179 | + * If the preconditions on the parameters do not hold | |
| 180 | + */ | |
| 181 | + {#if[encoder]?protected:private} | |
| 182 | + Charset$Coder$(Charset cs, | |
| 183 | + float average$ItypesPerOtype$, | |
| 184 | + float max$ItypesPerOtype$, | |
| 185 | + $replType$ replacement) | |
| 186 | + { | |
| 187 | + this.charset = cs; | |
| 188 | + if (average$ItypesPerOtype$ <= 0.0f) | |
| 189 | + throw new IllegalArgumentException("Non-positive " | |
| 190 | + + "average$ItypesPerOtype$"); | |
| 191 | + if (max$ItypesPerOtype$ <= 0.0f) | |
| 192 | + throw new IllegalArgumentException("Non-positive " | |
| 193 | + + "max$ItypesPerOtype$"); | |
| 194 | + if (!Charset.atBugLevel("1.4")) { | |
| 195 | + if (average$ItypesPerOtype$ > max$ItypesPerOtype$) | |
| 196 | + throw new IllegalArgumentException("average$ItypesPerOtype$" | |
| 197 | + + " exceeds " | |
| 198 | + + "max$ItypesPerOtype$"); | |
| 199 | + } | |
| 200 | + this.replacement = replacement; | |
| 201 | + this.average$ItypesPerOtype$ = average$ItypesPerOtype$; | |
| 202 | + this.max$ItypesPerOtype$ = max$ItypesPerOtype$; | |
| 203 | + replaceWith(replacement); | |
| 204 | + } | |
| 205 | + | |
| 206 | + /** | |
| 207 | + * Initializes a new $coder$. The new $coder$ will have the given | |
| 208 | + * $otypes-per-itype$ values and its replacement will be the | |
| 209 | + * $replTypeName$ $defaultReplName$. </p> | |
| 210 | + * | |
| 211 | + * @param average$ItypesPerOtype$ | |
| 212 | + * A positive float value indicating the expected number of | |
| 213 | + * $otype$s that will be produced for each input $itype$ | |
| 214 | + * | |
| 215 | + * @param max$ItypesPerOtype$ | |
| 216 | + * A positive float value indicating the maximum number of | |
| 217 | + * $otype$s that will be produced for each input $itype$ | |
| 218 | + * | |
| 219 | + * @throws IllegalArgumentException | |
| 220 | + * If the preconditions on the parameters do not hold | |
| 221 | + */ | |
| 222 | + protected Charset$Coder$(Charset cs, | |
| 223 | + float average$ItypesPerOtype$, | |
| 224 | + float max$ItypesPerOtype$) | |
| 225 | + { | |
| 226 | + this(cs, | |
| 227 | + average$ItypesPerOtype$, max$ItypesPerOtype$, | |
| 228 | + $defaultRepl$); | |
| 229 | + } | |
| 230 | + | |
| 231 | + /** | |
| 232 | + * Returns the charset that created this $coder$. </p> | |
| 233 | + * | |
| 234 | + * @return This $coder$'s charset | |
| 235 | + */ | |
| 236 | + public final Charset charset() { | |
| 237 | + return charset; | |
| 238 | + } | |
| 239 | + | |
| 240 | + /** | |
| 241 | + * Returns this $coder$'s replacement value. </p> | |
| 242 | + * | |
| 243 | + * @return This $coder$'s current replacement, | |
| 244 | + * which is never <tt>null</tt> and is never empty | |
| 245 | + */ | |
| 246 | + public final $replType$ replacement() { | |
| 247 | + return replacement; | |
| 248 | + } | |
| 249 | + | |
| 250 | + /** | |
| 251 | + * Changes this $coder$'s replacement value. | |
| 252 | + * | |
| 253 | + * <p> This method invokes the {@link #implReplaceWith implReplaceWith} | |
| 254 | + * method, passing the new replacement, after checking that the new | |
| 255 | + * replacement is acceptable. </p> | |
| 256 | + * | |
| 257 | + * @param newReplacement | |
| 258 | + * | |
| 259 | +#if[decoder] | |
| 260 | + * The new replacement; must not be <tt>null</tt> | |
| 261 | + * and must have non-zero length | |
| 262 | +#end[decoder] | |
| 263 | +#if[encoder] | |
| 264 | + * The new replacement; must not be <tt>null</tt>, must have | |
| 265 | + * non-zero length, must not be longer than the value returned by | |
| 266 | + * the {@link #max$ItypesPerOtype$() max$ItypesPerOtype$} method, and | |
| 267 | + * must be {@link #isLegalReplacement </code>legal<code>} | |
| 268 | +#end[encoder] | |
| 269 | + * | |
| 270 | + * @return This $coder$ | |
| 271 | + * | |
| 272 | + * @throws IllegalArgumentException | |
| 273 | + * If the preconditions on the parameter do not hold | |
| 274 | + */ | |
| 275 | + public final Charset$Coder$ replaceWith($replType$ newReplacement) { | |
| 276 | + if (newReplacement == null) | |
| 277 | + throw new IllegalArgumentException("Null replacement"); | |
| 278 | + int len = newReplacement.$replLength$; | |
| 279 | + if (len == 0) | |
| 280 | + throw new IllegalArgumentException("Empty replacement"); | |
| 281 | + if (len > max$ItypesPerOtype$) | |
| 282 | + throw new IllegalArgumentException("Replacement too long"); | |
| 283 | +#if[encoder] | |
| 284 | + if (!isLegalReplacement(newReplacement)) | |
| 285 | + throw new IllegalArgumentException("Illegal replacement"); | |
| 286 | +#end[encoder] | |
| 287 | + this.replacement = newReplacement; | |
| 288 | + implReplaceWith(newReplacement); | |
| 289 | + return this; | |
| 290 | + } | |
| 291 | + | |
| 292 | + /** | |
| 293 | + * Reports a change to this $coder$'s replacement value. | |
| 294 | + * | |
| 295 | + * <p> The default implementation of this method does nothing. This method | |
| 296 | + * should be overridden by $coder$s that require notification of changes to | |
| 297 | + * the replacement. </p> | |
| 298 | + * | |
| 299 | + * @param newReplacement | |
| 300 | + */ | |
| 301 | + protected void implReplaceWith($replType$ newReplacement) { | |
| 302 | + } | |
| 303 | + | |
| 304 | +#if[encoder] | |
| 305 | + | |
| 306 | + private WeakReference<CharsetDecoder> cachedDecoder = null; | |
| 307 | + | |
| 308 | + /** | |
| 309 | + * Tells whether or not the given byte array is a legal replacement value | |
| 310 | + * for this encoder. | |
| 311 | + * | |
| 312 | + * <p> A replacement is legal if, and only if, it is a legal sequence of | |
| 313 | + * bytes in this encoder's charset; that is, it must be possible to decode | |
| 314 | + * the replacement into one or more sixteen-bit Unicode characters. | |
| 315 | + * | |
| 316 | + * <p> The default implementation of this method is not very efficient; it | |
| 317 | + * should generally be overridden to improve performance. </p> | |
| 318 | + * | |
| 319 | + * @param repl The byte array to be tested | |
| 320 | + * | |
| 321 | + * @return <tt>true</tt> if, and only if, the given byte array | |
| 322 | + * is a legal replacement value for this encoder | |
| 323 | + */ | |
| 324 | + public boolean isLegalReplacement(byte[] repl) { | |
| 325 | + WeakReference<CharsetDecoder> wr = cachedDecoder; | |
| 326 | + CharsetDecoder dec = null; | |
| 327 | + if ((wr == null) || ((dec = wr.get()) == null)) { | |
| 328 | + dec = charset().newDecoder(); | |
| 329 | + dec.onMalformedInput(CodingErrorAction.REPORT); | |
| 330 | + dec.onUnmappableCharacter(CodingErrorAction.REPORT); | |
| 331 | + cachedDecoder = new WeakReference<CharsetDecoder>(dec); | |
| 332 | + } else { | |
| 333 | + dec.reset(); | |
| 334 | + } | |
| 335 | + ByteBuffer bb = ByteBuffer.wrap(repl); | |
| 336 | + CharBuffer cb = CharBuffer.allocate((int)(bb.remaining() | |
| 337 | + * dec.maxCharsPerByte())); | |
| 338 | + CoderResult cr = dec.decode(bb, cb, true); | |
| 339 | + return !cr.isError(); | |
| 340 | + } | |
| 341 | + | |
| 342 | +#end[encoder] | |
| 343 | + | |
| 344 | + /** | |
| 345 | + * Returns this $coder$'s current action for malformed-input errors. </p> | |
| 346 | + * | |
| 347 | + * @return The current malformed-input action, which is never <tt>null</tt> | |
| 348 | + */ | |
| 349 | + public CodingErrorAction malformedInputAction() { | |
| 350 | + return malformedInputAction; | |
| 351 | + } | |
| 352 | + | |
| 353 | + /** | |
| 354 | + * Changes this $coder$'s action for malformed-input errors. </p> | |
| 355 | + * | |
| 356 | + * <p> This method invokes the {@link #implOnMalformedInput | |
| 357 | + * implOnMalformedInput} method, passing the new action. </p> | |
| 358 | + * | |
| 359 | + * @param newAction The new action; must not be <tt>null</tt> | |
| 360 | + * | |
| 361 | + * @return This $coder$ | |
| 362 | + * | |
| 363 | + * @throws IllegalArgumentException | |
| 364 | + * If the precondition on the parameter does not hold | |
| 365 | + */ | |
| 366 | + public final Charset$Coder$ onMalformedInput(CodingErrorAction newAction) { | |
| 367 | + if (newAction == null) | |
| 368 | + throw new IllegalArgumentException("Null action"); | |
| 369 | + malformedInputAction = newAction; | |
| 370 | + implOnMalformedInput(newAction); | |
| 371 | + return this; | |
| 372 | + } | |
| 373 | + | |
| 374 | + /** | |
| 375 | + * Reports a change to this $coder$'s malformed-input action. | |
| 376 | + * | |
| 377 | + * <p> The default implementation of this method does nothing. This method | |
| 378 | + * should be overridden by $coder$s that require notification of changes to | |
| 379 | + * the malformed-input action. </p> | |
| 380 | + */ | |
| 381 | + protected void implOnMalformedInput(CodingErrorAction newAction) { } | |
| 382 | + | |
| 383 | + /** | |
| 384 | + * Returns this $coder$'s current action for unmappable-character errors. | |
| 385 | + * </p> | |
| 386 | + * | |
| 387 | + * @return The current unmappable-character action, which is never | |
| 388 | + * <tt>null</tt> | |
| 389 | + */ | |
| 390 | + public CodingErrorAction unmappableCharacterAction() { | |
| 391 | + return unmappableCharacterAction; | |
| 392 | + } | |
| 393 | + | |
| 394 | + /** | |
| 395 | + * Changes this $coder$'s action for unmappable-character errors. | |
| 396 | + * | |
| 397 | + * <p> This method invokes the {@link #implOnUnmappableCharacter | |
| 398 | + * implOnUnmappableCharacter} method, passing the new action. </p> | |
| 399 | + * | |
| 400 | + * @param newAction The new action; must not be <tt>null</tt> | |
| 401 | + * | |
| 402 | + * @return This $coder$ | |
| 403 | + * | |
| 404 | + * @throws IllegalArgumentException | |
| 405 | + * If the precondition on the parameter does not hold | |
| 406 | + */ | |
| 407 | + public final Charset$Coder$ onUnmappableCharacter(CodingErrorAction | |
| 408 | + newAction) | |
| 409 | + { | |
| 410 | + if (newAction == null) | |
| 411 | + throw new IllegalArgumentException("Null action"); | |
| 412 | + unmappableCharacterAction = newAction; | |
| 413 | + implOnUnmappableCharacter(newAction); | |
| 414 | + return this; | |
| 415 | + } | |
| 416 | + | |
| 417 | + /** | |
| 418 | + * Reports a change to this $coder$'s unmappable-character action. | |
| 419 | + * | |
| 420 | + * <p> The default implementation of this method does nothing. This method | |
| 421 | + * should be overridden by $coder$s that require notification of changes to | |
| 422 | + * the unmappable-character action. </p> | |
| 423 | + */ | |
| 424 | + protected void implOnUnmappableCharacter(CodingErrorAction newAction) { } | |
| 425 | + | |
| 426 | + /** | |
| 427 | + * Returns the average number of $otype$s that will be produced for each | |
| 428 | + * $itype$ of input. This heuristic value may be used to estimate the size | |
| 429 | + * of the output buffer required for a given input sequence. </p> | |
| 430 | + * | |
| 431 | + * @return The average number of $otype$s produced | |
| 432 | + * per $itype$ of input | |
| 433 | + */ | |
| 434 | + public final float average$ItypesPerOtype$() { | |
| 435 | + return average$ItypesPerOtype$; | |
| 436 | + } | |
| 437 | + | |
| 438 | + /** | |
| 439 | + * Returns the maximum number of $otype$s that will be produced for each | |
| 440 | + * $itype$ of input. This value may be used to compute the worst-case size | |
| 441 | + * of the output buffer required for a given input sequence. </p> | |
| 442 | + * | |
| 443 | + * @return The maximum number of $otype$s that will be produced per | |
| 444 | + * $itype$ of input | |
| 445 | + */ | |
| 446 | + public final float max$ItypesPerOtype$() { | |
| 447 | + return max$ItypesPerOtype$; | |
| 448 | + } | |
| 449 | + | |
| 450 | + /** | |
| 451 | + * $Code$s as many $itype$s as possible from the given input buffer, | |
| 452 | + * writing the results to the given output buffer. | |
| 453 | + * | |
| 454 | + * <p> The buffers are read from, and written to, starting at their current | |
| 455 | + * positions. At most {@link Buffer#remaining in.remaining()} $itype$s | |
| 456 | + * will be read and at most {@link Buffer#remaining out.remaining()} | |
| 457 | + * $otype$s will be written. The buffers' positions will be advanced to | |
| 458 | + * reflect the $itype$s read and the $otype$s written, but their marks and | |
| 459 | + * limits will not be modified. | |
| 460 | + * | |
| 461 | + * <p> In addition to reading $itype$s from the input buffer and writing | |
| 462 | + * $otype$s to the output buffer, this method returns a {@link CoderResult} | |
| 463 | + * object to describe its reason for termination: | |
| 464 | + * | |
| 465 | + * <ul> | |
| 466 | + * | |
| 467 | + * <li><p> {@link CoderResult#UNDERFLOW} indicates that as much of the | |
| 468 | + * input buffer as possible has been $code$d. If there is no further | |
| 469 | + * input then the invoker can proceed to the next step of the | |
| 470 | + * <a href="#steps">$coding$ operation</a>. Otherwise this method | |
| 471 | + * should be invoked again with further input. </p></li> | |
| 472 | + * | |
| 473 | + * <li><p> {@link CoderResult#OVERFLOW} indicates that there is | |
| 474 | + * insufficient space in the output buffer to $code$ any more $itype$s. | |
| 475 | + * This method should be invoked again with an output buffer that has | |
| 476 | + * more {@linkplain Buffer#remaining remaining} $otype$s. This is | |
| 477 | + * typically done by draining any $code$d $otype$s from the output | |
| 478 | + * buffer. </p></li> | |
| 479 | + * | |
| 480 | + * <li><p> A {@link CoderResult#malformedForLength | |
| 481 | + * </code>malformed-input<code>} result indicates that a malformed-input | |
| 482 | + * error has been detected. The malformed $itype$s begin at the input | |
| 483 | + * buffer's (possibly incremented) position; the number of malformed | |
| 484 | + * $itype$s may be determined by invoking the result object's {@link | |
| 485 | + * CoderResult#length() length} method. This case applies only if the | |
| 486 | + * {@link #onMalformedInput </code>malformed action<code>} of this $coder$ | |
| 487 | + * is {@link CodingErrorAction#REPORT}; otherwise the malformed input | |
| 488 | + * will be ignored or replaced, as requested. </p></li> | |
| 489 | + * | |
| 490 | + * <li><p> An {@link CoderResult#unmappableForLength | |
| 491 | + * </code>unmappable-character<code>} result indicates that an | |
| 492 | + * unmappable-character error has been detected. The $itype$s that | |
| 493 | + * $code$ the unmappable character begin at the input buffer's (possibly | |
| 494 | + * incremented) position; the number of such $itype$s may be determined | |
| 495 | + * by invoking the result object's {@link CoderResult#length() length} | |
| 496 | + * method. This case applies only if the {@link #onUnmappableCharacter | |
| 497 | + * </code>unmappable action<code>} of this $coder$ is {@link | |
| 498 | + * CodingErrorAction#REPORT}; otherwise the unmappable character will be | |
| 499 | + * ignored or replaced, as requested. </p></li> | |
| 500 | + * | |
| 501 | + * </ul> | |
| 502 | + * | |
| 503 | + * In any case, if this method is to be reinvoked in the same $coding$ | |
| 504 | + * operation then care should be taken to preserve any $itype$s remaining | |
| 505 | + * in the input buffer so that they are available to the next invocation. | |
| 506 | + * | |
| 507 | + * <p> The <tt>endOfInput</tt> parameter advises this method as to whether | |
| 508 | + * the invoker can provide further input beyond that contained in the given | |
| 509 | + * input buffer. If there is a possibility of providing additional input | |
| 510 | + * then the invoker should pass <tt>false</tt> for this parameter; if there | |
| 511 | + * is no possibility of providing further input then the invoker should | |
| 512 | + * pass <tt>true</tt>. It is not erroneous, and in fact it is quite | |
| 513 | + * common, to pass <tt>false</tt> in one invocation and later discover that | |
| 514 | + * no further input was actually available. It is critical, however, that | |
| 515 | + * the final invocation of this method in a sequence of invocations always | |
| 516 | + * pass <tt>true</tt> so that any remaining un$code$d input will be treated | |
| 517 | + * as being malformed. | |
| 518 | + * | |
| 519 | + * <p> This method works by invoking the {@link #$code$Loop $code$Loop} | |
| 520 | + * method, interpreting its results, handling error conditions, and | |
| 521 | + * reinvoking it as necessary. </p> | |
| 522 | + * | |
| 523 | + * | |
| 524 | + * @param in | |
| 525 | + * The input $itype$ buffer | |
| 526 | + * | |
| 527 | + * @param out | |
| 528 | + * The output $otype$ buffer | |
| 529 | + * | |
| 530 | + * @param endOfInput | |
| 531 | + * <tt>true</tt> if, and only if, the invoker can provide no | |
| 532 | + * additional input $itype$s beyond those in the given buffer | |
| 533 | + * | |
| 534 | + * @return A coder-result object describing the reason for termination | |
| 535 | + * | |
| 536 | + * @throws IllegalStateException | |
| 537 | + * If $a$ $coding$ operation is already in progress and the previous | |
| 538 | + * step was an invocation neither of the {@link #reset reset} | |
| 539 | + * method, nor of this method with a value of <tt>false</tt> for | |
| 540 | + * the <tt>endOfInput</tt> parameter, nor of this method with a | |
| 541 | + * value of <tt>true</tt> for the <tt>endOfInput</tt> parameter | |
| 542 | + * but a return value indicating an incomplete $coding$ operation | |
| 543 | + * | |
| 544 | + * @throws CoderMalfunctionError | |
| 545 | + * If an invocation of the $code$Loop method threw | |
| 546 | + * an unexpected exception | |
| 547 | + */ | |
| 548 | + public final CoderResult $code$($Itype$Buffer in, $Otype$Buffer out, | |
| 549 | + boolean endOfInput) | |
| 550 | + { | |
| 551 | + int newState = endOfInput ? ST_END : ST_CODING; | |
| 552 | + if ((state != ST_RESET) && (state != ST_CODING) | |
| 553 | + && !(endOfInput && (state == ST_END))) | |
| 554 | + throwIllegalStateException(state, newState); | |
| 555 | + state = newState; | |
| 556 | + | |
| 557 | + for (;;) { | |
| 558 | + | |
| 559 | + CoderResult cr; | |
| 560 | + try { | |
| 561 | + cr = $code$Loop(in, out); | |
| 562 | + } catch (BufferUnderflowException x) { | |
| 563 | + throw new CoderMalfunctionError(x); | |
| 564 | + } catch (BufferOverflowException x) { | |
| 565 | + throw new CoderMalfunctionError(x); | |
| 566 | + } | |
| 567 | + | |
| 568 | + if (cr.isOverflow()) | |
| 569 | + return cr; | |
| 570 | + | |
| 571 | + if (cr.isUnderflow()) { | |
| 572 | + if (endOfInput && in.hasRemaining()) { | |
| 573 | + cr = CoderResult.malformedForLength(in.remaining()); | |
| 574 | + // Fall through to malformed-input case | |
| 575 | + } else { | |
| 576 | + return cr; | |
| 577 | + } | |
| 578 | + } | |
| 579 | + | |
| 580 | + CodingErrorAction action = null; | |
| 581 | + if (cr.isMalformed()) | |
| 582 | + action = malformedInputAction; | |
| 583 | + else if (cr.isUnmappable()) | |
| 584 | + action = unmappableCharacterAction; | |
| 585 | + else | |
| 586 | + assert false : cr.toString(); | |
| 587 | + | |
| 588 | + if (action == CodingErrorAction.REPORT) | |
| 589 | + return cr; | |
| 590 | + | |
| 591 | + if (action == CodingErrorAction.REPLACE) { | |
| 592 | + if (out.remaining() < replacement.$replLength$) | |
| 593 | + return CoderResult.OVERFLOW; | |
| 594 | + out.put(replacement); | |
| 595 | + } | |
| 596 | + | |
| 597 | + if ((action == CodingErrorAction.IGNORE) | |
| 598 | + || (action == CodingErrorAction.REPLACE)) { | |
| 599 | + // Skip erroneous input either way | |
| 600 | + in.position(in.position() + cr.length()); | |
| 601 | + continue; | |
| 602 | + } | |
| 603 | + | |
| 604 | + assert false; | |
| 605 | + } | |
| 606 | + | |
| 607 | + } | |
| 608 | + | |
| 609 | + /** | |
| 610 | + * Flushes this $coder$. | |
| 611 | + * | |
| 612 | + * <p> Some $coder$s maintain internal state and may need to write some | |
| 613 | + * final $otype$s to the output buffer once the overall input sequence has | |
| 614 | + * been read. | |
| 615 | + * | |
| 616 | + * <p> Any additional output is written to the output buffer beginning at | |
| 617 | + * its current position. At most {@link Buffer#remaining out.remaining()} | |
| 618 | + * $otype$s will be written. The buffer's position will be advanced | |
| 619 | + * appropriately, but its mark and limit will not be modified. | |
| 620 | + * | |
| 621 | + * <p> If this method completes successfully then it returns {@link | |
| 622 | + * CoderResult#UNDERFLOW}. If there is insufficient room in the output | |
| 623 | + * buffer then it returns {@link CoderResult#OVERFLOW}. If this happens | |
| 624 | + * then this method must be invoked again, with an output buffer that has | |
| 625 | + * more room, in order to complete the current <a href="#steps">$coding$ | |
| 626 | + * operation</a>. | |
| 627 | + * | |
| 628 | + * <p> If this $coder$ has already been flushed then invoking this method | |
| 629 | + * has no effect. | |
| 630 | + * | |
| 631 | + * <p> This method invokes the {@link #implFlush implFlush} method to | |
| 632 | + * perform the actual flushing operation. </p> | |
| 633 | + * | |
| 634 | + * @param out | |
| 635 | + * The output $otype$ buffer | |
| 636 | + * | |
| 637 | + * @return A coder-result object, either {@link CoderResult#UNDERFLOW} or | |
| 638 | + * {@link CoderResult#OVERFLOW} | |
| 639 | + * | |
| 640 | + * @throws IllegalStateException | |
| 641 | + * If the previous step of the current $coding$ operation was an | |
| 642 | + * invocation neither of the {@link #flush flush} method nor of | |
| 643 | + * the three-argument {@link | |
| 644 | + * #$code$($Itype$Buffer,$Otype$Buffer,boolean) $code$} method | |
| 645 | + * with a value of <tt>true</tt> for the <tt>endOfInput</tt> | |
| 646 | + * parameter | |
| 647 | + */ | |
| 648 | + public final CoderResult flush($Otype$Buffer out) { | |
| 649 | + if (state == ST_END) { | |
| 650 | + CoderResult cr = implFlush(out); | |
| 651 | + if (cr.isUnderflow()) | |
| 652 | + state = ST_FLUSHED; | |
| 653 | + return cr; | |
| 654 | + } | |
| 655 | + | |
| 656 | + if (state != ST_FLUSHED) | |
| 657 | + throwIllegalStateException(state, ST_FLUSHED); | |
| 658 | + | |
| 659 | + return CoderResult.UNDERFLOW; // Already flushed | |
| 660 | + } | |
| 661 | + | |
| 662 | + /** | |
| 663 | + * Flushes this $coder$. | |
| 664 | + * | |
| 665 | + * <p> The default implementation of this method does nothing, and always | |
| 666 | + * returns {@link CoderResult#UNDERFLOW}. This method should be overridden | |
| 667 | + * by $coder$s that may need to write final $otype$s to the output buffer | |
| 668 | + * once the entire input sequence has been read. </p> | |
| 669 | + * | |
| 670 | + * @param out | |
| 671 | + * The output $otype$ buffer | |
| 672 | + * | |
| 673 | + * @return A coder-result object, either {@link CoderResult#UNDERFLOW} or | |
| 674 | + * {@link CoderResult#OVERFLOW} | |
| 675 | + */ | |
| 676 | + protected CoderResult implFlush($Otype$Buffer out) { | |
| 677 | + return CoderResult.UNDERFLOW; | |
| 678 | + } | |
| 679 | + | |
| 680 | + /** | |
| 681 | + * Resets this $coder$, clearing any internal state. | |
| 682 | + * | |
| 683 | + * <p> This method resets charset-independent state and also invokes the | |
| 684 | + * {@link #implReset() implReset} method in order to perform any | |
| 685 | + * charset-specific reset actions. </p> | |
| 686 | + * | |
| 687 | + * @return This $coder$ | |
| 688 | + * | |
| 689 | + */ | |
| 690 | + public final Charset$Coder$ reset() { | |
| 691 | + implReset(); | |
| 692 | + state = ST_RESET; | |
| 693 | + return this; | |
| 694 | + } | |
| 695 | + | |
| 696 | + /** | |
| 697 | + * Resets this $coder$, clearing any charset-specific internal state. | |
| 698 | + * | |
| 699 | + * <p> The default implementation of this method does nothing. This method | |
| 700 | + * should be overridden by $coder$s that maintain internal state. </p> | |
| 701 | + */ | |
| 702 | + protected void implReset() { } | |
| 703 | + | |
| 704 | + /** | |
| 705 | + * $Code$s one or more $itype$s into one or more $otype$s. | |
| 706 | + * | |
| 707 | + * <p> This method encapsulates the basic $coding$ loop, $coding$ as many | |
| 708 | + * $itype$s as possible until it either runs out of input, runs out of room | |
| 709 | + * in the output buffer, or encounters $a$ $coding$ error. This method is | |
| 710 | + * invoked by the {@link #$code$ $code$} method, which handles result | |
| 711 | + * interpretation and error recovery. | |
| 712 | + * | |
| 713 | + * <p> The buffers are read from, and written to, starting at their current | |
| 714 | + * positions. At most {@link Buffer#remaining in.remaining()} $itype$s | |
| 715 | + * will be read, and at most {@link Buffer#remaining out.remaining()} | |
| 716 | + * $otype$s will be written. The buffers' positions will be advanced to | |
| 717 | + * reflect the $itype$s read and the $otype$s written, but their marks and | |
| 718 | + * limits will not be modified. | |
| 719 | + * | |
| 720 | + * <p> This method returns a {@link CoderResult} object to describe its | |
| 721 | + * reason for termination, in the same manner as the {@link #$code$ $code$} | |
| 722 | + * method. Most implementations of this method will handle $coding$ errors | |
| 723 | + * by returning an appropriate result object for interpretation by the | |
| 724 | + * {@link #$code$ $code$} method. An optimized implementation may instead | |
| 725 | + * examine the relevant error action and implement that action itself. | |
| 726 | + * | |
| 727 | + * <p> An implementation of this method may perform arbitrary lookahead by | |
| 728 | + * returning {@link CoderResult#UNDERFLOW} until it receives sufficient | |
| 729 | + * input. </p> | |
| 730 | + * | |
| 731 | + * @param in | |
| 732 | + * The input $itype$ buffer | |
| 733 | + * | |
| 734 | + * @param out | |
| 735 | + * The output $otype$ buffer | |
| 736 | + * | |
| 737 | + * @return A coder-result object describing the reason for termination | |
| 738 | + */ | |
| 739 | + protected abstract CoderResult $code$Loop($Itype$Buffer in, | |
| 740 | + $Otype$Buffer out); | |
| 741 | + | |
| 742 | + /** | |
| 743 | + * Convenience method that $code$s the remaining content of a single input | |
| 744 | + * $itype$ buffer into a newly-allocated $otype$ buffer. | |
| 745 | + * | |
| 746 | + * <p> This method implements an entire <a href="#steps">$coding$ | |
| 747 | + * operation</a>; that is, it resets this $coder$, then it $code$s the | |
| 748 | + * $itype$s in the given $itype$ buffer, and finally it flushes this | |
| 749 | + * $coder$. This method should therefore not be invoked if $a$ $coding$ | |
| 750 | + * operation is already in progress. </p> | |
| 751 | + * | |
| 752 | + * @param in | |
| 753 | + * The input $itype$ buffer | |
| 754 | + * | |
| 755 | + * @return A newly-allocated $otype$ buffer containing the result of the | |
| 756 | + * $coding$ operation. The buffer's position will be zero and its | |
| 757 | + * limit will follow the last $otype$ written. | |
| 758 | + * | |
| 759 | + * @throws IllegalStateException | |
| 760 | + * If $a$ $coding$ operation is already in progress | |
| 761 | + * | |
| 762 | + * @throws MalformedInputException | |
| 763 | + * If the $itype$ sequence starting at the input buffer's current | |
| 764 | + * position is $notLegal$ and the current malformed-input action | |
| 765 | + * is {@link CodingErrorAction#REPORT} | |
| 766 | + * | |
| 767 | + * @throws UnmappableCharacterException | |
| 768 | + * If the $itype$ sequence starting at the input buffer's current | |
| 769 | + * position cannot be mapped to an equivalent $otype$ sequence and | |
| 770 | + * the current unmappable-character action is {@link | |
| 771 | + * CodingErrorAction#REPORT} | |
| 772 | + */ | |
| 773 | + public final $Otype$Buffer $code$($Itype$Buffer in) | |
| 774 | + throws CharacterCodingException | |
| 775 | + { | |
| 776 | + int n = (int)(in.remaining() * average$ItypesPerOtype$()); | |
| 777 | + $Otype$Buffer out = $Otype$Buffer.allocate(n); | |
| 778 | + | |
| 779 | + if ((n == 0) && (in.remaining() == 0)) | |
| 780 | + return out; | |
| 781 | + reset(); | |
| 782 | + for (;;) { | |
| 783 | + CoderResult cr = in.hasRemaining() ? | |
| 784 | + $code$(in, out, true) : CoderResult.UNDERFLOW; | |
| 785 | + if (cr.isUnderflow()) | |
| 786 | + cr = flush(out); | |
| 787 | + | |
| 788 | + if (cr.isUnderflow()) | |
| 789 | + break; | |
| 790 | + if (cr.isOverflow()) { | |
| 791 | + n = 2*n + 1; // Ensure progress; n might be 0! | |
| 792 | + $Otype$Buffer o = $Otype$Buffer.allocate(n); | |
| 793 | + out.flip(); | |
| 794 | + o.put(out); | |
| 795 | + out = o; | |
| 796 | + continue; | |
| 797 | + } | |
| 798 | + cr.throwException(); | |
| 799 | + } | |
| 800 | + out.flip(); | |
| 801 | + return out; | |
| 802 | + } | |
| 803 | + | |
| 804 | +#if[decoder] | |
| 805 | + | |
| 806 | + /** | |
| 807 | + * Tells whether or not this decoder implements an auto-detecting charset. | |
| 808 | + * | |
| 809 | + * <p> The default implementation of this method always returns | |
| 810 | + * <tt>false</tt>; it should be overridden by auto-detecting decoders to | |
| 811 | + * return <tt>true</tt>. </p> | |
| 812 | + * | |
| 813 | + * @return <tt>true</tt> if, and only if, this decoder implements an | |
| 814 | + * auto-detecting charset | |
| 815 | + */ | |
| 816 | + public boolean isAutoDetecting() { | |
| 817 | + return false; | |
| 818 | + } | |
| 819 | + | |
| 820 | + /** | |
| 821 | + * Tells whether or not this decoder has yet detected a | |
| 822 | + * charset <i>(optional operation)</i>. | |
| 823 | + * | |
| 824 | + * <p> If this decoder implements an auto-detecting charset then at a | |
| 825 | + * single point during a decoding operation this method may start returning | |
| 826 | + * <tt>true</tt> to indicate that a specific charset has been detected in | |
| 827 | + * the input byte sequence. Once this occurs, the {@link #detectedCharset | |
| 828 | + * detectedCharset} method may be invoked to retrieve the detected charset. | |
| 829 | + * | |
| 830 | + * <p> That this method returns <tt>false</tt> does not imply that no bytes | |
| 831 | + * have yet been decoded. Some auto-detecting decoders are capable of | |
| 832 | + * decoding some, or even all, of an input byte sequence without fixing on | |
| 833 | + * a particular charset. | |
| 834 | + * | |
| 835 | + * <p> The default implementation of this method always throws an {@link | |
| 836 | + * UnsupportedOperationException}; it should be overridden by | |
| 837 | + * auto-detecting decoders to return <tt>true</tt> once the input charset | |
| 838 | + * has been determined. </p> | |
| 839 | + * | |
| 840 | + * @return <tt>true</tt> if, and only if, this decoder has detected a | |
| 841 | + * specific charset | |
| 842 | + * | |
| 843 | + * @throws UnsupportedOperationException | |
| 844 | + * If this decoder does not implement an auto-detecting charset | |
| 845 | + */ | |
| 846 | + public boolean isCharsetDetected() { | |
| 847 | + throw new UnsupportedOperationException(); | |
| 848 | + } | |
| 849 | + | |
| 850 | + /** | |
| 851 | + * Retrieves the charset that was detected by this | |
| 852 | + * decoder <i>(optional operation)</i>. | |
| 853 | + * | |
| 854 | + * <p> If this decoder implements an auto-detecting charset then this | |
| 855 | + * method returns the actual charset once it has been detected. After that | |
| 856 | + * point, this method returns the same value for the duration of the | |
| 857 | + * current decoding operation. If not enough input bytes have yet been | |
| 858 | + * read to determine the actual charset then this method throws an {@link | |
| 859 | + * IllegalStateException}. | |
| 860 | + * | |
| 861 | + * <p> The default implementation of this method always throws an {@link | |
| 862 | + * UnsupportedOperationException}; it should be overridden by | |
| 863 | + * auto-detecting decoders to return the appropriate value. </p> | |
| 864 | + * | |
| 865 | + * @return The charset detected by this auto-detecting decoder, | |
| 866 | + * or <tt>null</tt> if the charset has not yet been determined | |
| 867 | + * | |
| 868 | + * @throws IllegalStateException | |
| 869 | + * If insufficient bytes have been read to determine a charset | |
| 870 | + * | |
| 871 | + * @throws UnsupportedOperationException | |
| 872 | + * If this decoder does not implement an auto-detecting charset | |
| 873 | + */ | |
| 874 | + public Charset detectedCharset() { | |
| 875 | + throw new UnsupportedOperationException(); | |
| 876 | + } | |
| 877 | + | |
| 878 | +#end[decoder] | |
| 879 | + | |
| 880 | +#if[encoder] | |
| 881 | + | |
| 882 | + private boolean canEncode(CharBuffer cb) { | |
| 883 | + if (state == ST_FLUSHED) | |
| 884 | + reset(); | |
| 885 | + else if (state != ST_RESET) | |
| 886 | + throwIllegalStateException(state, ST_CODING); | |
| 887 | + CodingErrorAction ma = malformedInputAction(); | |
| 888 | + CodingErrorAction ua = unmappableCharacterAction(); | |
| 889 | + try { | |
| 890 | + onMalformedInput(CodingErrorAction.REPORT); | |
| 891 | + onUnmappableCharacter(CodingErrorAction.REPORT); | |
| 892 | + encode(cb); | |
| 893 | + } catch (CharacterCodingException x) { | |
| 894 | + return false; | |
| 895 | + } finally { | |
| 896 | + onMalformedInput(ma); | |
| 897 | + onUnmappableCharacter(ua); | |
| 898 | + reset(); | |
| 899 | + } | |
| 900 | + return true; | |
| 901 | + } | |
| 902 | + | |
| 903 | + /** | |
| 904 | + * Tells whether or not this encoder can encode the given character. | |
| 905 | + * | |
| 906 | + * <p> This method returns <tt>false</tt> if the given character is a | |
| 907 | + * surrogate character; such characters can be interpreted only when they | |
| 908 | + * are members of a pair consisting of a high surrogate followed by a low | |
| 909 | + * surrogate. The {@link #canEncode(java.lang.CharSequence) | |
| 910 | + * canEncode(CharSequence)} method may be used to test whether or not a | |
| 911 | + * character sequence can be encoded. | |
| 912 | + * | |
| 913 | + * <p> This method may modify this encoder's state; it should therefore not | |
| 914 | + * be invoked if an <a href="#steps">encoding operation</a> is already in | |
| 915 | + * progress. | |
| 916 | + * | |
| 917 | + * <p> The default implementation of this method is not very efficient; it | |
| 918 | + * should generally be overridden to improve performance. </p> | |
| 919 | + * | |
| 920 | + * @return <tt>true</tt> if, and only if, this encoder can encode | |
| 921 | + * the given character | |
| 922 | + * | |
| 923 | + * @throws IllegalStateException | |
| 924 | + * If $a$ $coding$ operation is already in progress | |
| 925 | + */ | |
| 926 | + public boolean canEncode(char c) { | |
| 927 | + CharBuffer cb = CharBuffer.allocate(1); | |
| 928 | + cb.put(c); | |
| 929 | + cb.flip(); | |
| 930 | + return canEncode(cb); | |
| 931 | + } | |
| 932 | + | |
| 933 | + /** | |
| 934 | + * Tells whether or not this encoder can encode the given character | |
| 935 | + * sequence. | |
| 936 | + * | |
| 937 | + * <p> If this method returns <tt>false</tt> for a particular character | |
| 938 | + * sequence then more information about why the sequence cannot be encoded | |
| 939 | + * may be obtained by performing a full <a href="#steps">encoding | |
| 940 | + * operation</a>. | |
| 941 | + * | |
| 942 | + * <p> This method may modify this encoder's state; it should therefore not | |
| 943 | + * be invoked if an encoding operation is already in progress. | |
| 944 | + * | |
| 945 | + * <p> The default implementation of this method is not very efficient; it | |
| 946 | + * should generally be overridden to improve performance. </p> | |
| 947 | + * | |
| 948 | + * @return <tt>true</tt> if, and only if, this encoder can encode | |
| 949 | + * the given character without throwing any exceptions and without | |
| 950 | + * performing any replacements | |
| 951 | + * | |
| 952 | + * @throws IllegalStateException | |
| 953 | + * If $a$ $coding$ operation is already in progress | |
| 954 | + */ | |
| 955 | + public boolean canEncode(CharSequence cs) { | |
| 956 | + CharBuffer cb; | |
| 957 | + if (cs instanceof CharBuffer) | |
| 958 | + cb = ((CharBuffer)cs).duplicate(); | |
| 959 | + else | |
| 960 | + cb = CharBuffer.wrap(cs.toString()); | |
| 961 | + return canEncode(cb); | |
| 962 | + } | |
| 963 | + | |
| 964 | +#end[encoder] | |
| 965 | + | |
| 966 | + | |
| 967 | + private void throwIllegalStateException(int from, int to) { | |
| 968 | + throw new IllegalStateException("Current state = " + stateNames[from] | |
| 969 | + + ", new state = " + stateNames[to]); | |
| 970 | + } | |
| 971 | + | |
| 972 | +} | |
Binary file not shown.
| @@ -0,0 +1,923 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.charset; | |
| 27 | + | |
| 28 | +import java.nio.ByteBuffer; | |
| 29 | +import java.nio.CharBuffer; | |
| 30 | +import java.nio.charset.spi.CharsetProvider; | |
| 31 | +import java.security.AccessController; | |
| 32 | +import java.security.AccessControlException; | |
| 33 | +import java.security.PrivilegedAction; | |
| 34 | +import java.util.Collections; | |
| 35 | +import java.util.HashSet; | |
| 36 | +import java.util.Iterator; | |
| 37 | +import java.util.Locale; | |
| 38 | +import java.util.Map; | |
| 39 | +import java.util.NoSuchElementException; | |
| 40 | +import java.util.Set; | |
| 41 | +import java.util.ServiceLoader; | |
| 42 | +import java.util.ServiceConfigurationError; | |
| 43 | +import java.util.SortedMap; | |
| 44 | +import java.util.TreeMap; | |
| 45 | +import sun.misc.ASCIICaseInsensitiveComparator; | |
| 46 | +import sun.nio.cs.StandardCharsets; | |
| 47 | +import sun.nio.cs.ThreadLocalCoders; | |
| 48 | +import sun.security.action.GetPropertyAction; | |
| 49 | + | |
| 50 | + | |
| 51 | +/** | |
| 52 | + * A named mapping between sequences of sixteen-bit Unicode <a | |
| 53 | + * href="../../lang/Character.html#unicode">code units</a> and sequences of | |
| 54 | + * bytes. This class defines methods for creating decoders and encoders and | |
| 55 | + * for retrieving the various names associated with a charset. Instances of | |
| 56 | + * this class are immutable. | |
| 57 | + * | |
| 58 | + * <p> This class also defines static methods for testing whether a particular | |
| 59 | + * charset is supported, for locating charset instances by name, and for | |
| 60 | + * constructing a map that contains every charset for which support is | |
| 61 | + * available in the current Java virtual machine. Support for new charsets can | |
| 62 | + * be added via the service-provider interface defined in the {@link | |
| 63 | + * java.nio.charset.spi.CharsetProvider} class. | |
| 64 | + * | |
| 65 | + * <p> All of the methods defined in this class are safe for use by multiple | |
| 66 | + * concurrent threads. | |
| 67 | + * | |
| 68 | + * | |
| 69 | + * <a name="names"><a name="charenc"> | |
| 70 | + * <h4>Charset names</h4> | |
| 71 | + * | |
| 72 | + * <p> Charsets are named by strings composed of the following characters: | |
| 73 | + * | |
| 74 | + * <ul> | |
| 75 | + * | |
| 76 | + * <li> The uppercase letters <tt>'A'</tt> through <tt>'Z'</tt> | |
| 77 | + * (<tt>'\u0041'</tt> through <tt>'\u005a'</tt>), | |
| 78 | + * | |
| 79 | + * <li> The lowercase letters <tt>'a'</tt> through <tt>'z'</tt> | |
| 80 | + * (<tt>'\u0061'</tt> through <tt>'\u007a'</tt>), | |
| 81 | + * | |
| 82 | + * <li> The digits <tt>'0'</tt> through <tt>'9'</tt> | |
| 83 | + * (<tt>'\u0030'</tt> through <tt>'\u0039'</tt>), | |
| 84 | + * | |
| 85 | + * <li> The dash character <tt>'-'</tt> | |
| 86 | + * (<tt>'\u002d'</tt>, <small>HYPHEN-MINUS</small>), | |
| 87 | + * | |
| 88 | + * <li> The plus character <tt>'+'</tt> | |
| 89 | + * (<tt>'\u002b'</tt>, <small>PLUS SIGN</small>), | |
| 90 | + * | |
| 91 | + * <li> The period character <tt>'.'</tt> | |
| 92 | + * (<tt>'\u002e'</tt>, <small>FULL STOP</small>), | |
| 93 | + * | |
| 94 | + * <li> The colon character <tt>':'</tt> | |
| 95 | + * (<tt>'\u003a'</tt>, <small>COLON</small>), and | |
| 96 | + * | |
| 97 | + * <li> The underscore character <tt>'_'</tt> | |
| 98 | + * (<tt>'\u005f'</tt>, <small>LOW LINE</small>). | |
| 99 | + * | |
| 100 | + * </ul> | |
| 101 | + * | |
| 102 | + * A charset name must begin with either a letter or a digit. The empty string | |
| 103 | + * is not a legal charset name. Charset names are not case-sensitive; that is, | |
| 104 | + * case is always ignored when comparing charset names. Charset names | |
| 105 | + * generally follow the conventions documented in <a | |
| 106 | + * href="http://www.ietf.org/rfc/rfc2278.txt"><i>RFC 2278: IANA Charset | |
| 107 | + * Registration Procedures</i></a>. | |
| 108 | + * | |
| 109 | + * <p> Every charset has a <i>canonical name</i> and may also have one or more | |
| 110 | + * <i>aliases</i>. The canonical name is returned by the {@link #name() name} method | |
| 111 | + * of this class. Canonical names are, by convention, usually in upper case. | |
| 112 | + * The aliases of a charset are returned by the {@link #aliases() aliases} | |
| 113 | + * method. | |
| 114 | + * | |
| 115 | + * <a name="hn"> | |
| 116 | + * | |
| 117 | + * <p> Some charsets have an <i>historical name</i> that is defined for | |
| 118 | + * compatibility with previous versions of the Java platform. A charset's | |
| 119 | + * historical name is either its canonical name or one of its aliases. The | |
| 120 | + * historical name is returned by the <tt>getEncoding()</tt> methods of the | |
| 121 | + * {@link java.io.InputStreamReader#getEncoding InputStreamReader} and {@link | |
| 122 | + * java.io.OutputStreamWriter#getEncoding OutputStreamWriter} classes. | |
| 123 | + * | |
| 124 | + * <a name="iana"> | |
| 125 | + * | |
| 126 | + * <p> If a charset listed in the <a | |
| 127 | + * href="http://www.iana.org/assignments/character-sets"><i>IANA Charset | |
| 128 | + * Registry</i></a> is supported by an implementation of the Java platform then | |
| 129 | + * its canonical name must be the name listed in the registry. Many charsets | |
| 130 | + * are given more than one name in the registry, in which case the registry | |
| 131 | + * identifies one of the names as <i>MIME-preferred</i>. If a charset has more | |
| 132 | + * than one registry name then its canonical name must be the MIME-preferred | |
| 133 | + * name and the other names in the registry must be valid aliases. If a | |
| 134 | + * supported charset is not listed in the IANA registry then its canonical name | |
| 135 | + * must begin with one of the strings <tt>"X-"</tt> or <tt>"x-"</tt>. | |
| 136 | + * | |
| 137 | + * <p> The IANA charset registry does change over time, and so the canonical | |
| 138 | + * name and the aliases of a particular charset may also change over time. To | |
| 139 | + * ensure compatibility it is recommended that no alias ever be removed from a | |
| 140 | + * charset, and that if the canonical name of a charset is changed then its | |
| 141 | + * previous canonical name be made into an alias. | |
| 142 | + * | |
| 143 | + * | |
| 144 | + * <h4>Standard charsets</h4> | |
| 145 | + * | |
| 146 | + * <a name="standard"> | |
| 147 | + * | |
| 148 | + * <p> Every implementation of the Java platform is required to support the | |
| 149 | + * following standard charsets. Consult the release documentation for your | |
| 150 | + * implementation to see if any other charsets are supported. The behavior | |
| 151 | + * of such optional charsets may differ between implementations. | |
| 152 | + * | |
| 153 | + * <blockquote><table width="80%" summary="Description of standard charsets"> | |
| 154 | + * <tr><th><p align="left">Charset</p></th><th><p align="left">Description</p></th></tr> | |
| 155 | + * <tr><td valign=top><tt>US-ASCII</tt></td> | |
| 156 | + * <td>Seven-bit ASCII, a.k.a. <tt>ISO646-US</tt>, | |
| 157 | + * a.k.a. the Basic Latin block of the Unicode character set</td></tr> | |
| 158 | + * <tr><td valign=top><tt>ISO-8859-1 </tt></td> | |
| 159 | + * <td>ISO Latin Alphabet No. 1, a.k.a. <tt>ISO-LATIN-1</tt></td></tr> | |
| 160 | + * <tr><td valign=top><tt>UTF-8</tt></td> | |
| 161 | + * <td>Eight-bit UCS Transformation Format</td></tr> | |
| 162 | + * <tr><td valign=top><tt>UTF-16BE</tt></td> | |
| 163 | + * <td>Sixteen-bit UCS Transformation Format, | |
| 164 | + * big-endian byte order</td></tr> | |
| 165 | + * <tr><td valign=top><tt>UTF-16LE</tt></td> | |
| 166 | + * <td>Sixteen-bit UCS Transformation Format, | |
| 167 | + * little-endian byte order</td></tr> | |
| 168 | + * <tr><td valign=top><tt>UTF-16</tt></td> | |
| 169 | + * <td>Sixteen-bit UCS Transformation Format, | |
| 170 | + * byte order identified by an optional byte-order mark</td></tr> | |
| 171 | + * </table></blockquote> | |
| 172 | + * | |
| 173 | + * <p> The <tt>UTF-8</tt> charset is specified by <a | |
| 174 | + * href="http://www.ietf.org/rfc/rfc2279.txt"><i>RFC 2279</i></a>; the | |
| 175 | + * transformation format upon which it is based is specified in | |
| 176 | + * Amendment 2 of ISO 10646-1 and is also described in the <a | |
| 177 | + * href="http://www.unicode.org/unicode/standard/standard.html"><i>Unicode | |
| 178 | + * Standard</i></a>. | |
| 179 | + * | |
| 180 | + * <p> The <tt>UTF-16</tt> charsets are specified by <a | |
| 181 | + * href="http://www.ietf.org/rfc/rfc2781.txt"><i>RFC 2781</i></a>; the | |
| 182 | + * transformation formats upon which they are based are specified in | |
| 183 | + * Amendment 1 of ISO 10646-1 and are also described in the <a | |
| 184 | + * href="http://www.unicode.org/unicode/standard/standard.html"><i>Unicode | |
| 185 | + * Standard</i></a>. | |
| 186 | + * | |
| 187 | + * <p> The <tt>UTF-16</tt> charsets use sixteen-bit quantities and are | |
| 188 | + * therefore sensitive to byte order. In these encodings the byte order of a | |
| 189 | + * stream may be indicated by an initial <i>byte-order mark</i> represented by | |
| 190 | + * the Unicode character <tt>'\uFEFF'</tt>. Byte-order marks are handled | |
| 191 | + * as follows: | |
| 192 | + * | |
| 193 | + * <ul> | |
| 194 | + * | |
| 195 | + * <li><p> When decoding, the <tt>UTF-16BE</tt> and <tt>UTF-16LE</tt> | |
| 196 | + * charsets interpret the initial byte-order marks as a <small>ZERO-WIDTH | |
| 197 | + * NON-BREAKING SPACE</small>; when encoding, they do not write | |
| 198 | + * byte-order marks. </p></li> | |
| 199 | + | |
| 200 | + * | |
| 201 | + * <li><p> When decoding, the <tt>UTF-16</tt> charset interprets the | |
| 202 | + * byte-order mark at the beginning of the input stream to indicate the | |
| 203 | + * byte-order of the stream but defaults to big-endian if there is no | |
| 204 | + * byte-order mark; when encoding, it uses big-endian byte order and writes | |
| 205 | + * a big-endian byte-order mark. </p></li> | |
| 206 | + * | |
| 207 | + * </ul> | |
| 208 | + * | |
| 209 | + * In any case, byte order marks occuring after the first element of an | |
| 210 | + * input sequence are not omitted since the same code is used to represent | |
| 211 | + * <small>ZERO-WIDTH NON-BREAKING SPACE</small>. | |
| 212 | + * | |
| 213 | + * <p> Every instance of the Java virtual machine has a default charset, which | |
| 214 | + * may or may not be one of the standard charsets. The default charset is | |
| 215 | + * determined during virtual-machine startup and typically depends upon the | |
| 216 | + * locale and charset being used by the underlying operating system. </p> | |
| 217 | + * | |
| 218 | + * <p>The {@link StandardCharsets} class defines constants for each of the | |
| 219 | + * standard charsets. | |
| 220 | + * | |
| 221 | + * <h4>Terminology</h4> | |
| 222 | + * | |
| 223 | + * <p> The name of this class is taken from the terms used in | |
| 224 | + * <a href="http://www.ietf.org/rfc/rfc2278.txt"><i>RFC 2278</i></a>. | |
| 225 | + * In that document a <i>charset</i> is defined as the combination of | |
| 226 | + * one or more coded character sets and a character-encoding scheme. | |
| 227 | + * (This definition is confusing; some other software systems define | |
| 228 | + * <i>charset</i> as a synonym for <i>coded character set</i>.) | |
| 229 | + * | |
| 230 | + * <p> A <i>coded character set</i> is a mapping between a set of abstract | |
| 231 | + * characters and a set of integers. US-ASCII, ISO 8859-1, | |
| 232 | + * JIS X 0201, and Unicode are examples of coded character sets. | |
| 233 | + * | |
| 234 | + * <p> Some standards have defined a <i>character set</i> to be simply a | |
| 235 | + * set of abstract characters without an associated assigned numbering. | |
| 236 | + * An alphabet is an example of such a character set. However, the subtle | |
| 237 | + * distinction between <i>character set</i> and <i>coded character set</i> | |
| 238 | + * is rarely used in practice; the former has become a short form for the | |
| 239 | + * latter, including in the Java API specification. | |
| 240 | + * | |
| 241 | + * <p> A <i>character-encoding scheme</i> is a mapping between one or more | |
| 242 | + * coded character sets and a set of octet (eight-bit byte) sequences. | |
| 243 | + * UTF-8, UTF-16, ISO 2022, and EUC are examples of | |
| 244 | + * character-encoding schemes. Encoding schemes are often associated with | |
| 245 | + * a particular coded character set; UTF-8, for example, is used only to | |
| 246 | + * encode Unicode. Some schemes, however, are associated with multiple | |
| 247 | + * coded character sets; EUC, for example, can be used to encode | |
| 248 | + * characters in a variety of Asian coded character sets. | |
| 249 | + * | |
| 250 | + * <p> When a coded character set is used exclusively with a single | |
| 251 | + * character-encoding scheme then the corresponding charset is usually | |
| 252 | + * named for the coded character set; otherwise a charset is usually named | |
| 253 | + * for the encoding scheme and, possibly, the locale of the coded | |
| 254 | + * character sets that it supports. Hence <tt>US-ASCII</tt> is both the | |
| 255 | + * name of a coded character set and of the charset that encodes it, while | |
| 256 | + * <tt>EUC-JP</tt> is the name of the charset that encodes the | |
| 257 | + * JIS X 0201, JIS X 0208, and JIS X 0212 | |
| 258 | + * coded character sets for the Japanese language. | |
| 259 | + * | |
| 260 | + * <p> The native character encoding of the Java programming language is | |
| 261 | + * UTF-16. A charset in the Java platform therefore defines a mapping | |
| 262 | + * between sequences of sixteen-bit UTF-16 code units (that is, sequences | |
| 263 | + * of chars) and sequences of bytes. </p> | |
| 264 | + * | |
| 265 | + * | |
| 266 | + * @author Mark Reinhold | |
| 267 | + * @author JSR-51 Expert Group | |
| 268 | + * @since 1.4 | |
| 269 | + * | |
| 270 | + * @see CharsetDecoder | |
| 271 | + * @see CharsetEncoder | |
| 272 | + * @see java.nio.charset.spi.CharsetProvider | |
| 273 | + * @see java.lang.Character | |
| 274 | + */ | |
| 275 | + | |
| 276 | +public abstract class Charset | |
| 277 | + implements Comparable<Charset> | |
| 278 | +{ | |
| 279 | + | |
| 280 | + /* -- Static methods -- */ | |
| 281 | + | |
| 282 | + private static volatile String bugLevel = null; | |
| 283 | + | |
| 284 | + static boolean atBugLevel(String bl) { // package-private | |
| 285 | + String level = bugLevel; | |
| 286 | + if (level == null) { | |
| 287 | + if (!sun.misc.VM.isBooted()) | |
| 288 | + return false; | |
| 289 | + bugLevel = level = AccessController.doPrivileged( | |
| 290 | + new GetPropertyAction("sun.nio.cs.bugLevel", "")); | |
| 291 | + } | |
| 292 | + return level.equals(bl); | |
| 293 | + } | |
| 294 | + | |
| 295 | + /** | |
| 296 | + * Checks that the given string is a legal charset name. </p> | |
| 297 | + * | |
| 298 | + * @param s | |
| 299 | + * A purported charset name | |
| 300 | + * | |
| 301 | + * @throws IllegalCharsetNameException | |
| 302 | + * If the given name is not a legal charset name | |
| 303 | + */ | |
| 304 | + private static void checkName(String s) { | |
| 305 | + int n = s.length(); | |
| 306 | + if (!atBugLevel("1.4")) { | |
| 307 | + if (n == 0) | |
| 308 | + throw new IllegalCharsetNameException(s); | |
| 309 | + } | |
| 310 | + for (int i = 0; i < n; i++) { | |
| 311 | + char c = s.charAt(i); | |
| 312 | + if (c >= 'A' && c <= 'Z') continue; | |
| 313 | + if (c >= 'a' && c <= 'z') continue; | |
| 314 | + if (c >= '0' && c <= '9') continue; | |
| 315 | + if (c == '-' && i != 0) continue; | |
| 316 | + if (c == '+' && i != 0) continue; | |
| 317 | + if (c == ':' && i != 0) continue; | |
| 318 | + if (c == '_' && i != 0) continue; | |
| 319 | + if (c == '.' && i != 0) continue; | |
| 320 | + throw new IllegalCharsetNameException(s); | |
| 321 | + } | |
| 322 | + } | |
| 323 | + | |
| 324 | + /* The standard set of charsets */ | |
| 325 | + private static CharsetProvider standardProvider = new StandardCharsets(); | |
| 326 | + | |
| 327 | + // Cache of the most-recently-returned charsets, | |
| 328 | + // along with the names that were used to find them | |
| 329 | + // | |
| 330 | + private static volatile Object[] cache1 = null; // "Level 1" cache | |
| 331 | + private static volatile Object[] cache2 = null; // "Level 2" cache | |
| 332 | + | |
| 333 | + private static void cache(String charsetName, Charset cs) { | |
| 334 | + cache2 = cache1; | |
| 335 | + cache1 = new Object[] { charsetName, cs }; | |
| 336 | + } | |
| 337 | + | |
| 338 | + // Creates an iterator that walks over the available providers, ignoring | |
| 339 | + // those whose lookup or instantiation causes a security exception to be | |
| 340 | + // thrown. Should be invoked with full privileges. | |
| 341 | + // | |
| 342 | + private static Iterator providers() { | |
| 343 | + return new Iterator() { | |
| 344 | + | |
| 345 | + ClassLoader cl = ClassLoader.getSystemClassLoader(); | |
| 346 | + ServiceLoader<CharsetProvider> sl = | |
| 347 | + ServiceLoader.load(CharsetProvider.class, cl); | |
| 348 | + Iterator<CharsetProvider> i = sl.iterator(); | |
| 349 | + | |
| 350 | + Object next = null; | |
| 351 | + | |
| 352 | + private boolean getNext() { | |
| 353 | + while (next == null) { | |
| 354 | + try { | |
| 355 | + if (!i.hasNext()) | |
| 356 | + return false; | |
| 357 | + next = i.next(); | |
| 358 | + } catch (ServiceConfigurationError sce) { | |
| 359 | + if (sce.getCause() instanceof SecurityException) { | |
| 360 | + // Ignore security exceptions | |
| 361 | + continue; | |
| 362 | + } | |
| 363 | + throw sce; | |
| 364 | + } | |
| 365 | + } | |
| 366 | + return true; | |
| 367 | + } | |
| 368 | + | |
| 369 | + public boolean hasNext() { | |
| 370 | + return getNext(); | |
| 371 | + } | |
| 372 | + | |
| 373 | + public Object next() { | |
| 374 | + if (!getNext()) | |
| 375 | + throw new NoSuchElementException(); | |
| 376 | + Object n = next; | |
| 377 | + next = null; | |
| 378 | + return n; | |
| 379 | + } | |
| 380 | + | |
| 381 | + public void remove() { | |
| 382 | + throw new UnsupportedOperationException(); | |
| 383 | + } | |
| 384 | + | |
| 385 | + }; | |
| 386 | + } | |
| 387 | + | |
| 388 | + // Thread-local gate to prevent recursive provider lookups | |
| 389 | + private static ThreadLocal<ThreadLocal> gate = new ThreadLocal<ThreadLocal>(); | |
| 390 | + | |
| 391 | + private static Charset lookupViaProviders(final String charsetName) { | |
| 392 | + | |
| 393 | + // The runtime startup sequence looks up standard charsets as a | |
| 394 | + // consequence of the VM's invocation of System.initializeSystemClass | |
| 395 | + // in order to, e.g., set system properties and encode filenames. At | |
| 396 | + // that point the application class loader has not been initialized, | |
| 397 | + // however, so we can't look for providers because doing so will cause | |
| 398 | + // that loader to be prematurely initialized with incomplete | |
| 399 | + // information. | |
| 400 | + // | |
| 401 | + if (!sun.misc.VM.isBooted()) | |
| 402 | + return null; | |
| 403 | + | |
| 404 | + if (gate.get() != null) | |
| 405 | + // Avoid recursive provider lookups | |
| 406 | + return null; | |
| 407 | + try { | |
| 408 | + gate.set(gate); | |
| 409 | + | |
| 410 | + return AccessController.doPrivileged( | |
| 411 | + new PrivilegedAction<Charset>() { | |
| 412 | + public Charset run() { | |
| 413 | + for (Iterator i = providers(); i.hasNext();) { | |
| 414 | + CharsetProvider cp = (CharsetProvider)i.next(); | |
| 415 | + Charset cs = cp.charsetForName(charsetName); | |
| 416 | + if (cs != null) | |
| 417 | + return cs; | |
| 418 | + } | |
| 419 | + return null; | |
| 420 | + } | |
| 421 | + }); | |
| 422 | + | |
| 423 | + } finally { | |
| 424 | + gate.set(null); | |
| 425 | + } | |
| 426 | + } | |
| 427 | + | |
| 428 | + /* The extended set of charsets */ | |
| 429 | + private static Object extendedProviderLock = new Object(); | |
| 430 | + private static boolean extendedProviderProbed = false; | |
| 431 | + private static CharsetProvider extendedProvider = null; | |
| 432 | + | |
| 433 | + private static void probeExtendedProvider() { | |
| 434 | + AccessController.doPrivileged(new PrivilegedAction<Object>() { | |
| 435 | + public Object run() { | |
| 436 | + try { | |
| 437 | + Class epc | |
| 438 | + = Class.forName("sun.nio.cs.ext.ExtendedCharsets"); | |
| 439 | + extendedProvider = (CharsetProvider)epc.newInstance(); | |
| 440 | + } catch (ClassNotFoundException x) { | |
| 441 | + // Extended charsets not available | |
| 442 | + // (charsets.jar not present) | |
| 443 | + } catch (InstantiationException x) { | |
| 444 | + throw new Error(x); | |
| 445 | + } catch (IllegalAccessException x) { | |
| 446 | + throw new Error(x); | |
| 447 | + } | |
| 448 | + return null; | |
| 449 | + } | |
| 450 | + }); | |
| 451 | + } | |
| 452 | + | |
| 453 | + private static Charset lookupExtendedCharset(String charsetName) { | |
| 454 | + CharsetProvider ecp = null; | |
| 455 | + synchronized (extendedProviderLock) { | |
| 456 | + if (!extendedProviderProbed) { | |
| 457 | + probeExtendedProvider(); | |
| 458 | + extendedProviderProbed = true; | |
| 459 | + } | |
| 460 | + ecp = extendedProvider; | |
| 461 | + } | |
| 462 | + return (ecp != null) ? ecp.charsetForName(charsetName) : null; | |
| 463 | + } | |
| 464 | + | |
| 465 | + private static Charset lookup(String charsetName) { | |
| 466 | + if (charsetName == null) | |
| 467 | + throw new IllegalArgumentException("Null charset name"); | |
| 468 | + | |
| 469 | + Object[] a; | |
| 470 | + if ((a = cache1) != null && charsetName.equals(a[0])) | |
| 471 | + return (Charset)a[1]; | |
| 472 | + // We expect most programs to use one Charset repeatedly. | |
| 473 | + // We convey a hint to this effect to the VM by putting the | |
| 474 | + // level 1 cache miss code in a separate method. | |
| 475 | + return lookup2(charsetName); | |
| 476 | + } | |
| 477 | + | |
| 478 | + private static Charset lookup2(String charsetName) { | |
| 479 | + Object[] a; | |
| 480 | + if ((a = cache2) != null && charsetName.equals(a[0])) { | |
| 481 | + cache2 = cache1; | |
| 482 | + cache1 = a; | |
| 483 | + return (Charset)a[1]; | |
| 484 | + } | |
| 485 | + | |
| 486 | + Charset cs; | |
| 487 | + if ((cs = standardProvider.charsetForName(charsetName)) != null || | |
| 488 | + (cs = lookupExtendedCharset(charsetName)) != null || | |
| 489 | + (cs = lookupViaProviders(charsetName)) != null) | |
| 490 | + { | |
| 491 | + cache(charsetName, cs); | |
| 492 | + return cs; | |
| 493 | + } | |
| 494 | + | |
| 495 | + /* Only need to check the name if we didn't find a charset for it */ | |
| 496 | + checkName(charsetName); | |
| 497 | + return null; | |
| 498 | + } | |
| 499 | + | |
| 500 | + /** | |
| 501 | + * Tells whether the named charset is supported. </p> | |
| 502 | + * | |
| 503 | + * @param charsetName | |
| 504 | + * The name of the requested charset; may be either | |
| 505 | + * a canonical name or an alias | |
| 506 | + * | |
| 507 | + * @return <tt>true</tt> if, and only if, support for the named charset | |
| 508 | + * is available in the current Java virtual machine | |
| 509 | + * | |
| 510 | + * @throws IllegalCharsetNameException | |
| 511 | + * If the given charset name is illegal | |
| 512 | + * | |
| 513 | + * @throws IllegalArgumentException | |
| 514 | + * If the given <tt>charsetName</tt> is null | |
| 515 | + */ | |
| 516 | + public static boolean isSupported(String charsetName) { | |
| 517 | + return (lookup(charsetName) != null); | |
| 518 | + } | |
| 519 | + | |
| 520 | + /** | |
| 521 | + * Returns a charset object for the named charset. </p> | |
| 522 | + * | |
| 523 | + * @param charsetName | |
| 524 | + * The name of the requested charset; may be either | |
| 525 | + * a canonical name or an alias | |
| 526 | + * | |
| 527 | + * @return A charset object for the named charset | |
| 528 | + * | |
| 529 | + * @throws IllegalCharsetNameException | |
| 530 | + * If the given charset name is illegal | |
| 531 | + * | |
| 532 | + * @throws IllegalArgumentException | |
| 533 | + * If the given <tt>charsetName</tt> is null | |
| 534 | + * | |
| 535 | + * @throws UnsupportedCharsetException | |
| 536 | + * If no support for the named charset is available | |
| 537 | + * in this instance of the Java virtual machine | |
| 538 | + */ | |
| 539 | + public static Charset forName(String charsetName) { | |
| 540 | + Charset cs = lookup(charsetName); | |
| 541 | + if (cs != null) | |
| 542 | + return cs; | |
| 543 | + throw new UnsupportedCharsetException(charsetName); | |
| 544 | + } | |
| 545 | + | |
| 546 | + // Fold charsets from the given iterator into the given map, ignoring | |
| 547 | + // charsets whose names already have entries in the map. | |
| 548 | + // | |
| 549 | + private static void put(Iterator<Charset> i, Map<String,Charset> m) { | |
| 550 | + while (i.hasNext()) { | |
| 551 | + Charset cs = i.next(); | |
| 552 | + if (!m.containsKey(cs.name())) | |
| 553 | + m.put(cs.name(), cs); | |
| 554 | + } | |
| 555 | + } | |
| 556 | + | |
| 557 | + /** | |
| 558 | + * Constructs a sorted map from canonical charset names to charset objects. | |
| 559 | + * | |
| 560 | + * <p> The map returned by this method will have one entry for each charset | |
| 561 | + * for which support is available in the current Java virtual machine. If | |
| 562 | + * two or more supported charsets have the same canonical name then the | |
| 563 | + * resulting map will contain just one of them; which one it will contain | |
| 564 | + * is not specified. </p> | |
| 565 | + * | |
| 566 | + * <p> The invocation of this method, and the subsequent use of the | |
| 567 | + * resulting map, may cause time-consuming disk or network I/O operations | |
| 568 | + * to occur. This method is provided for applications that need to | |
| 569 | + * enumerate all of the available charsets, for example to allow user | |
| 570 | + * charset selection. This method is not used by the {@link #forName | |
| 571 | + * forName} method, which instead employs an efficient incremental lookup | |
| 572 | + * algorithm. | |
| 573 | + * | |
| 574 | + * <p> This method may return different results at different times if new | |
| 575 | + * charset providers are dynamically made available to the current Java | |
| 576 | + * virtual machine. In the absence of such changes, the charsets returned | |
| 577 | + * by this method are exactly those that can be retrieved via the {@link | |
| 578 | + * #forName forName} method. </p> | |
| 579 | + * | |
| 580 | + * @return An immutable, case-insensitive map from canonical charset names | |
| 581 | + * to charset objects | |
| 582 | + */ | |
| 583 | + public static SortedMap<String,Charset> availableCharsets() { | |
| 584 | + return AccessController.doPrivileged( | |
| 585 | + new PrivilegedAction<SortedMap<String,Charset>>() { | |
| 586 | + public SortedMap<String,Charset> run() { | |
| 587 | + TreeMap<String,Charset> m = | |
| 588 | + new TreeMap<String,Charset>( | |
| 589 | + ASCIICaseInsensitiveComparator.CASE_INSENSITIVE_ORDER); | |
| 590 | + put(standardProvider.charsets(), m); | |
| 591 | + for (Iterator i = providers(); i.hasNext();) { | |
| 592 | + CharsetProvider cp = (CharsetProvider)i.next(); | |
| 593 | + put(cp.charsets(), m); | |
| 594 | + } | |
| 595 | + return Collections.unmodifiableSortedMap(m); | |
| 596 | + } | |
| 597 | + }); | |
| 598 | + } | |
| 599 | + | |
| 600 | + private static volatile Charset defaultCharset; | |
| 601 | + | |
| 602 | + /** | |
| 603 | + * Returns the default charset of this Java virtual machine. | |
| 604 | + * | |
| 605 | + * <p> The default charset is determined during virtual-machine startup and | |
| 606 | + * typically depends upon the locale and charset of the underlying | |
| 607 | + * operating system. | |
| 608 | + * | |
| 609 | + * @return A charset object for the default charset | |
| 610 | + * | |
| 611 | + * @since 1.5 | |
| 612 | + */ | |
| 613 | + public static Charset defaultCharset() { | |
| 614 | + if (defaultCharset == null) { | |
| 615 | + synchronized (Charset.class) { | |
| 616 | + String csn = AccessController.doPrivileged( | |
| 617 | + new GetPropertyAction("file.encoding")); | |
| 618 | + Charset cs = lookup(csn); | |
| 619 | + if (cs != null) | |
| 620 | + defaultCharset = cs; | |
| 621 | + else | |
| 622 | + defaultCharset = forName("UTF-8"); | |
| 623 | + } | |
| 624 | + } | |
| 625 | + return defaultCharset; | |
| 626 | + } | |
| 627 | + | |
| 628 | + | |
| 629 | + /* -- Instance fields and methods -- */ | |
| 630 | + | |
| 631 | + private final String name; // tickles a bug in oldjavac | |
| 632 | + private final String[] aliases; // tickles a bug in oldjavac | |
| 633 | + private Set<String> aliasSet = null; | |
| 634 | + | |
| 635 | + /** | |
| 636 | + * Initializes a new charset with the given canonical name and alias | |
| 637 | + * set. </p> | |
| 638 | + * | |
| 639 | + * @param canonicalName | |
| 640 | + * The canonical name of this charset | |
| 641 | + * | |
| 642 | + * @param aliases | |
| 643 | + * An array of this charset's aliases, or null if it has no aliases | |
| 644 | + * | |
| 645 | + * @throws IllegalCharsetNameException | |
| 646 | + * If the canonical name or any of the aliases are illegal | |
| 647 | + */ | |
| 648 | + protected Charset(String canonicalName, String[] aliases) { | |
| 649 | + checkName(canonicalName); | |
| 650 | + String[] as = (aliases == null) ? new String[0] : aliases; | |
| 651 | + for (int i = 0; i < as.length; i++) | |
| 652 | + checkName(as[i]); | |
| 653 | + this.name = canonicalName; | |
| 654 | + this.aliases = as; | |
| 655 | + } | |
| 656 | + | |
| 657 | + /** | |
| 658 | + * Returns this charset's canonical name. </p> | |
| 659 | + * | |
| 660 | + * @return The canonical name of this charset | |
| 661 | + */ | |
| 662 | + public final String name() { | |
| 663 | + return name; | |
| 664 | + } | |
| 665 | + | |
| 666 | + /** | |
| 667 | + * Returns a set containing this charset's aliases. </p> | |
| 668 | + * | |
| 669 | + * @return An immutable set of this charset's aliases | |
| 670 | + */ | |
| 671 | + public final Set<String> aliases() { | |
| 672 | + if (aliasSet != null) | |
| 673 | + return aliasSet; | |
| 674 | + int n = aliases.length; | |
| 675 | + HashSet<String> hs = new HashSet<String>(n); | |
| 676 | + for (int i = 0; i < n; i++) | |
| 677 | + hs.add(aliases[i]); | |
| 678 | + aliasSet = Collections.unmodifiableSet(hs); | |
| 679 | + return aliasSet; | |
| 680 | + } | |
| 681 | + | |
| 682 | + /** | |
| 683 | + * Returns this charset's human-readable name for the default locale. | |
| 684 | + * | |
| 685 | + * <p> The default implementation of this method simply returns this | |
| 686 | + * charset's canonical name. Concrete subclasses of this class may | |
| 687 | + * override this method in order to provide a localized display name. </p> | |
| 688 | + * | |
| 689 | + * @return The display name of this charset in the default locale | |
| 690 | + */ | |
| 691 | + public String displayName() { | |
| 692 | + return name; | |
| 693 | + } | |
| 694 | + | |
| 695 | + /** | |
| 696 | + * Tells whether or not this charset is registered in the <a | |
| 697 | + * href="http://www.iana.org/assignments/character-sets">IANA Charset | |
| 698 | + * Registry</a>. </p> | |
| 699 | + * | |
| 700 | + * @return <tt>true</tt> if, and only if, this charset is known by its | |
| 701 | + * implementor to be registered with the IANA | |
| 702 | + */ | |
| 703 | + public final boolean isRegistered() { | |
| 704 | + return !name.startsWith("X-") && !name.startsWith("x-"); | |
| 705 | + } | |
| 706 | + | |
| 707 | + /** | |
| 708 | + * Returns this charset's human-readable name for the given locale. | |
| 709 | + * | |
| 710 | + * <p> The default implementation of this method simply returns this | |
| 711 | + * charset's canonical name. Concrete subclasses of this class may | |
| 712 | + * override this method in order to provide a localized display name. </p> | |
| 713 | + * | |
| 714 | + * @param locale | |
| 715 | + * The locale for which the display name is to be retrieved | |
| 716 | + * | |
| 717 | + * @return The display name of this charset in the given locale | |
| 718 | + */ | |
| 719 | + public String displayName(Locale locale) { | |
| 720 | + return name; | |
| 721 | + } | |
| 722 | + | |
| 723 | + /** | |
| 724 | + * Tells whether or not this charset contains the given charset. | |
| 725 | + * | |
| 726 | + * <p> A charset <i>C</i> is said to <i>contain</i> a charset <i>D</i> if, | |
| 727 | + * and only if, every character representable in <i>D</i> is also | |
| 728 | + * representable in <i>C</i>. If this relationship holds then it is | |
| 729 | + * guaranteed that every string that can be encoded in <i>D</i> can also be | |
| 730 | + * encoded in <i>C</i> without performing any replacements. | |
| 731 | + * | |
| 732 | + * <p> That <i>C</i> contains <i>D</i> does not imply that each character | |
| 733 | + * representable in <i>C</i> by a particular byte sequence is represented | |
| 734 | + * in <i>D</i> by the same byte sequence, although sometimes this is the | |
| 735 | + * case. | |
| 736 | + * | |
| 737 | + * <p> Every charset contains itself. | |
| 738 | + * | |
| 739 | + * <p> This method computes an approximation of the containment relation: | |
| 740 | + * If it returns <tt>true</tt> then the given charset is known to be | |
| 741 | + * contained by this charset; if it returns <tt>false</tt>, however, then | |
| 742 | + * it is not necessarily the case that the given charset is not contained | |
| 743 | + * in this charset. | |
| 744 | + * | |
| 745 | + * @return <tt>true</tt> if the given charset is contained in this charset | |
| 746 | + */ | |
| 747 | + public abstract boolean contains(Charset cs); | |
| 748 | + | |
| 749 | + /** | |
| 750 | + * Constructs a new decoder for this charset. </p> | |
| 751 | + * | |
| 752 | + * @return A new decoder for this charset | |
| 753 | + */ | |
| 754 | + public abstract CharsetDecoder newDecoder(); | |
| 755 | + | |
| 756 | + /** | |
| 757 | + * Constructs a new encoder for this charset. </p> | |
| 758 | + * | |
| 759 | + * @return A new encoder for this charset | |
| 760 | + * | |
| 761 | + * @throws UnsupportedOperationException | |
| 762 | + * If this charset does not support encoding | |
| 763 | + */ | |
| 764 | + public abstract CharsetEncoder newEncoder(); | |
| 765 | + | |
| 766 | + /** | |
| 767 | + * Tells whether or not this charset supports encoding. | |
| 768 | + * | |
| 769 | + * <p> Nearly all charsets support encoding. The primary exceptions are | |
| 770 | + * special-purpose <i>auto-detect</i> charsets whose decoders can determine | |
| 771 | + * which of several possible encoding schemes is in use by examining the | |
| 772 | + * input byte sequence. Such charsets do not support encoding because | |
| 773 | + * there is no way to determine which encoding should be used on output. | |
| 774 | + * Implementations of such charsets should override this method to return | |
| 775 | + * <tt>false</tt>. </p> | |
| 776 | + * | |
| 777 | + * @return <tt>true</tt> if, and only if, this charset supports encoding | |
| 778 | + */ | |
| 779 | + public boolean canEncode() { | |
| 780 | + return true; | |
| 781 | + } | |
| 782 | + | |
| 783 | + /** | |
| 784 | + * Convenience method that decodes bytes in this charset into Unicode | |
| 785 | + * characters. | |
| 786 | + * | |
| 787 | + * <p> An invocation of this method upon a charset <tt>cs</tt> returns the | |
| 788 | + * same result as the expression | |
| 789 | + * | |
| 790 | + * <pre> | |
| 791 | + * cs.newDecoder() | |
| 792 | + * .onMalformedInput(CodingErrorAction.REPLACE) | |
| 793 | + * .onUnmappableCharacter(CodingErrorAction.REPLACE) | |
| 794 | + * .decode(bb); </pre> | |
| 795 | + * | |
| 796 | + * except that it is potentially more efficient because it can cache | |
| 797 | + * decoders between successive invocations. | |
| 798 | + * | |
| 799 | + * <p> This method always replaces malformed-input and unmappable-character | |
| 800 | + * sequences with this charset's default replacement byte array. In order | |
| 801 | + * to detect such sequences, use the {@link | |
| 802 | + * CharsetDecoder#decode(java.nio.ByteBuffer)} method directly. </p> | |
| 803 | + * | |
| 804 | + * @param bb The byte buffer to be decoded | |
| 805 | + * | |
| 806 | + * @return A char buffer containing the decoded characters | |
| 807 | + */ | |
| 808 | + public final CharBuffer decode(ByteBuffer bb) { | |
| 809 | + try { | |
| 810 | + return ThreadLocalCoders.decoderFor(this) | |
| 811 | + .onMalformedInput(CodingErrorAction.REPLACE) | |
| 812 | + .onUnmappableCharacter(CodingErrorAction.REPLACE) | |
| 813 | + .decode(bb); | |
| 814 | + } catch (CharacterCodingException x) { | |
| 815 | + throw new Error(x); // Can't happen | |
| 816 | + } | |
| 817 | + } | |
| 818 | + | |
| 819 | + /** | |
| 820 | + * Convenience method that encodes Unicode characters into bytes in this | |
| 821 | + * charset. | |
| 822 | + * | |
| 823 | + * <p> An invocation of this method upon a charset <tt>cs</tt> returns the | |
| 824 | + * same result as the expression | |
| 825 | + * | |
| 826 | + * <pre> | |
| 827 | + * cs.newEncoder() | |
| 828 | + * .onMalformedInput(CodingErrorAction.REPLACE) | |
| 829 | + * .onUnmappableCharacter(CodingErrorAction.REPLACE) | |
| 830 | + * .encode(bb); </pre> | |
| 831 | + * | |
| 832 | + * except that it is potentially more efficient because it can cache | |
| 833 | + * encoders between successive invocations. | |
| 834 | + * | |
| 835 | + * <p> This method always replaces malformed-input and unmappable-character | |
| 836 | + * sequences with this charset's default replacement string. In order to | |
| 837 | + * detect such sequences, use the {@link | |
| 838 | + * CharsetEncoder#encode(java.nio.CharBuffer)} method directly. </p> | |
| 839 | + * | |
| 840 | + * @param cb The char buffer to be encoded | |
| 841 | + * | |
| 842 | + * @return A byte buffer containing the encoded characters | |
| 843 | + */ | |
| 844 | + public final ByteBuffer encode(CharBuffer cb) { | |
| 845 | + try { | |
| 846 | + return ThreadLocalCoders.encoderFor(this) | |
| 847 | + .onMalformedInput(CodingErrorAction.REPLACE) | |
| 848 | + .onUnmappableCharacter(CodingErrorAction.REPLACE) | |
| 849 | + .encode(cb); | |
| 850 | + } catch (CharacterCodingException x) { | |
| 851 | + throw new Error(x); // Can't happen | |
| 852 | + } | |
| 853 | + } | |
| 854 | + | |
| 855 | + /** | |
| 856 | + * Convenience method that encodes a string into bytes in this charset. | |
| 857 | + * | |
| 858 | + * <p> An invocation of this method upon a charset <tt>cs</tt> returns the | |
| 859 | + * same result as the expression | |
| 860 | + * | |
| 861 | + * <pre> | |
| 862 | + * cs.encode(CharBuffer.wrap(s)); </pre> | |
| 863 | + * | |
| 864 | + * @param str The string to be encoded | |
| 865 | + * | |
| 866 | + * @return A byte buffer containing the encoded characters | |
| 867 | + */ | |
| 868 | + public final ByteBuffer encode(String str) { | |
| 869 | + return encode(CharBuffer.wrap(str)); | |
| 870 | + } | |
| 871 | + | |
| 872 | + /** | |
| 873 | + * Compares this charset to another. | |
| 874 | + * | |
| 875 | + * <p> Charsets are ordered by their canonical names, without regard to | |
| 876 | + * case. </p> | |
| 877 | + * | |
| 878 | + * @param that | |
| 879 | + * The charset to which this charset is to be compared | |
| 880 | + * | |
| 881 | + * @return A negative integer, zero, or a positive integer as this charset | |
| 882 | + * is less than, equal to, or greater than the specified charset | |
| 883 | + */ | |
| 884 | + public final int compareTo(Charset that) { | |
| 885 | + return (name().compareToIgnoreCase(that.name())); | |
| 886 | + } | |
| 887 | + | |
| 888 | + /** | |
| 889 | + * Computes a hashcode for this charset. </p> | |
| 890 | + * | |
| 891 | + * @return An integer hashcode | |
| 892 | + */ | |
| 893 | + public final int hashCode() { | |
| 894 | + return name().hashCode(); | |
| 895 | + } | |
| 896 | + | |
| 897 | + /** | |
| 898 | + * Tells whether or not this object is equal to another. | |
| 899 | + * | |
| 900 | + * <p> Two charsets are equal if, and only if, they have the same canonical | |
| 901 | + * names. A charset is never equal to any other type of object. </p> | |
| 902 | + * | |
| 903 | + * @return <tt>true</tt> if, and only if, this charset is equal to the | |
| 904 | + * given object | |
| 905 | + */ | |
| 906 | + public final boolean equals(Object ob) { | |
| 907 | + if (!(ob instanceof Charset)) | |
| 908 | + return false; | |
| 909 | + if (this == ob) | |
| 910 | + return true; | |
| 911 | + return name.equals(((Charset)ob).name()); | |
| 912 | + } | |
| 913 | + | |
| 914 | + /** | |
| 915 | + * Returns a string describing this charset. </p> | |
| 916 | + * | |
| 917 | + * @return A string describing this charset | |
| 918 | + */ | |
| 919 | + public final String toString() { | |
| 920 | + return name(); | |
| 921 | + } | |
| 922 | + | |
| 923 | +} | |
Binary file not shown.
| @@ -0,0 +1,54 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2001, 2007, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.charset; | |
| 27 | + | |
| 28 | + | |
| 29 | +/** | |
| 30 | + * Error thrown when the {@link CharsetDecoder#decodeLoop decodeLoop} method of | |
| 31 | + * a {@link CharsetDecoder}, or the {@link CharsetEncoder#encodeLoop | |
| 32 | + * encodeLoop} method of a {@link CharsetEncoder}, throws an unexpected | |
| 33 | + * exception. | |
| 34 | + * | |
| 35 | + * @since 1.4 | |
| 36 | + */ | |
| 37 | + | |
| 38 | +public class CoderMalfunctionError | |
| 39 | + extends Error | |
| 40 | +{ | |
| 41 | + | |
| 42 | + private static final long serialVersionUID = -1151412348057794301L; | |
| 43 | + | |
| 44 | + /** | |
| 45 | + * Initializes an instance of this class. | |
| 46 | + * | |
| 47 | + * @param cause | |
| 48 | + * The unexpected exception that was thrown | |
| 49 | + */ | |
| 50 | + public CoderMalfunctionError(Exception cause) { | |
| 51 | + super(cause); | |
| 52 | + } | |
| 53 | + | |
| 54 | +} | |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,284 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.charset; | |
| 27 | + | |
| 28 | +import java.lang.ref.WeakReference; | |
| 29 | +import java.nio.*; | |
| 30 | +import java.util.Map; | |
| 31 | +import java.util.HashMap; | |
| 32 | + | |
| 33 | + | |
| 34 | +/** | |
| 35 | + * A description of the result state of a coder. | |
| 36 | + * | |
| 37 | + * <p> A charset coder, that is, either a decoder or an encoder, consumes bytes | |
| 38 | + * (or characters) from an input buffer, translates them, and writes the | |
| 39 | + * resulting characters (or bytes) to an output buffer. A coding process | |
| 40 | + * terminates for one of four categories of reasons, which are described by | |
| 41 | + * instances of this class: | |
| 42 | + * | |
| 43 | + * <ul> | |
| 44 | + * | |
| 45 | + * <li><p> <i>Underflow</i> is reported when there is no more input to be | |
| 46 | + * processed, or there is insufficient input and additional input is | |
| 47 | + * required. This condition is represented by the unique result object | |
| 48 | + * {@link #UNDERFLOW}, whose {@link #isUnderflow() isUnderflow} method | |
| 49 | + * returns <tt>true</tt>. </p></li> | |
| 50 | + * | |
| 51 | + * <li><p> <i>Overflow</i> is reported when there is insufficient room | |
| 52 | + * remaining in the output buffer. This condition is represented by the | |
| 53 | + * unique result object {@link #OVERFLOW}, whose {@link #isOverflow() | |
| 54 | + * isOverflow} method returns <tt>true</tt>. </p></li> | |
| 55 | + * | |
| 56 | + * <li><p> A <i>malformed-input error</i> is reported when a sequence of | |
| 57 | + * input units is not well-formed. Such errors are described by instances of | |
| 58 | + * this class whose {@link #isMalformed() isMalformed} method returns | |
| 59 | + * <tt>true</tt> and whose {@link #length() length} method returns the length | |
| 60 | + * of the malformed sequence. There is one unique instance of this class for | |
| 61 | + * all malformed-input errors of a given length. </p></li> | |
| 62 | + * | |
| 63 | + * <li><p> An <i>unmappable-character error</i> is reported when a sequence | |
| 64 | + * of input units denotes a character that cannot be represented in the | |
| 65 | + * output charset. Such errors are described by instances of this class | |
| 66 | + * whose {@link #isUnmappable() isUnmappable} method returns <tt>true</tt> and | |
| 67 | + * whose {@link #length() length} method returns the length of the input | |
| 68 | + * sequence denoting the unmappable character. There is one unique instance | |
| 69 | + * of this class for all unmappable-character errors of a given length. | |
| 70 | + * </p></li> | |
| 71 | + * | |
| 72 | + * </ul> | |
| 73 | + * | |
| 74 | + * For convenience, the {@link #isError() isError} method returns <tt>true</tt> | |
| 75 | + * for result objects that describe malformed-input and unmappable-character | |
| 76 | + * errors but <tt>false</tt> for those that describe underflow or overflow | |
| 77 | + * conditions. </p> | |
| 78 | + * | |
| 79 | + * | |
| 80 | + * @author Mark Reinhold | |
| 81 | + * @author JSR-51 Expert Group | |
| 82 | + * @since 1.4 | |
| 83 | + */ | |
| 84 | + | |
| 85 | +public class CoderResult { | |
| 86 | + | |
| 87 | + private static final int CR_UNDERFLOW = 0; | |
| 88 | + private static final int CR_OVERFLOW = 1; | |
| 89 | + private static final int CR_ERROR_MIN = 2; | |
| 90 | + private static final int CR_MALFORMED = 2; | |
| 91 | + private static final int CR_UNMAPPABLE = 3; | |
| 92 | + | |
| 93 | + private static final String[] names | |
| 94 | + = { "UNDERFLOW", "OVERFLOW", "MALFORMED", "UNMAPPABLE" }; | |
| 95 | + | |
| 96 | + private final int type; | |
| 97 | + private final int length; | |
| 98 | + | |
| 99 | + private CoderResult(int type, int length) { | |
| 100 | + this.type = type; | |
| 101 | + this.length = length; | |
| 102 | + } | |
| 103 | + | |
| 104 | + /** | |
| 105 | + * Returns a string describing this coder result. | |
| 106 | + * | |
| 107 | + * @return A descriptive string | |
| 108 | + */ | |
| 109 | + public String toString() { | |
| 110 | + String nm = names[type]; | |
| 111 | + return isError() ? nm + "[" + length + "]" : nm; | |
| 112 | + } | |
| 113 | + | |
| 114 | + /** | |
| 115 | + * Tells whether or not this object describes an underflow condition. </p> | |
| 116 | + * | |
| 117 | + * @return <tt>true</tt> if, and only if, this object denotes underflow | |
| 118 | + */ | |
| 119 | + public boolean isUnderflow() { | |
| 120 | + return (type == CR_UNDERFLOW); | |
| 121 | + } | |
| 122 | + | |
| 123 | + /** | |
| 124 | + * Tells whether or not this object describes an overflow condition. </p> | |
| 125 | + * | |
| 126 | + * @return <tt>true</tt> if, and only if, this object denotes overflow | |
| 127 | + */ | |
| 128 | + public boolean isOverflow() { | |
| 129 | + return (type == CR_OVERFLOW); | |
| 130 | + } | |
| 131 | + | |
| 132 | + /** | |
| 133 | + * Tells whether or not this object describes an error condition. </p> | |
| 134 | + * | |
| 135 | + * @return <tt>true</tt> if, and only if, this object denotes either a | |
| 136 | + * malformed-input error or an unmappable-character error | |
| 137 | + */ | |
| 138 | + public boolean isError() { | |
| 139 | + return (type >= CR_ERROR_MIN); | |
| 140 | + } | |
| 141 | + | |
| 142 | + /** | |
| 143 | + * Tells whether or not this object describes a malformed-input error. | |
| 144 | + * </p> | |
| 145 | + * | |
| 146 | + * @return <tt>true</tt> if, and only if, this object denotes a | |
| 147 | + * malformed-input error | |
| 148 | + */ | |
| 149 | + public boolean isMalformed() { | |
| 150 | + return (type == CR_MALFORMED); | |
| 151 | + } | |
| 152 | + | |
| 153 | + /** | |
| 154 | + * Tells whether or not this object describes an unmappable-character | |
| 155 | + * error. </p> | |
| 156 | + * | |
| 157 | + * @return <tt>true</tt> if, and only if, this object denotes an | |
| 158 | + * unmappable-character error | |
| 159 | + */ | |
| 160 | + public boolean isUnmappable() { | |
| 161 | + return (type == CR_UNMAPPABLE); | |
| 162 | + } | |
| 163 | + | |
| 164 | + /** | |
| 165 | + * Returns the length of the erroneous input described by this | |
| 166 | + * object <i>(optional operation)</i>. </p> | |
| 167 | + * | |
| 168 | + * @return The length of the erroneous input, a positive integer | |
| 169 | + * | |
| 170 | + * @throws UnsupportedOperationException | |
| 171 | + * If this object does not describe an error condition, that is, | |
| 172 | + * if the {@link #isError() isError} does not return <tt>true</tt> | |
| 173 | + */ | |
| 174 | + public int length() { | |
| 175 | + if (!isError()) | |
| 176 | + throw new UnsupportedOperationException(); | |
| 177 | + return length; | |
| 178 | + } | |
| 179 | + | |
| 180 | + /** | |
| 181 | + * Result object indicating underflow, meaning that either the input buffer | |
| 182 | + * has been completely consumed or, if the input buffer is not yet empty, | |
| 183 | + * that additional input is required. </p> | |
| 184 | + */ | |
| 185 | + public static final CoderResult UNDERFLOW | |
| 186 | + = new CoderResult(CR_UNDERFLOW, 0); | |
| 187 | + | |
| 188 | + /** | |
| 189 | + * Result object indicating overflow, meaning that there is insufficient | |
| 190 | + * room in the output buffer. </p> | |
| 191 | + */ | |
| 192 | + public static final CoderResult OVERFLOW | |
| 193 | + = new CoderResult(CR_OVERFLOW, 0); | |
| 194 | + | |
| 195 | + private static abstract class Cache { | |
| 196 | + | |
| 197 | + private Map<Integer,WeakReference<CoderResult>> cache = null; | |
| 198 | + | |
| 199 | + protected abstract CoderResult create(int len); | |
| 200 | + | |
| 201 | + private synchronized CoderResult get(int len) { | |
| 202 | + if (len <= 0) | |
| 203 | + throw new IllegalArgumentException("Non-positive length"); | |
| 204 | + Integer k = new Integer(len); | |
| 205 | + WeakReference<CoderResult> w; | |
| 206 | + CoderResult e = null; | |
| 207 | + if (cache == null) { | |
| 208 | + cache = new HashMap<Integer,WeakReference<CoderResult>>(); | |
| 209 | + } else if ((w = cache.get(k)) != null) { | |
| 210 | + e = w.get(); | |
| 211 | + } | |
| 212 | + if (e == null) { | |
| 213 | + e = create(len); | |
| 214 | + cache.put(k, new WeakReference<CoderResult>(e)); | |
| 215 | + } | |
| 216 | + return e; | |
| 217 | + } | |
| 218 | + | |
| 219 | + } | |
| 220 | + | |
| 221 | + private static Cache malformedCache | |
| 222 | + = new Cache() { | |
| 223 | + public CoderResult create(int len) { | |
| 224 | + return new CoderResult(CR_MALFORMED, len); | |
| 225 | + }}; | |
| 226 | + | |
| 227 | + /** | |
| 228 | + * Static factory method that returns the unique object describing a | |
| 229 | + * malformed-input error of the given length. </p> | |
| 230 | + * | |
| 231 | + * @return The requested coder-result object | |
| 232 | + */ | |
| 233 | + public static CoderResult malformedForLength(int length) { | |
| 234 | + return malformedCache.get(length); | |
| 235 | + } | |
| 236 | + | |
| 237 | + private static Cache unmappableCache | |
| 238 | + = new Cache() { | |
| 239 | + public CoderResult create(int len) { | |
| 240 | + return new CoderResult(CR_UNMAPPABLE, len); | |
| 241 | + }}; | |
| 242 | + | |
| 243 | + /** | |
| 244 | + * Static factory method that returns the unique result object describing | |
| 245 | + * an unmappable-character error of the given length. </p> | |
| 246 | + * | |
| 247 | + * @return The requested coder-result object | |
| 248 | + */ | |
| 249 | + public static CoderResult unmappableForLength(int length) { | |
| 250 | + return unmappableCache.get(length); | |
| 251 | + } | |
| 252 | + | |
| 253 | + /** | |
| 254 | + * Throws an exception appropriate to the result described by this object. | |
| 255 | + * </p> | |
| 256 | + * | |
| 257 | + * @throws BufferUnderflowException | |
| 258 | + * If this object is {@link #UNDERFLOW} | |
| 259 | + * | |
| 260 | + * @throws BufferOverflowException | |
| 261 | + * If this object is {@link #OVERFLOW} | |
| 262 | + * | |
| 263 | + * @throws MalformedInputException | |
| 264 | + * If this object represents a malformed-input error; the | |
| 265 | + * exception's length value will be that of this object | |
| 266 | + * | |
| 267 | + * @throws UnmappableCharacterException | |
| 268 | + * If this object represents an unmappable-character error; the | |
| 269 | + * exceptions length value will be that of this object | |
| 270 | + */ | |
| 271 | + public void throwException() | |
| 272 | + throws CharacterCodingException | |
| 273 | + { | |
| 274 | + switch (type) { | |
| 275 | + case CR_UNDERFLOW: throw new BufferUnderflowException(); | |
| 276 | + case CR_OVERFLOW: throw new BufferOverflowException(); | |
| 277 | + case CR_MALFORMED: throw new MalformedInputException(length); | |
| 278 | + case CR_UNMAPPABLE: throw new UnmappableCharacterException(length); | |
| 279 | + default: | |
| 280 | + assert false; | |
| 281 | + } | |
| 282 | + } | |
| 283 | + | |
| 284 | +} | |
Binary file not shown.
| @@ -0,0 +1,84 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.charset; | |
| 27 | + | |
| 28 | + | |
| 29 | +/** | |
| 30 | + * A typesafe enumeration for coding-error actions. | |
| 31 | + * | |
| 32 | + * <p> Instances of this class are used to specify how malformed-input and | |
| 33 | + * unmappable-character errors are to be handled by charset <a | |
| 34 | + * href="CharsetDecoder.html#cae">decoders</a> and <a | |
| 35 | + * href="CharsetEncoder.html#cae">encoders</a>. </p> | |
| 36 | + * | |
| 37 | + * | |
| 38 | + * @author Mark Reinhold | |
| 39 | + * @author JSR-51 Expert Group | |
| 40 | + * @since 1.4 | |
| 41 | + */ | |
| 42 | + | |
| 43 | +public class CodingErrorAction { | |
| 44 | + | |
| 45 | + private String name; | |
| 46 | + | |
| 47 | + private CodingErrorAction(String name) { | |
| 48 | + this.name = name; | |
| 49 | + } | |
| 50 | + | |
| 51 | + /** | |
| 52 | + * Action indicating that a coding error is to be handled by dropping the | |
| 53 | + * erroneous input and resuming the coding operation. </p> | |
| 54 | + */ | |
| 55 | + public static final CodingErrorAction IGNORE | |
| 56 | + = new CodingErrorAction("IGNORE"); | |
| 57 | + | |
| 58 | + /** | |
| 59 | + * Action indicating that a coding error is to be handled by dropping the | |
| 60 | + * erroneous input, appending the coder's replacement value to the output | |
| 61 | + * buffer, and resuming the coding operation. </p> | |
| 62 | + */ | |
| 63 | + public static final CodingErrorAction REPLACE | |
| 64 | + = new CodingErrorAction("REPLACE"); | |
| 65 | + | |
| 66 | + /** | |
| 67 | + * Action indicating that a coding error is to be reported, either by | |
| 68 | + * returning a {@link CoderResult} object or by throwing a {@link | |
| 69 | + * CharacterCodingException}, whichever is appropriate for the method | |
| 70 | + * implementing the coding process. | |
| 71 | + */ | |
| 72 | + public static final CodingErrorAction REPORT | |
| 73 | + = new CodingErrorAction("REPORT"); | |
| 74 | + | |
| 75 | + /** | |
| 76 | + * Returns a string describing this action. </p> | |
| 77 | + * | |
| 78 | + * @return A descriptive string | |
| 79 | + */ | |
| 80 | + public String toString() { | |
| 81 | + return name; | |
| 82 | + } | |
| 83 | + | |
| 84 | +} | |
Binary file not shown.
| @@ -0,0 +1,57 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.charset; | |
| 27 | + | |
| 28 | + | |
| 29 | +/** | |
| 30 | + * Checked exception thrown when an input byte sequence is not legal for given | |
| 31 | + * charset, or an input character sequence is not a legal sixteen-bit Unicode | |
| 32 | + * sequence. | |
| 33 | + * | |
| 34 | + * @since 1.4 | |
| 35 | + */ | |
| 36 | + | |
| 37 | +public class MalformedInputException | |
| 38 | + extends CharacterCodingException | |
| 39 | +{ | |
| 40 | + | |
| 41 | + private static final long serialVersionUID = -3438823399834806194L; | |
| 42 | + | |
| 43 | + private int inputLength; | |
| 44 | + | |
| 45 | + public MalformedInputException(int inputLength) { | |
| 46 | + this.inputLength = inputLength; | |
| 47 | + } | |
| 48 | + | |
| 49 | + public int getInputLength() { | |
| 50 | + return inputLength; | |
| 51 | + } | |
| 52 | + | |
| 53 | + public String getMessage() { | |
| 54 | + return "Input length = " + inputLength; | |
| 55 | + } | |
| 56 | + | |
| 57 | +} | |
Binary file not shown.
| @@ -0,0 +1,66 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | +package java.nio.charset; | |
| 26 | + | |
| 27 | +/** | |
| 28 | + * Constant definitions for the standard {@link Charset Charsets}. These | |
| 29 | + * charsets are guaranteed to be available on every implementation of the Java | |
| 30 | + * platform. | |
| 31 | + * | |
| 32 | + * @see <a href="Charset#standard">Standard Charsets</a> | |
| 33 | + * @since 1.7 | |
| 34 | + */ | |
| 35 | +public final class StandardCharsets { | |
| 36 | + | |
| 37 | + private StandardCharsets() { | |
| 38 | + throw new AssertionError("No java.nio.charset.StandardCharsets instances for you!"); | |
| 39 | + } | |
| 40 | + /** | |
| 41 | + * Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the | |
| 42 | + * Unicode character set | |
| 43 | + */ | |
| 44 | + public static final Charset US_ASCII = Charset.forName("US-ASCII"); | |
| 45 | + /** | |
| 46 | + * ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1 | |
| 47 | + */ | |
| 48 | + public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1"); | |
| 49 | + /** | |
| 50 | + * Eight-bit UCS Transformation Format | |
| 51 | + */ | |
| 52 | + public static final Charset UTF_8 = Charset.forName("UTF-8"); | |
| 53 | + /** | |
| 54 | + * Sixteen-bit UCS Transformation Format, big-endian byte order | |
| 55 | + */ | |
| 56 | + public static final Charset UTF_16BE = Charset.forName("UTF-16BE"); | |
| 57 | + /** | |
| 58 | + * Sixteen-bit UCS Transformation Format, little-endian byte order | |
| 59 | + */ | |
| 60 | + public static final Charset UTF_16LE = Charset.forName("UTF-16LE"); | |
| 61 | + /** | |
| 62 | + * Sixteen-bit UCS Transformation Format, byte order identified by an | |
| 63 | + * optional byte-order mark | |
| 64 | + */ | |
| 65 | + public static final Charset UTF_16 = Charset.forName("UTF-16"); | |
| 66 | +} | |
Binary file not shown.
| @@ -0,0 +1,57 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2001, 2007, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.charset; | |
| 27 | + | |
| 28 | + | |
| 29 | +/** | |
| 30 | + * Checked exception thrown when an input character (or byte) sequence | |
| 31 | + * is valid but cannot be mapped to an output byte (or character) | |
| 32 | + * sequence. </p> | |
| 33 | + * | |
| 34 | + * @since 1.4 | |
| 35 | + */ | |
| 36 | + | |
| 37 | +public class UnmappableCharacterException | |
| 38 | + extends CharacterCodingException | |
| 39 | +{ | |
| 40 | + | |
| 41 | + private static final long serialVersionUID = -7026962371537706123L; | |
| 42 | + | |
| 43 | + private int inputLength; | |
| 44 | + | |
| 45 | + public UnmappableCharacterException(int inputLength) { | |
| 46 | + this.inputLength = inputLength; | |
| 47 | + } | |
| 48 | + | |
| 49 | + public int getInputLength() { | |
| 50 | + return inputLength; | |
| 51 | + } | |
| 52 | + | |
| 53 | + public String getMessage() { | |
| 54 | + return "Input length = " + inputLength; | |
| 55 | + } | |
| 56 | + | |
| 57 | +} | |
| @@ -0,0 +1,53 @@ | ||
| 1 | +# | |
| 2 | +# Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved. | |
| 3 | +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | +# | |
| 5 | +# This code is free software; you can redistribute it and/or modify it | |
| 6 | +# under the terms of the GNU General Public License version 2 only, as | |
| 7 | +# published by the Free Software Foundation. Oracle designates this | |
| 8 | +# particular file as subject to the "Classpath" exception as provided | |
| 9 | +# by Oracle in the LICENSE file that accompanied this code. | |
| 10 | +# | |
| 11 | +# This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | +# version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | +# accompanied this code). | |
| 16 | +# | |
| 17 | +# You should have received a copy of the GNU General Public License version | |
| 18 | +# 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | +# | |
| 21 | +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | +# or visit www.oracle.com if you need additional information or have any | |
| 23 | +# questions. | |
| 24 | +# | |
| 25 | + | |
| 26 | +# Generated exception classes for java.nio.charset | |
| 27 | + | |
| 28 | +SINCE=1.4 | |
| 29 | +PACKAGE=java.nio.charset | |
| 30 | +# This year should only change if the generated source is modified. | |
| 31 | +COPYRIGHT_YEARS="2000, 2007," | |
| 32 | + | |
| 33 | +SUPER=java.io.IOException | |
| 34 | + | |
| 35 | +gen CharacterCodingException " | |
| 36 | + * Checked exception thrown when a character encoding | |
| 37 | + * or decoding error occurs." \ | |
| 38 | + 8421532232154627783L | |
| 39 | + | |
| 40 | + | |
| 41 | +SUPER=IllegalArgumentException | |
| 42 | + | |
| 43 | +gen IllegalCharsetNameException " | |
| 44 | + * Unchecked exception thrown when a string that is not a | |
| 45 | + * <a href="Charset.html#names">legal charset name</a> is used as such." \ | |
| 46 | + 1457525358470002989L \ | |
| 47 | + String charsetName CharsetName "illegal charset name" | |
| 48 | + | |
| 49 | +gen UnsupportedCharsetException " | |
| 50 | + * Unchecked exception thrown when no support is available | |
| 51 | + * for a requested charset." \ | |
| 52 | + 1490765524727386367L \ | |
| 53 | + String charsetName CharsetName "name of the unsupported charset" | |
| @@ -0,0 +1,18 @@ | ||
| 1 | +<../../../../../mkconfig | |
| 2 | + | |
| 3 | +DIRS=\ | |
| 4 | + spi\ | |
| 5 | + | |
| 6 | +TARG=\ | |
| 7 | + Charset.dis\ | |
| 8 | + CoderMalfunctionError.dis\ | |
| 9 | + CoderResult.dis\ | |
| 10 | + CodingErrorAction.dis\ | |
| 11 | + MalformedInputException.dis\ | |
| 12 | + StandardCharsets.dis\ | |
| 13 | + UnmappableCharacterException.dis\ | |
| 14 | + | |
| 15 | +DISBIN=$ROOT/java/dis/java/java/java/nio/charset | |
| 16 | + | |
| 17 | +<$ROOT/mkfiles/mkjava | |
| 18 | +<$ROOT/mkfiles/mksubdirs | |
| @@ -0,0 +1,88 @@ | ||
| 1 | +<!-- | |
| 2 | + Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + | |
| 5 | + This code is free software; you can redistribute it and/or modify it | |
| 6 | + under the terms of the GNU General Public License version 2 only, as | |
| 7 | + published by the Free Software Foundation. Oracle designates this | |
| 8 | + particular file as subject to the "Classpath" exception as provided | |
| 9 | + by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + | |
| 11 | + This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + accompanied this code). | |
| 16 | + | |
| 17 | + You should have received a copy of the GNU General Public License version | |
| 18 | + 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + | |
| 21 | + Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + or visit www.oracle.com if you need additional information or have any | |
| 23 | + questions. | |
| 24 | +--> | |
| 25 | + | |
| 26 | +<!doctype html public "-//IETF//DTD HTML//EN"> | |
| 27 | +<html> | |
| 28 | +<body bgcolor="white"> | |
| 29 | + | |
| 30 | + | |
| 31 | +Defines charsets, decoders, and encoders, for translating between bytes and | |
| 32 | +Unicode characters. | |
| 33 | + | |
| 34 | +<blockquote><table cellspacing=1 cellpadding=0 summary="Summary of charsets, decoders, and encoders in this package"> | |
| 35 | + <tr><th><p align="left">Class name</p></th><th><p align="left">Description</p></th></tr> | |
| 36 | + <tr><td valign=top><tt>{@link java.nio.charset.Charset}</tt></td> | |
| 37 | + <td>A named mapping between characters<br>and bytes</td></tr> | |
| 38 | + <tr><td valign=top><tt>{@link java.nio.charset.CharsetDecoder}</tt></td> | |
| 39 | + <td>Decodes bytes into characters</td></tr> | |
| 40 | + <tr><td valign=top><tt>{@link java.nio.charset.CharsetEncoder} </tt></td> | |
| 41 | + <td>Encodes characters into bytes</td></tr> | |
| 42 | + <tr><td valign=top><tt>{@link java.nio.charset.CoderResult} </tt></td> | |
| 43 | + <td>Describes coder results</td></tr> | |
| 44 | + <tr><td valign=top><tt>{@link java.nio.charset.CodingErrorAction} </tt></td> | |
| 45 | + <td>Describes actions to take when<br>coding errors are detected</td></tr> | |
| 46 | + | |
| 47 | +</table></blockquote> | |
| 48 | + | |
| 49 | +<p> A <i>charset</i> is named mapping between sequences of sixteen-bit Unicode | |
| 50 | +characters and sequences of bytes, in the sense defined in <a | |
| 51 | +href="http://www.ietf.org/rfc/rfc2278.txt"><i>RFC 2278</i></a>. A | |
| 52 | +<i>decoder</i> is an engine which transforms bytes in a specific charset into | |
| 53 | +characters, and an <i>encoder</i> is an engine which transforms characters into | |
| 54 | +bytes. Encoders and decoders operate on byte and character buffers. They are | |
| 55 | +collectively referred to as <i>coders</i>. | |
| 56 | + | |
| 57 | +<p> The {@link java.nio.charset.Charset} class defines methods for creating | |
| 58 | +coders for a given charset and for retrieving the various names associated with | |
| 59 | +a charset. It also defines static methods for testing whether a particular | |
| 60 | +charset is supported, for locating charset instances by name, and for | |
| 61 | +constructing a map that contains every charset for which support is available | |
| 62 | +in the current Java virtual machine. | |
| 63 | + | |
| 64 | +<p> Most users will not use these classes directly; instead they will use the | |
| 65 | +existing charset-related constructors and methods in the {@link | |
| 66 | +java.lang.String} class, together with the existing {@link | |
| 67 | +java.io.InputStreamReader} and {@link java.io.OutputStreamWriter} classes, all | |
| 68 | +of whose implementations have been reworked to make use of the charset | |
| 69 | +facilities defined in this package. A small number of changes have been made | |
| 70 | +to the {@link java.io.InputStreamReader} and {@link java.io.OutputStreamWriter} | |
| 71 | +classes in order to allow explicit charset objects to be specified in the | |
| 72 | +construction of instances of those classes. | |
| 73 | + | |
| 74 | +<p> Support for new charsets can be made available via the interface defined in | |
| 75 | +the {@link java.nio.charset.spi.CharsetProvider} class in the <tt>{@link | |
| 76 | +java.nio.charset.spi}</tt> package. | |
| 77 | + | |
| 78 | +<p> Unless otherwise noted, passing a <tt>null</tt> argument to a constructor | |
| 79 | +or method in any class or interface in this package will cause a {@link | |
| 80 | +java.lang.NullPointerException NullPointerException} to be thrown. | |
| 81 | + | |
| 82 | + | |
| 83 | +@since 1.4 | |
| 84 | +@author Mark Reinhold | |
| 85 | +@author JSR-51 Expert Group | |
| 86 | + | |
| 87 | +</body> | |
| 88 | +</html> | |
Binary file not shown.
| @@ -0,0 +1,110 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.charset.spi; | |
| 27 | + | |
| 28 | +import java.nio.charset.Charset; | |
| 29 | +import java.util.Iterator; | |
| 30 | + | |
| 31 | + | |
| 32 | +/** | |
| 33 | + * Charset service-provider class. | |
| 34 | + * | |
| 35 | + * <p> A charset provider is a concrete subclass of this class that has a | |
| 36 | + * zero-argument constructor and some number of associated charset | |
| 37 | + * implementation classes. Charset providers may be installed in an instance | |
| 38 | + * of the Java platform as extensions, that is, jar files placed into any of | |
| 39 | + * the usual extension directories. Providers may also be made available by | |
| 40 | + * adding them to the applet or application class path or by some other | |
| 41 | + * platform-specific means. Charset providers are looked up via the current | |
| 42 | + * thread's {@link java.lang.Thread#getContextClassLoader() </code>context | |
| 43 | + * class loader<code>}. | |
| 44 | + * | |
| 45 | + * <p> A charset provider identifies itself with a provider-configuration file | |
| 46 | + * named <tt>java.nio.charset.spi.CharsetProvider</tt> in the resource | |
| 47 | + * directory <tt>META-INF/services</tt>. The file should contain a list of | |
| 48 | + * fully-qualified concrete charset-provider class names, one per line. A line | |
| 49 | + * is terminated by any one of a line feed (<tt>'\n'</tt>), a carriage return | |
| 50 | + * (<tt>'\r'</tt>), or a carriage return followed immediately by a line feed. | |
| 51 | + * Space and tab characters surrounding each name, as well as blank lines, are | |
| 52 | + * ignored. The comment character is <tt>'#'</tt> (<tt>'\u0023'</tt>); on | |
| 53 | + * each line all characters following the first comment character are ignored. | |
| 54 | + * The file must be encoded in UTF-8. | |
| 55 | + * | |
| 56 | + * <p> If a particular concrete charset provider class is named in more than | |
| 57 | + * one configuration file, or is named in the same configuration file more than | |
| 58 | + * once, then the duplicates will be ignored. The configuration file naming a | |
| 59 | + * particular provider need not be in the same jar file or other distribution | |
| 60 | + * unit as the provider itself. The provider must be accessible from the same | |
| 61 | + * class loader that was initially queried to locate the configuration file; | |
| 62 | + * this is not necessarily the class loader that loaded the file. </p> | |
| 63 | + * | |
| 64 | + * | |
| 65 | + * @author Mark Reinhold | |
| 66 | + * @author JSR-51 Expert Group | |
| 67 | + * @since 1.4 | |
| 68 | + * | |
| 69 | + * @see java.nio.charset.Charset | |
| 70 | + */ | |
| 71 | + | |
| 72 | +public abstract class CharsetProvider { | |
| 73 | + | |
| 74 | + /** | |
| 75 | + * Initializes a new charset provider. </p> | |
| 76 | + * | |
| 77 | + * @throws SecurityException | |
| 78 | + * If a security manager has been installed and it denies | |
| 79 | + * {@link RuntimePermission}<tt>("charsetProvider")</tt> | |
| 80 | + */ | |
| 81 | + protected CharsetProvider() { | |
| 82 | + SecurityManager sm = System.getSecurityManager(); | |
| 83 | + if (sm != null) | |
| 84 | + sm.checkPermission(new RuntimePermission("charsetProvider")); | |
| 85 | + } | |
| 86 | + | |
| 87 | + /** | |
| 88 | + * Creates an iterator that iterates over the charsets supported by this | |
| 89 | + * provider. This method is used in the implementation of the {@link | |
| 90 | + * java.nio.charset.Charset#availableCharsets Charset.availableCharsets} | |
| 91 | + * method. </p> | |
| 92 | + * | |
| 93 | + * @return The new iterator | |
| 94 | + */ | |
| 95 | + public abstract Iterator<Charset> charsets(); | |
| 96 | + | |
| 97 | + /** | |
| 98 | + * Retrieves a charset for the given charset name. </p> | |
| 99 | + * | |
| 100 | + * @param charsetName | |
| 101 | + * The name of the requested charset; may be either | |
| 102 | + * a canonical name or an alias | |
| 103 | + * | |
| 104 | + * @return A charset object for the named charset, | |
| 105 | + * or <tt>null</tt> if the named charset | |
| 106 | + * is not supported by this provider | |
| 107 | + */ | |
| 108 | + public abstract Charset charsetForName(String charsetName); | |
| 109 | + | |
| 110 | +} | |
| @@ -0,0 +1,8 @@ | ||
| 1 | +<../../../../../../mkconfig | |
| 2 | + | |
| 3 | +TARG=\ | |
| 4 | + CharsetProvider.dis\ | |
| 5 | + | |
| 6 | +DISBIN=$ROOT/java/dis/java/java/java/nio/charset/spi | |
| 7 | + | |
| 8 | +<$ROOT/mkfiles/mkjava | |
| @@ -0,0 +1,45 @@ | ||
| 1 | +<!-- | |
| 2 | + Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + | |
| 5 | + This code is free software; you can redistribute it and/or modify it | |
| 6 | + under the terms of the GNU General Public License version 2 only, as | |
| 7 | + published by the Free Software Foundation. Oracle designates this | |
| 8 | + particular file as subject to the "Classpath" exception as provided | |
| 9 | + by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + | |
| 11 | + This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + accompanied this code). | |
| 16 | + | |
| 17 | + You should have received a copy of the GNU General Public License version | |
| 18 | + 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + | |
| 21 | + Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + or visit www.oracle.com if you need additional information or have any | |
| 23 | + questions. | |
| 24 | +--> | |
| 25 | + | |
| 26 | +<!doctype html public "-//IETF//DTD HTML//EN"> | |
| 27 | +<html> | |
| 28 | +<body bgcolor="white"> | |
| 29 | + | |
| 30 | +Service-provider classes for the <tt>{@link java.nio.charset}</tt> package. | |
| 31 | + | |
| 32 | +<p> Only developers who are defining new charsets should need to make direct | |
| 33 | +use of this package. </p> | |
| 34 | + | |
| 35 | +<p> Unless otherwise noted, passing a <tt>null</tt> argument to a constructor | |
| 36 | +or method in any class or interface in this package will cause a {@link | |
| 37 | +java.lang.NullPointerException NullPointerException} to be thrown. | |
| 38 | + | |
| 39 | + | |
| 40 | +@since 1.4 | |
| 41 | +@author Mark Reinhold | |
| 42 | +@author JSR-51 Expert Group | |
| 43 | + | |
| 44 | +</body> | |
| 45 | +</html> | |
| @@ -0,0 +1,60 @@ | ||
| 1 | +# | |
| 2 | +# Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved. | |
| 3 | +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | +# | |
| 5 | +# This code is free software; you can redistribute it and/or modify it | |
| 6 | +# under the terms of the GNU General Public License version 2 only, as | |
| 7 | +# published by the Free Software Foundation. Oracle designates this | |
| 8 | +# particular file as subject to the "Classpath" exception as provided | |
| 9 | +# by Oracle in the LICENSE file that accompanied this code. | |
| 10 | +# | |
| 11 | +# This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | +# version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | +# accompanied this code). | |
| 16 | +# | |
| 17 | +# You should have received a copy of the GNU General Public License version | |
| 18 | +# 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | +# | |
| 21 | +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | +# or visit www.oracle.com if you need additional information or have any | |
| 23 | +# questions. | |
| 24 | +# | |
| 25 | + | |
| 26 | +# Generated exception classes for java.nio | |
| 27 | + | |
| 28 | +SINCE=1.4 | |
| 29 | +PACKAGE=java.nio | |
| 30 | +# This year should only change if the generated source is modified. | |
| 31 | +COPYRIGHT_YEARS="2000, 2007," | |
| 32 | + | |
| 33 | + | |
| 34 | +SUPER=RuntimeException | |
| 35 | + | |
| 36 | +gen BufferOverflowException " | |
| 37 | + * Unchecked exception thrown when a relative <i>put</i> operation reaches | |
| 38 | + * the target buffer's limit." \ | |
| 39 | + -5484897634319144535L | |
| 40 | + | |
| 41 | +gen BufferUnderflowException " | |
| 42 | + * Unchecked exception thrown when a relative <i>get</i> operation reaches | |
| 43 | + * the source buffer's limit." \ | |
| 44 | + -1713313658691622206L | |
| 45 | + | |
| 46 | + | |
| 47 | +SUPER=IllegalStateException | |
| 48 | + | |
| 49 | +gen InvalidMarkException " | |
| 50 | + * Unchecked exception thrown when an attempt is made to reset a buffer | |
| 51 | + * when its mark is not defined." \ | |
| 52 | + 1698329710438510774L | |
| 53 | + | |
| 54 | + | |
| 55 | +SUPER=UnsupportedOperationException | |
| 56 | + | |
| 57 | +gen ReadOnlyBufferException " | |
| 58 | + * Unchecked exception thrown when a content-mutation method such as | |
| 59 | + * <tt>put</tt> or <tt>compact</tt> is invoked upon a read-only buffer." \ | |
| 60 | + -1210063976496234090L | |
Binary file not shown.
| @@ -0,0 +1,68 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.file; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * Checked exception thrown when a file system operation is denied, typically | |
| 30 | + * due to a file permission or other access check. | |
| 31 | + * | |
| 32 | + * <p> This exception is not related to the {@link | |
| 33 | + * java.security.AccessControlException AccessControlException} or {@link | |
| 34 | + * SecurityException} thrown by access controllers or security managers when | |
| 35 | + * access to a file is denied. | |
| 36 | + * | |
| 37 | + * @since 1.7 | |
| 38 | + */ | |
| 39 | + | |
| 40 | +public class AccessDeniedException | |
| 41 | + extends FileSystemException | |
| 42 | +{ | |
| 43 | + private static final long serialVersionUID = 4943049599949219617L; | |
| 44 | + | |
| 45 | + /** | |
| 46 | + * Constructs an instance of this class. | |
| 47 | + * | |
| 48 | + * @param file | |
| 49 | + * a string identifying the file or {@code null} if not known | |
| 50 | + */ | |
| 51 | + public AccessDeniedException(String file) { | |
| 52 | + super(file); | |
| 53 | + } | |
| 54 | + | |
| 55 | + /** | |
| 56 | + * Constructs an instance of this class. | |
| 57 | + * | |
| 58 | + * @param file | |
| 59 | + * a string identifying the file or {@code null} if not known | |
| 60 | + * @param other | |
| 61 | + * a string identifying the other file or {@code null} if not known | |
| 62 | + * @param reason | |
| 63 | + * a reason message with additional information or {@code null} | |
| 64 | + */ | |
| 65 | + public AccessDeniedException(String file, String other, String reason) { | |
| 66 | + super(file, other, reason); | |
| 67 | + } | |
| 68 | +} | |
Binary file not shown.
| @@ -0,0 +1,47 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.file; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * Defines access modes used to test the accessibility of a file. | |
| 30 | + * | |
| 31 | + * @since 1.7 | |
| 32 | + */ | |
| 33 | + | |
| 34 | +public enum AccessMode { | |
| 35 | + /** | |
| 36 | + * Test read access. | |
| 37 | + */ | |
| 38 | + READ, | |
| 39 | + /** | |
| 40 | + * Test write access. | |
| 41 | + */ | |
| 42 | + WRITE, | |
| 43 | + /** | |
| 44 | + * Test execute access. | |
| 45 | + */ | |
| 46 | + EXECUTE; | |
| 47 | +} | |
Binary file not shown.
| @@ -0,0 +1,56 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.file; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * Checked exception thrown when a file cannot be moved as an atomic file system | |
| 30 | + * operation. | |
| 31 | + * | |
| 32 | + * @since 1.7 | |
| 33 | + */ | |
| 34 | + | |
| 35 | +public class AtomicMoveNotSupportedException | |
| 36 | + extends FileSystemException | |
| 37 | +{ | |
| 38 | + static final long serialVersionUID = 5402760225333135579L; | |
| 39 | + | |
| 40 | + /** | |
| 41 | + * Constructs an instance of this class. | |
| 42 | + * | |
| 43 | + * @param source | |
| 44 | + * a string identifying the source file or {@code null} if not known | |
| 45 | + * @param target | |
| 46 | + * a string identifying the target file or {@code null} if not known | |
| 47 | + * @param reason | |
| 48 | + * a reason message with additional information | |
| 49 | + */ | |
| 50 | + public AtomicMoveNotSupportedException(String source, | |
| 51 | + String target, | |
| 52 | + String reason) | |
| 53 | + { | |
| 54 | + super(source, target, reason); | |
| 55 | + } | |
| 56 | +} | |
Binary file not shown.
| @@ -0,0 +1,45 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.file; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * Unchecked exception thrown when an attempt is made to invoke an operation on | |
| 30 | + * a directory stream that is closed. | |
| 31 | + * | |
| 32 | + * @since 1.7 | |
| 33 | + */ | |
| 34 | + | |
| 35 | +public class ClosedDirectoryStreamException | |
| 36 | + extends IllegalStateException | |
| 37 | +{ | |
| 38 | + static final long serialVersionUID = 4228386650900895400L; | |
| 39 | + | |
| 40 | + /** | |
| 41 | + * Constructs an instance of this class. | |
| 42 | + */ | |
| 43 | + public ClosedDirectoryStreamException() { | |
| 44 | + } | |
| 45 | +} | |
Binary file not shown.
| @@ -0,0 +1,43 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.file; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * Unchecked exception thrown when an attempt is made to invoke an operation on | |
| 30 | + * a file and the file system is closed. | |
| 31 | + */ | |
| 32 | + | |
| 33 | +public class ClosedFileSystemException | |
| 34 | + extends IllegalStateException | |
| 35 | +{ | |
| 36 | + static final long serialVersionUID = -8158336077256193488L; | |
| 37 | + | |
| 38 | + /** | |
| 39 | + * Constructs an instance of this class. | |
| 40 | + */ | |
| 41 | + public ClosedFileSystemException() { | |
| 42 | + } | |
| 43 | +} | |
Binary file not shown.
| @@ -0,0 +1,43 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.file; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * Unchecked exception thrown when an attempt is made to invoke an operation on | |
| 30 | + * a watch service that is closed. | |
| 31 | + */ | |
| 32 | + | |
| 33 | +public class ClosedWatchServiceException | |
| 34 | + extends IllegalStateException | |
| 35 | +{ | |
| 36 | + static final long serialVersionUID = 1853336266231677732L; | |
| 37 | + | |
| 38 | + /** | |
| 39 | + * Constructs an instance of this class. | |
| 40 | + */ | |
| 41 | + public ClosedWatchServiceException() { | |
| 42 | + } | |
| 43 | +} | |
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,160 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.file; | |
| 27 | + | |
| 28 | +import java.nio.file.attribute.*; | |
| 29 | +import java.io.InputStream; | |
| 30 | +import java.io.IOException; | |
| 31 | + | |
| 32 | +/** | |
| 33 | + * Helper class to support copying or moving files when the source and target | |
| 34 | + * are associated with different providers. | |
| 35 | + */ | |
| 36 | + | |
| 37 | +class CopyMoveHelper { | |
| 38 | + private CopyMoveHelper() { } | |
| 39 | + | |
| 40 | + /** | |
| 41 | + * Parses the arguments for a file copy operation. | |
| 42 | + */ | |
| 43 | + private static class CopyOptions { | |
| 44 | + boolean replaceExisting = false; | |
| 45 | + boolean copyAttributes = false; | |
| 46 | + boolean followLinks = true; | |
| 47 | + | |
| 48 | + private CopyOptions() { } | |
| 49 | + | |
| 50 | + static CopyOptions parse(CopyOption... options) { | |
| 51 | + CopyOptions result = new CopyOptions(); | |
| 52 | + for (CopyOption option: options) { | |
| 53 | + if (option == StandardCopyOption.REPLACE_EXISTING) { | |
| 54 | + result.replaceExisting = true; | |
| 55 | + continue; | |
| 56 | + } | |
| 57 | + if (option == LinkOption.NOFOLLOW_LINKS) { | |
| 58 | + result.followLinks = false; | |
| 59 | + continue; | |
| 60 | + } | |
| 61 | + if (option == StandardCopyOption.COPY_ATTRIBUTES) { | |
| 62 | + result.copyAttributes = true; | |
| 63 | + continue; | |
| 64 | + } | |
| 65 | + if (option == null) | |
| 66 | + throw new NullPointerException(); | |
| 67 | + throw new UnsupportedOperationException("'" + option + | |
| 68 | + "' is not a recognized copy option"); | |
| 69 | + } | |
| 70 | + return result; | |
| 71 | + } | |
| 72 | + } | |
| 73 | + | |
| 74 | + /** | |
| 75 | + * Converts the given array of options for moving a file to options suitable | |
| 76 | + * for copying the file when a move is implemented as copy + delete. | |
| 77 | + */ | |
| 78 | + private static CopyOption[] convertMoveToCopyOptions(CopyOption... options) | |
| 79 | + throws AtomicMoveNotSupportedException | |
| 80 | + { | |
| 81 | + int len = options.length; | |
| 82 | + CopyOption[] newOptions = new CopyOption[len+2]; | |
| 83 | + for (int i=0; i<len; i++) { | |
| 84 | + CopyOption option = options[i]; | |
| 85 | + if (option == StandardCopyOption.ATOMIC_MOVE) { | |
| 86 | + throw new AtomicMoveNotSupportedException(null, null, | |
| 87 | + "Atomic move between providers is not supported"); | |
| 88 | + } | |
| 89 | + newOptions[i] = option; | |
| 90 | + } | |
| 91 | + newOptions[len] = LinkOption.NOFOLLOW_LINKS; | |
| 92 | + newOptions[len+1] = StandardCopyOption.COPY_ATTRIBUTES; | |
| 93 | + return newOptions; | |
| 94 | + } | |
| 95 | + | |
| 96 | + /** | |
| 97 | + * Simple copy for use when source and target are associated with different | |
| 98 | + * providers | |
| 99 | + */ | |
| 100 | + static void copyToForeignTarget(Path source, Path target, | |
| 101 | + CopyOption... options) | |
| 102 | + throws IOException | |
| 103 | + { | |
| 104 | + CopyOptions opts = CopyOptions.parse(options); | |
| 105 | + LinkOption[] linkOptions = (opts.followLinks) ? new LinkOption[0] : | |
| 106 | + new LinkOption[] { LinkOption.NOFOLLOW_LINKS }; | |
| 107 | + | |
| 108 | + // attributes of source file | |
| 109 | + BasicFileAttributes attrs = Files.readAttributes(source, | |
| 110 | + BasicFileAttributes.class, | |
| 111 | + linkOptions); | |
| 112 | + if (attrs.isSymbolicLink()) | |
| 113 | + throw new IOException("Copying of symbolic links not supported"); | |
| 114 | + | |
| 115 | + // delete target if it exists and REPLACE_EXISTING is specified | |
| 116 | + if (opts.replaceExisting) { | |
| 117 | + Files.deleteIfExists(target); | |
| 118 | + } else if (Files.exists(target)) | |
| 119 | + throw new FileAlreadyExistsException(target.toString()); | |
| 120 | + | |
| 121 | + // create directory or copy file | |
| 122 | + if (attrs.isDirectory()) { | |
| 123 | + Files.createDirectory(target); | |
| 124 | + } else { | |
| 125 | + try (InputStream in = Files.newInputStream(source)) { | |
| 126 | + Files.copy(in, target); | |
| 127 | + } | |
| 128 | + } | |
| 129 | + | |
| 130 | + // copy basic attributes to target | |
| 131 | + if (opts.copyAttributes) { | |
| 132 | + BasicFileAttributeView view = | |
| 133 | + Files.getFileAttributeView(target, BasicFileAttributeView.class, linkOptions); | |
| 134 | + try { | |
| 135 | + view.setTimes(attrs.lastModifiedTime(), | |
| 136 | + attrs.lastAccessTime(), | |
| 137 | + attrs.creationTime()); | |
| 138 | + } catch (Throwable x) { | |
| 139 | + // rollback | |
| 140 | + try { | |
| 141 | + Files.delete(target); | |
| 142 | + } catch (Throwable suppressed) { | |
| 143 | + x.addSuppressed(suppressed); | |
| 144 | + } | |
| 145 | + throw x; | |
| 146 | + } | |
| 147 | + } | |
| 148 | + } | |
| 149 | + | |
| 150 | + /** | |
| 151 | + * Simple move implements as copy+delete for use when source and target are | |
| 152 | + * associated with different providers | |
| 153 | + */ | |
| 154 | + static void moveToForeignTarget(Path source, Path target, | |
| 155 | + CopyOption... options) throws IOException | |
| 156 | + { | |
| 157 | + copyToForeignTarget(source, target, convertMoveToCopyOptions(options)); | |
| 158 | + Files.delete(source); | |
| 159 | + } | |
| 160 | +} | |
Binary file not shown.
| @@ -0,0 +1,45 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.file; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * An object that configures how to copy or move a file. | |
| 30 | + * | |
| 31 | + * <p> Objects of this type may be used with the {@link | |
| 32 | + * Files#copy(Path,Path,CopyOption[]) Files.copy(Path,Path,CopyOption...)}, | |
| 33 | + * {@link Files#copy(java.io.InputStream,Path,CopyOption[]) | |
| 34 | + * Files.copy(InputStream,Path,CopyOption...)} and {@link Files#move | |
| 35 | + * Files.move(Path,Path,CopyOption...)} methods to configure how a file is | |
| 36 | + * copied or moved. | |
| 37 | + * | |
| 38 | + * <p> The {@link StandardCopyOption} enumeration type defines the | |
| 39 | + * <i>standard</i> options. | |
| 40 | + * | |
| 41 | + * @since 1.7 | |
| 42 | + */ | |
| 43 | + | |
| 44 | +public interface CopyOption { | |
| 45 | +} | |
Binary file not shown.
| @@ -0,0 +1,87 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.file; | |
| 27 | + | |
| 28 | +import java.util.ConcurrentModificationException; | |
| 29 | +import java.util.Objects; | |
| 30 | +import java.io.IOException; | |
| 31 | +import java.io.ObjectInputStream; | |
| 32 | +import java.io.InvalidObjectException; | |
| 33 | + | |
| 34 | +/** | |
| 35 | + * Runtime exception thrown if an I/O error is encountered when iterating over | |
| 36 | + * the entries in a directory. The I/O error is retrieved as an {@link | |
| 37 | + * IOException} using the {@link #getCause() getCause()} method. | |
| 38 | + * | |
| 39 | + * @since 1.7 | |
| 40 | + * @see DirectoryStream | |
| 41 | + */ | |
| 42 | + | |
| 43 | +public final class DirectoryIteratorException | |
| 44 | + extends ConcurrentModificationException | |
| 45 | +{ | |
| 46 | + private static final long serialVersionUID = -6012699886086212874L; | |
| 47 | + | |
| 48 | + /** | |
| 49 | + * Constructs an instance of this class. | |
| 50 | + * | |
| 51 | + * @param cause | |
| 52 | + * the {@code IOException} that caused the directory iteration | |
| 53 | + * to fail | |
| 54 | + * | |
| 55 | + * @throws NullPointerException | |
| 56 | + * if the cause is {@code null} | |
| 57 | + */ | |
| 58 | + public DirectoryIteratorException(IOException cause) { | |
| 59 | + super(Objects.requireNonNull(cause)); | |
| 60 | + } | |
| 61 | + | |
| 62 | + /** | |
| 63 | + * Returns the cause of this exception. | |
| 64 | + * | |
| 65 | + * @return the cause | |
| 66 | + */ | |
| 67 | + @Override | |
| 68 | + public IOException getCause() { | |
| 69 | + return (IOException)super.getCause(); | |
| 70 | + } | |
| 71 | + | |
| 72 | + /** | |
| 73 | + * Called to read the object from a stream. | |
| 74 | + * | |
| 75 | + * @throws InvalidObjectException | |
| 76 | + * if the object is invalid or has a cause that is not | |
| 77 | + * an {@code IOException} | |
| 78 | + */ | |
| 79 | + private void readObject(ObjectInputStream s) | |
| 80 | + throws IOException, ClassNotFoundException | |
| 81 | + { | |
| 82 | + s.defaultReadObject(); | |
| 83 | + Throwable cause = super.getCause(); | |
| 84 | + if (!(cause instanceof IOException)) | |
| 85 | + throw new InvalidObjectException("Cause must be an IOException"); | |
| 86 | + } | |
| 87 | +} | |
Binary file not shown.
| @@ -0,0 +1,49 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.file; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * Checked exception thrown when a file system operation fails because a | |
| 30 | + * directory is not empty. | |
| 31 | + * | |
| 32 | + * @since 1.7 | |
| 33 | + */ | |
| 34 | + | |
| 35 | +public class DirectoryNotEmptyException | |
| 36 | + extends FileSystemException | |
| 37 | +{ | |
| 38 | + static final long serialVersionUID = 3056667871802779003L; | |
| 39 | + | |
| 40 | + /** | |
| 41 | + * Constructs an instance of this class. | |
| 42 | + * | |
| 43 | + * @param dir | |
| 44 | + * a string identifying the directory or {@code null} if not known | |
| 45 | + */ | |
| 46 | + public DirectoryNotEmptyException(String dir) { | |
| 47 | + super(dir); | |
| 48 | + } | |
| 49 | +} | |
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,159 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.file; | |
| 27 | + | |
| 28 | +import java.util.Iterator; | |
| 29 | +import java.io.Closeable; | |
| 30 | +import java.io.IOException; | |
| 31 | + | |
| 32 | +/** | |
| 33 | + * An object to iterate over the entries in a directory. A directory stream | |
| 34 | + * allows for the convenient use of the for-each construct to iterate over a | |
| 35 | + * directory. | |
| 36 | + * | |
| 37 | + * <p> <b> While {@code DirectoryStream} extends {@code Iterable}, it is not a | |
| 38 | + * general-purpose {@code Iterable} as it supports only a single {@code | |
| 39 | + * Iterator}; invoking the {@link #iterator iterator} method to obtain a second | |
| 40 | + * or subsequent iterator throws {@code IllegalStateException}. </b> | |
| 41 | + * | |
| 42 | + * <p> An important property of the directory stream's {@code Iterator} is that | |
| 43 | + * its {@link Iterator#hasNext() hasNext} method is guaranteed to read-ahead by | |
| 44 | + * at least one element. If {@code hasNext} method returns {@code true}, and is | |
| 45 | + * followed by a call to the {@code next} method, it is guaranteed that the | |
| 46 | + * {@code next} method will not throw an exception due to an I/O error, or | |
| 47 | + * because the stream has been {@link #close closed}. The {@code Iterator} does | |
| 48 | + * not support the {@link Iterator#remove remove} operation. | |
| 49 | + * | |
| 50 | + * <p> A {@code DirectoryStream} is opened upon creation and is closed by | |
| 51 | + * invoking the {@code close} method. Closing a directory stream releases any | |
| 52 | + * resources associated with the stream. Failure to close the stream may result | |
| 53 | + * in a resource leak. The try-with-resources statement provides a useful | |
| 54 | + * construct to ensure that the stream is closed: | |
| 55 | + * <pre> | |
| 56 | + * Path dir = ... | |
| 57 | + * try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) { | |
| 58 | + * for (Path entry: stream) { | |
| 59 | + * ... | |
| 60 | + * } | |
| 61 | + * } | |
| 62 | + * </pre> | |
| 63 | + * | |
| 64 | + * <p> Once a directory stream is closed, then further access to the directory, | |
| 65 | + * using the {@code Iterator}, behaves as if the end of stream has been reached. | |
| 66 | + * Due to read-ahead, the {@code Iterator} may return one or more elements | |
| 67 | + * after the directory stream has been closed. Once these buffered elements | |
| 68 | + * have been read, then subsequent calls to the {@code hasNext} method returns | |
| 69 | + * {@code false}, and subsequent calls to the {@code next} method will throw | |
| 70 | + * {@code NoSuchElementException}. | |
| 71 | + * | |
| 72 | + * <p> A directory stream is not required to be <i>asynchronously closeable</i>. | |
| 73 | + * If a thread is blocked on the directory stream's iterator reading from the | |
| 74 | + * directory, and another thread invokes the {@code close} method, then the | |
| 75 | + * second thread may block until the read operation is complete. | |
| 76 | + * | |
| 77 | + * <p> If an I/O error is encountered when accessing the directory then it | |
| 78 | + * causes the {@code Iterator}'s {@code hasNext} or {@code next} methods to | |
| 79 | + * throw {@link DirectoryIteratorException} with the {@link IOException} as the | |
| 80 | + * cause. As stated above, the {@code hasNext} method is guaranteed to | |
| 81 | + * read-ahead by at least one element. This means that if {@code hasNext} method | |
| 82 | + * returns {@code true}, and is followed by a call to the {@code next} method, | |
| 83 | + * then it is guaranteed that the {@code next} method will not fail with a | |
| 84 | + * {@code DirectoryIteratorException}. | |
| 85 | + * | |
| 86 | + * <p> The elements returned by the iterator are in no specific order. Some file | |
| 87 | + * systems maintain special links to the directory itself and the directory's | |
| 88 | + * parent directory. Entries representing these links are not returned by the | |
| 89 | + * iterator. | |
| 90 | + * | |
| 91 | + * <p> The iterator is <i>weakly consistent</i>. It is thread safe but does not | |
| 92 | + * freeze the directory while iterating, so it may (or may not) reflect updates | |
| 93 | + * to the directory that occur after the {@code DirectoryStream} is created. | |
| 94 | + * | |
| 95 | + * <p> <b>Usage Examples:</b> | |
| 96 | + * Suppose we want a list of the source files in a directory. This example uses | |
| 97 | + * both the for-each and try-with-resources constructs. | |
| 98 | + * <pre> | |
| 99 | + * List<Path> listSourceFiles(Path dir) throws IOException { | |
| 100 | + * List<Path> result = new ArrayList<>(); | |
| 101 | + * try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "*.{c,h,cpp,hpp,java}")) { | |
| 102 | + * for (Path entry: stream) { | |
| 103 | + * result.add(entry); | |
| 104 | + * } | |
| 105 | + * } catch (DirectoryIteratorException ex) { | |
| 106 | + * // I/O error encounted during the iteration, the cause is an IOException | |
| 107 | + * throw ex.getCause(); | |
| 108 | + * } | |
| 109 | + * return result; | |
| 110 | + * } | |
| 111 | + * </pre> | |
| 112 | + * @param <T> The type of element returned by the iterator | |
| 113 | + * | |
| 114 | + * @since 1.7 | |
| 115 | + * | |
| 116 | + * @see Files#newDirectoryStream(Path) | |
| 117 | + */ | |
| 118 | + | |
| 119 | +public interface DirectoryStream<T> | |
| 120 | + extends Closeable, Iterable<T> | |
| 121 | +{ | |
| 122 | + /** | |
| 123 | + * An interface that is implemented by objects that decide if a directory | |
| 124 | + * entry should be accepted or filtered. A {@code Filter} is passed as the | |
| 125 | + * parameter to the {@link Files#newDirectoryStream(Path,DirectoryStream.Filter)} | |
| 126 | + * method when opening a directory to iterate over the entries in the | |
| 127 | + * directory. | |
| 128 | + * | |
| 129 | + * @param <T> the type of the directory entry | |
| 130 | + * | |
| 131 | + * @since 1.7 | |
| 132 | + */ | |
| 133 | + public static interface Filter<T> { | |
| 134 | + /** | |
| 135 | + * Decides if the given directory entry should be accepted or filtered. | |
| 136 | + * | |
| 137 | + * @param entry | |
| 138 | + * the directory entry to be tested | |
| 139 | + * | |
| 140 | + * @return {@code true} if the directory entry should be accepted | |
| 141 | + * | |
| 142 | + * @throws IOException | |
| 143 | + * If an I/O error occurs | |
| 144 | + */ | |
| 145 | + boolean accept(T entry) throws IOException; | |
| 146 | + } | |
| 147 | + | |
| 148 | + /** | |
| 149 | + * Returns the iterator associated with this {@code DirectoryStream}. | |
| 150 | + * | |
| 151 | + * @return the iterator associated with this {@code DirectoryStream} | |
| 152 | + * | |
| 153 | + * @throws IllegalStateException | |
| 154 | + * if this directory stream is closed or the iterator has already | |
| 155 | + * been returned | |
| 156 | + */ | |
| 157 | + @Override | |
| 158 | + Iterator<T> iterator(); | |
| 159 | +} | |
Binary file not shown.
| @@ -0,0 +1,63 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.file; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * Checked exception thrown when an attempt is made to create a file or | |
| 30 | + * directory and a file of that name already exists. | |
| 31 | + * | |
| 32 | + * @since 1.7 | |
| 33 | + */ | |
| 34 | + | |
| 35 | +public class FileAlreadyExistsException | |
| 36 | + extends FileSystemException | |
| 37 | +{ | |
| 38 | + static final long serialVersionUID = 7579540934498831181L; | |
| 39 | + | |
| 40 | + /** | |
| 41 | + * Constructs an instance of this class. | |
| 42 | + * | |
| 43 | + * @param file | |
| 44 | + * a string identifying the file or {@code null} if not known | |
| 45 | + */ | |
| 46 | + public FileAlreadyExistsException(String file) { | |
| 47 | + super(file); | |
| 48 | + } | |
| 49 | + | |
| 50 | + /** | |
| 51 | + * Constructs an instance of this class. | |
| 52 | + * | |
| 53 | + * @param file | |
| 54 | + * a string identifying the file or {@code null} if not known | |
| 55 | + * @param other | |
| 56 | + * a string identifying the other file or {@code null} if not known | |
| 57 | + * @param reason | |
| 58 | + * a reason message with additional information or {@code null} | |
| 59 | + */ | |
| 60 | + public FileAlreadyExistsException(String file, String other, String reason) { | |
| 61 | + super(file, other, reason); | |
| 62 | + } | |
| 63 | +} | |
Binary file not shown.
| @@ -0,0 +1,219 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.file; | |
| 27 | + | |
| 28 | +import java.nio.file.attribute.*; | |
| 29 | +import java.io.IOException; | |
| 30 | + | |
| 31 | +/** | |
| 32 | + * Storage for files. A {@code FileStore} represents a storage pool, device, | |
| 33 | + * partition, volume, concrete file system or other implementation specific means | |
| 34 | + * of file storage. The {@code FileStore} for where a file is stored is obtained | |
| 35 | + * by invoking the {@link Files#getFileStore getFileStore} method, or all file | |
| 36 | + * stores can be enumerated by invoking the {@link FileSystem#getFileStores | |
| 37 | + * getFileStores} method. | |
| 38 | + * | |
| 39 | + * <p> In addition to the methods defined by this class, a file store may support | |
| 40 | + * one or more {@link FileStoreAttributeView FileStoreAttributeView} classes | |
| 41 | + * that provide a read-only or updatable view of a set of file store attributes. | |
| 42 | + * | |
| 43 | + * @since 1.7 | |
| 44 | + */ | |
| 45 | + | |
| 46 | +public abstract class FileStore { | |
| 47 | + | |
| 48 | + /** | |
| 49 | + * Initializes a new instance of this class. | |
| 50 | + */ | |
| 51 | + protected FileStore() { | |
| 52 | + } | |
| 53 | + | |
| 54 | + /** | |
| 55 | + * Returns the name of this file store. The format of the name is highly | |
| 56 | + * implementation specific. It will typically be the name of the storage | |
| 57 | + * pool or volume. | |
| 58 | + * | |
| 59 | + * <p> The string returned by this method may differ from the string | |
| 60 | + * returned by the {@link Object#toString() toString} method. | |
| 61 | + * | |
| 62 | + * @return the name of this file store | |
| 63 | + */ | |
| 64 | + public abstract String name(); | |
| 65 | + | |
| 66 | + /** | |
| 67 | + * Returns the <em>type</em> of this file store. The format of the string | |
| 68 | + * returned by this method is highly implementation specific. It may | |
| 69 | + * indicate, for example, the format used or if the file store is local | |
| 70 | + * or remote. | |
| 71 | + * | |
| 72 | + * @return a string representing the type of this file store | |
| 73 | + */ | |
| 74 | + public abstract String type(); | |
| 75 | + | |
| 76 | + /** | |
| 77 | + * Tells whether this file store is read-only. A file store is read-only if | |
| 78 | + * it does not support write operations or other changes to files. Any | |
| 79 | + * attempt to create a file, open an existing file for writing etc. causes | |
| 80 | + * an {@code IOException} to be thrown. | |
| 81 | + * | |
| 82 | + * @return {@code true} if, and only if, this file store is read-only | |
| 83 | + */ | |
| 84 | + public abstract boolean isReadOnly(); | |
| 85 | + | |
| 86 | + /** | |
| 87 | + * Returns the size, in bytes, of the file store. | |
| 88 | + * | |
| 89 | + * @return the size of the file store, in bytes | |
| 90 | + * | |
| 91 | + * @throws IOException | |
| 92 | + * if an I/O error occurs | |
| 93 | + */ | |
| 94 | + public abstract long getTotalSpace() throws IOException; | |
| 95 | + | |
| 96 | + /** | |
| 97 | + * Returns the number of bytes available to this Java virtual machine on the | |
| 98 | + * file store. | |
| 99 | + * | |
| 100 | + * <p> The returned number of available bytes is a hint, but not a | |
| 101 | + * guarantee, that it is possible to use most or any of these bytes. The | |
| 102 | + * number of usable bytes is most likely to be accurate immediately | |
| 103 | + * after the space attributes are obtained. It is likely to be made inaccurate | |
| 104 | + * by any external I/O operations including those made on the system outside | |
| 105 | + * of this Java virtual machine. | |
| 106 | + * | |
| 107 | + * @return the number of bytes available | |
| 108 | + * | |
| 109 | + * @throws IOException | |
| 110 | + * if an I/O error occurs | |
| 111 | + */ | |
| 112 | + public abstract long getUsableSpace() throws IOException; | |
| 113 | + | |
| 114 | + /** | |
| 115 | + * Returns the number of unallocated bytes in the file store. | |
| 116 | + * | |
| 117 | + * <p> The returned number of unallocated bytes is a hint, but not a | |
| 118 | + * guarantee, that it is possible to use most or any of these bytes. The | |
| 119 | + * number of unallocated bytes is most likely to be accurate immediately | |
| 120 | + * after the space attributes are obtained. It is likely to be | |
| 121 | + * made inaccurate by any external I/O operations including those made on | |
| 122 | + * the system outside of this virtual machine. | |
| 123 | + * | |
| 124 | + * @return the number of unallocated bytes | |
| 125 | + * | |
| 126 | + * @throws IOException | |
| 127 | + * if an I/O error occurs | |
| 128 | + */ | |
| 129 | + public abstract long getUnallocatedSpace() throws IOException; | |
| 130 | + | |
| 131 | + /** | |
| 132 | + * Tells whether or not this file store supports the file attributes | |
| 133 | + * identified by the given file attribute view. | |
| 134 | + * | |
| 135 | + * <p> Invoking this method to test if the file store supports {@link | |
| 136 | + * BasicFileAttributeView} will always return {@code true}. In the case of | |
| 137 | + * the default provider, this method cannot guarantee to give the correct | |
| 138 | + * result when the file store is not a local storage device. The reasons for | |
| 139 | + * this are implementation specific and therefore unspecified. | |
| 140 | + * | |
| 141 | + * @param type | |
| 142 | + * the file attribute view type | |
| 143 | + * | |
| 144 | + * @return {@code true} if, and only if, the file attribute view is | |
| 145 | + * supported | |
| 146 | + */ | |
| 147 | + public abstract boolean supportsFileAttributeView(Class<? extends FileAttributeView> type); | |
| 148 | + | |
| 149 | + /** | |
| 150 | + * Tells whether or not this file store supports the file attributes | |
| 151 | + * identified by the given file attribute view. | |
| 152 | + * | |
| 153 | + * <p> Invoking this method to test if the file store supports {@link | |
| 154 | + * BasicFileAttributeView}, identified by the name "{@code basic}" will | |
| 155 | + * always return {@code true}. In the case of the default provider, this | |
| 156 | + * method cannot guarantee to give the correct result when the file store is | |
| 157 | + * not a local storage device. The reasons for this are implementation | |
| 158 | + * specific and therefore unspecified. | |
| 159 | + * | |
| 160 | + * @param name | |
| 161 | + * the {@link FileAttributeView#name name} of file attribute view | |
| 162 | + * | |
| 163 | + * @return {@code true} if, and only if, the file attribute view is | |
| 164 | + * supported | |
| 165 | + */ | |
| 166 | + public abstract boolean supportsFileAttributeView(String name); | |
| 167 | + | |
| 168 | + /** | |
| 169 | + * Returns a {@code FileStoreAttributeView} of the given type. | |
| 170 | + * | |
| 171 | + * <p> This method is intended to be used where the file store attribute | |
| 172 | + * view defines type-safe methods to read or update the file store attributes. | |
| 173 | + * The {@code type} parameter is the type of the attribute view required and | |
| 174 | + * the method returns an instance of that type if supported. | |
| 175 | + * | |
| 176 | + * @param type | |
| 177 | + * the {@code Class} object corresponding to the attribute view | |
| 178 | + * | |
| 179 | + * @return a file store attribute view of the specified type or | |
| 180 | + * {@code null} if the attribute view is not available | |
| 181 | + */ | |
| 182 | + public abstract <V extends FileStoreAttributeView> V | |
| 183 | + getFileStoreAttributeView(Class<V> type); | |
| 184 | + | |
| 185 | + /** | |
| 186 | + * Reads the value of a file store attribute. | |
| 187 | + * | |
| 188 | + * <p> The {@code attribute} parameter identifies the attribute to be read | |
| 189 | + * and takes the form: | |
| 190 | + * <blockquote> | |
| 191 | + * <i>view-name</i><b>:</b><i>attribute-name</i> | |
| 192 | + * </blockquote> | |
| 193 | + * where the character {@code ':'} stands for itself. | |
| 194 | + * | |
| 195 | + * <p> <i>view-name</i> is the {@link FileStoreAttributeView#name name} of | |
| 196 | + * a {@link FileStore AttributeView} that identifies a set of file attributes. | |
| 197 | + * <i>attribute-name</i> is the name of the attribute. | |
| 198 | + * | |
| 199 | + * <p> <b>Usage Example:</b> | |
| 200 | + * Suppose we want to know if ZFS compression is enabled (assuming the "zfs" | |
| 201 | + * view is supported): | |
| 202 | + * <pre> | |
| 203 | + * boolean compression = (Boolean)fs.getAttribute("zfs:compression"); | |
| 204 | + * </pre> | |
| 205 | + * | |
| 206 | + * @param attribute | |
| 207 | + * the attribute to read | |
| 208 | + | |
| 209 | + * @return the attribute value; {@code null} may be a valid valid for some | |
| 210 | + * attributes | |
| 211 | + * | |
| 212 | + * @throws UnsupportedOperationException | |
| 213 | + * if the attribute view is not available or it does not support | |
| 214 | + * reading the attribute | |
| 215 | + * @throws IOException | |
| 216 | + * if an I/O error occurs | |
| 217 | + */ | |
| 218 | + public abstract Object getAttribute(String attribute) throws IOException; | |
| 219 | +} | |
Binary file not shown.
| @@ -0,0 +1,469 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.file; | |
| 27 | + | |
| 28 | +import java.nio.file.attribute.*; | |
| 29 | +import java.nio.file.spi.FileSystemProvider; | |
| 30 | +import java.util.Set; | |
| 31 | +import java.io.Closeable; | |
| 32 | +import java.io.IOException; | |
| 33 | + | |
| 34 | +/** | |
| 35 | + * Provides an interface to a file system and is the factory for objects to | |
| 36 | + * access files and other objects in the file system. | |
| 37 | + * | |
| 38 | + * <p> The default file system, obtained by invoking the {@link FileSystems#getDefault | |
| 39 | + * FileSystems.getDefault} method, provides access to the file system that is | |
| 40 | + * accessible to the Java virtual machine. The {@link FileSystems} class defines | |
| 41 | + * methods to create file systems that provide access to other types of (custom) | |
| 42 | + * file systems. | |
| 43 | + * | |
| 44 | + * <p> A file system is the factory for several types of objects: | |
| 45 | + * | |
| 46 | + * <ul> | |
| 47 | + * <li><p> The {@link #getPath getPath} method converts a system dependent | |
| 48 | + * <em>path string</em>, returning a {@link Path} object that may be used | |
| 49 | + * to locate and access a file. </p></li> | |
| 50 | + * <li><p> The {@link #getPathMatcher getPathMatcher} method is used | |
| 51 | + * to create a {@link PathMatcher} that performs match operations on | |
| 52 | + * paths. </p></li> | |
| 53 | + * <li><p> The {@link #getFileStores getFileStores} method returns an iterator | |
| 54 | + * over the underlying {@link FileStore file-stores}. </p></li> | |
| 55 | + * <li><p> The {@link #getUserPrincipalLookupService getUserPrincipalLookupService} | |
| 56 | + * method returns the {@link UserPrincipalLookupService} to lookup users or | |
| 57 | + * groups by name. </p></li> | |
| 58 | + * <li><p> The {@link #newWatchService newWatchService} method creates a | |
| 59 | + * {@link WatchService} that may be used to watch objects for changes and | |
| 60 | + * events. </p></li> | |
| 61 | + * </ul> | |
| 62 | + * | |
| 63 | + * <p> File systems vary greatly. In some cases the file system is a single | |
| 64 | + * hierarchy of files with one top-level root directory. In other cases it may | |
| 65 | + * have several distinct file hierarchies, each with its own top-level root | |
| 66 | + * directory. The {@link #getRootDirectories getRootDirectories} method may be | |
| 67 | + * used to iterate over the root directories in the file system. A file system | |
| 68 | + * is typically composed of one or more underlying {@link FileStore file-stores} | |
| 69 | + * that provide the storage for the files. Theses file stores can also vary in | |
| 70 | + * the features they support, and the file attributes or <em>meta-data</em> that | |
| 71 | + * they associate with files. | |
| 72 | + * | |
| 73 | + * <p> A file system is open upon creation and can be closed by invoking its | |
| 74 | + * {@link #close() close} method. Once closed, any further attempt to access | |
| 75 | + * objects in the file system cause {@link ClosedFileSystemException} to be | |
| 76 | + * thrown. File systems created by the default {@link FileSystemProvider provider} | |
| 77 | + * cannot be closed. | |
| 78 | + * | |
| 79 | + * <p> A {@code FileSystem} can provide read-only or read-write access to the | |
| 80 | + * file system. Whether or not a file system provides read-only access is | |
| 81 | + * established when the {@code FileSystem} is created and can be tested by invoking | |
| 82 | + * its {@link #isReadOnly() isReadOnly} method. Attempts to write to file stores | |
| 83 | + * by means of an object associated with a read-only file system throws {@link | |
| 84 | + * ReadOnlyFileSystemException}. | |
| 85 | + * | |
| 86 | + * <p> File systems are safe for use by multiple concurrent threads. The {@link | |
| 87 | + * #close close} method may be invoked at any time to close a file system but | |
| 88 | + * whether a file system is <i>asynchronously closeable</i> is provider specific | |
| 89 | + * and therefore unspecified. In other words, if a thread is accessing an | |
| 90 | + * object in a file system, and another thread invokes the {@code close} method | |
| 91 | + * then it may require to block until the first operation is complete. Closing | |
| 92 | + * a file system causes all open channels, watch services, and other {@link | |
| 93 | + * Closeable closeable} objects associated with the file system to be closed. | |
| 94 | + * | |
| 95 | + * @since 1.7 | |
| 96 | + */ | |
| 97 | + | |
| 98 | +public abstract class FileSystem | |
| 99 | + implements Closeable | |
| 100 | +{ | |
| 101 | + /** | |
| 102 | + * Initializes a new instance of this class. | |
| 103 | + */ | |
| 104 | + protected FileSystem() { | |
| 105 | + } | |
| 106 | + | |
| 107 | + /** | |
| 108 | + * Returns the provider that created this file system. | |
| 109 | + * | |
| 110 | + * @return The provider that created this file system. | |
| 111 | + */ | |
| 112 | + public abstract FileSystemProvider provider(); | |
| 113 | + | |
| 114 | + /** | |
| 115 | + * Closes this file system. | |
| 116 | + * | |
| 117 | + * <p> After a file system is closed then all subsequent access to the file | |
| 118 | + * system, either by methods defined by this class or on objects associated | |
| 119 | + * with this file system, throw {@link ClosedFileSystemException}. If the | |
| 120 | + * file system is already closed then invoking this method has no effect. | |
| 121 | + * | |
| 122 | + * <p> Closing a file system will close all open {@link | |
| 123 | + * java.nio.channels.Channel channels}, {@link DirectoryStream directory-streams}, | |
| 124 | + * {@link WatchService watch-service}, and other closeable objects associated | |
| 125 | + * with this file system. The {@link FileSystems#getDefault default} file | |
| 126 | + * system cannot be closed. | |
| 127 | + * | |
| 128 | + * @throws IOException | |
| 129 | + * If an I/O error occurs | |
| 130 | + * @throws UnsupportedOperationException | |
| 131 | + * Thrown in the case of the default file system | |
| 132 | + */ | |
| 133 | + @Override | |
| 134 | + public abstract void close() throws IOException; | |
| 135 | + | |
| 136 | + /** | |
| 137 | + * Tells whether or not this file system is open. | |
| 138 | + * | |
| 139 | + * <p> File systems created by the default provider are always open. | |
| 140 | + * | |
| 141 | + * @return {@code true} if, and only if, this file system is open | |
| 142 | + */ | |
| 143 | + public abstract boolean isOpen(); | |
| 144 | + | |
| 145 | + /** | |
| 146 | + * Tells whether or not this file system allows only read-only access to | |
| 147 | + * its file stores. | |
| 148 | + * | |
| 149 | + * @return {@code true} if, and only if, this file system provides | |
| 150 | + * read-only access | |
| 151 | + */ | |
| 152 | + public abstract boolean isReadOnly(); | |
| 153 | + | |
| 154 | + /** | |
| 155 | + * Returns the name separator, represented as a string. | |
| 156 | + * | |
| 157 | + * <p> The name separator is used to separate names in a path string. An | |
| 158 | + * implementation may support multiple name separators in which case this | |
| 159 | + * method returns an implementation specific <em>default</em> name separator. | |
| 160 | + * This separator is used when creating path strings by invoking the {@link | |
| 161 | + * Path#toString() toString()} method. | |
| 162 | + * | |
| 163 | + * <p> In the case of the default provider, this method returns the same | |
| 164 | + * separator as {@link java.io.File#separator}. | |
| 165 | + * | |
| 166 | + * @return The name separator | |
| 167 | + */ | |
| 168 | + public abstract String getSeparator(); | |
| 169 | + | |
| 170 | + /** | |
| 171 | + * Returns an object to iterate over the paths of the root directories. | |
| 172 | + * | |
| 173 | + * <p> A file system provides access to a file store that may be composed | |
| 174 | + * of a number of distinct file hierarchies, each with its own top-level | |
| 175 | + * root directory. Unless denied by the security manager, each element in | |
| 176 | + * the returned iterator corresponds to the root directory of a distinct | |
| 177 | + * file hierarchy. The order of the elements is not defined. The file | |
| 178 | + * hierarchies may change during the lifetime of the Java virtual machine. | |
| 179 | + * For example, in some implementations, the insertion of removable media | |
| 180 | + * may result in the creation of a new file hierarchy with its own | |
| 181 | + * top-level directory. | |
| 182 | + * | |
| 183 | + * <p> When a security manager is installed, it is invoked to check access | |
| 184 | + * to the each root directory. If denied, the root directory is not returned | |
| 185 | + * by the iterator. In the case of the default provider, the {@link | |
| 186 | + * SecurityManager#checkRead(String)} method is invoked to check read access | |
| 187 | + * to each root directory. It is system dependent if the permission checks | |
| 188 | + * are done when the iterator is obtained or during iteration. | |
| 189 | + * | |
| 190 | + * @return An object to iterate over the root directories | |
| 191 | + */ | |
| 192 | + public abstract Iterable<Path> getRootDirectories(); | |
| 193 | + | |
| 194 | + /** | |
| 195 | + * Returns an object to iterate over the underlying file stores. | |
| 196 | + * | |
| 197 | + * <p> The elements of the returned iterator are the {@link | |
| 198 | + * FileStore FileStores} for this file system. The order of the elements is | |
| 199 | + * not defined and the file stores may change during the lifetime of the | |
| 200 | + * Java virtual machine. When an I/O error occurs, perhaps because a file | |
| 201 | + * store is not accessible, then it is not returned by the iterator. | |
| 202 | + * | |
| 203 | + * <p> In the case of the default provider, and a security manager is | |
| 204 | + * installed, the security manager is invoked to check {@link | |
| 205 | + * RuntimePermission}<tt>("getFileStoreAttributes")</tt>. If denied, then | |
| 206 | + * no file stores are returned by the iterator. In addition, the security | |
| 207 | + * manager's {@link SecurityManager#checkRead(String)} method is invoked to | |
| 208 | + * check read access to the file store's <em>top-most</em> directory. If | |
| 209 | + * denied, the file store is not returned by the iterator. It is system | |
| 210 | + * dependent if the permission checks are done when the iterator is obtained | |
| 211 | + * or during iteration. | |
| 212 | + * | |
| 213 | + * <p> <b>Usage Example:</b> | |
| 214 | + * Suppose we want to print the space usage for all file stores: | |
| 215 | + * <pre> | |
| 216 | + * for (FileStore store: FileSystems.getDefault().getFileStores()) { | |
| 217 | + * long total = store.getTotalSpace() / 1024; | |
| 218 | + * long used = (store.getTotalSpace() - store.getUnallocatedSpace()) / 1024; | |
| 219 | + * long avail = store.getUsableSpace() / 1024; | |
| 220 | + * System.out.format("%-20s %12d %12d %12d%n", store, total, used, avail); | |
| 221 | + * } | |
| 222 | + * </pre> | |
| 223 | + * | |
| 224 | + * @return An object to iterate over the backing file stores | |
| 225 | + */ | |
| 226 | + public abstract Iterable<FileStore> getFileStores(); | |
| 227 | + | |
| 228 | + /** | |
| 229 | + * Returns the set of the {@link FileAttributeView#name names} of the file | |
| 230 | + * attribute views supported by this {@code FileSystem}. | |
| 231 | + * | |
| 232 | + * <p> The {@link BasicFileAttributeView} is required to be supported and | |
| 233 | + * therefore the set contains at least one element, "basic". | |
| 234 | + * | |
| 235 | + * <p> The {@link FileStore#supportsFileAttributeView(String) | |
| 236 | + * supportsFileAttributeView(String)} method may be used to test if an | |
| 237 | + * underlying {@link FileStore} supports the file attributes identified by a | |
| 238 | + * file attribute view. | |
| 239 | + * | |
| 240 | + * @return An unmodifiable set of the names of the supported file attribute | |
| 241 | + * views | |
| 242 | + */ | |
| 243 | + public abstract Set<String> supportedFileAttributeViews(); | |
| 244 | + | |
| 245 | + /** | |
| 246 | + * Converts a path string, or a sequence of strings that when joined form | |
| 247 | + * a path string, to a {@code Path}. If {@code more} does not specify any | |
| 248 | + * elements then the value of the {@code first} parameter is the path string | |
| 249 | + * to convert. If {@code more} specifies one or more elements then each | |
| 250 | + * non-empty string, including {@code first}, is considered to be a sequence | |
| 251 | + * of name elements (see {@link Path}) and is joined to form a path string. | |
| 252 | + * The details as to how the Strings are joined is provider specific but | |
| 253 | + * typically they will be joined using the {@link #getSeparator | |
| 254 | + * name-separator} as the separator. For example, if the name separator is | |
| 255 | + * "{@code /}" and {@code getPath("/foo","bar","gus")} is invoked, then the | |
| 256 | + * path string {@code "/foo/bar/gus"} is converted to a {@code Path}. | |
| 257 | + * A {@code Path} representing an empty path is returned if {@code first} | |
| 258 | + * is the empty string and {@code more} does not contain any non-empty | |
| 259 | + * strings. | |
| 260 | + * | |
| 261 | + * <p> The parsing and conversion to a path object is inherently | |
| 262 | + * implementation dependent. In the simplest case, the path string is rejected, | |
| 263 | + * and {@link InvalidPathException} thrown, if the path string contains | |
| 264 | + * characters that cannot be converted to characters that are <em>legal</em> | |
| 265 | + * to the file store. For example, on UNIX systems, the NUL (\u0000) | |
| 266 | + * character is not allowed to be present in a path. An implementation may | |
| 267 | + * choose to reject path strings that contain names that are longer than those | |
| 268 | + * allowed by any file store, and where an implementation supports a complex | |
| 269 | + * path syntax, it may choose to reject path strings that are <em>badly | |
| 270 | + * formed</em>. | |
| 271 | + * | |
| 272 | + * <p> In the case of the default provider, path strings are parsed based | |
| 273 | + * on the definition of paths at the platform or virtual file system level. | |
| 274 | + * For example, an operating system may not allow specific characters to be | |
| 275 | + * present in a file name, but a specific underlying file store may impose | |
| 276 | + * different or additional restrictions on the set of legal | |
| 277 | + * characters. | |
| 278 | + * | |
| 279 | + * <p> This method throws {@link InvalidPathException} when the path string | |
| 280 | + * cannot be converted to a path. Where possible, and where applicable, | |
| 281 | + * the exception is created with an {@link InvalidPathException#getIndex | |
| 282 | + * index} value indicating the first position in the {@code path} parameter | |
| 283 | + * that caused the path string to be rejected. | |
| 284 | + * | |
| 285 | + * @param first | |
| 286 | + * the path string or initial part of the path string | |
| 287 | + * @param more | |
| 288 | + * additional strings to be joined to form the path string | |
| 289 | + * | |
| 290 | + * @return the resulting {@code Path} | |
| 291 | + * | |
| 292 | + * @throws InvalidPathException | |
| 293 | + * If the path string cannot be converted | |
| 294 | + */ | |
| 295 | + public abstract Path getPath(String first, String... more); | |
| 296 | + | |
| 297 | + /** | |
| 298 | + * Returns a {@code PathMatcher} that performs match operations on the | |
| 299 | + * {@code String} representation of {@link Path} objects by interpreting a | |
| 300 | + * given pattern. | |
| 301 | + * | |
| 302 | + * The {@code syntaxAndPattern} parameter identifies the syntax and the | |
| 303 | + * pattern and takes the form: | |
| 304 | + * <blockquote><pre> | |
| 305 | + * <i>syntax</i><b>:</b><i>pattern</i> | |
| 306 | + * </pre></blockquote> | |
| 307 | + * where {@code ':'} stands for itself. | |
| 308 | + * | |
| 309 | + * <p> A {@code FileSystem} implementation supports the "{@code glob}" and | |
| 310 | + * "{@code regex}" syntaxes, and may support others. The value of the syntax | |
| 311 | + * component is compared without regard to case. | |
| 312 | + * | |
| 313 | + * <p> When the syntax is "{@code glob}" then the {@code String} | |
| 314 | + * representation of the path is matched using a limited pattern language | |
| 315 | + * that resembles regular expressions but with a simpler syntax. For example: | |
| 316 | + * | |
| 317 | + * <blockquote> | |
| 318 | + * <table border="0"> | |
| 319 | + * <tr> | |
| 320 | + * <td>{@code *.java}</td> | |
| 321 | + * <td>Matches a path that represents a file name ending in {@code .java}</td> | |
| 322 | + * </tr> | |
| 323 | + * <tr> | |
| 324 | + * <td>{@code *.*}</td> | |
| 325 | + * <td>Matches file names containing a dot</td> | |
| 326 | + * </tr> | |
| 327 | + * <tr> | |
| 328 | + * <tr> | |
| 329 | + * <td>{@code *.{java,class}}</td> | |
| 330 | + * <td>Matches file names ending with {@code .java} or {@code .class}</td> | |
| 331 | + * </tr> | |
| 332 | + * <tr> | |
| 333 | + * <td>{@code foo.?}</td> | |
| 334 | + * <td>Matches file names starting with {@code foo.} and a single | |
| 335 | + * character extension</td> | |
| 336 | + * </tr> | |
| 337 | + * <tr> | |
| 338 | + * <td><tt>/home/*/*</tt> | |
| 339 | + * <td>Matches <tt>/home/gus/data</tt> on UNIX platforms</td> | |
| 340 | + * </tr> | |
| 341 | + * <tr> | |
| 342 | + * <td><tt>/home/**</tt> | |
| 343 | + * <td>Matches <tt>/home/gus</tt> and | |
| 344 | + * <tt>/home/gus/data</tt> on UNIX platforms</td> | |
| 345 | + * </tr> | |
| 346 | + * <tr> | |
| 347 | + * <td><tt>C:\\*</tt> | |
| 348 | + * <td>Matches <tt>C:\foo</tt> and <tt>C:\bar</tt> on the Windows | |
| 349 | + * platform (note that the backslash is escaped; as a string literal in the | |
| 350 | + * Java Language the pattern would be <tt>"C:\\\\*"</tt>) </td> | |
| 351 | + * </tr> | |
| 352 | + * | |
| 353 | + * </table> | |
| 354 | + * </blockquote> | |
| 355 | + * | |
| 356 | + * <p> The following rules are used to interpret glob patterns: | |
| 357 | + * | |
| 358 | + * <p> <ul> | |
| 359 | + * <li><p> The {@code *} character matches zero or more {@link Character | |
| 360 | + * characters} of a {@link Path#getName(int) name} component without | |
| 361 | + * crossing directory boundaries. </p></li> | |
| 362 | + * | |
| 363 | + * <li><p> The {@code **} characters matches zero or more {@link Character | |
| 364 | + * characters} crossing directory boundaries. </p></li> | |
| 365 | + * | |
| 366 | + * <li><p> The {@code ?} character matches exactly one character of a | |
| 367 | + * name component.</p></li> | |
| 368 | + * | |
| 369 | + * <li><p> The backslash character ({@code \}) is used to escape characters | |
| 370 | + * that would otherwise be interpreted as special characters. The expression | |
| 371 | + * {@code \\} matches a single backslash and "\{" matches a left brace | |
| 372 | + * for example. </p></li> | |
| 373 | + * | |
| 374 | + * <li><p> The {@code [ ]} characters are a <i>bracket expression</i> that | |
| 375 | + * match a single character of a name component out of a set of characters. | |
| 376 | + * For example, {@code [abc]} matches {@code "a"}, {@code "b"}, or {@code "c"}. | |
| 377 | + * The hyphen ({@code -}) may be used to specify a range so {@code [a-z]} | |
| 378 | + * specifies a range that matches from {@code "a"} to {@code "z"} (inclusive). | |
| 379 | + * These forms can be mixed so [abce-g] matches {@code "a"}, {@code "b"}, | |
| 380 | + * {@code "c"}, {@code "e"}, {@code "f"} or {@code "g"}. If the character | |
| 381 | + * after the {@code [} is a {@code !} then it is used for negation so {@code | |
| 382 | + * [!a-c]} matches any character except {@code "a"}, {@code "b"}, or {@code | |
| 383 | + * "c"}. | |
| 384 | + * <p> Within a bracket expression the {@code *}, {@code ?} and {@code \} | |
| 385 | + * characters match themselves. The ({@code -}) character matches itself if | |
| 386 | + * it is the first character within the brackets, or the first character | |
| 387 | + * after the {@code !} if negating.</p></li> | |
| 388 | + * | |
| 389 | + * <li><p> The {@code { }} characters are a group of subpatterns, where | |
| 390 | + * the group matches if any subpattern in the group matches. The {@code ","} | |
| 391 | + * character is used to separate the subpatterns. Groups cannot be nested. | |
| 392 | + * </p></li> | |
| 393 | + * | |
| 394 | + * <li><p> Leading period<tt>/</tt>dot characters in file name are | |
| 395 | + * treated as regular characters in match operations. For example, | |
| 396 | + * the {@code "*"} glob pattern matches file name {@code ".login"}. | |
| 397 | + * The {@link Files#isHidden} method may be used to test whether a file | |
| 398 | + * is considered hidden. | |
| 399 | + * </p></li> | |
| 400 | + * | |
| 401 | + * <li><p> All other characters match themselves in an implementation | |
| 402 | + * dependent manner. This includes characters representing any {@link | |
| 403 | + * FileSystem#getSeparator name-separators}. </p></li> | |
| 404 | + * | |
| 405 | + * <li><p> The matching of {@link Path#getRoot root} components is highly | |
| 406 | + * implementation-dependent and is not specified. </p></li> | |
| 407 | + * | |
| 408 | + * </ul> | |
| 409 | + * | |
| 410 | + * <p> When the syntax is "{@code regex}" then the pattern component is a | |
| 411 | + * regular expression as defined by the {@link java.util.regex.Pattern} | |
| 412 | + * class. | |
| 413 | + * | |
| 414 | + * <p> For both the glob and regex syntaxes, the matching details, such as | |
| 415 | + * whether the matching is case sensitive, are implementation-dependent | |
| 416 | + * and therefore not specified. | |
| 417 | + * | |
| 418 | + * @param syntaxAndPattern | |
| 419 | + * The syntax and pattern | |
| 420 | + * | |
| 421 | + * @return A path matcher that may be used to match paths against the pattern | |
| 422 | + * | |
| 423 | + * @throws IllegalArgumentException | |
| 424 | + * If the parameter does not take the form: {@code syntax:pattern} | |
| 425 | + * @throws java.util.regex.PatternSyntaxException | |
| 426 | + * If the pattern is invalid | |
| 427 | + * @throws UnsupportedOperationException | |
| 428 | + * If the pattern syntax is not known to the implementation | |
| 429 | + * | |
| 430 | + * @see Files#newDirectoryStream(Path,String) | |
| 431 | + */ | |
| 432 | + public abstract PathMatcher getPathMatcher(String syntaxAndPattern); | |
| 433 | + | |
| 434 | + /** | |
| 435 | + * Returns the {@code UserPrincipalLookupService} for this file system | |
| 436 | + * <i>(optional operation)</i>. The resulting lookup service may be used to | |
| 437 | + * lookup user or group names. | |
| 438 | + * | |
| 439 | + * <p> <b>Usage Example:</b> | |
| 440 | + * Suppose we want to make "joe" the owner of a file: | |
| 441 | + * <pre> | |
| 442 | + * UserPrincipalLookupService lookupService = FileSystems.getDefault().getUserPrincipalLookupService(); | |
| 443 | + * Files.setOwner(path, lookupService.lookupPrincipalByName("joe")); | |
| 444 | + * </pre> | |
| 445 | + * | |
| 446 | + * @throws UnsupportedOperationException | |
| 447 | + * If this {@code FileSystem} does not does have a lookup service | |
| 448 | + * | |
| 449 | + * @return The {@code UserPrincipalLookupService} for this file system | |
| 450 | + */ | |
| 451 | + public abstract UserPrincipalLookupService getUserPrincipalLookupService(); | |
| 452 | + | |
| 453 | + /** | |
| 454 | + * Constructs a new {@link WatchService} <i>(optional operation)</i>. | |
| 455 | + * | |
| 456 | + * <p> This method constructs a new watch service that may be used to watch | |
| 457 | + * registered objects for changes and events. | |
| 458 | + * | |
| 459 | + * @return a new watch service | |
| 460 | + * | |
| 461 | + * @throws UnsupportedOperationException | |
| 462 | + * If this {@code FileSystem} does not support watching file system | |
| 463 | + * objects for changes and events. This exception is not thrown | |
| 464 | + * by {@code FileSystems} created by the default provider. | |
| 465 | + * @throws IOException | |
| 466 | + * If an I/O error occurs | |
| 467 | + */ | |
| 468 | + public abstract WatchService newWatchService() throws IOException; | |
| 469 | +} | |
Binary file not shown.
| @@ -0,0 +1,53 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.file; | |
| 27 | + | |
| 28 | +/** | |
| 29 | + * Runtime exception thrown when an attempt is made to create a file system that | |
| 30 | + * already exists. | |
| 31 | + */ | |
| 32 | + | |
| 33 | +public class FileSystemAlreadyExistsException | |
| 34 | + extends RuntimeException | |
| 35 | +{ | |
| 36 | + static final long serialVersionUID = -5438419127181131148L; | |
| 37 | + | |
| 38 | + /** | |
| 39 | + * Constructs an instance of this class. | |
| 40 | + */ | |
| 41 | + public FileSystemAlreadyExistsException() { | |
| 42 | + } | |
| 43 | + | |
| 44 | + /** | |
| 45 | + * Constructs an instance of this class. | |
| 46 | + * | |
| 47 | + * @param msg | |
| 48 | + * the detail message | |
| 49 | + */ | |
| 50 | + public FileSystemAlreadyExistsException(String msg) { | |
| 51 | + super(msg); | |
| 52 | + } | |
| 53 | +} | |
Binary file not shown.
| @@ -0,0 +1,125 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved. | |
| 3 | + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| 4 | + * | |
| 5 | + * This code is free software; you can redistribute it and/or modify it | |
| 6 | + * under the terms of the GNU General Public License version 2 only, as | |
| 7 | + * published by the Free Software Foundation. Oracle designates this | |
| 8 | + * particular file as subject to the "Classpath" exception as provided | |
| 9 | + * by Oracle in the LICENSE file that accompanied this code. | |
| 10 | + * | |
| 11 | + * This code is distributed in the hope that it will be useful, but WITHOUT | |
| 12 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 13 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 14 | + * version 2 for more details (a copy is included in the LICENSE file that | |
| 15 | + * accompanied this code). | |
| 16 | + * | |
| 17 | + * You should have received a copy of the GNU General Public License version | |
| 18 | + * 2 along with this work; if not, write to the Free Software Foundation, | |
| 19 | + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| 20 | + * | |
| 21 | + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| 22 | + * or visit www.oracle.com if you need additional information or have any | |
| 23 | + * questions. | |
| 24 | + */ | |
| 25 | + | |
| 26 | +package java.nio.file; | |
| 27 | + | |
| 28 | +import java.io.IOException; | |
| 29 | + | |
| 30 | +/** | |
| 31 | + * Thrown when a file system operation fails on one or two files. This class is | |
| 32 | + * the general class for file system exceptions. | |
| 33 | + * | |
| 34 | + * @since 1.7 | |
| 35 | + */ | |
| 36 | + | |
| 37 | +public class FileSystemException | |
| 38 | + extends IOException | |
| 39 | +{ | |
| 40 | + static final long serialVersionUID = -3055425747967319812L; | |
| 41 | + | |
| 42 | + private final String file; | |
| 43 | + private final String other; | |
| 44 | + | |
| 45 | + /** | |
| 46 | + * Constructs an instance of this class. This constructor should be used | |
| 47 | + * when an operation involving one file fails and there isn't any additional | |
| 48 | + * information to explain the reason. | |
| 49 | + * | |
| 50 | + * @param file | |
| 51 | + * a string identifying the file or {@code null} if not known. | |
| 52 | + */ | |
| 53 | + public FileSystemException(String file) { | |
| 54 | + super((String)null); | |
71 more lines aren’t shown here.
Binary file not shown.
This diff is large: its 51 lines aren’t shown here.
Binary file not shown.
This diff is large: its 53 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 406 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 249 lines aren’t shown here.
Binary file not shown.
This diff is large: its 42 lines aren’t shown here.
Binary file not shown.
This diff is large: its 63 lines aren’t shown here.
Binary file not shown.
This diff is large: its 178 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 3121 lines aren’t shown here.
Binary file not shown.
This diff is large: its 131 lines aren’t shown here.
Binary file not shown.
This diff is large: its 44 lines aren’t shown here.
Binary file not shown.
This diff is large: its 108 lines aren’t shown here.
Binary file not shown.
This diff is large: its 64 lines aren’t shown here.
Binary file not shown.
This diff is large: its 50 lines aren’t shown here.
Binary file not shown.
This diff is large: its 64 lines aren’t shown here.
Binary file not shown.
This diff is large: its 46 lines aren’t shown here.
Binary file not shown.
This diff is large: its 802 lines aren’t shown here.
Binary file not shown.
This diff is large: its 50 lines aren’t shown here.
Binary file not shown.
This diff is large: its 150 lines aren’t shown here.
Binary file not shown.
This diff is large: its 54 lines aren’t shown here.
Binary file not shown.
This diff is large: its 53 lines aren’t shown here.
Binary file not shown.
This diff is large: its 44 lines aren’t shown here.
Binary file not shown.
This diff is large: its 307 lines aren’t shown here.
Binary file not shown.
This diff is large: its 113 lines aren’t shown here.
Binary file not shown.
This diff is large: its 48 lines aren’t shown here.
Binary file not shown.
This diff is large: its 126 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 95 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 176 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 112 lines aren’t shown here.
Binary file not shown.
This diff is large: its 151 lines aren’t shown here.
Binary file not shown.
This diff is large: its 175 lines aren’t shown here.
Binary file not shown.
This diff is large: its 128 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 394 lines aren’t shown here.
Binary file not shown.
This diff is large: its 66 lines aren’t shown here.
Binary file not shown.
This diff is large: its 131 lines aren’t shown here.
Binary file not shown.
This diff is large: its 57 lines aren’t shown here.
Binary file not shown.
This diff is large: its 210 lines aren’t shown here.
Binary file not shown.
This diff is large: its 44 lines aren’t shown here.
Binary file not shown.
This diff is large: its 178 lines aren’t shown here.
Binary file not shown.
This diff is large: its 145 lines aren’t shown here.
Binary file not shown.
This diff is large: its 180 lines aren’t shown here.
Binary file not shown.
This diff is large: its 85 lines aren’t shown here.
Binary file not shown.
This diff is large: its 51 lines aren’t shown here.
Binary file not shown.
This diff is large: its 43 lines aren’t shown here.
Binary file not shown.
This diff is large: its 102 lines aren’t shown here.
Binary file not shown.
This diff is large: its 39 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This diff is large: its 364 lines aren’t shown here.
Binary file not shown.
This diff is large: its 43 lines aren’t shown here.
Binary file not shown.
This diff is large: its 194 lines aren’t shown here.
Binary file not shown.
This diff is large: its 76 lines aren’t shown here.
Binary file not shown.
This diff is large: its 85 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 181 lines aren’t shown here.
Binary file not shown.
This diff is large: its 232 lines aren’t shown here.
Binary file not shown.
This diff is large: its 55 lines aren’t shown here.
Binary file not shown.
This diff is large: its 105 lines aren’t shown here.
Binary file not shown.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 111 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 118 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 1094 lines aren’t shown here.
Binary file not shown.
This diff is large: its 107 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 140 lines aren’t shown here.