/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jute;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
*
*/
class XmlInputArchive implements InputArchive {
static private class Value {
private String type;
private StringBuffer sb;
public Value(String t) {
type = t;
sb = new StringBuffer();
}
public void addChars(char[] buf, int offset, int len) {
sb.append(buf, offset, len);
}
public String getValue() { return sb.toString(); }
public String getType() { return type; }
}
private static class XMLParser extends DefaultHandler {
private boolean charsValid = false;
private ArrayList<Value> valList;
private XMLParser(ArrayList<Value> vlist) {
valList = vlist;
}
public void startDocument() throws SAXException {}
public void endDocument() throws SAXException {}
public void startElement(String ns,
String sname,
String qname,
Attributes attrs) throws SAXException {
charsValid = false;
if ("boolean".equals(qname) ||
"i4".equals(qname) ||
"int".equals(qname) ||
"string".equals(qname) ||
"double".equals(qname) ||
"ex:i1".equals(qname) ||
"ex:i8".equals(qname) ||
"ex:float".equals(qname)) {
charsValid = true;
valList.add(new Value(qname));
} else if ("struct".equals(qname) ||
"array".equals(qname)) {
valList.add(new Value(qname));
}
}
public void endElement(String ns,
String sname,
String qname) throws SAXException {
charsValid = false;
if ("struct".equals(qname) ||
"array".equals(qname)) {
valList.add(new Value("/"+qname));
}
}
public void characters(char buf[], int offset, int len)
throws SAXException {
if (charsValid) {
Value v = valList.get(valList.size()-1);
v.addChars(buf, offset,len);
}
}
}
private class XmlIndex implements Index {
public boolean done() {
Value v = valList.get(vIdx);
if ("/array".equals(v.getType())) {
valList.set(vIdx, null);
vIdx++;
return true;
} else {
return false;
}
}
public void incr() {}
}
private ArrayList<Value> valList;
private int vLen;
private int vIdx;
private Value next() throws IOException {
if (vIdx < vLen) {
Value v = valList.get(vIdx);
valList.set(vIdx, null);
vIdx++;
return v;
} else {
throw new IOException("Error in deserialization.");
}
}
static XmlInputArchive getArchive(InputStream strm)
throws ParserConfigurationException, SAXException, IOException {
return new XmlInputArchive(strm);
}
/** Creates a new instance of BinaryInputArchive */
public XmlInputArchive(InputStream in)
throws ParserConfigurationException, SAXException, IOException {
valList = new ArrayList<Value>();
DefaultHandler handler = new XMLParser(valList);
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
parser.parse(in, handler);
vLen = valList.size();
vIdx = 0;
}
public byte readByte(String tag) throws IOException {
Value v = next();
if (!"ex:i1".equals(v.getType())) {
throw new IOException("Error deserializing "+tag+".");
}
return Byte.parseByte(v.getValue());
}
public boolean readBool(String tag) throws IOException {
Value v = next();
if (!"boolean".equals(v.getType())) {
throw new IOException("Error deserializing "+tag+".");
}
return "1".equals(v.getValue());
}
public int readInt(String tag) throws IOException {
Value v = next();
if (!"i4".equals(v.getType()) &&
!"int".equals(v.getType())) {
throw new IOException("Error deserializing "+tag+".");
}
return Integer.parseInt(v.getValue());
}
public long readLong(String tag) throws IOException {
Value v = next();
if (!"ex:i8".equals(v.getType())) {
throw new IOException("Error deserializing "+tag+".");
}
return Long.parseLong(v.getValue());
}
public float readFloat(String tag) throws IOException {
Value v = next();
if (!"ex:float".equals(v.getType())) {
throw new IOException("Error deserializing "+tag+".");
}
return Float.parseFloat(v.getValue());
}
public double readDouble(String tag) throws IOException {
Value v = next();
if (!"double".equals(v.getType())) {
throw new IOException("Error deserializing "+tag+".");
}
return Double.parseDouble(v.getValue());
}
public String readString(String tag) throws IOException {
Value v = next();
if (!"string".equals(v.getType())) {
throw new IOException("Error deserializing "+tag+".");
}
return Utils.fromXMLString(v.getValue());
}
public byte[] readBuffer(String tag) throws IOException {
Value v = next();
if (!"string".equals(v.getType())) {
throw new IOException("Error deserializing "+tag+".");
}
return Utils.fromXMLBuffer(v.getValue());
}
public void readRecord(Record r, String tag) throws IOException {
r.deserialize(this, tag);
}
public void startRecord(String tag) throws IOException {
Value v = next();
if (!"struct".equals(v.getType())) {
throw new IOException("Error deserializing "+tag+".");
}
}
public void endRecord(String tag) throws IOException {
Value v = next();
if (!"/struct".equals(v.getType())) {
throw new IOException("Error deserializing "+tag+".");
}
}
public Index startVector(String tag) throws IOException {
Value v = next();
if (!"array".equals(v.getType())) {
throw new IOException("Error deserializing "+tag+".");
}
return new XmlIndex();
}
public void endVector(String tag) throws IOException {}
public Index startMap(String tag) throws IOException {
return startVector(tag);
}
public void endMap(String tag) throws IOException { endVector(tag); }
}