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.