Showing the changes to java/pkg/java/nio/charset (6 of 84 files). Show all
Unified · Split
| @@ -0,0 +1,51 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * | ||
| 4 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 5 | * | ||
| 6 | * This code is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms of the GNU General Public License version 2 only, as | ||
| 8 | * published by the Free Software Foundation. Oracle designates this | ||
| 9 | * particular file as subject to the "Classpath" exception as provided | ||
| 10 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 11 | * | ||
| 12 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 15 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 16 | * accompanied this code). | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License version | ||
| 19 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 20 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 21 | * | ||
| 22 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 23 | * or visit www.oracle.com if you need additional information or have any | ||
| 24 | * questions. | ||
| 25 | * | ||
| 26 | */ | ||
| 27 | |||
| 28 | // -- This file was mechanically generated: Do not edit! -- // | ||
| 29 | |||
| 30 | package java.nio.charset; | ||
| 31 | |||
| 32 | |||
| 33 | /** | ||
| 34 | * Checked exception thrown when a character encoding | ||
| 35 | * or decoding error occurs. | ||
| 36 | * | ||
| 37 | * @since 1.4 | ||
| 38 | */ | ||
| 39 | |||
| 40 | public class CharacterCodingException | ||
| 41 | extends java.io.IOException | ||
| 42 | { | ||
| 43 | |||
| 44 | private static final long serialVersionUID = 8421532232154627783L; | ||
| 45 | |||
| 46 | /** | ||
| 47 | * Constructs an instance of this class. | ||
| 48 | */ | ||
| 49 | public CharacterCodingException() { } | ||
| 50 | |||
| 51 | } | ||
| @@ -612,15 +612,19 @@ public abstract class Charset · 611 unmodified lines | |||
| 612 | */ | 612 | */ |
| 613 | public static Charset defaultCharset() { | 613 | public static Charset defaultCharset() { |
| 614 | if (defaultCharset == null) { | 614 | if (defaultCharset == null) { |
| 615 | synchronized (Charset.class) { | 615 | // [Inferno] < |
| 616 | String csn = AccessController.doPrivileged( | 616 | //synchronized (Charset.class) { |
| 617 | new GetPropertyAction("file.encoding")); | 617 | // String csn = AccessController.doPrivileged( |
| 618 | Charset cs = lookup(csn); | 618 | // new GetPropertyAction("file.encoding")); |
| 619 | if (cs != null) | 619 | // Charset cs = lookup(csn); |
| 620 | defaultCharset = cs; | 620 | // if (cs != null) |
| 621 | else | 621 | // defaultCharset = cs; |
| 622 | defaultCharset = forName("UTF-8"); | 622 | // else |
| 623 | } | 623 | // defaultCharset = forName("UTF-8"); |
| 624 | //} | ||
| 625 | // [Inferno] = | ||
| 626 | defaultCharset = forName("UTF-8"); | ||
| 627 | // [Inferno] > | ||
| 624 | } | 628 | } |
| 625 | return defaultCharset; | 629 | return defaultCharset; |
| 626 | } | 630 | } |
| @@ -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 | // -- This file was mechanically generated: Do not edit! -- // | ||
| 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 bytes in a specific charset into a sequence of | ||
| 41 | * sixteen-bit Unicode characters. | ||
| 42 | * | ||
| 43 | * <a name="steps"> | ||
| 44 | * | ||
| 45 | * <p> The input byte sequence is provided in a byte buffer or a series | ||
| 46 | * of such buffers. The output character sequence is written to a character buffer | ||
| 47 | * or a series of such buffers. A decoder should always be used by making | ||
| 48 | * the following sequence of method invocations, hereinafter referred to as a | ||
| 49 | * <i>decoding operation</i>: | ||
| 50 | * | ||
| 51 | * <ol> | ||
| 52 | * | ||
| 53 | * <li><p> Reset the decoder via the {@link #reset reset} method, unless it | ||
| 54 | * has not been used before; </p></li> | ||
| 55 | * | ||
| 56 | * <li><p> Invoke the {@link #decode decode} 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 #decode decode} 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 decoder can | ||
| 65 | * flush any internal state to the output buffer. </p></li> | ||
| 66 | * | ||
| 67 | * </ol> | ||
| 68 | * | ||
| 69 | * Each invocation of the {@link #decode decode} method will decode as many | ||
| 70 | * bytes as possible from the input buffer, writing the resulting characters | ||
| 71 | * to the output buffer. The {@link #decode decode} method returns when more | ||
| 72 | * input is required, when there is not enough room in the output buffer, or | ||
| 73 | * when a decoding 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 decoding error, as appropriate, and try again. | ||
| 77 | * | ||
| 78 | * <a name="ce"> | ||
| 79 | * | ||
| 80 | * <p> There are two general types of decoding errors. If the input byte | ||
| 81 | * sequence is not legal for this charset then the input is considered <i>malformed</i>. If | ||
| 82 | * the input byte sequence is legal but cannot be mapped to a valid | ||
| 83 | * Unicode character then an <i>unmappable character</i> has been encountered. | ||
| 84 | * | ||
| 85 | * <a name="cae"> | ||
| 86 | * | ||
| 87 | * <p> How a decoding 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 string. The replacement | ||
| 95 | * | ||
| 96 | |||
| 97 | |||
| 98 | |||
| 99 | |||
| 100 | |||
| 101 | * has the initial value <tt>"\uFFFD"</tt>; | ||
| 102 | |||
| 103 | * | ||
| 104 | * its value may be changed via the {@link #replaceWith(java.lang.String) | ||
| 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 decoding | ||
| 115 | * process, including the implementation of error actions. A decoder for a | ||
| 116 | * specific charset, which is a concrete subclass of this class, need only | ||
| 117 | * implement the abstract {@link #decodeLoop decodeLoop} method, which | ||
| 118 | * encapsulates the basic decoding 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 CharsetEncoder | ||
| 134 | */ | ||
| 135 | |||
| 136 | public abstract class CharsetDecoder { | ||
| 137 | |||
| 138 | private final Charset charset; | ||
| 139 | private final float averageCharsPerByte; | ||
| 140 | private final float maxCharsPerByte; | ||
| 141 | |||
| 142 | private String 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 decoder. The new decoder will have the given | ||
| 163 | * chars-per-byte and replacement values. </p> | ||
| 164 | * | ||
| 165 | * @param averageCharsPerByte | ||
| 166 | * A positive float value indicating the expected number of | ||
| 167 | * characters that will be produced for each input byte | ||
| 168 | * | ||
| 169 | * @param maxCharsPerByte | ||
| 170 | * A positive float value indicating the maximum number of | ||
| 171 | * characters that will be produced for each input byte | ||
| 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 maxCharsPerByte, | ||
| 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 | private | ||
| 182 | CharsetDecoder(Charset cs, | ||
| 183 | float averageCharsPerByte, | ||
| 184 | float maxCharsPerByte, | ||
| 185 | String replacement) | ||
| 186 | { | ||
| 187 | this.charset = cs; | ||
| 188 | if (averageCharsPerByte <= 0.0f) | ||
| 189 | throw new IllegalArgumentException("Non-positive " | ||
| 190 | + "averageCharsPerByte"); | ||
| 191 | if (maxCharsPerByte <= 0.0f) | ||
| 192 | throw new IllegalArgumentException("Non-positive " | ||
| 193 | + "maxCharsPerByte"); | ||
| 194 | if (!Charset.atBugLevel("1.4")) { | ||
| 195 | if (averageCharsPerByte > maxCharsPerByte) | ||
| 196 | throw new IllegalArgumentException("averageCharsPerByte" | ||
| 197 | + " exceeds " | ||
| 198 | + "maxCharsPerByte"); | ||
| 199 | } | ||
| 200 | this.replacement = replacement; | ||
| 201 | this.averageCharsPerByte = averageCharsPerByte; | ||
| 202 | this.maxCharsPerByte = maxCharsPerByte; | ||
| 203 | replaceWith(replacement); | ||
| 204 | } | ||
| 205 | |||
| 206 | /** | ||
| 207 | * Initializes a new decoder. The new decoder will have the given | ||
| 208 | * chars-per-byte values and its replacement will be the | ||
| 209 | * string <tt>"\uFFFD"</tt>. </p> | ||
| 210 | * | ||
| 211 | * @param averageCharsPerByte | ||
| 212 | * A positive float value indicating the expected number of | ||
| 213 | * characters that will be produced for each input byte | ||
| 214 | * | ||
| 215 | * @param maxCharsPerByte | ||
| 216 | * A positive float value indicating the maximum number of | ||
| 217 | * characters that will be produced for each input byte | ||
| 218 | * | ||
| 219 | * @throws IllegalArgumentException | ||
| 220 | * If the preconditions on the parameters do not hold | ||
| 221 | */ | ||
| 222 | protected CharsetDecoder(Charset cs, | ||
| 223 | float averageCharsPerByte, | ||
| 224 | float maxCharsPerByte) | ||
| 225 | { | ||
| 226 | this(cs, | ||
| 227 | averageCharsPerByte, maxCharsPerByte, | ||
| 228 | "\uFFFD"); | ||
| 229 | } | ||
| 230 | |||
| 231 | /** | ||
| 232 | * Returns the charset that created this decoder. </p> | ||
| 233 | * | ||
| 234 | * @return This decoder's charset | ||
| 235 | */ | ||
| 236 | public final Charset charset() { | ||
| 237 | return charset; | ||
| 238 | } | ||
| 239 | |||
| 240 | /** | ||
| 241 | * Returns this decoder's replacement value. </p> | ||
| 242 | * | ||
| 243 | * @return This decoder's current replacement, | ||
| 244 | * which is never <tt>null</tt> and is never empty | ||
| 245 | */ | ||
| 246 | public final String replacement() { | ||
| 247 | return replacement; | ||
| 248 | } | ||
| 249 | |||
| 250 | /** | ||
| 251 | * Changes this decoder'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 | |||
| 260 | * The new replacement; must not be <tt>null</tt> | ||
| 261 | * and must have non-zero length | ||
| 262 | |||
| 263 | |||
| 264 | |||
| 265 | |||
| 266 | |||
| 267 | |||
| 268 | |||
| 269 | * | ||
| 270 | * @return This decoder | ||
| 271 | * | ||
| 272 | * @throws IllegalArgumentException | ||
| 273 | * If the preconditions on the parameter do not hold | ||
| 274 | */ | ||
| 275 | public final CharsetDecoder replaceWith(String newReplacement) { | ||
| 276 | if (newReplacement == null) | ||
| 277 | throw new IllegalArgumentException("Null replacement"); | ||
| 278 | int len = newReplacement.length(); | ||
| 279 | if (len == 0) | ||
| 280 | throw new IllegalArgumentException("Empty replacement"); | ||
| 281 | if (len > maxCharsPerByte) | ||
| 282 | throw new IllegalArgumentException("Replacement too long"); | ||
| 283 | |||
| 284 | |||
| 285 | |||
| 286 | |||
| 287 | this.replacement = newReplacement; | ||
| 288 | implReplaceWith(newReplacement); | ||
| 289 | return this; | ||
| 290 | } | ||
| 291 | |||
| 292 | /** | ||
| 293 | * Reports a change to this decoder's replacement value. | ||
| 294 | * | ||
| 295 | * <p> The default implementation of this method does nothing. This method | ||
| 296 | * should be overridden by decoders that require notification of changes to | ||
| 297 | * the replacement. </p> | ||
| 298 | * | ||
| 299 | * @param newReplacement | ||
| 300 | */ | ||
| 301 | protected void implReplaceWith(String newReplacement) { | ||
| 302 | } | ||
| 303 | |||
| 304 | |||
| 305 | |||
| 306 | |||
| 307 | |||
| 308 | |||
| 309 | |||
| 310 | |||
| 311 | |||
| 312 | |||
| 313 | |||
| 314 | |||
| 315 | |||
| 316 | |||
| 317 | |||
| 318 | |||
| 319 | |||
| 320 | |||
| 321 | |||
| 322 | |||
| 323 | |||
| 324 | |||
| 325 | |||
| 326 | |||
| 327 | |||
| 328 | |||
| 329 | |||
| 330 | |||
| 331 | |||
| 332 | |||
| 333 | |||
| 334 | |||
| 335 | |||
| 336 | |||
| 337 | |||
| 338 | |||
| 339 | |||
| 340 | |||
| 341 | |||
| 342 | |||
| 343 | |||
| 344 | /** | ||
| 345 | * Returns this decoder'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 decoder'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 decoder | ||
| 362 | * | ||
| 363 | * @throws IllegalArgumentException | ||
| 364 | * If the precondition on the parameter does not hold | ||
| 365 | */ | ||
| 366 | public final CharsetDecoder 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 decoder's malformed-input action. | ||
| 376 | * | ||
| 377 | * <p> The default implementation of this method does nothing. This method | ||
| 378 | * should be overridden by decoders that require notification of changes to | ||
| 379 | * the malformed-input action. </p> | ||
| 380 | */ | ||
| 381 | protected void implOnMalformedInput(CodingErrorAction newAction) { } | ||
| 382 | |||
| 383 | /** | ||
| 384 | * Returns this decoder'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 decoder'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 decoder | ||
| 403 | * | ||
| 404 | * @throws IllegalArgumentException | ||
| 405 | * If the precondition on the parameter does not hold | ||
| 406 | */ | ||
| 407 | public final CharsetDecoder 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 decoder's unmappable-character action. | ||
| 419 | * | ||
| 420 | * <p> The default implementation of this method does nothing. This method | ||
| 421 | * should be overridden by decoders 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 characters that will be produced for each | ||
| 428 | * byte 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 characters produced | ||
| 432 | * per byte of input | ||
| 433 | */ | ||
| 434 | public final float averageCharsPerByte() { | ||
| 435 | return averageCharsPerByte; | ||
| 436 | } | ||
| 437 | |||
| 438 | /** | ||
| 439 | * Returns the maximum number of characters that will be produced for each | ||
| 440 | * byte 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 characters that will be produced per | ||
| 444 | * byte of input | ||
| 445 | */ | ||
| 446 | public final float maxCharsPerByte() { | ||
| 447 | return maxCharsPerByte; | ||
| 448 | } | ||
| 449 | |||
| 450 | /** | ||
| 451 | * Decodes as many bytes 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()} bytes | ||
| 456 | * will be read and at most {@link Buffer#remaining out.remaining()} | ||
| 457 | * characters will be written. The buffers' positions will be advanced to | ||
| 458 | * reflect the bytes read and the characters written, but their marks and | ||
| 459 | * limits will not be modified. | ||
| 460 | * | ||
| 461 | * <p> In addition to reading bytes from the input buffer and writing | ||
| 462 | * characters 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 decoded. If there is no further | ||
| 469 | * input then the invoker can proceed to the next step of the | ||
| 470 | * <a href="#steps">decoding 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 decode any more bytes. | ||
| 475 | * This method should be invoked again with an output buffer that has | ||
| 476 | * more {@linkplain Buffer#remaining remaining} characters. This is | ||
| 477 | * typically done by draining any decoded characters 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 bytes begin at the input | ||
| 483 | * buffer's (possibly incremented) position; the number of malformed | ||
| 484 | * bytes 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 decoder | ||
| 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 bytes that | ||
| 493 | * decode the unmappable character begin at the input buffer's (possibly | ||
| 494 | * incremented) position; the number of such bytes 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 decoder 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 decoding | ||
| 504 | * operation then care should be taken to preserve any bytes 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 undecoded input will be treated | ||
| 517 | * as being malformed. | ||
| 518 | * | ||
| 519 | * <p> This method works by invoking the {@link #decodeLoop decodeLoop} | ||
| 520 | * method, interpreting its results, handling error conditions, and | ||
| 521 | * reinvoking it as necessary. </p> | ||
| 522 | * | ||
| 523 | * | ||
| 524 | * @param in | ||
| 525 | * The input byte buffer | ||
| 526 | * | ||
| 527 | * @param out | ||
| 528 | * The output character buffer | ||
| 529 | * | ||
| 530 | * @param endOfInput | ||
| 531 | * <tt>true</tt> if, and only if, the invoker can provide no | ||
| 532 | * additional input bytes 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 decoding 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 decoding operation | ||
| 543 | * | ||
| 544 | * @throws CoderMalfunctionError | ||
| 545 | * If an invocation of the decodeLoop method threw | ||
| 546 | * an unexpected exception | ||
| 547 | */ | ||
| 548 | public final CoderResult decode(ByteBuffer in, CharBuffer 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 = decodeLoop(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.length()) | ||
| 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 decoder. | ||
| 611 | * | ||
| 612 | * <p> Some decoders maintain internal state and may need to write some | ||
| 613 | * final characters 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 | * characters 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">decoding | ||
| 626 | * operation</a>. | ||
| 627 | * | ||
| 628 | * <p> If this decoder 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 character 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 decoding operation was an | ||
| 642 | * invocation neither of the {@link #flush flush} method nor of | ||
| 643 | * the three-argument {@link | ||
| 644 | * #decode(ByteBuffer,CharBuffer,boolean) decode} method | ||
| 645 | * with a value of <tt>true</tt> for the <tt>endOfInput</tt> | ||
| 646 | * parameter | ||
| 647 | */ | ||
| 648 | public final CoderResult flush(CharBuffer 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 decoder. | ||
| 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 decoders that may need to write final characters to the output buffer | ||
| 668 | * once the entire input sequence has been read. </p> | ||
| 669 | * | ||
| 670 | * @param out | ||
| 671 | * The output character buffer | ||
| 672 | * | ||
| 673 | * @return A coder-result object, either {@link CoderResult#UNDERFLOW} or | ||
| 674 | * {@link CoderResult#OVERFLOW} | ||
| 675 | */ | ||
| 676 | protected CoderResult implFlush(CharBuffer out) { | ||
| 677 | return CoderResult.UNDERFLOW; | ||
| 678 | } | ||
| 679 | |||
| 680 | /** | ||
| 681 | * Resets this decoder, 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 decoder | ||
| 688 | * | ||
| 689 | */ | ||
| 690 | public final CharsetDecoder reset() { | ||
| 691 | implReset(); | ||
| 692 | state = ST_RESET; | ||
| 693 | return this; | ||
| 694 | } | ||
| 695 | |||
| 696 | /** | ||
| 697 | * Resets this decoder, clearing any charset-specific internal state. | ||
| 698 | * | ||
| 699 | * <p> The default implementation of this method does nothing. This method | ||
| 700 | * should be overridden by decoders that maintain internal state. </p> | ||
| 701 | */ | ||
| 702 | protected void implReset() { } | ||
| 703 | |||
| 704 | /** | ||
| 705 | * Decodes one or more bytes into one or more characters. | ||
| 706 | * | ||
| 707 | * <p> This method encapsulates the basic decoding loop, decoding as many | ||
| 708 | * bytes as possible until it either runs out of input, runs out of room | ||
| 709 | * in the output buffer, or encounters a decoding error. This method is | ||
| 710 | * invoked by the {@link #decode decode} 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()} bytes | ||
| 715 | * will be read, and at most {@link Buffer#remaining out.remaining()} | ||
| 716 | * characters will be written. The buffers' positions will be advanced to | ||
| 717 | * reflect the bytes read and the characters 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 #decode decode} | ||
| 722 | * method. Most implementations of this method will handle decoding errors | ||
| 723 | * by returning an appropriate result object for interpretation by the | ||
| 724 | * {@link #decode decode} 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 byte buffer | ||
| 733 | * | ||
| 734 | * @param out | ||
| 735 | * The output character buffer | ||
| 736 | * | ||
| 737 | * @return A coder-result object describing the reason for termination | ||
| 738 | */ | ||
| 739 | protected abstract CoderResult decodeLoop(ByteBuffer in, | ||
| 740 | CharBuffer out); | ||
| 741 | |||
| 742 | /** | ||
| 743 | * Convenience method that decodes the remaining content of a single input | ||
| 744 | * byte buffer into a newly-allocated character buffer. | ||
| 745 | * | ||
| 746 | * <p> This method implements an entire <a href="#steps">decoding | ||
| 747 | * operation</a>; that is, it resets this decoder, then it decodes the | ||
| 748 | * bytes in the given byte buffer, and finally it flushes this | ||
| 749 | * decoder. This method should therefore not be invoked if a decoding | ||
| 750 | * operation is already in progress. </p> | ||
| 751 | * | ||
| 752 | * @param in | ||
| 753 | * The input byte buffer | ||
| 754 | * | ||
| 755 | * @return A newly-allocated character buffer containing the result of the | ||
| 756 | * decoding operation. The buffer's position will be zero and its | ||
| 757 | * limit will follow the last character written. | ||
| 758 | * | ||
| 759 | * @throws IllegalStateException | ||
| 760 | * If a decoding operation is already in progress | ||
| 761 | * | ||
| 762 | * @throws MalformedInputException | ||
| 763 | * If the byte sequence starting at the input buffer's current | ||
| 764 | * position is not legal for this charset and the current malformed-input action | ||
| 765 | * is {@link CodingErrorAction#REPORT} | ||
| 766 | * | ||
| 767 | * @throws UnmappableCharacterException | ||
| 768 | * If the byte sequence starting at the input buffer's current | ||
| 769 | * position cannot be mapped to an equivalent character sequence and | ||
| 770 | * the current unmappable-character action is {@link | ||
| 771 | * CodingErrorAction#REPORT} | ||
| 772 | */ | ||
| 773 | public final CharBuffer decode(ByteBuffer in) | ||
| 774 | throws CharacterCodingException | ||
| 775 | { | ||
| 776 | int n = (int)(in.remaining() * averageCharsPerByte()); | ||
| 777 | CharBuffer out = CharBuffer.allocate(n); | ||
| 778 | |||
| 779 | if ((n == 0) && (in.remaining() == 0)) | ||
| 780 | return out; | ||
| 781 | reset(); | ||
| 782 | for (;;) { | ||
| 783 | CoderResult cr = in.hasRemaining() ? | ||
| 784 | decode(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 | CharBuffer o = CharBuffer.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 | |||
| 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 | |||
| 879 | |||
| 880 | |||
| 881 | |||
| 882 | |||
| 883 | |||
| 884 | |||
| 885 | |||
| 886 | |||
| 887 | |||
| 888 | |||
| 889 | |||
| 890 | |||
| 891 | |||
| 892 | |||
| 893 | |||
| 894 | |||
| 895 | |||
| 896 | |||
| 897 | |||
| 898 | |||
| 899 | |||
| 900 | |||
| 901 | |||
| 902 | |||
| 903 | |||
| 904 | |||
| 905 | |||
| 906 | |||
| 907 | |||
| 908 | |||
| 909 | |||
| 910 | |||
| 911 | |||
| 912 | |||
| 913 | |||
| 914 | |||
| 915 | |||
| 916 | |||
| 917 | |||
| 918 | |||
| 919 | |||
| 920 | |||
| 921 | |||
| 922 | |||
| 923 | |||
| 924 | |||
| 925 | |||
| 926 | |||
| 927 | |||
| 928 | |||
| 929 | |||
| 930 | |||
| 931 | |||
| 932 | |||
| 933 | |||
| 934 | |||
| 935 | |||
| 936 | |||
| 937 | |||
| 938 | |||
| 939 | |||
| 940 | |||
| 941 | |||
| 942 | |||
| 943 | |||
| 944 | |||
| 945 | |||
| 946 | |||
| 947 | |||
| 948 | |||
| 949 | |||
| 950 | |||
| 951 | |||
| 952 | |||
| 953 | |||
| 954 | |||
| 955 | |||
| 956 | |||
| 957 | |||
| 958 | |||
| 959 | |||
| 960 | |||
| 961 | |||
| 962 | |||
| 963 | |||
| 964 | |||
| 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 | } | ||
| @@ -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 | // -- This file was mechanically generated: Do not edit! -- // | ||
| 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 sixteen-bit Unicode characters into a sequence of | ||
| 41 | * bytes in a specific charset. | ||
| 42 | * | ||
| 43 | * <a name="steps"> | ||
| 44 | * | ||
| 45 | * <p> The input character sequence is provided in a character buffer or a series | ||
| 46 | * of such buffers. The output byte sequence is written to a byte buffer | ||
| 47 | * or a series of such buffers. An encoder should always be used by making | ||
| 48 | * the following sequence of method invocations, hereinafter referred to as an | ||
| 49 | * <i>encoding operation</i>: | ||
| 50 | * | ||
| 51 | * <ol> | ||
| 52 | * | ||
| 53 | * <li><p> Reset the encoder via the {@link #reset reset} method, unless it | ||
| 54 | * has not been used before; </p></li> | ||
| 55 | * | ||
| 56 | * <li><p> Invoke the {@link #encode encode} 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 #encode encode} 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 encoder can | ||
| 65 | * flush any internal state to the output buffer. </p></li> | ||
| 66 | * | ||
| 67 | * </ol> | ||
| 68 | * | ||
| 69 | * Each invocation of the {@link #encode encode} method will encode as many | ||
| 70 | * characters as possible from the input buffer, writing the resulting bytes | ||
| 71 | * to the output buffer. The {@link #encode encode} method returns when more | ||
| 72 | * input is required, when there is not enough room in the output buffer, or | ||
| 73 | * when an encoding 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 an encoding error, as appropriate, and try again. | ||
| 77 | * | ||
| 78 | * <a name="ce"> | ||
| 79 | * | ||
| 80 | * <p> There are two general types of encoding errors. If the input character | ||
| 81 | * sequence is not a legal sixteen-bit Unicode sequence then the input is considered <i>malformed</i>. If | ||
| 82 | * the input character sequence is legal but cannot be mapped to a valid | ||
| 83 | * byte sequence in the given charset then an <i>unmappable character</i> has been encountered. | ||
| 84 | * | ||
| 85 | * <a name="cae"> | ||
| 86 | * | ||
| 87 | * <p> How an encoding 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 byte array. The replacement | ||
| 95 | * | ||
| 96 | |||
| 97 | * is initially set to the encoder's default replacement, which often | ||
| 98 | * (but not always) has the initial value <tt>{</tt> <tt>(byte)'?'</tt> <tt>}</tt>; | ||
| 99 | |||
| 100 | |||
| 101 | |||
| 102 | |||
| 103 | * | ||
| 104 | * its value may be changed via the {@link #replaceWith(byte[]) | ||
| 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 encoding | ||
| 115 | * process, including the implementation of error actions. An encoder for a | ||
| 116 | * specific charset, which is a concrete subclass of this class, need only | ||
| 117 | * implement the abstract {@link #encodeLoop encodeLoop} method, which | ||
| 118 | * encapsulates the basic encoding 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 CharsetDecoder | ||
| 134 | */ | ||
| 135 | |||
| 136 | public abstract class CharsetEncoder { | ||
| 137 | |||
| 138 | private final Charset charset; | ||
| 139 | private final float averageBytesPerChar; | ||
| 140 | private final float maxBytesPerChar; | ||
| 141 | |||
| 142 | private byte[] 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 encoder. The new encoder will have the given | ||
| 163 | * bytes-per-char and replacement values. </p> | ||
| 164 | * | ||
| 165 | * @param averageBytesPerChar | ||
| 166 | * A positive float value indicating the expected number of | ||
| 167 | * bytes that will be produced for each input character | ||
| 168 | * | ||
| 169 | * @param maxBytesPerChar | ||
| 170 | * A positive float value indicating the maximum number of | ||
| 171 | * bytes that will be produced for each input character | ||
| 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 maxBytesPerChar, | ||
| 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 | protected | ||
| 182 | CharsetEncoder(Charset cs, | ||
| 183 | float averageBytesPerChar, | ||
| 184 | float maxBytesPerChar, | ||
| 185 | byte[] replacement) | ||
| 186 | { | ||
| 187 | this.charset = cs; | ||
| 188 | if (averageBytesPerChar <= 0.0f) | ||
| 189 | throw new IllegalArgumentException("Non-positive " | ||
| 190 | + "averageBytesPerChar"); | ||
| 191 | if (maxBytesPerChar <= 0.0f) | ||
| 192 | throw new IllegalArgumentException("Non-positive " | ||
| 193 | + "maxBytesPerChar"); | ||
| 194 | if (!Charset.atBugLevel("1.4")) { | ||
| 195 | if (averageBytesPerChar > maxBytesPerChar) | ||
| 196 | throw new IllegalArgumentException("averageBytesPerChar" | ||
| 197 | + " exceeds " | ||
| 198 | + "maxBytesPerChar"); | ||
| 199 | } | ||
| 200 | this.replacement = replacement; | ||
| 201 | this.averageBytesPerChar = averageBytesPerChar; | ||
| 202 | this.maxBytesPerChar = maxBytesPerChar; | ||
| 203 | replaceWith(replacement); | ||
| 204 | } | ||
| 205 | |||
| 206 | /** | ||
| 207 | * Initializes a new encoder. The new encoder will have the given | ||
| 208 | * bytes-per-char values and its replacement will be the | ||
| 209 | * byte array <tt>{</tt> <tt>(byte)'?'</tt> <tt>}</tt>. </p> | ||
| 210 | * | ||
| 211 | * @param averageBytesPerChar | ||
| 212 | * A positive float value indicating the expected number of | ||
| 213 | * bytes that will be produced for each input character | ||
| 214 | * | ||
| 215 | * @param maxBytesPerChar | ||
| 216 | * A positive float value indicating the maximum number of | ||
| 217 | * bytes that will be produced for each input character | ||
| 218 | * | ||
| 219 | * @throws IllegalArgumentException | ||
| 220 | * If the preconditions on the parameters do not hold | ||
| 221 | */ | ||
| 222 | protected CharsetEncoder(Charset cs, | ||
| 223 | float averageBytesPerChar, | ||
| 224 | float maxBytesPerChar) | ||
| 225 | { | ||
| 226 | this(cs, | ||
| 227 | averageBytesPerChar, maxBytesPerChar, | ||
| 228 | new byte[] { (byte)'?' }); | ||
| 229 | } | ||
| 230 | |||
| 231 | /** | ||
| 232 | * Returns the charset that created this encoder. </p> | ||
| 233 | * | ||
| 234 | * @return This encoder's charset | ||
| 235 | */ | ||
| 236 | public final Charset charset() { | ||
| 237 | return charset; | ||
| 238 | } | ||
| 239 | |||
| 240 | /** | ||
| 241 | * Returns this encoder's replacement value. </p> | ||
| 242 | * | ||
| 243 | * @return This encoder's current replacement, | ||
| 244 | * which is never <tt>null</tt> and is never empty | ||
| 245 | */ | ||
| 246 | public final byte[] replacement() { | ||
| 247 | return replacement; | ||
| 248 | } | ||
| 249 | |||
| 250 | /** | ||
| 251 | * Changes this encoder'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 | |||
| 260 | |||
| 261 | |||
| 262 | |||
| 263 | |||
| 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 #maxBytesPerChar() maxBytesPerChar} method, and | ||
| 267 | * must be {@link #isLegalReplacement </code>legal<code>} | ||
| 268 | |||
| 269 | * | ||
| 270 | * @return This encoder | ||
| 271 | * | ||
| 272 | * @throws IllegalArgumentException | ||
| 273 | * If the preconditions on the parameter do not hold | ||
| 274 | */ | ||
| 275 | public final CharsetEncoder replaceWith(byte[] newReplacement) { | ||
| 276 | if (newReplacement == null) | ||
| 277 | throw new IllegalArgumentException("Null replacement"); | ||
| 278 | int len = newReplacement.length; | ||
| 279 | if (len == 0) | ||
| 280 | throw new IllegalArgumentException("Empty replacement"); | ||
| 281 | if (len > maxBytesPerChar) | ||
| 282 | throw new IllegalArgumentException("Replacement too long"); | ||
| 283 | |||
| 284 | if (!isLegalReplacement(newReplacement)) | ||
| 285 | throw new IllegalArgumentException("Illegal replacement"); | ||
| 286 | |||
| 287 | this.replacement = newReplacement; | ||
| 288 | implReplaceWith(newReplacement); | ||
| 289 | return this; | ||
| 290 | } | ||
| 291 | |||
| 292 | /** | ||
| 293 | * Reports a change to this encoder's replacement value. | ||
| 294 | * | ||
| 295 | * <p> The default implementation of this method does nothing. This method | ||
| 296 | * should be overridden by encoders that require notification of changes to | ||
| 297 | * the replacement. </p> | ||
| 298 | * | ||
| 299 | * @param newReplacement | ||
| 300 | */ | ||
| 301 | protected void implReplaceWith(byte[] newReplacement) { | ||
| 302 | } | ||
| 303 | |||
| 304 | |||
| 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 | |||
| 343 | |||
| 344 | /** | ||
| 345 | * Returns this encoder'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 encoder'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 encoder | ||
| 362 | * | ||
| 363 | * @throws IllegalArgumentException | ||
| 364 | * If the precondition on the parameter does not hold | ||
| 365 | */ | ||
| 366 | public final CharsetEncoder 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 encoder's malformed-input action. | ||
| 376 | * | ||
| 377 | * <p> The default implementation of this method does nothing. This method | ||
| 378 | * should be overridden by encoders that require notification of changes to | ||
| 379 | * the malformed-input action. </p> | ||
| 380 | */ | ||
| 381 | protected void implOnMalformedInput(CodingErrorAction newAction) { } | ||
| 382 | |||
| 383 | /** | ||
| 384 | * Returns this encoder'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 encoder'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 encoder | ||
| 403 | * | ||
| 404 | * @throws IllegalArgumentException | ||
| 405 | * If the precondition on the parameter does not hold | ||
| 406 | */ | ||
| 407 | public final CharsetEncoder 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 encoder's unmappable-character action. | ||
| 419 | * | ||
| 420 | * <p> The default implementation of this method does nothing. This method | ||
| 421 | * should be overridden by encoders 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 bytes that will be produced for each | ||
| 428 | * character 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 bytes produced | ||
| 432 | * per character of input | ||
| 433 | */ | ||
| 434 | public final float averageBytesPerChar() { | ||
| 435 | return averageBytesPerChar; | ||
| 436 | } | ||
| 437 | |||
| 438 | /** | ||
| 439 | * Returns the maximum number of bytes that will be produced for each | ||
| 440 | * character 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 bytes that will be produced per | ||
| 444 | * character of input | ||
| 445 | */ | ||
| 446 | public final float maxBytesPerChar() { | ||
| 447 | return maxBytesPerChar; | ||
| 448 | } | ||
| 449 | |||
| 450 | /** | ||
| 451 | * Encodes as many characters 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()} characters | ||
| 456 | * will be read and at most {@link Buffer#remaining out.remaining()} | ||
| 457 | * bytes will be written. The buffers' positions will be advanced to | ||
| 458 | * reflect the characters read and the bytes written, but their marks and | ||
| 459 | * limits will not be modified. | ||
| 460 | * | ||
| 461 | * <p> In addition to reading characters from the input buffer and writing | ||
| 462 | * bytes 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 encoded. If there is no further | ||
| 469 | * input then the invoker can proceed to the next step of the | ||
| 470 | * <a href="#steps">encoding 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 encode any more characters. | ||
| 475 | * This method should be invoked again with an output buffer that has | ||
| 476 | * more {@linkplain Buffer#remaining remaining} bytes. This is | ||
| 477 | * typically done by draining any encoded bytes 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 characters begin at the input | ||
| 483 | * buffer's (possibly incremented) position; the number of malformed | ||
| 484 | * characters 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 encoder | ||
| 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 characters that | ||
| 493 | * encode the unmappable character begin at the input buffer's (possibly | ||
| 494 | * incremented) position; the number of such characters 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 encoder 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 encoding | ||
| 504 | * operation then care should be taken to preserve any characters 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 unencoded input will be treated | ||
| 517 | * as being malformed. | ||
| 518 | * | ||
| 519 | * <p> This method works by invoking the {@link #encodeLoop encodeLoop} | ||
| 520 | * method, interpreting its results, handling error conditions, and | ||
| 521 | * reinvoking it as necessary. </p> | ||
| 522 | * | ||
| 523 | * | ||
| 524 | * @param in | ||
| 525 | * The input character buffer | ||
| 526 | * | ||
| 527 | * @param out | ||
| 528 | * The output byte buffer | ||
| 529 | * | ||
| 530 | * @param endOfInput | ||
| 531 | * <tt>true</tt> if, and only if, the invoker can provide no | ||
| 532 | * additional input characters beyond those in the given buffer | ||
| 533 | * | ||
| 534 | * @return A coder-result object describing the reason for termination | ||
| 535 | * | ||
| 536 | * @throws IllegalStateException | ||
| 537 | * If an encoding 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 encoding operation | ||
| 543 | * | ||
| 544 | * @throws CoderMalfunctionError | ||
| 545 | * If an invocation of the encodeLoop method threw | ||
| 546 | * an unexpected exception | ||
| 547 | */ | ||
| 548 | public final CoderResult encode(CharBuffer in, ByteBuffer 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 = encodeLoop(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.length) | ||
| 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 encoder. | ||
| 611 | * | ||
| 612 | * <p> Some encoders maintain internal state and may need to write some | ||
| 613 | * final bytes 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 | * bytes 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">encoding | ||
| 626 | * operation</a>. | ||
| 627 | * | ||
| 628 | * <p> If this encoder 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 byte 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 encoding operation was an | ||
| 642 | * invocation neither of the {@link #flush flush} method nor of | ||
| 643 | * the three-argument {@link | ||
| 644 | * #encode(CharBuffer,ByteBuffer,boolean) encode} method | ||
| 645 | * with a value of <tt>true</tt> for the <tt>endOfInput</tt> | ||
| 646 | * parameter | ||
| 647 | */ | ||
| 648 | public final CoderResult flush(ByteBuffer 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 encoder. | ||
| 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 encoders that may need to write final bytes to the output buffer | ||
| 668 | * once the entire input sequence has been read. </p> | ||
| 669 | * | ||
| 670 | * @param out | ||
| 671 | * The output byte buffer | ||
| 672 | * | ||
| 673 | * @return A coder-result object, either {@link CoderResult#UNDERFLOW} or | ||
| 674 | * {@link CoderResult#OVERFLOW} | ||
| 675 | */ | ||
| 676 | protected CoderResult implFlush(ByteBuffer out) { | ||
| 677 | return CoderResult.UNDERFLOW; | ||
| 678 | } | ||
| 679 | |||
| 680 | /** | ||
| 681 | * Resets this encoder, 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 encoder | ||
| 688 | * | ||
| 689 | */ | ||
| 690 | public final CharsetEncoder reset() { | ||
| 691 | implReset(); | ||
| 692 | state = ST_RESET; | ||
| 693 | return this; | ||
| 694 | } | ||
| 695 | |||
| 696 | /** | ||
| 697 | * Resets this encoder, clearing any charset-specific internal state. | ||
| 698 | * | ||
| 699 | * <p> The default implementation of this method does nothing. This method | ||
| 700 | * should be overridden by encoders that maintain internal state. </p> | ||
| 701 | */ | ||
| 702 | protected void implReset() { } | ||
| 703 | |||
| 704 | /** | ||
| 705 | * Encodes one or more characters into one or more bytes. | ||
| 706 | * | ||
| 707 | * <p> This method encapsulates the basic encoding loop, encoding as many | ||
| 708 | * characters as possible until it either runs out of input, runs out of room | ||
| 709 | * in the output buffer, or encounters an encoding error. This method is | ||
| 710 | * invoked by the {@link #encode encode} 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()} characters | ||
| 715 | * will be read, and at most {@link Buffer#remaining out.remaining()} | ||
| 716 | * bytes will be written. The buffers' positions will be advanced to | ||
| 717 | * reflect the characters read and the bytes 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 #encode encode} | ||
| 722 | * method. Most implementations of this method will handle encoding errors | ||
| 723 | * by returning an appropriate result object for interpretation by the | ||
| 724 | * {@link #encode encode} 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 character buffer | ||
| 733 | * | ||
| 734 | * @param out | ||
| 735 | * The output byte buffer | ||
| 736 | * | ||
| 737 | * @return A coder-result object describing the reason for termination | ||
| 738 | */ | ||
| 739 | protected abstract CoderResult encodeLoop(CharBuffer in, | ||
| 740 | ByteBuffer out); | ||
| 741 | |||
| 742 | /** | ||
| 743 | * Convenience method that encodes the remaining content of a single input | ||
| 744 | * character buffer into a newly-allocated byte buffer. | ||
| 745 | * | ||
| 746 | * <p> This method implements an entire <a href="#steps">encoding | ||
| 747 | * operation</a>; that is, it resets this encoder, then it encodes the | ||
| 748 | * characters in the given character buffer, and finally it flushes this | ||
| 749 | * encoder. This method should therefore not be invoked if an encoding | ||
| 750 | * operation is already in progress. </p> | ||
| 751 | * | ||
| 752 | * @param in | ||
| 753 | * The input character buffer | ||
| 754 | * | ||
| 755 | * @return A newly-allocated byte buffer containing the result of the | ||
| 756 | * encoding operation. The buffer's position will be zero and its | ||
| 757 | * limit will follow the last byte written. | ||
| 758 | * | ||
| 759 | * @throws IllegalStateException | ||
| 760 | * If an encoding operation is already in progress | ||
| 761 | * | ||
| 762 | * @throws MalformedInputException | ||
| 763 | * If the character sequence starting at the input buffer's current | ||
| 764 | * position is not a legal sixteen-bit Unicode sequence and the current malformed-input action | ||
| 765 | * is {@link CodingErrorAction#REPORT} | ||
| 766 | * | ||
| 767 | * @throws UnmappableCharacterException | ||
| 768 | * If the character sequence starting at the input buffer's current | ||
| 769 | * position cannot be mapped to an equivalent byte sequence and | ||
| 770 | * the current unmappable-character action is {@link | ||
| 771 | * CodingErrorAction#REPORT} | ||
| 772 | */ | ||
| 773 | public final ByteBuffer encode(CharBuffer in) | ||
| 774 | throws CharacterCodingException | ||
| 775 | { | ||
| 776 | int n = (int)(in.remaining() * averageBytesPerChar()); | ||
| 777 | ByteBuffer out = ByteBuffer.allocate(n); | ||
| 778 | |||
| 779 | if ((n == 0) && (in.remaining() == 0)) | ||
| 780 | return out; | ||
| 781 | reset(); | ||
| 782 | for (;;) { | ||
| 783 | CoderResult cr = in.hasRemaining() ? | ||
| 784 | encode(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 | ByteBuffer o = ByteBuffer.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 | |||
| 805 | |||
| 806 | |||
| 807 | |||
| 808 | |||
| 809 | |||
| 810 | |||
| 811 | |||
| 812 | |||
| 813 | |||
| 814 | |||
| 815 | |||
| 816 | |||
| 817 | |||
| 818 | |||
| 819 | |||
| 820 | |||
| 821 | |||
| 822 | |||
| 823 | |||
| 824 | |||
| 825 | |||
| 826 | |||
| 827 | |||
| 828 | |||
| 829 | |||
| 830 | |||
| 831 | |||
| 832 | |||
| 833 | |||
| 834 | |||
| 835 | |||
| 836 | |||
| 837 | |||
| 838 | |||
| 839 | |||
| 840 | |||
| 841 | |||
| 842 | |||
| 843 | |||
| 844 | |||
| 845 | |||
| 846 | |||
| 847 | |||
| 848 | |||
| 849 | |||
| 850 | |||
| 851 | |||
| 852 | |||
| 853 | |||
| 854 | |||
| 855 | |||
| 856 | |||
| 857 | |||
| 858 | |||
| 859 | |||
| 860 | |||
| 861 | |||
| 862 | |||
| 863 | |||
| 864 | |||
| 865 | |||
| 866 | |||
| 867 | |||
| 868 | |||
| 869 | |||
| 870 | |||
| 871 | |||
| 872 | |||
| 873 | |||
| 874 | |||
| 875 | |||
| 876 | |||
| 877 | |||
| 878 | |||
| 879 | |||
| 880 | |||
| 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 an encoding 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 an encoding 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 | |||
| 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 | } | ||
| @@ -0,0 +1,68 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * | ||
| 4 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 5 | * | ||
| 6 | * This code is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms of the GNU General Public License version 2 only, as | ||
| 8 | * published by the Free Software Foundation. Oracle designates this | ||
| 9 | * particular file as subject to the "Classpath" exception as provided | ||
| 10 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 11 | * | ||
| 12 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 15 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 16 | * accompanied this code). | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License version | ||
| 19 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 20 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 21 | * | ||
| 22 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 23 | * or visit www.oracle.com if you need additional information or have any | ||
| 24 | * questions. | ||
| 25 | * | ||
| 26 | */ | ||
| 27 | |||
| 28 | // -- This file was mechanically generated: Do not edit! -- // | ||
| 29 | |||
| 30 | package java.nio.charset; | ||
| 31 | |||
| 32 | |||
| 33 | /** | ||
| 34 | * Unchecked exception thrown when a string that is not a | ||
| 35 | * <a href=Charset.html#names>legal charset name</a> is used as such. | ||
| 36 | * | ||
| 37 | * @since 1.4 | ||
| 38 | */ | ||
| 39 | |||
| 40 | public class IllegalCharsetNameException | ||
| 41 | extends IllegalArgumentException | ||
| 42 | { | ||
| 43 | |||
| 44 | private static final long serialVersionUID = 1457525358470002989L; | ||
| 45 | |||
| 46 | private String charsetName; | ||
| 47 | |||
| 48 | /** | ||
| 49 | * Constructs an instance of this class. </p> | ||
| 50 | * | ||
| 51 | * @param charsetName | ||
| 52 | * The illegal charset name | ||
| 53 | */ | ||
| 54 | public IllegalCharsetNameException(String charsetName) { | ||
| 55 | super(String.valueOf(charsetName)); | ||
| 56 | this.charsetName = charsetName; | ||
| 57 | } | ||
| 58 | |||
| 59 | /** | ||
| 60 | * Retrieves the illegal charset name. </p> | ||
| 61 | * | ||
| 62 | * @return The illegal charset name | ||
| 63 | */ | ||
| 64 | public String getCharsetName() { | ||
| 65 | return charsetName; | ||
| 66 | } | ||
| 67 | |||
| 68 | } | ||
| @@ -0,0 +1,68 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * | ||
| 4 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 5 | * | ||
| 6 | * This code is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms of the GNU General Public License version 2 only, as | ||
| 8 | * published by the Free Software Foundation. Oracle designates this | ||
| 9 | * particular file as subject to the "Classpath" exception as provided | ||
| 10 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 11 | * | ||
| 12 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 15 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 16 | * accompanied this code). | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License version | ||
| 19 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 20 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 21 | * | ||
| 22 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 23 | * or visit www.oracle.com if you need additional information or have any | ||
| 24 | * questions. | ||
| 25 | * | ||
| 26 | */ | ||
| 27 | |||
| 28 | // -- This file was mechanically generated: Do not edit! -- // | ||
| 29 | |||
| 30 | package java.nio.charset; | ||
| 31 | |||
| 32 | |||
| 33 | /** | ||
| 34 | * Unchecked exception thrown when no support is available | ||
| 35 | * for a requested charset. | ||
| 36 | * | ||
| 37 | * @since 1.4 | ||
| 38 | */ | ||
| 39 | |||
| 40 | public class UnsupportedCharsetException | ||
| 41 | extends IllegalArgumentException | ||
| 42 | { | ||
| 43 | |||
| 44 | private static final long serialVersionUID = 1490765524727386367L; | ||
| 45 | |||
| 46 | private String charsetName; | ||
| 47 | |||
| 48 | /** | ||
| 49 | * Constructs an instance of this class. </p> | ||
| 50 | * | ||
| 51 | * @param charsetName | ||
| 52 | * The name of the unsupported charset | ||
| 53 | */ | ||
| 54 | public UnsupportedCharsetException(String charsetName) { | ||
| 55 | super(String.valueOf(charsetName)); | ||
| 56 | this.charsetName = charsetName; | ||
| 57 | } | ||
| 58 | |||
| 59 | /** | ||
| 60 | * Retrieves the name of the unsupported charset. </p> | ||
| 61 | * | ||
| 62 | * @return The name of the unsupported charset | ||
| 63 | */ | ||
| 64 | public String getCharsetName() { | ||
| 65 | return charsetName; | ||
| 66 | } | ||
| 67 | |||
| 68 | } | ||