001 /*
002 * Copyright (c) 2007 Henri Sivonen
003 *
004 * Permission is hereby granted, free of charge, to any person obtaining a
005 * copy of this software and associated documentation files (the "Software"),
006 * to deal in the Software without restriction, including without limitation
007 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
008 * and/or sell copies of the Software, and to permit persons to whom the
009 * Software is furnished to do so, subject to the following conditions:
010 *
011 * The above copyright notice and this permission notice shall be included in
012 * all copies or substantial portions of the Software.
013 *
014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
015 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
017 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
018 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
019 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
020 * DEALINGS IN THE SOFTWARE.
021 */
022
023 package nu.validator.htmlparser.impl;
024
025 import org.xml.sax.Attributes;
026
027 /**
028 * Be careful with this class. QName is the name in from
029 * HTML tokenization. Otherwise, please refer to the interface doc.
030 *
031 * @version $Id: AttributesImpl.java 150 2007-08-16 19:21:25Z hsivonen $
032 * @author hsivonen
033 */
034 public class AttributesImpl implements Attributes {
035
036 private int length = 0;
037
038 private int limit = 0;
039
040 private String[] array = new String[10]; // covers 98.3% of elements according to Hixie
041
042 public final int getIndex(String qName) {
043 for (int i = 0; i < limit; i += 2) {
044 if (array[i].equals(qName)) {
045 return i / 2;
046 }
047 }
048 return -1;
049 }
050
051 public int getIndex(String uri, String localName) {
052 if ("".equals(uri)) {
053 return getIndex(localName);
054 } else {
055 return -1;
056 }
057 }
058
059 public final int getLength() {
060 return length;
061 }
062
063 public final String getLocalName(int index) {
064 return getQName(index);
065 }
066
067 public final String getQName(int index) {
068 return index < length ? array[index * 2] : null;
069 }
070
071 public final String getType(int index) {
072 if (index < length) {
073 if ("id".equals(getQName(index))) {
074 return "ID";
075 } else {
076 return "CDATA";
077 }
078 } else {
079 return null;
080 }
081 }
082
083 public final String getType(String qName) {
084 int index = getIndex(qName);
085 if (index == -1) {
086 return null;
087 } else {
088 return getType(index);
089 }
090 }
091
092 public String getType(String uri, String localName) {
093 if ("".equals(uri)) {
094 return getType(localName);
095 } else {
096 return null;
097 }
098 }
099
100 public String getURI(int index) {
101 return index < length ? "" : null;
102 }
103
104 public final String getValue(int index) {
105 return index < length ? array[index * 2 + 1] : null;
106 }
107
108 public final String getValue(String qName) {
109 int index = getIndex(qName);
110 if (index == -1) {
111 return null;
112 } else {
113 return getValue(index);
114 }
115 }
116
117 public String getValue(String uri, String localName) {
118 if ("".equals(uri)) {
119 return getValue(localName);
120 } else {
121 return null;
122 }
123 }
124
125 public final void addAttribute(String name, String value) {
126 if (array.length == limit) {
127 String[] newArray = new String[array.length + 10]; // The first growth covers virtually 100% of elements according to Hixie
128 System.arraycopy(array, 0, newArray, 0, array.length);
129 array = newArray;
130 }
131 array[limit] = name;
132 array[limit + 1] = value;
133 length++;
134 limit += 2;
135 }
136
137 }