Home | History | Annotate | Download | only in adapter
      1 /* Copyright (c) 2002,2003, Stefan Haustein, Oberhausen, Rhld., Germany
      2  *
      3  * Permission is hereby granted, free of charge, to any person obtaining a copy
      4  * of this software and associated documentation files (the "Software"), to deal
      5  * in the Software without restriction, including without limitation the rights
      6  * to use, copy, modify, merge, publish, distribute, sublicense, and/or
      7  * sell copies of the Software, and to permit persons to whom the Software is
      8  * furnished to do so, subject to the following conditions:
      9  *
     10  * The  above copyright notice and this permission notice shall be included in
     11  * all copies or substantial portions of the Software.
     12  *
     13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     18  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     19  * IN THE SOFTWARE. */
     20 
     21 //Contributors: Jonathan Cox, Bogdan Onoiu, Jerry Tian
     22 //Simplified for Google, Inc. by Marc Blank
     23 
     24 package com.android.exchange.adapter;
     25 
     26 import com.android.exchange.Eas;
     27 import com.android.exchange.utility.FileLogger;
     28 
     29 import android.content.ContentValues;
     30 import android.util.Log;
     31 
     32 import java.io.ByteArrayOutputStream;
     33 import java.io.IOException;
     34 import java.io.OutputStream;
     35 import java.util.Hashtable;
     36 
     37 public class Serializer {
     38 
     39     private static final String TAG = "Serializer";
     40     private boolean logging = false;    // DO NOT CHECK IN WITH THIS TRUE!
     41 
     42     private static final int NOT_PENDING = -1;
     43 
     44     ByteArrayOutputStream out = new ByteArrayOutputStream();
     45     ByteArrayOutputStream buf = new ByteArrayOutputStream();
     46 
     47     String pending;
     48     int pendingTag = NOT_PENDING;
     49     int depth;
     50     String name;
     51     String[] nameStack = new String[20];
     52 
     53     Hashtable<String, Object> tagTable = new Hashtable<String, Object>();
     54 
     55     private int tagPage;
     56 
     57     public Serializer() {
     58         this(true);
     59     }
     60 
     61     public Serializer(boolean startDocument, boolean _logging) {
     62         this(true);
     63         logging = _logging;
     64     }
     65 
     66     public Serializer(boolean startDocument) {
     67         super();
     68         if (startDocument) {
     69             try {
     70                 startDocument();
     71                 //logging = Eas.PARSER_LOG;
     72             } catch (IOException e) {
     73                 // Nothing to be done
     74             }
     75         } else {
     76             out.write(0);
     77         }
     78     }
     79 
     80     void log(String str) {
     81         int cr = str.indexOf('\n');
     82         if (cr > 0) {
     83             str = str.substring(0, cr);
     84         }
     85         Log.v(TAG, str);
     86         if (Eas.FILE_LOG) {
     87             FileLogger.log(TAG, str);
     88         }
     89     }
     90 
     91     public void done() throws IOException {
     92         if (depth != 0) {
     93             throw new IOException("Done received with unclosed tags");
     94         }
     95         writeInteger(out, 0);
     96         out.write(buf.toByteArray());
     97         out.flush();
     98     }
     99 
    100     public void startDocument() throws IOException{
    101         out.write(0x03); // version 1.3
    102         out.write(0x01); // unknown or missing public identifier
    103         out.write(106);
    104     }
    105 
    106     public void checkPendingTag(boolean degenerated) throws IOException {
    107         if (pendingTag == NOT_PENDING)
    108             return;
    109 
    110         int page = pendingTag >> Tags.PAGE_SHIFT;
    111         int tag = pendingTag & Tags.PAGE_MASK;
    112         if (page != tagPage) {
    113             tagPage = page;
    114             buf.write(Wbxml.SWITCH_PAGE);
    115             buf.write(page);
    116         }
    117 
    118         buf.write(degenerated ? tag : tag | 64);
    119         if (logging) {
    120             String name = Tags.pages[page][tag - 5];
    121             nameStack[depth] = name;
    122             log("<" + name + '>');
    123         }
    124         pendingTag = NOT_PENDING;
    125     }
    126 
    127     public Serializer start(int tag) throws IOException {
    128         checkPendingTag(false);
    129         pendingTag = tag;
    130         depth++;
    131         return this;
    132     }
    133 
    134     public Serializer end() throws IOException {
    135         if (pendingTag >= 0) {
    136             checkPendingTag(true);
    137         } else {
    138             buf.write(Wbxml.END);
    139             if (logging) {
    140                 log("</" + nameStack[depth] + '>');
    141             }
    142         }
    143         depth--;
    144         return this;
    145     }
    146 
    147     public Serializer tag(int t) throws IOException {
    148         start(t);
    149         end();
    150         return this;
    151     }
    152 
    153     public Serializer data(int tag, String value) throws IOException {
    154         if (value == null) {
    155             Log.e(TAG, "Writing null data for tag: " + tag);
    156         }
    157         start(tag);
    158         text(value);
    159         end();
    160         return this;
    161     }
    162 
    163     @Override
    164     public String toString() {
    165         return out.toString();
    166     }
    167 
    168     public byte[] toByteArray() {
    169         return out.toByteArray();
    170     }
    171 
    172     public Serializer text(String text) throws IOException {
    173         if (text == null) {
    174             Log.e(TAG, "Writing null text for pending tag: " + pendingTag);
    175         }
    176         checkPendingTag(false);
    177         buf.write(Wbxml.STR_I);
    178         writeLiteralString(buf, text);
    179         if (logging) {
    180             log(text);
    181         }
    182         return this;
    183     }
    184 
    185     void writeInteger(OutputStream out, int i) throws IOException {
    186         byte[] buf = new byte[5];
    187         int idx = 0;
    188 
    189         do {
    190             buf[idx++] = (byte) (i & 0x7f);
    191             i = i >> 7;
    192         } while (i != 0);
    193 
    194         while (idx > 1) {
    195             out.write(buf[--idx] | 0x80);
    196         }
    197         out.write(buf[0]);
    198         if (logging) {
    199             log(Integer.toString(i));
    200         }
    201     }
    202 
    203     void writeLiteralString(OutputStream out, String s) throws IOException {
    204         byte[] data = s.getBytes("UTF-8");
    205         out.write(data);
    206         out.write(0);
    207     }
    208 
    209     void writeStringValue (ContentValues cv, String key, int tag) throws IOException {
    210         String value = cv.getAsString(key);
    211         if (value != null && value.length() > 0) {
    212             data(tag, value);
    213         }
    214     }
    215 }
    216