blob: 6af8be3a42a34cf689d3817fd1bf80b622628c61 [file] [log] [blame]
//TODO INCOMPLETE
/*
* @author: ucla-cs
*
* Decodes CCN object into xml
*/
var TextXMLDecoder = function TextXMLDecoder(){
this.reader = null;
};
exports.TextXMLDecoder = TextXMLDecoder;
exports.prototype.initializeDecoding = function(){
try {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
_reader = factory.newPullParser();
_reader.setInput(_istream, null);
} catch (XmlPullParserException e) {
throw new ContentDecodingException(e.getMessage(), e);
}
};
exports.prototype.readStartDocument = function(){
try {
int event = _reader.getEventType();
_reader.next();
if (event != XmlPullParser.START_DOCUMENT) {
throw new ContentDecodingException("Expected start document, got: " + XmlPullParser.TYPES[event]);
}
} catch (XmlPullParserException e) {
throw new ContentDecodingException(e.getMessage(), e);
} catch (IOException e) {
throw new ContentDecodingException(e.getMessage(), e);
}
};
public void readEndDocument() throws ContentDecodingException {
int event;
try {
event = _reader.getEventType();
} catch (XmlPullParserException e) {
throw new ContentDecodingException(e.getMessage(), e);
}
if (event != XmlPullParser.END_DOCUMENT) {
throw new ContentDecodingException("Expected end document, got: " + XmlPullParser.TYPES[event]);
}
};
exports.prototype.readStartElement = function(/*String*/ startTag,
TreeMap<String, String> attributes) throws ContentDecodingException {
int event = readToNextTag(XmlPullParser.START_TAG);
if (event != XmlPullParser.START_TAG) {
throw new ContentDecodingException("Expected start element, got: " + XmlPullParser.TYPES[event]);
}
// Use getLocalPart to strip namespaces.
// Assumes we are working with a global default namespace of CCN.
if (!startTag.equals(_reader.getName())) {
// Coming back with namespace decoration doesn't match
throw new ContentDecodingException("Expected start element: " + startTag + " got: " + _reader.getName());
}
if (null != attributes) {
// we might be expecting attributes
for (int i=0; i < _reader.getAttributeCount(); ++i) {
// may need fancier namespace handling.
attributes.put(_reader.getAttributeName(i), _reader.getAttributeValue(i));
}
}
try {
_reader.next();
} catch (XmlPullParserException e) {
throw new ContentDecodingException(e.getMessage());
} catch (IOException e) {
throw new ContentDecodingException(e.getMessage());
}
}
public void readStartElement(long startTagLong,
TreeMap<String, String> attributes) throws ContentDecodingException {
String startTag = tagToString(startTagLong);
int event = readToNextTag(XmlPullParser.START_TAG);
if (event != XmlPullParser.START_TAG) {
throw new ContentDecodingException("Expected start element, got: " + XmlPullParser.TYPES[event]);
}
// Use getLocalPart to strip namespaces.
// Assumes we are working with a global default namespace of CCN.
if (!startTag.equals(_reader.getName())) {
// Coming back with namespace decoration doesn't match
throw new ContentDecodingException("Expected start element: " + startTag + " got: " + _reader.getName());
}
if (null != attributes) {
// we might be expecting attributes
for (int i=0; i < _reader.getAttributeCount(); ++i) {
// may need fancier namespace handling.
attributes.put(_reader.getAttributeName(i), _reader.getAttributeValue(i));
}
}
try {
_reader.next();
} catch (XmlPullParserException e) {
throw new ContentDecodingException(e.getMessage());
} catch (IOException e) {
throw new ContentDecodingException(e.getMessage());
}
}
public String peekStartElementAsString() throws ContentDecodingException {
int event = readToNextTag(XmlPullParser.START_TAG);
if (event != XmlPullParser.START_TAG) {
return null;
}
return _reader.getName();
}
public Long peekStartElementAsLong() throws ContentDecodingException {
String strTag = peekStartElementAsString();
if (null == strTag) {
return null; // e.g. hit an end tag...
}
return stringToTag(strTag);
}
/**
* Helper method to decode text (UTF-8) and binary elements. Consumes the end element,
* behavior which other decoders are forced to match.
* @return the read data, as a String
* @throws ContentDecodingException if there is a problem decoding the data
*/
public String readUString() throws ContentDecodingException {
StringBuffer buf = new StringBuffer();
try {
int event = _reader.getEventType();;
// Handles empty text element.
while (event == XmlPullParser.TEXT) {
buf.append(_reader.getText());
event = _reader.next();
}
if (event == XmlPullParser.START_TAG) {
throw new ContentDecodingException("readElementText expects start element to have been previously consumed, got: " + XmlPullParser.TYPES[event]);
} else if (event != XmlPullParser.END_TAG) {
throw new ContentDecodingException("Expected end of text element, got: " + XmlPullParser.TYPES[event]);
}
readEndElement();
return buf.toString();
} catch (XmlPullParserException e) {
throw new ContentDecodingException(e.getMessage(), e);
} catch (IOException e) {
throw new ContentDecodingException(e.getMessage(), e);
}
}
public void readEndElement() throws ContentDecodingException {
int event = readToNextTag(XmlPullParser.END_TAG);
if (event != XmlPullParser.END_TAG) {
throw new ContentDecodingException("Expected end element, got: " + XmlPullParser.TYPES[event]);
}
try {
_reader.next();
} catch (XmlPullParserException e) {
throw new ContentDecodingException(e.getMessage());
} catch (IOException e) {
throw new ContentDecodingException(e.getMessage());
}
}
/**
* Read a BLOB. Consumes the end element, so force other versions
* to match.
*/
public byte [] readBlob() throws ContentDecodingException {
try {
String strElementText = readUString();
// readEndElement(); // readElementText consumes end element
return TextXMLCodec.decodeBinaryElement(strElementText);
} catch (IOException e) {
throw new ContentDecodingException(e.getMessage(),e);
}
}
public CCNTime readDateTime(String startTag) throws ContentDecodingException {
String strTimestamp = readUTF8Element(startTag);
CCNTime timestamp;
try {
timestamp = TextXMLCodec.parseDateTime(strTimestamp);
} catch (ParseException e) {
timestamp = null;
}
if (null == timestamp) {
throw new ContentDecodingException("Cannot parse timestamp: " + strTimestamp);
}
return timestamp;
}
public CCNTime readDateTime(long startTag) throws ContentDecodingException {
String strTimestamp = readUTF8Element(startTag);
CCNTime timestamp;
try {
timestamp = TextXMLCodec.parseDateTime(strTimestamp);
} catch (ParseException e) {
timestamp = null;
}
if (null == timestamp) {
throw new ContentDecodingException("Cannot parse timestamp: " + strTimestamp);
}
return timestamp;
}
private int readToNextTag(int type) throws ContentDecodingException {
int event;
try {
event = _reader.getEventType();
if (event == type)
return event;
if (event == XmlPullParser.TEXT || event == XmlPullParser.COMMENT)
event = _reader.next();
} catch (IOException e) {
throw new ContentDecodingException(e.getMessage(), e);
} catch (XmlPullParserException e) {
throw new ContentDecodingException(e.getMessage(), e);
}
return event;
}
};