KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > apache > xerces > readers > UTF8Reader


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 1999,2000 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Xerces" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation and was
52  * originally based on software copyright (c) 1999, International
53  * Business Machines, Inc., http://www.apache.org. For more
54  * information on the Apache Software Foundation, please see
55  * <http://www.apache.org/>.
56  */

57
58 package org.enhydra.apache.xerces.readers;
59
60 import java.io.InputStream JavaDoc;
61
62 import org.enhydra.apache.xerces.framework.XMLErrorReporter;
63 import org.enhydra.apache.xerces.utils.QName;
64 import org.enhydra.apache.xerces.utils.StringPool;
65 import org.enhydra.apache.xerces.utils.SymbolCache;
66 import org.enhydra.apache.xerces.utils.UTF8DataChunk;
67 import org.enhydra.apache.xerces.utils.XMLCharacterProperties;
68
69 /**
70  * This is the primary reader used for UTF-8 encoded byte streams.
71  * <p>
72  * This reader processes requests from the scanners against the
73  * underlying UTF-8 byte stream, avoiding when possible any up-front
74  * transcoding. When the StringPool handle interfaces are used,
75  * the information in the data stream will be added to the string
76  * pool and lazy-evaluated until asked for.
77  * <p>
78  * We use the SymbolCache to match expected names (element types in
79  * end tags) and walk the data structures of that class directly.
80  * <p>
81  * There is a significant amount of hand-inlining and some blatant
82  * voilation of good object oriented programming rules, ignoring
83  * boundaries of modularity, etc., in the name of good performance.
84  * <p>
85  * There are also some places where the code here frequently crashes
86  * the SUN java runtime compiler (JIT) and the code here has been
87  * carefully "crafted" to avoid those problems.
88  *
89  * @version $Id: UTF8Reader.java,v 1.2 2005/01/26 08:28:44 jkjome Exp $
90  */

91 final class UTF8Reader extends XMLEntityReader {
92     //
93
//
94
//
95
private final static boolean USE_OUT_OF_LINE_LOAD_NEXT_BYTE = false;
96     private final static boolean USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE = true;
97     //
98
//
99
//
100
public UTF8Reader(XMLEntityHandler entityHandler, XMLErrorReporter errorReporter, boolean sendCharDataAsCharArray, InputStream JavaDoc dataStream, StringPool stringPool) throws Exception JavaDoc {
101         super(entityHandler, errorReporter, sendCharDataAsCharArray);
102         fInputStream = dataStream;
103         fStringPool = stringPool;
104         fCharArrayRange = fStringPool.createCharArrayRange();
105         fCurrentChunk = UTF8DataChunk.createChunk(fStringPool, null);
106         fillCurrentChunk();
107     }
108     /**
109      *
110      */

111     public int addString(int offset, int length) {
112         if (length == 0)
113             return 0;
114         return fCurrentChunk.addString(offset, length);
115     }
116     /**
117      *
118      */

119     public int addSymbol(int offset, int length) {
120         if (length == 0)
121             return 0;
122         return fCurrentChunk.addSymbol(offset, length, 0);
123     }
124     /**
125      *
126      */

127     private int addSymbol(int offset, int length, int hashcode) {
128         if (length == 0)
129             return 0;
130         return fCurrentChunk.addSymbol(offset, length, hashcode);
131     }
132     /**
133      *
134      */

135     public void append(XMLEntityHandler.CharBuffer charBuffer, int offset, int length) {
136         fCurrentChunk.append(charBuffer, offset, length);
137     }
138     //
139
//
140
//
141
private int slowLoadNextByte() throws Exception JavaDoc {
142         fCallClearPreviousChunk = true;
143         if (fCurrentChunk.nextChunk() != null) {
144             fCurrentChunk = fCurrentChunk.nextChunk();
145             fCurrentIndex = 0;
146             fMostRecentData = fCurrentChunk.toByteArray();
147             return(fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
148         } else {
149             fCurrentChunk = UTF8DataChunk.createChunk(fStringPool, fCurrentChunk);
150             return fillCurrentChunk();
151         }
152     }
153     private int loadNextByte() throws Exception JavaDoc {
154         fCurrentOffset++;
155         if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
156             fCurrentIndex++;
157             try {
158                 fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
159                 return fMostRecentByte;
160             } catch (ArrayIndexOutOfBoundsException JavaDoc ex) {
161                 return slowLoadNextByte();
162             }
163         } else {
164             if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
165                 return slowLoadNextByte();
166             else
167                 return(fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
168         }
169     }
170     //
171
//
172
//
173
private boolean atEOF(int offset) {
174         return(offset > fLength);
175     }
176     //
177
//
178
//
179
public XMLEntityHandler.EntityReader changeReaders() throws Exception JavaDoc {
180         XMLEntityHandler.EntityReader nextReader = super.changeReaders();
181         fCurrentChunk.releaseChunk();
182         fCurrentChunk = null;
183         fMostRecentData = null;
184         fMostRecentByte = 0;
185         return nextReader;
186     }
187     //
188
//
189
//
190
public boolean lookingAtChar(char ch, boolean skipPastChar) throws Exception JavaDoc {
191         int b0 = fMostRecentByte;
192         if (b0 != ch) {
193             if (b0 == 0) {
194                 if (atEOF(fCurrentOffset + 1)) {
195                     return changeReaders().lookingAtChar(ch, skipPastChar);
196                 }
197             }
198             if (ch == 0x0A && b0 == 0x0D) {
199                 if (skipPastChar) {
200                     fCarriageReturnCounter++;
201                     fCharacterCounter = 1;
202                     if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
203                         b0 = loadNextByte();
204                     } else {
205                         fCurrentOffset++;
206                         if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
207                             fCurrentIndex++;
208                             try {
209                                 fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
210                                 b0 = fMostRecentByte;
211                             } catch (ArrayIndexOutOfBoundsException JavaDoc ex) {
212                                 b0 = slowLoadNextByte();
213                             }
214                         } else {
215                             if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
216                                 b0 = slowLoadNextByte();
217                             else
218                                 b0 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
219                         }
220                     }
221                     if (b0 == 0x0A) {
222                         fLinefeedCounter++;
223                         if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
224                             loadNextByte();
225                         } else {
226                             fCurrentOffset++;
227                             if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
228                                 fCurrentIndex++;
229                                 try {
230                                     fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
231                                 } catch (ArrayIndexOutOfBoundsException JavaDoc ex) {
232                                     slowLoadNextByte();
233                                 }
234                             } else {
235                                 if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
236                                     slowLoadNextByte();
237                                 else
238                                     fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
239                             }
240                         }
241                     }
242                 }
243                 return true;
244             }
245             return false;
246         }
247         if (ch == 0x0D)
248             return false;
249         if (skipPastChar) {
250             fCharacterCounter++;
251             if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
252                 loadNextByte();
253             } else {
254                 fCurrentOffset++;
255                 if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
256                     fCurrentIndex++;
257                     try {
258                         fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
259                     } catch (ArrayIndexOutOfBoundsException JavaDoc ex) {
260                         slowLoadNextByte();
261                     }
262                 } else {
263                     if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
264                         slowLoadNextByte();
265                     else
266                         fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
267                 }
268             }
269         }
270         return true;
271     }
272     //
273
//
274
//
275
public boolean lookingAtValidChar(boolean skipPastChar) throws Exception JavaDoc {
276         int b0 = fMostRecentByte;
277         if (b0 < 0x80) { // 0xxxxxxx
278
if (b0 >= 0x20 || b0 == 0x09) {
279                 if (skipPastChar) {
280                     fCharacterCounter++;
281                     if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
282                         loadNextByte();
283                     } else {
284                         fCurrentOffset++;
285                         if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
286                             fCurrentIndex++;
287                             try {
288                                 fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
289                             } catch (ArrayIndexOutOfBoundsException JavaDoc ex) {
290                                 slowLoadNextByte();
291                             }
292                         } else {
293                             if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
294                                 slowLoadNextByte();
295                             else
296                                 fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
297                         }
298                     }
299                 }
300                 return true;
301             }
302             if (b0 == 0x0A) {
303                 if (skipPastChar) {
304                     fLinefeedCounter++;
305                     fCharacterCounter = 1;
306                     if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
307                         loadNextByte();
308                     } else {
309                         fCurrentOffset++;
310                         if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
311                             fCurrentIndex++;
312                             try {
313                                 fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
314                             } catch (ArrayIndexOutOfBoundsException JavaDoc ex) {
315                                 slowLoadNextByte();
316                             }
317                         } else {
318                             if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
319                                 slowLoadNextByte();
320                             else
321                                 fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
322                         }
323                     }
324                 }
325                 return true;
326             }
327             if (b0 == 0x0D) {
328                 if (skipPastChar) {
329                     fCarriageReturnCounter++;
330                     fCharacterCounter = 1;
331                     if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
332                         b0 = loadNextByte();
333                     } else {
334                         fCurrentOffset++;
335                         if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
336                             fCurrentIndex++;
337                             try {
338                                 fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
339                                 b0 = fMostRecentByte;
340                             } catch (ArrayIndexOutOfBoundsException JavaDoc ex) {
341                                 b0 = slowLoadNextByte();
342                             }
343                         } else {
344                             if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
345                                 b0 = slowLoadNextByte();
346                             else
347                                 b0 = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
348                         }
349                     }
350                     if (b0 == 0x0A) {
351                         fLinefeedCounter++;
352                         if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
353                             loadNextByte();
354                         } else {
355                             fCurrentOffset++;
356                             if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
357                                 fCurrentIndex++;
358                                 try {
359                                     fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
360                                 } catch (ArrayIndexOutOfBoundsException JavaDoc ex) {
361                                     slowLoadNextByte();
362                                 }
363                             } else {
364                                 if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
365                                     slowLoadNextByte();
366                                 else
367                                     fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
368                             }
369                         }
370                     }
371                 }
372                 return true;
373             }
374             if (b0 == 0) {
375                 if (atEOF(fCurrentOffset + 1)) {
376                     return changeReaders().lookingAtValidChar(skipPastChar);
377                 }
378             }
379             return false;
380         }
381         //
382
// REVISIT - optimize this with in-buffer lookahead.
383
//
384
UTF8DataChunk saveChunk = fCurrentChunk;
385         int saveIndex = fCurrentIndex;
386         int saveOffset = fCurrentOffset;
387         int b1 = loadNextByte();
388         if ((0xe0 & b0) == 0xc0) { // 110yyyyy 10xxxxxx (0x80 to 0x7ff)
389
if (skipPastChar) {
390                 fCharacterCounter++;
391                 loadNextByte();
392             } else {
393                 fCurrentChunk = saveChunk;
394                 fCurrentIndex = saveIndex;
395                 fCurrentOffset = saveOffset;
396                 fMostRecentData = saveChunk.toByteArray();
397                 fMostRecentByte = b0;
398             }
399             return true; // [#x20-#xD7FF]
400
}
401         int b2 = loadNextByte();
402         if ((0xf0 & b0) == 0xe0) { // 1110zzzz 10yyyyyy 10xxxxxx
403
// ch = ((0x0f & b0)<<12) + ((0x3f & b1)<<6) + (0x3f & b2); // zzzz yyyy yyxx xxxx (0x800 to 0xffff)
404
// if (!((ch >= 0xD800 && ch <= 0xDFFF) || ch >= 0xFFFE))
405
// if ((ch <= 0xD7FF) || (ch >= 0xE000 && ch <= 0xFFFD))
406
boolean result = false;
407             if (!((b0 == 0xED && b1 >= 0xA0) || (b0 == 0xEF && b1 == 0xBF && b2 >= 0xBE))) { // [#x20-#xD7FF] | [#xE000-#xFFFD]
408
if (skipPastChar) {
409                     fCharacterCounter++;
410                     loadNextByte();
411                     return true;
412                 }
413                 result = true;
414             }
415             fCurrentChunk = saveChunk;
416             fCurrentIndex = saveIndex;
417             fCurrentOffset = saveOffset;
418             fMostRecentData = saveChunk.toByteArray();
419             fMostRecentByte = b0;
420             return result;
421         }
422         int b3 = loadNextByte(); // 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
423
// ch = ((0x0f & b0)<<18) + ((0x3f & b1)<<12) + ((0x3f & b2)<<6) + (0x3f & b3); // u uuuu zzzz yyyy yyxx xxxx (0x10000 to 0x1ffff)
424
// if (ch >= 0x110000)
425
boolean result = false;
426
427         //if (( 0xf8 & b0 ) == 0xf0 ) {
428
//if (!(b0 > 0xF4 || (b0 == 0xF4 && b1 >= 0x90))) { // [#x10000-#x10FFFF]
429
if ( ((b0&0xf8) == 0xf0) && ((b1&0xc0)==0x80) &&
430              ((b2&0xc0) == 0x80) && ((b3&0xc0)==0x80)){
431             if (!(b0 > 0xF4 || (b0 == 0xF4 && b1 >= 0x90))) { // [#x10000-#x10FFFF]
432

433                 if (skipPastChar) {
434                     fCharacterCounter++;
435                     loadNextByte();
436                     return true;
437                 }
438                 result = true;
439             }
440             fCurrentChunk = saveChunk;
441             fCurrentIndex = saveIndex;
442             fCurrentOffset = saveOffset;
443             fMostRecentData = saveChunk.toByteArray();
444             fMostRecentByte = b0;
445             return result;
446         } else{
447             fCurrentChunk = saveChunk;
448             fCurrentIndex = saveIndex;
449             fCurrentOffset = saveOffset;
450             fMostRecentData = saveChunk.toByteArray();
451             fMostRecentByte = b0;
452             return result;
453         }
454     }
455     //
456
//
457
//
458
public boolean lookingAtSpace(boolean skipPastChar) throws Exception JavaDoc {
459         int ch = fMostRecentByte;
460         if (ch > 0x20)
461             return false;
462         if (ch == 0x20 || ch == 0x09) {
463             if (!skipPastChar)
464                 return true;
465             fCharacterCounter++;
466         } else if (ch == 0x0A) {
467             if (!skipPastChar)
468                 return true;
469             fLinefeedCounter++;
470             fCharacterCounter = 1;
471         } else if (ch == 0x0D) {
472             if (!skipPastChar)
473                 return true;
474             fCarriageReturnCounter++;
475             fCharacterCounter = 1;
476             if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
477                 ch = loadNextByte();
478             } else {
479                 fCurrentOffset++;
480                 if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
481                     fCurrentIndex++;
482                     try {
483                         fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
484                         ch = fMostRecentByte;
485                     } catch (ArrayIndexOutOfBoundsException JavaDoc ex) {
486                         ch = slowLoadNextByte();
487                     }
488                 } else {
489                     if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
490                         ch = slowLoadNextByte();
491                     else
492                         ch = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
493                 }
494             }
495             if (ch != 0x0A)
496                 return true;
497             fLinefeedCounter++;
498         } else {
499             if (ch == 0) { // REVISIT - should we be checking this here ?
500
if (atEOF(fCurrentOffset + 1)) {
501                     return changeReaders().lookingAtSpace(skipPastChar);
502                 }
503             }
504             return false;
505         }
506         if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
507             loadNextByte();
508         } else {
509             fCurrentOffset++;
510             if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
511                 fCurrentIndex++;
512                 try {
513                     fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
514                 } catch (ArrayIndexOutOfBoundsException JavaDoc ex) {
515                     slowLoadNextByte();
516                 }
517             } else {
518                 if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
519                     slowLoadNextByte();
520                 else
521                     fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
522             }
523         }
524         return true;
525     }
526     //
527
//
528
//
529
public void skipToChar(char ch) throws Exception JavaDoc {
530         //
531
// REVISIT - this will skip invalid characters without reporting them.
532
//
533
int b0 = fMostRecentByte;
534         while (true) {
535             if (b0 == ch) // ch will always be an ascii character
536
return;
537             if (b0 == 0) {
538                 if (atEOF(fCurrentOffset + 1)) {
539                     changeReaders().skipToChar(ch);
540                     return;
541                 }
542                 fCharacterCounter++;
543             } else if (b0 == 0x0A) {
544                 fLinefeedCounter++;
545                 fCharacterCounter = 1;
546             } else if (b0 == 0x0D) {
547                 fCarriageReturnCounter++;
548                 fCharacterCounter = 1;
549                 b0 = loadNextByte();
550                 if (b0 != 0x0A)
551                     continue;
552                 fLinefeedCounter++;
553             } else if (b0 < 0x80) { // 0xxxxxxx
554
fCharacterCounter++;
555             } else {
556                 fCharacterCounter++;
557                 if ((0xe0 & b0) == 0xc0) { // 110yyyyy 10xxxxxx
558
loadNextByte();
559                 } else if ((0xf0 & b0) == 0xe0) { // 1110zzzz 10yyyyyy 10xxxxxx
560
loadNextByte();
561                     loadNextByte();
562                 } else { // 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
563
loadNextByte();
564                     loadNextByte();
565                     loadNextByte();
566                 }
567             }
568             b0 = loadNextByte();
569         }
570     }
571     //
572
//
573
//
574
public void skipPastSpaces() throws Exception JavaDoc {
575         int ch = fMostRecentByte;
576         while (true) {
577             if (ch == 0x20 || ch == 0x09) {
578                 fCharacterCounter++;
579             } else if (ch == 0x0A) {
580                 fLinefeedCounter++;
581                 fCharacterCounter = 1;
582             } else if (ch == 0x0D) {
583                 fCarriageReturnCounter++;
584                 fCharacterCounter = 1;
585                 if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
586                     ch = loadNextByte();
587                 } else {
588                     fCurrentOffset++;
589                     if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
590                         fCurrentIndex++;
591                         try {
592                             fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
593                             ch = fMostRecentByte;
594                         } catch (ArrayIndexOutOfBoundsException JavaDoc ex) {
595                             ch = slowLoadNextByte();
596                         }
597                     } else {
598                         if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
599                             ch = slowLoadNextByte();
600                         else
601                             ch = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
602                     }
603                 }
604                 if (ch != 0x0A)
605                     continue;
606                 fLinefeedCounter++;
607             } else {
608                 if (ch == 0 && atEOF(fCurrentOffset + 1))
609                     changeReaders().skipPastSpaces();
610                 return;
611             }
612             if (USE_OUT_OF_LINE_LOAD_NEXT_BYTE) {
613                 ch = loadNextByte();
614             } else {
615                 fCurrentOffset++;
616                 if (USE_TRY_CATCH_FOR_LOAD_NEXT_BYTE) {
617                     fCurrentIndex++;
618                     try {
619                         fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF;
620                         ch = fMostRecentByte;
621                     } catch (ArrayIndexOutOfBoundsException JavaDoc ex) {
622                         ch = slowLoadNextByte();
623                     }
624                 } else {
625                     if (++fCurrentIndex == UTF8DataChunk.CHUNK_SIZE)
626                         ch = slowLoadNextByte();
627                     else
628                         ch = (fMostRecentByte = fMostRecentData[fCurrentIndex] & 0xFF);
629                 }
630             }
631         }
632     }
633     //
634
//
635
//
636
protected boolean skippedMultiByteCharWithFlag(int b0, int flag) throws Exception JavaDoc {
637         UTF8DataChunk saveChunk = fCurrentChunk;
638         int saveOffset = fCurrentOffset;
639         int saveIndex = fCurrentIndex;
640         if (!fCalledCharPropInit) {
641             XMLCharacterProperties.initCharFlags();
642             fCalledCharPropInit = true;
643         }
644         int b1 = loadNextByte();
645         if ((0xe0 & b0) == 0xc0) { // 110yyyyy 10xxxxxx
646
if ((XMLCharacterProperties.fgCharFlags[((0x1f & b0)<<6) + (0x3f & b1)] & flag) == 0) { // yyy yyxx xxxx (0x80 to 0x7ff)
647
fCurrentChunk = saveChunk;
648                 fCurrentIndex = saveIndex;
649                 fCurrentOffset = saveOffset;
650                 fMostRecentData = saveChunk.toByteArray();
651                 fMostRecentByte = b0;
652                 return false;
653             }
654             return true;
655         }
656         int b2 = loadNextByte();
657         if ((0xf0 & b0) == 0xe0) { // 1110zzzz 10yyyyyy 10xxxxxx
658
// if ((ch >= 0xD800 && ch <= 0xDFFF) || ch >= 0xFFFE)
659
if ((b0 == 0xED && b1 >= 0xA0) || (b0 == 0xEF && b1 == 0xBF && b2 >= 0xBE)) {
660                 fCurrentChunk = saveChunk;
661                 fCurrentIndex = saveIndex;
662                 fCurrentOffset = saveOffset;
663                 fMostRecentData = saveChunk.toByteArray();
664                 fMostRecentByte = b0;
665                 return false;
666             }
667             if ((XMLCharacterProperties.fgCharFlags[((0x0f & b0)<<12) + ((0x3f & b1)<<6) + (0x3f & b2)] & flag) == 0) { // zzzz yyyy yyxx xxxx (0x800 to 0xffff)
668
fCurrentChunk = saveChunk;
669                 fCurrentIndex = saveIndex;
670                 fCurrentOffset = saveOffset;
671                 fMostRecentData = saveChunk.toByteArray();
672                 fMostRecentByte = b0;
673                 return false;
674             }
675             return true;
676         } else { // 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
677
fCurrentChunk = saveChunk;
678             fCurrentIndex = saveIndex;
679             fCurrentOffset = saveOffset;
680             fMostRecentData = saveChunk.toByteArray();
681             fMostRecentByte = b0;
682             return false;
683         }
684     }
685     public void skipPastName(char fastcheck) throws Exception JavaDoc {
686         int b0 = fMostRecentByte;
687         if (b0 < 0x80) {
688             if (XMLCharacterProperties.fgAsciiInitialNameChar[b0] == 0)
689                 return;
690         } else {
691             if (!fCalledCharPropInit) {
692                 XMLCharacterProperties.initCharFlags();
693                 fCalledCharPropInit = true;
694             }
695             if (!skippedMultiByteCharWithFlag(b0, XMLCharacterProperties.E_InitialNameCharFlag))
696                 return;
697         }
698         while (true) {
699             fCharacterCounter++;
700             b0 = loadNextByte();
701             if (fastcheck == b0)
702                 return;
703             if (b0 < 0x80) {
704                 if (XMLCharacterProperties.fgAsciiNameChar[b0] == 0)
705                     return;
706            &nbs