home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 139 / dpcs0999.iso / Web / CFserver / data1.cab / Java / CFJava.cab / CFJavaRuntime.cab / netscape / application / HTMLTokenGenerator.class (.txt) < prev    next >
Encoding:
Java Class File  |  1998-10-01  |  6.3 KB  |  407 lines

  1. package netscape.application;
  2.  
  3. import java.io.FilterInputStream;
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6.  
  7. class HTMLTokenGenerator extends FilterInputStream {
  8.    public static final byte NULL_TOKEN = 0;
  9.    public static final byte STRING_TOKEN = 1;
  10.    public static final byte MARKER_BEGIN_TOKEN = 2;
  11.    public static final byte MARKER_END_TOKEN = 3;
  12.    public static final byte COMMENT_TOKEN = 4;
  13.    static final byte LAST_TOKEN_TYPE = 4;
  14.    static final int CHARACTER_COUNT_PER_ARRAY = 128;
  15.    static final int CCPA_BIT_COUNT = 7;
  16.    static final int CCPA_MASK = 127;
  17.    static final int PARSING_NONE_STATE = 0;
  18.    static final int PARSING_STRING_STATE = 1;
  19.    static final int PARSING_MARKER_STATE = 2;
  20.    static final int PARSING_COMMENT_STATE = 3;
  21.    static final int PARSING_MARKER_OR_COMMENT_STATE = 4;
  22.    static final int PARSING_END_COMMENT_ONE_STATE = 5;
  23.    static final int PARSING_END_COMMENT_TWO_STATE = 6;
  24.    private byte[][] input = new byte[1][];
  25.    private int nextAvailableByteIndex;
  26.    private int markedByteIndex;
  27.    private int nextFreeByteSlotIndex;
  28.    private int currentLineNumber;
  29.    private int parserState;
  30.    private int currentToken;
  31.    private String currentTokenString;
  32.    private String currentTokenAttributes;
  33.  
  34.    public HTMLTokenGenerator(InputStream var1) {
  35.       super(var1);
  36.       this.input[0] = new byte[128];
  37.       this.nextAvailableByteIndex = 0;
  38.       this.nextFreeByteSlotIndex = 0;
  39.       this.currentLineNumber = 0;
  40.       this.parserState = 0;
  41.    }
  42.  
  43.    private final void markCurrentCharacter() {
  44.       this.markedByteIndex = this.nextAvailableByteIndex;
  45.    }
  46.  
  47.    private final void markPreviousCharacter() {
  48.       this.markedByteIndex = this.nextAvailableByteIndex - 1;
  49.    }
  50.  
  51.    private final void growInputBuffer() {
  52.       byte[][] var1 = new byte[this.input.length + 1][];
  53.       System.arraycopy(this.input, 0, var1, 0, this.input.length);
  54.       var1[this.input.length] = new byte[128];
  55.       this.input = var1;
  56.    }
  57.  
  58.    private final void readMoreCharacters() throws IOException {
  59.       int var2 = this.nextFreeByteSlotIndex >> 7;
  60.       if (var2 >= this.input.length) {
  61.          this.growInputBuffer();
  62.       }
  63.  
  64.       int var1 = ((FilterInputStream)this).read(this.input[var2], this.nextFreeByteSlotIndex & 127, 128 - (this.nextFreeByteSlotIndex & 127));
  65.       if (var1 != -1) {
  66.          this.nextFreeByteSlotIndex += var1;
  67.          if (var1 < 128) {
  68.             var2 = this.nextFreeByteSlotIndex >> 7;
  69.             if (var2 >= this.input.length) {
  70.                this.growInputBuffer();
  71.             }
  72.  
  73.             var1 = ((FilterInputStream)this).read(this.input[var2], this.nextFreeByteSlotIndex & 127, 128 - (this.nextFreeByteSlotIndex & 127));
  74.             if (var1 != -1) {
  75.                this.nextFreeByteSlotIndex += var1;
  76.             }
  77.          }
  78.  
  79.       }
  80.    }
  81.  
  82.    private final boolean hasMoreCharacters() throws IOException {
  83.       if (this.nextAvailableByteIndex < this.nextFreeByteSlotIndex) {
  84.          return true;
  85.       } else {
  86.          this.readMoreCharacters();
  87.          return this.nextAvailableByteIndex < this.nextFreeByteSlotIndex;
  88.       }
  89.    }
  90.  
  91.    private final byte peekNextCharacter() throws IOException {
  92.       byte var1 = 0;
  93.       if (this.nextAvailableByteIndex >= this.nextFreeByteSlotIndex) {
  94.          this.readMoreCharacters();
  95.       }
  96.  
  97.       if (this.nextAvailableByteIndex < this.nextFreeByteSlotIndex) {
  98.          var1 = this.input[this.nextAvailableByteIndex >> 7][this.nextAvailableByteIndex & 127];
  99.          ++this.nextAvailableByteIndex;
  100.       }
  101.  
  102.       return var1;
  103.    }
  104.  
  105.    private final void rewindToMarkedCharacter() {
  106.       this.nextAvailableByteIndex = this.markedByteIndex;
  107.    }
  108.  
  109.    private final void deletePeekedCharacters() {
  110.       for(this.markedByteIndex = -1; this.nextAvailableByteIndex >> 7 > 0; this.nextFreeByteSlotIndex -= 128) {
  111.          byte[] var1 = this.input[0];
  112.          int var2 = 0;
  113.  
  114.          for(int var3 = this.input.length - 1; var2 < var3; ++var2) {
  115.             this.input[var2] = this.input[var2 + 1];
  116.          }
  117.  
  118.          this.input[this.input.length - 1] = var1;
  119.          this.nextAvailableByteIndex -= 128;
  120.       }
  121.  
  122.    }
  123.  
  124.    private final void deletePeekedCharactersMinusOne() {
  125.       for(this.markedByteIndex = -1; this.nextAvailableByteIndex - 1 >> 7 > 0; this.nextFreeByteSlotIndex -= 128) {
  126.          byte[] var1 = this.input[0];
  127.          int var2 = 0;
  128.  
  129.          for(int var3 = this.input.length - 1; var2 < var3; ++var2) {
  130.             this.input[var2] = this.input[var2 + 1];
  131.          }
  132.  
  133.          this.input[this.input.length - 1] = var1;
  134.          this.nextAvailableByteIndex -= 128;
  135.       }
  136.  
  137.    }
  138.  
  139.    private final byte[] getAndDeletePeekedCharacters() {
  140.       int var1 = this.nextAvailableByteIndex - this.markedByteIndex;
  141.       byte[] var2 = new byte[var1];
  142.       int var3 = this.markedByteIndex;
  143.  
  144.       for(int var4 = this.markedByteIndex + var1; var3 < var4; ++var3) {
  145.          var2[var3 - this.markedByteIndex] = this.input[var3 >> 7][var3 & 127];
  146.       }
  147.  
  148.       this.deletePeekedCharacters();
  149.       this.markedByteIndex = -1;
  150.       return var2;
  151.    }
  152.  
  153.    private final byte[] getAndDeletePeekedCharactersMinusOne() {
  154.       int var1 = this.nextAvailableByteIndex - this.markedByteIndex - 1;
  155.       byte[] var2 = new byte[var1];
  156.       int var3 = this.markedByteIndex;
  157.  
  158.       for(int var4 = this.markedByteIndex + var1; var3 < var4; ++var3) {
  159.          var2[var3 - this.markedByteIndex] = this.input[var3 >> 7][var3 & 127];
  160.       }
  161.  
  162.       this.deletePeekedCharactersMinusOne();
  163.       this.markedByteIndex = -1;
  164.       return var2;
  165.    }
  166.  
  167.    private final boolean isSpaceOrCR(byte var1) {
  168.       return var1 == 32 || var1 == 9 || var1 == 10 || var1 == 13;
  169.    }
  170.  
  171.    private String attributes(byte[] var1) throws HTMLParsingException {
  172.       if (var1.length == 0 || var1[0] != 60 || var1[var1.length - 1] != 62) {
  173.          this.syntaxError("Malformed marker");
  174.       }
  175.  
  176.       int var2 = 1;
  177.  
  178.       int var3;
  179.       for(var3 = var1.length; var2 < var3 && this.isSpaceOrCR(var1[var2]); ++var2) {
  180.       }
  181.  
  182.       while(var2 < var3 && !this.isSpaceOrCR(var1[var2])) {
  183.          ++var2;
  184.       }
  185.  
  186.       while(var2 < var3 && this.isSpaceOrCR(var1[var2])) {
  187.          ++var2;
  188.       }
  189.  
  190.       return var3 - 1 - var2 > 0 ? new String(var1, 0, var2, var3 - 1 - var2) : "";
  191.    }
  192.  
  193.    private String marker(byte[] var1) throws HTMLParsingException {
  194.       if (var1.length == 0 || var1[0] != 60 || var1[var1.length - 1] != 62) {
  195.          this.syntaxError("Malformed marker");
  196.       }
  197.  
  198.       int var2 = 1;
  199.       int var4 = 1;
  200.  
  201.       int var3;
  202.       for(var3 = var1.length; var2 < var3 && this.isSpaceOrCR(var1[var2]); ++var4) {
  203.          ++var2;
  204.       }
  205.  
  206.       if (var1[var2] == 47) {
  207.          ++var2;
  208.          ++var4;
  209.       }
  210.  
  211.       while(var2 < var3 - 1 && !this.isSpaceOrCR(var1[var2])) {
  212.          ++var2;
  213.       }
  214.  
  215.       return (new String(var1, 0, var4, var2 - var4)).toUpperCase();
  216.    }
  217.  
  218.    private boolean isMarkerBegin(byte[] var1) throws HTMLParsingException {
  219.       if (var1.length == 0 || var1[0] != 60 || var1[var1.length - 1] != 62) {
  220.          this.syntaxError("Malformed marker");
  221.       }
  222.  
  223.       int var2 = 1;
  224.  
  225.       for(int var3 = var1.length; var2 < var3 && this.isSpaceOrCR(var1[var2]); ++var2) {
  226.       }
  227.  
  228.       return var1[var2] != 47;
  229.    }
  230.  
  231.    private final void parseOneToken() throws HTMLParsingException, IOException {
  232.       while(true) {
  233.          if (this.currentToken == 0) {
  234.             if (this.hasMoreCharacters()) {
  235.                byte var1 = this.peekNextCharacter();
  236.                if (var1 == 10) {
  237.                   ++this.currentLineNumber;
  238.                }
  239.  
  240.                switch (this.parserState) {
  241.                   case 0:
  242.                      if (var1 == 60) {
  243.                         this.parserState = 4;
  244.                      } else {
  245.                         this.parserState = 1;
  246.                      }
  247.  
  248.                      this.markPreviousCharacter();
  249.                      continue;
  250.                   case 1:
  251.                      if (var1 == 60) {
  252.                         this.currentToken = 1;
  253.                         this.currentTokenAttributes = null;
  254.                         this.currentTokenString = new String(this.getAndDeletePeekedCharactersMinusOne(), 0);
  255.                         this.markPreviousCharacter();
  256.                         this.parserState = 4;
  257.                      }
  258.                      continue;
  259.                   case 2:
  260.                      if (var1 != 62) {
  261.                         continue;
  262.                      }
  263.  
  264.                      byte[] var2 = this.getAndDeletePeekedCharacters();
  265.                      if (this.isMarkerBegin(var2)) {
  266.                         this.currentToken = 2;
  267.                      } else {
  268.                         this.currentToken = 3;
  269.                      }
  270.  
  271.                      this.currentTokenAttributes = this.attributes(var2);
  272.                      this.currentTokenString = this.marker(var2);
  273.                      this.parserState = 0;
  274.                      continue;
  275.                   case 3:
  276.                      if (var1 == 45) {
  277.                         this.parserState = 5;
  278.                         continue;
  279.                      }
  280.  
  281.                      if (var1 == 62) {
  282.                         this.currentToken = 4;
  283.                         this.currentTokenString = new String(this.getAndDeletePeekedCharacters(), 0);
  284.                         this.currentTokenAttributes = null;
  285.                         this.parserState = 0;
  286.                      }
  287.                      continue;
  288.                   case 4:
  289.                      if (var1 == 33) {
  290.                         this.parserState = 3;
  291.                         continue;
  292.                      }
  293.  
  294.                      this.parserState = 2;
  295.                      continue;
  296.                   case 5:
  297.                      if (var1 == 45) {
  298.                         this.parserState = 6;
  299.                         continue;
  300.                      }
  301.  
  302.                      if (var1 == 62) {
  303.                         this.currentToken = 4;
  304.                         this.currentTokenString = new String(this.getAndDeletePeekedCharacters(), 0);
  305.                         this.currentTokenAttributes = null;
  306.                         this.parserState = 0;
  307.                         continue;
  308.                      }
  309.  
  310.                      this.parserState = 3;
  311.                      continue;
  312.                   case 6:
  313.                      if (var1 != 10 && var1 != 13) {
  314.                         if (var1 == 62) {
  315.                            this.currentToken = 4;
  316.                            this.currentTokenString = new String(this.getAndDeletePeekedCharacters(), 0);
  317.                            this.currentTokenAttributes = null;
  318.                            this.parserState = 0;
  319.                         } else {
  320.                            this.parserState = 3;
  321.                         }
  322.                      }
  323.                   default:
  324.                      continue;
  325.                }
  326.             }
  327.  
  328.             if (this.parserState != 1 && this.markedByteIndex != -1) {
  329.                this.rewindToMarkedCharacter();
  330.             }
  331.          }
  332.  
  333.          if (this.currentToken == 0 && !this.hasMoreCharacters()) {
  334.             switch (this.parserState) {
  335.                case 0:
  336.                   break;
  337.                case 1:
  338.                   this.currentToken = 1;
  339.                   this.currentTokenString = new String(this.getAndDeletePeekedCharacters(), 0);
  340.                   this.currentTokenAttributes = null;
  341.                   this.parserState = 0;
  342.                   return;
  343.                case 2:
  344.                case 4:
  345.                   this.parserState = 0;
  346.                   this.syntaxError("Unterminated marker");
  347.                   return;
  348.                case 3:
  349.                default:
  350.                   this.parserState = 0;
  351.                   this.syntaxError("Unterminated comment. Comment should end with -->");
  352.                   return;
  353.             }
  354.          }
  355.  
  356.          return;
  357.       }
  358.    }
  359.  
  360.    public final boolean hasMoreTokens() throws HTMLParsingException, IOException {
  361.       if (this.currentToken != 0) {
  362.          return true;
  363.       } else {
  364.          this.parseOneToken();
  365.          return this.currentToken != 0;
  366.       }
  367.    }
  368.  
  369.    public final int nextToken() throws HTMLParsingException, IOException {
  370.       int var1 = 0;
  371.       if (this.currentToken == 0) {
  372.          this.parseOneToken();
  373.       }
  374.  
  375.       if (this.currentToken != 0) {
  376.          var1 = this.currentToken;
  377.          this.currentToken = 0;
  378.       }
  379.  
  380.       return var1;
  381.    }
  382.  
  383.    final int peekNextToken() throws HTMLParsingException, IOException {
  384.       if (this.currentToken == 0) {
  385.          this.parseOneToken();
  386.       }
  387.  
  388.       return this.currentToken;
  389.    }
  390.  
  391.    public final String stringForLastToken() {
  392.       return this.currentTokenString;
  393.    }
  394.  
  395.    public final String attributesForLastToken() {
  396.       return this.currentTokenAttributes;
  397.    }
  398.  
  399.    final int lineForLastToken() {
  400.       return this.currentLineNumber + 1;
  401.    }
  402.  
  403.    final void syntaxError(String var1) throws HTMLParsingException {
  404.       throw new HTMLParsingException(var1, this.lineForLastToken());
  405.    }
  406. }
  407.