mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-01 06:35:42 +00:00
Include the .java sources for translated files in the HTML5 parser
This commit is contained in:
parent
1bea387bfb
commit
fb8e881c05
2793
content/html/parser/javasrc/AttributeName.java
Normal file
2793
content/html/parser/javasrc/AttributeName.java
Normal file
File diff suppressed because it is too large
Load Diff
1513
content/html/parser/javasrc/ElementName.java
Normal file
1513
content/html/parser/javasrc/ElementName.java
Normal file
File diff suppressed because it is too large
Load Diff
484
content/html/parser/javasrc/HtmlAttributes.java
Normal file
484
content/html/parser/javasrc/HtmlAttributes.java
Normal file
@ -0,0 +1,484 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Henri Sivonen
|
||||
* Copyright (c) 2008-2009 Mozilla Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package nu.validator.htmlparser.impl;
|
||||
|
||||
import nu.validator.htmlparser.annotation.IdType;
|
||||
import nu.validator.htmlparser.annotation.Local;
|
||||
import nu.validator.htmlparser.annotation.NsUri;
|
||||
import nu.validator.htmlparser.annotation.Prefix;
|
||||
import nu.validator.htmlparser.annotation.QName;
|
||||
import nu.validator.htmlparser.common.XmlViolationPolicy;
|
||||
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* Be careful with this class. QName is the name in from HTML tokenization.
|
||||
* Otherwise, please refer to the interface doc.
|
||||
*
|
||||
* @version $Id: AttributesImpl.java 206 2008-03-20 14:09:29Z hsivonen $
|
||||
* @author hsivonen
|
||||
*/
|
||||
public final class HtmlAttributes implements Attributes {
|
||||
|
||||
// [NOCPP[
|
||||
|
||||
private static final AttributeName[] EMPTY_ATTRIBUTENAMES = new AttributeName[0];
|
||||
|
||||
private static final String[] EMPTY_STRINGS = new String[0];
|
||||
|
||||
// ]NOCPP]
|
||||
|
||||
public static final HtmlAttributes EMPTY_ATTRIBUTES = new HtmlAttributes(
|
||||
AttributeName.HTML);
|
||||
|
||||
private int mode;
|
||||
|
||||
private int length;
|
||||
|
||||
private AttributeName[] names;
|
||||
|
||||
private String[] values; // XXX perhaps make this @NoLength?
|
||||
|
||||
// [NOCPP[
|
||||
|
||||
private String idValue;
|
||||
|
||||
private int xmlnsLength;
|
||||
|
||||
private AttributeName[] xmlnsNames;
|
||||
|
||||
private String[] xmlnsValues;
|
||||
|
||||
// ]NOCPP]
|
||||
|
||||
public HtmlAttributes(int mode) {
|
||||
this.mode = mode;
|
||||
this.length = 0;
|
||||
this.names = new AttributeName[5]; // covers 98.3% of elements
|
||||
// according to
|
||||
// Hixie
|
||||
this.values = new String[5];
|
||||
|
||||
// [NOCPP[
|
||||
|
||||
this.idValue = null;
|
||||
|
||||
this.xmlnsLength = 0;
|
||||
|
||||
this.xmlnsNames = HtmlAttributes.EMPTY_ATTRIBUTENAMES;
|
||||
|
||||
this.xmlnsValues = HtmlAttributes.EMPTY_STRINGS;
|
||||
|
||||
// ]NOCPP]
|
||||
}
|
||||
/*
|
||||
public HtmlAttributes(HtmlAttributes other) {
|
||||
this.mode = other.mode;
|
||||
this.length = other.length;
|
||||
this.names = new AttributeName[other.length];
|
||||
this.values = new String[other.length];
|
||||
// [NOCPP[
|
||||
this.idValue = other.idValue;
|
||||
this.xmlnsLength = other.xmlnsLength;
|
||||
this.xmlnsNames = new AttributeName[other.xmlnsLength];
|
||||
this.xmlnsValues = new String[other.xmlnsLength];
|
||||
// ]NOCPP]
|
||||
}
|
||||
*/
|
||||
|
||||
void destructor() {
|
||||
clear(0);
|
||||
Portability.releaseArray(names);
|
||||
Portability.releaseArray(values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Only use with a static argument
|
||||
*
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
public int getIndex(AttributeName name) {
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (names[i] == name) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// [NOCPP[
|
||||
|
||||
public int getIndex(String qName) {
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (names[i].getQName(mode).equals(qName)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int getIndex(String uri, String localName) {
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (names[i].getLocal(mode).equals(localName)
|
||||
&& names[i].getUri(mode).equals(uri)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public @IdType String getType(String qName) {
|
||||
int index = getIndex(qName);
|
||||
if (index == -1) {
|
||||
return null;
|
||||
} else {
|
||||
return getType(index);
|
||||
}
|
||||
}
|
||||
|
||||
public @IdType String getType(String uri, String localName) {
|
||||
int index = getIndex(uri, localName);
|
||||
if (index == -1) {
|
||||
return null;
|
||||
} else {
|
||||
return getType(index);
|
||||
}
|
||||
}
|
||||
|
||||
public String getValue(String qName) {
|
||||
int index = getIndex(qName);
|
||||
if (index == -1) {
|
||||
return null;
|
||||
} else {
|
||||
return getValue(index);
|
||||
}
|
||||
}
|
||||
|
||||
public String getValue(String uri, String localName) {
|
||||
int index = getIndex(uri, localName);
|
||||
if (index == -1) {
|
||||
return null;
|
||||
} else {
|
||||
return getValue(index);
|
||||
}
|
||||
}
|
||||
|
||||
// ]NOCPP]
|
||||
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public @Local String getLocalName(int index) {
|
||||
if (index < length && index >= 0) {
|
||||
return names[index].getLocal(mode);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// [NOCPP[
|
||||
|
||||
public @QName String getQName(int index) {
|
||||
if (index < length && index >= 0) {
|
||||
return names[index].getQName(mode);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public @IdType String getType(int index) {
|
||||
if (index < length && index >= 0) {
|
||||
return names[index].getType(mode);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// ]NOCPP]
|
||||
|
||||
public AttributeName getAttributeName(int index) {
|
||||
if (index < length && index >= 0) {
|
||||
return names[index];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public @NsUri String getURI(int index) {
|
||||
if (index < length && index >= 0) {
|
||||
return names[index].getUri(mode);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public @Prefix String getPrefix(int index) {
|
||||
if (index < length && index >= 0) {
|
||||
return names[index].getPrefix(mode);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getValue(int index) {
|
||||
if (index < length && index >= 0) {
|
||||
return values[index];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Only use with static argument.
|
||||
*
|
||||
* @see org.xml.sax.Attributes#getValue(java.lang.String)
|
||||
*/
|
||||
public String getValue(AttributeName name) {
|
||||
int index = getIndex(name);
|
||||
if (index == -1) {
|
||||
return null;
|
||||
} else {
|
||||
return getValue(index);
|
||||
}
|
||||
}
|
||||
|
||||
// [NOCPP[
|
||||
|
||||
public String getId() {
|
||||
return idValue;
|
||||
}
|
||||
|
||||
public int getXmlnsLength() {
|
||||
return xmlnsLength;
|
||||
}
|
||||
|
||||
public @Local String getXmlnsLocalName(int index) {
|
||||
if (index < xmlnsLength && index >= 0) {
|
||||
return xmlnsNames[index].getLocal(mode);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public @NsUri String getXmlnsURI(int index) {
|
||||
if (index < xmlnsLength && index >= 0) {
|
||||
return xmlnsNames[index].getUri(mode);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getXmlnsValue(int index) {
|
||||
if (index < xmlnsLength && index >= 0) {
|
||||
return xmlnsValues[index];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public int getXmlnsIndex(AttributeName name) {
|
||||
for (int i = 0; i < xmlnsLength; i++) {
|
||||
if (xmlnsNames[i] == name) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public String getXmlnsValue(AttributeName name) {
|
||||
int index = getXmlnsIndex(name);
|
||||
if (index == -1) {
|
||||
return null;
|
||||
} else {
|
||||
return getXmlnsValue(index);
|
||||
}
|
||||
}
|
||||
|
||||
public AttributeName getXmlnsAttributeName(int index) {
|
||||
if (index < xmlnsLength && index >= 0) {
|
||||
return xmlnsNames[index];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// ]NOCPP]
|
||||
|
||||
void addAttribute(AttributeName name, String value
|
||||
// [NOCPP[
|
||||
, XmlViolationPolicy xmlnsPolicy
|
||||
// ]NOCPP]
|
||||
) throws SAXException {
|
||||
// [NOCPP[
|
||||
if (name == AttributeName.ID) {
|
||||
idValue = value;
|
||||
}
|
||||
|
||||
if (name.isXmlns()) {
|
||||
if (xmlnsNames.length == xmlnsLength) {
|
||||
int newLen = xmlnsLength == 0 ? 2 : xmlnsLength << 1;
|
||||
AttributeName[] newNames = new AttributeName[newLen];
|
||||
System.arraycopy(xmlnsNames, 0, newNames, 0, xmlnsNames.length);
|
||||
xmlnsNames = newNames;
|
||||
String[] newValues = new String[newLen];
|
||||
System.arraycopy(xmlnsValues, 0, newValues, 0, xmlnsValues.length);
|
||||
xmlnsValues = newValues;
|
||||
}
|
||||
xmlnsNames[xmlnsLength] = name;
|
||||
xmlnsValues[xmlnsLength] = value;
|
||||
xmlnsLength++;
|
||||
switch (xmlnsPolicy) {
|
||||
case FATAL:
|
||||
// this is ugly
|
||||
throw new SAXException("Saw an xmlns attribute.");
|
||||
case ALTER_INFOSET:
|
||||
return;
|
||||
case ALLOW:
|
||||
// fall through
|
||||
}
|
||||
}
|
||||
|
||||
// ]NOCPP]
|
||||
|
||||
if (names.length == length) {
|
||||
int newLen = length << 1; // The first growth covers virtually
|
||||
// 100% of elements according to
|
||||
// Hixie
|
||||
AttributeName[] newNames = new AttributeName[newLen];
|
||||
System.arraycopy(names, 0, newNames, 0, names.length);
|
||||
Portability.releaseArray(names);
|
||||
names = newNames;
|
||||
String[] newValues = new String[newLen];
|
||||
System.arraycopy(values, 0, newValues, 0, values.length);
|
||||
Portability.releaseArray(values);
|
||||
values = newValues;
|
||||
}
|
||||
names[length] = name;
|
||||
values[length] = value;
|
||||
length++;
|
||||
}
|
||||
|
||||
void clear(int m) {
|
||||
for (int i = 0; i < length; i++) {
|
||||
names[i].release();
|
||||
names[i] = null;
|
||||
Portability.releaseString(values[i]);
|
||||
values[i] = null;
|
||||
}
|
||||
length = 0;
|
||||
mode = m;
|
||||
// [NOCPP[
|
||||
idValue = null;
|
||||
for (int i = 0; i < xmlnsLength; i++) {
|
||||
xmlnsNames[i] = null;
|
||||
xmlnsValues[i] = null;
|
||||
}
|
||||
xmlnsLength = 0;
|
||||
// ]NOCPP]
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used in C++ to release special <code>isindex</code>
|
||||
* attribute values whose ownership is not transferred.
|
||||
*/
|
||||
void releaseValue(int i) {
|
||||
Portability.releaseString(values[i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is only used for <code>AttributeName</code> ownership transfer
|
||||
* in the isindex case to avoid freeing custom names twice in C++.
|
||||
*/
|
||||
void clearWithoutReleasingContents() {
|
||||
for (int i = 0; i < length; i++) {
|
||||
names[i] = null;
|
||||
values[i] = null;
|
||||
}
|
||||
length = 0;
|
||||
}
|
||||
|
||||
boolean contains(AttributeName name) {
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (name.equalsAnother(names[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// [NOCPP[
|
||||
for (int i = 0; i < xmlnsLength; i++) {
|
||||
if (name.equalsAnother(xmlnsNames[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// ]NOCPP]
|
||||
return false;
|
||||
}
|
||||
|
||||
public void adjustForMath() {
|
||||
mode = AttributeName.MATHML;
|
||||
}
|
||||
|
||||
public void adjustForSvg() {
|
||||
mode = AttributeName.SVG;
|
||||
}
|
||||
|
||||
// [NOCPP[
|
||||
|
||||
void processNonNcNames(TreeBuilder<?> treeBuilder, XmlViolationPolicy namePolicy) throws SAXException {
|
||||
for (int i = 0; i < length; i++) {
|
||||
AttributeName attName = names[i];
|
||||
if (!attName.isNcName(mode)) {
|
||||
String name = attName.getLocal(mode);
|
||||
switch (namePolicy) {
|
||||
case ALTER_INFOSET:
|
||||
names[i] = AttributeName.create(NCName.escapeName(name));
|
||||
// fall through
|
||||
case ALLOW:
|
||||
if (attName != AttributeName.XML_LANG) {
|
||||
treeBuilder.warn("Attribute \u201C" + name + "\u201D is not serializable as XML 1.0.");
|
||||
}
|
||||
break;
|
||||
case FATAL:
|
||||
treeBuilder.fatal("Attribute \u201C" + name + "\u201D is not serializable as XML 1.0.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void merge(HtmlAttributes attributes) throws SAXException {
|
||||
int len = attributes.getLength();
|
||||
for (int i = 0; i < len; i++) {
|
||||
AttributeName name = attributes.getAttributeName(i);
|
||||
if (!contains(name)) {
|
||||
addAttribute(name, attributes.getValue(i), XmlViolationPolicy.ALLOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ]NOCPP]
|
||||
|
||||
}
|
696
content/html/parser/javasrc/MetaScanner.java
Normal file
696
content/html/parser/javasrc/MetaScanner.java
Normal file
@ -0,0 +1,696 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Henri Sivonen
|
||||
* Copyright (c) 2008-2009 Mozilla Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package nu.validator.htmlparser.impl;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import nu.validator.htmlparser.annotation.NoLength;
|
||||
import nu.validator.htmlparser.common.ByteReadable;
|
||||
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
public abstract class MetaScanner {
|
||||
|
||||
private static final @NoLength char[] CHARSET = "charset".toCharArray();
|
||||
|
||||
private static final @NoLength char[] CONTENT = "content".toCharArray();
|
||||
|
||||
private static final int NO = 0;
|
||||
|
||||
private static final int M = 1;
|
||||
|
||||
private static final int E = 2;
|
||||
|
||||
private static final int T = 3;
|
||||
|
||||
private static final int A = 4;
|
||||
|
||||
private static final int DATA = 0;
|
||||
|
||||
private static final int TAG_OPEN = 1;
|
||||
|
||||
private static final int SCAN_UNTIL_GT = 2;
|
||||
|
||||
private static final int TAG_NAME = 3;
|
||||
|
||||
private static final int BEFORE_ATTRIBUTE_NAME = 4;
|
||||
|
||||
private static final int ATTRIBUTE_NAME = 5;
|
||||
|
||||
private static final int AFTER_ATTRIBUTE_NAME = 6;
|
||||
|
||||
private static final int BEFORE_ATTRIBUTE_VALUE = 7;
|
||||
|
||||
private static final int ATTRIBUTE_VALUE_DOUBLE_QUOTED = 8;
|
||||
|
||||
private static final int ATTRIBUTE_VALUE_SINGLE_QUOTED = 9;
|
||||
|
||||
private static final int ATTRIBUTE_VALUE_UNQUOTED = 10;
|
||||
|
||||
private static final int AFTER_ATTRIBUTE_VALUE_QUOTED = 11;
|
||||
|
||||
private static final int MARKUP_DECLARATION_OPEN = 13;
|
||||
|
||||
private static final int MARKUP_DECLARATION_HYPHEN = 14;
|
||||
|
||||
private static final int COMMENT_START = 15;
|
||||
|
||||
private static final int COMMENT_START_DASH = 16;
|
||||
|
||||
private static final int COMMENT = 17;
|
||||
|
||||
private static final int COMMENT_END_DASH = 18;
|
||||
|
||||
private static final int COMMENT_END = 19;
|
||||
|
||||
private static final int SELF_CLOSING_START_TAG = 20;
|
||||
|
||||
protected ByteReadable readable;
|
||||
|
||||
private int metaState = NO;
|
||||
|
||||
private int contentIndex = -1;
|
||||
|
||||
private int charsetIndex = -1;
|
||||
|
||||
protected int stateSave = DATA;
|
||||
|
||||
private int strBufLen;
|
||||
|
||||
private char[] strBuf;
|
||||
|
||||
// [NOCPP[
|
||||
|
||||
/**
|
||||
* @param source
|
||||
* @param errorHandler
|
||||
* @param publicId
|
||||
* @param systemId
|
||||
*/
|
||||
public MetaScanner() {
|
||||
this.readable = null;
|
||||
this.metaState = NO;
|
||||
this.contentIndex = -1;
|
||||
this.charsetIndex = -1;
|
||||
this.stateSave = DATA;
|
||||
strBufLen = 0;
|
||||
strBuf = new char[36];
|
||||
}
|
||||
|
||||
/**
|
||||
* -1 means end.
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
protected int read() throws IOException {
|
||||
return readable.readByte();
|
||||
}
|
||||
|
||||
// ]NOCPP]
|
||||
|
||||
// WARNING When editing this, makes sure the bytecode length shown by javap
|
||||
// stays under 8000 bytes!
|
||||
protected final void stateLoop(int state)
|
||||
throws SAXException, IOException {
|
||||
int c = -1;
|
||||
boolean reconsume = false;
|
||||
stateloop: for (;;) {
|
||||
switch (state) {
|
||||
case DATA:
|
||||
dataloop: for (;;) {
|
||||
if (reconsume) {
|
||||
reconsume = false;
|
||||
} else {
|
||||
c = read();
|
||||
}
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case '<':
|
||||
state = MetaScanner.TAG_OPEN;
|
||||
break dataloop; // FALL THROUGH continue
|
||||
// stateloop;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
|
||||
case TAG_OPEN:
|
||||
tagopenloop: for (;;) {
|
||||
c = read();
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case 'm':
|
||||
case 'M':
|
||||
metaState = M;
|
||||
state = MetaScanner.TAG_NAME;
|
||||
break tagopenloop;
|
||||
// continue stateloop;
|
||||
case '!':
|
||||
state = MetaScanner.MARKUP_DECLARATION_OPEN;
|
||||
continue stateloop;
|
||||
case '?':
|
||||
case '/':
|
||||
state = MetaScanner.SCAN_UNTIL_GT;
|
||||
continue stateloop;
|
||||
case '>':
|
||||
state = MetaScanner.DATA;
|
||||
continue stateloop;
|
||||
default:
|
||||
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
|
||||
metaState = NO;
|
||||
state = MetaScanner.TAG_NAME;
|
||||
break tagopenloop;
|
||||
// continue stateloop;
|
||||
}
|
||||
state = MetaScanner.DATA;
|
||||
reconsume = true;
|
||||
continue stateloop;
|
||||
}
|
||||
}
|
||||
// FALL THROUGH DON'T REORDER
|
||||
case TAG_NAME:
|
||||
tagnameloop: for (;;) {
|
||||
c = read();
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
case '\u000C':
|
||||
state = MetaScanner.BEFORE_ATTRIBUTE_NAME;
|
||||
break tagnameloop;
|
||||
// continue stateloop;
|
||||
case '/':
|
||||
state = MetaScanner.SELF_CLOSING_START_TAG;
|
||||
continue stateloop;
|
||||
case '>':
|
||||
state = MetaScanner.DATA;
|
||||
continue stateloop;
|
||||
case 'e':
|
||||
case 'E':
|
||||
if (metaState == M) {
|
||||
metaState = E;
|
||||
} else {
|
||||
metaState = NO;
|
||||
}
|
||||
continue;
|
||||
case 't':
|
||||
case 'T':
|
||||
if (metaState == E) {
|
||||
metaState = T;
|
||||
} else {
|
||||
metaState = NO;
|
||||
}
|
||||
continue;
|
||||
case 'a':
|
||||
case 'A':
|
||||
if (metaState == T) {
|
||||
metaState = A;
|
||||
} else {
|
||||
metaState = NO;
|
||||
}
|
||||
continue;
|
||||
default:
|
||||
metaState = NO;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// FALLTHRU DON'T REORDER
|
||||
case BEFORE_ATTRIBUTE_NAME:
|
||||
beforeattributenameloop: for (;;) {
|
||||
if (reconsume) {
|
||||
reconsume = false;
|
||||
} else {
|
||||
c = read();
|
||||
}
|
||||
/*
|
||||
* Consume the next input character:
|
||||
*/
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
case '\u000C':
|
||||
continue;
|
||||
case '/':
|
||||
state = MetaScanner.SELF_CLOSING_START_TAG;
|
||||
continue stateloop;
|
||||
case '>':
|
||||
state = DATA;
|
||||
continue stateloop;
|
||||
case 'c':
|
||||
case 'C':
|
||||
contentIndex = 0;
|
||||
charsetIndex = 0;
|
||||
state = MetaScanner.ATTRIBUTE_NAME;
|
||||
break beforeattributenameloop;
|
||||
default:
|
||||
contentIndex = -1;
|
||||
charsetIndex = -1;
|
||||
state = MetaScanner.ATTRIBUTE_NAME;
|
||||
break beforeattributenameloop;
|
||||
// continue stateloop;
|
||||
}
|
||||
}
|
||||
// FALLTHRU DON'T REORDER
|
||||
case ATTRIBUTE_NAME:
|
||||
attributenameloop: for (;;) {
|
||||
c = read();
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
case '\u000C':
|
||||
state = MetaScanner.AFTER_ATTRIBUTE_NAME;
|
||||
continue stateloop;
|
||||
case '/':
|
||||
state = MetaScanner.SELF_CLOSING_START_TAG;
|
||||
continue stateloop;
|
||||
case '=':
|
||||
strBufLen = 0;
|
||||
state = MetaScanner.BEFORE_ATTRIBUTE_VALUE;
|
||||
break attributenameloop;
|
||||
// continue stateloop;
|
||||
case '>':
|
||||
state = MetaScanner.DATA;
|
||||
continue stateloop;
|
||||
default:
|
||||
if (metaState == A) {
|
||||
if (c >= 'A' && c <= 'Z') {
|
||||
c += 0x20;
|
||||
}
|
||||
if (contentIndex == 6) {
|
||||
contentIndex = -1;
|
||||
} else if (contentIndex > -1
|
||||
&& contentIndex < 6
|
||||
&& (c == CONTENT[contentIndex + 1])) {
|
||||
contentIndex++;
|
||||
}
|
||||
if (charsetIndex == 6) {
|
||||
charsetIndex = -1;
|
||||
} else if (charsetIndex > -1
|
||||
&& charsetIndex < 6
|
||||
&& (c == CHARSET[charsetIndex + 1])) {
|
||||
charsetIndex++;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// FALLTHRU DON'T REORDER
|
||||
case BEFORE_ATTRIBUTE_VALUE:
|
||||
beforeattributevalueloop: for (;;) {
|
||||
c = read();
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
case '\u000C':
|
||||
continue;
|
||||
case '"':
|
||||
state = MetaScanner.ATTRIBUTE_VALUE_DOUBLE_QUOTED;
|
||||
break beforeattributevalueloop;
|
||||
// continue stateloop;
|
||||
case '\'':
|
||||
state = MetaScanner.ATTRIBUTE_VALUE_SINGLE_QUOTED;
|
||||
continue stateloop;
|
||||
case '>':
|
||||
state = MetaScanner.DATA;
|
||||
continue stateloop;
|
||||
default:
|
||||
if (charsetIndex == 6 || contentIndex == 6) {
|
||||
addToBuffer(c);
|
||||
}
|
||||
state = MetaScanner.ATTRIBUTE_VALUE_UNQUOTED;
|
||||
continue stateloop;
|
||||
}
|
||||
}
|
||||
// FALLTHRU DON'T REORDER
|
||||
case ATTRIBUTE_VALUE_DOUBLE_QUOTED:
|
||||
attributevaluedoublequotedloop: for (;;) {
|
||||
if (reconsume) {
|
||||
reconsume = false;
|
||||
} else {
|
||||
c = read();
|
||||
}
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case '"':
|
||||
if (tryCharset()) {
|
||||
break stateloop;
|
||||
}
|
||||
state = MetaScanner.AFTER_ATTRIBUTE_VALUE_QUOTED;
|
||||
break attributevaluedoublequotedloop;
|
||||
// continue stateloop;
|
||||
default:
|
||||
if (metaState == A && (contentIndex == 6 || charsetIndex == 6)) {
|
||||
addToBuffer(c);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// FALLTHRU DON'T REORDER
|
||||
case AFTER_ATTRIBUTE_VALUE_QUOTED:
|
||||
afterattributevaluequotedloop: for (;;) {
|
||||
c = read();
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
case '\u000C':
|
||||
state = MetaScanner.BEFORE_ATTRIBUTE_NAME;
|
||||
continue stateloop;
|
||||
case '/':
|
||||
state = MetaScanner.SELF_CLOSING_START_TAG;
|
||||
break afterattributevaluequotedloop;
|
||||
// continue stateloop;
|
||||
case '>':
|
||||
state = MetaScanner.DATA;
|
||||
continue stateloop;
|
||||
default:
|
||||
state = MetaScanner.BEFORE_ATTRIBUTE_NAME;
|
||||
reconsume = true;
|
||||
continue stateloop;
|
||||
}
|
||||
}
|
||||
// FALLTHRU DON'T REORDER
|
||||
case SELF_CLOSING_START_TAG:
|
||||
c = read();
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case '>':
|
||||
state = MetaScanner.DATA;
|
||||
continue stateloop;
|
||||
default:
|
||||
state = MetaScanner.BEFORE_ATTRIBUTE_NAME;
|
||||
reconsume = true;
|
||||
continue stateloop;
|
||||
}
|
||||
// XXX reorder point
|
||||
case ATTRIBUTE_VALUE_UNQUOTED:
|
||||
for (;;) {
|
||||
if (reconsume) {
|
||||
reconsume = false;
|
||||
} else {
|
||||
c = read();
|
||||
}
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
|
||||
case '\u000C':
|
||||
if (tryCharset()) {
|
||||
break stateloop;
|
||||
}
|
||||
state = MetaScanner.BEFORE_ATTRIBUTE_NAME;
|
||||
continue stateloop;
|
||||
case '>':
|
||||
if (tryCharset()) {
|
||||
break stateloop;
|
||||
}
|
||||
state = MetaScanner.DATA;
|
||||
continue stateloop;
|
||||
default:
|
||||
if (metaState == A && (contentIndex == 6 || charsetIndex == 6)) {
|
||||
addToBuffer(c);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// XXX reorder point
|
||||
case AFTER_ATTRIBUTE_NAME:
|
||||
for (;;) {
|
||||
c = read();
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
case '\u000C':
|
||||
continue;
|
||||
case '/':
|
||||
if (tryCharset()) {
|
||||
break stateloop;
|
||||
}
|
||||
state = MetaScanner.SELF_CLOSING_START_TAG;
|
||||
continue stateloop;
|
||||
case '=':
|
||||
state = MetaScanner.BEFORE_ATTRIBUTE_VALUE;
|
||||
continue stateloop;
|
||||
case '>':
|
||||
if (tryCharset()) {
|
||||
break stateloop;
|
||||
}
|
||||
state = MetaScanner.DATA;
|
||||
continue stateloop;
|
||||
case 'c':
|
||||
case 'C':
|
||||
contentIndex = 0;
|
||||
charsetIndex = 0;
|
||||
state = MetaScanner.ATTRIBUTE_NAME;
|
||||
continue stateloop;
|
||||
default:
|
||||
contentIndex = -1;
|
||||
charsetIndex = -1;
|
||||
state = MetaScanner.ATTRIBUTE_NAME;
|
||||
continue stateloop;
|
||||
}
|
||||
}
|
||||
// XXX reorder point
|
||||
case MARKUP_DECLARATION_OPEN:
|
||||
markupdeclarationopenloop: for (;;) {
|
||||
c = read();
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case '-':
|
||||
state = MetaScanner.MARKUP_DECLARATION_HYPHEN;
|
||||
break markupdeclarationopenloop;
|
||||
// continue stateloop;
|
||||
default:
|
||||
state = MetaScanner.SCAN_UNTIL_GT;
|
||||
reconsume = true;
|
||||
continue stateloop;
|
||||
}
|
||||
}
|
||||
// FALLTHRU DON'T REORDER
|
||||
case MARKUP_DECLARATION_HYPHEN:
|
||||
markupdeclarationhyphenloop: for (;;) {
|
||||
c = read();
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case '-':
|
||||
state = MetaScanner.COMMENT_START;
|
||||
break markupdeclarationhyphenloop;
|
||||
// continue stateloop;
|
||||
default:
|
||||
state = MetaScanner.SCAN_UNTIL_GT;
|
||||
reconsume = true;
|
||||
continue stateloop;
|
||||
}
|
||||
}
|
||||
// FALLTHRU DON'T REORDER
|
||||
case COMMENT_START:
|
||||
commentstartloop: for (;;) {
|
||||
c = read();
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case '-':
|
||||
state = MetaScanner.COMMENT_START_DASH;
|
||||
continue stateloop;
|
||||
case '>':
|
||||
state = MetaScanner.DATA;
|
||||
continue stateloop;
|
||||
default:
|
||||
state = MetaScanner.COMMENT;
|
||||
break commentstartloop;
|
||||
// continue stateloop;
|
||||
}
|
||||
}
|
||||
// FALLTHRU DON'T REORDER
|
||||
case COMMENT:
|
||||
commentloop: for (;;) {
|
||||
c = read();
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case '-':
|
||||
state = MetaScanner.COMMENT_END_DASH;
|
||||
break commentloop;
|
||||
// continue stateloop;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// FALLTHRU DON'T REORDER
|
||||
case COMMENT_END_DASH:
|
||||
commentenddashloop: for (;;) {
|
||||
c = read();
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case '-':
|
||||
state = MetaScanner.COMMENT_END;
|
||||
break commentenddashloop;
|
||||
// continue stateloop;
|
||||
default:
|
||||
state = MetaScanner.COMMENT;
|
||||
continue stateloop;
|
||||
}
|
||||
}
|
||||
// FALLTHRU DON'T REORDER
|
||||
case COMMENT_END:
|
||||
for (;;) {
|
||||
c = read();
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case '>':
|
||||
state = MetaScanner.DATA;
|
||||
continue stateloop;
|
||||
case '-':
|
||||
continue;
|
||||
default:
|
||||
state = MetaScanner.COMMENT;
|
||||
continue stateloop;
|
||||
}
|
||||
}
|
||||
// XXX reorder point
|
||||
case COMMENT_START_DASH:
|
||||
c = read();
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case '-':
|
||||
state = MetaScanner.COMMENT_END;
|
||||
continue stateloop;
|
||||
case '>':
|
||||
state = MetaScanner.DATA;
|
||||
continue stateloop;
|
||||
default:
|
||||
state = MetaScanner.COMMENT;
|
||||
continue stateloop;
|
||||
}
|
||||
// XXX reorder point
|
||||
case ATTRIBUTE_VALUE_SINGLE_QUOTED:
|
||||
for (;;) {
|
||||
if (reconsume) {
|
||||
reconsume = false;
|
||||
} else {
|
||||
c = read();
|
||||
}
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case '\'':
|
||||
if (tryCharset()) {
|
||||
break stateloop;
|
||||
}
|
||||
state = MetaScanner.AFTER_ATTRIBUTE_VALUE_QUOTED;
|
||||
continue stateloop;
|
||||
default:
|
||||
if (metaState == A && (contentIndex == 6 || charsetIndex == 6)) {
|
||||
addToBuffer(c);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// XXX reorder point
|
||||
case SCAN_UNTIL_GT:
|
||||
for (;;) {
|
||||
if (reconsume) {
|
||||
reconsume = false;
|
||||
} else {
|
||||
c = read();
|
||||
}
|
||||
switch (c) {
|
||||
case -1:
|
||||
break stateloop;
|
||||
case '>':
|
||||
state = MetaScanner.DATA;
|
||||
continue stateloop;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stateSave = state;
|
||||
}
|
||||
|
||||
private void addToBuffer(int c) {
|
||||
if (strBufLen == strBuf.length) {
|
||||
char[] newBuf = new char[strBuf.length + (strBuf.length << 1)];
|
||||
System.arraycopy(strBuf, 0, newBuf, 0, strBuf.length);
|
||||
Portability.releaseArray(strBuf);
|
||||
strBuf = newBuf;
|
||||
}
|
||||
strBuf[strBufLen++] = (char)c;
|
||||
}
|
||||
|
||||
private boolean tryCharset() throws SAXException {
|
||||
if (metaState != A || !(contentIndex == 6 || charsetIndex == 6)) {
|
||||
return false;
|
||||
}
|
||||
String attVal = Portability.newStringFromBuffer(strBuf, 0, strBufLen);
|
||||
String candidateEncoding;
|
||||
if (contentIndex == 6) {
|
||||
candidateEncoding = TreeBuilder.extractCharsetFromContent(attVal);
|
||||
Portability.releaseString(attVal);
|
||||
} else {
|
||||
candidateEncoding = attVal;
|
||||
}
|
||||
if (candidateEncoding == null) {
|
||||
return false;
|
||||
}
|
||||
boolean rv = tryCharset(candidateEncoding);
|
||||
Portability.releaseString(candidateEncoding);
|
||||
contentIndex = -1;
|
||||
charsetIndex = -1;
|
||||
return rv;
|
||||
}
|
||||
|
||||
protected abstract boolean tryCharset(String encoding) throws SAXException;
|
||||
|
||||
|
||||
}
|
167
content/html/parser/javasrc/Portability.java
Normal file
167
content/html/parser/javasrc/Portability.java
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2009 Mozilla Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package nu.validator.htmlparser.impl;
|
||||
|
||||
import nu.validator.htmlparser.annotation.Literal;
|
||||
import nu.validator.htmlparser.annotation.Local;
|
||||
import nu.validator.htmlparser.annotation.NoLength;
|
||||
|
||||
public final class Portability {
|
||||
|
||||
// Allocating methods
|
||||
|
||||
/**
|
||||
* Allocates a new local name object. In C++, the refcount must be set up in such a way that
|
||||
* calling <code>releaseLocal</code> on the return value balances the refcount set by this method.
|
||||
*/
|
||||
public static @Local String newLocalNameFromBuffer(@NoLength char[] buf, int offset, int length) {
|
||||
return new String(buf, offset, length).intern();
|
||||
}
|
||||
|
||||
public static String newStringFromBuffer(@NoLength char[] buf, int offset, int length) {
|
||||
return new String(buf, offset, length);
|
||||
}
|
||||
|
||||
public static String newEmptyString() {
|
||||
return "";
|
||||
}
|
||||
|
||||
public static String newStringFromLiteral(@Literal String literal) {
|
||||
return literal;
|
||||
}
|
||||
|
||||
// XXX get rid of this
|
||||
public static char[] newCharArrayFromLocal(@Local String local) {
|
||||
return local.toCharArray();
|
||||
}
|
||||
|
||||
public static char[] newCharArrayFromString(String string) {
|
||||
return string.toCharArray();
|
||||
}
|
||||
|
||||
// Deallocation methods
|
||||
|
||||
public static void releaseString(String str) {
|
||||
// No-op in Java
|
||||
}
|
||||
|
||||
public static void retainLocal(@Local String local) {
|
||||
// No-op in Java
|
||||
}
|
||||
|
||||
/**
|
||||
* This MUST be a no-op on locals that are known at compile time.
|
||||
* @param local
|
||||
*/
|
||||
public static void releaseLocal(@Local String local) {
|
||||
// No-op in Java
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases a Java array. This method is magically replaced by a macro in C++.
|
||||
* @param arr
|
||||
*/
|
||||
public static void releaseArray(Object arr) {
|
||||
// No-op in Java
|
||||
}
|
||||
|
||||
public static void retainElement(Object elt) {
|
||||
// No-op in Java
|
||||
}
|
||||
|
||||
public static void releaseElement(Object elt) {
|
||||
// No-op in Java
|
||||
}
|
||||
|
||||
// Comparison methods
|
||||
|
||||
public static boolean localEqualsBuffer(@Local String local, @NoLength char[] buf, int offset, int length) {
|
||||
if (local.length() != length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (local.charAt(i) != buf[offset + i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(@Literal String lowerCaseLiteral,
|
||||
String string) {
|
||||
if (string == null) {
|
||||
return false;
|
||||
}
|
||||
if (lowerCaseLiteral.length() > string.length()) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < lowerCaseLiteral.length(); i++) {
|
||||
char c0 = lowerCaseLiteral.charAt(i);
|
||||
char c1 = string.charAt(i);
|
||||
if (c1 >= 'A' && c1 <= 'Z') {
|
||||
c1 += 0x20;
|
||||
}
|
||||
if (c0 != c1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean lowerCaseLiteralEqualsIgnoreAsciiCaseString(@Literal String lowerCaseLiteral,
|
||||
String string) {
|
||||
if (string == null) {
|
||||
return false;
|
||||
}
|
||||
if (lowerCaseLiteral.length() != string.length()) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < lowerCaseLiteral.length(); i++) {
|
||||
char c0 = lowerCaseLiteral.charAt(i);
|
||||
char c1 = string.charAt(i);
|
||||
if (c1 >= 'A' && c1 <= 'Z') {
|
||||
c1 += 0x20;
|
||||
}
|
||||
if (c0 != c1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean literalEqualsString(@Literal String literal, String string) {
|
||||
return literal.equals(string);
|
||||
}
|
||||
|
||||
public static char[] isIndexPrompt() {
|
||||
return "This is a searchable index. Insert your search keywords here: ".toCharArray();
|
||||
}
|
||||
|
||||
public static void delete(Object o) {
|
||||
|
||||
}
|
||||
|
||||
public static void deleteArray(Object o) {
|
||||
|
||||
}
|
||||
}
|
155
content/html/parser/javasrc/StackNode.java
Normal file
155
content/html/parser/javasrc/StackNode.java
Normal file
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Henri Sivonen
|
||||
* Copyright (c) 2007-2009 Mozilla Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package nu.validator.htmlparser.impl;
|
||||
|
||||
import nu.validator.htmlparser.annotation.Local;
|
||||
import nu.validator.htmlparser.annotation.NsUri;
|
||||
|
||||
final class StackNode<T> {
|
||||
final int group;
|
||||
|
||||
final @Local String name;
|
||||
|
||||
final @Local String popName;
|
||||
|
||||
final @NsUri String ns;
|
||||
|
||||
final T node;
|
||||
|
||||
final boolean scoping;
|
||||
|
||||
final boolean special;
|
||||
|
||||
final boolean fosterParenting;
|
||||
|
||||
private int refcount = 1;
|
||||
|
||||
/**
|
||||
* @param group
|
||||
* TODO
|
||||
* @param name
|
||||
* @param node
|
||||
* @param scoping
|
||||
* @param special
|
||||
* @param popName
|
||||
* TODO
|
||||
*/
|
||||
StackNode(int group, final @NsUri String ns, final @Local String name, final T node,
|
||||
final boolean scoping, final boolean special,
|
||||
final boolean fosterParenting, final @Local String popName) {
|
||||
this.group = group;
|
||||
this.name = name;
|
||||
this.popName = popName;
|
||||
this.ns = ns;
|
||||
this.node = node;
|
||||
this.scoping = scoping;
|
||||
this.special = special;
|
||||
this.fosterParenting = fosterParenting;
|
||||
this.refcount = 1;
|
||||
Portability.retainLocal(name);
|
||||
Portability.retainLocal(popName);
|
||||
Portability.retainElement(node);
|
||||
// not retaining namespace for now
|
||||
}
|
||||
|
||||
/**
|
||||
* @param elementName
|
||||
* TODO
|
||||
* @param node
|
||||
*/
|
||||
StackNode(final @NsUri String ns, ElementName elementName, final T node) {
|
||||
this.group = elementName.group;
|
||||
this.name = elementName.name;
|
||||
this.popName = elementName.name;
|
||||
this.ns = ns;
|
||||
this.node = node;
|
||||
this.scoping = elementName.scoping;
|
||||
this.special = elementName.special;
|
||||
this.fosterParenting = elementName.fosterParenting;
|
||||
this.refcount = 1;
|
||||
Portability.retainLocal(name);
|
||||
Portability.retainLocal(popName);
|
||||
Portability.retainElement(node);
|
||||
// not retaining namespace for now
|
||||
}
|
||||
|
||||
StackNode(final @NsUri String ns, ElementName elementName, final T node, @Local String popName) {
|
||||
this.group = elementName.group;
|
||||
this.name = elementName.name;
|
||||
this.popName = popName;
|
||||
this.ns = ns;
|
||||
this.node = node;
|
||||
this.scoping = elementName.scoping;
|
||||
this.special = elementName.special;
|
||||
this.fosterParenting = elementName.fosterParenting;
|
||||
this.refcount = 1;
|
||||
Portability.retainLocal(name);
|
||||
Portability.retainLocal(popName);
|
||||
Portability.retainElement(node);
|
||||
// not retaining namespace for now
|
||||
}
|
||||
|
||||
StackNode(final @NsUri String ns, ElementName elementName, final T node, @Local String popName, boolean scoping) {
|
||||
this.group = elementName.group;
|
||||
this.name = elementName.name;
|
||||
this.popName = popName;
|
||||
this.ns = ns;
|
||||
this.node = node;
|
||||
this.scoping = scoping;
|
||||
this.special = false;
|
||||
this.fosterParenting = false;
|
||||
this.refcount = 1;
|
||||
Portability.retainLocal(name);
|
||||
Portability.retainLocal(popName);
|
||||
Portability.retainElement(node);
|
||||
// not retaining namespace for now
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused") private void destructor() {
|
||||
Portability.releaseLocal(name);
|
||||
Portability.releaseLocal(popName);
|
||||
Portability.releaseElement(node);
|
||||
// not releasing namespace for now
|
||||
}
|
||||
|
||||
// [NOCPP[
|
||||
/**
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override public @Local String toString() {
|
||||
return name;
|
||||
}
|
||||
// ]NOCPP]
|
||||
|
||||
public void retain() {
|
||||
refcount++;
|
||||
}
|
||||
|
||||
public void release() {
|
||||
refcount--;
|
||||
if (refcount == 0) {
|
||||
Portability.delete(this);
|
||||
}
|
||||
}
|
||||
}
|
59
content/html/parser/javasrc/StateSnapshot.java
Normal file
59
content/html/parser/javasrc/StateSnapshot.java
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Mozilla Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package nu.validator.htmlparser.impl;
|
||||
|
||||
|
||||
public class StateSnapshot<T> {
|
||||
|
||||
/**
|
||||
* @param stack
|
||||
* @param listOfActiveFormattingElements
|
||||
* @param formPointer
|
||||
*/
|
||||
StateSnapshot(StackNode<T>[] stack,
|
||||
StackNode<T>[] listOfActiveFormattingElements, T formPointer) {
|
||||
this.stack = stack;
|
||||
this.listOfActiveFormattingElements = listOfActiveFormattingElements;
|
||||
this.formPointer = formPointer;
|
||||
}
|
||||
|
||||
final StackNode<T>[] stack;
|
||||
|
||||
final StackNode<T>[] listOfActiveFormattingElements;
|
||||
|
||||
final T formPointer;
|
||||
|
||||
@SuppressWarnings("unused") private void destructor() {
|
||||
for (int i = 0; i < stack.length; i++) {
|
||||
stack[i].release();
|
||||
}
|
||||
Portability.releaseArray(stack);
|
||||
for (int i = 0; i < listOfActiveFormattingElements.length; i++) {
|
||||
if (listOfActiveFormattingElements[i] != null) {
|
||||
listOfActiveFormattingElements[i].release();
|
||||
}
|
||||
}
|
||||
Portability.releaseArray(listOfActiveFormattingElements);
|
||||
Portability.retainElement(formPointer);
|
||||
}
|
||||
}
|
5711
content/html/parser/javasrc/Tokenizer.java
Normal file
5711
content/html/parser/javasrc/Tokenizer.java
Normal file
File diff suppressed because it is too large
Load Diff
5093
content/html/parser/javasrc/TreeBuilder.java
Normal file
5093
content/html/parser/javasrc/TreeBuilder.java
Normal file
File diff suppressed because it is too large
Load Diff
99
content/html/parser/javasrc/UTF16Buffer.java
Normal file
99
content/html/parser/javasrc/UTF16Buffer.java
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Mozilla Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package nu.validator.htmlparser.impl;
|
||||
|
||||
import nu.validator.htmlparser.annotation.NoLength;
|
||||
|
||||
public final class UTF16Buffer {
|
||||
private final @NoLength char[] buffer;
|
||||
|
||||
private int start;
|
||||
|
||||
private int end;
|
||||
|
||||
/**
|
||||
* @param buffer
|
||||
* @param start
|
||||
* @param end
|
||||
*/
|
||||
public UTF16Buffer(@NoLength char[] buffer, int start, int end) {
|
||||
this.buffer = buffer;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the start.
|
||||
*
|
||||
* @return the start
|
||||
*/
|
||||
public int getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the start.
|
||||
*
|
||||
* @param start the start to set
|
||||
*/
|
||||
public void setStart(int start) {
|
||||
this.start = start;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the buffer.
|
||||
*
|
||||
* @return the buffer
|
||||
*/
|
||||
public @NoLength char[] getBuffer() {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the end.
|
||||
*
|
||||
* @return the end
|
||||
*/
|
||||
public int getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
public boolean hasMore() {
|
||||
return start < end;
|
||||
}
|
||||
|
||||
public void adjust(boolean lastWasCR) {
|
||||
if (lastWasCR && buffer[start] == '\n') {
|
||||
start++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the end.
|
||||
*
|
||||
* @param end the end to set
|
||||
*/
|
||||
public void setEnd(int end) {
|
||||
this.end = end;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user