KickJava   Java API By Example, From Geeks To Geeks.

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


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.Reader JavaDoc;
61 import java.util.Vector JavaDoc;
62
63 import org.enhydra.apache.xerces.framework.XMLErrorReporter;
64 import org.enhydra.apache.xerces.utils.CharDataChunk;
65 import org.enhydra.apache.xerces.utils.ImplementationMessages;
66 import org.enhydra.apache.xerces.utils.QName;
67 import org.enhydra.apache.xerces.utils.StringHasher;
68 import org.enhydra.apache.xerces.utils.StringPool;
69 import org.enhydra.apache.xerces.utils.XMLCharacterProperties;
70
71 /**
72  * An reader class for applications that need to process input data as
73  * it arrives on the stream.
74  *
75  * @version $Id: StreamingCharReader.java,v 1.2 2005/01/26 08:28:44 jkjome Exp $
76  */

77 public class StreamingCharReader extends XMLEntityReader {
78
79     /**
80      * Constructor
81      *
82      * @param entityHandler The entity handler.
83      * @param errorReporter The error reporter.
84      * @param sendCharDataAsCharArray true if char data should be reported using
85      * char arrays instead of string handles.
86      * @param stringPool The string pool.
87      */

88     public StreamingCharReader(XMLEntityHandler entityHandler, XMLErrorReporter errorReporter, boolean sendCharDataAsCharArray, Reader JavaDoc reader, StringPool stringPool) throws Exception JavaDoc {
89         super(entityHandler, errorReporter, sendCharDataAsCharArray);
90         fStringPool = stringPool;
91         fCharacterStream = reader;
92         fCurrentChunk = CharDataChunk.createChunk(fStringPool, null);
93         loadFirstChar();
94     }
95
96     /**
97      * Delay reporting an error message.
98      *
99      * If there is an error detected in the underlying input stream during
100      * the fillCurrentChunk method, the error is described here and will be
101      * reported when we reach that offset during normal processing. The
102      * subclass should place a character with a value of zero at that offset,
103      * which will be detected here as an invalid character. When the invalid
104      * character is scanned, we will generate the deferred exception.
105      *
106      * @param errorCode the errorCode to report
107      * @param args an array of arguments needed to generate a good error message
108      * @param offset the position in the reader where the error occured
109      */

110     protected void deferException(int errorCode, Object JavaDoc[] args, int offset) {
111         if (fDeferredErrors == null)
112             fDeferredErrors = new Vector JavaDoc();
113         DeferredError de = new DeferredError(errorCode, args, offset);
114         fDeferredErrors.addElement(de);
115     }
116
117     /**
118      * Change readers at end of input.
119      *
120      * We override our superclass method to release the final chunk
121      * of the input data before handing off to the next reader.
122      *
123      * @return The next reader used to continue processing the document.
124      */

125     protected XMLEntityHandler.EntityReader changeReaders() throws Exception JavaDoc {
126         XMLEntityHandler.EntityReader nextReader = super.changeReaders();
127         fCurrentChunk.releaseChunk();
128         fCurrentChunk = null;
129         return nextReader;
130     }
131
132     //
133
// XMLEntityHandler.EntityReader implementation
134
//
135
// The first five methods of the interface are implemented
136
// in the XMLEntityHandler base class for us, namely
137
//
138
// public int currentOffset();
139
// public int getLineNumber();
140
// public int getColumnNumber();
141
// public void setInCDSect(boolean inCDSect);
142
// public boolean getInCDSect();
143
//
144

145     /**
146      * Append the characters processed by this reader associated with <code>offset</code> and
147      * <code>length</code> to the <code>CharBuffer</code>.
148      *
149      * @param charBuffer The <code>CharBuffer</code> to append the characters to.
150      * @param offset The offset within this reader where the copy should start.
151      * @param length The length within this reader where the copy should stop.
152      */

153     public void append(XMLEntityHandler.CharBuffer charBuffer, int offset, int length) {
154         fCurrentChunk.append(charBuffer, offset, length);
155     }
156
157     /**
158      * Add a string to the <code>StringPool</code> from the characters scanned using this
159      * reader as described by <code>offset</code> and <code>length</code>.
160      *
161      * @param offset The offset within this reader where the characters start.
162      * @param length The length within this reader where the characters end.
163      * @return The <code>StringPool</code> handle for the string.
164      */

165     public int addString(int offset, int length) {
166         if (length == 0)
167             return 0;
168         return fCurrentChunk.addString(offset, length);
169     }
170
171     /**
172      * Add a symbol to the <code>StringPool</code> from the characters scanned using this
173      * reader as described by <code>offset</code> and <code>length</code>.
174      *
175      * @param offset The offset within this reader where the characters start.
176      * @param length The length within this reader where the characters end.
177      * @return The <code>StringPool</code> handle for the symbol.
178      */

179     public int addSymbol(int offset, int length) {
180         if (length == 0)
181             return 0;
182         return fCurrentChunk.addSymbol(offset, length, 0);
183     }
184
185     /**
186      *
187      */

188     public boolean lookingAtChar(char chr, boolean skipPastChar) throws Exception JavaDoc {
189         int ch = fMostRecentChar;
190         if (ch != chr) {
191             if (ch == 0) {
192                 if (atEOF(fCurrentOffset + 1)) {
193                     return changeReaders().lookingAtChar(chr, skipPastChar);
194                 }
195             }
196             return false;
197         }
198         if (skipPastChar) {
199             fCharacterCounter++;
200             loadNextChar();
201         }
202         return true;
203     }
204
205     /**
206      *
207      */

208     public boolean lookingAtValidChar(boolean skipPastChar) throws Exception JavaDoc {
209         int ch = fMostRecentChar;
210         if (ch < 0xD800) {
211             if (ch >= 0x20 || ch == 0x09) {
212                 if (skipPastChar) {
213                     fCharacterCounter++;
214                     loadNextChar();
215                 }
216                 return true;
217             }
218             if (ch == 0x0A) {
219                 if (skipPastChar) {
220                     fLinefeedCounter++;
221                     fCharacterCounter = 1;
222                     loadNextChar();
223                 }
224                 return true;
225             }
226             if (ch == 0) {
227                 if (atEOF(fCurrentOffset + 1)) {
228                     return changeReaders().lookingAtValidChar(skipPastChar);
229                 }
230             }
231             return false;
232         }
233         if (ch > 0xFFFD) {
234             return false;
235         }
236         if (ch < 0xDC00) {
237             CharDataChunk savedChunk = fCurrentChunk;
238             int savedIndex = fCurrentIndex;
239             int savedOffset = fCurrentOffset;
240             ch = loadNextChar();
241             boolean valid = (ch >= 0xDC00 && ch < 0xE000);
242             if (!valid || !skipPastChar) {
243                 fCurrentChunk = savedChunk;
244                 fCurrentIndex = savedIndex;
245                 fCurrentOffset = savedOffset;
246                 fMostRecentData = savedChunk.toCharArray();
247                 fMostRecentChar = fMostRecentData[savedIndex] & 0xFFFF;
248                 return valid;
249             }
250         } else if (ch < 0xE000) {
251             return false;
252         }
253         if (skipPastChar) {
254             fCharacterCounter++;
255             loadNextChar();
256         }
257         return true;
258     }
259
260     /**
261      *
262      */

263     public boolean lookingAtSpace(boolean skipPastChar) throws Exception JavaDoc {
264         int ch = fMostRecentChar;
265         if (ch > 0x20)
266             return false;
267         if (ch == 0x20 || ch == 0x09) {
268             if (!skipPastChar)
269                 return true;
270             fCharacterCounter++;
271         } else if (ch == 0x0A) {
272             if (!skipPastChar)
273                 return true;
274             fLinefeedCounter++;
275             fCharacterCounter = 1;
276         } else {
277             if (ch == 0) { // REVISIT - should we be checking this here ?
278
if (atEOF(fCurrentOffset + 1)) {
279                     return changeReaders().lookingAtSpace(skipPastChar);
280                 }
281             }
282             return false;
283         }
284         loadNextChar();
285         return true;
286     }
287
288     /**
289      *
290      */

291     public void skipToChar(char chr) throws Exception JavaDoc {
292         //
293
// REVISIT - this will skip invalid characters without reporting them.
294
//
295
int ch = fMostRecentChar;
296         while (true) {
297             if (ch == chr)
298                 return;
299             if (ch == 0) {
300                 if (atEOF(fCurrentOffset + 1)) {
301                     changeReaders().skipToChar(chr);
302                     return;
303                 }
304                 fCharacterCounter++;
305             } else if (ch == 0x0A) {
306                 fLinefeedCounter++;
307                 fCharacterCounter = 1;
308             } else if (ch >= 0xD800 && ch < 0xDC00) {
309                 fCharacterCounter++;
310                 ch = loadNextChar();
311                 if (ch < 0xDC00 || ch >= 0xE000)
312                     continue;
313             } else
314                 fCharacterCounter++;
315             ch = loadNextChar();
316         }
317     }
318
319     /**
320      *
321      */

322     public void skipPastSpaces() throws Exception JavaDoc {
323         int ch = fMostRecentChar;
324         while (true) {
325             if (ch == 0x20 || ch == 0x09) {
326                 fCharacterCounter++;
327             } else if (ch == 0x0A) {
328                 fLinefeedCounter++;
329                 fCharacterCounter = 1;
330             } else {
331                 if (ch == 0 && atEOF(fCurrentOffset + 1))
332                     changeReaders().skipPastSpaces();
333                 return;
334             }
335             ch = loadNextChar();
336         }
337     }
338
339     /**
340      *
341      */

342     public void skipPastName(char fastcheck) throws Exception JavaDoc {
343         int ch = fMostRecentChar;
344         if (ch < 0x80) {
345             if (XMLCharacterProperties.fgAsciiInitialNameChar[ch] == 0)
346                 return;
347         } else {
348             if (!fCalledCharPropInit) {
349                 XMLCharacterProperties.initCharFlags();
350                 fCalledCharPropInit = true;
351             }
352             if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_InitialNameCharFlag) == 0)
353                 return;
354         }
355         while (true) {
356             fCharacterCounter++;
357             ch = loadNextChar();
358             if (fastcheck == ch)
359                 return;
360             if (ch < 0x80) {
361                 if (XMLCharacterProperties.fgAsciiNameChar[ch] == 0)
362                     return;
363             } else {
364                 if (!fCalledCharPropInit) {
365                     XMLCharacterProperties.initCharFlags();
366                     fCalledCharPropInit = true;
367                 }
368                 if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
369                     return;
370             }
371         }
372     }
373
374     /**
375      *
376      */

377     public void skipPastNmtoken(char fastcheck) throws Exception JavaDoc {
378         int ch = fMostRecentChar;
379         while (true) {
380             if (fastcheck == ch)
381                 return;
382             if (ch < 0x80) {
383                 if (XMLCharacterProperties.fgAsciiNameChar[ch] == 0)
384                     return;
385             } else {
386                 if (!fCalledCharPropInit) {
387                     XMLCharacterProperties.initCharFlags();
388                     fCalledCharPropInit = true;
389                 }
390                 if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
391                     return;
392             }
393             fCharacterCounter++;
394             ch = loadNextChar();
395         }
396     }
397
398     /**
399      *
400      */

401     public boolean skippedString(char[] s) throws Exception JavaDoc {
402         int ch = fMostRecentChar;
403         if (ch != s[0])
404             return false;
405         int length = s.length;
406         CharDataChunk dataChunk = fCurrentChunk;
407         int offset = fCurrentOffset;
408         int index = fCurrentIndex;
409         ch = loadNextChar();
410         for (int i = 1; i < length; i++) {
411             if (ch != s[i]) {
412                 fCurrentChunk = dataChunk;
413                 fCurrentIndex = index;
414                 fCurrentOffset = offset;
415                 fMostRecentData = dataChunk.toCharArray();
416                 fMostRecentChar = fMostRecentData[index] & 0xFFFF;
417                 return false;
418             }
419             ch = loadNextChar();
420         }
421         fCharacterCounter += length;
422         return true;
423     }
424
425     /**
426      *
427      */

428     public int scanInvalidChar() throws Exception JavaDoc {
429         int ch = fMostRecentChar;
430         if (ch == 0x0A) {
431             fLinefeedCounter++;
432             fCharacterCounter = 1;
433             loadNextChar();
434         } else if (ch == 0) {
435             if (atEOF(fCurrentOffset + 1)) {
436                 return changeReaders().scanInvalidChar();
437             }
438             if (fDeferredErrors != null) {
439                 for (int i = 0; i < fDeferredErrors.size(); i++) {
440                     DeferredError de = (DeferredError)fDeferredErrors.elementAt(i);
441                     if (de.offset == fCurrentIndex) {
442                         fErrorReporter.reportError(fErrorReporter.getLocator(),
443                                                    ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
444                                                    de.errorCode,
445                                                    0,
446                                                    de.args,
447                                                    XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
448                         fDeferredErrors.removeElementAt(i);
449                         fCharacterCounter++;
450                         loadNextChar();
451                         return -1;
452                     }
453                 }
454             }
455             fCharacterCounter++;
456             loadNextChar();
457         } else {
458             fCharacterCounter++;
459             if (ch >= 0xD800 && ch < 0xDC00) {
460                 int ch2 = loadNextChar();
461                 if (ch2 >= 0xDC00 && ch2 < 0xE000) {
462                     ch = ((ch-0xD800)<<10)+(ch2-0xDC00)+0x10000;
463                     loadNextChar();
464                 }
465             } else
466                 loadNextChar();
467         }
468         return ch;
469     }
470
471     /**
472      *
473      */

474     public int scanCharRef(boolean hex) throws Exception JavaDoc {
475         int ch = fMostRecentChar;
476         if (ch == 0) {
477             if (atEOF(fCurrentOffset + 1)) {
478                 return changeReaders().scanCharRef(hex);
479             }
480             return XMLEntityHandler.CHARREF_RESULT_INVALID_CHAR;
481         }
482         int num = 0;
483         if (hex) {
484             if (ch > 'f' || XMLCharacterProperties.fgAsciiXDigitChar[ch] == 0)
485                 return XMLEntityHandler.CHARREF_RESULT_INVALID_CHAR;
486             num = ch - (ch < 'A' ? '0' : (ch < 'a' ? 'A' : 'a') - 10);
487         } else {
488             if (ch < '0' || ch > '9')
489                 return XMLEntityHandler.CHARREF_RESULT_INVALID_CHAR;
490             num = ch - '0';
491         }
492         fCharacterCounter++;
493         loadNextChar();
494         boolean toobig = false;
495         while (true) {
496             ch = fMostRecentChar;
497             if (ch == 0)
498                 break;
499             if (hex) {
500                 if (ch > 'f' || XMLCharacterProperties.fgAsciiXDigitChar[ch] == 0)
501                     break;
502             } else {
503                 if (ch < '0' || ch > '9')
504                     break;
505             }
506             fCharacterCounter++;
507             loadNextChar();
508             if (hex) {
509                 int dig = ch - (ch < 'A' ? '0' : (ch < 'a' ? 'A' : 'a') - 10);
510                 num = (num << 4) + dig;
511             } else {
512                 int dig = ch - '0';
513                 num = (num * 10) + dig;
514             }
515             if (num > 0x10FFFF) {
516                 toobig = true;
517                 num = 0;
518             }
519         }
520         if (ch != ';')
521             return XMLEntityHandler.CHARREF_RESULT_SEMICOLON_REQUIRED;
522         fCharacterCounter++;
523         loadNextChar();
524         if (toobig)
525             return XMLEntityHandler.CHARREF_RESULT_OUT_OF_RANGE;
526         return num;
527     }
528
529     /**
530      *
531      */

532     public int scanStringLiteral() throws Exception JavaDoc {
533         boolean single;
534         if (!(single = lookingAtChar('\'', true)) && !lookingAtChar('\"', true)) {
535             return XMLEntityHandler.STRINGLIT_RESULT_QUOTE_REQUIRED;
536         }
537         int offset = fCurrentOffset;
538         char qchar = single ? '\'' : '\"';
539         while (!lookingAtChar(qchar, false)) {
540             if (!lookingAtValidChar(true)) {
541                 return XMLEntityHandler.STRINGLIT_RESULT_INVALID_CHAR;
542             }
543         }
544         int stringIndex = addString(offset, fCurrentOffset - offset);
545         lookingAtChar(qchar, true); // move past qchar
546
return stringIndex;
547     }
548
549     //
550
// [10] AttValue ::= '"' ([^<&"] | Reference)* '"'
551
// | "'" ([^<&'] | Reference)* "'"
552
//
553
/**
554      *
555      */

556     public int scanAttValue(char qchar, boolean asSymbol) throws Exception JavaDoc
557     {
558         int offset = fCurrentOffset;
559         while (true) {
560             if (lookingAtChar(qchar, false)) {
561                 break;
562             }
563             if (lookingAtChar(' ', true)) {
564                 continue;
565             }
566             if (lookingAtSpace(false)) {
567                 return XMLEntityHandler.ATTVALUE_RESULT_COMPLEX;
568             }
569             if (lookingAtChar('&', false)) {
570                 return XMLEntityHandler.ATTVALUE_RESULT_COMPLEX;
571             }
572             if (lookingAtChar('<', false)) {
573                 return XMLEntityHandler.ATTVALUE_RESULT_LESSTHAN;
574             }
575             if (!lookingAtValidChar(true)) {
576                 return XMLEntityHandler.ATTVALUE_RESULT_INVALID_CHAR;
577             }
578         }
579         int result = asSymbol ? addSymbol(offset, fCurrentOffset - offset) : addString(offset, fCurrentOffset - offset);
580         lookingAtChar(qchar, true);
581         return result;
582     }
583
584     //
585
// [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"'
586
// | "'" ([^%&'] | PEReference | Reference)* "'"
587
//
588
/**
589      *
590      */

591     public int scanEntityValue(int qchar, boolean createString) throws Exception JavaDoc
592     {
593         int offset = fCurrentOffset;
594         while (true) {
595             if (atEOF(fCurrentOffset + 1)) {
596                 changeReaders();
597                 return XMLEntityHandler.ENTITYVALUE_RESULT_END_OF_INPUT;
598             }
599             if (qchar != -1 && lookingAtChar((char)qchar, false)) {
600                 if (!createString)
601                     return XMLEntityHandler.ENTITYVALUE_RESULT_FINISHED;
602                 break;
603             }
604             if (lookingAtChar('&', false)) {
605                 return XMLEntityHandler.ENTITYVALUE_RESULT_REFERENCE;
606             }
607             if (lookingAtChar('%', false)) {
608                 return XMLEntityHandler.ENTITYVALUE_RESULT_PEREF;
609             }
610             if (!lookingAtValidChar(true)) {
611                 return XMLEntityHandler.ENTITYVALUE_RESULT_INVALID_CHAR;
612             }
613         }
614         int result = addString(offset, fCurrentOffset - offset);
615         lookingAtChar((char)qchar, true);
616         return result;
617     }
618
619     /**
620      *
621      */

622     public int scanName(char fastcheck) throws Exception JavaDoc {
623         int ch = fMostRecentChar;
624         if (ch < 0x80) {
625             if (XMLCharacterProperties.fgAsciiInitialNameChar[ch] == 0)
626                 return -1;
627         } else {
628             if (!fCalledCharPropInit) {
629                 XMLCharacterProperties.initCharFlags();
630                 fCalledCharPropInit = true;
631             }
632             if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_InitialNameCharFlag) == 0)
633                 return -1;
634         }
635         int offset = fCurrentOffset;
636         fCharacterCounter++;
637         int hashcode = 0;
638         while (true) {
639             hashcode = StringHasher.hashChar(hashcode, ch);
640             ch = loadNextChar();
641             if (fastcheck == ch)
642                 break;
643             if (ch < 0x80) {
644                 if (XMLCharacterProperties.fgAsciiNameChar[ch] == 0)
645                     break;
646             } else {
647                 if (!fCalledCharPropInit) {
648                     XMLCharacterProperties.initCharFlags();
649                     fCalledCharPropInit = true;
650                 }
651                 if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
652                     break;
653             }
654             fCharacterCounter++;
655         }
656         hashcode = StringHasher.finishHash(hashcode);
657         int length = fCurrentOffset - offset;
658         int nameIndex = fCurrentChunk.addSymbol(offset, length, hashcode);
659         return nameIndex;
660     }
661
662     /**
663      *
664      */

665     public boolean scanExpectedName(char fastcheck, StringPool.CharArrayRange expectedName) throws Exception JavaDoc {
666         char[] expected = expectedName.chars;
667         int offset = expectedName.offset;
668         int len = expectedName.length;
669         int ch = fMostRecentChar;
670         for (int i = 0; i < len; i++) {
671             if (ch != expected[offset++]) {
672                 skipPastNmtoken(fastcheck);
673                 return false;
674             }
675             fCharacterCounter++;
676             ch = loadNextChar();
677         }
678         if (ch == fastcheck)
679             return true;
680         if (ch < 0x80) {
681             if (XMLCharacterProperties.fgAsciiNameChar[ch] == 0)
682                 return true;
683         } else {
684             if (!fCalledCharPropInit) {
685                 XMLCharacterProperties.initCharFlags();
686                 fCalledCharPropInit = true;
687             }
688             if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
689                 return true;
690         }
691         skipPastNmtoken(fastcheck);
692         return false;
693     }
694
695     /**
696      *
697      */

698     public void scanQName(char fastcheck, QName qname) throws Exception JavaDoc {
699         int ch = fMostRecentChar;
700         if (ch < 0x80) {
701             if (XMLCharacterProperties.fgAsciiInitialNameChar[ch] == 0) {
702                 qname.clear();
703                 return;
704             }
705             if (ch == ':') {
706                 qname.clear();
707                 return;
708             }
709         } else {
710             if (!fCalledCharPropInit) {
711                 XMLCharacterProperties.initCharFlags();
712                 fCalledCharPropInit = true;
713             }
714             if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_InitialNameCharFlag) == 0) {
715                 qname.clear();
716                 return;
717             }
718         }
719         int offset = fCurrentOffset;
720         fCharacterCounter++;
721         int hashcode = 0;
722         int prefixend = -1;
723         while (true) {
724             hashcode = StringHasher.hashChar(hashcode, ch);
725             ch = loadNextChar();
726             if (fastcheck == ch)
727                 break;
728             if (ch < 0x80) {
729                 if (XMLCharacterProperties.fgAsciiNameChar[ch] == 0)
730                     break;
731                 if (ch == ':') {
732                     if (prefixend != -1)
733                         break;
734                     prefixend = fCurrentOffset;
735                     //
736
// We need to peek ahead one character. If the next character is not a
737
// valid initial name character, or is another colon, then we cannot meet
738
// both the Prefix and LocalPart productions for the QName production,
739
// which means that there is no Prefix and we need to terminate the QName
740
// at the first colon.
741
//
742
CharDataChunk savedChunk = fCurrentChunk;
743                     int savedOffset = fCurrentOffset;
744                     int savedIndex = fCurrentIndex;
745                     ch = loadNextChar();
746                     fCurrentChunk = savedChunk;
747                     fCurrentOffset = savedOffset;
748                     fCurrentIndex = savedIndex;
749                     fMostRecentData = savedChunk.toCharArray();
750                     boolean lpok = true;
751                     if (ch < 0x80) {
752                         if (XMLCharacterProperties.fgAsciiInitialNameChar[ch] == 0 || ch == ':')
753                             lpok = false;
754                     } else {
755                         if (!fCalledCharPropInit) {
756                             XMLCharacterProperties.initCharFlags();
757                             fCalledCharPropInit = true;
758                         }
759                         if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_InitialNameCharFlag) == 0)
760                             lpok = false;
761                     }
762                     ch = ':';
763                     if (!lpok) {
764                         prefixend = -1;
765                         fMostRecentChar = ch;
766                         break;
767                     }
768                 }
769             } else {
770                 if (!fCalledCharPropInit) {
771                     XMLCharacterProperties.initCharFlags();
772                     fCalledCharPropInit = true;
773                 }
774                 if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
775                     break;
776             }
777             fCharacterCounter++;
778         }
779         hashcode = StringHasher.finishHash(hashcode);
780         int length = fCurrentOffset - offset;
781         qname.rawname = fCurrentChunk.addSymbol(offset, length, hashcode);
782         qname.prefix = prefixend == -1 ? -1 : addSymbol(offset, prefixend - offset);
783         qname.localpart = prefixend == -1 ? qname.rawname : addSymbol(prefixend + 1, fCurrentOffset - (prefixend + 1));
784         qname.uri = StringPool.EMPTY_STRING;
785
786     } // scanQName(char,QName)
787

788     //
789
// [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
790
//
791
/**
792      *
793      */

794     public int scanContent(QName element) throws Exception JavaDoc {
795         if (fCallClearPreviousChunk && fCurrentChunk.clearPreviousChunk())
796             fCallClearPreviousChunk = false;
797         int charDataOffset = fCurrentOffset;
798         int ch = fMostRecentChar;
799         if (ch < 0x80) {
800             switch (XMLCharacterProperties.fgAsciiWSCharData[ch]) {
801             case 0:
802                 fCharacterCounter++;
803                 ch = loadNextChar();
804                 break;
805             case 1: // '<'
806
fCharacterCounter++;
807                 ch = loadNextChar();
808                 if (!fInCDSect) {
809                     return recognizeMarkup(ch);
810                 }
811                 break;
812             case 2: // '&'
813
fCharacterCounter++;
814                 ch = loadNextChar();
815                 if (!fInCDSect) {
816                     return recognizeReference(ch);
817                 }
818                 break;
819             case 3: // ']'
820
fCharacterCounter++;
821                 ch = loadNextChar();
822                 if (ch != ']')
823                     break;
824                 {
825                     CharDataChunk dataChunk = fCurrentChunk;
826                     int index = fCurrentIndex;
827                     int offset = fCurrentOffset;
828                     if (loadNextChar() != '>') {
829                         fCurrentChunk = dataChunk;
830                         fCurrentIndex = index;
831                         fCurrentOffset = offset;
832                         fMostRecentData = dataChunk.toCharArray();
833                         fMostRecentChar = ']';
834                         break;
835                     }
836                 }
837                 loadNextChar();
838                 fCharacterCounter += 2;
839                 return XMLEntityHandler.CONTENT_RESULT_END_OF_CDSECT;
840             case 4: // invalid char
841
if (ch == 0 && atEOF(fCurrentOffset + 1)) {
842                     changeReaders();
843                     return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR; // REVISIT - not quite...
844
}
845                 return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
846             case 5:
847                 do {
848                     if (ch == 0x0A) {
849                         fLinefeedCounter++;
850                         fCharacterCounter = 1;
851                     } else
852                         fCharacterCounter++;
853                     ch = loadNextChar();
854                 } while (ch == 0x20 || ch == 0x09 || ch == 0x0A);
855                 if (ch < 0x80) {
856                     switch (XMLCharacterProperties.fgAsciiCharData[ch]) {
857                     case 0:
858                         fCharacterCounter++;
859                         ch = loadNextChar();
860                         break;
861                     case 1: // '<'
862
if (!fInCDSect) {
863                             callCharDataHandler(charDataOffset, fCurrentOffset, true);
864                             fCharacterCounter++;
865                             ch = loadNextChar();
866                             return recognizeMarkup(ch);
867                         }
868                         fCharacterCounter++;
869                         ch = loadNextChar();
870                         break;
871                     case 2: // '&'
872
if (!fInCDSect) {
873                             callCharDataHandler(charDataOffset, fCurrentOffset, true);
874                             fCharacterCounter++;
875                             ch = loadNextChar();
876                             return recognizeReference(ch);
877                         }
878                         fCharacterCounter++;
879                         ch = loadNextChar();
880                         break;
881                     case 3: // ']'
882
int endOffset = fCurrentOffset;
883                         ch = loadNextChar();
884                         if (ch != ']') {
885                             fCharacterCounter++;
886                             break;
887                         }
888                         {
889                             CharDataChunk dataChunk = fCurrentChunk;
890                             int index = fCurrentIndex;
891                             int offset = fCurrentOffset;
892                             if (loadNextChar() != '>') {
893                                 fCurrentChunk = dataChunk;
894                                 fCurrentIndex = index;
895                                 fCurrentOffset = offset;
896                                 fMostRecentData = dataChunk.toCharArray();
897                                 fMostRecentChar = ']';
898                                 fCharacterCounter++;
899                                 break;
900                             }
901                         }
902                         loadNextChar();
903                         callCharDataHandler(charDataOffset, endOffset, true);
904                         fCharacterCounter += 3;
905                         return XMLEntityHandler.CONTENT_RESULT_END_OF_CDSECT;
906                     case 4: // invalid char
907
callCharDataHandler(charDataOffset, fCurrentOffset, true);
908                         if (ch == 0 && atEOF(fCurrentOffset + 1)) {
909                             changeReaders();
910                             return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR; // REVISIT - not quite...
911
}
912                         return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
913                     }
914                 } else if (!skipMultiByteCharData(ch)) {
915                     callCharDataHandler(charDataOffset, fCurrentOffset, true);
916                     return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
917                 }
918                 break;
919             }
920         } else if (!skipMultiByteCharData(ch)) {
921             return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
922         }
923         ch = skipAsciiCharData();
924         while (true) {
925             if (ch < 0x80) {
926                 switch (XMLCharacterProperties.fgAsciiCharData[ch]) {
927                 case 0:
928                     fCharacterCounter++;
929                     ch = loadNextChar();
930                     break;
931                 case 1: // '<'
932
if (!fInCDSect) {
933                         callCharDataHandler(charDataOffset, fCurrentOffset, false);
934                         fCharacterCounter++;
935                         ch = loadNextChar();
936                         return recognizeMarkup(ch);
937                     }
938                     fCharacterCounter++;
939                     ch = loadNextChar();
940                     break;
941                 case 2: // '&'
942
if (!fInCDSect) {
943                         callCharDataHandler(charDataOffset, fCurrentOffset, false);
944                         fCharacterCounter++;
945                         ch = loadNextChar();
946                         return recognizeReference(ch);
947                     }
948                     fCharacterCounter++;
949                     ch = loadNextChar();
950                     break;
951                 case 3: // ']'
952
int endOffset = fCurrentOffset;
953                     ch = loadNextChar();
954                     if (ch != ']') {
955                         fCharacterCounter++;
956                         break;
957                     }
958                     CharDataChunk dataChunk = fCurrentChunk;
959                     int index = fCurrentIndex;
960                     int offset = fCurrentOffset;
961                     if (loadNextChar() != '>') {
962                         fCurrentChunk = dataChunk;
963                         fCurrentIndex = index;
964                         fCurrentOffset = offset;
965                         fMostRecentData = dataChunk.toCharArray();
966                         fMostRecentChar = ']';
967                         fCharacterCounter++;
968                         break;
969                     }
970                     loadNextChar();
971                     callCharDataHandler(charDataOffset, endOffset, false);
972                     fCharacterCounter += 3;
973                     return XMLEntityHandler.CONTENT_RESULT_END_OF_CDSECT;
974                 case 4: // invalid char
975
if (ch == 0x0A) {
976                         fLinefeedCounter++;
977                         fCharacterCounter = 1;
978                         ch = loadNextChar();
979                         break;
980                     }
981                     callCharDataHandler(charDataOffset, fCurrentOffset, false);
982                     if (ch == 0 && atEOF(fCurrentOffset + 1)) {
983                         changeReaders();
984                         return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR; // REVISIT - not quite...
985
}
986                     return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
987                 }
988             } else {
989                 if (!skipMultiByteCharData(ch)) {
990                     callCharDataHandler(charDataOffset, fCurrentOffset, false);
991                     return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
992                 }
993                 ch = fMostRecentChar;
994             }
995         }
996     }
997
998     //
999
// Private data members
1000
//
1001
private static final char[] cdata_string = { 'C','D','A','T','A','[' };
1002    private StringPool fStringPool = null;
1003    private boolean fCallClearPreviousChunk = true;
1004    private Vector JavaDoc fDeferredErrors = null;
1005
1006    //
1007
// Private classes
1008
//
1009
private class DeferredError {
1010        int errorCode;
1011        Object JavaDoc[] args;
1012        int offset;
1013        DeferredError(int ec, Object JavaDoc[] a, int o) {
1014            errorCode = ec;
1015            args = a;
1016            offset = o;
1017        }
1018    }
1019
1020    //
1021
// Private methods
1022
//
1023

1024    /*
1025     * Return a result code for scanContent when the character data
1026     * ends with a less-than character.
1027     */

1028    private int recognizeMarkup(int ch) throws Exception JavaDoc {
1029        switch (ch) {
1030        case 0:
1031            return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
1032        case '?':
1033            fCharacterCounter++;
1034            loadNextChar();
1035            return XMLEntityHandler.CONTENT_RESULT_START_OF_PI;
1036        case '!':
1037            fCharacterCounter++;
1038            ch = loadNextChar();
1039            if (ch == 0) {
1040                fCharacterCounter--;
1041                fCurrentOffset--;
1042                return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
1043            }
1044            if (ch == '-') {
1045                fCharacterCounter++;
1046                ch = loadNextChar();
1047                if (ch == 0) {
1048                    fCharacterCounter -= 2;
1049                    fCurrentOffset -= 2;
1050                    return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
1051                }
1052                if (ch == '-') {
1053                    fCharacterCounter++;
1054                    loadNextChar();
1055                    return XMLEntityHandler.CONTENT_RESULT_START_OF_COMMENT;
1056                }
1057                break;
1058            }
1059            if (ch == '[') {
1060                for (int i = 0; i < 6; i++) {
1061                    fCharacterCounter++;
1062                    ch = loadNextChar();
1063                    if (ch == 0) {
1064                        fCharacterCounter -= (2 + i);
1065                        fCurrentOffset -= (2 + i);
1066                        return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
1067                    }
1068                    if (ch != cdata_string[i]) {
1069                        return XMLEntityHandler.CONTENT_RESULT_MARKUP_NOT_RECOGNIZED;
1070                    }
1071                }
1072                fCharacterCounter++;
1073                loadNextChar();
1074                return XMLEntityHandler.CONTENT_RESULT_START_OF_CDSECT;
1075            }
1076            break;
1077        case '/':
1078            fCharacterCounter++;
1079            loadNextChar();
1080            return XMLEntityHandler.CONTENT_RESULT_START_OF_ETAG;
1081        default:
1082            return XMLEntityHandler.CONTENT_RESULT_START_OF_ELEMENT;
1083        }
1084        return XMLEntityHandler.CONTENT_RESULT_MARKUP_NOT_RECOGNIZED;
1085    }
1086
1087    /*
1088     * Return a result code for scanContent when the character data
1089     * ends with an ampersand character.
1090     */

1091    private int recognizeReference(int ch) throws Exception JavaDoc {
1092        if (ch == 0) {
1093            return XMLEntityHandler.CONTENT_RESULT_REFERENCE_END_OF_INPUT;
1094        }
1095        //
1096
// [67] Reference ::= EntityRef | CharRef
1097
// [68] EntityRef ::= '&' Name ';'
1098
// [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'
1099
//
1100
if (ch == '#') {
1101            fCharacterCounter++;
1102            loadNextChar();
1103            return XMLEntityHandler.CONTENT_RESULT_START_OF_CHARREF;
1104        } else {
1105            return XMLEntityHandler.CONTENT_RESULT_START_OF_ENTITYREF;
1106        }
1107    }
1108
1109    /*
1110     * Skip over a multi-byte character.
1111     */

1112    private boolean skipMultiByteCharData(int ch) throws Exception JavaDoc {
1113        if (ch < 0xD800) {
1114            loadNextChar();
1115            return true;
1116        }
1117        if (ch > 0xFFFD)
1118            return false;
1119        if (ch >= 0xDC00 && ch < 0xE000)
1120            return false;
1121        if (ch >= 0xD800 && ch < 0xDC00) {
1122            CharDataChunk savedChunk = fCurrentChunk;
1123            int savedIndex = fCurrentIndex;
1124            int savedOffset = fCurrentOffset;
1125            ch = loadNextChar();
1126            if (ch < 0xDC00 || ch >= 0xE000) {
1127                fCurrentChunk = savedChunk;
1128                fCurrentIndex = savedIndex;
1129                fCurrentOffset = savedOffset;
1130                fMostRecentData = savedChunk.toCharArray();
1131                fMostRecentChar = fMostRecentData[savedIndex] & 0xFFFF;
1132                return false;
1133            }
1134        }
1135        loadNextChar();
1136        return true;
1137    }
1138
1139    /*
1140     * Skip over contiguous ascii character data.
1141     *
1142     * @return the character skipped
1143     * @exception java.lang.Exception
1144     */

1145    private int skipAsciiCharData() throws Exception JavaDoc {
1146        int ch = fMostRecentChar;
1147        while (true) {
1148            if (ch >= 0x80) {
1149                return ch;
1150            }
1151            if (XMLCharacterProperties.fgAsciiCharData[ch] == 0) {
1152                fCharacterCounter++;
1153            } else if (ch == 0x0A) {
1154                fLinefeedCounter++;
1155                fCharacterCounter = 1;
1156            } else {
1157                return ch;
1158            }
1159            ch = loadNextChar();
1160        }
1161    }
1162
1163    /*
1164     * Report character data to the parser through the entity handler interface.
1165     *
1166     * @param offset the offset of the start of the character data
1167     * @param endOffset the offset of the end of the character data
1168     * @param isWhitespace true if the character data is whitespace
1169     * @exception java.lang.Exception
1170     */

1171    private void callCharDataHandler(int offset, int endOffset, boolean isWhitespace) throws Exception JavaDoc {
1172
1173        int length = endOffset - offset;
1174        if (!fSendCharDataAsCharArray) {
1175            int stringIndex = addString(offset, length);
1176            if (isWhitespace)
1177                fCharDataHandler.processWhitespace(stringIndex);
1178            else
1179                fCharDataHandler.processCharacters(stringIndex);
1180            return;
1181        }
1182
1183        CharDataChunk dataChunk = fCurrentChunk.chunkFor(offset);
1184        int index = offset & CharDataChunk.CHUNK_MASK;
1185        if (index + length <= CharDataChunk.CHUNK_SIZE) {
1186            //
1187
// All the chars are in the same chunk
1188
//
1189
if (length != 0) {
1190                if (isWhitespace)
1191                    fCharDataHandler.processWhitespace(dataChunk.toCharArray(), index, length);
1192                else
1193                    fCharDataHandler.processCharacters(dataChunk.toCharArray(), index, length);
1194            }
1195            return;
1196        }
1197
1198        //
1199
// The data is spread across chunks.
1200
//
1201
int count = length;
1202        int nbytes = CharDataChunk.CHUNK_SIZE - index;
1203        if (isWhitespace)
1204            fCharDataHandler.processWhitespace(dataChunk.toCharArray(), index, nbytes);
1205        else
1206            fCharDataHandler.processCharacters(dataChunk.toCharArray(), index, nbytes);
1207        count -= nbytes;
1208
1209        //
1210
// Use each Chunk in turn until we are done.
1211
//
1212
do {
1213            dataChunk = dataChunk.nextChunk();
1214            if (dataChunk == null) {
1215                throw new RuntimeException JavaDoc(new ImplementationMessages().createMessage(null, ImplementationMessages.INT_DCN, 0, null));
1216            }
1217            nbytes = count <= CharDataChunk.CHUNK_SIZE ? count : CharDataChunk.CHUNK_SIZE;
1218            if (isWhitespace)
1219                fCharDataHandler.processWhitespace(dataChunk.toCharArray(), 0, nbytes);
1220            else
1221                fCharDataHandler.processCharacters(dataChunk.toCharArray(), 0, nbytes);
1222            count -= nbytes;
1223        } while (count > 0);
1224    }
1225
1226    /*
1227     * Advance the reader's notion of where it is, moving on to the next chunk.
1228     *
1229     * @return The next character that will be processed.
1230     * @exception java.lang.Exception
1231     */

1232    private int slowLoadNextChar() throws Exception JavaDoc {
1233        fCallClearPreviousChunk = true;
1234        if (fCurrentChunk.nextChunk() != null) {
1235            fCurrentChunk = fCurrentChunk.nextChunk();
1236            fCurrentIndex = 0;
1237            fMostRecentData = fCurrentChunk.toCharArray();
1238            return (fMostRecentChar = fMostRecentData[fCurrentIndex] & 0xFFFF);
1239        } else {
1240            fCurrentChunk = CharDataChunk.createChunk(fStringPool, fCurrentChunk);
1241            fCurrentIndex = 0;
1242            fFillIndex = 0;
1243            loadFirstChar();
1244            return fMostRecentChar;
1245        }
1246    }
1247
1248    /*
1249     * Advance the reader's notion of where it is
1250     *
1251     * @return The next character that will be processed.
1252     * @exception java.lang.Exception
1253     */

1254    private int loadNextChar() throws Exception JavaDoc {
1255        fCurrentOffset++;
1256        if (++fCurrentIndex == CharDataChunk.CHUNK_SIZE)
1257            return slowLoadNextChar();
1258        if (fCurrentIndex < fFillIndex)
1259            return (fMostRecentChar = fMostRecentData[fCurrentIndex] & 0xFFFF);
1260        return loadMoreChars();
1261    }
1262
1263    /*
1264     * Read the first character.
1265     *
1266     * @exception java.lang.Exception
1267     */

1268    private void loadFirstChar() throws Exception JavaDoc {
1269        fMostRecentData = fCurrentChunk.toCharArray();
1270        if (fMostRecentData == null) {
1271            fMostRecentData = new char[CharDataChunk.CHUNK_SIZE];
1272            fCurrentChunk.setCharArray(fMostRecentData);
1273        }
1274        loadMoreChars();
1275    }
1276
1277    /*
1278     * Fetch more characters.
1279     *
1280     * @exception java.lang.Exception
1281     */

1282    private boolean seenCR = false;
1283    private int oweChar = -1;
1284    private char[] inBuffer = new char[2];
1285    private int loadMoreChars() throws Exception JavaDoc {
1286        if (oweChar != -1) {
1287            fMostRecentData[fFillIndex] = (char)oweChar;
1288            fFillIndex++;
1289            fLength++;
1290            fMostRecentChar = oweChar;
1291            oweChar = -1;
1292            return fMostRecentChar;
1293        }
1294        int result = -1;
1295        try {
1296            while (true) {
1297                result = fCharacterStream.read(inBuffer, 0, 2);
1298                switch (result) {
1299                case -1:
1300                    break;
1301                case 0:
1302                    continue;
1303                case 1:
1304                    result = inBuffer[0];
1305                    if (seenCR) {
1306                        seenCR = false;
1307                        if (result == 0x0A)
1308                            continue;
1309                    }
1310                    if (result == 0x0D) {
1311                        seenCR = true;
1312                        result = 0x0A;
1313                    }
1314                    fMostRecentChar = (fMostRecentData[fFillIndex] = (char)result);
1315                    fFillIndex++;
1316                    fLength++;
1317                    return fMostRecentChar;
1318                case 2:
1319                    result = inBuffer[0];
1320                    boolean readchar2 = false;
1321                    if (seenCR) {
1322                        seenCR = false;
1323                        if (result == 0x0A) {
1324                            result = inBuffer[1];
1325                            readchar2 = true;
1326                        }
1327                    }
1328                    if (result == 0x0D) {
1329                        seenCR = true;
1330                        result = 0x0A;
1331                    }
1332                    fMostRecentChar = (fMostRecentData[fFillIndex] = (char)result);
1333                    fFillIndex++;
1334                    fLength++;
1335                    if (!readchar2) {
1336                        result = inBuffer[1];
1337                        if (seenCR) {
1338                            seenCR = false;
1339                            if (result == 0x0A)
1340                                return fMostRecentChar;
1341                        }
1342                        if (result == 0x0D) {
1343                            seenCR = true;
1344                            result = 0x0A;
1345                        }
1346                        oweChar = result;
1347                    }
1348                    return fMostRecentChar;
1349                }
1350                break;
1351            }
1352        } catch (java.io.IOException JavaDoc ex) {
1353        }
1354        //
1355
// We have reached the end of the stream.
1356
//
1357
try {
1358            fCharacterStream.close();
1359        } catch (java.io.IOException JavaDoc ex) {
1360        }
1361        fCharacterStream = null;
1362        fMostRecentChar = (fMostRecentData[fFillIndex] = 0);
1363        return 0;
1364    }
1365
1366    /*
1367     * Would the reader be at end of file at a given offset?
1368     *
1369     * @param offset the offset to test for being at EOF
1370     * @return true if being at offset would mean being at or beyond EOF
1371     */

1372    private boolean atEOF(int offset) {
1373        return (offset > fLength);
1374    }
1375
1376    //
1377
//
1378
//
1379
protected Reader JavaDoc fCharacterStream = null;
1380    protected CharDataChunk fCurrentChunk = null;
1381    protected int fCurrentIndex = 0;
1382    protected int fFillIndex = 0;
1383    protected char[] fMostRecentData = null;
1384    protected int fMostRecentChar = 0;
1385    protected int fLength = 0;
1386    protected boolean fCalledCharPropInit = false;
1387
1388}
1389
Popular Tags