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    }