156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson/* 256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Copyright (C) 2010 Google Inc. 356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Licensed under the Apache License, Version 2.0 (the "License"); 556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * you may not use this file except in compliance with the License. 656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * You may obtain a copy of the License at 756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * http://www.apache.org/licenses/LICENSE-2.0 956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 1056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Unless required by applicable law or agreed to in writing, software 1156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * distributed under the License is distributed on an "AS IS" BASIS, 1256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * See the License for the specific language governing permissions and 1456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * limitations under the License. 1556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 1656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 1756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonpackage com.google.streamhtmlparser.impl; 1856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 1956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonimport com.google.common.base.Preconditions; 2056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 2156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonimport java.util.concurrent.atomic.AtomicInteger; 2256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 2356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson/** 2456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * A very simple representation of the parser internal state. The state 2556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * contains a small integer identifier (from 1 to 255) to allow for 2656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * the implementation of a simple finite state machine. The name is 2756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * purely informational. 2856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 2956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * <p>In order to eliminate the possibility that different states have 3056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * the same identifier, this class manages the idenitifiers themselves. 3156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * The HTML and Javascript parser states are managed elsewhere in different 3256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * "namespaces" hence will not clash and there is no current need for this 3356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * class to disambiguate them further. 3456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 3556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * <p>The methods to create new <code>InternalState</code> instances are 3656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * package-scope only as they are only needed by <code>HtmlParserImpl</code> 3756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * and <code>JavascriptParserImpl</code>. 3856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 3956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonclass InternalState { 4056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 4156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // An InternalState to represent an error condition for all parsers. 4256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson static final InternalState INTERNAL_ERROR_STATE = new InternalState(); 4356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 4456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson // MAX_ID and FIRST_ID are only used for asserts against developer error. 4556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private static final int MAX_ID = 255; 4656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private static final int FIRST_ID = 1; 4756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 4856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private static AtomicInteger htmlStates = new AtomicInteger(FIRST_ID); 4956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private static AtomicInteger javascriptStates = new AtomicInteger(FIRST_ID); 5056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private final String name; 5156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private final int id; 5256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 5356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson /** 5456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * @param name the {@code String} identifier for this state 5556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * @param id the integer identiifer for this state, guaranteed to be unique 5656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 5756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private InternalState(String name, int id) { 5856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson Preconditions.checkNotNull(name); 5956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson Preconditions.checkArgument(id >= FIRST_ID); 6056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson Preconditions.checkArgument(id <= MAX_ID); 6156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson this.name = name; 6256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson this.id = id; 6356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 6456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 6556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson /** 6656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Used only for the error state. Bypasses assert checks. 6756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 6856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson private InternalState() { 6956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson name = "InternalStateError"; 7056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson id = 0; 7156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 7256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 7356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson /** 7456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * @return {@code String} name of that state. 7556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 7656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public String getName() { 7756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return name; 7856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 7956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 8056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson /** 8156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * @return {@code int} id of that state. 8256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 8356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public int getId() { 8456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return id; 8556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 8656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 8756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson /** 8856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * @return {@code String} representation of that object, the format 8956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * may change. 9056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 9156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson @Override 9256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson public String toString() { 9356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return String.format("InternalState: Name: %s; Id: %d", name, id); 9456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 9556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 9656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson /** 9756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Obtain a new {@code InternalState} instance for the HTML parser. 9856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 9956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * @param name a unique identifier for this state useful during debugging 10056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * @return a new {@code InternalState} object 10156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 10256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson static InternalState getInstanceHtml(String name) { 10356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson int htmlStateId = htmlStates.getAndIncrement(); 10456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return new InternalState(name, htmlStateId); 10556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 10656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson 10756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson /** 10856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Obtain a new <code>InternalState</code> instance for the Javascript parser. 10956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * 11056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * @param name A unique identifier for this state useful during debugging 11156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * @return a new {@code InternalState} object 11256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */ 11356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson static InternalState getInstanceJavascript(String name) { 11456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson int javascriptStateId = javascriptStates.getAndIncrement(); 11556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson return new InternalState(name, javascriptStateId); 11656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson } 11756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson} 118