KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xerces > impl > XML11EntityScanner


1 /*
2  * Copyright 1999-2002,2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.xerces.impl;
18
19 import java.io.IOException JavaDoc;
20
21 import org.apache.xerces.impl.msg.XMLMessageFormatter;
22 import org.apache.xerces.util.XMLChar;
23 import org.apache.xerces.util.XML11Char;
24 import org.apache.xerces.util.XMLStringBuffer;
25 import org.apache.xerces.xni.QName;
26 import org.apache.xerces.xni.XMLString;
27
28 /**
29  * Implements the entity scanner methods in
30  * the context of XML 1.1.
31  *
32  * @xerces.internal
33  *
34  * @author Michael Glavassevich, IBM
35  * @author Neil Graham, IBM
36  * @version $Id: XML11EntityScanner.java,v 1.14 2004/10/04 21:45:49 mrglavas Exp $
37  */

38
39 public class XML11EntityScanner
40     extends XMLEntityScanner {
41
42     //
43
// Constructors
44
//
45

46     /** Default constructor. */
47     public XML11EntityScanner() {
48         super();
49     } // <init>()
50

51     //
52
// XMLEntityScanner methods
53
//
54

55     /**
56      * Returns the next character on the input.
57      * <p>
58      * <strong>Note:</strong> The character is <em>not</em> consumed.
59      *
60      * @throws IOException Thrown if i/o error occurs.
61      * @throws EOFException Thrown on end of file.
62      */

63     public int peekChar() throws IOException JavaDoc {
64
65         // load more characters, if needed
66
if (fCurrentEntity.position == fCurrentEntity.count) {
67             load(0, true);
68         }
69
70         // peek at character
71
int c = fCurrentEntity.ch[fCurrentEntity.position];
72
73         // return peeked character
74
if (fCurrentEntity.isExternal()) {
75             return (c != '\r' && c != 0x85 && c != 0x2028) ? c : '\n';
76         }
77         else {
78             return c;
79         }
80
81     } // peekChar():int
82

83     /**
84      * Returns the next character on the input.
85      * <p>
86      * <strong>Note:</strong> The character is consumed.
87      *
88      * @throws IOException Thrown if i/o error occurs.
89      * @throws EOFException Thrown on end of file.
90      */

91     public int scanChar() throws IOException JavaDoc {
92
93         // load more characters, if needed
94
if (fCurrentEntity.position == fCurrentEntity.count) {
95             load(0, true);
96         }
97
98         // scan character
99
int c = fCurrentEntity.ch[fCurrentEntity.position++];
100         boolean external = false;
101         if (c == '\n' ||
102             ((c == '\r' || c == 0x85 || c == 0x2028) && (external = fCurrentEntity.isExternal()))) {
103             fCurrentEntity.lineNumber++;
104             fCurrentEntity.columnNumber = 1;
105             if (fCurrentEntity.position == fCurrentEntity.count) {
106                 fCurrentEntity.ch[0] = (char)c;
107                 load(1, false);
108             }
109             if (c == '\r' && external) {
110                 int cc = fCurrentEntity.ch[fCurrentEntity.position++];
111                 if (cc != '\n' && cc != 0x85) {
112                     fCurrentEntity.position--;
113                 }
114             }
115             c = '\n';
116         }
117
118         // return character that was scanned
119
fCurrentEntity.columnNumber++;
120         return c;
121
122     } // scanChar():int
123

124     /**
125      * Returns a string matching the NMTOKEN production appearing immediately
126      * on the input as a symbol, or null if NMTOKEN Name string is present.
127      * <p>
128      * <strong>Note:</strong> The NMTOKEN characters are consumed.
129      * <p>
130      * <strong>Note:</strong> The string returned must be a symbol. The
131      * SymbolTable can be used for this purpose.
132      *
133      * @throws IOException Thrown if i/o error occurs.
134      * @throws EOFException Thrown on end of file.
135      *
136      * @see org.apache.xerces.util.SymbolTable
137      * @see org.apache.xerces.util.XML11Char#isXML11Name
138      */

139     public String JavaDoc scanNmtoken() throws IOException JavaDoc {
140         // load more characters, if needed
141
if (fCurrentEntity.position == fCurrentEntity.count) {
142             load(0, true);
143         }
144
145         // scan nmtoken
146
int offset = fCurrentEntity.position;
147         
148         do {
149             char ch = fCurrentEntity.ch[fCurrentEntity.position];
150             if (XML11Char.isXML11Name(ch)) {
151                 if (++fCurrentEntity.position == fCurrentEntity.count) {
152                     int length = fCurrentEntity.position - offset;
153                     if (length == fCurrentEntity.ch.length) {
154                         // bad luck we have to resize our buffer
155
char[] tmp = new char[fCurrentEntity.ch.length << 1];
156                         System.arraycopy(fCurrentEntity.ch, offset,
157                                          tmp, 0, length);
158                         fCurrentEntity.ch = tmp;
159                     }
160                     else {
161                         System.arraycopy(fCurrentEntity.ch, offset,
162                                          fCurrentEntity.ch, 0, length);
163                     }
164                     offset = 0;
165                     if (load(length, false)) {
166                         break;
167                     }
168                 }
169             }
170             else if (XML11Char.isXML11NameHighSurrogate(ch)) {
171                 if (++fCurrentEntity.position == fCurrentEntity.count) {
172                     int length = fCurrentEntity.position - offset;
173                     if (length == fCurrentEntity.ch.length) {
174                         // bad luck we have to resize our buffer
175
char[] tmp = new char[fCurrentEntity.ch.length << 1];
176                         System.arraycopy(fCurrentEntity.ch, offset,
177                                          tmp, 0, length);
178                         fCurrentEntity.ch = tmp;
179                     }
180                     else {
181                         System.arraycopy(fCurrentEntity.ch, offset,
182                                          fCurrentEntity.ch, 0, length);
183                     }
184                     offset = 0;
185                     if (load(length, false)) {
186                         --fCurrentEntity.startPosition;
187                         --fCurrentEntity.position;
188                         break;
189                     }
190                 }
191                 char ch2 = fCurrentEntity.ch[fCurrentEntity.position];
192                 if ( !XMLChar.isLowSurrogate(ch2) ||
193                      !XML11Char.isXML11Name(XMLChar.supplemental(ch, ch2)) ) {
194                     --fCurrentEntity.position;
195                     break;
196                 }
197                 if (++fCurrentEntity.position == fCurrentEntity.count) {
198                     int length = fCurrentEntity.position - offset;
199                     if (length == fCurrentEntity.ch.length) {
200                         // bad luck we have to resize our buffer
201
char[] tmp = new char[fCurrentEntity.ch.length << 1];
202                         System.arraycopy(fCurrentEntity.ch, offset,
203                                          tmp, 0, length);
204                         fCurrentEntity.ch = tmp;
205                     }
206                     else {
207                         System.arraycopy(fCurrentEntity.ch, offset,
208                                          fCurrentEntity.ch, 0, length);
209                     }
210                     offset = 0;
211                     if (load(length, false)) {
212                         break;
213                     }
214                 }
215             }
216             else {
217                 break;
218             }
219         }
220         while (true);
221         
222         int length = fCurrentEntity.position - offset;
223         fCurrentEntity.columnNumber += length;
224
225         // return nmtoken
226
String JavaDoc symbol = null;
227         if (length > 0) {
228             symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, offset, length);
229         }
230         return symbol;
231
232     } // scanNmtoken():String
233

234     /**
235      * Returns a string matching the Name production appearing immediately
236      * on the input as a symbol, or null if no Name string is present.
237      * <p>
238      * <strong>Note:</strong> The Name characters are consumed.
239      * <p>
240      * <strong>Note:</strong> The string returned must be a symbol. The
241      * SymbolTable can be used for this purpose.
242      *
243      * @throws IOException Thrown if i/o error occurs.
244      * @throws EOFException Thrown on end of file.
245      *
246      * @see org.apache.xerces.util.SymbolTable
247      * @see org.apache.xerces.util.XML11Char#isXML11Name
248      * @see org.apache.xerces.util.XML11Char#isXML11NameStart
249      */

250     public String JavaDoc scanName() throws IOException JavaDoc {
251         // load more characters, if needed
252
if (fCurrentEntity.position == fCurrentEntity.count) {
253             load(0, true);
254         }
255
256         // scan name
257
int offset = fCurrentEntity.position;
258         char ch = fCurrentEntity.ch[offset];
259         
260         if (XML11Char.isXML11NameStart(ch)) {
261             if (++fCurrentEntity.position == fCurrentEntity.count) {
262                 fCurrentEntity.ch[0] = ch;
263                 offset = 0;
264                 if (load(1, false)) {
265                     fCurrentEntity.columnNumber++;
266                     String JavaDoc symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 1);
267                     return symbol;
268                 }
269             }
270         }
271         else if (XML11Char.isXML11NameHighSurrogate(ch)) {
272             if (++fCurrentEntity.position == fCurrentEntity.count) {
273                 fCurrentEntity.ch[0] = ch;
274                 offset = 0;
275                 if (load(1, false)) {
276                     --fCurrentEntity.position;
277                     --fCurrentEntity.startPosition;
278                     return null;
279                 }
280             }
281             char ch2 = fCurrentEntity.ch[fCurrentEntity.position];
282             if ( !XMLChar.isLowSurrogate(ch2) ||
283                  !XML11Char.isXML11NameStart(XMLChar.supplemental(ch, ch2)) ) {
284                 --fCurrentEntity.position;
285                 return null;
286             }
287             if (++fCurrentEntity.position == fCurrentEntity.count) {
288                 fCurrentEntity.ch[0] = ch;
289                 fCurrentEntity.ch[1] = ch2;
290                 offset = 0;
291                 if (load(2, false)) {
292                     fCurrentEntity.columnNumber += 2;
293                     String JavaDoc symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 2);
294                     return symbol;
295                 }
296             }
297         }
298         else {
299             return null;
300         }
301         
302         do {
303             ch = fCurrentEntity.ch[fCurrentEntity.position];
304             if (XML11Char.isXML11Name(ch)) {
305                 if (++fCurrentEntity.position == fCurrentEntity.count) {
306                     int length = fCurrentEntity.position - offset;
307                     if (length == fCurrentEntity.ch.length) {
308                         // bad luck we have to resize our buffer
309
char[] tmp = new char[fCurrentEntity.ch.length << 1];
310                         System.arraycopy(fCurrentEntity.ch, offset,
311                                          tmp, 0, length);
312                         fCurrentEntity.ch = tmp;
313                     }
314                     else {
315                         System.arraycopy(fCurrentEntity.ch, offset,
316                                          fCurrentEntity.ch, 0, length);
317                     }
318                     offset = 0;
319                     if (load(length, false)) {
320                         break;
321                     }
322                 }
323             }
324             else if (XML11Char.isXML11NameHighSurrogate(ch)) {
325                 if (++fCurrentEntity.position == fCurrentEntity.count) {
326                     int length = fCurrentEntity.position - offset;
327                     if (length == fCurrentEntity.ch.length) {
328                         // bad luck we have to resize our buffer
329
char[] tmp = new char[fCurrentEntity.ch.length << 1];
330                         System.arraycopy(fCurrentEntity.ch, offset,
331                                          tmp, 0, length);
332                         fCurrentEntity.ch = tmp;
333                     }
334                     else {
335                         System.arraycopy(fCurrentEntity.ch, offset,
336                                          fCurrentEntity.ch, 0, length);
337                     }
338                     offset = 0;
339                     if (load(length, false)) {
340                         --fCurrentEntity.position;
341                         --fCurrentEntity.startPosition;
342                         break;
343                     }
344                 }
345                 char ch2 = fCurrentEntity.ch[fCurrentEntity.position];
346                 if ( !XMLChar.isLowSurrogate(ch2) ||
347                      !XML11Char.isXML11Name(XMLChar.supplemental(ch, ch2)) ) {
348                     --fCurrentEntity.position;
349                     break;
350                 }
351                 if (++fCurrentEntity.position == fCurrentEntity.count) {
352                     int length = fCurrentEntity.position - offset;
353                     if (length == fCurrentEntity.ch.length) {
354                         // bad luck we have to resize our buffer
355
char[] tmp = new char[fCurrentEntity.ch.length << 1];
356                         System.arraycopy(fCurrentEntity.ch, offset,
357                                          tmp, 0, length);
358                         fCurrentEntity.ch = tmp;
359                     }
360                     else {
361                         System.arraycopy(fCurrentEntity.ch, offset,
362                                          fCurrentEntity.ch, 0, length);
363                     }
364                     offset = 0;
365                     if (load(length, false)) {
366                         break;
367                     }
368                 }
369             }
370             else {
371                 break;
372             }
373         }
374         while (true);
375
376         int length = fCurrentEntity.position - offset;
377         fCurrentEntity.columnNumber += length;
378
379         // return name
380
String JavaDoc symbol = null;
381         if (length > 0) {
382             symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, offset, length);
383         }
384         return symbol;
385
386     } // scanName():String
387

388     /**
389      * Returns a string matching the NCName production appearing immediately
390      * on the input as a symbol, or null if no NCName string is present.
391      * <p>
392      * <strong>Note:</strong> The NCName characters are consumed.
393      * <p>
394      * <strong>Note:</strong> The string returned must be a symbol. The
395      * SymbolTable can be used for this purpose.
396      *
397      * @throws IOException Thrown if i/o error occurs.
398      * @throws EOFException Thrown on end of file.
399      *
400      * @see org.apache.xerces.util.SymbolTable
401      * @see org.apache.xerces.util.XML11Char#isXML11NCName
402      * @see org.apache.xerces.util.XML11Char#isXML11NCNameStart
403      */

404     public String JavaDoc scanNCName() throws IOException JavaDoc {
405
406         // load more characters, if needed
407
if (fCurrentEntity.position == fCurrentEntity.count) {
408             load(0, true);
409         }
410
411         // scan name
412
int offset = fCurrentEntity.position;
413         char ch = fCurrentEntity.ch[offset];
414         
415         if (XML11Char.isXML11NCNameStart(ch)) {
416             if (++fCurrentEntity.position == fCurrentEntity.count) {
417                 fCurrentEntity.ch[0] = ch;
418                 offset = 0;
419                 if (load(1, false)) {
420                     fCurrentEntity.columnNumber++;
421                     String JavaDoc symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 1);
422                     return symbol;
423                 }
424             }
425         }
426         else if (XML11Char.isXML11NameHighSurrogate(ch)) {
427             if (++fCurrentEntity.position == fCurrentEntity.count) {
428                 fCurrentEntity.ch[0] = ch;
429                 offset = 0;
430                 if (load(1, false)) {
431                     --fCurrentEntity.position;
432                     --fCurrentEntity.startPosition;
433                     return null;
434                 }
435             }
436             char ch2 = fCurrentEntity.ch[fCurrentEntity.position];
437             if ( !XMLChar.isLowSurrogate(ch2) ||
438                  !XML11Char.isXML11NCNameStart(XMLChar.supplemental(ch, ch2)) ) {
439                 --fCurrentEntity.position;
440                 return null;
441             }
442             if (++fCurrentEntity.position == fCurrentEntity.count) {
443                 fCurrentEntity.ch[0] = ch;
444                 fCurrentEntity.ch[1] = ch2;
445                 offset = 0;
446                 if (load(2, false)) {
447                     fCurrentEntity.columnNumber += 2;
448                     String JavaDoc symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 2);
449                     return symbol;
450                 }
451             }
452         }
453         else {
454             return null;
455         }
456         
457         do {
458             ch = fCurrentEntity.ch[fCurrentEntity.position];
459             if (XML11Char.isXML11NCName(ch)) {
460                 if (++fCurrentEntity.position == fCurrentEntity.count) {
461                     int length = fCurrentEntity.position - offset;
462                     if (length == fCurrentEntity.ch.length) {
463                         // bad luck we have to resize our buffer
464
char[] tmp = new char[fCurrentEntity.ch.length << 1];
465                         System.arraycopy(fCurrentEntity.ch, offset,
466                                          tmp, 0, length);
467                         fCurrentEntity.ch = tmp;
468                     }
469                     else {
470                         System.arraycopy(fCurrentEntity.ch, offset,
471                                          fCurrentEntity.ch, 0, length);
472                     }
473                     offset = 0;
474                     if (load(length, false)) {
475                         break;
476                     }
477                 }
478             }
479             else if (XML11Char.isXML11NameHighSurrogate(ch)) {
480                 if (++fCurrentEntity.position == fCurrentEntity.count) {
481                     int length = fCurrentEntity.position - offset;
482                     if (length == fCurrentEntity.ch.length) {
483                         // bad luck we have to resize our buffer
484
char[] tmp = new char[fCurrentEntity.ch.length << 1];
485                         System.arraycopy(fCurrentEntity.ch, offset,
486                                          tmp, 0, length);
487                         fCurrentEntity.ch = tmp;
488                     }
489                     else {
490                         System.arraycopy(fCurrentEntity.ch, offset,
491                                          fCurrentEntity.ch, 0, length);
492                     }
493                     offset = 0;
494                     if (load(length, false)) {
495                         --fCurrentEntity.startPosition;
496                         --fCurrentEntity.position;
497                         break;
498                     }
499                 }
500                 char ch2 = fCurrentEntity.ch[fCurrentEntity.position];
501                 if ( !XMLChar.isLowSurrogate(ch2) ||
502                      !XML11Char.isXML11NCName(XMLChar.supplemental(ch, ch2)) ) {
503                     --fCurrentEntity.position;
504                     break;
505                 }
506                 if (++fCurrentEntity.position == fCurrentEntity.count) {
507                     int length = fCurrentEntity.position - offset;
508                     if (length == fCurrentEntity.ch.length) {
509                         // bad luck we have to resize our buffer
510
char[] tmp = new char[fCurrentEntity.ch.length << 1];
511                         System.arraycopy(fCurrentEntity.ch, offset,
512                                          tmp, 0, length);
513                         fCurrentEntity.ch = tmp;
514                     }
515                     else {
516                         System.arraycopy(fCurrentEntity.ch, offset,
517                                          fCurrentEntity.ch, 0, length);
518                     }
519                     offset = 0;
520                     if (load(length, false)) {
521                         break;
522                     }
523                 }
524             }
525             else {
526                 break;
527             }
528         }
529         while (true);
530         
531         int length = fCurrentEntity.position - offset;
532         fCurrentEntity.columnNumber += length;
533
534         // return name
535
String JavaDoc symbol = null;
536         if (length > 0) {
537             symbol = fSymbolTable.addSymbol(fCurrentEntity.ch, offset, length);
538         }
539         return symbol;
540
541     } // scanNCName():String
542

543     /**
544      * Scans a qualified name from the input, setting the fields of the
545      * QName structure appropriately.
546      * <p>
547      * <strong>Note:</strong> The qualified name characters are consumed.
548      * <p>
549      * <strong>Note:</strong> The strings used to set the values of the
550      * QName structure must be symbols. The SymbolTable can be used for
551      * this purpose.
552      *
553      * @param qname The qualified name structure to fill.
554      *
555      * @return Returns true if a qualified name appeared immediately on
556      * the input and was scanned, false otherwise.
557      *
558      * @throws IOException Thrown if i/o error occurs.
559      * @throws EOFException Thrown on end of file.
560      *
561      * @see org.apache.xerces.util.SymbolTable
562      * @see org.apache.xerces.util.XML11Char#isXML11Name
563      * @see org.apache.xerces.util.XML11Char#isXML11NameStart
564      */

565     public boolean scanQName(QName qname) throws IOException JavaDoc {
566
567         // load more characters, if needed
568
if (fCurrentEntity.position == fCurrentEntity.count) {
569             load(0, true);
570         }
571
572         // scan qualified name
573
int offset = fCurrentEntity.position;
574         char ch = fCurrentEntity.ch[offset];
575         
576         if (XML11Char.isXML11NCNameStart(ch)) {
577             if (++fCurrentEntity.position == fCurrentEntity.count) {
578                 fCurrentEntity.ch[0] = ch;
579                 offset = 0;
580                 if (load(1, false)) {
581                     fCurrentEntity.columnNumber++;
582                     String JavaDoc name = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 1);
583                     qname.setValues(null, name, name, null);
584                     return true;
585                 }
586             }
587         }
588         else if (XML11Char.isXML11NameHighSurrogate(ch)) {
589             if (++fCurrentEntity.position == fCurrentEntity.count) {
590                 fCurrentEntity.ch[0] = ch;
591                 offset = 0;
592                 if (load(1, false)) {
593                     --fCurrentEntity.startPosition;
594                     --fCurrentEntity.position;
595                     return false;
596                 }
597             }
598             char ch2 = fCurrentEntity.ch[fCurrentEntity.position];
599             if ( !XMLChar.isLowSurrogate(ch2) ||
600                  !XML11Char.isXML11NCNameStart(XMLChar.supplemental(ch, ch2)) ) {
601                 --fCurrentEntity.position;
602                 return false;
603             }
604             if (++fCurrentEntity.position == fCurrentEntity.count) {
605                 fCurrentEntity.ch[0] = ch;
606                 fCurrentEntity.ch[1] = ch2;
607                 offset = 0;
608                 if (load(2, false)) {
609                     fCurrentEntity.columnNumber += 2;
610                     String JavaDoc name = fSymbolTable.addSymbol(fCurrentEntity.ch, 0, 2);
611                     qname.setValues(null, name, name, null);
612                     return true;
613                 }
614             }
615         }
616         else {
617             return false;
618         }
619         
620         int index = -1;
621         boolean sawIncompleteSurrogatePair = false;
622         do {
623             ch = fCurrentEntity.ch[fCurrentEntity.position];
624             if (XML11Char.isXML11Name(ch)) {
625                 if (ch == ':') {
626                     if (index != -1) {
627                         break;
628                     }
629                     index = fCurrentEntity.position;
630                 }
631                 if (++fCurrentEntity.position == fCurrentEntity.count) {
632                     int length = fCurrentEntity.position - offset;
633                     if (length == fCurrentEntity.ch.length) {
634                         // bad luck we have to resize our buffer
635
char[] tmp = new char[fCurrentEntity.ch.length << 1];
636                         System.arraycopy(fCurrentEntity.ch, offset,
637                                          tmp, 0, length);
638                         fCurrentEntity.ch = tmp;
639                     }
640                     else {
641                         System.arraycopy(fCurrentEntity.ch, offset,
642                                          fCurrentEntity.ch, 0, length);
643                     }
644                     if (index != -1) {
645                         index = index - offset;
646                     }
647                     offset = 0;
648                     if (load(length, false)) {
649                         break;
650                     }
651                 }
652             }
653             else if (XML11Char.isXML11NameHighSurrogate(ch)) {
654                 if (++fCurrentEntity.position == fCurrentEntity.count) {
655                     int length = fCurrentEntity.position - offset;
656                     if (length == fCurrentEntity.ch.length) {
657                         // bad luck we have to resize our buffer
658
char[] tmp = new char[fCurrentEntity.ch.length << 1];
659                         System.arraycopy(fCurrentEntity.ch, offset,
660                                          tmp, 0, length);
661                         fCurrentEntity.ch = tmp;
662                     }
663                     else {
664                         System.arraycopy(fCurrentEntity.ch, offset,
665                                          fCurrentEntity.ch, 0, length);
666                     }
667                     if (index != -1) {
668                         index = index - offset;
669                     }
670                     offset = 0;
671                     if (load(length, false)) {
672                         sawIncompleteSurrogatePair = true;
673                         --fCurrentEntity.startPosition;
674                         --fCurrentEntity.position;
675                         break;
676                     }
677                 }
678                 char ch2 = fCurrentEntity.ch[fCurrentEntity.position];
679                 if ( !XMLChar.isLowSurrogate(ch2) ||
680                      !XML11Char.isXML11Name(XMLChar.supplemental(ch, ch2)) ) {
681                     sawIncompleteSurrogatePair = true;
682                     --fCurrentEntity.position;
683                     break;
684                 }
685                 if (++fCurrentEntity.position == fCurrentEntity.count) {
686                     int length = fCurrentEntity.position - offset;
687                     if (length == fCurrentEntity.ch.length) {
688                         // bad luck we have to resize our buffer
689
char[] tmp = new char[fCurrentEntity.ch.length << 1];
690                         System.arraycopy(fCurrentEntity.ch, offset,
691                                          tmp, 0, length);
692                         fCurrentEntity.ch = tmp;
693                     }
694                     else {
695                         System.arraycopy(fCurrentEntity.ch, offset,
696                                          fCurrentEntity.ch, 0, length);
697                     }
698                     if (index != -1) {
699                         index = index - offset;
700                     }
701                     offset = 0;
702                     if (load(length, false)) {
703                         break;
704                     }
705                 }
706             }
707             else {
708                 break;
709             }
710         }
711         while (true);
712         
713         int length = fCurrentEntity.position - offset;
714         fCurrentEntity.columnNumber += length;
715         
716         if (length > 0) {
717             String JavaDoc prefix = null;
718             String JavaDoc localpart = null;
719             String JavaDoc rawname = fSymbolTable.addSymbol(fCurrentEntity.ch,
720                                                     offset, length);
721             if (index != -1) {
722                 int prefixLength = index - offset;
723                 prefix = fSymbolTable.addSymbol(fCurrentEntity.ch,
724                                                     offset, prefixLength);
725                 int len = length - prefixLength - 1;
726                 int startLocal = index +1;
727                 if (!XML11Char.isXML11NCNameStart(fCurrentEntity.ch[startLocal]) &&
728                     (!XML11Char.isXML11NameHighSurrogate(fCurrentEntity.ch[startLocal]) ||
729                     sawIncompleteSurrogatePair)){
730                     fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
731                                                "IllegalQName",
732                                                null,
733                                                XMLErrorReporter.SEVERITY_FATAL_ERROR);
734                 }
735                 localpart = fSymbolTable.addSymbol(fCurrentEntity.ch,
736                                                    index + 1, len);
737
738             }
739             else {
740                 localpart = rawname;
741             }
742             qname.setValues(prefix, localpart, rawname, null);
743             return true;
744         }
745         return false;
746
747     } // scanQName(QName):boolean
748

749     /**
750      * Scans a range of parsed character data, setting the fields of the
751      * XMLString structure, appropriately.
752      * <p>
753      * <strong>Note:</strong> The characters are consumed.
754      * <p>
755      * <strong>Note:</strong> This method does not guarantee to return
756      * the longest run of parsed character data. This method may return
757      * before markup due to reaching the end of the input buffer or any
758      * other reason.
759      * <p>
760      * <strong>Note:</strong> The fields contained in the XMLString
761      * structure are not guaranteed to remain valid upon subsequent calls
762      * to the entity scanner. Therefore, the caller is responsible for
763      * immediately using the returned character data or making a copy of
764      * the character data.
765      *
766      * @param content The content structure to fill.
767      *
768      * @return Returns the next character on the input, if known. This
769      * value may be -1 but this does <em>note</em> designate
770      * end of file.
771      *
772      * @throws IOException Thrown if i/o error occurs.
773      * @throws EOFException Thrown on end of file.
774      */

775     public int scanContent(XMLString content) throws IOException JavaDoc {
776
777         // load more characters, if needed
778
if (fCurrentEntity.position == fCurrentEntity.count) {
779             load(0, true);
780         }
781         else if (fCurrentEntity.position == fCurrentEntity.count - 1) {
782             fCurrentEntity.ch[0] = fCurrentEntity.ch[fCurrentEntity.count - 1];
783             load(1, false);
784             fCurrentEntity.position = 0;
785             fCurrentEntity.startPosition = 0;
786         }
787
788         // normalize newlines
789
int offset = fCurrentEntity.position;
790         int c = fCurrentEntity.ch[offset];
791         int newlines = 0;
792         boolean external = fCurrentEntity.isExternal();
793         if (c == '\n' || ((c == '\r' || c == 0x85 || c == 0x2028) && external)) {
794             do {
795                 c = fCurrentEntity.ch[fCurrentEntity.position++];
796                 if ((c == '\r' ) && external) {
797                     newlines++;
798                     fCurrentEntity.lineNumber++;
799                     fCurrentEntity.columnNumber = 1;
800                     if (fCurrentEntity.position == fCurrentEntity.count) {
801                         offset = 0;
802                         fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition);
803                         fCurrentEntity.position = newlines;
804                         fCurrentEntity.startPosition = newlines;
805                         if (load(newlines, false)) {
806                             break;
807                         }
808                     }
809                     int cc = fCurrentEntity.ch[fCurrentEntity.position];
810                     if (cc == '\n' || cc == 0x85) {
811                         fCurrentEntity.position++;
812                         offset++;
813                     }
814                     /*** NEWLINE NORMALIZATION ***/
815                     else {
816                         newlines++;
817                     }
818                 }
819                 else if (c == '\n' || ((c == 0x85 || c == 0x2028) && external)) {
820                     newlines++;
821                     fCurrentEntity.lineNumber++;
822                     fCurrentEntity.columnNumber = 1;
823                     if (fCurrentEntity.position == fCurrentEntity.count) {
824                         offset = 0;
825                         fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition);
826                         fCurrentEntity.position = newlines;
827                         fCurrentEntity.startPosition = newlines;
828                         if (load(newlines, false)) {
829                             break;
830                         }
831                     }
832                 }
833                 else {
834                     fCurrentEntity.position--;
835                     break;
836                 }
837             } while (fCurrentEntity.position < fCurrentEntity.count - 1);
838             for (int i = offset; i < fCurrentEntity.position; i++) {
839                 fCurrentEntity.ch[i] = '\n';
840             }
841             int length = fCurrentEntity.position - offset;
842             if (fCurrentEntity.position == fCurrentEntity.count - 1) {
843                 content.setValues(fCurrentEntity.ch, offset, length);
844                 return -1;
845             }
846         }
847
848         // inner loop, scanning for content
849
if (external) {
850             while (fCurrentEntity.position < fCurrentEntity.count) {
851                 c = fCurrentEntity.ch[fCurrentEntity.position++];
852                 if (!XML11Char.isXML11Content(c) || c == 0x85 || c == 0x2028) {
853                     fCurrentEntity.position--;
854                     break;
855                 }
856             }
857         }
858         else {
859             while (fCurrentEntity.position < fCurrentEntity.count) {
860                 c = fCurrentEntity.ch[fCurrentEntity.position++];
861                 // In internal entities control characters are allowed to appear unescaped.
862
if (!XML11Char.isXML11InternalEntityContent(c)) {
863                     fCurrentEntity.position--;
864                     break;
865                 }
866             }
867         }
868         int length = fCurrentEntity.position - offset;
869         fCurrentEntity.columnNumber += length - newlines;
870         content.setValues(fCurrentEntity.ch, offset, length);
871
872         // return next character
873
if (fCurrentEntity.position != fCurrentEntity.count) {
874             c = fCurrentEntity.ch[fCurrentEntity.position];
875             // REVISIT: Does this need to be updated to fix the
876
// #x0D ^#x0A newline normalization problem? -Ac
877
if ((c == '\r' || c == 0x85 || c == 0x2028) && external) {
878                 c = '\n';
879             }
880         }
881         else {
882             c = -1;
883         }
884         return c;
885
886     } // scanContent(XMLString):int
887

888     /**
889      * Scans a range of attribute value data, setting the fields of the
890      * XMLString structure, appropriately.
891      * <p>
892      * <strong>Note:</strong> The characters are consumed.
893      * <p>
894      * <strong>Note:</strong> This method does not guarantee to return
895      * the longest run of attribute value data. This method may return
896      * before the quote character due to reaching the end of the input
897      * buffer or any other reason.
898      * <p>
899      * <strong>Note:</strong> The fields contained in the XMLString
900      * structure are not guaranteed to remain valid upon subsequent calls
901      * to the entity scanner. Therefore, the caller is responsible for
902      * immediately using the returned character data or making a copy of
903      * the character data.
904      *
905      * @param quote The quote character that signifies the end of the
906      * attribute value data.
907      * @param content The content structure to fill.
908      *
909      * @return Returns the next character on the input, if known. This
910      * value may be -1 but this does <em>note</em> designate
911      * end of file.
912      *
913      * @throws IOException Thrown if i/o error occurs.
914      * @throws EOFException Thrown on end of file.
915      */

916     public int scanLiteral(int quote, XMLString content)
917         throws IOException JavaDoc {
918
919         // load more characters, if needed
920
if (fCurrentEntity.position == fCurrentEntity.count) {
921             load(0, true);
922         }
923         else if (fCurrentEntity.position == fCurrentEntity.count - 1) {
924             fCurrentEntity.ch[0] = fCurrentEntity.ch[fCurrentEntity.count - 1];
925             load(1, false);
926             fCurrentEntity.startPosition = 0;
927             fCurrentEntity.position = 0;
928         }
929
930         // normalize newlines
931
int offset = fCurrentEntity.position;
932         int c = fCurrentEntity.ch[offset];
933         int newlines = 0;
934         boolean external = fCurrentEntity.isExternal();
935         if (c == '\n' || ((c == '\r' || c == 0x85 || c == 0x2028) && external)) {
936             do {
937                 c = fCurrentEntity.ch[fCurrentEntity.position++];
938                 if ((c == '\r' ) && external) {
939                     newlines++;
940                     fCurrentEntity.lineNumber++;
941                     fCurrentEntity.columnNumber = 1;
942                     if (fCurrentEntity.position == fCurrentEntity.count) {
943                         offset = 0;
944                         fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition);
945                         fCurrentEntity.position = newlines;
946                         fCurrentEntity.startPosition = newlines;
947                         if (load(newlines, false)) {
948                             break;
949                         }
950                     }
951                     int cc = fCurrentEntity.ch[fCurrentEntity.position];
952                     if (cc == '\n' || cc == 0x85) {
953                         fCurrentEntity.position++;
954                         offset++;
955                     }
956                     /*** NEWLINE NORMALIZATION ***/
957                     else {
958                         newlines++;
959                     }
960                 }
961                 else if (c == '\n' || ((c == 0x85 || c == 0x2028) && external)) {
962                     newlines++;
963                     fCurrentEntity.lineNumber++;
964                     fCurrentEntity.columnNumber = 1;
965                     if (fCurrentEntity.position == fCurrentEntity.count) {
966                         offset = 0;
967                         fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition);
968                         fCurrentEntity.position = newlines;
969                         fCurrentEntity.startPosition = newlines;
970                         if (load(newlines, false)) {
971                             break;
972                         }
973                     }
974                 }
975                 else {
976                     fCurrentEntity.position--;
977                     break;
978                 }
979             } while (fCurrentEntity.position < fCurrentEntity.count - 1);
980             for (int i = offset; i < fCurrentEntity.position; i++) {
981                 fCurrentEntity.ch[i] = '\n';
982             }
983             int length = fCurrentEntity.position - offset;
984             if (fCurrentEntity.position == fCurrentEntity.count - 1) {
985                 content.setValues(fCurrentEntity.ch, offset, length);
986                 return -1;
987             }
988         }
989
990         // scan literal value
991
if (external) {
992             while (fCurrentEntity.position < fCurrentEntity.count) {
993                 c = fCurrentEntity.ch[fCurrentEntity.position++];
994                 if (c == quote || c == '%' || !XML11Char.isXML11Content(c)
995                     || c == 0x85 || c == 0x2028) {
996                     fCurrentEntity.position--;
997                     break;
998                 }
999             }
1000        }
1001        else {
1002            while (fCurrentEntity.position < fCurrentEntity.count) {
1003                c = fCurrentEntity.ch[fCurrentEntity.position++];
1004                // In internal entities control characters are allowed to appear unescaped.
1005
if ((c == quote && !fCurrentEntity.literal)
1006                    || c == '%' || !XML11Char.isXML11InternalEntityContent(c)) {
1007                    fCurrentEntity.position--;
1008                    break;
1009                }
1010            }
1011        }
1012        int length = fCurrentEntity.position - offset;
1013        fCurrentEntity.columnNumber += length - newlines;
1014        content.setValues(fCurrentEntity.ch, offset, length);
1015
1016        // return next character
1017
if (fCurrentEntity.position != fCurrentEntity.count) {
1018            c = fCurrentEntity.ch[fCurrentEntity.position];
1019            // NOTE: We don't want to accidentally signal the
1020
// end of the literal if we're expanding an
1021
// entity appearing in the literal. -Ac
1022
if (c == quote && fCurrentEntity.literal) {
1023                c = -1;
1024            }
1025        }
1026        else {
1027            c = -1;
1028        }
1029        return c;
1030
1031    } // scanLiteral(int,XMLString):int
1032

1033    /**
1034     * Scans a range of character data up to the specicied delimiter,
1035     * setting the fields of the XMLString structure, appropriately.
1036     * <p>
1037     * <strong>Note:</strong> The characters are consumed.
1038     * <p>
1039     * <strong>Note:</strong> This assumes that the internal buffer is
1040     * at least the same size, or bigger, than the length of the delimiter
1041     * and that the delimiter contains at least one character.
1042     * <p>
1043     * <strong>Note:</strong> This method does not guarantee to return
1044     * the longest run of character data. This method may return before
1045     * the delimiter due to reaching the end of the input buffer or any
1046     * other reason.
1047     * <p>
1048     * <strong>Note:</strong> The fields contained in the XMLString
1049     * structure are not guaranteed to remain valid upon subsequent calls
1050     * to the entity scanner. Therefore, the caller is responsible for
1051     * immediately using the returned character data or making a copy of
1052     * the character data.
1053     *
1054     * @param delimiter The string that signifies the end of the character
1055     * data to be scanned.
1056     * @param data The data structure to fill.
1057     *
1058     * @return Returns true if there is more data to scan, false otherwise.
1059     *
1060     * @throws IOException Thrown if i/o error occurs.
1061     * @throws EOFException Thrown on end of file.
1062     */

1063    public boolean scanData(String JavaDoc delimiter, XMLStringBuffer buffer)
1064        throws IOException JavaDoc {
1065
1066        boolean done = false;
1067        int delimLen = delimiter.length();
1068        char charAt0 = delimiter.charAt(0);
1069        boolean external = fCurrentEntity.isExternal();
1070        do {
1071            // load more characters, if needed
1072
if (fCurrentEntity.position == fCurrentEntity.count) {
1073                load(0, true);
1074            }
1075
1076            boolean bNextEntity = false;
1077
1078            while ((fCurrentEntity.position >= fCurrentEntity.count - delimLen)
1079                && (!bNextEntity))
1080            {
1081              System.arraycopy(fCurrentEntity.ch,
1082                               fCurrentEntity.position,
1083                               fCurrentEntity.ch,
1084                               0,
1085                               fCurrentEntity.count - fCurrentEntity.position);
1086
1087              bNextEntity = load(fCurrentEntity.count - fCurrentEntity.position, false);
1088              fCurrentEntity.position = 0;
1089              fCurrentEntity.startPosition = 0;
1090            }
1091
1092            if (fCurrentEntity.position >= fCurrentEntity.count - delimLen) {
1093                // something must be wrong with the input: e.g., file ends an unterminated comment
1094
int length = fCurrentEntity.count - fCurrentEntity.position;
1095                buffer.append (fCurrentEntity.ch, fCurrentEntity.position, length);
1096                fCurrentEntity.columnNumber += fCurrentEntity.count;
1097                fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition);
1098                fCurrentEntity.position = fCurrentEntity.count;
1099                fCurrentEntity.startPosition = fCurrentEntity.count;
1100                load(0,true);
1101                return false;
1102            }
1103
1104            // normalize newlines
1105
int offset = fCurrentEntity.position;
1106            int c = fCurrentEntity.ch[offset];
1107            int newlines = 0;
1108            if (c == '\n' || ((c == '\r' || c == 0x85 || c == 0x2028) && external)) {
1109                do {
1110                    c = fCurrentEntity.ch[fCurrentEntity.position++];
1111                    if ((c == '\r' ) && external) {
1112                        newlines++;
1113                        fCurrentEntity.lineNumber++;
1114                        fCurrentEntity.columnNumber = 1;
1115                        if (fCurrentEntity.position == fCurrentEntity.count) {
1116                            offset = 0;
1117                            fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition);
1118                            fCurrentEntity.position = newlines;
1119                            fCurrentEntity.startPosition = newlines;
1120                            if (load(newlines, false)) {
1121                                break;
1122                            }
1123                        }
1124                        int cc = fCurrentEntity.ch[fCurrentEntity.position];
1125                        if (cc == '\n' || cc == 0x85) {
1126                            fCurrentEntity.position++;
1127                            offset++;
1128                        }
1129                        /*** NEWLINE NORMALIZATION ***/
1130                        else {
1131                            newlines++;
1132                        }
1133                    }
1134                    else if (c == '\n' || ((c == 0x85 || c == 0x2028) && external)) {
1135                        newlines++;
1136                        fCurrentEntity.lineNumber++;
1137                        fCurrentEntity.columnNumber = 1;
1138                        if (fCurrentEntity.position == fCurrentEntity.count) {
1139                            offset = 0;
1140                            fCurrentEntity.baseCharOffset += (fCurrentEntity.position - fCurrentEntity.startPosition);
1141                            fCurrentEntity.position = newlines;
1142                            fCurrentEntity.startPosition = newlines;
1143                            fCurrentEntity.count = newlines;
1144                            if (load(newlines, false)) {
1145                                break;
1146                            }
1147                        }
1148                    }
1149                    else {
1150                        fCurrentEntity.position--;
1151                        break;
1152                    }
1153                } while (fCurrentEntity.position < fCurrentEntity.count - 1);
1154                for (int i = offset; i < fCurrentEntity.position; i++) {
1155                    fCurrentEntity.ch[i] = '\n';
1156                }
1157                int length = fCurrentEntity.position - offset;
1158                if (fCurrentEntity.position == fCurrentEntity.count - 1) {
1159                    buffer.append(fCurrentEntity.ch, offset, length);
1160                    return true;
1161                }
1162            }
1163
1164            // iterate over buffer looking for delimiter
1165
if (external) {
1166                OUTER: while (fCurrentEntity.position < fCurrentEntity.count) {
1167                    c = fCurrentEntity.ch[fCurrentEntity.position++];
1168                    if (c == charAt0) {
1169                        // looks like we just hit the delimiter
1170
int delimOffset = fCurrentEntity.position - 1;
1171                        for (int i = 1; i < delimLen; i++) {
1172                            if (fCurrentEntity.position == fCurrentEntity.count) {
1173                                fCurrentEntity.position -= i;
1174                                break OUTER;
1175                            }
1176                            c = fCurrentEntity.ch[fCurrentEntity.position++];
1177                            if (delimiter.charAt(i) != c) {
1178                                fCurrentEntity.position--;
1179                                break;
1180                            }
1181                         }
1182                         if (fCurrentEntity.position == delimOffset + delimLen) {
1183                            done = true;
1184                            break;
1185                         }
1186                    }
1187                    else if (c == '\n' || c == '\r' || c == 0x85 || c == 0x2028) {
1188                        fCurrentEntity.position--;
1189                        break;
1190                    }
1191                    // In external entities control characters cannot appear
1192
// as literals so do not skip over them.
1193
else if (!XML11Char.isXML11ValidLiteral(c)) {
1194                        fCurrentEntity.position--;
1195                        int length = fCurrentEntity.position - offset;
1196                        fCurrentEntity.columnNumber += length - newlines;
1197                        buffer.append(fCurrentEntity.ch, offset, length);
1198                        return true;
1199                    }
1200                }
1201            }
1202            else {
1203                OUTER: while (fCurrentEntity.position < fCurrentEntity.count) {
1204                    c = fCurrentEntity.ch[fCurrentEntity.position++];
1205                    if (c == charAt0) {
1206                        // looks like we just hit the delimiter
1207
int delimOffset = fCurrentEntity.position - 1;
1208                        for (int i = 1; i < delimLen; i++) {
1209                            if (fCurrentEntity.position == fCurrentEntity.count) {
1210                                fCurrentEntity.position -= i;
1211                                break OUTER;
1212                            }
1213                            c = fCurrentEntity.ch[fCurrentEntity.position++];
1214                            if (delimiter.charAt(i) != c) {
1215                                fCurrentEntity.position--;
1216                                break;
1217                            }
1218                        }
1219                        if (fCurrentEntity.position == delimOffset + delimLen) {
1220                            done = true;
1221                            break;
1222                        }
1223                    }
1224                    else if (c == '\n') {
1225                        fCurrentEntity.position--;
1226                        break;
1227                    }
1228                    // Control characters are allowed to appear as literals
1229
// in internal entities.
1230
else if (!XML11Char.isXML11Valid(c)) {
1231                        fCurrentEntity.position--;
1232                        int length = fCurrentEntity.position - offset;
1233                        fCurrentEntity.columnNumber += length - newlines;
1234                        buffer.append(fCurrentEntity.ch, offset, length);
1235                        return true;
1236                    }
1237                }
1238            }
1239            int length = fCurrentEntity.position - offset;
1240            fCurrentEntity.columnNumber += length - newlines;
1241            if (done) {
1242                length -= delimLen;
1243            }
1244            buffer.append(fCurrentEntity.ch, offset, length);
1245
1246            // return true if string was skipped
1247
} while (!done);
1248        return !done;
1249
1250    } // scanData(String,XMLString)
1251

1252    /**
1253     * Skips a character appearing immediately on the input.
1254     * <p>
1255     * <strong>Note:</strong> The character is consumed only if it matches
1256     * the specified character.
1257     *
1258     * @param c The character to skip.
1259     *
1260     * @return Returns true if the character was skipped.
1261     *
1262     * @throws IOException Thrown if i/o error occurs.
1263     * @throws EOFException Thrown on end of file.
1264     */

1265    public boolean skipChar(int c) throws IOException JavaDoc {
1266
1267        // load more characters, if needed
1268
if (fCurrentEntity.position == fCurrentEntity.count) {
1269            load(0, true);
1270        }
1271
1272        // skip character
1273
int cc = fCurrentEntity.ch[fCurrentEntity.position];
1274        if (cc == c) {
1275            fCurrentEntity.position++;
1276            if (c == '\n') {
1277                fCurrentEntity.lineNumber++;
1278                fCurrentEntity.columnNumber = 1;
1279            }
1280            else {
1281                fCurrentEntity.columnNumber++;
1282            }
1283            return true;
1284        }
1285        else if (c == '\n' && ((cc == 0x2028 || cc == 0x85) && fCurrentEntity.isExternal())) {
1286            fCurrentEntity.position++;
1287            fCurrentEntity.lineNumber++;
1288            fCurrentEntity.columnNumber = 1;
1289            return true;
1290        }
1291        else if (c == '\n' && (cc == '\r' ) && fCurrentEntity.isExternal()) {
1292            // handle newlines
1293
if (fCurrentEntity.position == fCurrentEntity.count) {
1294                fCurrentEntity.ch[0] = (char)cc;
1295                load(1, false);
1296            }
1297            int ccc = fCurrentEntity.ch[++fCurrentEntity.position];
1298            if (ccc == '\n' || ccc == 0x85) {
1299                fCurrentEntity.position++;
1300            }
1301            fCurrentEntity.lineNumber++;
1302            fCurrentEntity.columnNumber = 1;
1303            return true;
1304        }
1305
1306        // character was not skipped
1307
return false;
1308
1309    } // skipChar(int):boolean
1310

1311    /**
1312     * Skips space characters appearing immediately on the input.
1313     * <p>
1314     * <strong>Note:</strong> The characters are consumed only if they are
1315     * space characters.
1316     *
1317     * @return Returns true if at least one space character was skipped.
1318     *
1319     * @throws IOException Thrown if i/o error occurs.
1320     * @throws EOFException Thrown on end of file.
1321     *
1322     * @see org.apache.xerces.util.XMLChar#isSpace
1323     * @see org.apache.xerces.util.XML11Char#isXML11Space
1324     */

1325    public boolean skipSpaces() throws IOException JavaDoc {
1326
1327        // load more characters, if needed
1328
if (fCurrentEntity.position == fCurrentEntity.count) {
1329            load(0, true);
1330        }
1331
1332        // skip spaces
1333
int c = fCurrentEntity.ch[fCurrentEntity.position];
1334        
1335        // External -- Match: S + 0x85 + 0x2028, and perform end of line normalization
1336
if (fCurrentEntity.isExternal()) {
1337            if (XML11Char.isXML11Space(c)) {
1338                do {
1339                    boolean entityChanged = false;
1340                    // handle newlines
1341
if (c == '\n' || c == '\r' || c == 0x85 || c == 0x2028) {
1342                        fCurrentEntity.lineNumber++;
1343                        fCurrentEntity.columnNumber = 1;
1344                        if (fCurrentEntity.position == fCurrentEntity.count - 1) {
1345                            fCurrentEntity.ch[0] = (char)c;
1346                            entityChanged = load(1, true);
1347                            if (!entityChanged) {
1348                                // the load change the position to be 1,
1349
// need to restore it when entity not changed
1350
fCurrentEntity.startPosition = 0;
1351                                fCurrentEntity.position = 0;
1352                            }
1353                        }
1354                        if (c == '\r') {
1355                            // REVISIT: Does this need to be updated to fix the
1356
// #x0D ^#x0A newline normalization problem? -Ac
1357
int cc = fCurrentEntity.ch[++fCurrentEntity.position];
1358                            if (cc != '\n' && cc != 0x85 ) {
1359                                fCurrentEntity.position--;
1360                            }
1361                        }
1362                    }
1363                    else {
1364                        fCurrentEntity.columnNumber++;
1365                    }
1366                    // load more characters, if needed
1367
if (!entityChanged)
1368                        fCurrentEntity.position++;
1369                    if (fCurrentEntity.position == fCurrentEntity.count) {
1370                        load(0, true);
1371                    }
1372                } while (XML11Char.isXML11Space(c = fCurrentEntity.ch[fCurrentEntity.position]));
1373                return true;
1374            }
1375        }
1376        // Internal -- Match: S (only)
1377
else if (XMLChar.isSpace(c)) {
1378            do {
1379                boolean entityChanged = false;
1380                // handle newlines
1381
if (c == '\n') {
1382                    fCurrentEntity.lineNumber++;
1383                    fCurrentEntity.columnNumber = 1;
1384                    if (fCurrentEntity.position == fCurrentEntity.count - 1) {
1385                        fCurrentEntity.ch[0] = (char)c;
1386                        entityChanged = load(1, true);
1387                        if (!entityChanged) {
1388                            // the load change the position to be 1,
1389
// need to restore it when entity not changed
1390
fCurrentEntity.startPosition = 0;
1391                            fCurrentEntity.position = 0;
1392                        }
1393                    }
1394                }
1395                else {
1396                    fCurrentEntity.columnNumber++;
1397                }
1398                // load more characters, if needed
1399
if (!entityChanged)
1400                    fCurrentEntity.position++;
1401                if (fCurrentEntity.position == fCurrentEntity.count) {
1402                    load(0, true);
1403                }
1404            } while (XMLChar.isSpace(c = fCurrentEntity.ch[fCurrentEntity.position]));
1405            return true;
1406        }
1407
1408        // no spaces were found
1409
return false;
1410
1411    } // skipSpaces():boolean
1412

1413    /**
1414     * Skips the specified string appearing immediately on the input.
1415     * <p>
1416     * <strong>Note:</strong> The characters are consumed only if they are
1417     * space characters.
1418     *
1419     * @param s The string to skip.
1420     *
1421     * @return Returns true if the string was skipped.
1422     *
1423     * @throws IOException Thrown if i/o error occurs.
1424     * @throws EOFException Thrown on end of file.
1425     */

1426    public boolean skipString(String JavaDoc s) throws IOException JavaDoc {
1427
1428        // load more characters, if needed
1429
if (fCurrentEntity.position == fCurrentEntity.count) {
1430            load(0, true);
1431        }
1432
1433        // skip string
1434
final int length = s.length();
1435        for (int i = 0; i < length; i++) {
1436            char c = fCurrentEntity.ch[fCurrentEntity.position++];
1437            if (c != s.charAt(i)) {
1438                fCurrentEntity.position -= i + 1;
1439                return false;
1440            }
1441            if (i < length - 1 && fCurrentEntity.position == fCurrentEntity.count) {
1442                System.arraycopy(fCurrentEntity.ch, fCurrentEntity.count - i - 1, fCurrentEntity.ch, 0, i + 1);
1443                // REVISIT: Can a string to be skipped cross an
1444
// entity boundary? -Ac
1445
if (load(i + 1, false)) {
1446                    fCurrentEntity.startPosition -= i + 1;
1447                    fCurrentEntity.position -= i + 1;
1448                    return false;
1449                }
1450            }
1451        }
1452        fCurrentEntity.columnNumber += length;
1453        return true;
1454
1455    } // skipString(String):boolean
1456

1457} // class XML11EntityScanner
1458

1459
Popular Tags