?? wbxmldecoder.java~8~
字號:
/**
* JWAP - A Java Implementation of the WAP Protocols
* Copyright (C) 2001-2004 Niko Bender
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package net.sourceforge.jwap.util.wbxml;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import net.sourceforge.jwap.util.TransTable;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.Text;
/**
* to do's :- string table length is in multiple byte format, currently it is assumed to be single byte
* index in string table should also be read as multiple byte format
* character encoding supported is only utf-8,
* for other encodings the termination character in string table can be different...
*
*
* @author <a href="mailto:suvarna@witscale.com">Suvarna Kadam</a>
*/
public class WBXMLDecoder {
private static WBXMLDecoder instance;
private DataInputStream wbxmlStream;
private Document xmlDocument;
private String publicId = "UNKNOWN";
private byte publicIdIndex = -1;
private String encoding;
private StringBuffer stringTable;
private byte parentBitMask = (byte) 0x40;
// The bit representation 10000000
private byte attributeBitMask = (byte) 0x80;
// The bit representation 01000000
private TokenRepository tokenRepository;
public static WBXMLDecoder getInstance() {
if (instance == null)
instance = new WBXMLDecoder();
return instance;
}
private WBXMLDecoder() {
initialize();
}
private void initialize() {
}
public Document decode(InputStream wbxmlStream) {
this.wbxmlStream = new DataInputStream(wbxmlStream);
try {
xmlDocument =
DocumentBuilderFactory
.newInstance()
.newDocumentBuilder()
.newDocument();
decodeProlog();
decodeBody();
} catch (Exception exp) {
//exp.printStackTrace();
}
return xmlDocument;
}
public int decodeFowChk(InputStream wbxmlStream) {
int ret=0;
this.wbxmlStream = new DataInputStream(wbxmlStream);
try {
xmlDocument =
DocumentBuilderFactory
.newInstance()
.newDocumentBuilder()
.newDocument();
try {
byte version = this.wbxmlStream.readByte();
readPublicID();
//System.out.println(""+publicIdIndex);
byte charset = this.wbxmlStream.readByte(); // to do for mutiple byte
encoding = TransTable.getTable("charsets").code2str(charset);
byte strtblSize = this.wbxmlStream.readByte();
// TODO for multi-byte and negative size
stringTable = new StringBuffer(strtblSize);
for (int i = 0; i < strtblSize; i++)
stringTable.append((char) this.wbxmlStream.readByte());
if (publicIdIndex != -1)
readPublicIDFromStringTable();
// Now initialze the token repository as per the public identifier specified
String publicIDInHex =
PublicIdentifiers.getInstance().getPublicIdentifierValueHex(
publicId);
tokenRepository = TokenRepository.getInstance(publicIDInHex);
}
catch (IOException ex) {
}
decodeBody();
} catch (Exception exp) {
//exp.printStackTrace();
}
return ret;
}
/**
* currently encoding cannot be specifies as DOM does not have any API to access the XML declaration.
* by default utf-16 is used.. If encoding is to be used ...
* xmlDocument.getImplementation().String piData = "version=\"1.0\" encoding=\"" + encoding + "\"";
* ProcessingInstruction xmlDeclaration = xmlDocument.createProcessingInstruction("xml", piData);
* xmlDocument.insertBefore(xmlDeclaration, xmlDocument.getDocumentElement());
**/
private void decodeProlog(){
try {
byte version = wbxmlStream.readByte();
readPublicID();
byte charset = wbxmlStream.readByte(); // to do for mutiple byte
encoding = TransTable.getTable("charsets").code2str(charset);
byte strtblSize = wbxmlStream.readByte();
// TODO for multi-byte and negative size
stringTable = new StringBuffer(strtblSize);
for (int i = 0; i < strtblSize; i++)
stringTable.append((char) wbxmlStream.readByte());
if (publicIdIndex != -1)
readPublicIDFromStringTable();
// Now initialze the token repository as per the public identifier specified
String publicIDInHex =
PublicIdentifiers.getInstance().getPublicIdentifierValueHex(
publicId);
tokenRepository = TokenRepository.getInstance(publicIDInHex);
}
catch (IOException ex) {
}
}
private void readPublicIDFromStringTable() {
char c = 0x0;
int endIndex =
stringTable.toString().indexOf(new String(new char[] { c }), publicIdIndex);
if (endIndex == -1)
publicId = stringTable.substring(publicIdIndex);
else
publicId = stringTable.substring(publicIdIndex, endIndex);
}
private void readPublicID(){
byte[] multipleBytes = new byte[4];
byte nextByte = (byte) 0;
try {
nextByte = wbxmlStream.readByte();
if (nextByte == 0) {
// public id is encoded as string in form:- 0 indexInstringtable
publicIdIndex = wbxmlStream.readByte();
}
else { // public id is encoded in multi-byte integer format(mb_u_int32)
int i = 0;
StringBuffer strBuf = new StringBuffer();
while ( (nextByte & 0x80) == 0x80) { //msb IS 1
String str = Integer.toBinaryString(nextByte & 0x7F);
if (str.length() < 7) {
int zerosToPumpIn = 7 - str.length();
for (int j = 0; j < zerosToPumpIn; j++)
strBuf.append('0');
}
strBuf.append(str);
nextByte = wbxmlStream.readByte();
}
String str = Integer.toBinaryString(nextByte & 0x7F);
if (str.length() < 7) {
int zerosToPumpIn = 7 - str.length();
for (int j = 0; j < zerosToPumpIn; j++)
strBuf.append('0');
}
strBuf.append(str);
int publicIdValue =
Integer.valueOf(strBuf.toString(), 2).intValue();
publicId =
PublicIdentifiers.getInstance().getPublicIdentifier(
publicIdValue);
}
}
catch (IOException ex) {
}
}
private void decodeBody(){
writeRootElement();
}
private void writeRootElement(){
byte maskedTokenValue = (byte) 0;
try {
maskedTokenValue = wbxmlStream.readByte();
}
catch (IOException ex) {
}
byte actualTokenValue = getTokenValue(maskedTokenValue);
String rootElementName = tokenRepository.getTagName(actualTokenValue);
try {
DocumentBuilder builder =
DocumentBuilderFactory.newInstance().newDocumentBuilder();
String systemId =
PublicIdentifiers.getInstance().getSystemIdentifier(publicId);
DocumentType docType =
builder.getDOMImplementation().createDocumentType(
rootElementName,
publicId,
systemId);
xmlDocument =
builder.getDOMImplementation().createDocument(
"",
rootElementName,
docType);
if (hasAttributes(maskedTokenValue))
setAttributes(xmlDocument.getDocumentElement());
if (hasContent(maskedTokenValue))
writeChildElement(xmlDocument.getDocumentElement());
} catch (Exception exp) {
//exp.printStackTrace();
}
}
private void writeChildElement(Element parent) throws IOException {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -