KickJava   Java API By Example, From Geeks To Geeks.

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


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 org.enhydra.apache.xerces.framework.XMLErrorReporter;
61 import org.enhydra.apache.xerces.utils.QName;
62 import org.enhydra.apache.xerces.utils.StringPool;
63 import org.enhydra.apache.xerces.utils.XMLCharacterProperties;
64
65 /**
66  * Reader for processing internal entity replacement text.
67  * <p>
68  * This reader processes data contained within strings kept
69  * in the string pool. It provides the support for both
70  * general and parameter entities. The location support
71  * as we are processing the replacement text is somewhat
72  * poor and needs to be updated when "nested locations"
73  * have been implemented.
74  * <p>
75  * For efficiency, we return instances of this class to a
76  * free list and reuse those instances to process other
77  * strings.
78  *
79  * @version $id$
80  */

81 final class StringReader extends XMLEntityReader {
82     /**
83      * Allocate a string reader
84      *
85      * @param entityHandler The current entity handler.
86      * @param errorReporter The current error reporter.
87      * @param sendCharDataAsCharArray true if char data should be reported using
88      * char arrays instead of string handles.
89      * @param lineNumber The line number to return as our position.
90      * @param columnNumber The column number to return as our position.
91      * @param stringHandle The StringPool handle for the data to process.
92      * @param stringPool The string pool.
93      * @param addEnclosingSpaces If true, treat the data to process as if
94      * there were a leading and trailing space
95      * character enclosing the string data.
96      * @return The reader that will process the string data.
97      */

98     public static StringReader createStringReader(XMLEntityHandler entityHandler,
99                                                   XMLErrorReporter errorReporter,
100                                                   boolean sendCharDataAsCharArray,
101                                                   int lineNumber,
102                                                   int columnNumber,
103                                                   int stringHandle,
104                                                   StringPool stringPool,
105                                                   boolean addEnclosingSpaces)
106     {
107         StringReader reader = null;
108         synchronized (StringReader.class) {
109             reader = fgFreeReaders;
110             if (reader == null) {
111                 return new StringReader(entityHandler, errorReporter, sendCharDataAsCharArray, lineNumber, columnNumber,
112                                         stringHandle, stringPool, addEnclosingSpaces);
113             }
114             fgFreeReaders = reader.fNextFreeReader;
115         }
116         reader.init(entityHandler, errorReporter, sendCharDataAsCharArray, lineNumber, columnNumber,
117                     stringHandle, stringPool, addEnclosingSpaces);
118         return reader;
119     }
120     //
121
//
122
//
123
private StringReader(XMLEntityHandler entityHandler, XMLErrorReporter errorReporter,
124                          boolean sendCharDataAsCharArray, int lineNumber, int columnNumber,
125                          int stringHandle, StringPool stringPool, boolean addEnclosingSpaces)
126     {
127         super(entityHandler, errorReporter, sendCharDataAsCharArray, lineNumber, columnNumber);
128         fStringPool = stringPool;
129         fData = fStringPool.toString(stringHandle);
130         fCurrentOffset = 0;
131         fEndOffset = fData.length();
132         if (addEnclosingSpaces) {
133             fMostRecentChar = ' ';
134             fCurrentOffset--;
135             oweTrailingSpace = hadTrailingSpace = true;
136         } else {
137             fMostRecentChar = fEndOffset == 0 ? -1 : fData.charAt(0);
138         }
139     }
140     private void init(XMLEntityHandler entityHandler, XMLErrorReporter errorReporter,
141                       boolean sendCharDataAsCharArray, int lineNumber, int columnNumber,
142                       int stringHandle, StringPool stringPool, boolean addEnclosingSpaces)
143     {
144         super.init(entityHandler, errorReporter, sendCharDataAsCharArray, lineNumber, columnNumber);
145         fStringPool = stringPool;
146         fData = fStringPool.toString(stringHandle);
147         fCurrentOffset = 0;
148         fEndOffset = fData.length();
149         fNextFreeReader = null;
150         if (addEnclosingSpaces) {
151             fMostRecentChar = ' ';
152             fCurrentOffset--;
153             oweTrailingSpace = hadTrailingSpace = true;
154         } else {
155             fMostRecentChar = fEndOffset == 0 ? -1 : fData.charAt(0);
156             oweTrailingSpace = hadTrailingSpace = false;
157         }
158     }
159     //
160
//
161
//
162
public int addString(int offset, int length) {
163         if (length == 0)
164             return 0;
165         return fStringPool.addString(fData.substring(offset, offset + length));
166     }
167     //
168
//
169
//
170
public int addSymbol(int offset, int length) {
171         if (length == 0)
172             return 0;
173         return fStringPool.addSymbol(fData.substring(offset, offset + length));
174     }
175     //
176
//
177
//
178
public void append(XMLEntityHandler.CharBuffer charBuffer, int offset, int length) {
179         boolean addSpace = false;
180         for (int i = 0; i < length; i++) {
181             try {
182                 charBuffer.append(fData.charAt(offset++));
183             } catch (StringIndexOutOfBoundsException JavaDoc ex) {
184                 if (offset == fEndOffset + 1 && hadTrailingSpace) {
185                     charBuffer.append(' ');
186                 } else {
187                     System.err.println("StringReader.append()");
188                     throw ex;
189                 }
190             }
191         }
192     }
193     //
194
//
195
//
196
private int loadNextChar() {
197         if (++fCurrentOffset >= fEndOffset) {
198             if (oweTrailingSpace) {
199                 oweTrailingSpace = false;
200                 fMostRecentChar = ' ';
201             } else {
202                 fMostRecentChar = -1;
203             }
204         } else {
205             fMostRecentChar = fData.charAt(fCurrentOffset);
206         }
207         return fMostRecentChar;
208     }
209     //
210
//
211
//
212
public XMLEntityHandler.EntityReader changeReaders() throws Exception JavaDoc {
213         XMLEntityHandler.EntityReader nextReader = super.changeReaders();
214         synchronized (StringReader.class) {
215             fNextFreeReader = fgFreeReaders;
216             fgFreeReaders = this;
217             // Allow these following two fields to be GC-ed.
218
fStringPool = null;
219             fData = null;
220         }
221         return nextReader;
222     }
223     //
224
//
225
//
226
public boolean lookingAtChar(char chr, boolean skipPastChar) throws Exception JavaDoc {
227         int ch = fMostRecentChar;
228         if (ch != chr) {
229             if (ch == -1) {
230                 return changeReaders().lookingAtChar(chr, skipPastChar);
231             }
232             return false;
233         }
234         if (skipPastChar) {
235             if (++fCurrentOffset >= fEndOffset) {
236                 if (oweTrailingSpace) {
237                     oweTrailingSpace = false;
238                     fMostRecentChar = ' ';
239                 } else {
240                     fMostRecentChar = -1;
241                 }
242             } else {
243                 fMostRecentChar = fData.charAt(fCurrentOffset);
244             }
245         }
246         return true;
247     }
248     //
249
//
250
//
251
public boolean lookingAtValidChar(boolean skipPastChar) throws Exception JavaDoc {
252         int ch = fMostRecentChar;
253         if (ch < 0xD800) {
254             if (ch < 0x20 && ch != 0x09 && ch != 0x0A && ch != 0x0D) {
255                 if (ch == -1)
256                     return changeReaders().lookingAtValidChar(skipPastChar);
257                 return false;
258             }
259             if (skipPastChar) {
260                 if (++fCurrentOffset >= fEndOffset) {
261                     if (oweTrailingSpace) {
262                         oweTrailingSpace = false;
263                         fMostRecentChar = ' ';
264                     } else {
265                         fMostRecentChar = -1;
266                     }
267                 } else {
268                     fMostRecentChar = fData.charAt(fCurrentOffset);
269                 }
270             }
271             return true;
272         }
273         if (ch > 0xFFFD) {
274             return false;
275         }
276         if (ch < 0xDC00) {
277             if (fCurrentOffset + 1 >= fEndOffset) {
278                 return false;
279             }
280             ch = fData.charAt(fCurrentOffset + 1);
281             if (ch < 0xDC00 || ch >= 0xE000) {
282                 return false;
283             } else if (!skipPastChar) {
284                 return true;
285             } else {
286                 fCurrentOffset++;
287             }
288         } else if (ch < 0xE000) {
289             return false;
290         }
291         if (skipPastChar) {
292             if (++fCurrentOffset >= fEndOffset) {
293                 if (oweTrailingSpace) {
294                     oweTrailingSpace = false;
295                     fMostRecentChar = ' ';
296                 } else {
297                     fMostRecentChar = -1;
298                 }
299             } else {
300                 fMostRecentChar = fData.charAt(fCurrentOffset);
301             }
302         }
303         return true;
304     }
305     //
306
//
307
//
308
public boolean lookingAtSpace(boolean skipPastChar) throws Exception JavaDoc {
309         int ch = fMostRecentChar;
310         if (ch > 0x20)
311             return false;
312         if (ch == 0x20 || ch == 0x0A || ch == 0x0D || ch == 0x09) {
313             if (skipPastChar) {
314                 loadNextChar();
315             }
316             return true;
317         }
318         if (ch == -1) {
319             return changeReaders().lookingAtSpace(skipPastChar);
320         }
321         return false;
322     }
323     //
324
//
325
//
326
public void skipToChar(char chr) throws Exception JavaDoc {
327         //
328
// REVISIT - this will skip invalid characters without reporting them.
329
//
330
int ch = fMostRecentChar;
331         while (true) {
332             if (ch == chr)
333                 return;
334             if (ch == -1) {
335                 changeReaders().skipToChar(chr);
336                 return;
337             }
338             ch = loadNextChar();
339         }
340     }
341     //
342
//
343
//
344
public void skipPastSpaces() throws Exception JavaDoc {
345         int ch = fMostRecentChar;
346         if (ch == -1) {
347             changeReaders().skipPastSpaces();
348             return;
349         }
350         while (true) {
351             if (ch > 0x20 || (ch != 0x20 && ch != 0x0A && ch != 0x09 && ch != 0x0D)) {
352                 fMostRecentChar = ch;
353                 return;
354             }
355             if (++fCurrentOffset >= fEndOffset) {
356                 changeReaders().skipPastSpaces();
357                 return;
358             }
359             ch = fData.charAt(fCurrentOffset);
360         }
361     }
362     //
363
//
364
//
365
public void skipPastName(char fastcheck) throws Exception JavaDoc {
366         int ch = fMostRecentChar;
367         if (ch < 0x80) {
368             if (ch == -1 || XMLCharacterProperties.fgAsciiInitialNameChar[ch] == 0)
369                 return;
370         } else {
371             if (!fCalledCharPropInit) {
372                 XMLCharacterProperties.initCharFlags();
373                 fCalledCharPropInit = true;
374             }
375             if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_InitialNameCharFlag) == 0)
376                 return;
377         }
378         while (true) {
379             ch = loadNextChar();
380             if (fastcheck == ch)
381                 return;
382             if (ch < 0x80) {
383                 if (ch == -1 || 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         }
394     }
395     //
396
//
397
//
398
public void skipPastNmtoken(char fastcheck) throws Exception JavaDoc {
399         int ch = fMostRecentChar;
400         while (true) {
401             if (fastcheck == ch)
402                 return;
403             if (ch < 0x80) {
404                 if (ch == -1 || XMLCharacterProperties.fgAsciiNameChar[ch] == 0)
405                     return;
406             } else {
407                 if (!fCalledCharPropInit) {
408                     XMLCharacterProperties.initCharFlags();
409                     fCalledCharPropInit = true;
410                 }
411                 if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
412                     return;
413             }
414             ch = loadNextChar();
415         }
416     }
417     //
418
//
419
//
420
public boolean skippedString(char[] s) throws Exception JavaDoc {
421         int ch = fMostRecentChar;
422         if (ch != s[0]) {
423             if (ch == -1)
424                 return changeReaders().skippedString(s);
425             return false;
426         }
427         if (fCurrentOffset + s.length > fEndOffset)
428             return false;
429         for (int i = 1; i < s.length; i++) {
430             if (fData.charAt(fCurrentOffset + i) != s[i])
431                 return false;
432         }
433         fCurrentOffset += (s.length - 1);
434         loadNextChar();
435         return true;
436     }
437     //
438
//
439
//
440
public int scanInvalidChar() throws Exception JavaDoc {
441         int ch = fMostRecentChar;
442         if (ch == -1)
443             return changeReaders().scanInvalidChar();
444         loadNextChar();
445         return ch;
446     }
447     //
448
//
449
//
450
public int scanCharRef(boolean hex) throws Exception JavaDoc {
451         int ch = fMostRecentChar;
452         if (ch == -1)
453             return changeReaders().scanCharRef(hex);
454         int num = 0;
455         if (hex) {
456             if (ch > 'f' || XMLCharacterProperties.fgAsciiXDigitChar[ch] == 0)
457                 return XMLEntityHandler.CHARREF_RESULT_INVALID_CHAR;
458             num = ch - (ch < 'A' ? '0' : (ch < 'a' ? 'A' : 'a') - 10);
459         } else {
460             if (ch < '0' || ch > '9')
461                 return XMLEntityHandler.CHARREF_RESULT_INVALID_CHAR;
462             num = ch - '0';
463         }
464         boolean toobig = false;
465         while (true) {
466             ch = loadNextChar();
467             if (ch == -1)
468                 return XMLEntityHandler.CHARREF_RESULT_SEMICOLON_REQUIRED;
469             if (hex) {
470                 if (ch > 'f' || XMLCharacterProperties.fgAsciiXDigitChar[ch] == 0)
471                     break;
472             } else {
473                 if (ch < '0' || ch > '9')
474                     break;
475             }
476             if (hex) {
477                 int dig = ch - (ch < 'A' ? '0' : (ch < 'a' ? 'A' : 'a') - 10);
478                 num = (num << 4) + dig;
479             } else {
480                 int dig = ch - '0';
481                 num = (num * 10) + dig;
482             }
483             if (num > 0x10FFFF) {
484                 toobig = true;
485                 num = 0;
486             }
487         }
488         if (ch != ';')
489             return XMLEntityHandler.CHARREF_RESULT_SEMICOLON_REQUIRED;
490         loadNextChar();
491         if (toobig)
492             return XMLEntityHandler.CHARREF_RESULT_OUT_OF_RANGE;
493         return num;
494     }
495     //
496
//
497
//
498
public int scanStringLiteral() throws Exception JavaDoc {
499         boolean single;
500         if (!(single = lookingAtChar('\'', true)) && !lookingAtChar('\"', true)) {
501             return XMLEntityHandler.STRINGLIT_RESULT_QUOTE_REQUIRED;
502         }
503         int offset = fCurrentOffset;
504         char qchar = single ? '\'' : '\"';
505         while (!lookingAtChar(qchar, false)) {
506             if (!lookingAtValidChar(true)) {
507                 return XMLEntityHandler.STRINGLIT_RESULT_INVALID_CHAR;
508             }
509         }
510         int stringIndex = addString(offset, fCurrentOffset - offset);
511         lookingAtChar(qchar, true); // move past qchar
512
return stringIndex;
513     }
514     //
515
// [10] AttValue ::= '"' ([^<&"] | Reference)* '"'
516
// | "'" ([^<&'] | Reference)* "'"
517
//
518
public int scanAttValue(char qchar, boolean asSymbol) throws Exception JavaDoc
519     {
520         int offset = fCurrentOffset;
521         while (true) {
522             if (lookingAtChar(qchar, false)) {
523                 break;
524             }
525             if (lookingAtChar(' ', true)) {
526                 continue;
527             }
528             if (lookingAtSpace(false)) {
529                 return XMLEntityHandler.ATTVALUE_RESULT_COMPLEX;
530             }
531             if (lookingAtChar('&', false)) {
532                 return XMLEntityHandler.ATTVALUE_RESULT_COMPLEX;
533             }
534             if (lookingAtChar('<', false)) {
535                 return XMLEntityHandler.ATTVALUE_RESULT_LESSTHAN;
536             }
537             if (!lookingAtValidChar(true)) {
538                 return XMLEntityHandler.ATTVALUE_RESULT_INVALID_CHAR;
539             }
540         }
541         int result = asSymbol ? addSymbol(offset, fCurrentOffset - offset) : addString(offset, fCurrentOffset - offset);
542         lookingAtChar(qchar, true);
543         return result;
544     }
545     //
546
// [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"'
547
// | "'" ([^%&'] | PEReference | Reference)* "'"
548
//
549
// The values in the following table are defined as:
550
//
551
// 0 - not special
552
// 1 - quote character
553
// 2 - reference
554
// 3 - peref
555
// 4 - invalid
556
//
557
public static final byte fgAsciiEntityValueChar[] = {
558         4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 4, 4, 0, 4, 4,
559         4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
560         0, 0, 1, 0, 0, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, // '\"', '%', '&', '\''
561
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
562         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
563         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
564         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
565         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
566     };
567     public int scanEntityValue(int qchar, boolean createString) throws Exception JavaDoc
568     {
569         int offset = fCurrentOffset;
570         int ch = fMostRecentChar;
571         while (true) {
572             if (ch == -1) {
573                 changeReaders(); // do not call next reader, our caller may need to change the parameters
574
return XMLEntityHandler.ENTITYVALUE_RESULT_END_OF_INPUT;
575             }
576             if (ch < 0x80) {
577                 switch (fgAsciiEntityValueChar[ch]) {
578                 case 1: // quote char
579
if (ch == qchar) {
580                         if (!createString)
581                             return XMLEntityHandler.ENTITYVALUE_RESULT_FINISHED;
582                         int length = fCurrentOffset - offset;
583                         int result = length == 0 ? StringPool.EMPTY_STRING : addString(offset, length);
584                         loadNextChar();
585                         return result;
586                     }
587                     // the other quote character is not special
588
// fall through
589
case 0: // non-special char
590
if (++fCurrentOffset >= fEndOffset) {
591                         if (oweTrailingSpace) {
592                             oweTrailingSpace = false;
593                             ch = fMostRecentChar = ' ';
594                         } else {
595                             ch = fMostRecentChar = -1;
596                         }
597                     } else {
598                         ch = fMostRecentChar = fData.charAt(fCurrentOffset);
599                     }
600                     continue;
601                 case 2: // reference
602
return XMLEntityHandler.ENTITYVALUE_RESULT_REFERENCE;
603                 case 3: // peref
604
return XMLEntityHandler.ENTITYVALUE_RESULT_PEREF;
605                 case 4: // invalid
606
return XMLEntityHandler.ENTITYVALUE_RESULT_INVALID_CHAR;
607                 }
608             } else if (ch < 0xD800) {
609                 ch = loadNextChar();
610             } else if (ch >= 0xE000 && (ch <= 0xFFFD || (ch >= 0x10000 && ch <= 0x10FFFF))) {
611                 //
612
// REVISIT - needs more code to check surrogates.
613
//
614
ch = loadNextChar();
615             } else {
616                 return XMLEntityHandler.ENTITYVALUE_RESULT_INVALID_CHAR;
617             }
618         }
619     }
620     //
621
//
622
//
623
public boolean scanExpectedName(char fastcheck, StringPool.CharArrayRange expectedName) throws Exception JavaDoc {
624         int ch = fMostRecentChar;
625         if (ch == -1) {
626             return changeReaders().scanExpectedName(fastcheck, expectedName);
627         }
628         if (!fCalledCharPropInit) {
629             XMLCharacterProperties.initCharFlags();
630             fCalledCharPropInit = true;
631         }
632         int nameOffset = fCurrentOffset;
633         if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_InitialNameCharFlag) == 0)
634             return false;
635         while (true) {
636             ch = loadNextChar();
637             if (fastcheck == ch)
638                 break;
639             if (ch == -1)
640                 break;
641             if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
642                 break;
643         }
644         int nameIndex = fStringPool.addSymbol(fData.substring(nameOffset, fCurrentOffset));
645         // DEFECT !! check name against expected name
646

647         return true;
648     }
649     //
650
//
651
//
652
public void scanQName(char fastcheck, QName qname) throws Exception JavaDoc {
653         int ch = fMostRecentChar;
654         if (ch == -1) {
655             changeReaders().scanQName(fastcheck, qname);
656             return;
657         }
658         if (!fCalledCharPropInit) {
659             XMLCharacterProperties.initCharFlags();
660             fCalledCharPropInit = true;
661         }
662         int nameOffset = fCurrentOffset;
663         if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_InitialNameCharFlag) == 0) {
664             qname.clear();
665             return;
666         }
667         while (true) {
668             ch = loadNextChar();
669             if (fastcheck == ch)
670                 break;
671             if (ch == -1)
672                 break;
673             if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
674                 break;
675         }
676
677         qname.clear();
678         qname.rawname = fStringPool.addSymbol(fData.substring(nameOffset, fCurrentOffset));
679        
680         int index = fData.indexOf(':', nameOffset);
681         if (index != -1 && index < fCurrentOffset) {
682             qname.prefix = fStringPool.addSymbol(fData.substring(nameOffset, index));
683             int indexOfSpaceChar = fData.indexOf( ' ', index + 1 );//one past : look for blank
684
String JavaDoc localPart;
685             if( indexOfSpaceChar != -1 ){//found one
686
localPart = fData.substring(index+1, indexOfSpaceChar );
687                 qname.localpart = fStringPool.addSymbol(localPart);
688             } else{//then get up to end of String
689
int lenfData = fData.length();
690                 localPart = fData.substring( index + 1, lenfData );
691                 qname.localpart = fStringPool.addSymbol(localPart);
692             }
693             qname.localpart = fStringPool.addSymbol(localPart);
694         }
695         else {
696             qname.localpart = qname.rawname;
697         }
698
699     } // scanQName(char,QName)
700

701     //
702
//
703
//
704
public int scanName(char fastcheck) throws Exception JavaDoc {
705         int ch = fMostRecentChar;
706         if (ch == -1) {
707             return changeReaders().scanName(fastcheck);
708         }
709         if (!fCalledCharPropInit) {
710             XMLCharacterProperties.initCharFlags();
711             fCalledCharPropInit = true;
712         }
713         int nameOffset = fCurrentOffset;
714         if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_InitialNameCharFlag) == 0)
715             return -1;
716         while (true) {
717             if (++fCurrentOffset >= fEndOffset) {
718                 if (oweTrailingSpace) {
719                     oweTrailingSpace = false;
720                     fMostRecentChar = ' ';
721                 } else {
722                     fMostRecentChar = -1;
723                 }
724                 break;
725             }
726             ch = fMostRecentChar = fData.charAt(fCurrentOffset);
727             if (fastcheck == ch)
728                 break;
729             if ((XMLCharacterProperties.fgCharFlags[ch] & XMLCharacterProperties.E_NameCharFlag) == 0)
730                 break;
731         }
732         int nameIndex = fStringPool.addSymbol(fData.substring(nameOffset, fCurrentOffset));
733         return nameIndex;
734     }
735     //
736
// There are no leading/trailing space checks here because scanContent cannot
737
// be called on a parameter entity reference value.
738
//
739
private int recognizeMarkup(int ch) throws Exception JavaDoc {
740         if (ch == -1) {
741             return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
742         }
743         switch (ch) {
744         case '?':
745             loadNextChar();
746             return XMLEntityHandler.CONTENT_RESULT_START_OF_PI;
747         case '!':
748             ch = loadNextChar();
749             if (ch == -1) {
750                 fCurrentOffset -= 2;
751                 loadNextChar();
752                 return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
753             }
754             if (ch == '-') {
755                 ch = loadNextChar();
756                 if (ch == -1) {
757                     fCurrentOffset -= 3;
758                     loadNextChar();
759                     return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
760                 }
761                 if (ch == '-') {
762                     loadNextChar();
763                     return XMLEntityHandler.CONTENT_RESULT_START_OF_COMMENT;
764                 }
765                 break;
766             }
767             if (ch == '[') {
768                 for (int i = 0; i < 6; i++) {
769                     ch = loadNextChar();
770                     if (ch == -1) {
771                         fCurrentOffset -= (3 + i);
772                         loadNextChar();
773                         return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
774                     }
775                     if (ch != cdata_string[i]) {
776                         return XMLEntityHandler.CONTENT_RESULT_MARKUP_NOT_RECOGNIZED;
777                     }
778                 }
779                 loadNextChar();
780                 return XMLEntityHandler.CONTENT_RESULT_START_OF_CDSECT;
781             }
782             break;
783         case '/':
784             loadNextChar();
785             return XMLEntityHandler.CONTENT_RESULT_START_OF_ETAG;
786         default:
787             return XMLEntityHandler.CONTENT_RESULT_START_OF_ELEMENT;
788         }
789         return XMLEntityHandler.CONTENT_RESULT_MARKUP_NOT_RECOGNIZED;
790     }
791     private int recognizeReference(int ch) throws Exception JavaDoc {
792         if (ch == -1) {
793             return XMLEntityHandler.CONTENT_RESULT_MARKUP_END_OF_INPUT;
794         }
795         //
796
// [67] Reference ::= EntityRef | CharRef
797
// [68] EntityRef ::= '&' Name ';'
798
// [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'
799
//
800
if (ch == '#') {
801             loadNextChar();
802             return XMLEntityHandler.CONTENT_RESULT_START_OF_CHARREF;
803         } else {
804             return XMLEntityHandler.CONTENT_RESULT_START_OF_ENTITYREF;
805         }
806     }
807     public int scanContent(QName element) throws Exception JavaDoc {
808         int ch = fMostRecentChar;
809         if (ch == -1) {
810             return changeReaders().scanContent(element);
811         }
812         int offset = fCurrentOffset;
813         if (ch < 0x80) {
814             switch (XMLCharacterProperties.fgAsciiWSCharData[ch]) {
815             case 0:
816                 ch = loadNextChar();
817                 break;
818             case 1:
819                 ch = loadNextChar();
820                 if (!fInCDSect) {
821                     return recognizeMarkup(ch);
822                 }
823                 break;
824             case 2:
825                 ch = loadNextChar();
826                 if (!fInCDSect) {
827                     return recognizeReference(ch);
828                 }
829                 break;
830             case 3:
831                 ch = loadNextChar();
832                 if (ch == ']' && fCurrentOffset + 1 < fEndOffset && fData.charAt(fCurrentOffset + 1) == '>') {
833                     loadNextChar();
834                     loadNextChar();
835                     return XMLEntityHandler.CONTENT_RESULT_END_OF_CDSECT;
836                 }
837                 break;
838             case 4:
839                 return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
840             case 5:
841                 do {
842                     ch = loadNextChar();
843                     if (ch == -1) {
844                         callCharDataHandler(offset, fEndOffset, true);
845                         return changeReaders().scanContent(element);
846                     }
847                 } while (ch == 0x20 || ch == 0x0A || ch == 0x0D || ch == 0x09);
848                 if (ch < 0x80) {
849                     switch (XMLCharacterProperties.fgAsciiCharData[ch]) {
850                     case 0:
851                         ch = loadNextChar();
852                         break;
853                     case 1:
854                         ch = loadNextChar();
855                         if (!fInCDSect) {
856                             callCharDataHandler(offset, fCurrentOffset - 1, true);
857                             return recognizeMarkup(ch);
858                         }
859                         break;
860                     case 2:
861                         ch = loadNextChar();
862                         if (!fInCDSect) {
863                             callCharDataHandler(offset, fCurrentOffset - 1, true);
864                             return recognizeReference(ch);
865                         }
866                         break;
867                     case 3:
868                         ch = loadNextChar();
869                         if (ch == ']' && fCurrentOffset + 1 < fEndOffset && fData.charAt(fCurrentOffset + 1) == '>') {
870                             callCharDataHandler(offset, fCurrentOffset - 1, true);
871                             loadNextChar();
872                             loadNextChar();
873                             return XMLEntityHandler.CONTENT_RESULT_END_OF_CDSECT;
874                         }
875                         break;
876                     case 4:
877                         callCharDataHandler(offset, fCurrentOffset, true);
878                         return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
879                     }
880                 } else {
881                     if (ch == 0xFFFE || ch == 0xFFFF) {
882                         callCharDataHandler(offset, fCurrentOffset, true);
883                         return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
884                     }
885                     ch = loadNextChar();
886                 }
887             }
888         } else {
889             if (ch == 0xFFFE || ch == 0xFFFF) {
890                 callCharDataHandler(offset, fCurrentOffset, false);
891                 return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
892             }
893             ch = loadNextChar();
894         }
895         while (true) {
896             if (ch == -1) {
897                 callCharDataHandler(offset, fEndOffset, false);
898                 return changeReaders().scanContent(element);
899             }
900             if (ch >= 0x80)
901                 break;
902             if (XMLCharacterProperties.fgAsciiCharData[ch] != 0)
903                 break;
904             ch = loadNextChar();
905         }
906         while (true) { // REVISIT - EOF check ?
907
if (ch < 0x80) {
908                 switch (XMLCharacterProperties.fgAsciiCharData[ch]) {
909                 case 0:
910                     ch = loadNextChar();
911                     break;
912                 case 1:
913                     ch = loadNextChar();
914                     if (!fInCDSect) {
915                         callCharDataHandler(offset, fCurrentOffset - 1, false);
916                         return recognizeMarkup(ch);
917                     }
918                     break;
919                 case 2:
920                     ch = loadNextChar();
921                     if (!fInCDSect) {
922                         callCharDataHandler(offset, fCurrentOffset - 1, false);
923                         return recognizeReference(ch);
924                     }
925                     break;
926                 case 3:
927                     ch = loadNextChar();
928                     if (ch == ']' && fCurrentOffset + 1 < fEndOffset && fData.charAt(fCurrentOffset + 1) == '>') {
929                         callCharDataHandler(offset, fCurrentOffset - 1, false);
930                         loadNextChar();
931                         loadNextChar();
932                         return XMLEntityHandler.CONTENT_RESULT_END_OF_CDSECT;
933                     }
934                     break;
935                 case 4:
936                     callCharDataHandler(offset, fCurrentOffset, false);
937                     return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
938                 }
939             } else {
940                 if (ch == 0xFFFE || ch == 0xFFFF) {
941                     callCharDataHandler(offset, fCurrentOffset, false);
942                     return XMLEntityHandler.CONTENT_RESULT_INVALID_CHAR;
943                 }
944                 ch = loadNextChar();
945             }
946             if (ch == -1) {
947                 callCharDataHandler(offset, fCurrentOffset, false);
948                 return changeReaders().scanContent(element);
949             }
950         }
951     }
952     //
953
//
954
//
955
private void callCharDataHandler(int offset, int endOffset, boolean isWhitespace) throws Exception JavaDoc {
956         int length = endOffset - offset;
957         if (!fSendCharDataAsCharArray) {
958             int stringIndex = addString(offset, length);
959             if (isWhitespace)
960                 fCharDataHandler.processWhitespace(stringIndex);
961             else
962                 fCharDataHandler.processCharacters(stringIndex);
963             return;
964         }
965         if (isWhitespace)
966             fCharDataHandler.processWhitespace(fData.toCharArray(), offset, length);
967         else
968             fCharDataHandler.processCharacters(fData.toCharArray(), offset, length);
969     }
970     //
971
//
972
//
973
private static final char[] cdata_string = { 'C','D','A','T','A','[' };
974     //
975
//
976
//
977
private StringPool fStringPool = null;
978     private String JavaDoc fData = null;
979     private int fEndOffset;
980     private boolean hadTrailingSpace = false;
981     private boolean oweTrailingSpace = false;
982     private int fMostRecentChar;
983     private StringReader fNextFreeReader = null;
984     private static StringReader fgFreeReaders = null;
985     private boolean fCalledCharPropInit = false;
986 }
987
Popular Tags