home *** CD-ROM | disk | FTP | other *** search
/ Cre@te Online 2000 December / Cre@teOnline CD05.iso / MacSoft / XML ConsoleMax.sea / XML ConsoleMax / Required / swingall.jar / javax / swing / text / html / parser / Parser.class (.txt) < prev    next >
Encoding:
Java Class File  |  1999-07-15  |  21.8 KB  |  1,633 lines

  1. package javax.swing.text.html.parser;
  2.  
  3. import java.io.CharArrayReader;
  4. import java.io.IOException;
  5. import java.io.InterruptedIOException;
  6. import java.io.Reader;
  7. import java.util.Enumeration;
  8. import java.util.Vector;
  9. import javax.swing.text.ChangedCharSetException;
  10. import javax.swing.text.SimpleAttributeSet;
  11. import javax.swing.text.html.HTML;
  12. import javax.swing.text.html.HTML.Attribute;
  13.  
  14. public class Parser implements DTDConstants {
  15.    private char[] text = new char[1024];
  16.    private int textpos = 0;
  17.    private TagElement last;
  18.    private boolean space;
  19.    private char[] str = new char[128];
  20.    private int strpos = 0;
  21.    protected DTD dtd = null;
  22.    // $FF: renamed from: ch int
  23.    private int field_0;
  24.    // $FF: renamed from: ln int
  25.    private int field_1;
  26.    // $FF: renamed from: in java.io.Reader
  27.    private Reader field_2;
  28.    private Element recent;
  29.    private TagStack stack;
  30.    private boolean skipTag = false;
  31.    private TagElement lastFormSent = null;
  32.    private SimpleAttributeSet attributes = new SimpleAttributeSet();
  33.    private boolean seenHtml = false;
  34.    private boolean seenHead = false;
  35.    private boolean seenBody = false;
  36.    protected boolean strict = false;
  37.    private int crlfCount;
  38.    private int crCount;
  39.    private int lfCount;
  40.    private char[] buf = new char[256];
  41.    private int pos;
  42.    private int len;
  43.    private int currentPosition;
  44.  
  45.    public Parser(DTD var1) {
  46.       this.dtd = var1;
  47.    }
  48.  
  49.    void addString(int var1) {
  50.       if (this.strpos == this.str.length) {
  51.          char[] var2 = new char[this.str.length + 128];
  52.          System.arraycopy(this.str, 0, var2, 0, this.str.length);
  53.          this.str = var2;
  54.       }
  55.  
  56.       this.str[this.strpos++] = (char)var1;
  57.    }
  58.  
  59.    protected void endTag(boolean var1) {
  60.       this.handleText(this.stack.tag);
  61.       if (var1 && !this.stack.elem.omitEnd()) {
  62.          this.error("end.missing", this.stack.elem.getName());
  63.       } else if (!this.stack.terminate()) {
  64.          this.error("end.unexpected", this.stack.elem.getName());
  65.       }
  66.  
  67.       this.handleEndTag(this.stack.tag);
  68.       this.stack = this.stack.next;
  69.       this.recent = this.stack != null ? this.stack.elem : null;
  70.    }
  71.  
  72.    protected void error(String var1) {
  73.       this.error(var1, "?", "?", "?");
  74.    }
  75.  
  76.    protected void error(String var1, String var2) {
  77.       this.error(var1, var2, "?", "?");
  78.    }
  79.  
  80.    protected void error(String var1, String var2, String var3) {
  81.       this.error(var1, var2, var3, "?");
  82.    }
  83.  
  84.    protected void error(String var1, String var2, String var3, String var4) {
  85.       this.handleError(this.field_1, var1 + var2 + var3 + var4);
  86.    }
  87.  
  88.    void errorContext() throws ChangedCharSetException {
  89.       while(this.stack != null && this.stack.tag.getElement() != this.dtd.body) {
  90.          this.handleEndTag(this.stack.tag);
  91.          this.stack = this.stack.next;
  92.       }
  93.  
  94.       if (this.stack == null) {
  95.          this.legalElementContext(this.dtd.body);
  96.          this.startTag(this.makeTag(this.dtd.body, true));
  97.       }
  98.  
  99.    }
  100.  
  101.    protected void flushAttributes() {
  102.       this.attributes.removeAttributes(this.attributes);
  103.    }
  104.  
  105.    protected SimpleAttributeSet getAttributes() {
  106.       return this.attributes;
  107.    }
  108.  
  109.    char[] getChars(int var1) {
  110.       char[] var2 = new char[this.strpos - var1];
  111.       System.arraycopy(this.str, var1, var2, 0, this.strpos - var1);
  112.       this.strpos = var1;
  113.       return var2;
  114.    }
  115.  
  116.    char[] getChars(int var1, int var2) {
  117.       char[] var3 = new char[var2 - var1];
  118.       System.arraycopy(this.str, var1, var3, 0, var2 - var1);
  119.       return var3;
  120.    }
  121.  
  122.    protected int getCurrentLine() {
  123.       return this.field_1;
  124.    }
  125.  
  126.    protected int getCurrentPos() {
  127.       return this.currentPosition;
  128.    }
  129.  
  130.    String getEndOfLineString() {
  131.       if (this.crlfCount >= this.crCount) {
  132.          return this.lfCount >= this.crlfCount ? "\n" : "\r\n";
  133.       } else {
  134.          return this.crCount > this.lfCount ? "\r" : "\n";
  135.       }
  136.    }
  137.  
  138.    String getString(int var1) {
  139.       char[] var2 = new char[this.strpos - var1];
  140.       System.arraycopy(this.str, var1, var2, 0, this.strpos - var1);
  141.       this.strpos = var1;
  142.       return new String(var2);
  143.    }
  144.  
  145.    protected void handleComment(char[] var1) {
  146.    }
  147.  
  148.    protected void handleEOFInComment() {
  149.       int var1 = this.strIndexOf('\n');
  150.       if (var1 >= 0) {
  151.          this.handleComment(this.getChars(0, var1));
  152.  
  153.          try {
  154.             this.field_2.close();
  155.             this.field_2 = new CharArrayReader(this.getChars(var1 + 1));
  156.             this.field_0 = 62;
  157.          } catch (IOException var2) {
  158.             this.error("ioexception");
  159.          }
  160.  
  161.          this.resetStrBuffer();
  162.       } else {
  163.          this.error("eof.comment");
  164.       }
  165.  
  166.    }
  167.  
  168.    protected void handleEmptyTag(TagElement var1) throws ChangedCharSetException {
  169.    }
  170.  
  171.    protected void handleEndTag(TagElement var1) {
  172.    }
  173.  
  174.    protected void handleError(int var1, String var2) {
  175.       Thread.dumpStack();
  176.       System.out.println("**** " + this.stack);
  177.       System.out.println("line " + var1 + ": error: " + var2);
  178.       System.out.println();
  179.    }
  180.  
  181.    protected void handleStartTag(TagElement var1) {
  182.    }
  183.  
  184.    void handleText(TagElement var1) {
  185.       if (var1.breaksFlow()) {
  186.          this.space = false;
  187.       }
  188.  
  189.       if (this.textpos != 0 || this.space && this.stack != null && !this.last.breaksFlow() && this.stack.advance(this.dtd.pcdata)) {
  190.          if (this.space) {
  191.             if (this.textpos + 1 > this.text.length) {
  192.                char[] var2 = new char[this.text.length + 200];
  193.                System.arraycopy(this.text, 0, var2, 0, this.text.length);
  194.                this.text = var2;
  195.             }
  196.  
  197.             this.text[this.textpos++] = ' ';
  198.             this.space = false;
  199.          }
  200.  
  201.          char[] var3 = new char[this.textpos];
  202.          System.arraycopy(this.text, 0, var3, 0, this.textpos);
  203.          if (var1.getElement().getName().equals("title")) {
  204.             this.handleTitle(var3);
  205.          } else {
  206.             this.handleText(var3);
  207.          }
  208.  
  209.          this.textpos = 0;
  210.          this.last = var1;
  211.          this.space = false;
  212.       } else {
  213.          this.last = var1;
  214.          this.space = false;
  215.       }
  216.    }
  217.  
  218.    protected void handleText(char[] var1) {
  219.    }
  220.  
  221.    protected void handleTitle(char[] var1) {
  222.       this.handleText(var1);
  223.    }
  224.  
  225.    boolean ignoreElement(Element var1) {
  226.       String var2 = this.stack.elem.getName();
  227.       String var3 = var1.getName();
  228.       if ((!var3.equals("html") || !this.seenHtml) && (!var3.equals("head") || !this.seenHead) && (!var3.equals("body") || !this.seenBody)) {
  229.          if (var3.equals("dt") || var3.equals("dd")) {
  230.             TagStack var4;
  231.             for(var4 = this.stack; var4 != null && !var4.elem.getName().equals("dl"); var4 = var4.next) {
  232.             }
  233.  
  234.             if (var4 == null) {
  235.                return true;
  236.             }
  237.          }
  238.  
  239.          return var2.equals("table") && !var3.equals("#pcdata") && !var3.equals("input") || var3.equals("font") && (var2.equals("ul") || var2.equals("ol")) || var3.equals("meta") && this.stack != null || var3.equals("style") || var2.equals("table") && var3.equals("a");
  240.       } else {
  241.          return true;
  242.       }
  243.    }
  244.  
  245.    boolean legalElementContext(Element var1) throws ChangedCharSetException {
  246.       if (this.stack == null) {
  247.          if (var1 != this.dtd.html) {
  248.             this.startTag(this.makeTag(this.dtd.html, true));
  249.             return this.legalElementContext(var1);
  250.          } else {
  251.             return true;
  252.          }
  253.       } else if (this.stack.advance(var1)) {
  254.          this.markFirstTime(var1);
  255.          return true;
  256.       } else {
  257.          boolean var2 = false;
  258.          String var3 = this.stack.elem.getName();
  259.          String var4 = var1.getName();
  260.          if (!this.strict && (var3.equals("table") && var4.equals("td") || var3.equals("table") && var4.equals("th") || var3.equals("tr") && !var4.equals("tr"))) {
  261.             var2 = true;
  262.          }
  263.  
  264.          if (!this.strict && !var2 && (this.stack.elem.getName() != var1.getName() || var1.getName().equals("body")) && (this.skipTag = this.ignoreElement(var1))) {
  265.             this.error("tag.ignore", var1.getName());
  266.             return this.skipTag;
  267.          } else if (!this.strict && var3.equals("table") && !var4.equals("tr") && !var4.equals("td") && !var4.equals("th") && !var4.equals("caption")) {
  268.             Element var15 = this.dtd.getElement("tr");
  269.             TagElement var17 = this.makeTag(var15, true);
  270.             this.legalTagContext(var17);
  271.             this.startTag(var17);
  272.             this.error("start.missing", var1.getName());
  273.             return this.legalElementContext(var1);
  274.          } else {
  275.             if (!var2 && this.stack.terminate() && (!this.strict || this.stack.elem.omitEnd())) {
  276.                for(TagStack var5 = this.stack.next; var5 != null; var5 = var5.next) {
  277.                   if (var5.advance(var1)) {
  278.                      while(this.stack != var5) {
  279.                         this.endTag(true);
  280.                      }
  281.  
  282.                      return true;
  283.                   }
  284.  
  285.                   if (!var5.terminate() || this.strict && !var5.elem.omitEnd()) {
  286.                      break;
  287.                   }
  288.                }
  289.             }
  290.  
  291.             Element var14 = this.stack.first();
  292.             if (var14 == null || this.strict && !var14.omitStart() || var14 == this.dtd.head && var1 == this.dtd.pcdata) {
  293.                if (!this.strict) {
  294.                   ContentModel var16 = this.stack.contentModel();
  295.                   Vector var7 = new Vector();
  296.                   if (var16 != null) {
  297.                      var16.getElements(var7);
  298.                      Enumeration var8 = var7.elements();
  299.  
  300.                      while(var8.hasMoreElements()) {
  301.                         Element var9 = (Element)var8.nextElement();
  302.                         if (!this.stack.excluded(var9.getIndex())) {
  303.                            boolean var10 = false;
  304.  
  305.                            for(AttributeList var11 = var9.getAttributes(); var11 != null; var11 = var11.next) {
  306.                               if (var11.modifier == 2) {
  307.                                  var10 = true;
  308.                                  break;
  309.                               }
  310.                            }
  311.  
  312.                            if (!var10) {
  313.                               ContentModel var12 = var9.getContent();
  314.                               if (var12 != null && var12.first(var1)) {
  315.                                  TagElement var13 = this.makeTag(var9, true);
  316.                                  this.legalTagContext(var13);
  317.                                  this.startTag(var13);
  318.                                  this.error("start.missing", var9.getName());
  319.                                  return this.legalElementContext(var1);
  320.                               }
  321.                            }
  322.                         }
  323.                      }
  324.                   }
  325.                }
  326.  
  327.                if (this.stack.terminate() && this.stack.elem != this.dtd.body && (!this.strict || this.stack.elem.omitEnd())) {
  328.                   if (!this.stack.elem.omitEnd()) {
  329.                      this.error("end.missing", var1.getName());
  330.                   }
  331.  
  332.                   this.endTag(true);
  333.                   return this.legalElementContext(var1);
  334.                } else {
  335.                   return false;
  336.                }
  337.             } else {
  338.                TagElement var6 = this.makeTag(var14, true);
  339.                this.legalTagContext(var6);
  340.                this.startTag(var6);
  341.                if (!var14.omitStart()) {
  342.                   this.error("start.missing", var1.getName());
  343.                }
  344.  
  345.                return this.legalElementContext(var1);
  346.             }
  347.          }
  348.       }
  349.    }
  350.  
  351.    void legalTagContext(TagElement var1) throws ChangedCharSetException {
  352.       if (this.legalElementContext(var1.getElement())) {
  353.          this.markFirstTime(var1.getElement());
  354.       } else if (var1.breaksFlow() && this.stack != null && !this.stack.tag.breaksFlow()) {
  355.          this.endTag(true);
  356.          this.legalTagContext(var1);
  357.       } else {
  358.          for(TagStack var2 = this.stack; var2 != null; var2 = var2.next) {
  359.             if (var2.tag.getElement() == this.dtd.head) {
  360.                while(this.stack != var2) {
  361.                   this.endTag(true);
  362.                }
  363.  
  364.                this.endTag(true);
  365.                this.legalTagContext(var1);
  366.                return;
  367.             }
  368.          }
  369.  
  370.          this.error("tag.unexpected", var1.getElement().getName());
  371.       }
  372.    }
  373.  
  374.    protected TagElement makeTag(Element var1) {
  375.       return this.makeTag(var1, false);
  376.    }
  377.  
  378.    protected TagElement makeTag(Element var1, boolean var2) {
  379.       return new TagElement(var1, var2);
  380.    }
  381.  
  382.    protected void markFirstTime(Element var1) {
  383.       String var2 = var1.getName();
  384.       if (var2.equals("html")) {
  385.          this.seenHtml = true;
  386.       } else if (var2.equals("head")) {
  387.          this.seenHead = true;
  388.       } else if (var2.equals("body")) {
  389.          this.seenBody = true;
  390.       }
  391.  
  392.    }
  393.  
  394.    public synchronized void parse(Reader var1) throws IOException {
  395.       this.field_2 = var1;
  396.       this.field_1 = 1;
  397.       this.seenHtml = false;
  398.       this.seenHead = false;
  399.       this.seenBody = false;
  400.       this.crCount = this.lfCount = this.crlfCount = 0;
  401.  
  402.       try {
  403.          try {
  404.             this.field_0 = this.readCh();
  405.             this.text = new char[1024];
  406.             this.str = new char[128];
  407.             this.parseContent();
  408.  
  409.             while(this.stack != null) {
  410.                this.endTag(true);
  411.             }
  412.          } finally {
  413.             var1.close();
  414.          }
  415.       } catch (IOException var17) {
  416.          this.errorContext();
  417.          this.error("ioexception");
  418.          throw var17;
  419.       } catch (Exception var18) {
  420.          this.errorContext();
  421.          this.error("exception", var18.getClass().getName(), ((Throwable)var18).getMessage());
  422.          ((Throwable)var18).printStackTrace();
  423.       } catch (ThreadDeath var19) {
  424.          this.errorContext();
  425.          this.error("terminated");
  426.          ((Throwable)var19).printStackTrace();
  427.          throw var19;
  428.       } finally {
  429.          while(this.stack != null) {
  430.             this.handleEndTag(this.stack.tag);
  431.             this.stack = this.stack.next;
  432.          }
  433.  
  434.          this.text = null;
  435.          this.str = null;
  436.       }
  437.  
  438.    }
  439.  
  440.    void parseAttributeSpecificationList(Element var1) throws IOException {
  441.       while(true) {
  442.          this.skipSpace();
  443.          switch (this.field_0) {
  444.             case -1:
  445.             case 47:
  446.             case 60:
  447.             case 62:
  448.                return;
  449.             case 45:
  450.                if ((this.field_0 = this.readCh()) == 45) {
  451.                   this.field_0 = this.readCh();
  452.                   this.parseComment();
  453.                   this.strpos = 0;
  454.                   break;
  455.                }
  456.  
  457.                this.error("invalid.tagchar", "-", var1.getName());
  458.                this.field_0 = this.readCh();
  459.                break;
  460.             default:
  461.                Object var2 = null;
  462.                Object var3 = null;
  463.                Object var4 = null;
  464.                AttributeList var6;
  465.                String var7;
  466.                String var8;
  467.                if (this.parseIdentifier(true)) {
  468.                   var7 = this.getString(0);
  469.                   this.skipSpace();
  470.                   if (this.field_0 == 61) {
  471.                      this.field_0 = this.readCh();
  472.                      this.skipSpace();
  473.                      var6 = var1.getAttribute(var7);
  474.                      var8 = this.parseAttributeValue(var6 != null && var6.type != 1 && var6.type != 11 && var6.type != 7);
  475.                   } else {
  476.                      var8 = var7;
  477.                      var6 = var1.getAttributeByValue(var7);
  478.                      if (var6 == null) {
  479.                         var6 = var1.getAttribute(var7);
  480.                         if (var6 != null) {
  481.                            var8 = var6.getValue();
  482.                         }
  483.                      }
  484.                   }
  485.                } else {
  486.                   if (!this.strict && this.field_0 == 44) {
  487.                      this.field_0 = this.readCh();
  488.                      continue;
  489.                   }
  490.  
  491.                   if (!this.strict && this.field_0 == 34) {
  492.                      this.field_0 = this.readCh();
  493.                      this.skipSpace();
  494.                      if (!this.parseIdentifier(true)) {
  495.                         char[] var10 = new char[]{(char)this.field_0};
  496.                         this.error("invalid.tagchar", new String(var10), var1.getName());
  497.                         this.field_0 = this.readCh();
  498.                         continue;
  499.                      }
  500.  
  501.                      var7 = this.getString(0);
  502.                      if (this.field_0 == 34) {
  503.                         this.field_0 = this.readCh();
  504.                      }
  505.  
  506.                      this.skipSpace();
  507.                      if (this.field_0 == 61) {
  508.                         this.field_0 = this.readCh();
  509.                         this.skipSpace();
  510.                         var6 = var1.getAttribute(var7);
  511.                         var8 = this.parseAttributeValue(var6 != null && var6.type != 1 && var6.type != 11);
  512.                      } else {
  513.                         var8 = var7;
  514.                         var6 = var1.getAttributeByValue(var7);
  515.                         if (var6 == null) {
  516.                            var6 = var1.getAttribute(var7);
  517.                            if (var6 != null) {
  518.                               var8 = var6.getValue();
  519.                            }
  520.                         }
  521.                      }
  522.                   } else {
  523.                      if (this.strict || !this.attributes.isEmpty() || this.field_0 != 61) {
  524.                         if (!this.strict && this.field_0 == 61) {
  525.                            this.field_0 = this.readCh();
  526.                            this.skipSpace();
  527.                            var8 = this.parseAttributeValue(true);
  528.                            this.error("attvalerr");
  529.                            return;
  530.                         }
  531.  
  532.                         char[] var5 = new char[]{(char)this.field_0};
  533.                         this.error("invalid.tagchar", new String(var5), var1.getName());
  534.                         if (this.strict) {
  535.                            return;
  536.                         }
  537.  
  538.                         this.field_0 = this.readCh();
  539.                         continue;
  540.                      }
  541.  
  542.                      this.field_0 = this.readCh();
  543.                      this.skipSpace();
  544.                      var7 = var1.getName();
  545.                      var6 = var1.getAttribute(var7);
  546.                      var8 = this.parseAttributeValue(var6 != null && var6.type != 1 && var6.type != 11);
  547.                   }
  548.                }
  549.  
  550.                if (var6 != null) {
  551.                   var7 = var6.getName();
  552.                } else {
  553.                   this.error("invalid.tagatt", var7, var1.getName());
  554.                }
  555.  
  556.                if (this.attributes.isDefined(var7)) {
  557.                   this.error("multi.tagatt", var7, var1.getName());
  558.                }
  559.  
  560.                if (var8 == null) {
  561.                   var8 = var6 != null && var6.value != null ? var6.value : "#DEFAULT";
  562.                } else if (var6 != null && var6.values != null && !var6.values.contains(var8)) {
  563.                   this.error("invalid.tagattval", var7, var1.getName());
  564.                }
  565.  
  566.                HTML.Attribute var11 = HTML.getAttributeKey(var7);
  567.                if (var11 == null) {
  568.                   this.attributes.addAttribute(var7, var8);
  569.                } else {
  570.                   this.attributes.addAttribute(var11, var8);
  571.                }
  572.          }
  573.       }
  574.    }
  575.  
  576.    String parseAttributeValue(boolean var1) throws IOException {
  577.       int var2 = -1;
  578.       switch (this.field_0) {
  579.          case 34:
  580.          case 39:
  581.             var2 = this.field_0;
  582.             this.field_0 = this.readCh();
  583.          case 35:
  584.          case 36:
  585.          case 37:
  586.          case 38:
  587.       }
  588.  
  589.       label96:
  590.       while(true) {
  591.          int var3 = this.field_0;
  592.          switch (var3) {
  593.             case -1:
  594.                return this.getString(0);
  595.             case 9:
  596.                if (var2 < 0) {
  597.                   var3 = 32;
  598.                }
  599.             case 32:
  600.                this.field_0 = this.readCh();
  601.                if (var2 < 0) {
  602.                   return this.getString(0);
  603.                }
  604.                break;
  605.             case 10:
  606.                ++this.field_1;
  607.                this.field_0 = this.readCh();
  608.                ++this.lfCount;
  609.                if (var2 < 0) {
  610.                   return this.getString(0);
  611.                }
  612.                break;
  613.             case 13:
  614.                ++this.field_1;
  615.                if ((this.field_0 = this.readCh()) == 10) {
  616.                   this.field_0 = this.readCh();
  617.                   ++this.crlfCount;
  618.                } else {
  619.                   ++this.crCount;
  620.                }
  621.  
  622.                if (var2 < 0) {
  623.                   return this.getString(0);
  624.                }
  625.                break;
  626.             case 34:
  627.             case 39:
  628.                this.field_0 = this.readCh();
  629.                if (var3 == var2) {
  630.                   return this.getString(0);
  631.                }
  632.  
  633.                if (var2 == -1) {
  634.                   this.error("attvalerr");
  635.                   if (!this.strict && this.field_0 != 32) {
  636.                      continue;
  637.                   }
  638.  
  639.                   return this.getString(0);
  640.                }
  641.                break;
  642.             case 38:
  643.                if (this.strict && var2 < 0) {
  644.                   this.field_0 = this.readCh();
  645.                   break;
  646.                }
  647.  
  648.                char[] var4 = this.parseEntityReference();
  649.                int var5 = 0;
  650.  
  651.                while(true) {
  652.                   if (var5 >= var4.length) {
  653.                      continue label96;
  654.                   }
  655.  
  656.                   var3 = var4[var5];
  657.                   this.addString(var1 && var3 >= 65 && var3 <= 90 ? 97 + var3 - 65 : var3);
  658.                   ++var5;
  659.                }
  660.             case 60:
  661.             case 62:
  662.                if (var2 < 0) {
  663.                   return this.getString(0);
  664.                }
  665.  
  666.                this.field_0 = this.readCh();
  667.                break;
  668.             case 61:
  669.                if (var2 < 0) {
  670.                   this.error("attvalerr");
  671.                   if (this.strict) {
  672.                      return this.getString(0);
  673.                   }
  674.                }
  675.  
  676.                this.field_0 = this.readCh();
  677.                break;
  678.             default:
  679.                if (var1 && var3 >= 65 && var3 <= 90) {
  680.                   var3 = 97 + var3 - 65;
  681.                }
  682.  
  683.                this.field_0 = this.readCh();
  684.          }
  685.  
  686.          this.addString(var3);
  687.       }
  688.    }
  689.  
  690.    void parseComment() throws IOException {
  691.       while(true) {
  692.          int var1 = this.field_0;
  693.          switch (var1) {
  694.             case -1:
  695.                this.handleEOFInComment();
  696.                return;
  697.             case 10:
  698.                ++this.field_1;
  699.                this.field_0 = this.readCh();
  700.                ++this.lfCount;
  701.                break;
  702.             case 13:
  703.                ++this.field_1;
  704.                if ((this.field_0 = this.readCh()) == 10) {
  705.                   this.field_0 = this.readCh();
  706.                   ++this.crlfCount;
  707.                } else {
  708.                   ++this.crCount;
  709.                }
  710.  
  711.                var1 = 10;
  712.                break;
  713.             case 45:
  714.                if (!this.strict && this.strpos != 0 && this.str[this.strpos - 1] == '-') {
  715.                   if ((this.field_0 = this.readCh()) == 62) {
  716.                      return;
  717.                   }
  718.  
  719.                   if (this.field_0 == 33) {
  720.                      if ((this.field_0 = this.readCh()) == 62) {
  721.                         return;
  722.                      }
  723.  
  724.                      this.addString(45);
  725.                      this.addString(33);
  726.                      continue;
  727.                   }
  728.                } else if ((this.field_0 = this.readCh()) == 45) {
  729.                   this.field_0 = this.readCh();
  730.                   if (this.strict || this.field_0 == 62) {
  731.                      return;
  732.                   }
  733.  
  734.                   if (this.field_0 == 33) {
  735.                      if ((this.field_0 = this.readCh()) == 62) {
  736.                         return;
  737.                      }
  738.  
  739.                      this.addString(45);
  740.                      this.addString(33);
  741.                      continue;
  742.                   } else {
  743.                      this.addString(45);
  744.                   }
  745.                }
  746.                break;
  747.             case 62:
  748.                this.field_0 = this.readCh();
  749.                break;
  750.             default:
  751.                this.field_0 = this.readCh();
  752.          }
  753.  
  754.          this.addString(var1);
  755.       }
  756.    }
  757.  
  758.    void parseContent() throws IOException {
  759.       Thread var1 = Thread.currentThread();
  760.  
  761.       while(!var1.isInterrupted()) {
  762.          int var2 = this.field_0;
  763.          switch (var2) {
  764.             case -1:
  765.                return;
  766.             case 9:
  767.             case 32:
  768.                this.field_0 = this.readCh();
  769.                if (this.stack == null || !this.stack.pre) {
  770.                   this.space = true;
  771.                   continue;
  772.                }
  773.                break;
  774.             case 10:
  775.                ++this.field_1;
  776.                ++this.lfCount;
  777.                this.field_0 = this.readCh();
  778.                if (this.stack == null || !this.stack.pre) {
  779.                   this.space = true;
  780.                   continue;
  781.                }
  782.                break;
  783.             case 13:
  784.                ++this.field_1;
  785.                var2 = 10;
  786.                if ((this.field_0 = this.readCh()) == 10) {
  787.                   this.field_0 = this.readCh();
  788.                   ++this.crlfCount;
  789.                } else {
  790.                   ++this.crCount;
  791.                }
  792.  
  793.                if (this.stack == null || !this.stack.pre) {
  794.                   this.space = true;
  795.                   continue;
  796.                }
  797.                break;
  798.             case 38:
  799.                if (this.textpos == 0) {
  800.                   if (!this.legalElementContext(this.dtd.pcdata)) {
  801.                      this.error("unexpected.pcdata");
  802.                   }
  803.  
  804.                   if (this.last.breaksFlow()) {
  805.                      this.space = false;
  806.                   }
  807.                }
  808.  
  809.                char[] var3 = this.parseEntityReference();
  810.                if (this.textpos + var3.length + 1 > this.text.length) {
  811.                   char[] var4 = new char[Math.max(this.textpos + var3.length + 128, this.text.length * 2)];
  812.                   System.arraycopy(this.text, 0, var4, 0, this.text.length);
  813.                   this.text = var4;
  814.                }
  815.  
  816.                if (this.space) {
  817.                   this.space = false;
  818.                   this.text[this.textpos++] = ' ';
  819.                }
  820.  
  821.                System.arraycopy(var3, 0, this.text, this.textpos, var3.length);
  822.                this.textpos += var3.length;
  823.                continue;
  824.             case 47:
  825.                this.field_0 = this.readCh();
  826.                if (this.stack != null && this.stack.net) {
  827.                   this.endTag(false);
  828.                   continue;
  829.                }
  830.                break;
  831.             case 60:
  832.                this.parseTag();
  833.                continue;
  834.             default:
  835.                if (this.textpos == 0) {
  836.                   if (!this.legalElementContext(this.dtd.pcdata)) {
  837.                      this.error("unexpected.pcdata");
  838.                   }
  839.  
  840.                   if (this.last.breaksFlow()) {
  841.                      this.space = false;
  842.                   }
  843.                }
  844.  
  845.                this.field_0 = this.readCh();
  846.          }
  847.  
  848.          if (this.textpos + 2 > this.text.length) {
  849.             char[] var5 = new char[this.text.length + 128];
  850.             System.arraycopy(this.text, 0, var5, 0, this.text.length);
  851.             this.text = var5;
  852.          }
  853.  
  854.          if (this.space) {
  855.             this.text[this.textpos++] = ' ';
  856.             this.space = false;
  857.          }
  858.  
  859.          this.text[this.textpos++] = (char)var2;
  860.       }
  861.  
  862.       var1.interrupt();
  863.    }
  864.  
  865.    public String parseDTDMarkup() throws IOException {
  866.       StringBuffer var1 = new StringBuffer();
  867.       this.field_0 = this.readCh();
  868.  
  869.       while(true) {
  870.          switch (this.field_0) {
  871.             case -1:
  872.                this.error("invalid.markup");
  873.                return var1.toString();
  874.             case 10:
  875.                ++this.field_1;
  876.                this.field_0 = this.readCh();
  877.                ++this.lfCount;
  878.                break;
  879.             case 13:
  880.                ++this.field_1;
  881.                if ((this.field_0 = this.readCh()) == 10) {
  882.                   this.field_0 = this.readCh();
  883.                   ++this.crlfCount;
  884.                } else {
  885.                   ++this.crCount;
  886.                }
  887.                break;
  888.             case 34:
  889.                this.field_0 = this.readCh();
  890.                break;
  891.             case 62:
  892.                this.field_0 = this.readCh();
  893.                return var1.toString();
  894.             default:
  895.                var1.append((char)(this.field_0 & 255));
  896.                this.field_0 = this.readCh();
  897.          }
  898.       }
  899.    }
  900.  
  901.    private char[] parseEntityReference() throws IOException {
  902.       int var1 = this.strpos;
  903.       if ((this.field_0 = this.readCh()) == 35) {
  904.          int var2 = 0;
  905.          this.field_0 = this.readCh();
  906.          if (this.field_0 >= 48 && this.field_0 <= 57) {
  907.             while(this.field_0 >= 48 && this.field_0 <= 57) {
  908.                var2 = var2 * 10 + this.field_0 - 48;
  909.                this.field_0 = this.readCh();
  910.             }
  911.  
  912.             switch (this.field_0) {
  913.                case 10:
  914.                   ++this.field_1;
  915.                   this.field_0 = this.readCh();
  916.                   ++this.lfCount;
  917.                   break;
  918.                case 13:
  919.                   ++this.field_1;
  920.                   if ((this.field_0 = this.readCh()) == 10) {
  921.                      this.field_0 = this.readCh();
  922.                      ++this.crlfCount;
  923.                   } else {
  924.                      ++this.crCount;
  925.                   }
  926.                   break;
  927.                case 59:
  928.                   this.field_0 = this.readCh();
  929.             }
  930.  
  931.             char[] var8 = new char[]{(char)var2};
  932.             return var8;
  933.          }
  934.  
  935.          this.addString(35);
  936.          if (!this.parseIdentifier(false)) {
  937.             this.error("ident.expected");
  938.             this.strpos = var1;
  939.             char[] var3 = new char[]{'&', '#'};
  940.             return var3;
  941.          }
  942.       } else if (!this.parseIdentifier(false)) {
  943.          char[] var7 = new char[]{'&'};
  944.          return var7;
  945.       }
  946.  
  947.       switch (this.field_0) {
  948.          case 10:
  949.             ++this.field_1;
  950.             this.field_0 = this.readCh();
  951.             ++this.lfCount;
  952.             break;
  953.          case 13:
  954.             ++this.field_1;
  955.             if ((this.field_0 = this.readCh()) == 10) {
  956.                this.field_0 = this.readCh();
  957.                ++this.crlfCount;
  958.             } else {
  959.                ++this.crCount;
  960.             }
  961.             break;
  962.          case 59:
  963.             this.field_0 = this.readCh();
  964.       }
  965.  
  966.       String var6 = this.getString(var1);
  967.       Entity var9 = this.dtd.getEntity(var6);
  968.       if (!this.strict && var9 == null) {
  969.          var9 = this.dtd.getEntity(var6.toLowerCase());
  970.       }
  971.  
  972.       if (var9 != null && var9.isGeneral()) {
  973.          return var9.getData();
  974.       } else if (var6.length() == 0) {
  975.          this.error("invalid.entref", var6);
  976.          return new char[0];
  977.       } else {
  978.          String var4 = "&" + var6;
  979.          char[] var5 = new char[var4.length()];
  980.          var4.getChars(0, var5.length, var5, 0);
  981.          return var5;
  982.       }
  983.    }
  984.  
  985.    boolean parseIdentifier(boolean var1) throws IOException {
  986.       switch (this.field_0) {
  987.          case 65:
  988.          case 66:
  989.          case 67:
  990.          case 68:
  991.          case 69:
  992.          case 70:
  993.          case 71:
  994.          case 72:
  995.          case 73:
  996.          case 74:
  997.          case 75:
  998.          case 76:
  999.          case 77:
  1000.          case 78:
  1001.          case 79:
  1002.          case 80:
  1003.          case 81:
  1004.          case 82:
  1005.          case 83:
  1006.          case 84:
  1007.          case 85:
  1008.          case 86:
  1009.          case 87:
  1010.          case 88:
  1011.          case 89:
  1012.          case 90:
  1013.             if (var1) {
  1014.                this.field_0 = 97 + (this.field_0 - 65);
  1015.             }
  1016.             break;
  1017.          case 91:
  1018.          case 92:
  1019.          case 93:
  1020.          case 94:
  1021.          case 95:
  1022.          case 96:
  1023.          default:
  1024.             return false;
  1025.          case 97:
  1026.          case 98:
  1027.          case 99:
  1028.          case 100:
  1029.          case 101:
  1030.          case 102:
  1031.          case 103:
  1032.          case 104:
  1033.          case 105:
  1034.          case 106:
  1035.          case 107:
  1036.          case 108:
  1037.          case 109:
  1038.          case 110:
  1039.          case 111:
  1040.          case 112:
  1041.          case 113:
  1042.          case 114:
  1043.          case 115:
  1044.          case 116:
  1045.          case 117:
  1046.          case 118:
  1047.          case 119:
  1048.          case 120:
  1049.          case 121:
  1050.          case 122:
  1051.       }
  1052.  
  1053.       while(true) {
  1054.          this.addString(this.field_0);
  1055.          switch (this.field_0 = this.readCh()) {
  1056.             case 45:
  1057.             case 46:
  1058.             case 48:
  1059.             case 49:
  1060.             case 50:
  1061.             case 51:
  1062.             case 52:
  1063.             case 53:
  1064.             case 54:
  1065.             case 55:
  1066.             case 56:
  1067.             case 57:
  1068.             case 95:
  1069.             case 97:
  1070.             case 98:
  1071.             case 99:
  1072.             case 100:
  1073.             case 101:
  1074.             case 102:
  1075.             case 103:
  1076.             case 104:
  1077.             case 105:
  1078.             case 106:
  1079.             case 107:
  1080.             case 108:
  1081.             case 109:
  1082.             case 110:
  1083.             case 111:
  1084.             case 112:
  1085.             case 113:
  1086.             case 114:
  1087.             case 115:
  1088.             case 116:
  1089.             case 117:
  1090.             case 118:
  1091.             case 119:
  1092.             case 120:
  1093.             case 121:
  1094.             case 122:
  1095.                break;
  1096.             case 47:
  1097.             case 58:
  1098.             case 59:
  1099.             case 60:
  1100.             case 61:
  1101.             case 62:
  1102.             case 63:
  1103.             case 64:
  1104.             case 91:
  1105.             case 92:
  1106.             case 93:
  1107.             case 94:
  1108.             case 96:
  1109.             default:
  1110.                return true;
  1111.             case 65:
  1112.             case 66:
  1113.             case 67:
  1114.             case 68:
  1115.             case 69:
  1116.             case 70:
  1117.             case 71:
  1118.             case 72:
  1119.             case 73:
  1120.             case 74:
  1121.             case 75:
  1122.             case 76:
  1123.             case 77:
  1124.             case 78:
  1125.             case 79:
  1126.             case 80:
  1127.             case 81:
  1128.             case 82:
  1129.             case 83:
  1130.             case 84:
  1131.             case 85:
  1132.             case 86:
  1133.             case 87:
  1134.             case 88:
  1135.             case 89:
  1136.             case 90:
  1137.                if (var1) {
  1138.                   this.field_0 = 97 + (this.field_0 - 65);
  1139.                }
  1140.          }
  1141.       }
  1142.    }
  1143.  
  1144.    void parseInvalidTag() throws IOException {
  1145.       while(true) {
  1146.          this.skipSpace();
  1147.          switch (this.field_0) {
  1148.             case -1:
  1149.             case 62:
  1150.                this.field_0 = this.readCh();
  1151.                return;
  1152.             case 60:
  1153.                return;
  1154.             default:
  1155.                this.field_0 = this.readCh();
  1156.          }
  1157.       }
  1158.    }
  1159.  
  1160.    void parseLiteral(boolean var1) throws IOException {
  1161.       while(true) {
  1162.          int var2 = this.field_0;
  1163.          switch (var2) {
  1164.             case -1:
  1165.                this.error("eof.literal", this.stack.elem.getName());
  1166.                this.endTag(true);
  1167.                return;
  1168.             case 10:
  1169.                ++this.field_1;
  1170.                this.field_0 = this.readCh();
  1171.                ++this.lfCount;
  1172.                break;
  1173.             case 13:
  1174.                ++this.field_1;
  1175.                if ((this.field_0 = this.readCh()) == 10) {
  1176.                   this.field_0 = this.readCh();
  1177.                   ++this.crlfCount;
  1178.                } else {
  1179.                   ++this.crCount;
  1180.                }
  1181.  
  1182.                var2 = 10;
  1183.                break;
  1184.             case 38:
  1185.                char[] var5 = this.parseEntityReference();
  1186.                if (this.textpos + var5.length > this.text.length) {
  1187.                   char[] var6 = new char[Math.max(this.textpos + var5.length + 128, this.text.length * 2)];
  1188.                   System.arraycopy(this.text, 0, var6, 0, this.text.length);
  1189.                   this.text = var6;
  1190.                }
  1191.  
  1192.                System.arraycopy(var5, 0, this.text, this.textpos, var5.length);
  1193.                this.textpos += var5.length;
  1194.                continue;
  1195.             case 62:
  1196.                this.field_0 = this.readCh();
  1197.                int var3 = this.textpos - (this.stack.elem.name.length() + 2);
  1198.                int var4 = 0;
  1199.                if (var3 >= 0 && this.text[var3++] == '<' && this.text[var3] == '/') {
  1200.                   do {
  1201.                      ++var3;
  1202.                   } while(var3 < this.textpos && Character.toLowerCase(this.text[var3]) == this.stack.elem.name.charAt(var4++));
  1203.  
  1204.                   if (var3 == this.textpos) {
  1205.                      this.textpos -= this.stack.elem.name.length() + 2;
  1206.                      if (this.textpos > 0 && this.text[this.textpos - 1] == '\n') {
  1207.                         --this.textpos;
  1208.                      }
  1209.  
  1210.                      this.endTag(false);
  1211.                      return;
  1212.                   }
  1213.                }
  1214.                break;
  1215.             default:
  1216.                this.field_0 = this.readCh();
  1217.          }
  1218.  
  1219.          if (this.textpos == this.text.length) {
  1220.             char[] var8 = new char[this.text.length + 128];
  1221.             System.arraycopy(this.text, 0, var8, 0, this.text.length);
  1222.             this.text = var8;
  1223.          }
  1224.  
  1225.          this.text[this.textpos++] = (char)var2;
  1226.       }
  1227.    }
  1228.  
  1229.    protected boolean parseMarkupDeclarations(StringBuffer var1) throws IOException {
  1230.       if (var1.length() == "DOCTYPE".length() && var1.toString().toUpperCase().equals("DOCTYPE")) {
  1231.          this.parseDTDMarkup();
  1232.          return true;
  1233.       } else {
  1234.          return false;
  1235.       }
  1236.    }
  1237.  
  1238.    void parseTag() throws IOException {
  1239.       Object var1 = null;
  1240.       boolean var2 = false;
  1241.       boolean var3 = false;
  1242.       boolean var4 = false;
  1243.       switch (this.field_0 = this.readCh()) {
  1244.          case -1:
  1245.             this.error("eof");
  1246.             return;
  1247.          case 33:
  1248.             switch (this.field_0 = this.readCh()) {
  1249.                case 45:
  1250.                   while(true) {
  1251.                      if (this.field_0 == 45) {
  1252.                         if (!this.strict || (this.field_0 = this.readCh()) == 45) {
  1253.                            this.field_0 = this.readCh();
  1254.                            if (!this.strict && this.field_0 == 45) {
  1255.                               this.field_0 = this.readCh();
  1256.                            }
  1257.  
  1258.                            if (this.textpos != 0) {
  1259.                               char[] var13 = new char[this.textpos];
  1260.                               System.arraycopy(this.text, 0, var13, 0, this.textpos);
  1261.                               this.handleText(var13);
  1262.                               this.textpos = 0;
  1263.                            }
  1264.  
  1265.                            this.parseComment();
  1266.                            this.handleComment(this.getChars(0));
  1267.                            continue;
  1268.                         }
  1269.  
  1270.                         if (!var3) {
  1271.                            var3 = true;
  1272.                            this.error("invalid.commentchar", "-");
  1273.                         }
  1274.                      }
  1275.  
  1276.                      this.skipSpace();
  1277.                      switch (this.field_0) {
  1278.                         case 45:
  1279.                            break;
  1280.                         case 62:
  1281.                            this.field_0 = this.readCh();
  1282.                         case -1:
  1283.                            return;
  1284.                         default:
  1285.                            this.field_0 = this.readCh();
  1286.                            if (!var3) {
  1287.                               var3 = true;
  1288.                               this.error("invalid.commentchar", String.valueOf((char)this.field_0));
  1289.                            }
  1290.                      }
  1291.                   }
  1292.                default:
  1293.                   StringBuffer var14 = new StringBuffer();
  1294.  
  1295.                   while(true) {
  1296.                      var14.append((char)this.field_0);
  1297.                      if (this.parseMarkupDeclarations(var14)) {
  1298.                         return;
  1299.                      }
  1300.  
  1301.                      switch (this.field_0) {
  1302.                         case 10:
  1303.                            ++this.field_1;
  1304.                            this.field_0 = this.readCh();
  1305.                            ++this.lfCount;
  1306.                            break;
  1307.                         case 13:
  1308.                            ++this.field_1;
  1309.                            if ((this.field_0 = this.readCh()) == 10) {
  1310.                               this.field_0 = this.readCh();
  1311.                               ++this.crlfCount;
  1312.                            } else {
  1313.                               ++this.crCount;
  1314.                            }
  1315.                            break;
  1316.                         case 62:
  1317.                            this.field_0 = this.readCh();
  1318.                         case -1:
  1319.                            this.error("invalid.markup");
  1320.                            return;
  1321.                         default:
  1322.                            this.field_0 = this.readCh();
  1323.                      }
  1324.                   }
  1325.             }
  1326.          case 47:
  1327.             Element var7;
  1328.             switch (this.field_0 = this.readCh()) {
  1329.                case 61:
  1330.                default:
  1331.                   if (!this.parseIdentifier(true)) {
  1332.                      this.error("expected.endtagname");
  1333.                      return;
  1334.                   }
  1335.  
  1336.                   this.skipSpace();
  1337.                   switch (this.field_0) {
  1338.                      case 60:
  1339.                         break;
  1340.                      case 61:
  1341.                      default:
  1342.                         this.error("expected", "'>'");
  1343.  
  1344.                         while(this.field_0 != -1 && this.field_0 != 10 && this.field_0 != 62) {
  1345.                            this.field_0 = this.readCh();
  1346.                         }
  1347.  
  1348.                         if (this.field_0 == 62) {
  1349.                            this.field_0 = this.readCh();
  1350.                         }
  1351.                         break;
  1352.                      case 62:
  1353.                         this.field_0 = this.readCh();
  1354.                   }
  1355.  
  1356.                   String var5 = this.getString(0);
  1357.                   if (!this.dtd.elementExists(var5)) {
  1358.                      this.error("end.unrecognized", var5);
  1359.                      if (this.textpos > 0 && this.text[this.textpos - 1] == '\n') {
  1360.                         --this.textpos;
  1361.                      }
  1362.  
  1363.                      var7 = this.dtd.getElement("unknown");
  1364.                      var7.name = var5;
  1365.                      var4 = true;
  1366.                   } else {
  1367.                      var7 = this.dtd.getElement(var5);
  1368.                   }
  1369.                   break;
  1370.                case 62:
  1371.                   this.field_0 = this.readCh();
  1372.                case 60:
  1373.                   if (this.recent == null) {
  1374.                      this.error("invalid.shortend");
  1375.                      return;
  1376.                   }
  1377.  
  1378.                   var7 = this.recent;
  1379.             }
  1380.  
  1381.             if (this.stack == null) {
  1382.                this.error("end.extra.tag", var7.getName());
  1383.                return;
  1384.             } else {
  1385.                if (this.textpos > 0 && this.text[this.textpos - 1] == '\n') {
  1386.                   if (this.stack.pre) {
  1387.                      if (this.textpos > 1 && this.text[this.textpos - 2] != '\n') {
  1388.                         --this.textpos;
  1389.                      }
  1390.                   } else {
  1391.                      --this.textpos;
  1392.                   }
  1393.                }
  1394.  
  1395.                if (!this.strict && var7.getName().equals("form")) {
  1396.                   if (this.lastFormSent != null) {
  1397.                      this.handleEndTag(this.lastFormSent);
  1398.                      return;
  1399.                   }
  1400.  
  1401.                   return;
  1402.                } else if (var4) {
  1403.                   TagElement var12 = this.makeTag(var7);
  1404.                   this.handleText(var12);
  1405.                   this.attributes.addAttribute(Attribute.ENDTAG, "true");
  1406.                   this.handleEmptyTag(this.makeTag(var7));
  1407.                   var4 = false;
  1408.                   return;
  1409.                } else {
  1410.                   if (!this.strict) {
  1411.                      String var10 = this.stack.elem.getName();
  1412.                      if (var10.equals("table") && !var7.getName().equals(var10)) {
  1413.                         this.error("tag.ignore", var7.getName());
  1414.                         return;
  1415.                      }
  1416.  
  1417.                      if ((var10.equals("tr") || var10.equals("td")) && !var7.getName().equals("table") && !var7.getName().equals(var10)) {
  1418.                         this.error("tag.ignore", var7.getName());
  1419.                         return;
  1420.                      }
  1421.                   }
  1422.  
  1423.                   TagStack var11;
  1424.                   for(var11 = this.stack; var11 != null && var7 != var11.elem; var11 = var11.next) {
  1425.                   }
  1426.  
  1427.                   if (var11 == null) {
  1428.                      this.error("unmatched.endtag", var7.getName());
  1429.                      return;
  1430.                   } else {
  1431.                      String var6 = var7.getName();
  1432.                      if (this.stack == var11 || !var6.equals("font") && !var6.equals("center")) {
  1433.                         while(this.stack != var11) {
  1434.                            this.endTag(true);
  1435.                         }
  1436.  
  1437.                         this.endTag(false);
  1438.                         return;
  1439.                      }
  1440.  
  1441.                      if (var6.equals("center")) {
  1442.                         while(this.stack.elem.omitEnd() && this.stack != var11) {
  1443.                            this.endTag(true);
  1444.                         }
  1445.  
  1446.                         if (this.stack.elem == var7) {
  1447.                            this.endTag(false);
  1448.                         }
  1449.                      }
  1450.  
  1451.                      return;
  1452.                   }
  1453.                }
  1454.             }
  1455.          default:
  1456.             Element var8;
  1457.             if (!this.parseIdentifier(true)) {
  1458.                var8 = this.recent;
  1459.                if (this.field_0 != 62 || var8 == null) {
  1460.                   this.error("expected.tagname");
  1461.                   return;
  1462.                }
  1463.             } else {
  1464.                String var15 = this.getString(0);
  1465.                if (var15.equals("image")) {
  1466.                   var15 = new String("img");
  1467.                }
  1468.  
  1469.                if (!this.dtd.elementExists(var15)) {
  1470.                   this.error("tag.unrecognized ", var15);
  1471.                   var8 = this.dtd.getElement("unknown");
  1472.                   var8.name = var15;
  1473.                   var4 = true;
  1474.                } else {
  1475.                   var8 = this.dtd.getElement(var15);
  1476.                }
  1477.             }
  1478.  
  1479.             this.parseAttributeSpecificationList(var8);
  1480.             switch (this.field_0) {
  1481.                case 47:
  1482.                   var2 = true;
  1483.                case 62:
  1484.                   this.field_0 = this.readCh();
  1485.                case 60:
  1486.                   break;
  1487.                default:
  1488.                   this.error("expected", "'>'");
  1489.             }
  1490.  
  1491.             if (!this.strict && var8.getName().equals("script")) {
  1492.                this.error("javascript.unsupported");
  1493.             }
  1494.  
  1495.             if (!var8.isEmpty()) {
  1496.                if (this.field_0 == 10) {
  1497.                   ++this.field_1;
  1498.                   ++this.lfCount;
  1499.                   this.field_0 = this.readCh();
  1500.                } else if (this.field_0 == 13) {
  1501.                   ++this.field_1;
  1502.                   if ((this.field_0 = this.readCh()) == 10) {
  1503.                      this.field_0 = this.readCh();
  1504.                      ++this.crlfCount;
  1505.                   } else {
  1506.                      ++this.crCount;
  1507.                   }
  1508.                }
  1509.             }
  1510.  
  1511.             TagElement var16 = this.makeTag(var8, false);
  1512.             if (!this.strict && var8.getName().equals("form")) {
  1513.                if (this.lastFormSent == null) {
  1514.                   this.lastFormSent = var16;
  1515.                } else {
  1516.                   this.handleEndTag(this.lastFormSent);
  1517.                   this.lastFormSent = var16;
  1518.                }
  1519.             } else if (!var4) {
  1520.                this.legalTagContext(var16);
  1521.                if (!this.strict && this.skipTag) {
  1522.                   this.skipTag = false;
  1523.                   return;
  1524.                }
  1525.             }
  1526.  
  1527.             this.startTag(var16);
  1528.             if (!var8.isEmpty()) {
  1529.                switch (var8.getType()) {
  1530.                   case 1:
  1531.                      this.parseLiteral(false);
  1532.                      break;
  1533.                   case 16:
  1534.                      this.parseLiteral(true);
  1535.                      break;
  1536.                   default:
  1537.                      if (this.stack != null) {
  1538.                         this.stack.net = var2;
  1539.                      }
  1540.                }
  1541.             }
  1542.  
  1543.       }
  1544.    }
  1545.  
  1546.    private final int readCh() throws IOException {
  1547.       if (this.pos >= this.len) {
  1548.          try {
  1549.             this.len = this.field_2.read(this.buf);
  1550.          } catch (InterruptedIOException var2) {
  1551.             throw var2;
  1552.          }
  1553.  
  1554.          if (this.len <= 0) {
  1555.             return -1;
  1556.          }
  1557.  
  1558.          this.pos = 0;
  1559.       }
  1560.  
  1561.       ++this.currentPosition;
  1562.       return this.buf[this.pos++];
  1563.    }
  1564.  
  1565.    void resetStrBuffer() {
  1566.       this.strpos = 0;
  1567.    }
  1568.  
  1569.    void skipSpace() throws IOException {
  1570.       while(true) {
  1571.          switch (this.field_0) {
  1572.             case 9:
  1573.             case 32:
  1574.                this.field_0 = this.readCh();
  1575.                break;
  1576.             case 10:
  1577.                ++this.field_1;
  1578.                this.field_0 = this.readCh();
  1579.                ++this.lfCount;
  1580.                break;
  1581.             case 13:
  1582.                ++this.field_1;
  1583.                if ((this.field_0 = this.readCh()) == 10) {
  1584.                   this.field_0 = this.readCh();
  1585.                   ++this.crlfCount;
  1586.                   break;
  1587.                }
  1588.  
  1589.                ++this.crCount;
  1590.                break;
  1591.             default:
  1592.                return;
  1593.          }
  1594.       }
  1595.    }
  1596.  
  1597.    protected void startTag(TagElement var1) throws ChangedCharSetException {
  1598.       Element var2 = var1.getElement();
  1599.       if (var2.isEmpty() && this.textpos == 0) {
  1600.          this.last = var1;
  1601.       } else {
  1602.          this.handleText(var1);
  1603.       }
  1604.  
  1605.       for(AttributeList var3 = var2.atts; var3 != null; var3 = var3.next) {
  1606.          if (var3.modifier == 2 && (this.attributes.isEmpty() || !this.attributes.isDefined(var3.name))) {
  1607.             this.error("req.att ", var3.getName(), var2.getName());
  1608.          }
  1609.       }
  1610.  
  1611.       if (var2.isEmpty()) {
  1612.          this.handleEmptyTag(var1);
  1613.       } else if (var2.getName().equals("form")) {
  1614.          this.handleStartTag(var1);
  1615.       } else {
  1616.          this.recent = var2;
  1617.          this.stack = new TagStack(var1, this.stack);
  1618.          this.handleStartTag(var1);
  1619.       }
  1620.  
  1621.    }
  1622.  
  1623.    int strIndexOf(char var1) {
  1624.       for(int var2 = 0; var2 < this.strpos; ++var2) {
  1625.          if (this.str[var2] == var1) {
  1626.             return var2;
  1627.          }
  1628.       }
  1629.  
  1630.       return -1;
  1631.    }
  1632. }
  1633.