package com.ctc.wstx.evt;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Iterator;
import javax.xml.namespace.QName;
import javax.xml.stream.*;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.StartElement;
import org.codehaus.stax2.ri.evt.AttributeEventImpl;
import com.ctc.wstx.io.TextEscaper;
import com.ctc.wstx.sr.ElemAttrs;
import com.ctc.wstx.util.BaseNsContext;
import com.ctc.wstx.util.DataUtil;
public class CompactStartElement
extends BaseStartElement
{
private final static int OFFSET_NS_URI = 1;
private final static int OFFSET_NS_PREFIX = 2;
private final static int OFFSET_VALUE = 3;
final ElemAttrs mAttrs;
final String[] mRawAttrs;
private ArrayList<Attribute> mAttrList = null;
protected CompactStartElement(Location loc, QName name, BaseNsContext nsCtxt,
ElemAttrs attrs)
{
super(loc, name, nsCtxt);
mAttrs = attrs;
mRawAttrs = (attrs == null) ? null : attrs.getRawAttrs();
}
@Override
public Attribute getAttributeByName(QName name)
{
if (mAttrs == null) {
return null;
}
int ix = mAttrs.findIndex(name);
if (ix < 0) {
return null;
}
return constructAttr(mRawAttrs, ix, mAttrs.isDefault(ix));
}
@Override
public Iterator<Attribute> getAttributes()
{
if (mAttrList == null) {
if (mAttrs == null) {
return DataUtil.emptyIterator();
}
String[] rawAttrs = mRawAttrs;
int rawLen = rawAttrs.length;
int defOffset = mAttrs.getFirstDefaultOffset();
if (rawLen == 4) {
return DataUtil.singletonIterator(constructAttr(rawAttrs, 0, (defOffset == 0)));
}
ArrayList<Attribute> l = new ArrayList<Attribute>(rawLen >> 2);
for (int i = 0; i < rawLen; i += 4) {
l.add(constructAttr(rawAttrs, i, (i >= defOffset)));
}
mAttrList = l;
}
return mAttrList.iterator();
}
@Override
protected void outputNsAndAttr(Writer w) throws IOException
{
if (mNsCtxt != null) {
mNsCtxt.outputNamespaceDeclarations(w);
}
String[] raw = mRawAttrs;
if (raw != null) {
for (int i = 0, len = raw.length; i < len; i += 4) {
w.write(' ');
String prefix = raw[i + OFFSET_NS_PREFIX];
if (prefix != null && prefix.length() > 0) {
w.write(prefix);
w.write(':');
}
w.write(raw[i]);
w.write("=\"");
TextEscaper.writeEscapedAttrValue(w, raw[i + OFFSET_VALUE]);
w.write('"');
}
}
}
@Override
protected void outputNsAndAttr(XMLStreamWriter w) throws XMLStreamException
{
if (mNsCtxt != null) {
mNsCtxt.outputNamespaceDeclarations(w);
}
String[] raw = mRawAttrs;
if (raw != null) {
for (int i = 0, len = raw.length; i < len; i += 4) {
String ln = raw[i];
String prefix = raw[i + OFFSET_NS_PREFIX];
String nsURI = raw[i + OFFSET_NS_URI];
w.writeAttribute(prefix, nsURI, ln, raw[i + OFFSET_VALUE]);
}
}
}
protected Attribute constructAttr(String[] raw, int rawIndex, boolean isDef)
{
return new AttributeEventImpl(getLocation(), raw[rawIndex], raw[rawIndex+1],
raw[rawIndex+2], raw[rawIndex+3], !isDef);
}
}