KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > hessian > micro > MicroHessianInput


1 /*
2  * Copyright (c) 2001-2006 Caucho Technology, Inc. All rights reserved.
3  *
4  * The Apache Software License, Version 1.1
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  *
18  * 3. The end-user documentation included with the redistribution, if
19  * any, must include the following acknowlegement:
20  * "This product includes software developed by the
21  * Caucho Technology (http://www.caucho.com/)."
22  * Alternately, this acknowlegement may appear in the software itself,
23  * if and wherever such third-party acknowlegements normally appear.
24  *
25  * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
26  * endorse or promote products derived from this software without prior
27  * written permission. For written permission, please contact
28  * info@caucho.com.
29  *
30  * 5. Products derived from this software may not be called "Resin"
31  * nor may "Resin" appear in their names without prior written
32  * permission of Caucho Technology.
33  *
34  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
35  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
36  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37  * DISCLAIMED. IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
38  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
39  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
40  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
41  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
42  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
43  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
44  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45  *
46  * @author Scott Ferguson
47  */

48
49 package com.caucho.hessian.micro;
50
51 import java.io.ByteArrayOutputStream JavaDoc;
52 import java.io.IOException JavaDoc;
53 import java.io.InputStream JavaDoc;
54 import java.util.Date JavaDoc;
55
56 /**
57  * Input stream for Hessian requests, compatible with microedition
58  * Java. It only uses classes and types available to J2ME. In
59  * particular, it does not have any support for the <double> type.
60  *
61  * <p>MicroHessianInput does not depend on any classes other than
62  * in J2ME, so it can be extracted independently into a smaller package.
63  *
64  * <p>MicroHessianInput is unbuffered, so any client needs to provide
65  * its own buffering.
66  *
67  * <pre>
68  * InputStream is = ...; // from http connection
69  * MicroHessianInput in = new MicroHessianInput(is);
70  * String value;
71  *
72  * in.startReply(); // read reply header
73  * value = in.readString(); // read string value
74  * in.completeReply(); // read reply footer
75  * </pre>
76  */

77 public class MicroHessianInput {
78   protected InputStream JavaDoc is;
79   /**
80    * Creates a new Hessian input stream, initialized with an
81    * underlying input stream.
82    *
83    * @param is the underlying input stream.
84    */

85   public MicroHessianInput(InputStream JavaDoc is)
86   {
87     init(is);
88   }
89
90   /**
91    * Creates an uninitialized Hessian input stream.
92    */

93   public MicroHessianInput()
94   {
95   }
96
97   /**
98    * Initialize the hessian stream with the underlying input stream.
99    */

100   public void init(InputStream JavaDoc is)
101   {
102     this.is = is;
103   }
104
105   /**
106    * Starts reading the reply
107    *
108    * <p>A successful completion will have a single value:
109    *
110    * <pre>
111    * r x01 x00
112    * </pre>
113    */

114   public void startReply()
115     throws IOException JavaDoc
116   {
117     int tag = is.read();
118     
119     if (tag != 'r')
120       protocolException("expected hessian reply");
121
122     int major = is.read();
123     int minor = is.read();
124   }
125
126   /**
127    * Completes reading the call
128    *
129    * <p>A successful completion will have a single value:
130    *
131    * <pre>
132    * z
133    * </pre>
134    */

135   public void completeReply()
136     throws IOException JavaDoc
137   {
138     int tag = is.read();
139     
140     if (tag != 'z')
141       protocolException("expected end of reply");
142   }
143
144   /**
145    * Reads a boolean
146    *
147    * <pre>
148    * T
149    * F
150    * </pre>
151    */

152   public boolean readBoolean()
153     throws IOException JavaDoc
154   {
155     int tag = is.read();
156
157     switch (tag) {
158     case 'T': return true;
159     case 'F': return false;
160     default:
161       throw expect("boolean", tag);
162     }
163   }
164
165   /**
166    * Reads an integer
167    *
168    * <pre>
169    * I b32 b24 b16 b8
170    * </pre>
171    */

172   public int readInt()
173     throws IOException JavaDoc
174   {
175     int tag = is.read();
176
177     if (tag != 'I')
178       throw expect("integer", tag);
179
180     int b32 = is.read();
181     int b24 = is.read();
182     int b16 = is.read();
183     int b8 = is.read();
184
185     return (b32 << 24) + (b24 << 16) + (b16 << 8) + b8;
186   }
187
188   /**
189    * Reads a long
190    *
191    * <pre>
192    * L b64 b56 b48 b40 b32 b24 b16 b8
193    * </pre>
194    */

195   public long readLong()
196     throws IOException JavaDoc
197   {
198     int tag = is.read();
199
200     if (tag != 'L')
201       throw protocolException("expected long");
202
203     long b64 = is.read();
204     long b56 = is.read();
205     long b48 = is.read();
206     long b40 = is.read();
207     long b32 = is.read();
208     long b24 = is.read();
209     long b16 = is.read();
210     long b8 = is.read();
211
212     return ((b64 << 56) +
213             (b56 << 48) +
214             (b48 << 40) +
215             (b40 << 32) +
216             (b32 << 24) +
217             (b24 << 16) +
218             (b16 << 8) +
219             b8);
220   }
221
222   /**
223    * Reads a date.
224    *
225    * <pre>
226    * T b64 b56 b48 b40 b32 b24 b16 b8
227    * </pre>
228    */

229   public long readUTCDate()
230     throws IOException JavaDoc
231   {
232     int tag = is.read();
233
234     if (tag != 'd')
235       throw protocolException("expected date");
236
237     long b64 = is.read();
238     long b56 = is.read();
239     long b48 = is.read();
240     long b40 = is.read();
241     long b32 = is.read();
242     long b24 = is.read();
243     long b16 = is.read();
244     long b8 = is.read();
245
246     return ((b64 << 56) +
247             (b56 << 48) +
248             (b48 << 40) +
249             (b40 << 32) +
250             (b32 << 24) +
251             (b24 << 16) +
252             (b16 << 8) +
253             b8);
254   }
255
256   /**
257    * Reads a string
258    *
259    * <pre>
260    * S b16 b8 string value
261    * </pre>
262    */

263   public String JavaDoc readString()
264     throws IOException JavaDoc
265   {
266     int tag = is.read();
267
268     if (tag == 'N')
269       return null;
270
271     if (tag != 'S')
272       throw expect("string", tag);
273
274     int b16 = is.read();
275     int b8 = is.read();
276
277     int len = (b16 << 8) + b8;
278
279     return readStringImpl(len);
280   }
281
282   /**
283    * Reads a byte array
284    *
285    * <pre>
286    * B b16 b8 data value
287    * </pre>
288    */

289   public byte []readBytes()
290     throws IOException JavaDoc
291   {
292     int tag = is.read();
293
294     if (tag == 'N')
295       return null;
296
297     if (tag != 'B')
298       throw expect("bytes", tag);
299
300     int b16 = is.read();
301     int b8 = is.read();
302
303     int len = (b16 << 8) + b8;
304
305     ByteArrayOutputStream JavaDoc bos = new ByteArrayOutputStream JavaDoc();
306
307     for (int i = 0; i < len; i++)
308       bos.write(is.read());
309
310     return bos.toByteArray();
311   }
312
313   /**
314    * Reads an arbitrary object the input stream.
315    */

316   public Object JavaDoc readObject(Class JavaDoc expectedClass)
317     throws IOException JavaDoc
318   {
319     int tag = is.read();
320
321     switch (tag) {
322     case 'N':
323       return null;
324       
325     case 'T':
326       return new Boolean JavaDoc(true);
327       
328     case 'F':
329       return new Boolean JavaDoc(false);
330       
331     case 'I': {
332       int b32 = is.read();
333       int b24 = is.read();
334       int b16 = is.read();
335       int b8 = is.read();
336
337       return new Integer JavaDoc((b32 << 24) + (b24 << 16) + (b16 << 8) + b8);
338     }
339     
340     case 'L': {
341       long b64 = is.read();
342       long b56 = is.read();
343       long b48 = is.read();
344       long b40 = is.read();
345       long b32 = is.read();
346       long b24 = is.read();
347       long b16 = is.read();
348       long b8 = is.read();
349
350       return new Long JavaDoc((b64 << 56) +
351                       (b56 << 48) +
352                       (b48 << 40) +
353                       (b40 << 32) +
354                       (b32 << 24) +
355                       (b24 << 16) +
356                       (b16 << 8) +
357                       b8);
358     }
359     
360     case 'd': {
361       long b64 = is.read();
362       long b56 = is.read();
363       long b48 = is.read();
364       long b40 = is.read();
365       long b32 = is.read();
366       long b24 = is.read();
367       long b16 = is.read();
368       long b8 = is.read();
369
370       return new Date JavaDoc((b64 << 56) +
371                       (b56 << 48) +
372                       (b48 << 40) +
373                       (b40 << 32) +
374                       (b32 << 24) +
375                       (b24 << 16) +
376                       (b16 << 8) +
377                       b8);
378     }
379     
380     case 'S':
381     case 'X': {
382       int b16 = is.read();
383       int b8 = is.read();
384
385       int len = (b16 << 8) + b8;
386
387       return readStringImpl(len);
388     }
389     
390     case 'B': {
391       if (tag != 'B')
392         throw expect("bytes", tag);
393
394       int b16 = is.read();
395       int b8 = is.read();
396
397       int len = (b16 << 8) + b8;
398
399       ByteArrayOutputStream JavaDoc bos = new ByteArrayOutputStream JavaDoc();
400
401       for (int i = 0; i < len; i++)
402         bos.write(is.read());
403
404       return bos.toByteArray();
405     }
406     default:
407       throw new IOException JavaDoc("unknown code:" + (char) tag);
408     }
409   }
410
411   /**
412    * Reads a string from the underlying stream.
413    */

414   protected String JavaDoc readStringImpl(int length)
415     throws IOException JavaDoc
416   {
417     StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
418     
419     for (int i = 0; i < length; i++) {
420       int ch = is.read();
421
422       if (ch < 0x80)
423         sb.append((char) ch);
424       else if ((ch & 0xe0) == 0xc0) {
425         int ch1 = is.read();
426         int v = ((ch & 0x1f) << 6) + (ch1 & 0x3f);
427
428         sb.append((char) v);
429       }
430       else if ((ch & 0xf0) == 0xe0) {
431         int ch1 = is.read();
432         int ch2 = is.read();
433         int v = ((ch & 0x0f) << 12) + ((ch1 & 0x3f) << 6) + (ch2 & 0x3f);
434
435         sb.append((char) v);
436       }
437       else
438         throw new IOException JavaDoc("bad utf-8 encoding");
439     }
440
441     return sb.toString();
442   }
443
444   protected IOException JavaDoc expect(String JavaDoc expect, int ch)
445   {
446     if (ch < 0)
447       return protocolException("expected " + expect + " at end of file");
448     else
449       return protocolException("expected " + expect + " at " + (char) ch);
450   }
451   
452   protected IOException JavaDoc protocolException(String JavaDoc message)
453   {
454     return new IOException JavaDoc(message);
455   }
456 }
457
Popular Tags