📄 wbxmlparser.java
字号:
// (c) 2001 Stefan Haustein
// Contributors: Bjorn Aadland
package org.kxml.wap;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import org.kxml.Attribute;
import org.kxml.Xml;
import org.kxml.io.ParseException;
import org.kxml.parser.AbstractXmlParser;
import org.kxml.parser.ParseEvent;
import org.kxml.parser.StartTag;
import org.kxml.parser.Tag;
/** Still Todo:
* <ul>
* <li>implement Processing Instructions</li>
* <li>implement support for more than one codepages</li>
* </ul>
*/
public class WbxmlParser extends AbstractXmlParser {
InputStream in;
// all known code pages and their tables
Hashtable otherAttrStartTables = new Hashtable();
Hashtable otherAttrValueTables = new Hashtable();
Hashtable otherTagTables = new Hashtable();
String[] attrStartTable;
String[] attrValueTable;
String[] tagTable;
String stringTable;
int version;
int publicIdentifierId;
String publicIdentifier=null;
int charSet;
StartTag current;
ParseEvent next;
boolean whitespace;
private PublicIDEntry documentPubID=null;
private PublicIDEntry currentPubID=null;
public WbxmlParser(InputStream in) throws Exception {
int publicIdentifierOffset=-1;
this.in = in;
version = readByte();
publicIdentifierId = readInt();
if (publicIdentifierId == 0)
publicIdentifierOffset=readInt();
charSet = readInt(); // skip charset
int strTabSize = readInt();
StringBuffer buf = new StringBuffer(strTabSize);
for (int i = 0; i < strTabSize; i++)
buf.append((char)readByte());
stringTable = buf.toString();
// initialisation of tables and public identifier objects
WbxmlInitialiser initialiser=null;
if(publicIdentifierId!=0) {
initialiser=WbxmlInitialiserFactory.getInitialiserByPublicIdentifierCode(publicIdentifierId);
}
else {
if(publicIdentifierOffset>=0) {
extractInlinePublicID(publicIdentifierOffset);
if (publicIdentifier!=null) {
initialiser=WbxmlInitialiserFactory.getInitialiserByPublicIdentifier(publicIdentifier);
}
}
}
if(initialiser!=null) {
initialiser.initialise(this);
}
// load the public identifier
if(publicIdentifier==null) {
documentPubID=getPublicIDEntryByCode(publicIdentifierId);
}
else {
documentPubID=getPublicIDEntry(publicIdentifier);
}
}
private void extractInlinePublicID(int anOffset) {
publicIdentifier=this.extractFromStrT(anOffset);
}
public ParseEvent peek() throws IOException {
String s;
if (next != null)
return next;
if (current != null && current.getDegenerated()) {
next = new Tag
(Xml.END_TAG, current,
current.getNamespace(),
current.getName());
current = current.getParent();
return next;
}
ParseEvent result = null;
do {
int id = in.read();
switch (id) {
case -1:
if (current != null)
throw new RuntimeException("unclosed elements: " + current);
next = new ParseEvent(Xml.END_DOCUMENT, null);
break;
case Wbxml.SWITCH_PAGE:
int page = readByte();
switchPage(page);
break;
case Wbxml.END:
next = new Tag(Xml.END_TAG, current,
current.getNamespace(),
current.getName());
current = current.getParent();
break;
case Wbxml.ENTITY:
next = new ParseEvent(Xml.TEXT, "" + (char)readInt());
break;
case Wbxml.STR_I: {
s = readStrI();
next = new ParseEvent(whitespace ? Xml.WHITESPACE : Xml.TEXT, s);
break;
}
case Wbxml.EXT_I_0:
case Wbxml.EXT_I_1:
case Wbxml.EXT_I_2:
case Wbxml.EXT_T_0:
case Wbxml.EXT_T_1:
case Wbxml.EXT_T_2:
case Wbxml.EXT_0:
case Wbxml.EXT_1:
case Wbxml.EXT_2:
case Wbxml.OPAQUE:
next = parseWapExtension(id);
break;
case Wbxml.PI:
throw new RuntimeException("PI curr. not supp.");
// readPI;
// break;
case Wbxml.STR_T: {
int pos = readInt();
int end = stringTable.indexOf('\0', pos);
next = new ParseEvent
(Xml.TEXT, stringTable.substring(pos, end));
break;
}
default:
next = parseElement(id);
}
}
while (next == null);
return next;
}
public ParseEvent read() throws IOException {
if (next == null)
peek();
ParseEvent result = next;
next = null;
return result;
}
/**
* Switches to code page <code>page</code>
*
* @param page the page to switch to
*/
private void switchPage(int page){
Integer ipage = new Integer(page);
attrStartTable = (String[]) otherAttrStartTables.get(ipage);
attrValueTable = (String[]) otherAttrValueTables.get(ipage);
tagTable = (String[]) otherTagTables.get(ipage);
currentPubID=getPublicIDEntryByIndex(page);
}
/** For handling wap extensions in attributes, overwrite this
method, call super and return a corresponding TextEvent. */
public ParseEvent parseWapExtension(int id) throws IOException {
switch (id) {
case Wbxml.EXT_I_0:
case Wbxml.EXT_I_1:
case Wbxml.EXT_I_2:
return new WapExtensionEvent(id, readStrI());
case Wbxml.EXT_T_0:
case Wbxml.EXT_T_1:
case Wbxml.EXT_T_2:
return new WapExtensionEvent(id, new Integer(readInt()));
case Wbxml.EXT_0:
case Wbxml.EXT_1:
case Wbxml.EXT_2:
return new WapExtensionEvent(id, null);
case Wbxml.OPAQUE: {
int len = readInt();
byte[] buf = new byte[len];
for (int i = 0; i < len; i++) // enhance with blockread!
buf[i] = (byte)readByte();
return new WapExtensionEvent(id, buf);
} // case OPAQUE
} // SWITCH
throw new IOException("illegal id!");
}
public Vector readAttr() throws IOException {
Vector result = new Vector();
int id = readByte();
while (id != 1) {
String name = resolveId(attrStartTable, id);
StringBuffer value;
int cut = name.indexOf('=');
if (cut == -1)
value = new StringBuffer();
else {
value = new StringBuffer(name.substring(cut + 1));
name = name.substring(0, cut);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -