Source Code Cross Referenced for Charset-X-Coder.java in  » 6.0-JDK-Core » io-nio » java » nio » charset » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » io nio » java.nio.charset 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001/*
002 * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.  Sun designates this 
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this  code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this  code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this  work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026#warn This file is preprocessed before being compiled
027
028package java.nio.charset;
029
030import java.nio.Buffer;
031import java.nio.ByteBuffer;
032import java.nio.CharBuffer;
033import java.nio.BufferOverflowException;
034import java.nio.BufferUnderflowException;
035import java.lang.ref.WeakReference;
036import java.nio.charset.CoderMalfunctionError;			// javadoc
037
038
039/**
040 * An engine that can transform a sequence of $itypesPhrase$ into a sequence of
041 * $otypesPhrase$.
042 *
043 * <a name="steps">
044 *
045 * <p> The input $itype$ sequence is provided in a $itype$ buffer or a series
046 * of such buffers.  The output $otype$ sequence is written to a $otype$ buffer
047 * or a series of such buffers.  $A$ $coder$ should always be used by making
048 * the following sequence of method invocations, hereinafter referred to as $a$
049 * <i>$coding$ operation</i>:
050 *
051 * <ol>
052 *
053 *   <li><p> Reset the $coder$ via the {@link #reset reset} method, unless it
054 *   has not been used before; </p></li>
055 *
056 *   <li><p> Invoke the {@link #$code$ $code$} method zero or more times, as
057 *   long as additional input may be available, passing <tt>false</tt> for the
058 *   <tt>endOfInput</tt> argument and filling the input buffer and flushing the
059 *   output buffer between invocations; </p></li>
060 *
061 *   <li><p> Invoke the {@link #$code$ $code$} method one final time, passing
062 *   <tt>true</tt> for the <tt>endOfInput</tt> argument; and then </p></li>
063 *
064 *   <li><p> Invoke the {@link #flush flush} method so that the $coder$ can
065 *   flush any internal state to the output buffer. </p></li>
066 *
067 * </ol>
068 *
069 * Each invocation of the {@link #$code$ $code$} method will $code$ as many
070 * $itype$s as possible from the input buffer, writing the resulting $otype$s
071 * to the output buffer.  The {@link #$code$ $code$} method returns when more
072 * input is required, when there is not enough room in the output buffer, or
073 * when $a$ $coding$ error has occurred.  In each case a {@link CoderResult}
074 * object is returned to describe the reason for termination.  An invoker can
075 * examine this object and fill the input buffer, flush the output buffer, or
076 * attempt to recover from $a$ $coding$ error, as appropriate, and try again.
077 *
078 * <a name="ce">
079 *
080 * <p> There are two general types of $coding$ errors.  If the input $itype$
081 * sequence is $notLegal$ then the input is considered <i>malformed</i>.  If
082 * the input $itype$ sequence is legal but cannot be mapped to a valid
083 * $outSequence$ then an <i>unmappable character</i> has been encountered.
084 *
085 * <a name="cae">
086 *
087 * <p> How $a$ $coding$ error is handled depends upon the action requested for
088 * that type of error, which is described by an instance of the {@link
089 * CodingErrorAction} class.  The possible error actions are to {@link
090 * CodingErrorAction#IGNORE </code>ignore<code>} the erroneous input, {@link
091 * CodingErrorAction#REPORT </code>report<code>} the error to the invoker via
092 * the returned {@link CoderResult} object, or {@link CodingErrorAction#REPLACE
093 * </code>replace<code>} the erroneous input with the current value of the
094 * replacement $replTypeName$.  The replacement
095 *
096#if[encoder]
097 * is initially set to the $coder$'s default replacement, which often
098 * (but not always) has the initial value&nbsp;$defaultReplName$;
099#end[encoder]
100#if[decoder]
101 * has the initial value $defaultReplName$;
102#end[decoder]
103 *
104 * its value may be changed via the {@link #replaceWith($replFQType$)
105 * replaceWith} method.
106 *
107 * <p> The default action for malformed-input and unmappable-character errors
108 * is to {@link CodingErrorAction#REPORT </code>report<code>} them.  The
109 * malformed-input error action may be changed via the {@link
110 * #onMalformedInput(CodingErrorAction) onMalformedInput} method; the
111 * unmappable-character action may be changed via the {@link
112 * #onUnmappableCharacter(CodingErrorAction) onUnmappableCharacter} method.
113 *
114 * <p> This class is designed to handle many of the details of the $coding$
115 * process, including the implementation of error actions.  $A$ $coder$ for a
116 * specific charset, which is a concrete subclass of this class, need only
117 * implement the abstract {@link #$code$Loop $code$Loop} method, which
118 * encapsulates the basic $coding$ loop.  A subclass that maintains internal
119 * state should, additionally, override the {@link #implFlush implFlush} and
120 * {@link #implReset implReset} methods.
121 *
122 * <p> Instances of this class are not safe for use by multiple concurrent
123 * threads.  </p>
124 *
125 *
126 * @version 1.52, 07/05/05
127 * @author Mark Reinhold
128 * @author JSR-51 Expert Group
129 * @since 1.4
130 *
131 * @see ByteBuffer
132 * @see CharBuffer
133 * @see Charset
134 * @see Charset$OtherCoder$
135 */
136
137public abstract class Charset$Coder$ {
138
139    private final Charset charset;
140    private final float average$ItypesPerOtype$;
141    private final float max$ItypesPerOtype$;
142
143    private $replType$ replacement;
144    private CodingErrorAction malformedInputAction
145	= CodingErrorAction.REPORT;
146    private CodingErrorAction unmappableCharacterAction
147	= CodingErrorAction.REPORT;
148
149    // Internal states
150    //
151    private static final int ST_RESET   = 0;
152    private static final int ST_CODING  = 1;
153    private static final int ST_END     = 2;
154    private static final int ST_FLUSHED = 3;
155
156    private int state = ST_RESET;
157
158    private static String stateNames[]
159	= { "RESET", "CODING", "CODING_END", "FLUSHED" };
160
161
162    /**
163     * Initializes a new $coder$.  The new $coder$ will have the given
164     * $otypes-per-itype$ and replacement values. </p>
165     *
166     * @param  average$ItypesPerOtype$
167     *         A positive float value indicating the expected number of
168     *         $otype$s that will be produced for each input $itype$
169     *
170     * @param  max$ItypesPerOtype$
171     *         A positive float value indicating the maximum number of
172     *         $otype$s that will be produced for each input $itype$
173     *
174     * @param  replacement
175     *         The initial replacement; must not be <tt>null</tt>, must have
176     *         non-zero length, must not be longer than max$ItypesPerOtype$,
177     *         and must be {@link #isLegalReplacement </code>legal<code>}
178     *
179     * @throws  IllegalArgumentException
180     *          If the preconditions on the parameters do not hold
181     */
182    {#if[encoder]?protected:private}
183    Charset$Coder$(Charset cs,
184		   float average$ItypesPerOtype$,
185		   float max$ItypesPerOtype$,
186		   $replType$ replacement)
187    {
188	this .charset = cs;
189	if (average$ItypesPerOtype$ <= 0.0f)
190	    throw new IllegalArgumentException("Non-positive "
191					       + "average$ItypesPerOtype$");
192	if (max$ItypesPerOtype$ <= 0.0f)
193	    throw new IllegalArgumentException("Non-positive "
194					       + "max$ItypesPerOtype$");
195	if (!Charset.atBugLevel("1.4")) {
196	    if (average$ItypesPerOtype$ > max$ItypesPerOtype$)
197		throw new IllegalArgumentException("average$ItypesPerOtype$"
198						   + " exceeds "
199						   + "max$ItypesPerOtype$");
200	}
201	this .replacement = replacement;
202	this .average$ItypesPerOtype$ = average$ItypesPerOtype$;
203	this .max$ItypesPerOtype$ = max$ItypesPerOtype$;
204	replaceWith(replacement);
205    }
206
207    /**
208     * Initializes a new $coder$.  The new $coder$ will have the given
209     * $otypes-per-itype$ values and its replacement will be the
210     * $replTypeName$ $defaultReplName$. </p>
211     *
212     * @param  average$ItypesPerOtype$
213     *         A positive float value indicating the expected number of
214     *         $otype$s that will be produced for each input $itype$
215     *
216     * @param  max$ItypesPerOtype$
217     *         A positive float value indicating the maximum number of
218     *         $otype$s that will be produced for each input $itype$
219     *
220     * @throws  IllegalArgumentException
221     *          If the preconditions on the parameters do not hold
222     */
223    protected Charset$Coder$(Charset cs,
224			     float average$ItypesPerOtype$,
225			     float max$ItypesPerOtype$)
226    {
227	this (cs,
228	     average$ItypesPerOtype$, max$ItypesPerOtype$,
229	     $defaultRepl$);
230    }
231
232    /**
233     * Returns the charset that created this $coder$.  </p>
234     *
235     * @return  This $coder$'s charset
236     */
237    public final Charset charset() {
238	return charset;
239    }
240
241    /**
242     * Returns this $coder$'s replacement value. </p>
243     *
244     * @return  This $coder$'s current replacement,
245     *          which is never <tt>null</tt> and is never empty
246     */
247    public final $replType$ replacement() {
248	return replacement;
249    }
250
251    /**
252     * Changes this $coder$'s replacement value.
253     *
254     * <p> This method invokes the {@link #implReplaceWith implReplaceWith}
255     * method, passing the new replacement, after checking that the new
256     * replacement is acceptable.  </p>
257     *
258     * @param  newReplacement
259     *
260#if[decoder]
261     *         The new replacement; must not be <tt>null</tt>
262     *         and must have non-zero length
263#end[decoder]
264#if[encoder]
265     *         The new replacement; must not be <tt>null</tt>, must have
266     *         non-zero length, must not be longer than the value returned by
267     *         the {@link #max$ItypesPerOtype$() max$ItypesPerOtype$} method, and
268     *         must be {@link #isLegalReplacement </code>legal<code>}
269#end[encoder]
270     *
271     * @return  This $coder$
272     *
273     * @throws  IllegalArgumentException
274     *          If the preconditions on the parameter do not hold
275     */
276    public final Charset$Coder$ replaceWith($replType$ newReplacement) {
277	if (newReplacement == null)
278	    throw new IllegalArgumentException("Null replacement");
279	int len = newReplacement.$replLength$;
280	if (len == 0)
281	    throw new IllegalArgumentException("Empty replacement");
282	if (len > max$ItypesPerOtype$)
283	    throw new IllegalArgumentException("Replacement too long");
284#if[encoder]
285	if (!isLegalReplacement(newReplacement))
286	    throw new IllegalArgumentException("Illegal replacement");
287#end[encoder]
288	this .replacement = newReplacement;
289	implReplaceWith(newReplacement);
290	return this ;
291    }
292
293    /**
294     * Reports a change to this $coder$'s replacement value.
295     *
296     * <p> The default implementation of this method does nothing.  This method
297     * should be overridden by $coder$s that require notification of changes to
298     * the replacement.  </p>
299     *
300     * @param  newReplacement
301     */
302    protected void implReplaceWith($replType$ newReplacement) {
303    }
304
305#if[encoder]
306
307    private WeakReference cachedDecoder = null;
308
309    /**
310     * Tells whether or not the given byte array is a legal replacement value
311     * for this encoder.
312     *
313     * <p> A replacement is legal if, and only if, it is a legal sequence of
314     * bytes in this encoder's charset; that is, it must be possible to decode
315     * the replacement into one or more sixteen-bit Unicode characters.
316     *
317     * <p> The default implementation of this method is not very efficient; it
318     * should generally be overridden to improve performance.  </p>
319     *
320     * @param  repl  The byte array to be tested
321     *
322     * @return  <tt>true</tt> if, and only if, the given byte array
323     *          is a legal replacement value for this encoder
324     */
325    public boolean isLegalReplacement(byte[] repl) {
326	WeakReference wr = cachedDecoder;
327	CharsetDecoder dec = null;
328	if ((wr == null) || ((dec = (CharsetDecoder)wr.get()) == null)) {
329	    dec = charset().newDecoder();
330	    dec.onMalformedInput(CodingErrorAction.REPORT);
331	    dec.onUnmappableCharacter(CodingErrorAction.REPORT);
332	    cachedDecoder = new WeakReference(dec);
333	} else {
334	    dec.reset();
335	}
336	ByteBuffer bb = ByteBuffer.wrap(repl);
337	CharBuffer cb = CharBuffer.allocate((int)(bb.remaining()
338						  * dec.maxCharsPerByte()));
339	CoderResult cr = dec.decode(bb, cb, true);
340	return !cr.isError();
341    }
342
343#end[encoder]
344
345    /**
346     * Returns this $coder$'s current action for malformed-input errors.  </p>
347     *
348     * @return The current malformed-input action, which is never <tt>null</tt>
349     */
350    public CodingErrorAction malformedInputAction() {
351	return malformedInputAction;
352    }
353
354    /**
355     * Changes this $coder$'s action for malformed-input errors.  </p>
356     *
357     * <p> This method invokes the {@link #implOnMalformedInput
358     * implOnMalformedInput} method, passing the new action.  </p>
359     *
360     * @param  newAction  The new action; must not be <tt>null</tt>
361     *
362     * @return  This $coder$
363     *
364     * @throws IllegalArgumentException
365     *         If the precondition on the parameter does not hold
366     */
367    public final Charset$Coder$ onMalformedInput(CodingErrorAction newAction) {
368	if (newAction == null)
369	    throw new IllegalArgumentException("Null action");
370	malformedInputAction = newAction;
371	implOnMalformedInput(newAction);
372	return this ;
373    }
374
375    /**
376     * Reports a change to this $coder$'s malformed-input action.
377     *
378     * <p> The default implementation of this method does nothing.  This method
379     * should be overridden by $coder$s that require notification of changes to
380     * the malformed-input action.  </p>
381     */
382    protected void implOnMalformedInput(CodingErrorAction newAction) { }
383
384    /**
385     * Returns this $coder$'s current action for unmappable-character errors.
386     * </p>
387     *
388     * @return The current unmappable-character action, which is never
389     *         <tt>null</tt>
390     */
391    public CodingErrorAction unmappableCharacterAction() {
392	return unmappableCharacterAction;
393    }
394
395    /**
396     * Changes this $coder$'s action for unmappable-character errors.
397     *
398     * <p> This method invokes the {@link #implOnUnmappableCharacter
399     * implOnUnmappableCharacter} method, passing the new action.  </p>
400     *
401     * @param  newAction  The new action; must not be <tt>null</tt>
402     *
403     * @return  This $coder$
404     *
405     * @throws IllegalArgumentException
406     *         If the precondition on the parameter does not hold
407     */
408    public final Charset$Coder$ onUnmappableCharacter(CodingErrorAction
409						      newAction)
410    {
411	if (newAction == null)
412	    throw new IllegalArgumentException("Null action");
413	unmappableCharacterAction = newAction;
414	implOnUnmappableCharacter(newAction);
415	return this ;
416    }
417
418    /**
419     * Reports a change to this $coder$'s unmappable-character action.
420     *
421     * <p> The default implementation of this method does nothing.  This method
422     * should be overridden by $coder$s that require notification of changes to
423     * the unmappable-character action.  </p>
424     */
425    protected void implOnUnmappableCharacter(CodingErrorAction newAction) { }
426
427    /**
428     * Returns the average number of $otype$s that will be produced for each
429     * $itype$ of input.  This heuristic value may be used to estimate the size
430     * of the output buffer required for a given input sequence. </p>
431     *
432     * @return  The average number of $otype$s produced
433     *          per $itype$ of input
434     */
435    public final float average$ItypesPerOtype$() {
436	return average$ItypesPerOtype$;
437    }
438
439    /**
440     * Returns the maximum number of $otype$s that will be produced for each
441     * $itype$ of input.  This value may be used to compute the worst-case size
442     * of the output buffer required for a given input sequence. </p>
443     *
444     * @return  The maximum number of $otype$s that will be produced per
445     *          $itype$ of input
446     */
447    public final float max$ItypesPerOtype$() {
448	return max$ItypesPerOtype$;
449    }
450
451    /**
452     * $Code$s as many $itype$s as possible from the given input buffer,
453     * writing the results to the given output buffer.
454     *
455     * <p> The buffers are read from, and written to, starting at their current
456     * positions.  At most {@link Buffer#remaining in.remaining()} $itype$s
457     * will be read and at most {@link Buffer#remaining out.remaining()}
458     * $otype$s will be written.  The buffers' positions will be advanced to
459     * reflect the $itype$s read and the $otype$s written, but their marks and
460     * limits will not be modified.
461     *
462     * <p> In addition to reading $itype$s from the input buffer and writing
463     * $otype$s to the output buffer, this method returns a {@link CoderResult}
464     * object to describe its reason for termination:
465     *
466     * <ul>
467     *
468     *   <li><p> {@link CoderResult#UNDERFLOW} indicates that as much of the
469     *   input buffer as possible has been $code$d.  If there is no further
470     *   input then the invoker can proceed to the next step of the
471     *   <a href="#steps">$coding$ operation</a>.  Otherwise this method
472     *   should be invoked again with further input.  </p></li>
473     *
474     *   <li><p> {@link CoderResult#OVERFLOW} indicates that there is
475     *   insufficient space in the output buffer to $code$ any more $itype$s.
476     *   This method should be invoked again with an output buffer that has
477     *   more {@linkplain Buffer#remaining remaining} $otype$s. This is
478     *   typically done by draining any $code$d $otype$s from the output
479     *   buffer.  </p></li>
480     *
481     *   <li><p> A {@link CoderResult#malformedForLength
482     *   </code>malformed-input<code>} result indicates that a malformed-input
483     *   error has been detected.  The malformed $itype$s begin at the input
484     *   buffer's (possibly incremented) position; the number of malformed
485     *   $itype$s may be determined by invoking the result object's {@link
486     *   CoderResult#length() length} method.  This case applies only if the
487     *   {@link #onMalformedInput </code>malformed action<code>} of this $coder$
488     *   is {@link CodingErrorAction#REPORT}; otherwise the malformed input
489     *   will be ignored or replaced, as requested.  </p></li>
490     *
491     *   <li><p> An {@link CoderResult#unmappableForLength
492     *   </code>unmappable-character<code>} result indicates that an
493     *   unmappable-character error has been detected.  The $itype$s that
494     *   $code$ the unmappable character begin at the input buffer's (possibly
495     *   incremented) position; the number of such $itype$s may be determined
496     *   by invoking the result object's {@link CoderResult#length() length}
497     *   method.  This case applies only if the {@link #onUnmappableCharacter
498     *   </code>unmappable action<code>} of this $coder$ is {@link
499     *   CodingErrorAction#REPORT}; otherwise the unmappable character will be
500     *   ignored or replaced, as requested.  </p></li>
501     *
502     * </ul>
503     *
504     * In any case, if this method is to be reinvoked in the same $coding$
505     * operation then care should be taken to preserve any $itype$s remaining
506     * in the input buffer so that they are available to the next invocation.
507     *
508     * <p> The <tt>endOfInput</tt> parameter advises this method as to whether
509     * the invoker can provide further input beyond that contained in the given
510     * input buffer.  If there is a possibility of providing additional input
511     * then the invoker should pass <tt>false</tt> for this parameter; if there
512     * is no possibility of providing further input then the invoker should
513     * pass <tt>true</tt>.  It is not erroneous, and in fact it is quite
514     * common, to pass <tt>false</tt> in one invocation and later discover that
515     * no further input was actually available.  It is critical, however, that
516     * the final invocation of this method in a sequence of invocations always
517     * pass <tt>true</tt> so that any remaining un$code$d input will be treated
518     * as being malformed.
519     *
520     * <p> This method works by invoking the {@link #$code$Loop $code$Loop}
521     * method, interpreting its results, handling error conditions, and
522     * reinvoking it as necessary.  </p>
523     *
524     *
525     * @param  in
526     *         The input $itype$ buffer
527     *
528     * @param  out
529     *         The output $otype$ buffer
530     *
531     * @param  endOfInput
532     *         <tt>true</tt> if, and only if, the invoker can provide no
533     *         additional input $itype$s beyond those in the given buffer
534     *
535     * @return  A coder-result object describing the reason for termination
536     *
537     * @throws  IllegalStateException
538     *          If $a$ $coding$ operation is already in progress and the previous
539     *          step was an invocation neither of the {@link #reset reset}
540     *          method, nor of this method with a value of <tt>false</tt> for
541     *          the <tt>endOfInput</tt> parameter, nor of this method with a
542     *          value of <tt>true</tt> for the <tt>endOfInput</tt> parameter
543     *          but a return value indicating an incomplete $coding$ operation
544     *
545     * @throws  CoderMalfunctionError
546     *          If an invocation of the $code$Loop method threw
547     *          an unexpected exception
548     */
549    public final CoderResult $code$($Itype$Buffer in, $Otype$Buffer out,
550				    boolean endOfInput)
551    {
552	int newState = endOfInput ? ST_END : ST_CODING;
553	if ((state != ST_RESET) && (state != ST_CODING)
554	    && !(endOfInput && (state == ST_END)))
555	    throwIllegalStateException(state, newState);
556	state = newState;
557
558	for (;;) {
559
560	    CoderResult cr;
561	    try {
562		cr = $code$Loop(in, out);
563	    } catch (BufferUnderflowException x) {
564		throw new CoderMalfunctionError(x);
565	    } catch (BufferOverflowException x) {
566		throw new CoderMalfunctionError(x);
567	    }
568
569	    if (cr.isOverflow())
570		return cr;
571
572	    if (cr.isUnderflow()) {
573		if (endOfInput && in.hasRemaining()) {
574		    cr = CoderResult.malformedForLength(in.remaining());
575		    // Fall through to malformed-input case
576		} else {
577		    return cr;
578		}
579	    }
580
581	    CodingErrorAction action = null;
582	    if (cr.isMalformed())
583		action = malformedInputAction;
584	    else if (cr.isUnmappable())
585		action = unmappableCharacterAction;
586	    else
587		assert false : cr.toString();
588
589	    if (action == CodingErrorAction.REPORT)
590		return cr;
591
592	    if (action == CodingErrorAction.REPLACE) {
593		if (out.remaining() < replacement.$replLength$)
594		    return CoderResult.OVERFLOW;
595		out.put(replacement);
596	    }
597
598	    if ((action == CodingErrorAction.IGNORE)
599		|| (action == CodingErrorAction.REPLACE)) {
600		// Skip erroneous input either way
601		in.position(in.position() + cr.length());
602		continue;
603	    }
604
605	    assert false;
606	}
607
608    }
609
610    /**
611     * Flushes this $coder$.
612     *
613     * <p> Some $coder$s maintain internal state and may need to write some
614     * final $otype$s to the output buffer once the overall input sequence has
615     * been read.
616     *
617     * <p> Any additional output is written to the output buffer beginning at
618     * its current position.  At most {@link Buffer#remaining out.remaining()}
619     * $otype$s will be written.  The buffer's position will be advanced
620     * appropriately, but its mark and limit will not be modified.
621     *
622     * <p> If this method completes successfully then it returns {@link
623     * CoderResult#UNDERFLOW}.  If there is insufficient room in the output
624     * buffer then it returns {@link CoderResult#OVERFLOW}.  If this happens
625     * then this method must be invoked again, with an output buffer that has
626     * more room, in order to complete the current <a href="#steps">$coding$
627     * operation</a>.
628     *
629     * <p> If this $coder$ has already been flushed then invoking this method
630     * has no effect.
631     *
632     * <p> This method invokes the {@link #implFlush implFlush} method to
633     * perform the actual flushing operation.  </p>
634     *
635     * @param  out
636     *         The output $otype$ buffer
637     *
638     * @return  A coder-result object, either {@link CoderResult#UNDERFLOW} or
639     *          {@link CoderResult#OVERFLOW}
640     *
641     * @throws  IllegalStateException
642     *          If the previous step of the current $coding$ operation was an
643     *          invocation neither of the {@link #flush flush} method nor of
644     *          the three-argument {@link
645     *          #$code$($Itype$Buffer,$Otype$Buffer,boolean) $code$} method
646     *          with a value of <tt>true</tt> for the <tt>endOfInput</tt>
647     *          parameter
648     */
649    public final CoderResult flush($Otype$Buffer out) {
650	if (state == ST_END) {
651	    CoderResult cr = implFlush(out);
652	    if (cr.isUnderflow())
653		state = ST_FLUSHED;
654	    return cr;
655	}
656
657	if (state != ST_FLUSHED)
658	    throwIllegalStateException(state, ST_FLUSHED);
659
660	return CoderResult.UNDERFLOW; // Already flushed
661    }
662
663    /**
664     * Flushes this $coder$.
665     *
666     * <p> The default implementation of this method does nothing, and always
667     * returns {@link CoderResult#UNDERFLOW}.  This method should be overridden
668     * by $coder$s that may need to write final $otype$s to the output buffer
669     * once the entire input sequence has been read. </p>
670     *
671     * @param  out
672     *         The output $otype$ buffer
673     *
674     * @return  A coder-result object, either {@link CoderResult#UNDERFLOW} or
675     *          {@link CoderResult#OVERFLOW}
676     */
677    protected CoderResult implFlush($Otype$Buffer out) {
678	return CoderResult.UNDERFLOW;
679    }
680
681    /**
682     * Resets this $coder$, clearing any internal state.
683     *
684     * <p> This method resets charset-independent state and also invokes the
685     * {@link #implReset() implReset} method in order to perform any
686     * charset-specific reset actions.  </p>
687     *
688     * @return  This $coder$
689     *
690     */
691    public final Charset$Coder$ reset() {
692	implReset();
693	state = ST_RESET;
694	return this ;
695    }
696
697    /**
698     * Resets this $coder$, clearing any charset-specific internal state.
699     *
700     * <p> The default implementation of this method does nothing.  This method
701     * should be overridden by $coder$s that maintain internal state.  </p>
702     */
703    protected void implReset() { }
704
705    /**
706     * $Code$s one or more $itype$s into one or more $otype$s.
707     *
708     * <p> This method encapsulates the basic $coding$ loop, $coding$ as many
709     * $itype$s as possible until it either runs out of input, runs out of room
710     * in the output buffer, or encounters $a$ $coding$ error.  This method is
711     * invoked by the {@link #$code$ $code$} method, which handles result
712     * interpretation and error recovery.
713     *
714     * <p> The buffers are read from, and written to, starting at their current
715     * positions.  At most {@link Buffer#remaining in.remaining()} $itype$s
716     * will be read, and at most {@link Buffer#remaining out.remaining()}
717     * $otype$s will be written.  The buffers' positions will be advanced to
718     * reflect the $itype$s read and the $otype$s written, but their marks and
719     * limits will not be modified.
720     *
721     * <p> This method returns a {@link CoderResult} object to describe its
722     * reason for termination, in the same manner as the {@link #$code$ $code$}
723     * method.  Most implementations of this method will handle $coding$ errors
724     * by returning an appropriate result object for interpretation by the
725     * {@link #$code$ $code$} method.  An optimized implementation may instead
726     * examine the relevant error action and implement that action itself.
727     *
728     * <p> An implementation of this method may perform arbitrary lookahead by
729     * returning {@link CoderResult#UNDERFLOW} until it receives sufficient
730     * input.  </p>
731     *
732     * @param  in
733     *         The input $itype$ buffer
734     *
735     * @param  out
736     *         The output $otype$ buffer
737     *
738     * @return  A coder-result object describing the reason for termination
739     */
740    protected abstract CoderResult $code$Loop($Itype$Buffer in,
741					      $Otype$Buffer out);
742
743    /**
744     * Convenience method that $code$s the remaining content of a single input
745     * $itype$ buffer into a newly-allocated $otype$ buffer.
746     *
747     * <p> This method implements an entire <a href="#steps">$coding$
748     * operation</a>; that is, it resets this $coder$, then it $code$s the
749     * $itype$s in the given $itype$ buffer, and finally it flushes this
750     * $coder$.  This method should therefore not be invoked if $a$ $coding$
751     * operation is already in progress.  </p>
752     *
753     * @param  in
754     *         The input $itype$ buffer
755     *
756     * @return A newly-allocated $otype$ buffer containing the result of the
757     *         $coding$ operation.  The buffer's position will be zero and its
758     *         limit will follow the last $otype$ written.
759     *
760     * @throws  IllegalStateException
761     *          If $a$ $coding$ operation is already in progress
762     *
763     * @throws  MalformedInputException
764     *          If the $itype$ sequence starting at the input buffer's current
765     *          position is $notLegal$ and the current malformed-input action
766     *          is {@link CodingErrorAction#REPORT}
767     *
768     * @throws  UnmappableCharacterException
769     *          If the $itype$ sequence starting at the input buffer's current
770     *          position cannot be mapped to an equivalent $otype$ sequence and
771     *          the current unmappable-character action is {@link
772     *          CodingErrorAction#REPORT}
773     */
774    public final $Otype$Buffer $code$($Itype$Buffer in)
775	throws CharacterCodingException
776    {
777	int n = (int)(in.remaining() * average$ItypesPerOtype$());
778	$Otype$Buffer out = $Otype$Buffer.allocate(n);
779
780	if ((n == 0) && (in.remaining() == 0))
781	    return out;
782	reset();
783	for (;;) {
784	    CoderResult cr = in.hasRemaining() ?
785		$code$(in, out, true) : CoderResult.UNDERFLOW;
786	    if (cr.isUnderflow())
787		cr = flush(out);
788
789	    if (cr.isUnderflow())
790		break;
791	    if (cr.isOverflow()) {
792		n = 2*n + 1;	// Ensure progress; n might be 0!
793		$Otype$Buffer o = $Otype$Buffer.allocate(n);
794		out.flip();
795		o.put(out);
796		out = o;
797		continue;
798	    }
799	    cr.throwException();
800	}
801	out.flip();
802	return out;
803    }
804
805#if[decoder]
806
807    /**
808     * Tells whether or not this decoder implements an auto-detecting charset.
809     *
810     * <p> The default implementation of this method always returns
811     * <tt>false</tt>; it should be overridden by auto-detecting decoders to
812     * return <tt>true</tt>.  </p>
813     *
814     * @return  <tt>true</tt> if, and only if, this decoder implements an
815     *          auto-detecting charset
816     */
817    public boolean isAutoDetecting() {
818	return false;
819    }
820
821    /**
822     * Tells whether or not this decoder has yet detected a
823     * charset&nbsp;&nbsp;<i>(optional operation)</i>.
824     *
825     * <p> If this decoder implements an auto-detecting charset then at a
826     * single point during a decoding operation this method may start returning
827     * <tt>true</tt> to indicate that a specific charset has been detected in
828     * the input byte sequence.  Once this occurs, the {@link #detectedCharset
829     * detectedCharset} method may be invoked to retrieve the detected charset.
830     *
831     * <p> That this method returns <tt>false</tt> does not imply that no bytes
832     * have yet been decoded.  Some auto-detecting decoders are capable of
833     * decoding some, or even all, of an input byte sequence without fixing on
834     * a particular charset.
835     *
836     * <p> The default implementation of this method always throws an {@link
837     * UnsupportedOperationException}; it should be overridden by
838     * auto-detecting decoders to return <tt>true</tt> once the input charset
839     * has been determined.  </p>
840     *
841     * @return  <tt>true</tt> if, and only if, this decoder has detected a
842     *          specific charset
843     *
844     * @throws  UnsupportedOperationException
845     *          If this decoder does not implement an auto-detecting charset
846     */
847    public boolean isCharsetDetected() {
848	throw new UnsupportedOperationException();
849    }
850
851    /**
852     * Retrieves the charset that was detected by this
853     * decoder&nbsp;&nbsp;<i>(optional operation)</i>.
854     *
855     * <p> If this decoder implements an auto-detecting charset then this
856     * method returns the actual charset once it has been detected.  After that
857     * point, this method returns the same value for the duration of the
858     * current decoding operation.  If not enough input bytes have yet been
859     * read to determine the actual charset then this method throws an {@link
860     * IllegalStateException}.
861     *
862     * <p> The default implementation of this method always throws an {@link
863     * UnsupportedOperationException}; it should be overridden by
864     * auto-detecting decoders to return the appropriate value.  </p>
865     *
866     * @return  The charset detected by this auto-detecting decoder,
867     *          or <tt>null</tt> if the charset has not yet been determined
868     *
869     * @throws  IllegalStateException
870     *          If insufficient bytes have been read to determine a charset
871     *
872     * @throws  UnsupportedOperationException
873     *          If this decoder does not implement an auto-detecting charset
874     */
875    public Charset detectedCharset() {
876	throw new UnsupportedOperationException();
877    }
878
879#end[decoder]
880
881#if[encoder]
882
883    private boolean canEncode(CharBuffer cb) {
884	if (state == ST_FLUSHED)
885	    reset();
886	else if (state != ST_RESET)
887	    throwIllegalStateException(state, ST_CODING);
888	CodingErrorAction ma = malformedInputAction();
889	CodingErrorAction ua = unmappableCharacterAction();
890	try {
891	    onMalformedInput(CodingErrorAction.REPORT);
892	    onUnmappableCharacter(CodingErrorAction.REPORT);
893	    encode(cb);
894	} catch (CharacterCodingException x) {
895	    return false;
896	} finally {
897	    onMalformedInput(ma);
898	    onUnmappableCharacter(ua);
899	    reset();
900	}
901	return true;
902    }
903
904    /**
905     * Tells whether or not this encoder can encode the given character.
906     *
907     * <p> This method returns <tt>false</tt> if the given character is a
908     * surrogate character; such characters can be interpreted only when they
909     * are members of a pair consisting of a high surrogate followed by a low
910     * surrogate.  The {@link #canEncode(java.lang.CharSequence)
911     * canEncode(CharSequence)} method may be used to test whether or not a
912     * character sequence can be encoded.
913     *
914     * <p> This method may modify this encoder's state; it should therefore not
915     * be invoked if an <a href="#steps">encoding operation</a> is already in
916     * progress.
917     *
918     * <p> The default implementation of this method is not very efficient; it
919     * should generally be overridden to improve performance.  </p>
920     *
921     * @return  <tt>true</tt> if, and only if, this encoder can encode
922     *          the given character
923     *
924     * @throws  IllegalStateException
925     *          If $a$ $coding$ operation is already in progress
926     */
927    public boolean canEncode(char c) {
928	CharBuffer cb = CharBuffer.allocate(1);
929	cb.put(c);
930	cb.flip();
931	return canEncode(cb);
932    }
933
934    /**
935     * Tells whether or not this encoder can encode the given character
936     * sequence.
937     *
938     * <p> If this method returns <tt>false</tt> for a particular character
939     * sequence then more information about why the sequence cannot be encoded
940     * may be obtained by performing a full <a href="#steps">encoding
941     * operation</a>.
942     *
943     * <p> This method may modify this encoder's state; it should therefore not
944     * be invoked if an encoding operation is already in progress.
945     *
946     * <p> The default implementation of this method is not very efficient; it
947     * should generally be overridden to improve performance.  </p>
948     *
949     * @return  <tt>true</tt> if, and only if, this encoder can encode
950     *          the given character without throwing any exceptions and without
951     *          performing any replacements
952     *
953     * @throws  IllegalStateException
954     *          If $a$ $coding$ operation is already in progress
955     */
956    public boolean canEncode(CharSequence cs) {
957	CharBuffer cb;
958	if (cs instanceof  CharBuffer)
959	    cb = ((CharBuffer)cs).duplicate();
960	else
961	    cb = CharBuffer.wrap(cs.toString());
962	return canEncode(cb);
963    }
964
965#end[encoder]
966
967
968    private void throwIllegalStateException(int from, int to) {
969	throw new IllegalStateException("Current state = " + stateNames[from]
970					+ ", new state = " + stateNames[to]);
971    }
972
973}
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.