• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Serializer()57     public Serializer() {
58         this(true);
59     }
60 
Serializer(boolean startDocument, boolean _logging)61     public Serializer(boolean startDocument, boolean _logging) {
62         this(true);
63         logging = _logging;
64     }
65 
Serializer(boolean startDocument)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 
log(String str)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 
done()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 
startDocument()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 
checkPendingTag(boolean degenerated)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 
start(int tag)127     public Serializer start(int tag) throws IOException {
128         checkPendingTag(false);
129         pendingTag = tag;
130         depth++;
131         return this;
132     }
133 
end()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 
tag(int t)147     public Serializer tag(int t) throws IOException {
148         start(t);
149         end();
150         return this;
151     }
152 
data(int tag, String value)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
toString()164     public String toString() {
165         return out.toString();
166     }
167 
toByteArray()168     public byte[] toByteArray() {
169         return out.toByteArray();
170     }
171 
text(String text)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 
writeInteger(OutputStream out, int i)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 
writeLiteralString(OutputStream out, String s)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 
writeStringValue(ContentValues cv, String key, int tag)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