Source Code Cross Referenced for COMPOUND_TEXT_Decoder.java in  » 6.0-JDK-Platform » solaris » sun » nio » cs » ext » 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 » 6.0 JDK Platform » solaris » sun.nio.cs.ext 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2001-2005 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:        package sun.nio.cs.ext;
027:
028:        import java.io.ByteArrayOutputStream;
029:        import java.nio.ByteBuffer;
030:        import java.nio.CharBuffer;
031:        import java.nio.charset.*;
032:
033:        /**
034:         * An algorithmic conversion from COMPOUND_TEXT to Unicode.
035:         */
036:
037:        public class COMPOUND_TEXT_Decoder extends CharsetDecoder {
038:
039:            private static final int NORMAL_BYTES = 0;
040:            private static final int NONSTANDARD_BYTES = 1;
041:            private static final int VERSION_SEQUENCE_V = 2;
042:            private static final int VERSION_SEQUENCE_TERM = 3;
043:            private static final int ESCAPE_SEQUENCE = 4;
044:            private static final int CHARSET_NGIIF = 5;
045:            private static final int CHARSET_NLIIF = 6;
046:            private static final int CHARSET_NLIF = 7;
047:            private static final int CHARSET_NRIIF = 8;
048:            private static final int CHARSET_NRIF = 9;
049:            private static final int CHARSET_NONSTANDARD_FOML = 10;
050:            private static final int CHARSET_NONSTANDARD_OML = 11;
051:            private static final int CHARSET_NONSTANDARD_ML = 12;
052:            private static final int CHARSET_NONSTANDARD_L = 13;
053:            private static final int CHARSET_NONSTANDARD = 14;
054:            private static final int CHARSET_LIIF = 15;
055:            private static final int CHARSET_LIF = 16;
056:            private static final int CHARSET_RIIF = 17;
057:            private static final int CHARSET_RIF = 18;
058:            private static final int CONTROL_SEQUENCE_PIF = 19;
059:            private static final int CONTROL_SEQUENCE_IF = 20;
060:            private static final int EXTENSION_ML = 21;
061:            private static final int EXTENSION_L = 22;
062:            private static final int EXTENSION = 23;
063:            private static final int ESCAPE_SEQUENCE_OTHER = 24;
064:
065:            private static final String ERR_LATIN1 = "ISO8859_1 unsupported";
066:            private static final String ERR_ILLSTATE = "Illegal state";
067:            private static final String ERR_ESCBYTE = "Illegal byte in 0x1B escape sequence";
068:            private static final String ERR_ENCODINGBYTE = "Illegal byte in non-standard character set name";
069:            private static final String ERR_CTRLBYTE = "Illegal byte in 0x9B control sequence";
070:            private static final String ERR_CTRLPI = "P following I in 0x9B control sequence";
071:            private static final String ERR_VERSTART = "Versioning escape sequence can only appear at start of byte stream";
072:            private static final String ERR_VERMANDATORY = "Cannot parse mandatory extensions";
073:            private static final String ERR_ENCODING = "Unknown encoding: ";
074:            private static final String ERR_FLUSH = "Escape sequence, control sequence, or ML extension not terminated";
075:
076:            private int state = NORMAL_BYTES;
077:            private int ext_count, ext_offset;
078:            private boolean versionSequenceAllowed = true;
079:            private byte[] byteBuf = new byte[1];
080:            private ByteBuffer inBB = ByteBuffer.allocate(16);
081:            private ByteArrayOutputStream queue = new ByteArrayOutputStream(),
082:                    encodingQueue = new ByteArrayOutputStream();
083:
084:            private CharsetDecoder glDecoder, grDecoder, nonStandardDecoder,
085:                    lastDecoder;
086:            private boolean glHigh = false, grHigh = true;
087:
088:            public COMPOUND_TEXT_Decoder(Charset cs) {
089:                super (cs, 1.0f, 1.0f);
090:                try {
091:                    // Initial state in ISO 2022 designates Latin-1 charset.
092:                    glDecoder = Charset.forName("ASCII").newDecoder();
093:                    grDecoder = Charset.forName("ISO8859_1").newDecoder();
094:                } catch (IllegalArgumentException e) {
095:                    error(ERR_LATIN1);
096:                }
097:                initDecoder(glDecoder);
098:                initDecoder(grDecoder);
099:            }
100:
101:            protected CoderResult decodeLoop(ByteBuffer src, CharBuffer des) {
102:                CoderResult cr = CoderResult.UNDERFLOW;
103:                byte[] input = src.array();
104:                int inOff = src.arrayOffset() + src.position();
105:                int inEnd = src.arrayOffset() + src.limit();
106:
107:                try {
108:                    while (inOff < inEnd && cr.isUnderflow()) {
109:                        // Byte parsing is done with shorts instead of bytes because
110:                        // Java bytes are signed, while COMPOUND_TEXT bytes are not. If
111:                        // we used the Java byte type, the > and < tests during parsing
112:                        // would not work correctly.
113:                        cr = handleByte((short) (input[inOff] & 0xFF), des);
114:                        inOff++;
115:                    }
116:                    return cr;
117:                } finally {
118:                    src.position(inOff - src.arrayOffset());
119:                }
120:            }
121:
122:            private CoderResult handleByte(short newByte, CharBuffer cb) {
123:                CoderResult cr = CoderResult.UNDERFLOW;
124:                switch (state) {
125:                case NORMAL_BYTES:
126:                    cr = normalBytes(newByte, cb);
127:                    break;
128:                case NONSTANDARD_BYTES:
129:                    cr = nonStandardBytes(newByte, cb);
130:                    break;
131:                case VERSION_SEQUENCE_V:
132:                case VERSION_SEQUENCE_TERM:
133:                    cr = versionSequence(newByte);
134:                    break;
135:                case ESCAPE_SEQUENCE:
136:                    cr = escapeSequence(newByte);
137:                    break;
138:                case CHARSET_NGIIF:
139:                    cr = charset94N(newByte);
140:                    break;
141:                case CHARSET_NLIIF:
142:                case CHARSET_NLIF:
143:                    cr = charset94NL(newByte, cb);
144:                    break;
145:                case CHARSET_NRIIF:
146:                case CHARSET_NRIF:
147:                    cr = charset94NR(newByte, cb);
148:                    break;
149:                case CHARSET_NONSTANDARD_FOML:
150:                case CHARSET_NONSTANDARD_OML:
151:                case CHARSET_NONSTANDARD_ML:
152:                case CHARSET_NONSTANDARD_L:
153:                case CHARSET_NONSTANDARD:
154:                    cr = charsetNonStandard(newByte, cb);
155:                    break;
156:                case CHARSET_LIIF:
157:                case CHARSET_LIF:
158:                    cr = charset9496L(newByte, cb);
159:                    break;
160:                case CHARSET_RIIF:
161:                case CHARSET_RIF:
162:                    cr = charset9496R(newByte, cb);
163:                    break;
164:                case CONTROL_SEQUENCE_PIF:
165:                case CONTROL_SEQUENCE_IF:
166:                    cr = controlSequence(newByte);
167:                    break;
168:                case EXTENSION_ML:
169:                case EXTENSION_L:
170:                case EXTENSION:
171:                    cr = extension(newByte);
172:                    break;
173:                case ESCAPE_SEQUENCE_OTHER:
174:                    cr = escapeSequenceOther(newByte);
175:                    break;
176:                default:
177:                    error(ERR_ILLSTATE);
178:                }
179:                return cr;
180:            }
181:
182:            private CoderResult normalBytes(short newByte, CharBuffer cb) {
183:                CoderResult cr = CoderResult.UNDERFLOW;
184:                if ((newByte >= 0x00 && newByte <= 0x1F) || // C0 
185:                        (newByte >= 0x80 && newByte <= 0x9F)) { // C1
186:                    char newChar;
187:
188:                    switch (newByte) {
189:                    case 0x1B:
190:                        state = ESCAPE_SEQUENCE;
191:                        queue.write(newByte);
192:                        return cr;
193:                    case 0x9B:
194:                        state = CONTROL_SEQUENCE_PIF;
195:                        versionSequenceAllowed = false;
196:                        queue.write(newByte);
197:                        return cr;
198:                    case 0x09:
199:                        versionSequenceAllowed = false;
200:                        newChar = '\t';
201:                        break;
202:                    case 0x0A:
203:                        versionSequenceAllowed = false;
204:                        newChar = '\n';
205:                        break;
206:                    default:
207:                        versionSequenceAllowed = false;
208:                        return cr;
209:                    }
210:                    if (!cb.hasRemaining())
211:                        return CoderResult.OVERFLOW;
212:                    else
213:                        cb.put(newChar);
214:                } else {
215:                    CharsetDecoder decoder;
216:                    boolean high;
217:                    versionSequenceAllowed = false;
218:
219:                    if (newByte >= 0x20 && newByte <= 0x7F) {
220:                        decoder = glDecoder;
221:                        high = glHigh;
222:                    } else /* if (newByte >= 0xA0 && newByte <= 0xFF) */{
223:                        decoder = grDecoder;
224:                        high = grHigh;
225:                    }
226:                    if (lastDecoder != null && decoder != lastDecoder) {
227:                        cr = flushDecoder(lastDecoder, cb);
228:                    }
229:                    lastDecoder = decoder;
230:
231:                    if (decoder != null) {
232:                        byte b = (byte) newByte;
233:                        if (high) {
234:                            b |= 0x80;
235:                        } else {
236:                            b &= 0x7F;
237:                        }
238:                        inBB.put(b);
239:                        inBB.flip();
240:                        cr = decoder.decode(inBB, cb, false);
241:                        if (!inBB.hasRemaining() || cr.isMalformed()) {
242:                            inBB.clear();
243:                        } else {
244:                            int pos = inBB.limit();
245:                            inBB.clear();
246:                            inBB.position(pos);
247:                        }
248:                    } else if (cb.remaining() < replacement().length()) {
249:                        cb.put(replacement());
250:                    } else {
251:                        return CoderResult.OVERFLOW;
252:                    }
253:                }
254:                return cr;
255:            }
256:
257:            private CoderResult nonStandardBytes(short newByte, CharBuffer cb) {
258:                CoderResult cr = CoderResult.UNDERFLOW;
259:                if (nonStandardDecoder != null) {
260:                    //byteBuf[0] = (byte)newByte;
261:                    inBB.put((byte) newByte);
262:                    inBB.flip();
263:                    cr = nonStandardDecoder.decode(inBB, cb, false);
264:                    if (!inBB.hasRemaining()) {
265:                        inBB.clear();
266:                    } else {
267:                        int pos = inBB.limit();
268:                        inBB.clear();
269:                        inBB.position(pos);
270:                    }
271:                } else if (cb.remaining() < replacement().length()) {
272:                    cb.put(replacement());
273:                } else {
274:                    return CoderResult.OVERFLOW;
275:                }
276:
277:                ext_offset++;
278:                if (ext_offset >= ext_count) {
279:                    ext_offset = ext_count = 0;
280:                    state = NORMAL_BYTES;
281:                    cr = flushDecoder(nonStandardDecoder, cb);
282:                    nonStandardDecoder = null;
283:                }
284:                return cr;
285:            }
286:
287:            private CoderResult escapeSequence(short newByte) {
288:                switch (newByte) {
289:                case 0x23:
290:                    state = VERSION_SEQUENCE_V;
291:                    break;
292:                case 0x24:
293:                    state = CHARSET_NGIIF;
294:                    versionSequenceAllowed = false;
295:                    break;
296:                case 0x25:
297:                    state = CHARSET_NONSTANDARD_FOML;
298:                    versionSequenceAllowed = false;
299:                    break;
300:                case 0x28:
301:                    state = CHARSET_LIIF;
302:                    versionSequenceAllowed = false;
303:                    break;
304:                case 0x29:
305:                case 0x2D:
306:                    state = CHARSET_RIIF;
307:                    versionSequenceAllowed = false;
308:                    break;
309:                default:
310:                    // escapeSequenceOther will write to queue if appropriate
311:                    return escapeSequenceOther(newByte);
312:                }
313:
314:                queue.write(newByte);
315:                return CoderResult.UNDERFLOW;
316:            }
317:
318:            /**
319:             * Test for unknown, but valid, escape sequences.
320:             */
321:            private CoderResult escapeSequenceOther(short newByte) {
322:                if (newByte >= 0x20 && newByte <= 0x2F) {
323:                    // {I}
324:                    state = ESCAPE_SEQUENCE_OTHER;
325:                    versionSequenceAllowed = false;
326:                    queue.write(newByte);
327:                } else if (newByte >= 0x30 && newByte <= 0x7E) {
328:                    // F -- end of sequence
329:                    state = NORMAL_BYTES;
330:                    versionSequenceAllowed = false;
331:                    queue.reset();
332:                } else {
333:                    return malformedInput(ERR_ESCBYTE);
334:                }
335:                return CoderResult.UNDERFLOW;
336:            }
337:
338:            /**
339:             * Parses directionality, as well as unknown, but valid, control sequences.
340:             */
341:            private CoderResult controlSequence(short newByte) {
342:                if (newByte >= 0x30 && newByte <= 0x3F) {
343:                    // {P}
344:                    if (state == CONTROL_SEQUENCE_IF) {
345:                        // P no longer allowed
346:                        return malformedInput(ERR_CTRLPI);
347:                    }
348:                    queue.write(newByte);
349:                } else if (newByte >= 0x20 && newByte <= 0x2F) {
350:                    // {I}
351:                    state = CONTROL_SEQUENCE_IF;
352:                    queue.write(newByte);
353:                } else if (newByte >= 0x40 && newByte <= 0x7E) {
354:                    // F -- end of sequence
355:                    state = NORMAL_BYTES;
356:                    queue.reset();
357:                } else {
358:                    return malformedInput(ERR_CTRLBYTE);
359:                }
360:                return CoderResult.UNDERFLOW;
361:            }
362:
363:            private CoderResult versionSequence(short newByte) {
364:                if (state == VERSION_SEQUENCE_V) {
365:                    if (newByte >= 0x20 && newByte <= 0x2F) {
366:                        state = VERSION_SEQUENCE_TERM;
367:                        queue.write(newByte);
368:                    } else {
369:                        return escapeSequenceOther(newByte);
370:                    }
371:                } else /* if (state == VERSION_SEQUENCE_TERM) */{
372:                    switch (newByte) {
373:                    case 0x30:
374:                        if (!versionSequenceAllowed) {
375:                            return malformedInput(ERR_VERSTART);
376:                        }
377:
378:                        // OK to ignore extensions
379:                        versionSequenceAllowed = false;
380:                        state = NORMAL_BYTES;
381:                        queue.reset();
382:                        break;
383:                    case 0x31:
384:                        return malformedInput((versionSequenceAllowed) ? ERR_VERMANDATORY
385:                                : ERR_VERSTART);
386:                    default:
387:                        return escapeSequenceOther(newByte);
388:                    }
389:                }
390:                return CoderResult.UNDERFLOW;
391:            }
392:
393:            private CoderResult charset94N(short newByte) {
394:                switch (newByte) {
395:                case 0x28:
396:                    state = CHARSET_NLIIF;
397:                    break;
398:                case 0x29:
399:                    state = CHARSET_NRIIF;
400:                    break;
401:                default:
402:                    // escapeSequenceOther will write byte if appropriate
403:                    return escapeSequenceOther(newByte);
404:                }
405:
406:                queue.write(newByte);
407:                return CoderResult.UNDERFLOW;
408:            }
409:
410:            private CoderResult charset94NL(short newByte, CharBuffer cb) {
411:                if (newByte >= 0x21
412:                        && newByte <= (state == CHARSET_NLIIF ? 0x23 : 0x2F)) {
413:                    // {I}
414:                    state = CHARSET_NLIF;
415:                    queue.write(newByte);
416:                } else if (newByte >= 0x40 && newByte <= 0x7E) {
417:                    // F
418:                    return switchDecoder(newByte, cb);
419:                } else {
420:                    return escapeSequenceOther(newByte);
421:                }
422:                return CoderResult.UNDERFLOW;
423:            }
424:
425:            private CoderResult charset94NR(short newByte, CharBuffer cb) {
426:                if (newByte >= 0x21
427:                        && newByte <= (state == CHARSET_NRIIF ? 0x23 : 0x2F)) {
428:                    // {I}
429:                    state = CHARSET_NRIF;
430:                    queue.write(newByte);
431:                } else if (newByte >= 0x40 && newByte <= 0x7E) {
432:                    // F
433:                    return switchDecoder(newByte, cb);
434:                } else {
435:                    return escapeSequenceOther(newByte);
436:                }
437:                return CoderResult.UNDERFLOW;
438:            }
439:
440:            private CoderResult charset9496L(short newByte, CharBuffer cb) {
441:                if (newByte >= 0x21
442:                        && newByte <= (state == CHARSET_LIIF ? 0x23 : 0x2F)) {
443:                    // {I}
444:                    state = CHARSET_LIF;
445:                    queue.write(newByte);
446:                    return CoderResult.UNDERFLOW;
447:                } else if (newByte >= 0x40 && newByte <= 0x7E) {
448:                    // F
449:                    return switchDecoder(newByte, cb);
450:                } else {
451:                    return escapeSequenceOther(newByte);
452:                }
453:            }
454:
455:            private CoderResult charset9496R(short newByte, CharBuffer cb) {
456:                if (newByte >= 0x21
457:                        && newByte <= (state == CHARSET_RIIF ? 0x23 : 0x2F)) {
458:                    // {I}
459:                    state = CHARSET_RIF;
460:                    queue.write(newByte);
461:                    return CoderResult.UNDERFLOW;
462:                } else if (newByte >= 0x40 && newByte <= 0x7E) {
463:                    // F
464:                    return switchDecoder(newByte, cb);
465:                } else {
466:                    return escapeSequenceOther(newByte);
467:                }
468:            }
469:
470:            private CoderResult charsetNonStandard(short newByte, CharBuffer cb) {
471:                switch (state) {
472:                case CHARSET_NONSTANDARD_FOML:
473:                    if (newByte == 0x2F) {
474:                        state = CHARSET_NONSTANDARD_OML;
475:                        queue.write(newByte);
476:                    } else {
477:                        return escapeSequenceOther(newByte);
478:                    }
479:                    break;
480:                case CHARSET_NONSTANDARD_OML:
481:                    if (newByte >= 0x30 && newByte <= 0x34) {
482:                        state = CHARSET_NONSTANDARD_ML;
483:                        queue.write(newByte);
484:                    } else if (newByte >= 0x35 && newByte <= 0x3F) {
485:                        state = EXTENSION_ML;
486:                        queue.write(newByte);
487:                    } else {
488:                        return escapeSequenceOther(newByte);
489:                    }
490:                    break;
491:                case CHARSET_NONSTANDARD_ML:
492:                    ext_count = (newByte & 0x7F) * 0x80;
493:                    state = CHARSET_NONSTANDARD_L;
494:                    break;
495:                case CHARSET_NONSTANDARD_L:
496:                    ext_count = ext_count + (newByte & 0x7F);
497:                    state = (ext_count > 0) ? CHARSET_NONSTANDARD
498:                            : NORMAL_BYTES;
499:                    break;
500:                case CHARSET_NONSTANDARD:
501:                    if (newByte == 0x3F || newByte == 0x2A) {
502:                        queue.reset(); // In this case, only current byte is bad.
503:                        return malformedInput(ERR_ENCODINGBYTE);
504:                    }
505:                    ext_offset++;
506:                    if (ext_offset >= ext_count) {
507:                        ext_offset = ext_count = 0;
508:                        state = NORMAL_BYTES;
509:                        queue.reset();
510:                        encodingQueue.reset();
511:                    } else if (newByte == 0x02) {
512:                        // encoding name terminator
513:                        return switchDecoder((short) 0, cb);
514:                    } else {
515:                        encodingQueue.write(newByte);
516:                    }
517:                    break;
518:                default:
519:                    error(ERR_ILLSTATE);
520:                }
521:                return CoderResult.UNDERFLOW;
522:            }
523:
524:            private CoderResult extension(short newByte) {
525:                switch (state) {
526:                case EXTENSION_ML:
527:                    ext_count = (newByte & 0x7F) * 0x80;
528:                    state = EXTENSION_L;
529:                    break;
530:                case EXTENSION_L:
531:                    ext_count = ext_count + (newByte & 0x7F);
532:                    state = (ext_count > 0) ? EXTENSION : NORMAL_BYTES;
533:                    break;
534:                case EXTENSION:
535:                    // Consume 'count' bytes. Don't bother putting them on the queue.
536:                    // There may be too many and we can't do anything with them anyway.
537:                    ext_offset++;
538:                    if (ext_offset >= ext_count) {
539:                        ext_offset = ext_count = 0;
540:                        state = NORMAL_BYTES;
541:                        queue.reset();
542:                    }
543:                    break;
544:                default:
545:                    error(ERR_ILLSTATE);
546:                }
547:                return CoderResult.UNDERFLOW;
548:            }
549:
550:            /**
551:             * Preconditions:
552:             *   1. 'queue' contains ControlSequence.escSequence
553:             *   2. 'encodingQueue' contains ControlSequence.encoding
554:             */
555:            private CoderResult switchDecoder(short lastByte, CharBuffer cb) {
556:                CoderResult cr = CoderResult.UNDERFLOW;
557:                CharsetDecoder decoder = null;
558:                boolean high = false;
559:                byte[] escSequence;
560:                byte[] encoding = null;
561:
562:                if (lastByte != 0) {
563:                    queue.write(lastByte);
564:                }
565:
566:                escSequence = queue.toByteArray();
567:                queue.reset();
568:
569:                if (state == CHARSET_NONSTANDARD) {
570:                    encoding = encodingQueue.toByteArray();
571:                    encodingQueue.reset();
572:                    decoder = CompoundTextSupport.getNonStandardDecoder(
573:                            escSequence, encoding);
574:                } else {
575:                    decoder = CompoundTextSupport
576:                            .getStandardDecoder(escSequence);
577:                    high = CompoundTextSupport.getHighBit(escSequence);
578:                }
579:                if (decoder != null) {
580:                    initDecoder(decoder);
581:                } else if (unmappableCharacterAction() == CodingErrorAction.REPORT) {
582:                    int badInputLength = 1;
583:                    if (encoding != null) {
584:                        badInputLength = encoding.length;
585:                    } else if (escSequence.length > 0) {
586:                        badInputLength = escSequence.length;
587:                    }
588:                    return CoderResult.unmappableForLength(badInputLength);
589:                }
590:
591:                if (state == CHARSET_NLIIF || state == CHARSET_NLIF
592:                        || state == CHARSET_LIIF || state == CHARSET_LIF) {
593:                    if (lastDecoder == glDecoder) {
594:                        cr = flushDecoder(glDecoder, cb);
595:                    }
596:                    glDecoder = lastDecoder = decoder;
597:                    glHigh = high;
598:                    state = NORMAL_BYTES;
599:                } else if (state == CHARSET_NRIIF || state == CHARSET_NRIF
600:                        || state == CHARSET_RIIF || state == CHARSET_RIF) {
601:                    if (lastDecoder == grDecoder) {
602:                        cr = flushDecoder(grDecoder, cb);
603:                    }
604:                    grDecoder = lastDecoder = decoder;
605:                    grHigh = high;
606:                    state = NORMAL_BYTES;
607:                } else if (state == CHARSET_NONSTANDARD) {
608:                    if (lastDecoder != null) {
609:                        cr = flushDecoder(lastDecoder, cb);
610:                        lastDecoder = null;
611:                    }
612:                    nonStandardDecoder = decoder;
613:                    state = NONSTANDARD_BYTES;
614:                } else {
615:                    error(ERR_ILLSTATE);
616:                }
617:                return cr;
618:            }
619:
620:            private ByteBuffer fbb = ByteBuffer.allocate(0);
621:
622:            private CoderResult flushDecoder(CharsetDecoder dec, CharBuffer cb) {
623:                dec.decode(fbb, cb, true);
624:                CoderResult cr = dec.flush(cb);
625:                dec.reset(); //reuse
626:                return cr;
627:            }
628:
629:            private CoderResult malformedInput(String msg) {
630:                int badInputLength = queue.size() + 1 /* current byte */;
631:                queue.reset();
632:                //TBD: nowhere to put the msg in CoderResult
633:                return CoderResult.malformedForLength(badInputLength);
634:            }
635:
636:            private void error(String msg) {
637:                // For now, throw InternalError. Convert to 'assert' keyword later.
638:                throw new InternalError(msg);
639:            }
640:
641:            protected CoderResult implFlush(CharBuffer out) {
642:                CoderResult cr = CoderResult.UNDERFLOW;
643:                if (lastDecoder != null)
644:                    cr = flushDecoder(lastDecoder, out);
645:                if (state != NORMAL_BYTES)
646:                    //TBD message ERR_FLUSH;
647:                    cr = CoderResult.malformedForLength(0);
648:                reset();
649:                return cr;
650:            }
651:
652:            /**
653:             * Resets the decoder.
654:             * Call this method to reset the decoder to its initial state
655:             */
656:            protected void implReset() {
657:                state = NORMAL_BYTES;
658:                ext_count = ext_offset = 0;
659:                versionSequenceAllowed = true;
660:                queue.reset();
661:                encodingQueue.reset();
662:                nonStandardDecoder = lastDecoder = null;
663:                glHigh = false;
664:                grHigh = true;
665:                try {
666:                    // Initial state in ISO 2022 designates Latin-1 charset.
667:                    glDecoder = Charset.forName("ASCII").newDecoder();
668:                    grDecoder = Charset.forName("ISO8859_1").newDecoder();
669:                } catch (IllegalArgumentException e) {
670:                    error(ERR_LATIN1);
671:                }
672:                initDecoder(glDecoder);
673:                initDecoder(grDecoder);
674:            }
675:
676:            protected void implOnMalformedInput(CodingErrorAction newAction) {
677:                if (glDecoder != null)
678:                    glDecoder.onMalformedInput(newAction);
679:                if (grDecoder != null)
680:                    grDecoder.onMalformedInput(newAction);
681:                if (nonStandardDecoder != null)
682:                    nonStandardDecoder.onMalformedInput(newAction);
683:            }
684:
685:            protected void implOnUnmappableCharacter(CodingErrorAction newAction) {
686:                if (glDecoder != null)
687:                    glDecoder.onUnmappableCharacter(newAction);
688:                if (grDecoder != null)
689:                    grDecoder.onUnmappableCharacter(newAction);
690:                if (nonStandardDecoder != null)
691:                    nonStandardDecoder.onUnmappableCharacter(newAction);
692:            }
693:
694:            protected void implReplaceWith(String newReplacement) {
695:                if (glDecoder != null)
696:                    glDecoder.replaceWith(newReplacement);
697:                if (grDecoder != null)
698:                    grDecoder.replaceWith(newReplacement);
699:                if (nonStandardDecoder != null)
700:                    nonStandardDecoder.replaceWith(newReplacement);
701:            }
702:
703:            private void initDecoder(CharsetDecoder dec) {
704:                dec.onUnmappableCharacter(CodingErrorAction.REPLACE)
705:                        .replaceWith(replacement());
706:            }
707:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.