Android Open Source - One-Button-App---Android Wbxml Serializer






From Project

Back to project page One-Button-App---Android.

License

The source code is released under:

Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (...

If you think the Android project One-Button-App---Android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/* Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
 */*  w  ww. j av  a2s  .c o m*/
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The  above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE. */

//Contributors: Bogdan Onoiu (Genderal character encoding abstraction and UTF-8 Support)
package org.kxml2.wap;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Vector;

import org.xmlpull.v1.XmlSerializer;
// TODO: make some of the "direct" WBXML token writing methods public??

/**
 * A class for writing WBXML.
 * 
 */

@SuppressWarnings("unchecked")
public class WbxmlSerializer implements XmlSerializer {

  public static final HashMap HEXMAP = new HashMap();

  static {
    HEXMAP.put("0", new Integer(0));
    HEXMAP.put("1", new Integer(1));
    HEXMAP.put("2", new Integer(2));
    HEXMAP.put("3", new Integer(3));
    HEXMAP.put("4", new Integer(4));
    HEXMAP.put("5", new Integer(5));
    HEXMAP.put("6", new Integer(6));
    HEXMAP.put("7", new Integer(7));
    HEXMAP.put("8", new Integer(8));
    HEXMAP.put("9", new Integer(9));
    HEXMAP.put("A", new Integer(10));
    HEXMAP.put("B", new Integer(11));
    HEXMAP.put("C", new Integer(12));
    HEXMAP.put("D", new Integer(13));
    HEXMAP.put("E", new Integer(14));
    HEXMAP.put("F", new Integer(15));
  }
  Hashtable stringTable = new Hashtable();

  OutputStream out;

  ByteArrayOutputStream buf = new ByteArrayOutputStream();
  ByteArrayOutputStream stringTableBuf = new ByteArrayOutputStream();

  String pending;
  int depth;
  String name;
  String namespace;
  Vector attributes = new Vector();

  Hashtable attrStartTable = new Hashtable();
  Hashtable attrValueTable = new Hashtable();
  Hashtable tagTable = new Hashtable();

  private int attrPage;
  private int tagPage;

  private String encoding = null;

  public XmlSerializer attribute(String namespace, String name, String value) {
    attributes.addElement(name);
    attributes.addElement(value);
    return this;
  }

  public void cdsect(String cdsect) throws IOException {
    text(cdsect);
  }

  /* silently ignore comment */

  public void comment(String comment) {
  }

  public void docdecl(String docdecl) {
    throw new RuntimeException("Cannot write docdecl for WBXML");
  }

  public void entityRef(String er) {
    throw new RuntimeException("EntityReference not supported for WBXML");
  }

  public int getDepth() {
    return depth;
  }

  public boolean getFeature(String name) {
    return false;
  }

  public String getNamespace() {
    throw new RuntimeException("NYI");
  }

  public String getName() {
    throw new RuntimeException("NYI");
  }

  public String getPrefix(String nsp, boolean create) {
    throw new RuntimeException("NYI");
  }

  public Object getProperty(String name) {
    return null;
  }

  public void ignorableWhitespace(String sp) {
  }

  public void endDocument() throws IOException {
    writeInt(out, stringTableBuf.size());

    // write StringTable

    out.write(stringTableBuf.toByteArray());

    // write buf

    out.write(buf.toByteArray());

    // ready!

    out.flush();
  }

  /**
   * ATTENTION: flush cannot work since Wbxml documents require need
   * buffering. Thus, this call does nothing.
   */

  public void flush() {
  }

  public void checkPending(boolean degenerated) throws IOException {
    if (pending == null || pending.length() == 0)
      return;

    int len = attributes.size();

    int[] idx = (int[]) this.tagTable.get(pending);
    // if no entry in known table, then add as literal
    if (idx == null) {
      buf.write(len == 0
          ? (degenerated ? Wbxml.LITERAL : Wbxml.LITERAL_C)
          : (degenerated ? Wbxml.LITERAL_A : Wbxml.LITERAL_AC));

      writeStrT(pending);
    } else {
      if (idx[0] != tagPage) {
        tagPage = idx[0];
        buf.write(Wbxml.SWITCH_PAGE);
        buf.write(tagPage);
      }

      buf.write(len == 0
          ? (degenerated ? idx[1] : idx[1] | 64)
          : (degenerated ? idx[1] | 128 : idx[1] | 192));
    }
    // adding attributes if there are some.
    // the orignal processing is not suitable for WV att table,
    // this is a modified one, but i can not promise this will
    // be right.
    for (int i = 0; i < len;) {
      int start = i;

      boolean matchInWhole = false;
      // first try to match the attributes as a whole.
      String k = (String) attributes.elementAt(i);
      String v = (String) attributes.elementAt(++i);
      String attr = k + "=" + v;

      for (Iterator it = attrStartTable.keySet().iterator(); it.hasNext();) {
        String attrInTable = (String) it.next();
        if (attr.toLowerCase().startsWith(attrInTable.toLowerCase())) {
          idx = (int[]) attrStartTable.get(attrInTable);
          // seems no need here, since we only have one
          // attrStartTable.
          // i don't know why the orignal author add this code
          // anywhere,
          // careless copy and paste?
          // if(idx[0] != attrPage){
          // attrPage = idx[0];
          // buf.write(0);
          // buf.write(attrPage);
          // }
          buf.write(idx[1]);
          // add in line string if needed
          if (attr.length() > attrInTable.length()) {
            String strInLine = attr.substring(attrInTable.length());
            buf.write(Wbxml.STR_I);
            writeStrI(buf, strInLine);
          }
          ++i;
          matchInWhole = true;
          break;
        }
      }
      if (!matchInWhole) {
        i = start;

        idx = (int[]) attrStartTable.get(attributes.elementAt(i));
        if (idx == null) {
          buf.write(Wbxml.LITERAL);
          writeStrT((String) attributes.elementAt(i));
        } else {
          if (idx[0] != attrPage) {
            attrPage = idx[0];
            buf.write(0);
            buf.write(attrPage);
          }
          buf.write(idx[1]);
        }
        idx = (int[]) attrValueTable.get(attributes.elementAt(++i));
        if (idx == null) {
          buf.write(Wbxml.STR_I);
          writeStrI(buf, (String) attributes.elementAt(i));
        } else {
          if (idx[0] != attrPage) {
            attrPage = idx[0];
            buf.write(0);
            buf.write(attrPage);
          }
          buf.write(idx[1]);
        }
        ++i;
      }
    }
    if (len > 0)
      buf.write(Wbxml.END);
    pending = null;
    attributes.removeAllElements();
  }

  public void processingInstruction(String pi) {
    throw new RuntimeException("PI NYI");
  }

  public void setFeature(String name, boolean value) {
    throw new IllegalArgumentException("unknown feature " + name);
  }

  public void setOutput(Writer writer) {
    throw new RuntimeException("Wbxml requires an OutputStream!");
  }

  public void setOutput(OutputStream out, String encoding) throws IOException {

    if (encoding != null)
      throw new IllegalArgumentException(
          "encoding not yet supported for WBXML");

    this.out = out;

    buf = new ByteArrayOutputStream();
    stringTableBuf = new ByteArrayOutputStream();

    // ok, write header
  }

  public void setPrefix(String prefix, String nsp) {
    throw new RuntimeException("NYI");
  }

  public void setProperty(String property, Object value) {
    throw new IllegalArgumentException("unknown property " + property);
  }

  public void startDocument(String s, Boolean b) throws IOException {
    out.write(0x03); // version 1.3
    // http://www.openmobilealliance.org/tech/omna/omna-wbxml-public-docid.htm
    out.write(0x01); // unknown or missing public identifier

    // default encoding is UTF-8
    String[] encodings = {"UTF-8", "ISO-8859-1"};
    if (s == null || s.toUpperCase().equals(encodings[0])) {
      encoding = encodings[0];
      out.write(106);
    } else if (true == s.toUpperCase().equals(encodings[1])) {
      encoding = encodings[1];
      out.write(0x04);
    } else {
      throw new UnsupportedEncodingException(s);
    }
  }

  public XmlSerializer startTag(String namespace, String name)
      throws IOException {

    if (namespace != null && !"".equals(namespace))
      throw new RuntimeException("NSP NYI");

    // current = new State(current, prefixMap, name);

    checkPending(false);
    pending = name;
    depth++;

    return this;
  }

  public XmlSerializer text(char[] chars, int start, int len)
      throws IOException {

    checkPending(false);

    buf.write(Wbxml.STR_I);
    writeStrI(buf, new String(chars, start, len));

    return this;
  }

  public XmlSerializer text(String text) throws IOException {

    checkPending(false);

    int[] idx = (int[]) this.attrValueTable.get(text);
    if (idx == null) {
      int value = -1;
      try {
        value = Integer.parseInt(text);
      } catch (NumberFormatException ex) {
        ;
      }

      byte[] stream = buf.toByteArray();
      byte lastByte = stream[stream.length - 1];
      int tag = lastByte & 63;

      if (value > -1
          && ((tagPage == 0x00 && (tag == 0x0B || tag == 0x0F || tag == 0x3C)) || (tagPage == 0x01 && (tag == 0x32 || tag == 0x1C)))) {
        // "Code[0x00, 0x0B]", "ContentSize[0x00, 0x0F]",
        // *"DateTime[0x00, 0x11]", "Validity[0x00, 0x3C]",
        // "TimeToLive[0x01, 0x32]", "KeepAliveTime[0x01, 0x1C]" is
        // integer value and need to
        // be opaque encoded ("*DateTime" is not realized, it is
        // somewhat so complex and can be substitude with inline
        // string according to the conformance document).
        buf.write(Wbxml.OPAQUE);
        byte[] opaqued = opaqueEncode(text);
        buf.write(opaqued.length);
        buf.write(opaqueEncode(text));
      } else {
        buf.write(Wbxml.STR_I);
        writeStrI(buf, text);
      }
    } else {
      buf.write(Wbxml.EXT_T_0);
      buf.write(idx[1]);
    }

    return this;
  }

  /**
   * since I only encode a int value here, so no need to determine the page
   * code and the tag code in the method.
   * 
   * but if it is a full realization, this is a must.
   * 
   * @param v
   * @return
   */
  public byte[] opaqueEncode(String v) {
    String hexString = "00";
    try {
      int iValue = Integer.parseInt(v);
      hexString = Integer.toHexString(iValue);
    } catch (NumberFormatException ex) {
      ;
    }
    if (hexString.length() % 2 != 0)
      hexString = "0" + hexString;
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    for (int i = 0; i < hexString.length(); i = i + 2) {
      baos.write(hex2Byte(hexString.substring(i, i + 2)));
    }
    return baos.toByteArray();
  }

  /**
   * hex is a string with the length of two and holds 2 hex digits(big
   * endian).
   * 
   * @param hexStr
   *            string holds two hex digits.
   * @return int value of the byte
   */
  @SuppressWarnings("unchecked")
  public int hex2Byte(String hexStr) {
    if (hexStr.length() != 2) {
      throw new RuntimeException(
          "only two hex digits are valid, input unvalid");
    }
    hexStr = hexStr.toUpperCase();
    String hexH = hexStr.substring(0, 1);
    String hexL = hexStr.substring(1, 2);
    if (!HEXMAP.keySet().contains(hexH) || !HEXMAP.keySet().contains(hexL)) {
      throw new RuntimeException(
          "unvalid hex digits found, input unvalid");
    }
    int high = ((Integer) HEXMAP.get(hexH)).intValue() << 4;
    int low = ((Integer) HEXMAP.get(hexL)).intValue();
    return (high + low);
  }

  public XmlSerializer endTag(String namespace, String name)
      throws IOException {

    if (pending != null)
      checkPending(true);
    else
      buf.write(Wbxml.END);

    depth--;

    return this;
  }

  /** currently ignored! */

  public void writeLegacy(int type, String data) {
  }

  // ------------- internal methods --------------------------

  static void writeInt(OutputStream out, int i) throws IOException {
    byte[] buf = new byte[5];
    int idx = 0;

    do {
      buf[idx++] = (byte) (i & 0x7f);
      i = i >> 7;
    } while (i != 0);

    while (idx > 1) {
      out.write(buf[--idx] | 0x80);
    }
    out.write(buf[0]);
  }

  void writeStrI(OutputStream out, String s) throws IOException {
    /*
     * below is the orginal implementation,
     * it totally ignores the character set,
     * but write the int unicode value of every
     * single character in the string, which
     * is not suitable here.
    for (int i = 0; i < s.length(); i++) {
            out.write((byte) s.charAt(i));
        }
    */
    byte[] bs = s.getBytes(encoding);
    out.write(bs);
    out.write(0x00);
  }

  void writeStrT(String s) throws IOException {

    Integer idx = (Integer) stringTable.get(s);

    if (idx == null) {
      idx = new Integer(stringTableBuf.size());
      stringTable.put(s, idx);
      writeStrI(stringTableBuf, s);
      stringTableBuf.flush();
    }

    writeInt(buf, idx.intValue());
  }

  /**
   * Sets the tag table for a given page. The first string in the array
   * defines tag 5, the second tag 6 etc.
   */

  @SuppressWarnings("unchecked")
  public void setTagTable(int page, String[] tagTable) {
    if (page < 0 || tagTable.length == 0)
      return;

    for (int i = 0; i < tagTable.length; i++) {
      if (tagTable[i] != null) {
        Object idx = new int[]{page, i + 5};
        this.tagTable.put(tagTable[i], idx);
      }
    }
  }

  /**
   * Sets the attribute start Table for a given page. The first string in the
   * array defines attribute 5, the second attribute 6 etc. Please use the
   * character '=' (without quote!) as delimiter between the attribute name
   * and the (start of the) value
   */
  @SuppressWarnings("unchecked")
  public void setAttrStartTable(int page, String[] attrStartTable) {

    for (int i = 0; i < attrStartTable.length; i++) {
      if (attrStartTable[i] != null) {
        Object idx = new int[]{page, i + 5};
        this.attrStartTable.put(attrStartTable[i], idx);
      }
    }
  }

  /**
   * Sets the attribute value Table for a given page. The first string in the
   * array defines attribute value 0x85, the second attribute value 0x86 etc.
   * 
   * !!!!! no need to add 0x85 to wml attrValueTable now, since I insert 85
   * "null"s to the Wml attribute value table already, and by doing this, the
   * method is compatible with WV attrValueTable.
   */
  @SuppressWarnings("unchecked")
  public void setAttrValueTable(int page, String[] attrValueTable) {
    // clear entries in this.table!
    for (int i = 0; i < attrValueTable.length; i++) {
      if (attrValueTable[i] != null) {
        Object idx = new int[]{page, i};
        this.attrValueTable.put(attrValueTable[i], idx);
      }
    }
  }

}




Java Source Code List

edu.cc.oba.Android_OBAActivity.java
edu.cc.oba.Android_OBAActivity.java
edu.cc.oba.ConnectWithPass.java
edu.cc.oba.ConnectWithPass.java
edu.cc.oba.CopyOfcreateConnection.java
edu.cc.oba.CopyOfcreateConnection.java
edu.cc.oba.ImageDB.java
edu.cc.oba.TestOBA.java
edu.cc.oba.TestOBA.java
edu.cc.oba.chooseImage.java
edu.cc.oba.chooseImage.java
edu.cc.oba.createConnection.java
edu.cc.oba.createConnection.java
edu.cc.oba.mainUITabs.java
edu.cc.oba.mainUITabs.java
edu.cc.oba.oneButtons.java
edu.cc.oba.oneButtons.java
org.apache.http.examples.client.ClientAbortMethod.java
org.apache.http.examples.client.ClientAuthentication.java
org.apache.http.examples.client.ClientChunkEncodedPost.java
org.apache.http.examples.client.ClientConnectionRelease.java
org.apache.http.examples.client.ClientCustomContext.java
org.apache.http.examples.client.ClientCustomSSL.java
org.apache.http.examples.client.ClientEvictExpiredConnections.java
org.apache.http.examples.client.ClientExecuteDirect.java
org.apache.http.examples.client.ClientExecuteProxy.java
org.apache.http.examples.client.ClientExecuteSOCKS.java
org.apache.http.examples.client.ClientFormLogin.java
org.apache.http.examples.client.ClientGZipContentCompression.java
org.apache.http.examples.client.ClientInteractiveAuthentication.java
org.apache.http.examples.client.ClientKerberosAuthentication.java
org.apache.http.examples.client.ClientMultiThreadedExecution.java
org.apache.http.examples.client.ClientPreemptiveBasicAuthentication.java
org.apache.http.examples.client.ClientPreemptiveDigestAuthentication.java
org.apache.http.examples.client.ClientProxyAuthentication.java
org.apache.http.examples.client.ClientWithResponseHandler.java
org.apache.http.examples.conn.ManagerConnectDirect.java
org.apache.http.examples.conn.ManagerConnectProxy.java
org.apache.http.examples.conn.OperatorConnectDirect.java
org.apache.http.examples.conn.OperatorConnectProxy.java
org.apache.http.examples.entity.mime.ClientMultipartFormPost.java
org.kxml2.wap.WbxmlParser.java
org.kxml2.wap.WbxmlSerializer.java
org.kxml2.wap.wml.Wml.java
org.xmlrpc.android.Base64Coder.java
org.xmlrpc.android.IXMLRPCSerializer.java
org.xmlrpc.android.MethodCall.java
org.xmlrpc.android.Tag.java
org.xmlrpc.android.XMLRPCClient.java
org.xmlrpc.android.XMLRPCCommon.java
org.xmlrpc.android.XMLRPCException.java
org.xmlrpc.android.XMLRPCFault.java
org.xmlrpc.android.XMLRPCSerializable.java
org.xmlrpc.android.XMLRPCSerializer.java
org.xmlrpc.android.XMLRPCServer.java