1. /*
  2. * @(#)Charset-X-Coder.java 1.40 04/06/19
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. // -- This file was mechanically generated: Do not edit! -- //
  8. package java.nio.charset;
  9. import java.nio.Buffer;
  10. import java.nio.ByteBuffer;
  11. import java.nio.CharBuffer;
  12. import java.nio.BufferOverflowException;
  13. import java.nio.BufferUnderflowException;
  14. import java.lang.ref.WeakReference;
  15. import java.nio.charset.CoderMalfunctionError; // javadoc
  16. /**
  17. * An engine that can transform a sequence of bytes in a specific charset into a sequence of
  18. * sixteen-bit Unicode characters.
  19. *
  20. * <a name="steps">
  21. *
  22. * <p> The input byte sequence is provided in a byte buffer or a series
  23. * of such buffers. The output character sequence is written to a character buffer
  24. * or a series of such buffers. A decoder should always be used by making
  25. * the following sequence of method invocations, hereinafter referred to as a
  26. * <i>decoding operation</i>:
  27. *
  28. * <ol>
  29. *
  30. * <li><p> Reset the decoder via the {@link #reset reset} method, unless it
  31. * has not been used before; </p></li>
  32. *
  33. * <li><p> Invoke the {@link #decode decode} method zero or more times, as
  34. * long as additional input may be available, passing <tt>false</tt> for the
  35. * <tt>endOfInput</tt> argument and filling the input buffer and flushing the
  36. * output buffer between invocations; </p></li>
  37. *
  38. * <li><p> Invoke the {@link #decode decode} method one final time, passing
  39. * <tt>true</tt> for the <tt>endOfInput</tt> argument; and then </p></li>
  40. *
  41. * <li><p> Invoke the {@link #flush flush} method so that the decoder can
  42. * flush any internal state to the output buffer. </p></li>
  43. *
  44. * </ol>
  45. *
  46. * Each invocation of the {@link #decode decode} method will decode as many
  47. * bytes as possible from the input buffer, writing the resulting characters
  48. * to the output buffer. The {@link #decode decode} method returns when more
  49. * input is required, when there is not enough room in the output buffer, or
  50. * when a decoding error has occurred. In each case a {@link CoderResult}
  51. * object is returned to describe the reason for termination. An invoker can
  52. * examine this object and fill the input buffer, flush the output buffer, or
  53. * attempt to recover from a decoding error, as appropriate, and try again.
  54. *
  55. * <a name="ce">
  56. *
  57. * <p> There are two general types of decoding errors. If the input byte
  58. * sequence is not legal for this charset then the input is considered <i>malformed</i>. If
  59. * the input byte sequence is legal but cannot be mapped to a valid
  60. * Unicode character then an <i>unmappable character</i> has been encountered.
  61. *
  62. * <a name="cae">
  63. *
  64. * <p> How a decoding error is handled depends upon the action requested for
  65. * that type of error, which is described by an instance of the {@link
  66. * CodingErrorAction} class. The possible error actions are to {@link
  67. * CodingErrorAction#IGNORE </code>ignore<code>} the erroneous input, {@link
  68. * CodingErrorAction#REPORT </code>report<code>} the error to the invoker via
  69. * the returned {@link CoderResult} object, or {@link CodingErrorAction#REPLACE
  70. * </code>replace<code>} the erroneous input with the current value of the
  71. * replacement string. The replacement
  72. *
  73. * has the initial value <tt>"\uFFFD"</tt>
  74. *
  75. * its value may be changed via the {@link #replaceWith(java.lang.String)
  76. * replaceWith} method.
  77. *
  78. * <p> The default action for malformed-input and unmappable-character errors
  79. * is to {@link CodingErrorAction#REPORT </code>report<code>} them. The
  80. * malformed-input error action may be changed via the {@link
  81. * #onMalformedInput(CodingErrorAction) onMalformedInput} method; the
  82. * unmappable-character action may be changed via the {@link
  83. * #onUnmappableCharacter(CodingErrorAction) onUnmappableCharacter} method.
  84. *
  85. * <p> This class is designed to handle many of the details of the decoding
  86. * process, including the implementation of error actions. A decoder for a
  87. * specific charset, which is a concrete subclass of this class, need only
  88. * implement the abstract {@link #decodeLoop decodeLoop} method, which
  89. * encapsulates the basic decoding loop. A subclass that maintains internal
  90. * state should, additionally, override the {@link #flush flush} and {@link
  91. * #reset reset} methods.
  92. *
  93. * <p> Instances of this class are not safe for use by multiple concurrent
  94. * threads. </p>
  95. *
  96. *
  97. * @version 1.40, 04/06/19
  98. * @author Mark Reinhold
  99. * @author JSR-51 Expert Group
  100. * @since 1.4
  101. *
  102. * @see ByteBuffer
  103. * @see CharBuffer
  104. * @see Charset
  105. * @see CharsetEncoder
  106. */
  107. public abstract class CharsetDecoder {
  108. private final Charset charset;
  109. private final float averageCharsPerByte;
  110. private final float maxCharsPerByte;
  111. private String replacement;
  112. private CodingErrorAction malformedInputAction
  113. = CodingErrorAction.REPORT;
  114. private CodingErrorAction unmappableCharacterAction
  115. = CodingErrorAction.REPORT;
  116. // Internal states
  117. //
  118. private static final int ST_RESET = 0;
  119. private static final int ST_CODING = 1;
  120. private static final int ST_END = 2;
  121. private static final int ST_FLUSHED = 3;
  122. private int state = ST_RESET;
  123. private static String stateNames[]
  124. = { "RESET", "CODING", "CODING_END", "FLUSHED" };
  125. /**
  126. * Initializes a new decoder. The new decoder will have the given
  127. * chars-per-byte and replacement values. </p>
  128. *
  129. * @param averageCharsPerByte
  130. * A positive float value indicating the expected number of
  131. * characters that will be produced for each input byte
  132. *
  133. * @param maxCharsPerByte
  134. * A positive float value indicating the maximum number of
  135. * characters that will be produced for each input byte
  136. *
  137. * @param replacement
  138. * The initial replacement; must not be <tt>null</tt>, must have
  139. * non-zero length, must not be longer than maxCharsPerByte,
  140. * and must be {@link #isLegalReplacement </code>legal<code>}
  141. *
  142. * @throws IllegalArgumentException
  143. * If the preconditions on the parameters do not hold
  144. */
  145. private
  146. CharsetDecoder(Charset cs,
  147. float averageCharsPerByte,
  148. float maxCharsPerByte,
  149. String replacement)
  150. {
  151. this.charset = cs;
  152. if (averageCharsPerByte <= 0.0f)
  153. throw new IllegalArgumentException("Non-positive "
  154. + "averageCharsPerByte");
  155. if (maxCharsPerByte <= 0.0f)
  156. throw new IllegalArgumentException("Non-positive "
  157. + "maxCharsPerByte");
  158. if (!Charset.atBugLevel("1.4")) {
  159. if (averageCharsPerByte > maxCharsPerByte)
  160. throw new IllegalArgumentException("averageCharsPerByte"
  161. + " exceeds "
  162. + "maxCharsPerByte");
  163. }
  164. this.replacement = replacement;
  165. this.averageCharsPerByte = averageCharsPerByte;
  166. this.maxCharsPerByte = maxCharsPerByte;
  167. replaceWith(replacement);
  168. }
  169. /**
  170. * Initializes a new decoder. The new decoder will have the given
  171. * chars-per-byte values and its replacement will be the
  172. * string <tt>"\uFFFD"</tt>. </p>
  173. *
  174. * @param averageCharsPerByte
  175. * A positive float value indicating the expected number of
  176. * characters that will be produced for each input byte
  177. *
  178. * @param maxCharsPerByte
  179. * A positive float value indicating the maximum number of
  180. * characters that will be produced for each input byte
  181. *
  182. * @throws IllegalArgumentException
  183. * If the preconditions on the parameters do not hold
  184. */
  185. protected CharsetDecoder(Charset cs,
  186. float averageCharsPerByte,
  187. float maxCharsPerByte)
  188. {
  189. this(cs,
  190. averageCharsPerByte, maxCharsPerByte,
  191. "\uFFFD");
  192. }
  193. /**
  194. * Returns the charset that created this decoder. </p>
  195. *
  196. * @return This decoder's charset
  197. */
  198. public final Charset charset() {
  199. return charset;
  200. }
  201. /**
  202. * Returns this decoder's replacement value. </p>
  203. *
  204. * @return This decoder's current replacement,
  205. * which is never <tt>null</tt> and is never empty
  206. */
  207. public final String replacement() {
  208. return replacement;
  209. }
  210. /**
  211. * Changes this decoder's replacement value.
  212. *
  213. * <p> This method invokes the {@link #implReplaceWith implReplaceWith}
  214. * method, passing the new replacement, after checking that the new
  215. * replacement is acceptable. </p>
  216. *
  217. * @param newReplacement
  218. *
  219. * The new replacement; must not be <tt>null</tt>
  220. * and must have non-zero length
  221. *
  222. * @return This decoder
  223. *
  224. * @throws IllegalArgumentException
  225. * If the preconditions on the parameter do not hold
  226. */
  227. public final CharsetDecoder replaceWith(String newReplacement) {
  228. if (newReplacement == null)
  229. throw new IllegalArgumentException("Null replacement");
  230. int len = newReplacement.length();
  231. if (len == 0)
  232. throw new IllegalArgumentException("Empty replacement");
  233. if (len > maxCharsPerByte)
  234. throw new IllegalArgumentException("Replacement too long");
  235. this.replacement = newReplacement;
  236. implReplaceWith(newReplacement);
  237. return this;
  238. }
  239. /**
  240. * Reports a change to this decoder's replacement value.
  241. *
  242. * <p> The default implementation of this method does nothing. This method
  243. * should be overridden by decoders that require notification of changes to
  244. * the replacement. </p>
  245. *
  246. * @param newReplacement
  247. */
  248. protected void implReplaceWith(String newReplacement) {
  249. }
  250. /**
  251. * Returns this decoder's current action for malformed-input errors. </p>
  252. *
  253. * @return The current malformed-input action, which is never <tt>null</tt>
  254. */
  255. public CodingErrorAction malformedInputAction() {
  256. return malformedInputAction;
  257. }
  258. /**
  259. * Changes this decoder's action for malformed-input errors. </p>
  260. *
  261. * <p> This method invokes the {@link #implOnMalformedInput
  262. * implOnMalformedInput} method, passing the new action. </p>
  263. *
  264. * @param newAction The new action; must not be <tt>null</tt>
  265. *
  266. * @return This decoder
  267. *
  268. * @throws IllegalArgumentException
  269. * If the precondition on the parameter does not hold
  270. */
  271. public final CharsetDecoder onMalformedInput(CodingErrorAction newAction) {
  272. if (newAction == null)
  273. throw new IllegalArgumentException("Null action");
  274. malformedInputAction = newAction;
  275. implOnMalformedInput(newAction);
  276. return this;
  277. }
  278. /**
  279. * Reports a change to this decoder's malformed-input action.
  280. *
  281. * <p> The default implementation of this method does nothing. This method
  282. * should be overridden by decoders that require notification of changes to
  283. * the malformed-input action. </p>
  284. */
  285. protected void implOnMalformedInput(CodingErrorAction newAction) { }
  286. /**
  287. * Returns this decoder's current action for unmappable-character errors.
  288. * </p>
  289. *
  290. * @return The current unmappable-character action, which is never
  291. * <tt>null</tt>
  292. */
  293. public CodingErrorAction unmappableCharacterAction() {
  294. return unmappableCharacterAction;
  295. }
  296. /**
  297. * Changes this decoder's action for unmappable-character errors.
  298. *
  299. * <p> This method invokes the {@link #implOnUnmappableCharacter
  300. * implOnUnmappableCharacter} method, passing the new action. </p>
  301. *
  302. * @param newAction The new action; must not be <tt>null</tt>
  303. *
  304. * @return This decoder
  305. *
  306. * @throws IllegalArgumentException
  307. * If the precondition on the parameter does not hold
  308. */
  309. public final CharsetDecoder onUnmappableCharacter(CodingErrorAction
  310. newAction)
  311. {
  312. if (newAction == null)
  313. throw new IllegalArgumentException("Null action");
  314. unmappableCharacterAction = newAction;
  315. implOnUnmappableCharacter(newAction);
  316. return this;
  317. }
  318. /**
  319. * Reports a change to this decoder's unmappable-character action.
  320. *
  321. * <p> The default implementation of this method does nothing. This method
  322. * should be overridden by decoders that require notification of changes to
  323. * the unmappable-character action. </p>
  324. */
  325. protected void implOnUnmappableCharacter(CodingErrorAction newAction) { }
  326. /**
  327. * Returns the average number of characters that will be produced for each
  328. * byte of input. This heuristic value may be used to estimate the size
  329. * of the output buffer required for a given input sequence. </p>
  330. *
  331. * @return The average number of characters produced
  332. * per byte of input
  333. */
  334. public final float averageCharsPerByte() {
  335. return averageCharsPerByte;
  336. }
  337. /**
  338. * Returns the maximum number of characters that will be produced for each
  339. * byte of input. This value may be used to compute the worst-case size
  340. * of the output buffer required for a given input sequence. </p>
  341. *
  342. * @return The maximum number of characters that will be produced per
  343. * byte of input
  344. */
  345. public final float maxCharsPerByte() {
  346. return maxCharsPerByte;
  347. }
  348. /**
  349. * Decodes as many bytes as possible from the given input buffer,
  350. * writing the results to the given output buffer.
  351. *
  352. * <p> The buffers are read from, and written to, starting at their current
  353. * positions. At most {@link Buffer#remaining in.remaining()} bytes
  354. * will be read and at most {@link Buffer#remaining out.remaining()}
  355. * characters will be written. The buffers' positions will be advanced to
  356. * reflect the bytes read and the characters written, but their marks and
  357. * limits will not be modified.
  358. *
  359. * <p> In addition to reading bytes from the input buffer and writing
  360. * characters to the output buffer, this method returns a {@link CoderResult}
  361. * object to describe its reason for termination:
  362. *
  363. * <ul>
  364. *
  365. * <li><p> {@link CoderResult#UNDERFLOW} indicates that as much of the
  366. * input buffer as possible has been decoded. If there are no bytes
  367. * remaining and the invoker has no further input then the decoding
  368. * operation is complete. Otherwise there is insufficient input for the
  369. * operation to proceed, so this method should be invoked again with
  370. * further input. </p></li>
  371. *
  372. * <li><p> {@link CoderResult#OVERFLOW} indicates that the output buffer
  373. * is full. This method should be invoked again with a non-full output
  374. * buffer. </p></li>
  375. *
  376. * <li><p> A {@link CoderResult#malformedForLength
  377. * </code>malformed-input<code>} result indicates that a malformed-input
  378. * error has been detected. The malformed bytes begin at the input
  379. * buffer's (possibly incremented) position; the number of malformed
  380. * bytes may be determined by invoking the result object's {@link
  381. * CoderResult#length length} method. This case applies only if the
  382. * {@link #onMalformedInput </code>malformed action<code>} of this decoder
  383. * is {@link CodingErrorAction#REPORT}; otherwise the malformed input
  384. * will be ignored or replaced, as requested. </p></li>
  385. *
  386. * <li><p> An {@link CoderResult#unmappableForLength
  387. * </code>unmappable-character<code>} result indicates that an
  388. * unmappable-character error has been detected. The bytes that
  389. * decode the unmappable character begin at the input buffer's (possibly
  390. * incremented) position; the number of such bytes may be determined
  391. * by invoking the result object's {@link CoderResult#length length}
  392. * method. This case applies only if the {@link #onUnmappableCharacter
  393. * </code>unmappable action<code>} of this decoder is {@link
  394. * CodingErrorAction#REPORT}; otherwise the unmappable character will be
  395. * ignored or replaced, as requested. </p></li>
  396. *
  397. * </ul>
  398. *
  399. * In any case, if this method is to be reinvoked in the same decoding
  400. * operation then care should be taken to preserve any bytes remaining
  401. * in the input buffer so that they are available to the next invocation.
  402. *
  403. * <p> The <tt>endOfInput</tt> parameter advises this method as to whether
  404. * the invoker can provide further input beyond that contained in the given
  405. * input buffer. If there is a possibility of providing additional input
  406. * then the invoker should pass <tt>false</tt> for this parameter; if there
  407. * is no possibility of providing further input then the invoker should
  408. * pass <tt>true</tt>. It is not erroneous, and in fact it is quite
  409. * common, to pass <tt>false</tt> in one invocation and later discover that
  410. * no further input was actually available. It is critical, however, that
  411. * the final invocation of this method in a sequence of invocations always
  412. * pass <tt>true</tt> so that any remaining undecoded input will be treated
  413. * as being malformed.
  414. *
  415. * <p> This method works by invoking the {@link #decodeLoop decodeLoop}
  416. * method, interpreting its results, handling error conditions, and
  417. * reinvoking it as necessary. </p>
  418. *
  419. *
  420. * @param in
  421. * The input byte buffer
  422. *
  423. * @param out
  424. * The output character buffer
  425. *
  426. * @param endOfInput
  427. * <tt>true</tt> if, and only if, the invoker can provide no
  428. * additional input bytes beyond those in the given buffer
  429. *
  430. * @return A coder-result object describing the reason for termination
  431. *
  432. * @throws IllegalStateException
  433. * If a decoding operation is already in progress and the previous
  434. * step was an invocation neither of the {@link #reset reset}
  435. * method, nor of this method with a value of <tt>false</tt> for
  436. * the <tt>endOfInput</tt> parameter, nor of this method with a
  437. * value of <tt>true</tt> for the <tt>endOfInput</tt> parameter
  438. * but a return value indicating an incomplete decoding operation
  439. *
  440. * @throws CoderMalfunctionError
  441. * If an invocation of the decodeLoop method threw
  442. * an unexpected exception
  443. */
  444. public final CoderResult decode(ByteBuffer in, CharBuffer out,
  445. boolean endOfInput)
  446. {
  447. int newState = endOfInput ? ST_END : ST_CODING;
  448. if ((state != ST_RESET) && (state != ST_CODING)
  449. && !(endOfInput && (state == ST_END)))
  450. throwIllegalStateException(state, newState);
  451. state = newState;
  452. for (;;) {
  453. CoderResult cr;
  454. try {
  455. cr = decodeLoop(in, out);
  456. } catch (BufferUnderflowException x) {
  457. throw new CoderMalfunctionError(x);
  458. } catch (BufferOverflowException x) {
  459. throw new CoderMalfunctionError(x);
  460. }
  461. if (cr.isOverflow())
  462. return cr;
  463. if (cr.isUnderflow()) {
  464. if (endOfInput && in.hasRemaining()) {
  465. cr = CoderResult.malformedForLength(in.remaining());
  466. // Fall through to malformed-input case
  467. } else {
  468. return cr;
  469. }
  470. }
  471. CodingErrorAction action = null;
  472. if (cr.isMalformed())
  473. action = malformedInputAction;
  474. else if (cr.isUnmappable())
  475. action = unmappableCharacterAction;
  476. else
  477. assert false : cr.toString();
  478. if (action == CodingErrorAction.REPORT)
  479. return cr;
  480. if (action == CodingErrorAction.REPLACE) {
  481. if (out.remaining() < replacement.length())
  482. return CoderResult.OVERFLOW;
  483. out.put(replacement);
  484. }
  485. if ((action == CodingErrorAction.IGNORE)
  486. || (action == CodingErrorAction.REPLACE)) {
  487. // Skip erroneous input either way
  488. in.position(in.position() + cr.length());
  489. continue;
  490. }
  491. assert false;
  492. }
  493. }
  494. /**
  495. * Flushes this decoder.
  496. *
  497. * <p> Some decoders maintain internal state and may need to write some
  498. * final characters to the output buffer once the overall input sequence has
  499. * been read.
  500. *
  501. * <p> Any additional output is written to the output buffer beginning at
  502. * its current position. At most {@link Buffer#remaining out.remaining()}
  503. * characters will be written. The buffer's position will be advanced
  504. * appropriately, but its mark and limit will not be modified.
  505. *
  506. * <p> If this method completes successfully then it returns {@link
  507. * CoderResult#UNDERFLOW}. If there is insufficient room in the output
  508. * buffer then it returns {@link CoderResult#OVERFLOW}. If this happens
  509. * then this method must be invoked again, with an output buffer that has
  510. * more room, in order to complete the current <a href="#steps">decoding
  511. * operation</a>.
  512. *
  513. * <p> This method invokes the {@link #implFlush implFlush} method to
  514. * perform the actual flushing operation. </p>
  515. *
  516. * @param out
  517. * The output character buffer
  518. *
  519. * @return A coder-result object, either {@link CoderResult#UNDERFLOW} or
  520. * {@link CoderResult#OVERFLOW}
  521. *
  522. * @throws IllegalStateException
  523. * If the previous step of the current decoding operation was an
  524. * invocation neither of the {@link #reset reset} method nor of
  525. * the three-argument {@link
  526. * #decode(ByteBuffer,CharBuffer,boolean) decode} method
  527. * with a value of <tt>true</tt> for the <tt>endOfInput</tt>
  528. * parameter
  529. */
  530. public final CoderResult flush(CharBuffer out) {
  531. if (state != ST_END)
  532. throwIllegalStateException(state, ST_FLUSHED);
  533. state = ST_FLUSHED;
  534. return implFlush(out);
  535. }
  536. /**
  537. * Flushes this decoder.
  538. *
  539. * <p> The default implementation of this method does nothing, and always
  540. * returns {@link CoderResult#UNDERFLOW}. This method should be overridden
  541. * by decoders that may need to write final characters to the output buffer
  542. * once the entire input sequence has been read. </p>
  543. *
  544. * @param out
  545. * The output character buffer
  546. *
  547. * @return A coder-result object, either {@link CoderResult#UNDERFLOW} or
  548. * {@link CoderResult#OVERFLOW}
  549. */
  550. protected CoderResult implFlush(CharBuffer out) {
  551. return CoderResult.UNDERFLOW;
  552. }
  553. /**
  554. * Resets this decoder, clearing any internal state.
  555. *
  556. * <p> This method resets charset-independent state and also invokes the
  557. * {@link #implReset() implReset} method in order to perform any
  558. * charset-specific reset actions. </p>
  559. *
  560. * @return This decoder
  561. *
  562. */
  563. public final CharsetDecoder reset() {
  564. implReset();
  565. state = ST_RESET;
  566. return this;
  567. }
  568. /**
  569. * Resets this decoder, clearing any charset-specific internal state.
  570. *
  571. * <p> The default implementation of this method does nothing. This method
  572. * should be overridden by decoders that maintain internal state. </p>
  573. */
  574. protected void implReset() { }
  575. /**
  576. * Decodes one or more bytes into one or more characters.
  577. *
  578. * <p> This method encapsulates the basic decoding loop, decoding as many
  579. * bytes as possible until it either runs out of input, runs out of room
  580. * in the output buffer, or encounters a decoding error. This method is
  581. * invoked by the {@link #decode decode} method, which handles result
  582. * interpretation and error recovery.
  583. *
  584. * <p> The buffers are read from, and written to, starting at their current
  585. * positions. At most {@link Buffer#remaining in.remaining()} bytes
  586. * will be read, and at most {@link Buffer#remaining out.remaining()}
  587. * characters will be written. The buffers' positions will be advanced to
  588. * reflect the bytes read and the characters written, but their marks and
  589. * limits will not be modified.
  590. *
  591. * <p> This method returns a {@link CoderResult} object to describe its
  592. * reason for termination, in the same manner as the {@link #decode decode}
  593. * method. Most implementations of this method will handle decoding errors
  594. * by returning an appropriate result object for interpretation by the
  595. * {@link #decode decode} method. An optimized implementation may instead
  596. * examine the relevant error action and implement that action itself.
  597. *
  598. * <p> An implementation of this method may perform arbitrary lookahead by
  599. * returning {@link CoderResult#UNDERFLOW} until it receives sufficient
  600. * input. </p>
  601. *
  602. * @param in
  603. * The input byte buffer
  604. *
  605. * @param out
  606. * The output character buffer
  607. *
  608. * @return A coder-result object describing the reason for termination
  609. */
  610. protected abstract CoderResult decodeLoop(ByteBuffer in,
  611. CharBuffer out);
  612. /**
  613. * Convenience method that decodes the remaining content of a single input
  614. * byte buffer into a newly-allocated character buffer.
  615. *
  616. * <p> This method implements an entire <a href="#steps">decoding
  617. * operation</a> that is, it resets this decoder, then it decodes the
  618. * bytes in the given byte buffer, and finally it flushes this
  619. * decoder. This method should therefore not be invoked if a decoding
  620. * operation is already in progress. </p>
  621. *
  622. * @param in
  623. * The input byte buffer
  624. *
  625. * @return A newly-allocated character buffer containing the result of the
  626. * decoding operation. The buffer's position will be zero and its
  627. * limit will follow the last character written.
  628. *
  629. * @throws IllegalStateException
  630. * If a decoding operation is already in progress
  631. *
  632. * @throws MalformedInputException
  633. * If the byte sequence starting at the input buffer's current
  634. * position is not legal for this charset and the current malformed-input action
  635. * is {@link CodingErrorAction#REPORT}
  636. *
  637. * @throws UnmappableCharacterException
  638. * If the byte sequence starting at the input buffer's current
  639. * position cannot be mapped to an equivalent character sequence and
  640. * the current unmappable-character action is {@link
  641. * CodingErrorAction#REPORT}
  642. */
  643. public final CharBuffer decode(ByteBuffer in)
  644. throws CharacterCodingException
  645. {
  646. int n = (int)(in.remaining() * averageCharsPerByte());
  647. CharBuffer out = CharBuffer.allocate(n);
  648. if (n == 0)
  649. return out;
  650. reset();
  651. for (;;) {
  652. CoderResult cr;
  653. if (in.hasRemaining())
  654. cr = decode(in, out, true);
  655. else
  656. cr = flush(out);
  657. if (cr.isUnderflow())
  658. break;
  659. if (cr.isOverflow()) {
  660. n *= 2;
  661. CharBuffer o = CharBuffer.allocate(n);
  662. out.flip();
  663. o.put(out);
  664. out = o;
  665. continue;
  666. }
  667. cr.throwException();
  668. }
  669. out.flip();
  670. return out;
  671. }
  672. /**
  673. * Tells whether or not this decoder implements an auto-detecting charset.
  674. *
  675. * <p> The default implementation of this method always returns
  676. * <tt>false</tt> it should be overridden by auto-detecting decoders to
  677. * return <tt>true</tt>. </p>
  678. *
  679. * @return <tt>true</tt> if, and only if, this decoder implements an
  680. * auto-detecting charset
  681. */
  682. public boolean isAutoDetecting() {
  683. return false;
  684. }
  685. /**
  686. * Tells whether or not this decoder has yet detected a
  687. * charset  <i>(optional operation)</i>.
  688. *
  689. * <p> If this decoder implements an auto-detecting charset then at a
  690. * single point during a decoding operation this method may start returning
  691. * <tt>true</tt> to indicate that a specific charset has been detected in
  692. * the input byte sequence. Once this occurs, the {@link #detectedCharset
  693. * detectedCharset} method may be invoked to retrieve the detected charset.
  694. *
  695. * <p> That this method returns <tt>false</tt> does not imply that no bytes
  696. * have yet been decoded. Some auto-detecting decoders are capable of
  697. * decoding some, or even all, of an input byte sequence without fixing on
  698. * a particular charset.
  699. *
  700. * <p> The default implementation of this method always throws an {@link
  701. * UnsupportedOperationException}; it should be overridden by
  702. * auto-detecting decoders to return <tt>true</tt> once the input charset
  703. * has been determined. </p>
  704. *
  705. * @return <tt>true</tt> if, and only if, this decoder has detected a
  706. * specific charset
  707. *
  708. * @throws UnsupportedOperationException
  709. * If this decoder does not implement an auto-detecting charset
  710. */
  711. public boolean isCharsetDetected() {
  712. throw new UnsupportedOperationException();
  713. }
  714. /**
  715. * Retrieves the charset that was detected by this
  716. * decoder  <i>(optional operation)</i>.
  717. *
  718. * <p> If this decoder implements an auto-detecting charset then this
  719. * method returns the actual charset once it has been detected. After that
  720. * point, this method returns the same value for the duration of the
  721. * current decoding operation. If not enough input bytes have yet been
  722. * read to determine the actual charset then this method throws an {@link
  723. * IllegalStateException}.
  724. *
  725. * <p> The default implementation of this method always throws an {@link
  726. * UnsupportedOperationException}; it should be overridden by
  727. * auto-detecting decoders to return the appropriate value. </p>
  728. *
  729. * @return The charset detected by this auto-detecting decoder,
  730. * or <tt>null</tt> if the charset has not yet been determined
  731. *
  732. * @throws IllegalStateException
  733. * If insufficient bytes have been read to determine a charset
  734. *
  735. * @throws UnsupportedOperationException
  736. * If this decoder does not implement an auto-detecting charset
  737. */
  738. public Charset detectedCharset() {
  739. throw new UnsupportedOperationException();
  740. }
  741. private void throwIllegalStateException(int from, int to) {
  742. throw new IllegalStateException("Current state = " + stateNames[from]
  743. + ", new state = " + stateNames[to]);
  744. }
  745. }