< prev index next >

src/jdk.xml.bind/share/classes/com/sun/xml/internal/dtdparser/InputEntity.java

Print this page


   1 /*
   2  * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.xml.internal.dtdparser;
  27 
  28 import org.xml.sax.InputSource;
  29 import org.xml.sax.SAXException;
  30 import org.xml.sax.SAXParseException;
  31 
  32 import java.io.CharConversionException;
  33 import java.io.IOException;
  34 import java.io.InputStream;
  35 import java.io.InputStreamReader;
  36 import java.io.Reader;
  37 import java.io.UnsupportedEncodingException;
  38 import java.net.URL;

  39 import java.util.Locale;
  40 
  41 /**
  42  * This is how the parser talks to its input entities, of all kinds.
  43  * The entities are in a stack.
  44  * <p/>
  45  * <P> For internal entities, the character arrays are referenced here,
  46  * and read from as needed (they're read-only).  External entities have
  47  * mutable buffers, that are read into as needed.
  48  * <p/>
  49  * <P> <em>Note:</em> This maps CRLF (and CR) to LF without regard for
  50  * whether it's in an external (parsed) entity or not.  The XML 1.0 spec
  51  * is inconsistent in explaining EOL handling; this is the sensible way.
  52  *
  53  * @author David Brownell
  54  * @author Janet Koenig
  55  * @version 1.4 00/08/05
  56  */
  57 public class InputEntity {
  58     private int start, finish;
  59     private char buf [];
  60     private int lineNumber = 1;
  61     private boolean returnedFirstHalf = false;
  62     private boolean maybeInCRLF = false;
  63 
  64     // name of entity (never main document or unnamed DTD PE)
  65     private String name;
  66 
  67     private InputEntity next;
  68 


 131     //
 132     public String getName() {
 133         return name;
 134     }
 135 
 136     //
 137     // use this for an external parsed entity
 138     //
 139     public void init(InputSource in, String name, InputEntity stack,
 140                      boolean isPE)
 141             throws IOException, SAXException {
 142 
 143         input = in;
 144         this.isPE = isPE;
 145         reader = in.getCharacterStream();
 146 
 147         if (reader == null) {
 148             InputStream bytes = in.getByteStream();
 149 
 150             if (bytes == null)
 151                 reader = XmlReader.createReader(new URL(in.getSystemId())
 152                         .openStream());


 153             else if (in.getEncoding() != null)
 154                 reader = XmlReader.createReader(in.getByteStream(),
 155                         in.getEncoding());
 156             else
 157                 reader = XmlReader.createReader(in.getByteStream());
 158         }
 159         next = stack;
 160         buf = new char[BUFSIZ];
 161         this.name = name;
 162         checkRecursion(stack);
 163     }
 164 
 165     //
 166     // use this for an internal parsed entity; buffer is readonly
 167     //
 168     public void init(char b [], String name, InputEntity stack, boolean isPE)
 169             throws SAXException {
 170 
 171         next = stack;
 172         buf = b;
 173         finish = b.length;
 174         this.name = name;
 175         this.isPE = isPE;
 176         checkRecursion(stack);
 177     }
 178 
 179     private void checkRecursion(InputEntity stack)
 180             throws SAXException {
 181 
 182         if (stack == null)
 183             return;
 184         for (stack = stack.next; stack != null; stack = stack.next) {
 185             if (stack.name != null && stack.name.equals(name))
 186                 fatal("P-069", new Object[]{name});
 187         }
 188     }
 189 
 190     public InputEntity pop() throws IOException {
 191 
 192         // caller has ensured there's nothing left to read


 367                 //
 368                 if ((c == '\n' || c == '\r') && !isInternal()) {
 369                     if (!(c == '\n' && sawCR)) {
 370                         lineNumber++;
 371                         sawCR = false;
 372                     }
 373                     if (c == '\r')
 374                         sawCR = true;
 375                 }
 376             } else {
 377                 start--;
 378                 return isSpace;
 379             }
 380         }
 381     }
 382 
 383 
 384     /**
 385      * normal content; whitespace in markup may be handled
 386      * specially if the parser uses the content model.
 387      * <p/>
 388      * <P> content terminates with markup delimiter characters,
 389      * namely ampersand (&amp;amp;) and left angle bracket (&amp;lt;).
 390      * <p/>
 391      * <P> the document handler's characters() method is called
 392      * on all the content found
 393      */
 394     public boolean parsedContent(DTDEventListener docHandler
 395                                  /*ElementValidator validator*/)
 396             throws IOException, SAXException {
 397 
 398         // [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
 399 
 400         int first;        // first char to return
 401         int last;        // last char to return
 402         boolean sawContent;    // sent any chars?
 403         char c;
 404 
 405         // deliver right out of the buffer, until delimiter, EOF,
 406         // or error, refilling as we go
 407         for (first = last = start, sawContent = false; ; last++) {
 408 
 409             // buffer empty?
 410             if (last >= finish) {


 530                 else {
 531                     last--;
 532                     // also terminate on surrogate pair oddities
 533                     break;
 534                 }
 535                 continue;
 536             }
 537 
 538             fatal("P-071", new Object[]{Integer.toHexString(c)});
 539         }
 540         if (last == first)
 541             return sawContent;
 542 //    validator.text ();
 543         docHandler.characters(buf, first, last - first);
 544         start = last;
 545         return true;
 546     }
 547 
 548 
 549     /**
 550      * CDATA -- character data, terminated by "]]>" and optionally
 551      * including unescaped markup delimiters (ampersand and left angle
 552      * bracket).  This should otherwise be exactly like character data,
 553      * modulo differences in error report details.
 554      * <p/>
 555      * <P> The document handler's characters() or ignorableWhitespace()
 556      * methods are invoked on all the character data found
 557      *
 558      * @param docHandler               gets callbacks for character data
 559      * @param ignorableWhitespace      if true, whitespace characters will
 560      *                                 be reported using docHandler.ignorableWhitespace(); implicitly,
 561      *                                 non-whitespace characters will cause validation errors
 562      * @param whitespaceInvalidMessage if true, ignorable whitespace
 563      *                                 causes a validity error report as well as a callback
 564      */
 565     public boolean unparsedContent(DTDEventListener docHandler,
 566                                    /*ElementValidator validator,*/
 567                                    boolean ignorableWhitespace,
 568                                    String whitespaceInvalidMessage)
 569             throws IOException, SAXException {
 570 
 571         // [18] CDSect ::= CDStart CData CDEnd
 572         // [19] CDStart ::= '<![CDATA['
 573         // [20] CData ::= (Char* - (Char* ']]>' Char*))
 574         // [21] CDEnd ::= ']]>'


 603                             continue;
 604                         } else {
 605                             last--;
 606                             break;
 607                         }
 608                     }
 609                     fatal("P-071", new Object[]
 610                     {Integer.toHexString(buf[last])});
 611                 }
 612                 if (c == '\n') {
 613                     if (!isInternal())
 614                         lineNumber++;
 615                     continue;
 616                 }
 617                 if (c == '\r') {
 618                     // As above, we can't repeat CR/CRLF --> LF mapping
 619                     if (isInternal())
 620                         continue;
 621 
 622                     if (white) {
 623                         if (whitespaceInvalidMessage != null)
 624                             errHandler.error(new SAXParseException(DTDParser.messages.getMessage(locale,
 625                                     whitespaceInvalidMessage), null));
 626                         docHandler.ignorableWhitespace(buf, start,
 627                                 last - start);
 628                         docHandler.ignorableWhitespace(newline, 0, 1);
 629                     } else {
 630 //            validator.text ();
 631                         docHandler.characters(buf, start, last - start);
 632                         docHandler.characters(newline, 0, 1);
 633                     }
 634                     lineNumber++;
 635                     if (finish > (last + 1)) {
 636                         if (buf[last + 1] == '\n')
 637                             last++;
 638                     } else {    // CR at end of buffer
 639 // XXX case not yet handled ... as above
 640                     }
 641                     start = last + 1;
 642                     continue;
 643                 }
 644                 if (c != ']') {
 645                     if (c != ' ' && c != '\t')
 646                         white = false;
 647                     continue;
 648                 }
 649                 if ((last + 2) < finish) {
 650                     if (buf[last + 1] == ']' && buf[last + 2] == '>') {
 651                         done = true;
 652                         break;
 653                     }
 654                     white = false;
 655                     continue;
 656                 } else {
 657                     //last--;
 658                     break;
 659                 }
 660             }
 661             if (white) {
 662                 if (whitespaceInvalidMessage != null)
 663                     errHandler.error(new SAXParseException(DTDParser.messages.getMessage(locale,
 664                             whitespaceInvalidMessage), null));
 665                 docHandler.ignorableWhitespace(buf, start, last - start);
 666             } else {
 667 //        validator.text ();
 668                 docHandler.characters(buf, start, last - start);
 669             }
 670             if (done) {
 671                 start = last + 3;
 672                 break;
 673             }
 674             start = last;
 675             if (isEOF())
 676                 fatal("P-073", null);
 677         }
 678         docHandler.endCDATA();
 679         return true;
 680     }
 681 
 682     // return false to backstep at end of buffer)


 684             throws SAXException {
 685 
 686         if ((offset + 1) >= finish)
 687             return false;
 688 
 689         char c1 = buf[offset++];
 690         char c2 = buf[offset];
 691 
 692         if ((c1 >= 0xd800 && c1 < 0xdc00) && (c2 >= 0xdc00 && c2 <= 0xdfff))
 693             return true;
 694         fatal("P-074", new Object[]{
 695             Integer.toHexString(c1 & 0x0ffff),
 696             Integer.toHexString(c2 & 0x0ffff)
 697         });
 698         return false;
 699     }
 700 
 701 
 702     /**
 703      * whitespace in markup (flagged to app, discardable)
 704      * <p/>
 705      * <P> the document handler's ignorableWhitespace() method
 706      * is called on all the whitespace found
 707      */
 708     public boolean ignorableWhitespace(DTDEventListener handler)
 709             throws IOException, SAXException {
 710 
 711         char c;
 712         boolean isSpace = false;
 713         int first;
 714 
 715         // [3] S ::= #20 | #09 | #0D | #0A
 716         for (first = start; ;) {
 717             if (finish <= start) {
 718                 if (isSpace)
 719                     handler.ignorableWhitespace(buf, first, start - first);
 720                 fillbuf();
 721                 first = start;
 722             }
 723             if (finish <= start)
 724                 return isSpace;


 742                 handler.ignorableWhitespace(buf, first,
 743                         (start - 1) - first);
 744                 handler.ignorableWhitespace(newline, 0, 1);
 745                 if (start < finish && buf[start] == '\n')
 746                     ++start;
 747                 first = start;
 748                 continue;
 749 
 750             default:
 751                 ungetc();
 752                 if (isSpace)
 753                     handler.ignorableWhitespace(buf, first, start - first);
 754                 return isSpace;
 755             }
 756         }
 757     }
 758 
 759     /**
 760      * returns false iff 'next' string isn't as provided,
 761      * else skips that text and returns true.
 762      * <p/>
 763      * <P> NOTE:  two alternative string representations are
 764      * both passed in, since one is faster.
 765      */
 766     public boolean peek(String next, char chars [])
 767             throws IOException, SAXException {
 768 
 769         int len;
 770         int i;
 771 
 772         if (chars != null)
 773             len = chars.length;
 774         else
 775             len = next.length();
 776 
 777         // buffer should hold the whole thing ... give it a
 778         // chance for the end-of-buffer case and cope with EOF
 779         // by letting fillbuf compact and fill
 780         if (finish <= start || (finish - start) < len)
 781             fillbuf();
 782 


 793         } else {
 794             for (i = 0; i < len && (start + i) < finish; i++) {
 795                 if (buf[start + i] != next.charAt(i))
 796                     return false;
 797             }
 798         }
 799 
 800         // if the first fillbuf didn't get enough data, give
 801         // fillbuf another chance to read
 802         if (i < len) {
 803             if (reader == null || isClosed)
 804                 return false;
 805 
 806             //
 807             // This diagnostic "knows" that the only way big strings would
 808             // fail to be peeked is where it's a symbol ... e.g. for an
 809             // </EndTag> construct.  That knowledge could also be applied
 810             // to get rid of the symbol length constraint, since having
 811             // the wrong symbol is a fatal error anyway ...
 812             //
 813             if (len > buf.length)
 814                 fatal("P-077", new Object[]{new Integer(buf.length)});

 815 
 816             fillbuf();
 817             return peek(next, chars);
 818         }
 819 
 820         start += len;
 821         return true;
 822     }
 823 
 824 
 825     //
 826     // Support for reporting the internal DTD subset, so <!DOCTYPE...>
 827     // declarations can be recreated.  This is collected as a single
 828     // string; such subsets are normally small, and many applications
 829     // don't even care about this.
 830     //
 831     public void startRemembering() {
 832 
 833         if (startRemember != 0)
 834             throw new InternalError();


 967 
 968     public void close() {
 969 
 970         try {
 971             if (reader != null && !isClosed)
 972                 reader.close();
 973             isClosed = true;
 974         } catch (IOException e) {
 975             /* NOTHING */
 976         }
 977     }
 978 
 979 
 980     private void fatal(String messageId, Object params [])
 981             throws SAXException {
 982 
 983         SAXParseException x = new SAXParseException(DTDParser.messages.getMessage(locale, messageId, params), null);
 984 
 985         // not continuable ... e.g. WF errors
 986         close();

 987         errHandler.fatalError(x);

 988         throw x;
 989     }
 990 }
   1 /*
   2  * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.xml.internal.dtdparser;
  27 
  28 import org.xml.sax.InputSource;
  29 import org.xml.sax.SAXException;
  30 import org.xml.sax.SAXParseException;
  31 
  32 import java.io.CharConversionException;
  33 import java.io.IOException;
  34 import java.io.InputStream;
  35 import java.io.InputStreamReader;
  36 import java.io.Reader;
  37 import java.io.UnsupportedEncodingException;
  38 import java.net.URL;
  39 import java.util.Arrays;
  40 import java.util.Locale;
  41 
  42 /**
  43  * This is how the parser talks to its input entities, of all kinds.
  44  * The entities are in a stack.
  45  * <p>
  46  * <P> For internal entities, the character arrays are referenced here,
  47  * and read from as needed (they're read-only).  External entities have
  48  * mutable buffers, that are read into as needed.
  49  * <p>
  50  * <P> <em>Note:</em> This maps CRLF (and CR) to LF without regard for
  51  * whether it's in an external (parsed) entity or not.  The XML 1.0 spec
  52  * is inconsistent in explaining EOL handling; this is the sensible way.
  53  *
  54  * @author David Brownell
  55  * @author Janet Koenig
  56  * @version 1.4 00/08/05
  57  */
  58 public class InputEntity {
  59     private int start, finish;
  60     private char buf [];
  61     private int lineNumber = 1;
  62     private boolean returnedFirstHalf = false;
  63     private boolean maybeInCRLF = false;
  64 
  65     // name of entity (never main document or unnamed DTD PE)
  66     private String name;
  67 
  68     private InputEntity next;
  69 


 132     //
 133     public String getName() {
 134         return name;
 135     }
 136 
 137     //
 138     // use this for an external parsed entity
 139     //
 140     public void init(InputSource in, String name, InputEntity stack,
 141                      boolean isPE)
 142             throws IOException, SAXException {
 143 
 144         input = in;
 145         this.isPE = isPE;
 146         reader = in.getCharacterStream();
 147 
 148         if (reader == null) {
 149             InputStream bytes = in.getByteStream();
 150 
 151             if (bytes == null)
 152                 if (Boolean.valueOf(System.getProperty("enableExternalEntityProcessing")))
 153                     reader = XmlReader.createReader(new URL(in.getSystemId()).openStream());
 154                 else
 155                     fatal("P-082", new Object[] {in.getSystemId()});
 156             else if (in.getEncoding() != null)
 157                 reader = XmlReader.createReader(in.getByteStream(), in.getEncoding());

 158             else
 159                 reader = XmlReader.createReader(in.getByteStream());
 160         }
 161         next = stack;
 162         buf = new char[BUFSIZ];
 163         this.name = name;
 164         checkRecursion(stack);
 165     }
 166 
 167     //
 168     // use this for an internal parsed entity; buffer is readonly
 169     //
 170     public void init(char b [], String name, InputEntity stack, boolean isPE)
 171             throws SAXException {
 172 
 173         next = stack;
 174         buf = Arrays.copyOf(b, b.length);
 175         finish = b.length;
 176         this.name = name;
 177         this.isPE = isPE;
 178         checkRecursion(stack);
 179     }
 180 
 181     private void checkRecursion(InputEntity stack)
 182             throws SAXException {
 183 
 184         if (stack == null)
 185             return;
 186         for (stack = stack.next; stack != null; stack = stack.next) {
 187             if (stack.name != null && stack.name.equals(name))
 188                 fatal("P-069", new Object[]{name});
 189         }
 190     }
 191 
 192     public InputEntity pop() throws IOException {
 193 
 194         // caller has ensured there's nothing left to read


 369                 //
 370                 if ((c == '\n' || c == '\r') && !isInternal()) {
 371                     if (!(c == '\n' && sawCR)) {
 372                         lineNumber++;
 373                         sawCR = false;
 374                     }
 375                     if (c == '\r')
 376                         sawCR = true;
 377                 }
 378             } else {
 379                 start--;
 380                 return isSpace;
 381             }
 382         }
 383     }
 384 
 385 
 386     /**
 387      * normal content; whitespace in markup may be handled
 388      * specially if the parser uses the content model.
 389      * <p>
 390      * <P> content terminates with markup delimiter characters,
 391      * namely ampersand (&amp;amp;) and left angle bracket (&amp;lt;).
 392      * <p>
 393      * <P> the document handler's characters() method is called
 394      * on all the content found
 395      */
 396     public boolean parsedContent(DTDEventListener docHandler
 397                                  /*ElementValidator validator*/)
 398             throws IOException, SAXException {
 399 
 400         // [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
 401 
 402         int first;        // first char to return
 403         int last;        // last char to return
 404         boolean sawContent;    // sent any chars?
 405         char c;
 406 
 407         // deliver right out of the buffer, until delimiter, EOF,
 408         // or error, refilling as we go
 409         for (first = last = start, sawContent = false; ; last++) {
 410 
 411             // buffer empty?
 412             if (last >= finish) {


 532                 else {
 533                     last--;
 534                     // also terminate on surrogate pair oddities
 535                     break;
 536                 }
 537                 continue;
 538             }
 539 
 540             fatal("P-071", new Object[]{Integer.toHexString(c)});
 541         }
 542         if (last == first)
 543             return sawContent;
 544 //    validator.text ();
 545         docHandler.characters(buf, first, last - first);
 546         start = last;
 547         return true;
 548     }
 549 
 550 
 551     /**
 552      * CDATA -- character data, terminated by {@code "]]>"} and optionally
 553      * including unescaped markup delimiters (ampersand and left angle
 554      * bracket).  This should otherwise be exactly like character data,
 555      * modulo differences in error report details.
 556      * <p>
 557      * <P> The document handler's characters() or ignorableWhitespace()
 558      * methods are invoked on all the character data found
 559      *
 560      * @param docHandler               gets callbacks for character data
 561      * @param ignorableWhitespace      if true, whitespace characters will
 562      *                                 be reported using docHandler.ignorableWhitespace(); implicitly,
 563      *                                 non-whitespace characters will cause validation errors
 564      * @param whitespaceInvalidMessage if true, ignorable whitespace
 565      *                                 causes a validity error report as well as a callback
 566      */
 567     public boolean unparsedContent(DTDEventListener docHandler,
 568                                    /*ElementValidator validator,*/
 569                                    boolean ignorableWhitespace,
 570                                    String whitespaceInvalidMessage)
 571             throws IOException, SAXException {
 572 
 573         // [18] CDSect ::= CDStart CData CDEnd
 574         // [19] CDStart ::= '<![CDATA['
 575         // [20] CData ::= (Char* - (Char* ']]>' Char*))
 576         // [21] CDEnd ::= ']]>'


 605                             continue;
 606                         } else {
 607                             last--;
 608                             break;
 609                         }
 610                     }
 611                     fatal("P-071", new Object[]
 612                     {Integer.toHexString(buf[last])});
 613                 }
 614                 if (c == '\n') {
 615                     if (!isInternal())
 616                         lineNumber++;
 617                     continue;
 618                 }
 619                 if (c == '\r') {
 620                     // As above, we can't repeat CR/CRLF --> LF mapping
 621                     if (isInternal())
 622                         continue;
 623 
 624                     if (white) {
 625                         if (whitespaceInvalidMessage != null && errHandler != null)
 626                             errHandler.error(new SAXParseException(DTDParser.messages.getMessage(locale,
 627                                     whitespaceInvalidMessage), null));
 628                         docHandler.ignorableWhitespace(buf, start,
 629                                 last - start);
 630                         docHandler.ignorableWhitespace(newline, 0, 1);
 631                     } else {
 632 //            validator.text ();
 633                         docHandler.characters(buf, start, last - start);
 634                         docHandler.characters(newline, 0, 1);
 635                     }
 636                     lineNumber++;
 637                     if (finish > (last + 1)) {
 638                         if (buf[last + 1] == '\n')
 639                             last++;
 640                     } else {    // CR at end of buffer
 641 // XXX case not yet handled ... as above
 642                     }
 643                     start = last + 1;
 644                     continue;
 645                 }
 646                 if (c != ']') {
 647                     if (c != ' ' && c != '\t')
 648                         white = false;
 649                     continue;
 650                 }
 651                 if ((last + 2) < finish) {
 652                     if (buf[last + 1] == ']' && buf[last + 2] == '>') {
 653                         done = true;
 654                         break;
 655                     }
 656                     white = false;
 657                     continue;
 658                 } else {
 659                     //last--;
 660                     break;
 661                 }
 662             }
 663             if (white) {
 664                 if (whitespaceInvalidMessage != null && errHandler != null)
 665                     errHandler.error(new SAXParseException(DTDParser.messages.getMessage(locale,
 666                             whitespaceInvalidMessage), null));
 667                 docHandler.ignorableWhitespace(buf, start, last - start);
 668             } else {
 669 //        validator.text ();
 670                 docHandler.characters(buf, start, last - start);
 671             }
 672             if (done) {
 673                 start = last + 3;
 674                 break;
 675             }
 676             start = last;
 677             if (isEOF())
 678                 fatal("P-073", null);
 679         }
 680         docHandler.endCDATA();
 681         return true;
 682     }
 683 
 684     // return false to backstep at end of buffer)


 686             throws SAXException {
 687 
 688         if ((offset + 1) >= finish)
 689             return false;
 690 
 691         char c1 = buf[offset++];
 692         char c2 = buf[offset];
 693 
 694         if ((c1 >= 0xd800 && c1 < 0xdc00) && (c2 >= 0xdc00 && c2 <= 0xdfff))
 695             return true;
 696         fatal("P-074", new Object[]{
 697             Integer.toHexString(c1 & 0x0ffff),
 698             Integer.toHexString(c2 & 0x0ffff)
 699         });
 700         return false;
 701     }
 702 
 703 
 704     /**
 705      * whitespace in markup (flagged to app, discardable)
 706      * <p>
 707      * <P> the document handler's ignorableWhitespace() method
 708      * is called on all the whitespace found
 709      */
 710     public boolean ignorableWhitespace(DTDEventListener handler)
 711             throws IOException, SAXException {
 712 
 713         char c;
 714         boolean isSpace = false;
 715         int first;
 716 
 717         // [3] S ::= #20 | #09 | #0D | #0A
 718         for (first = start; ;) {
 719             if (finish <= start) {
 720                 if (isSpace)
 721                     handler.ignorableWhitespace(buf, first, start - first);
 722                 fillbuf();
 723                 first = start;
 724             }
 725             if (finish <= start)
 726                 return isSpace;


 744                 handler.ignorableWhitespace(buf, first,
 745                         (start - 1) - first);
 746                 handler.ignorableWhitespace(newline, 0, 1);
 747                 if (start < finish && buf[start] == '\n')
 748                     ++start;
 749                 first = start;
 750                 continue;
 751 
 752             default:
 753                 ungetc();
 754                 if (isSpace)
 755                     handler.ignorableWhitespace(buf, first, start - first);
 756                 return isSpace;
 757             }
 758         }
 759     }
 760 
 761     /**
 762      * returns false iff 'next' string isn't as provided,
 763      * else skips that text and returns true.
 764      * <p>
 765      * <P> NOTE:  two alternative string representations are
 766      * both passed in, since one is faster.
 767      */
 768     public boolean peek(String next, char chars [])
 769             throws IOException, SAXException {
 770 
 771         int len;
 772         int i;
 773 
 774         if (chars != null)
 775             len = chars.length;
 776         else
 777             len = next.length();
 778 
 779         // buffer should hold the whole thing ... give it a
 780         // chance for the end-of-buffer case and cope with EOF
 781         // by letting fillbuf compact and fill
 782         if (finish <= start || (finish - start) < len)
 783             fillbuf();
 784 


 795         } else {
 796             for (i = 0; i < len && (start + i) < finish; i++) {
 797                 if (buf[start + i] != next.charAt(i))
 798                     return false;
 799             }
 800         }
 801 
 802         // if the first fillbuf didn't get enough data, give
 803         // fillbuf another chance to read
 804         if (i < len) {
 805             if (reader == null || isClosed)
 806                 return false;
 807 
 808             //
 809             // This diagnostic "knows" that the only way big strings would
 810             // fail to be peeked is where it's a symbol ... e.g. for an
 811             // </EndTag> construct.  That knowledge could also be applied
 812             // to get rid of the symbol length constraint, since having
 813             // the wrong symbol is a fatal error anyway ...
 814             //
 815             if (len > buf.length) {
 816                 fatal("P-077", new Object[]{Integer.valueOf(buf.length)});
 817             }
 818 
 819             fillbuf();
 820             return peek(next, chars);
 821         }
 822 
 823         start += len;
 824         return true;
 825     }
 826 
 827 
 828     //
 829     // Support for reporting the internal DTD subset, so <!DOCTYPE...>
 830     // declarations can be recreated.  This is collected as a single
 831     // string; such subsets are normally small, and many applications
 832     // don't even care about this.
 833     //
 834     public void startRemembering() {
 835 
 836         if (startRemember != 0)
 837             throw new InternalError();


 970 
 971     public void close() {
 972 
 973         try {
 974             if (reader != null && !isClosed)
 975                 reader.close();
 976             isClosed = true;
 977         } catch (IOException e) {
 978             /* NOTHING */
 979         }
 980     }
 981 
 982 
 983     private void fatal(String messageId, Object params [])
 984             throws SAXException {
 985 
 986         SAXParseException x = new SAXParseException(DTDParser.messages.getMessage(locale, messageId, params), null);
 987 
 988         // not continuable ... e.g. WF errors
 989         close();
 990         if (errHandler != null) {
 991             errHandler.fatalError(x);
 992         }
 993         throw x;
 994     }
 995 }
< prev index next >