Source Code Cross Referenced for CharsetDecoder.java in  » Apache-Harmony-Java-SE » java-package » java » nio » charset » Java Source Code / Java DocumentationJava Source Code and Java Documentation

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 geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Apache Harmony Java SE » java package » java.nio.charset 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* Licensed to the Apache Software Foundation (ASF) under one or more
002:         * contributor license agreements.  See the NOTICE file distributed with
003:         * this work for additional information regarding copyright ownership.
004:         * The ASF licenses this file to You under the Apache License, Version 2.0
005:         * (the "License"); you may not use this file except in compliance with
006:         * the License.  You may obtain a copy of the License at
007:         * 
008:         *     http://www.apache.org/licenses/LICENSE-2.0
009:         * 
010:         * Unless required by applicable law or agreed to in writing, software
011:         * distributed under the License is distributed on an "AS IS" BASIS,
012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013:         * See the License for the specific language governing permissions and
014:         * limitations under the License.
015:         */
016:
017:        package java.nio.charset;
018:
019:        import java.nio.BufferOverflowException;
020:        import java.nio.BufferUnderflowException;
021:        import java.nio.ByteBuffer;
022:        import java.nio.CharBuffer;
023:
024:        import org.apache.harmony.niochar.internal.nls.Messages;
025:
026:        /**
027:         * An converter that can convert bytes sequence in some charset to 16-bit
028:         * Unicode character sequence.
029:         * <p>
030:         * The input byte sequence is wrapped by {@link java.nio.ByteBuffer ByteBuffer}
031:         * and the output character sequence is {@link java.nio.CharBuffer CharBuffer}.
032:         * A decoder instance should be used in following sequence, which is referred to
033:         * as a decoding operation:
034:         * <ol>
035:         * <li>Invoking the {@link #reset() reset} method to reset the decoder if the
036:         * decoder has been used;</li>
037:         * <li>Invoking the {@link #decode(ByteBuffer, CharBuffer, boolean) decode}
038:         * method until the additional input is not needed, the <code>endOfInput</code>
039:         * parameter must be set to false, the input buffer must be filled and the
040:         * output buffer must be flushed between invocations;</li>
041:         * <li>Invoking the {@link #decode(ByteBuffer, CharBuffer, boolean) decode}
042:         * method last time, and the the <code>endOfInput</code> parameter must be set
043:         * to true</li>
044:         * <li>Invoking the {@link #flush(CharBuffer) flush} method to flush the
045:         * output.</li>
046:         * </ol>
047:         * </p>
048:         * <p>
049:         * The {@link #decode(ByteBuffer, CharBuffer, boolean) decode} method will
050:         * convert as many bytes as possible, and the process won't stop except the
051:         * input bytes has been run out of, the output buffer has been filled or some
052:         * error has happened. A {@link CoderResult CoderResult} instance will be
053:         * returned to indicate the stop reason, and the invoker can identify the result
054:         * and choose further action, which can include filling the input buffer,
055:         * flushing the output buffer, recovering from error and trying again.
056:         * </p>
057:         * <p>
058:         * There are two common decoding errors. One is named as malformed and it is
059:         * returned when the input byte sequence is illegal for current specific
060:         * charset, the other is named as unmappable character and it is returned when a
061:         * problem occurs mapping a legal input byte sequence to its Unicode character
062:         * equivalent.
063:         * </p>
064:         * <p>
065:         * The two errors can be handled in three ways, the default one is to report the
066:         * error to the invoker by a {@link CoderResult CoderResult} instance, and the
067:         * alternatives are to ignore it or to replace the erroneous input with the
068:         * replacement string. The replacement string is "&#92;uFFFD" by default and can be
069:         * changed by invoking {@link #replaceWith(String) replaceWith} method. The
070:         * invoker of this decoder can choose one way by specifying a
071:         * {@link CodingErrorAction CodingErrorAction} instance for each error type via
072:         * {@link #onMalformedInput(CodingErrorAction) onMalformedInput} method and
073:         * {@link #onUnmappableCharacter(CodingErrorAction) onUnmappableCharacter}
074:         * method.
075:         * </p>
076:         * <p>
077:         * This class is abstract class and encapsulate many common operations of
078:         * decoding process for all charsets. Decoder for specific charset should extend
079:         * this class and need only implement
080:         * {@link #decodeLoop(ByteBuffer, CharBuffer) decodeLoop} method for basic
081:         * decoding loop. If a subclass maintains internal state, it should override the
082:         * {@link #implFlush(CharBuffer) implFlush} method and
083:         * {@link #implReset() implReset} method in addition.
084:         * </p>
085:         * <p>
086:         * This class is not thread-safe.
087:         * </p>
088:         * 
089:         * @see java.nio.charset.Charset
090:         * @see java.nio.charset.CharsetEncoder
091:         */
092:        public abstract class CharsetDecoder {
093:            /*
094:             * --------------------------------------- Consts
095:             * ---------------------------------------
096:             */
097:            /*
098:             * internal status consts
099:             */
100:            private static final int INIT = 0;
101:
102:            private static final int ONGOING = 1;
103:
104:            private static final int END = 2;
105:
106:            private static final int FLUSH = 3;
107:
108:            /*
109:             * --------------------------------------- Instance variables
110:             * ---------------------------------------
111:             */
112:            // average number of chars for one byte
113:            private float averChars;
114:
115:            // maximum number of chars for one byte
116:            private float maxChars;
117:
118:            // charset for this decoder
119:            private Charset cs;
120:
121:            // specify the action if malformed input error encountered
122:            private CodingErrorAction malformAction;
123:
124:            // specify the action if unmappable character error encountered
125:            private CodingErrorAction unmapAction;
126:
127:            // the replacement string
128:            private String replace;
129:
130:            // the current status
131:            private int status;
132:
133:            /*
134:             * --------------------------------------- Constructor
135:             * ---------------------------------------
136:             */
137:            /**
138:             * Construct a new <code>CharsetDecoder</code> using given
139:             * <code>Charset</code>, average number and maximum number of characters
140:             * created by this decoder for one input byte, and the default replacement
141:             * string "&#92;uFFFD".
142:             * 
143:             * @param charset
144:             *            this decoder's <code>Charset</code>, which create this
145:             *            decoder
146:             * @param averageCharsPerByte
147:             *            average number of characters created by this decoder for one
148:             *            input byte, must be positive
149:             * @param maxCharsPerByte
150:             *            maximum number of characters created by this decoder for one
151:             *            input byte, must be positive
152:             * @throws IllegalArgumentException
153:             *             if <code>averageCharsPerByte</code> or
154:             *             <code>maxCharsPerByte</code> is negative
155:             */
156:            protected CharsetDecoder(Charset charset,
157:                    float averageCharsPerByte, float maxCharsPerByte) {
158:                if (averageCharsPerByte <= 0 || maxCharsPerByte <= 0) {
159:                    // niochar.00=Characters number for one byte must be positive.
160:                    throw new IllegalArgumentException(Messages
161:                            .getString("niochar.00")); //$NON-NLS-1$
162:                }
163:                if (averageCharsPerByte > maxCharsPerByte) {
164:                    // niochar.01=averageCharsPerByte is greater than maxCharsPerByte
165:                    throw new IllegalArgumentException(Messages
166:                            .getString("niochar.01")); //$NON-NLS-1$
167:                }
168:                averChars = averageCharsPerByte;
169:                maxChars = maxCharsPerByte;
170:                cs = charset;
171:                status = INIT;
172:                malformAction = CodingErrorAction.REPORT;
173:                unmapAction = CodingErrorAction.REPORT;
174:                replace = "\ufffd"; //$NON-NLS-1$
175:            }
176:
177:            /*
178:             * --------------------------------------- Methods
179:             * ---------------------------------------
180:             */
181:            /**
182:             * get the average number of characters created by this decoder for single
183:             * input byte
184:             * 
185:             * @return the average number of characters created by this decoder for
186:             *         single input byte
187:             */
188:            public final float averageCharsPerByte() {
189:                return averChars;
190:            }
191:
192:            /**
193:             * Get the <code>Charset</code> which creates this decoder.
194:             * 
195:             * @return the <code>Charset</code> which creates this decoder
196:             */
197:            public final Charset charset() {
198:                return cs;
199:            }
200:
201:            /**
202:             * This is a facade method for decoding operation.
203:             * <p>
204:             * This method decodes the remaining byte sequence of the given byte buffer
205:             * into a new character buffer. This method performs a complete decoding
206:             * operation, resets at first, then decodes, and flushes at last.
207:             * </p>
208:             * <p>
209:             * This method should not be invoked if another decode operation is ongoing.
210:             * </p>
211:             * 
212:             * @param in
213:             *            the input buffer
214:             * @return a new <code>CharBuffer</code> containing the the characters
215:             *         produced by this decoding operation. The buffer's limit will be
216:             *         the position of last character in buffer, and the position will
217:             *         be zero
218:             * @throws IllegalStateException
219:             *             if another decoding operation is ongoing
220:             * @throws MalformedInputException
221:             *             if illegal input byte sequence for this charset encountered,
222:             *             and the action for malformed error is
223:             *             {@link CodingErrorAction#REPORT CodingErrorAction.REPORT}
224:             * @throws UnmappableCharacterException
225:             *             if legal but unmappable input byte sequence for this charset
226:             *             encountered, and the action for unmappable character error is
227:             *             {@link CodingErrorAction#REPORT CodingErrorAction.REPORT}.
228:             *             Unmappable means the byte sequence at the input buffer's
229:             *             current position cannot be mapped to a Unicode character
230:             *             sequence.
231:             * @throws CharacterCodingException
232:             *             if other exception happened during the decode operation
233:             */
234:            public final CharBuffer decode(ByteBuffer in)
235:                    throws CharacterCodingException {
236:                reset();
237:                int length = (int) (in.remaining() * averChars);
238:                CharBuffer output = CharBuffer.allocate(length);
239:                CoderResult result = null;
240:                while (true) {
241:                    result = decode(in, output, false);
242:                    checkCoderResult(result);
243:                    if (result.isUnderflow()) {
244:                        break;
245:                    } else if (result.isOverflow()) {
246:                        output = allocateMore(output);
247:                    }
248:                }
249:                result = decode(in, output, true);
250:                checkCoderResult(result);
251:
252:                while (true) {
253:                    result = flush(output);
254:                    checkCoderResult(result);
255:                    if (result.isOverflow()) {
256:                        output = allocateMore(output);
257:                    } else {
258:                        break;
259:                    }
260:                }
261:
262:                output.flip();
263:                status = FLUSH;
264:                return output;
265:            }
266:
267:            /*
268:             * checks the result whether it needs to throw CharacterCodingException.
269:             */
270:            private void checkCoderResult(CoderResult result)
271:                    throws CharacterCodingException {
272:                if (result.isMalformed()
273:                        && malformAction == CodingErrorAction.REPORT) {
274:                    throw new MalformedInputException(result.length());
275:                } else if (result.isUnmappable()
276:                        && unmapAction == CodingErrorAction.REPORT) {
277:                    throw new UnmappableCharacterException(result.length());
278:                }
279:            }
280:
281:            /*
282:             * original output is full and doesn't have remaining. allocate more space
283:             * to new CharBuffer and return it, the contents in the given buffer will be
284:             * copied into the new buffer.
285:             */
286:            private CharBuffer allocateMore(CharBuffer output) {
287:                if (output.capacity() == 0) {
288:                    return CharBuffer.allocate(1);
289:                }
290:                CharBuffer result = CharBuffer.allocate(output.capacity() * 2);
291:                output.flip();
292:                result.put(output);
293:                return result;
294:            }
295:
296:            /**
297:             * Decodes bytes starting at the current position of the given input buffer,
298:             * and writes the equivalent character sequence into the given output buffer
299:             * from its current position.
300:             * <p>
301:             * The buffers' position will be changed with the reading and writing
302:             * operation, but their limits and marks will be kept intact.
303:             * </p>
304:             * <p>
305:             * A <code>CoderResult</code> instance will be returned according to
306:             * following rules:
307:             * <ul>
308:             * <li>{@link CoderResult#OVERFLOW CoderResult.OVERFLOW} indicates that
309:             * even though not all of the input has been processed, the buffer the
310:             * output is being written to has reached its capacity. In the event of this
311:             * code being returned this method should be called once more with an
312:             * <code>out</code> argument that has not already been filled.</li>
313:             * <li>{@link CoderResult#UNDERFLOW CoderResult.UNDERFLOW} indicates that
314:             * as many bytes as possible in the input buffer have been decoded. If there
315:             * is no further input and no remaining bytes in the input buffer then this
316:             * operation may be regarded as complete. Otherwise, this method should be
317:             * called once more with additional input.</li>
318:             * <li>A {@link CoderResult#malformedForLength(int) malformed input} result
319:             * indicates that some malformed input error encountered, and the erroneous
320:             * bytes start at the input buffer's position and their number can be got by
321:             * result's {@link CoderResult#length() length}. This kind of result can be
322:             * returned only if the malformed action is
323:             * {@link CodingErrorAction#REPORT CodingErrorAction.REPORT}. </li>
324:             * <li>A {@link CoderResult#unmappableForLength(int) unmappable character}
325:             * result indicates that some unmappable character error encountered, and
326:             * the erroneous bytes start at the input buffer's position and their number
327:             * can be got by result's {@link CoderResult#length() length}. This kind of
328:             * result can be returned only if the unmappable character action is
329:             * {@link CodingErrorAction#REPORT CodingErrorAction.REPORT}. </li>
330:             * </ul>
331:             * </p>
332:             * <p>
333:             * The <code>endOfInput</code> parameter indicates that if the invoker can
334:             * provider further input. This parameter is true if and only if the bytes
335:             * in current input buffer are all inputs for this decoding operation. Note
336:             * that it is common and won't cause error that the invoker sets false and
337:             * then finds no more input available; while it may cause error that the
338:             * invoker always sets true in several consecutive invocations so that any
339:             * remaining input will be treated as malformed input.
340:             * </p>
341:             * <p>
342:             * This method invokes
343:             * {@link #decodeLoop(ByteBuffer, CharBuffer) decodeLoop} method to
344:             * implement basic decode logic for specific charset.
345:             * </p>
346:             * 
347:             * @param in
348:             *            the input buffer
349:             * @param out
350:             *            the output buffer
351:             * @param endOfInput
352:             *            true if all the input characters have been provided
353:             * @return a <code>CoderResult</code> instance which indicates the reason
354:             *         of termination
355:             * @throws IllegalStateException
356:             *             if decoding has started or no more input is needed in this
357:             *             decoding progress.
358:             * @throws CoderMalfunctionError
359:             *             if the {@link #decodeLoop(ByteBuffer, CharBuffer) decodeLoop}
360:             *             method threw an <code>BufferUnderflowException</code> or
361:             *             <code>BufferOverflowException</code>
362:             */
363:            public final CoderResult decode(ByteBuffer in, CharBuffer out,
364:                    boolean endOfInput) {
365:                /*
366:                 * status check
367:                 */
368:                if ((status == FLUSH) || (!endOfInput && status == END)) {
369:                    throw new IllegalStateException();
370:                }
371:
372:                CoderResult result = null;
373:
374:                // begin to decode
375:                while (true) {
376:                    CodingErrorAction action = null;
377:                    try {
378:                        result = decodeLoop(in, out);
379:                    } catch (BufferOverflowException ex) {
380:                        // unexpected exception
381:                        throw new CoderMalfunctionError(ex);
382:                    } catch (BufferUnderflowException ex) {
383:                        // unexpected exception
384:                        throw new CoderMalfunctionError(ex);
385:                    }
386:
387:                    /*
388:                     * result handling
389:                     */
390:                    if (result.isUnderflow()) {
391:                        int remaining = in.remaining();
392:                        status = endOfInput ? END : ONGOING;
393:                        if (endOfInput && remaining > 0) {
394:                            result = CoderResult.malformedForLength(remaining);
395:                        } else {
396:                            return result;
397:                        }
398:                    }
399:                    if (result.isOverflow()) {
400:                        return result;
401:                    }
402:                    // set coding error handle action
403:                    action = malformAction;
404:                    if (result.isUnmappable()) {
405:                        action = unmapAction;
406:                    }
407:                    // If the action is IGNORE or REPLACE, we should continue decoding.
408:                    if (action == CodingErrorAction.REPLACE) {
409:                        if (out.remaining() < replace.length()) {
410:                            return CoderResult.OVERFLOW;
411:                        }
412:                        out.put(replace);
413:                    } else {
414:                        if (action != CodingErrorAction.IGNORE)
415:                            return result;
416:                    }
417:                    in.position(in.position() + result.length());
418:                }
419:            }
420:
421:            /**
422:             * Decode bytes into characters. This method is called by
423:             * {@link #decode(ByteBuffer, CharBuffer, boolean) decode} method.
424:             * 
425:             * This method will implement the essential decoding operation, and it won't
426:             * stop decoding until either all the input bytes are read, the output
427:             * buffer is filled, or some exception encountered. And then it will return
428:             * a <code>CoderResult</code> object indicating the result of current
429:             * decoding operation. The rules to construct the <code>CoderResult</code>
430:             * is same as the {@link #decode(ByteBuffer, CharBuffer, boolean) decode}.
431:             * When exception encountered in the decoding operation, most implementation
432:             * of this method will return a relevant result object to
433:             * {@link #decode(ByteBuffer, CharBuffer, boolean) decode} method, and some
434:             * performance optimized implementation may handle the exception and
435:             * implement the error action itself.
436:             * 
437:             * The buffers are scanned from their current positions, and their positions
438:             * will be modified accordingly, while their marks and limits will be
439:             * intact. At most {@link ByteBuffer#remaining() in.remaining()} characters
440:             * will be read, and {@link CharBuffer#remaining() out.remaining()} bytes
441:             * will be written.
442:             * 
443:             * Note that some implementation may pre-scan the input buffer and return
444:             * <code>CoderResult.UNDERFLOW</code> until it receives sufficient input.
445:             * 
446:             * @param in
447:             *            the input buffer
448:             * @param out
449:             *            the output buffer
450:             * @return a <code>CoderResult</code> instance indicating the result
451:             */
452:            protected abstract CoderResult decodeLoop(ByteBuffer in,
453:                    CharBuffer out);
454:
455:            /**
456:             * Get the charset detected by this decoder, this method is optional.
457:             * <p>
458:             * If implementing an auto-detecting charset, then this decoder returns the
459:             * detected charset from this method when it is available. The returned
460:             * charset will be the same for the rest of the decode operation.
461:             * </p>
462:             * <p>
463:             * If insufficient bytes have been read to determine the charset,
464:             * <code>IllegalStateException</code> will be thrown.
465:             * </p>
466:             * <p>
467:             * The default implementation always throws
468:             * <code>UnsupportedOperationException</code>, so it should be overridden
469:             * by subclass if needed.
470:             * </p>
471:             * 
472:             * @return the charset detected by this decoder, or null if it is not yet
473:             *         determined
474:             * @throws UnsupportedOperationException
475:             *             if this decoder does not implement an auto-detecting charset
476:             * @throws IllegalStateException
477:             *             if insufficient bytes have been read to determine the charset
478:             */
479:            public Charset detectedCharset() {
480:                throw new UnsupportedOperationException();
481:            }
482:
483:            /**
484:             * Flush this decoder.
485:             * 
486:             * This method will call {@link #implFlush(CharBuffer) implFlush}. Some
487:             * decoders may need to write some characters to the output buffer when they
488:             * have read all input bytes, subclasses can overridden
489:             * {@link #implFlush(CharBuffer) implFlush} to perform writing action.
490:             * 
491:             * The maximum number of written bytes won't larger than
492:             * {@link CharBuffer#remaining() out.remaining()}. If some decoder want to
493:             * write more bytes than output buffer's remaining spaces, then
494:             * <code>CoderResult.OVERFLOW</code> will be returned, and this method
495:             * must be called again with a character buffer that has more spaces.
496:             * Otherwise this method will return <code>CoderResult.UNDERFLOW</code>,
497:             * which means one decoding process has been completed successfully.
498:             * 
499:             * During the flush, the output buffer's position will be changed
500:             * accordingly, while its mark and limit will be intact.
501:             * 
502:             * @param out
503:             *            the given output buffer
504:             * @return <code>CoderResult.UNDERFLOW</code> or
505:             *         <code>CoderResult.OVERFLOW</code>
506:             * @throws IllegalStateException
507:             *             if this decoder hasn't read all input bytes during one
508:             *             decoding process, which means neither after calling
509:             *             {@link #decode(ByteBuffer) decode(ByteBuffer)} nor after
510:             *             calling {@link #decode(ByteBuffer, CharBuffer, boolean)
511:             *             decode(ByteBuffer, CharBuffer, boolean)} with true value for
512:             *             the last boolean parameter
513:             */
514:            public final CoderResult flush(CharBuffer out) {
515:                if (status != END && status != INIT) {
516:                    throw new IllegalStateException();
517:                }
518:                CoderResult result = implFlush(out);
519:                if (result == CoderResult.UNDERFLOW) {
520:                    status = FLUSH;
521:                }
522:                return result;
523:            }
524:
525:            /**
526:             * Flush this decoder. Default implementation does nothing and always return
527:             * <code>CoderResult.UNDERFLOW</code>, and this method can be overridden
528:             * if needed.
529:             * 
530:             * @param out
531:             *            the output buffer
532:             * @return <code>CoderResult.UNDERFLOW</code> or
533:             *         <code>CoderResult.OVERFLOW</code>
534:             */
535:            protected CoderResult implFlush(CharBuffer out) {
536:                return CoderResult.UNDERFLOW;
537:            }
538:
539:            /**
540:             * Notify that this decoder's <code>CodingErrorAction</code> specified for
541:             * malformed input error has been changed. Default implementation does
542:             * nothing, and this method can be overridden if needed.
543:             * 
544:             * @param newAction
545:             *            The new action
546:             */
547:            protected void implOnMalformedInput(CodingErrorAction newAction) {
548:                // default implementation is empty
549:            }
550:
551:            /**
552:             * Notify that this decoder's <code>CodingErrorAction</code> specified for
553:             * unmappable character error has been changed. Default implementation does
554:             * nothing, and this method can be overridden if needed.
555:             * 
556:             * @param newAction
557:             *            The new action
558:             */
559:            protected void implOnUnmappableCharacter(CodingErrorAction newAction) {
560:                // default implementation is empty
561:            }
562:
563:            /**
564:             * Notify that this decoder's replacement has been changed. Default
565:             * implementation does nothing, and this method can be overridden if needed.
566:             * 
567:             * @param newReplacement
568:             *            the new replacement string
569:             */
570:            protected void implReplaceWith(String newReplacement) {
571:                // default implementation is empty
572:            }
573:
574:            /**
575:             * Reset this decoder's charset related state. Default implementation does
576:             * nothing, and this method can be overridden if needed.
577:             */
578:            protected void implReset() {
579:                // default implementation is empty
580:            }
581:
582:            /**
583:             * Get if this decoder implements an auto-detecting charset.
584:             * 
585:             * @return <code>true</code> if this decoder implements an auto-detecting
586:             *         charset
587:             */
588:            public boolean isAutoDetecting() {
589:                return false;
590:            }
591:
592:            /**
593:             * Get if this decoder has detected a charset, this method is optional.
594:             * <p>
595:             * If this decoder implements an auto-detecting charset, then this method
596:             * may start to return true during decoding operation to indicate that a
597:             * charset has been detected in the input bytes and that the charset can be
598:             * retrieved by invoking {@link #detectedCharset() detectedCharset} method.
599:             * </p>
600:             * <p>
601:             * Note that a decoder that implements an auto-detecting charset may still
602:             * succeed in decoding a portion of the given input even when it is unable
603:             * to detect the charset. For this reason users should be aware that a
604:             * <code>false</code> return value does not indicate that no decoding took
605:             * place.
606:             * </p>
607:             * <p>
608:             * The default implementation always throws an
609:             * <code>UnsupportedOperationException</code>; it should be overridden by
610:             * subclass if needed.
611:             * </p>
612:             * 
613:             * @return <code>true</code> this decoder has detected a charset
614:             * @throws UnsupportedOperationException
615:             *             if this decoder doesn't implement an auto-detecting charset
616:             */
617:            public boolean isCharsetDetected() {
618:                throw new UnsupportedOperationException();
619:            }
620:
621:            /**
622:             * Gets this decoder's <code>CodingErrorAction</code> when malformed input
623:             * occurred during decoding process.
624:             * 
625:             * @return this decoder's <code>CodingErrorAction</code> when malformed
626:             *         input occurred during decoding process.
627:             */
628:            public CodingErrorAction malformedInputAction() {
629:                return malformAction;
630:            }
631:
632:            /**
633:             * Get the maximum number of characters which can be created by this decoder
634:             * for one input byte, must be positive
635:             * 
636:             * @return the maximum number of characters which can be created by this
637:             *         decoder for one input byte, must be positive
638:             */
639:            public final float maxCharsPerByte() {
640:                return maxChars;
641:            }
642:
643:            /**
644:             * Set this decoder's action on malformed input error.
645:             * 
646:             * This method will call the
647:             * {@link #implOnMalformedInput(CodingErrorAction) implOnMalformedInput}
648:             * method with the given new action as argument.
649:             * 
650:             * @param newAction
651:             *            the new action on malformed input error
652:             * @return this decoder
653:             * @throws IllegalArgumentException
654:             *             if the given newAction is null
655:             */
656:            public final CharsetDecoder onMalformedInput(
657:                    CodingErrorAction newAction) {
658:                if (null == newAction) {
659:                    throw new IllegalArgumentException();
660:                }
661:                malformAction = newAction;
662:                implOnMalformedInput(newAction);
663:                return this ;
664:            }
665:
666:            /**
667:             * Set this decoder's action on unmappable character error.
668:             * 
669:             * This method will call the
670:             * {@link #implOnUnmappableCharacter(CodingErrorAction) implOnUnmappableCharacter}
671:             * method with the given new action as argument.
672:             * 
673:             * @param newAction
674:             *            the new action on unmappable character error
675:             * @return this decoder
676:             * @throws IllegalArgumentException
677:             *             if the given newAction is null
678:             */
679:            public final CharsetDecoder onUnmappableCharacter(
680:                    CodingErrorAction newAction) {
681:                if (null == newAction) {
682:                    throw new IllegalArgumentException();
683:                }
684:                unmapAction = newAction;
685:                implOnUnmappableCharacter(newAction);
686:                return this ;
687:            }
688:
689:            /**
690:             * Get the replacement string, which is never null or empty
691:             * 
692:             * @return the replacement string, cannot be null or empty
693:             */
694:            public final String replacement() {
695:                return replace;
696:            }
697:
698:            /**
699:             * Set new replacement value.
700:             * 
701:             * This method first checks the given replacement's validity, then changes
702:             * the replacement value, and at last calls
703:             * {@link #implReplaceWith(String) implReplaceWith} method with the given
704:             * new replacement as argument.
705:             * 
706:             * @param newReplacement
707:             *            the replacement string, cannot be null or empty
708:             * @return this decoder
709:             * @throws IllegalArgumentException
710:             *             if the given replacement cannot satisfy the requirement
711:             *             mentioned above
712:             */
713:            public final CharsetDecoder replaceWith(String newReplacement) {
714:                if (null == newReplacement || newReplacement.length() == 0) {
715:                    // niochar.06=Replacement string cannot be null or empty.
716:                    throw new IllegalArgumentException(Messages
717:                            .getString("niochar.06")); //$NON-NLS-1$
718:                }
719:                if (newReplacement.length() > maxChars) {
720:                    // niochar.07=Replacement string's length cannot be larger than max
721:                    // characters per byte.
722:                    throw new IllegalArgumentException(Messages
723:                            .getString("niochar.07")); //$NON-NLS-1$
724:                }
725:                replace = newReplacement;
726:                implReplaceWith(newReplacement);
727:                return this ;
728:            }
729:
730:            /**
731:             * Reset this decoder. This method will reset internal status, and then call
732:             * <code>implReset()</code> to reset any status related to specific
733:             * charset.
734:             * 
735:             * @return this decoder
736:             */
737:            public final CharsetDecoder reset() {
738:                status = INIT;
739:                implReset();
740:                return this ;
741:            }
742:
743:            /**
744:             * Gets this decoder's <code>CodingErrorAction</code> when unmappable
745:             * character occurred during decoding process.
746:             * 
747:             * @return this decoder's <code>CodingErrorAction</code> when unmappable
748:             *         character occurred during decoding process.
749:             */
750:            public CodingErrorAction unmappableCharacterAction() {
751:                return unmapAction;
752:            }
753:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.