KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > nio > charset > CharsetDecoder


1 /*
2  * @(#)Charset-X-Coder.java 1.42 05/03/03
3  *
4  * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 // -- This file was mechanically generated: Do not edit! -- //
9

10 package java.nio.charset;
11
12 import java.nio.Buffer JavaDoc;
13 import java.nio.ByteBuffer JavaDoc;
14 import java.nio.CharBuffer JavaDoc;
15 import java.nio.BufferOverflowException JavaDoc;
16 import java.nio.BufferUnderflowException JavaDoc;
17 import java.lang.ref.WeakReference JavaDoc;
18 import java.nio.charset.CoderMalfunctionError JavaDoc; // javadoc
19

20
21 /**
22  * An engine that can transform a sequence of bytes in a specific charset into a sequence of
23  * sixteen-bit Unicode characters.
24  *
25  * <a name="steps">
26  *
27  * <p> The input byte sequence is provided in a byte buffer or a series
28  * of such buffers. The output character sequence is written to a character buffer
29  * or a series of such buffers. A decoder should always be used by making
30  * the following sequence of method invocations, hereinafter referred to as a
31  * <i>decoding operation</i>:
32  *
33  * <ol>
34  *
35  * <li><p> Reset the decoder via the {@link #reset reset} method, unless it
36  * has not been used before; </p></li>
37  *
38  * <li><p> Invoke the {@link #decode decode} method zero or more times, as
39  * long as additional input may be available, passing <tt>false</tt> for the
40  * <tt>endOfInput</tt> argument and filling the input buffer and flushing the
41  * output buffer between invocations; </p></li>
42  *
43  * <li><p> Invoke the {@link #decode decode} method one final time, passing
44  * <tt>true</tt> for the <tt>endOfInput</tt> argument; and then </p></li>
45  *
46  * <li><p> Invoke the {@link #flush flush} method so that the decoder can
47  * flush any internal state to the output buffer. </p></li>
48  *
49  * </ol>
50  *
51  * Each invocation of the {@link #decode decode} method will decode as many
52  * bytes as possible from the input buffer, writing the resulting characters
53  * to the output buffer. The {@link #decode decode} method returns when more
54  * input is required, when there is not enough room in the output buffer, or
55  * when a decoding error has occurred. In each case a {@link CoderResult}
56  * object is returned to describe the reason for termination. An invoker can
57  * examine this object and fill the input buffer, flush the output buffer, or
58  * attempt to recover from a decoding error, as appropriate, and try again.
59  *
60  * <a name="ce">
61  *
62  * <p> There are two general types of decoding errors. If the input byte
63  * sequence is not legal for this charset then the input is considered <i>malformed</i>. If
64  * the input byte sequence is legal but cannot be mapped to a valid
65  * Unicode character then an <i>unmappable character</i> has been encountered.
66  *
67  * <a name="cae">
68  *
69  * <p> How a decoding error is handled depends upon the action requested for
70  * that type of error, which is described by an instance of the {@link
71  * CodingErrorAction} class. The possible error actions are to {@link
72  * CodingErrorAction#IGNORE </code>ignore<code>} the erroneous input, {@link
73  * CodingErrorAction#REPORT </code>report<code>} the error to the invoker via
74  * the returned {@link CoderResult} object, or {@link CodingErrorAction#REPLACE
75  * </code>replace<code>} the erroneous input with the current value of the
76  * replacement string. The replacement
77  *
78
79
80
81
82
83  * has the initial value <tt>"&#92;uFFFD"</tt>;
84
85  *
86  * its value may be changed via the {@link #replaceWith(java.lang.String)
87  * replaceWith} method.
88  *
89  * <p> The default action for malformed-input and unmappable-character errors
90  * is to {@link CodingErrorAction#REPORT </code>report<code>} them. The
91  * malformed-input error action may be changed via the {@link
92  * #onMalformedInput(CodingErrorAction) onMalformedInput} method; the
93  * unmappable-character action may be changed via the {@link
94  * #onUnmappableCharacter(CodingErrorAction) onUnmappableCharacter} method.
95  *
96  * <p> This class is designed to handle many of the details of the decoding
97  * process, including the implementation of error actions. A decoder for a
98  * specific charset, which is a concrete subclass of this class, need only
99  * implement the abstract {@link #decodeLoop decodeLoop} method, which
100  * encapsulates the basic decoding loop. A subclass that maintains internal
101  * state should, additionally, override the {@link #flush flush} and {@link
102  * #reset reset} methods.
103  *
104  * <p> Instances of this class are not safe for use by multiple concurrent
105  * threads. </p>
106  *
107  *
108  * @version 1.42, 05/03/03
109  * @author Mark Reinhold
110  * @author JSR-51 Expert Group
111  * @since 1.4
112  *
113  * @see ByteBuffer
114  * @see CharBuffer
115  * @see Charset
116  * @see CharsetEncoder
117  */

118
119 public abstract class CharsetDecoder {
120
121     private final Charset JavaDoc charset;
122     private final float averageCharsPerByte;
123     private final float maxCharsPerByte;
124
125     private String JavaDoc replacement;
126     private CodingErrorAction JavaDoc malformedInputAction
127     = CodingErrorAction.REPORT;
128     private CodingErrorAction JavaDoc unmappableCharacterAction
129     = CodingErrorAction.REPORT;
130
131     // Internal states
132
//
133
private static final int ST_RESET = 0;
134     private static final int ST_CODING = 1;
135     private static final int ST_END = 2;
136     private static final int ST_FLUSHED = 3;
137
138     private int state = ST_RESET;
139
140     private static String JavaDoc stateNames[]
141     = { "RESET", "CODING", "CODING_END", "FLUSHED" };
142
143
144     /**
145      * Initializes a new decoder. The new decoder will have the given
146      * chars-per-byte and replacement values. </p>
147      *
148      * @param averageCharsPerByte
149      * A positive float value indicating the expected number of
150      * characters that will be produced for each input byte
151      *
152      * @param maxCharsPerByte
153      * A positive float value indicating the maximum number of
154      * characters that will be produced for each input byte
155      *
156      * @param replacement
157      * The initial replacement; must not be <tt>null</tt>, must have
158      * non-zero length, must not be longer than maxCharsPerByte,
159      * and must be {@link #isLegalReplacement </code>legal<code>}
160      *
161      * @throws IllegalArgumentException
162      * If the preconditions on the parameters do not hold
163      */

164     private
165     CharsetDecoder(Charset JavaDoc cs,
166            float averageCharsPerByte,
167            float maxCharsPerByte,
168            String JavaDoc replacement)
169     {
170     this.charset = cs;
171     if (averageCharsPerByte <= 0.0f)
172         throw new IllegalArgumentException JavaDoc("Non-positive "
173                            + "averageCharsPerByte");
174     if (maxCharsPerByte <= 0.0f)
175         throw new IllegalArgumentException JavaDoc("Non-positive "
176                            + "maxCharsPerByte");
177     if (!Charset.atBugLevel("1.4")) {
178         if (averageCharsPerByte > maxCharsPerByte)
179         throw new IllegalArgumentException JavaDoc("averageCharsPerByte"
180                            + " exceeds "
181                            + "maxCharsPerByte");
182     }
183     this.replacement = replacement;
184     this.averageCharsPerByte = averageCharsPerByte;
185     this.maxCharsPerByte = maxCharsPerByte;
186     replaceWith(replacement);
187     }
188
189     /**
190      * Initializes a new decoder. The new decoder will have the given
191      * chars-per-byte values and its replacement will be the
192      * string <tt>"&#92;uFFFD"</tt>. </p>
193      *
194      * @param averageCharsPerByte
195      * A positive float value indicating the expected number of
196      * characters that will be produced for each input byte
197      *
198      * @param maxCharsPerByte
199      * A positive float value indicating the maximum number of
200      * characters that will be produced for each input byte
201      *
202      * @throws IllegalArgumentException
203      * If the preconditions on the parameters do not hold
204      */

205     protected CharsetDecoder(Charset JavaDoc cs,
206                  float averageCharsPerByte,
207                  float maxCharsPerByte)
208     {
209     this(cs,
210          averageCharsPerByte, maxCharsPerByte,
211          "\uFFFD");
212     }
213
214     /**
215      * Returns the charset that created this decoder. </p>
216      *
217      * @return This decoder's charset
218      */

219     public final Charset JavaDoc charset() {
220     return charset;
221     }
222
223     /**
224      * Returns this decoder's replacement value. </p>
225      *
226      * @return This decoder's current replacement,
227      * which is never <tt>null</tt> and is never empty
228      */

229     public final String JavaDoc replacement() {
230     return replacement;
231     }
232
233     /**
234      * Changes this decoder's replacement value.
235      *
236      * <p> This method invokes the {@link #implReplaceWith implReplaceWith}
237      * method, passing the new replacement, after checking that the new
238      * replacement is acceptable. </p>
239      *
240      * @param newReplacement
241      *
242
243      * The new replacement; must not be <tt>null</tt>
244      * and must have non-zero length
245
246
247
248
249
250
251
252      *
253      * @return This decoder
254      *
255      * @throws IllegalArgumentException
256      * If the preconditions on the parameter do not hold
257      */

258     public final CharsetDecoder JavaDoc replaceWith(String JavaDoc newReplacement) {
259     if (newReplacement == null)
260         throw new IllegalArgumentException JavaDoc("Null replacement");
261     int len = newReplacement.length();
262     if (len == 0)
263         throw new IllegalArgumentException JavaDoc("Empty replacement");
264     if (len > maxCharsPerByte)
265         throw new IllegalArgumentException JavaDoc("Replacement too long");
266
267
268
269
270     this.replacement = newReplacement;
271     implReplaceWith(newReplacement);
272     return this;
273     }
274
275     /**
276      * Reports a change to this decoder's replacement value.
277      *
278      * <p> The default implementation of this method does nothing. This method
279      * should be overridden by decoders that require notification of changes to
280      * the replacement. </p>
281      *
282      * @param newReplacement
283      */

284     protected void implReplaceWith(String JavaDoc newReplacement) {
285     }
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
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      * Returns this decoder's current action for malformed-input errors. </p>
331      *
332      * @return The current malformed-input action, which is never <tt>null</tt>
333      */

334     public CodingErrorAction JavaDoc malformedInputAction() {
335     return malformedInputAction;
336     }
337
338     /**
339      * Changes this decoder's action for malformed-input errors. </p>
340      *
341      * <p> This method invokes the {@link #implOnMalformedInput
342      * implOnMalformedInput} method, passing the new action. </p>
343      *
344      * @param newAction The new action; must not be <tt>null</tt>
345      *
346      * @return This decoder
347      *
348      * @throws IllegalArgumentException
349      * If the precondition on the parameter does not hold
350      */

351     public final CharsetDecoder JavaDoc onMalformedInput(CodingErrorAction JavaDoc newAction) {
352     if (newAction == null)
353         throw new IllegalArgumentException JavaDoc("Null action");
354     malformedInputAction = newAction;
355     implOnMalformedInput(newAction);
356     return this;
357     }
358
359     /**
360      * Reports a change to this decoder's malformed-input action.
361      *
362      * <p> The default implementation of this method does nothing. This method
363      * should be overridden by decoders that require notification of changes to
364      * the malformed-input action. </p>
365      */

366     protected void implOnMalformedInput(CodingErrorAction JavaDoc newAction) { }
367
368     /**
369      * Returns this decoder's current action for unmappable-character errors.
370      * </p>
371      *
372      * @return The current unmappable-character action, which is never
373      * <tt>null</tt>
374      */

375     public CodingErrorAction JavaDoc unmappableCharacterAction() {
376     return unmappableCharacterAction;
377     }
378
379     /**
380      * Changes this decoder's action for unmappable-character errors.
381      *
382      * <p> This method invokes the {@link #implOnUnmappableCharacter
383      * implOnUnmappableCharacter} method, passing the new action. </p>
384      *
385      * @param newAction The new action; must not be <tt>null</tt>
386      *
387      * @return This decoder
388      *
389      * @throws IllegalArgumentException
390      * If the precondition on the parameter does not hold
391      */

392     public final CharsetDecoder JavaDoc onUnmappableCharacter(CodingErrorAction JavaDoc
393                               newAction)
394     {
395     if (newAction == null)
396         throw new IllegalArgumentException JavaDoc("Null action");
397     unmappableCharacterAction = newAction;
398     implOnUnmappableCharacter(newAction);
399     return this;
400     }
401
402     /**
403      * Reports a change to this decoder's unmappable-character action.
404      *
405      * <p> The default implementation of this method does nothing. This method
406      * should be overridden by decoders that require notification of changes to
407      * the unmappable-character action. </p>
408      */

409     protected void implOnUnmappableCharacter(CodingErrorAction JavaDoc newAction) { }
410
411     /**
412      * Returns the average number of characters that will be produced for each
413      * byte of input. This heuristic value may be used to estimate the size
414      * of the output buffer required for a given input sequence. </p>
415      *
416      * @return The average number of characters produced
417      * per byte of input
418      */

419     public final float averageCharsPerByte() {
420     return averageCharsPerByte;
421     }
422
423     /**
424      * Returns the maximum number of characters that will be produced for each
425      * byte of input. This value may be used to compute the worst-case size
426      * of the output buffer required for a given input sequence. </p>
427      *
428      * @return The maximum number of characters that will be produced per
429      * byte of input
430      */

431     public final float maxCharsPerByte() {
432     return maxCharsPerByte;
433     }
434
435     /**
436      * Decodes as many bytes as possible from the given input buffer,
437      * writing the results to the given output buffer.
438      *
439      * <p> The buffers are read from, and written to, starting at their current
440      * positions. At most {@link Buffer#remaining in.remaining()} bytes
441      * will be read and at most {@link Buffer#remaining out.remaining()}
442      * characters will be written. The buffers' positions will be advanced to
443      * reflect the bytes read and the characters written, but their marks and
444      * limits will not be modified.
445      *
446      * <p> In addition to reading bytes from the input buffer and writing
447      * characters to the output buffer, this method returns a {@link CoderResult}
448      * object to describe its reason for termination:
449      *
450      * <ul>
451      *
452      * <li><p> {@link CoderResult#UNDERFLOW} indicates that as much of the
453      * input buffer as possible has been decoded. If there are no bytes
454      * remaining and the invoker has no further input then the decoding
455      * operation is complete. Otherwise there is insufficient input for the
456      * operation to proceed, so this method should be invoked again with
457      * further input. </p></li>
458      *
459      * <li><p> {@link CoderResult#OVERFLOW} indicates that the output buffer
460      * is full. This method should be invoked again with a non-full output
461      * buffer. </p></li>
462      *
463      * <li><p> A {@link CoderResult#malformedForLength
464      * </code>malformed-input<code>} result indicates that a malformed-input
465      * error has been detected. The malformed bytes begin at the input
466      * buffer's (possibly incremented) position; the number of malformed
467      * bytes may be determined by invoking the result object's {@link
468      * CoderResult#length length} method. This case applies only if the
469      * {@link #onMalformedInput </code>malformed action<code>} of this decoder
470      * is {@link CodingErrorAction#REPORT}; otherwise the malformed input
471      * will be ignored or replaced, as requested. </p></li>
472      *
473      * <li><p> An {@link CoderResult#unmappableForLength
474      * </code>unmappable-character<code>} result indicates that an
475      * unmappable-character error has been detected. The bytes that
476      * decode the unmappable character begin at the input buffer's (possibly
477      * incremented) position; the number of such bytes may be determined
478      * by invoking the result object's {@link CoderResult#length length}
479      * method. This case applies only if the {@link #onUnmappableCharacter
480      * </code>unmappable action<code>} of this decoder is {@link
481      * CodingErrorAction#REPORT}; otherwise the unmappable character will be
482      * ignored or replaced, as requested. </p></li>
483      *
484      * </ul>
485      *
486      * In any case, if this method is to be reinvoked in the same decoding
487      * operation then care should be taken to preserve any bytes remaining
488      * in the input buffer so that they are available to the next invocation.
489      *
490      * <p> The <tt>endOfInput</tt> parameter advises this method as to whether
491      * the invoker can provide further input beyond that contained in the given
492      * input buffer. If there is a possibility of providing additional input
493      * then the invoker should pass <tt>false</tt> for this parameter; if there
494      * is no possibility of providing further input then the invoker should
495      * pass <tt>true</tt>. It is not erroneous, and in fact it is quite
496      * common, to pass <tt>false</tt> in one invocation and later discover that
497      * no further input was actually available. It is critical, however, that
498      * the final invocation of this method in a sequence of invocations always
499      * pass <tt>true</tt> so that any remaining undecoded input will be treated
500      * as being malformed.
501      *
502      * <p> This method works by invoking the {@link #decodeLoop decodeLoop}
503      * method, interpreting its results, handling error conditions, and
504      * reinvoking it as necessary. </p>
505      *
506      *
507      * @param in
508      * The input byte buffer
509      *
510      * @param out
511      * The output character buffer
512      *
513      * @param endOfInput
514      * <tt>true</tt> if, and only if, the invoker can provide no
515      * additional input bytes beyond those in the given buffer
516      *
517      * @return A coder-result object describing the reason for termination
518      *
519      * @throws IllegalStateException
520      * If a decoding operation is already in progress and the previous
521      * step was an invocation neither of the {@link #reset reset}
522      * method, nor of this method with a value of <tt>false</tt> for
523      * the <tt>endOfInput</tt> parameter, nor of this method with a
524      * value of <tt>true</tt> for the <tt>endOfInput</tt> parameter
525      * but a return value indicating an incomplete decoding operation
526      *
527      * @throws CoderMalfunctionError
528      * If an invocation of the decodeLoop method threw
529      * an unexpected exception
530      */

531     public final CoderResult JavaDoc decode(ByteBuffer JavaDoc in, CharBuffer JavaDoc out,
532                     boolean endOfInput)
533     {
534     int newState = endOfInput ? ST_END : ST_CODING;
535     if ((state != ST_RESET) && (state != ST_CODING)
536         && !(endOfInput && (state == ST_END)))
537         throwIllegalStateException(state, newState);
538     state = newState;
539
540     for (;;) {
541
542         CoderResult JavaDoc cr;
543         try {
544         cr = decodeLoop(in, out);
545         } catch (BufferUnderflowException JavaDoc x) {
546         throw new CoderMalfunctionError JavaDoc(x);
547         } catch (BufferOverflowException JavaDoc x) {
548         throw new CoderMalfunctionError JavaDoc(x);
549         }
550
551         if (cr.isOverflow())
552         return cr;
553
554         if (cr.isUnderflow()) {
555         if (endOfInput && in.hasRemaining()) {
556             cr = CoderResult.malformedForLength(in.remaining());
557             // Fall through to malformed-input case
558
} else {
559             return cr;
560         }
561         }
562
563         CodingErrorAction JavaDoc action = null;
564         if (cr.isMalformed())
565         action = malformedInputAction;
566         else if (cr.isUnmappable())
567         action = unmappableCharacterAction;
568         else
569         assert false : cr.toString();
570
571         if (action == CodingErrorAction.REPORT)
572         return cr;
573
574         if (action == CodingErrorAction.REPLACE) {
575         if (out.remaining() < replacement.length())
576             return CoderResult.OVERFLOW;
577         out.put(replacement);
578         }
579
580         if ((action == CodingErrorAction.IGNORE)
581         || (action == CodingErrorAction.REPLACE)) {
582         // Skip erroneous input either way
583
in.position(in.position() + cr.length());
584         continue;
585         }
586
587         assert false;
588     }
589
590     }
591
592     /**
593      * Flushes this decoder.
594      *
595      * <p> Some decoders maintain internal state and may need to write some
596      * final characters to the output buffer once the overall input sequence has
597      * been read.
598      *
599      * <p> Any additional output is written to the output buffer beginning at
600      * its current position. At most {@link Buffer#remaining out.remaining()}
601      * characters will be written. The buffer's position will be advanced
602      * appropriately, but its mark and limit will not be modified.
603      *
604      * <p> If this method completes successfully then it returns {@link
605      * CoderResult#UNDERFLOW}. If there is insufficient room in the output
606      * buffer then it returns {@link CoderResult#OVERFLOW}. If this happens
607      * then this method must be invoked again, with an output buffer that has
608      * more room, in order to complete the current <a HREF="#steps">decoding
609      * operation</a>.
610      *
611      * <p> This method invokes the {@link #implFlush implFlush} method to
612      * perform the actual flushing operation. </p>
613      *
614      * @param out
615      * The output character buffer
616      *
617      * @return A coder-result object, either {@link CoderResult#UNDERFLOW} or
618      * {@link CoderResult#OVERFLOW}
619      *
620      * @throws IllegalStateException
621      * If the previous step of the current decoding operation was an
622      * invocation neither of the {@link #reset reset} method nor of
623      * the three-argument {@link
624      * #decode(ByteBuffer,CharBuffer,boolean) decode} method
625      * with a value of <tt>true</tt> for the <tt>endOfInput</tt>
626      * parameter
627      */

628     public final CoderResult JavaDoc flush(CharBuffer JavaDoc out) {
629     if (state != ST_END)
630         throwIllegalStateException(state, ST_FLUSHED);
631     state = ST_FLUSHED;
632     return implFlush(out);
633     }
634
635     /**
636      * Flushes this decoder.
637      *
638      * <p> The default implementation of this method does nothing, and always
639      * returns {@link CoderResult#UNDERFLOW}. This method should be overridden
640      * by decoders that may need to write final characters to the output buffer
641      * once the entire input sequence has been read. </p>
642      *
643      * @param out
644      * The output character buffer
645      *
646      * @return A coder-result object, either {@link CoderResult#UNDERFLOW} or
647      * {@link CoderResult#OVERFLOW}
648      */

649     protected CoderResult JavaDoc implFlush(CharBuffer JavaDoc out) {
650     return CoderResult.UNDERFLOW;
651     }
652
653     /**
654      * Resets this decoder, clearing any internal state.
655      *
656      * <p> This method resets charset-independent state and also invokes the
657      * {@link #implReset() implReset} method in order to perform any
658      * charset-specific reset actions. </p>
659      *
660      * @return This decoder
661      *
662      */

663     public final CharsetDecoder JavaDoc reset() {
664     implReset();
665     state = ST_RESET;
666     return this;
667     }
668
669     /**
670      * Resets this decoder, clearing any charset-specific internal state.
671      *
672      * <p> The default implementation of this method does nothing. This method
673      * should be overridden by decoders that maintain internal state. </p>
674      */

675     protected void implReset() { }
676
677     /**
678      * Decodes one or more bytes into one or more characters.
679      *
680      * <p> This method encapsulates the basic decoding loop, decoding as many
681      * bytes as possible until it either runs out of input, runs out of room
682      * in the output buffer, or encounters a decoding error. This method is
683      * invoked by the {@link #decode decode} method, which handles result
684      * interpretation and error recovery.
685      *
686      * <p> The buffers are read from, and written to, starting at their current
687      * positions. At most {@link Buffer#remaining in.remaining()} bytes
688      * will be read, and at most {@link Buffer#remaining out.remaining()}
689      * characters will be written. The buffers' positions will be advanced to
690      * reflect the bytes read and the characters written, but their marks and
691      * limits will not be modified.
692      *
693      * <p> This method returns a {@link CoderResult} object to describe its
694      * reason for termination, in the same manner as the {@link #decode decode}
695      * method. Most implementations of this method will handle decoding errors
696      * by returning an appropriate result object for interpretation by the
697      * {@link #decode decode} method. An optimized implementation may instead
698      * examine the relevant error action and implement that action itself.
699      *
700      * <p> An implementation of this method may perform arbitrary lookahead by
701      * returning {@link CoderResult#UNDERFLOW} until it receives sufficient
702      * input. </p>
703      *
704      * @param in
705      * The input byte buffer
706      *
707      * @param out
708      * The output character buffer
709      *
710      * @return A coder-result object describing the reason for termination
711      */

712     protected abstract CoderResult JavaDoc decodeLoop(ByteBuffer JavaDoc in,
713                           CharBuffer JavaDoc out);
714
715     /**
716      * Convenience method that decodes the remaining content of a single input
717      * byte buffer into a newly-allocated character buffer.
718      *
719      * <p> This method implements an entire <a HREF="#steps">decoding
720      * operation</a>; that is, it resets this decoder, then it decodes the
721      * bytes in the given byte buffer, and finally it flushes this
722      * decoder. This method should therefore not be invoked if a decoding
723      * operation is already in progress. </p>
724      *
725      * @param in
726      * The input byte buffer
727      *
728      * @return A newly-allocated character buffer containing the result of the
729      * decoding operation. The buffer's position will be zero and its
730      * limit will follow the last character written.
731      *
732      * @throws IllegalStateException
733      * If a decoding operation is already in progress
734      *
735      * @throws MalformedInputException
736      * If the byte sequence starting at the input buffer's current
737      * position is not legal for this charset and the current malformed-input action
738      * is {@link CodingErrorAction#REPORT}
739      *
740      * @throws UnmappableCharacterException
741      * If the byte sequence starting at the input buffer's current
742      * position cannot be mapped to an equivalent character sequence and
743      * the current unmappable-character action is {@link
744      * CodingErrorAction#REPORT}
745      */

746     public final CharBuffer JavaDoc decode(ByteBuffer JavaDoc in)
747     throws CharacterCodingException JavaDoc
748     {
749     int n = (int)(in.remaining() * averageCharsPerByte());
750     CharBuffer JavaDoc out = CharBuffer.allocate(n);
751
752     if (n == 0)
753         return out;
754     reset();
755     for (;;) {
756         CoderResult JavaDoc cr;
757         if (in.hasRemaining())
758         cr = decode(in, out, true);
759         else
760         cr = flush(out);
761         if (cr.isUnderflow())
762         break;
763         if (cr.isOverflow()) {
764         n *= 2;
765         CharBuffer JavaDoc o = CharBuffer.allocate(n);
766         out.flip();
767         o.put(out);
768         out = o;
769         continue;
770         }
771         cr.throwException();
772     }
773     out.flip();
774     return out;
775     }
776
777
778
779     /**
780      * Tells whether or not this decoder implements an auto-detecting charset.
781      *
782      * <p> The default implementation of this method always returns
783      * <tt>false</tt>; it should be overridden by auto-detecting decoders to
784      * return <tt>true</tt>. </p>
785      *
786      * @return <tt>true</tt> if, and only if, this decoder implements an
787      * auto-detecting charset
788      */

789     public boolean isAutoDetecting() {
790     return false;
791     }
792
793     /**
794      * Tells whether or not this decoder has yet detected a
795      * charset&nbsp;&nbsp;<i>(optional operation)</i>.
796      *
797      * <p> If this decoder implements an auto-detecting charset then at a
798      * single point during a decoding operation this method may start returning
799      * <tt>true</tt> to indicate that a specific charset has been detected in
800      * the input byte sequence. Once this occurs, the {@link #detectedCharset
801      * detectedCharset} method may be invoked to retrieve the detected charset.
802      *
803      * <p> That this method returns <tt>false</tt> does not imply that no bytes
804      * have yet been decoded. Some auto-detecting decoders are capable of
805      * decoding some, or even all, of an input byte sequence without fixing on
806      * a particular charset.
807      *
808      * <p> The default implementation of this method always throws an {@link
809      * UnsupportedOperationException}; it should be overridden by
810      * auto-detecting decoders to return <tt>true</tt> once the input charset
811      * has been determined. </p>
812      *
813      * @return <tt>true</tt> if, and only if, this decoder has detected a
814      * specific charset
815      *
816      * @throws UnsupportedOperationException
817      * If this decoder does not implement an auto-detecting charset
818      */

819     public boolean isCharsetDetected() {
820     throw new UnsupportedOperationException JavaDoc();
821     }
822
823     /**
824      * Retrieves the charset that was detected by this
825      * decoder&nbsp;&nbsp;<i>(optional operation)</i>.
826      *
827      * <p> If this decoder implements an auto-detecting charset then this
828      * method returns the actual charset once it has been detected. After that
829      * point, this method returns the same value for the duration of the
830      * current decoding operation. If not enough input bytes have yet been
831      * read to determine the actual charset then this method throws an {@link
832      * IllegalStateException}.
833      *
834      * <p> The default implementation of this method always throws an {@link
835      * UnsupportedOperationException}; it should be overridden by
836      * auto-detecting decoders to return the appropriate value. </p>
837      *
838      * @return The charset detected by this auto-detecting decoder,
839      * or <tt>null</tt> if the charset has not yet been determined
840      *
841      * @throws IllegalStateException
842      * If insufficient bytes have been read to determine a charset
843      *
844      * @throws UnsupportedOperationException
845      * If this decoder does not implement an auto-detecting charset
846      */

847     public Charset JavaDoc detectedCharset() {
848     throw new UnsupportedOperationException JavaDoc();
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
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     private void throwIllegalStateException(int from, int to) {
941     throw new IllegalStateException JavaDoc("Current state = " + stateNames[from]
942                     + ", new state = " + stateNames[to]);
943     }
944
945 }
946
Popular Tags