KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > quercus > lib > UnserializeReader


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.quercus.lib;
31
32 import com.caucho.quercus.env.*;
33 import com.caucho.util.L10N;
34 import com.caucho.util.LruCache;
35
36 import java.io.IOException JavaDoc;
37 import java.util.logging.Logger JavaDoc;
38
39 public final class UnserializeReader {
40   private static final L10N L = new L10N(UnserializeReader.class);
41   private static final Logger JavaDoc log
42     = Logger.getLogger(UnserializeReader.class.getName());
43
44   private static final LruCache<StringKey,StringValue> _keyCache
45     = new LruCache<StringKey,StringValue>(4096);
46
47   private final char []_buffer;
48   private final int _length;
49
50   private int _index;
51   private StringKey _key = new StringKey();
52
53   public UnserializeReader(StringValue s)
54   {
55     _buffer = s.toCharArray();
56     _length = s.length();
57   }
58
59   public UnserializeReader(String JavaDoc s)
60   {
61     _buffer = s.toCharArray();
62     _length = s.length();
63   }
64
65   public Value unserialize(Env env)
66     throws IOException JavaDoc
67   {
68     int ch = read();
69
70     switch (ch) {
71     case 'b':
72       {
73         expect(':');
74         long v = readInt();
75         expect(';');
76
77         return v == 0 ? BooleanValue.FALSE : BooleanValue.TRUE;
78       }
79
80     case 's':
81       {
82         expect(':');
83         int len = (int) readInt();
84         expect(':');
85         expect('"');
86
87         StringValue s = readStringValue(len);
88
89         expect('"');
90         expect(';');
91
92         return s;
93       }
94
95     case 'i':
96       {
97         expect(':');
98
99         long value = readInt();
100
101         expect(';');
102
103         return LongValue.create(value);
104       }
105
106     case 'd':
107       {
108         expect(':');
109
110         StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
111         for (ch = read(); ch >= 0 && ch != ';'; ch = read()) {
112           sb.append((char) ch);
113         }
114
115         if (ch != ';')
116           throw new IOException JavaDoc(L.l("expected ';'"));
117
118         return new DoubleValue(Double.parseDouble(sb.toString()));
119       }
120
121     case 'a':
122       {
123         expect(':');
124         long len = readInt();
125         expect(':');
126         expect('{');
127
128         ArrayValue array = new ArrayValueImpl((int) len);
129         for (int i = 0; i < len; i++) {
130           Value key = unserializeKey(env);
131           Value value = unserialize(env);
132
133           array.put(key, value);
134         }
135
136         expect('}');
137
138         return array;
139       }
140
141     case 'O':
142       {
143         expect(':');
144         int len = (int) readInt();
145         expect(':');
146         expect('"');
147
148         String JavaDoc className = readString(len);
149
150         expect('"');
151         expect(':');
152         long count = readInt();
153         expect(':');
154         expect('{');
155
156     QuercusClass qClass = env.findClass(className);
157     Value obj;
158
159     if (qClass != null)
160       obj = qClass.newInstance(env);
161     else {
162       log.fine(L.l("{0} is an undefined class in unserialize",
163                className));
164       
165       obj = env.createObject();
166       obj.putField(env,
167                "__Quercus_Incomplete_Class_name",
168                new StringValueImpl(className));
169     }
170     
171         for (int i = 0; i < count; i++) {
172           String JavaDoc key = unserializeString();
173           Value value = unserialize(env);
174
175           obj.putField(env, key, value);
176         }
177
178         expect('}');
179
180         return obj;
181       }
182
183     case 'N':
184       {
185         expect(';');
186
187         return NullValue.NULL;
188       }
189
190     default:
191       return BooleanValue.FALSE;
192     }
193   }
194
195   public Value unserializeKey(Env env)
196     throws IOException JavaDoc
197   {
198     int ch = read();
199
200     switch (ch) {
201     case 's':
202       {
203         expect(':');
204         int len = (int) readInt();
205         expect(':');
206         expect('"');
207
208         StringValue v;
209
210         if (len < 32) {
211           _key.init(_buffer, _index, len);
212
213           v = _keyCache.get(_key);
214
215           if (v != null) {
216             _index += len;
217           }
218           else {
219             StringKey key = new StringKey(_buffer, _index, len);
220
221             String JavaDoc s = readString(len);
222             v = new InternStringValue(s);
223
224             _keyCache.put(key, v);
225           }
226         }
227         else {
228           String JavaDoc s = readString(len);
229           v = new StringValueImpl(s);
230         }
231
232         expect('"');
233         expect(';');
234
235         return v;
236       }
237
238     case 'i':
239       {
240         expect(':');
241
242         long value = readInt();
243
244         expect(';');
245
246         return LongValue.create(value);
247       }
248
249     default:
250       return BooleanValue.FALSE;
251     }
252   }
253
254   private String JavaDoc unserializeString()
255     throws IOException JavaDoc
256   {
257     expect('s');
258     expect(':');
259     int len = (int) readInt();
260     expect(':');
261     expect('"');
262
263     String JavaDoc s = readString(len);
264
265     expect('"');
266     expect(';');
267
268     return s;
269   }
270
271   public final void expect(int expectCh)
272     throws IOException JavaDoc
273   {
274     if (_length <= _index)
275       throw new IOException JavaDoc(L.l("expected '{0}' at end of string",
276                                 String.valueOf((char) expectCh)));
277
278     int ch = _buffer[_index++];
279
280     if (ch != expectCh) {
281       throw new IOException JavaDoc(L.l("expected '{0}' at '{1}'",
282                                 String.valueOf((char) expectCh),
283                                 String.valueOf((char) ch)));
284     }
285   }
286
287   public final long readInt()
288   {
289     int ch = read();
290
291     long sign = 1;
292     long value = 0;
293
294     if (ch == '-') {
295       sign = -1;
296       ch = read();
297     }
298     else if (ch == '+') {
299       ch = read();
300     }
301
302     for (; '0' <= ch && ch <= '9'; ch = read()) {
303       value = 10 * value + ch - '0';
304     }
305
306     unread();
307
308     return sign * value;
309   }
310
311   public final String JavaDoc readString(int len)
312   {
313     String JavaDoc s = new String JavaDoc(_buffer, _index, len);
314
315     _index += len;
316
317     return s;
318   }
319
320   public final StringValue readStringValue(int len)
321   {
322     StringValue s = new StringBuilderValue(_buffer, _index, len, true);
323
324     _index += len;
325
326     return s;
327   }
328
329   public final int read()
330   {
331     if (_index < _length)
332       return _buffer[_index++];
333     else
334       return -1;
335   }
336
337   public final int read(char []buffer, int offset, int length)
338   {
339     System.arraycopy(_buffer, _index, buffer, offset, length);
340
341     _index += length;
342
343     return length;
344   }
345
346   public final void unread()
347   {
348     _index--;
349   }
350
351   public final static class StringKey {
352     char []_buffer;
353     int _offset;
354     int _length;
355
356     StringKey()
357     {
358     }
359
360     StringKey(char []buffer, int offset, int length)
361     {
362       _buffer = new char[length];
363       System.arraycopy(buffer, offset, _buffer, 0, length);
364       _offset = 0;
365       _length = length;
366     }
367
368     void init(char []buffer, int offset, int length)
369     {
370       _buffer = buffer;
371       _offset = offset;
372       _length = length;
373     }
374
375     public int hashCode()
376     {
377       char []buffer = _buffer;
378       int offset = _offset;
379       int end = offset + _length;
380       int hash = 17;
381
382       for (; offset < end; offset++)
383         hash = 65521 * hash + buffer[offset];
384
385       return hash;
386     }
387
388     public boolean equals(Object JavaDoc o)
389     {
390       if (! (o instanceof StringKey))
391         return false;
392
393       StringKey key = (StringKey) o;
394
395       int length = _length;
396
397       if (length != key._length)
398         return false;
399
400       char []aBuf = _buffer;
401       char []bBuf = key._buffer;
402
403       int aOffset = _offset;
404       int bOffset = key._offset;
405
406       int aEnd = aOffset + length;
407
408       while (aOffset < aEnd) {
409         if (aBuf[aOffset++] != bBuf[bOffset++])
410           return false;
411       }
412
413       return true;
414     }
415   }
416 }
417
418
419
Popular Tags