KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > burlap > io > BurlapOutput


1 /*
2  * Copyright (c) 2001-2004 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 "Burlap", "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.burlap.io;
50
51 import com.caucho.hessian.io.Serializer;
52 import com.caucho.hessian.io.SerializerFactory;
53
54 import java.io.IOException JavaDoc;
55 import java.io.OutputStream JavaDoc;
56 import java.util.Calendar JavaDoc;
57 import java.util.Date JavaDoc;
58 import java.util.IdentityHashMap JavaDoc;
59 import java.util.TimeZone JavaDoc;
60
61 /**
62  * Output stream for Burlap requests, compatible with microedition
63  * Java. It only uses classes and types available in JDK.
64  *
65  * <p>Since BurlapOutput does not depend on any classes other than
66  * in the JDK, it can be extracted independently into a smaller package.
67  *
68  * <p>BurlapOutput is unbuffered, so any client needs to provide
69  * its own buffering.
70  *
71  * <pre>
72  * OutputStream os = ...; // from http connection
73  * BurlapOutput out = new BurlapOutput(os);
74  * String value;
75  *
76  * out.startCall("hello"); // start hello call
77  * out.writeString("arg1"); // write a string argument
78  * out.completeCall(); // complete the call
79  * </pre>
80  */

81 public class BurlapOutput extends AbstractBurlapOutput {
82   // the output stream
83
protected OutputStream JavaDoc os;
84   // map of references
85
private IdentityHashMap JavaDoc _refs;
86
87   private Date JavaDoc date;
88   private Calendar JavaDoc utcCalendar;
89   private Calendar JavaDoc localCalendar;
90   /**
91    * Creates a new Burlap output stream, initialized with an
92    * underlying output stream.
93    *
94    * @param os the underlying output stream.
95    */

96   public BurlapOutput(OutputStream JavaDoc os)
97   {
98     init(os);
99   }
100
101   /**
102    * Creates an uninitialized Burlap output stream.
103    */

104   public BurlapOutput()
105   {
106   }
107
108   /**
109    * Initializes the output
110    */

111   public void init(OutputStream JavaDoc os)
112   {
113     this.os = os;
114
115     _refs = null;
116
117     if (_serializerFactory == null)
118       _serializerFactory = new SerializerFactory();
119   }
120
121   /**
122    * Writes a complete method call.
123    */

124   public void call(String JavaDoc method, Object JavaDoc []args)
125     throws IOException JavaDoc
126   {
127     startCall(method);
128     
129     if (args != null) {
130       for (int i = 0; i < args.length; i++)
131         writeObject(args[i]);
132     }
133     
134     completeCall();
135   }
136
137   /**
138    * Starts the method call. Clients would use <code>startCall</code>
139    * instead of <code>call</code> if they wanted finer control over
140    * writing the arguments, or needed to write headers.
141    *
142    * <code><pre>
143    * &lt;burlap:call>
144    * &lt;method>method-name&lt;/method>
145    * </pre></code>
146    *
147    * @param method the method name to call.
148    */

149   public void startCall(String JavaDoc method)
150     throws IOException JavaDoc
151   {
152     print("<burlap:call><method>");
153     print(method);
154     print("</method>");
155   }
156
157   /**
158    * Starts the method call. Clients would use <code>startCall</code>
159    * instead of <code>call</code> if they wanted finer control over
160    * writing the arguments, or needed to write headers.
161    *
162    * <code><pre>
163    * &lt;method>method-name&lt;/method>
164    * </pre></code>
165    *
166    * @param method the method name to call.
167    */

168   public void startCall()
169     throws IOException JavaDoc
170   {
171     print("<burlap:call>");
172   }
173
174   /**
175    * Writes the method for a call.
176    *
177    * <code><pre>
178    * &lt;method>value&lt;/method>
179    * </pre></code>
180    *
181    * @param method the method name to call.
182    */

183   public void writeMethod(String JavaDoc method)
184     throws IOException JavaDoc
185   {
186     print("<method>");
187     print(method);
188     print("</method>");
189   }
190   
191
192   /**
193    * Completes.
194    *
195    * <code><pre>
196    * &lt;/burlap:call>
197    * </pre></code>
198    */

199   public void completeCall()
200     throws IOException JavaDoc
201   {
202     print("</burlap:call>");
203   }
204
205   /**
206    * Starts the reply
207    *
208    * <p>A successful completion will have a single value:
209    *
210    * <pre>
211    * r
212    * </pre>
213    */

214   public void startReply()
215     throws IOException JavaDoc
216   {
217     print("<burlap:reply>");
218   }
219
220   /**
221    * Completes reading the reply
222    *
223    * <p>A successful completion will have a single value:
224    *
225    * <pre>
226    * &lt;/burlap:reply>
227    * </pre>
228    */

229   public void completeReply()
230     throws IOException JavaDoc
231   {
232     print("</burlap:reply>");
233   }
234
235   /**
236    * Writes a header name. The header value must immediately follow.
237    *
238    * <code><pre>
239    * &lt;header>foo&lt;/header>&lt;int>value&lt;/int>
240    * </pre></code>
241    */

242   public void writeHeader(String JavaDoc name)
243     throws IOException JavaDoc
244   {
245     print("<header>");
246     printString(name);
247     print("</header>");
248   }
249
250   /**
251    * Writes a fault. The fault will be written
252    * as a descriptive string followed by an object:
253    *
254    * <code><pre>
255    * &lt;fault>
256    * &lt;string>code
257    * &lt;string>the fault code
258    *
259    * &lt;string>message
260    * &lt;string>the fault mesage
261    *
262    * &lt;string>detail
263    * &lt;map>t\x00\xnnjavax.ejb.FinderException
264    * ...
265    * &lt;/map>
266    * &lt;/fault>
267    * </pre></code>
268    *
269    * @param code the fault code, a three digit
270    */

271   public void writeFault(String JavaDoc code, String JavaDoc message, Object JavaDoc detail)
272     throws IOException JavaDoc
273   {
274     print("<fault>");
275     writeString("code");
276     writeString(code);
277
278     writeString("message");
279     writeString(message);
280
281     if (detail != null) {
282       writeString("detail");
283       writeObject(detail);
284     }
285     print("</fault>");
286   }
287
288   /**
289    * Writes any object to the output stream.
290    */

291   public void writeObject(Object JavaDoc object)
292     throws IOException JavaDoc
293   {
294     if (object == null) {
295       writeNull();
296       return;
297     }
298
299     Serializer serializer;
300
301     serializer = _serializerFactory.getSerializer(object.getClass());
302
303     serializer.writeObject(object, this);
304   }
305
306   /**
307    * Writes the list header to the stream. List writers will call
308    * <code>writeListBegin</code> followed by the list contents and then
309    * call <code>writeListEnd</code>.
310    *
311    * <code><pre>
312    * &lt;list>
313    * &lt;type>java.util.ArrayList&lt;/type>
314    * &lt;length>3&lt;/length>
315    * &lt;int>1&lt;/int>
316    * &lt;int>2&lt;/int>
317    * &lt;int>3&lt;/int>
318    * &lt;/list>
319    * </pre></code>
320    */

321   public boolean writeListBegin(int length, String JavaDoc type)
322     throws IOException JavaDoc
323   {
324     print("<list><type>");
325     
326     if (type != null)
327       print(type);
328     
329     print("</type><length>");
330     print(length);
331     print("</length>");
332
333     return true;
334   }
335
336   /**
337    * Writes the tail of the list to the stream.
338    */

339   public void writeListEnd()
340     throws IOException JavaDoc
341   {
342     print("</list>");
343   }
344
345   /**
346    * Writes the map header to the stream. Map writers will call
347    * <code>writeMapBegin</code> followed by the map contents and then
348    * call <code>writeMapEnd</code>.
349    *
350    * <code><pre>
351    * &lt;map>
352    * &lt;type>type&lt;/type>
353    * (&lt;key> &lt;value>)*
354    * &lt;/map>
355    * </pre></code>
356    */

357   public void writeMapBegin(String JavaDoc type)
358     throws IOException JavaDoc
359   {
360     print("<map><type>");
361     if (type != null)
362       print(type);
363     
364     print("</type>");
365   }
366
367   /**
368    * Writes the tail of the map to the stream.
369    */

370   public void writeMapEnd()
371     throws IOException JavaDoc
372   {
373     print("</map>");
374   }
375
376   /**
377    * Writes a remote object reference to the stream. The type is the
378    * type of the remote interface.
379    *
380    * <code><pre>
381    * &lt;remote>
382    * &lt;type>test.account.Account&lt;/type>
383    * &lt;string>http://caucho.com/foo;ejbid=bar&lt;/string>
384    * &lt;/remote>
385    * </pre></code>
386    */

387   public void writeRemote(String JavaDoc type, String JavaDoc url)
388     throws IOException JavaDoc
389   {
390     print("<remote><type>");
391     print(type);
392     print("</type><string>");
393     print(url);
394     print("</string></remote>");
395   }
396
397   /**
398    * Writes a boolean value to the stream. The boolean will be written
399    * with the following syntax:
400    *
401    * <code><pre>
402    * &lt;boolean>0&lt;/boolean>
403    * &lt;boolean>1&lt;/boolean>
404    * </pre></code>
405    *
406    * @param value the boolean value to write.
407    */

408   public void writeBoolean(boolean value)
409     throws IOException JavaDoc
410   {
411     if (value)
412       print("<boolean>1</boolean>");
413     else
414       print("<boolean>0</boolean>");
415   }
416
417   /**
418    * Writes an integer value to the stream. The integer will be written
419    * with the following syntax:
420    *
421    * <code><pre>
422    * &lt;int>int value&lt;/int>
423    * </pre></code>
424    *
425    * @param value the integer value to write.
426    */

427   public void writeInt(int value)
428     throws IOException JavaDoc
429   {
430     print("<int>");
431     print(value);
432     print("</int>");
433   }
434
435   /**
436    * Writes a long value to the stream. The long will be written
437    * with the following syntax:
438    *
439    * <code><pre>
440    * &lt;long>int value&lt;/long>
441    * </pre></code>
442    *
443    * @param value the long value to write.
444    */

445   public void writeLong(long value)
446     throws IOException JavaDoc
447   {
448     print("<long>");
449     print(value);
450     print("</long>");
451   }
452
453   /**
454    * Writes a double value to the stream. The double will be written
455    * with the following syntax:
456    *
457    * <code><pre>
458    * &lt;double>value&lt;/double>
459    * </pre></code>
460    *
461    * @param value the double value to write.
462    */

463   public void writeDouble(double value)
464     throws IOException JavaDoc
465   {
466     print("<double>");
467     print(value);
468     print("</double>");
469   }
470
471   /**
472    * Writes a date to the stream.
473    *
474    * <code><pre>
475    * &lt;date>iso8901&lt;/date>
476    * </pre></code>
477    *
478    * @param time the date in milliseconds from the epoch in UTC
479    */

480   public void writeUTCDate(long time)
481     throws IOException JavaDoc
482   {
483     print("<date>");
484     if (utcCalendar == null) {
485       utcCalendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
486       date = new Date JavaDoc();
487     }
488
489     date.setTime(time);
490     utcCalendar.setTime(date);
491
492     printDate(utcCalendar);
493     print("</date>");
494   }
495
496   /**
497    * Writes a null value to the stream.
498    * The null will be written with the following syntax
499    *
500    * <code><pre>
501    * &lt;null>&lt;/null>
502    * </pre></code>
503    *
504    * @param value the string value to write.
505    */

506   public void writeNull()
507     throws IOException JavaDoc
508   {
509     print("<null></null>");
510   }
511
512   /**
513    * Writes a string value to the stream using UTF-8 encoding.
514    * The string will be written with the following syntax:
515    *
516    * <code><pre>
517    * &lt;string>string-value&lt;/string>
518    * </pre></code>
519    *
520    * If the value is null, it will be written as
521    *
522    * <code><pre>
523    * &lt;null>&lt;/null>
524    * </pre></code>
525    *
526    * @param value the string value to write.
527    */

528   public void writeString(String JavaDoc value)
529     throws IOException JavaDoc
530   {
531     if (value == null) {
532       print("<null></null>");
533     }
534     else {
535       print("<string>");
536       printString(value);
537       print("</string>");
538     }
539   }
540
541   /**
542    * Writes a string value to the stream using UTF-8 encoding.
543    * The string will be written with the following syntax:
544    *
545    * <code><pre>
546    * S b16 b8 string-value
547    * </pre></code>
548    *
549    * If the value is null, it will be written as
550    *
551    * <code><pre>
552    * N
553    * </pre></code>
554    *
555    * @param value the string value to write.
556    */

557   public void writeString(char []buffer, int offset, int length)
558     throws IOException JavaDoc
559   {
560     if (buffer == null) {
561       print("<null></null>");
562     }
563     else {
564       print("<string>");
565       printString(buffer, offset, length);
566       print("</string>");
567     }
568   }
569
570   /**
571    * Writes a byte array to the stream.
572    * The array will be written with the following syntax:
573    *
574    * <code><pre>
575    * &lt;base64>bytes&lt;/base64>
576    * </pre></code>
577    *
578    * If the value is null, it will be written as
579    *
580    * <code><pre>
581    * &lt;null>&lt;/null>
582    * </pre></code>
583    *
584    * @param value the string value to write.
585    */

586   public void writeBytes(byte []buffer)
587     throws IOException JavaDoc
588   {
589     if (buffer == null)
590       print("<null></null>");
591     else
592       writeBytes(buffer, 0, buffer.length);
593   }
594   /**
595    * Writes a byte array to the stream.
596    * The array will be written with the following syntax:
597    *
598    * <code><pre>
599    * &lt;base64>bytes&lt;/base64>
600    * </pre></code>
601    *
602    * If the value is null, it will be written as
603    *
604    * <code><pre>
605    * &lt;null>&lt;/null>
606    * </pre></code>
607    *
608    * @param value the string value to write.
609    */

610   public void writeBytes(byte []buffer, int offset, int length)
611     throws IOException JavaDoc
612   {
613     if (buffer == null) {
614       print("<null></null>");
615     }
616     else {
617       print("<base64>");
618
619       int i = 0;
620       for (; i + 2 < length; i += 3) {
621         if (i != 0 && (i & 0x3f) == 0)
622           print('\n');
623
624         int v = (((buffer[offset + i] & 0xff) << 16) +
625                  ((buffer[offset + i + 1] & 0xff) << 8) +
626                  (buffer[offset + i + 2] & 0xff));
627
628         print(encode(v >> 18));
629         print(encode(v >> 12));
630         print(encode(v >> 6));
631         print(encode(v));
632       }
633
634       if (i + 1 < length) {
635         int v = (((buffer[offset + i] & 0xff) << 8) +
636                  (buffer[offset + i + 1] & 0xff));
637
638         print(encode(v >> 10));
639         print(encode(v >> 4));
640         print(encode(v << 2));
641         print('=');
642       }
643       else if (i < length) {
644         int v = buffer[offset + i] & 0xff;
645
646         print(encode(v >> 2));
647         print(encode(v << 4));
648         print('=');
649         print('=');
650       }
651       
652       print("</base64>");
653     }
654   }
655   
656   /**
657    * Writes a byte buffer to the stream.
658    */

659   public void writeByteBufferStart()
660     throws IOException JavaDoc
661   {
662     throw new UnsupportedOperationException JavaDoc();
663   }
664   
665   /**
666    * Writes a byte buffer to the stream.
667    *
668    * <code><pre>
669    * b b16 b18 bytes
670    * </pre></code>
671    */

672   public void writeByteBufferPart(byte []buffer, int offset, int length)
673     throws IOException JavaDoc
674   {
675     throw new UnsupportedOperationException JavaDoc();
676   }
677   
678   /**
679    * Writes a byte buffer to the stream.
680    *
681    * <code><pre>
682    * b b16 b18 bytes
683    * </pre></code>
684    */

685   public void writeByteBufferEnd(byte []buffer, int offset, int length)
686     throws IOException JavaDoc
687   {
688     throw new UnsupportedOperationException JavaDoc();
689   }
690
691   /**
692    * Encodes a digit
693    */

694   private char encode(int d)
695   {
696     d &= 0x3f;
697     if (d < 26)
698       return (char) (d + 'A');
699     else if (d < 52)
700       return (char) (d + 'a' - 26);
701     else if (d < 62)
702       return (char) (d + '0' - 52);
703     else if (d == 62)
704       return '+';
705     else
706       return '/';
707   }
708
709   /**
710    * Writes a reference.
711    *
712    * <code><pre>
713    * &lt;ref>int&lt;/ref>
714    * </pre></code>
715    *
716    * @param value the integer value to write.
717    */

718   public void writeRef(int value)
719     throws IOException JavaDoc
720   {
721     print("<ref>");
722     print(value);
723     print("</ref>");
724   }
725
726   /**
727    * If the object has already been written, just write its ref.
728    *
729    * @return true if we're writing a ref.
730    */

731   public boolean addRef(Object JavaDoc object)
732     throws IOException JavaDoc
733   {
734     if (_refs == null)
735       _refs = new IdentityHashMap JavaDoc();
736
737     Integer JavaDoc ref = (Integer JavaDoc) _refs.get(object);
738
739     if (ref != null) {
740       int value = ref.intValue();
741       
742       writeRef(value);
743       return true;
744     }
745     else {
746       _refs.put(object, new Integer JavaDoc(_refs.size()));
747       
748       return false;
749     }
750   }
751
752   /**
753    * Removes a reference.
754    */

755   public boolean removeRef(Object JavaDoc obj)
756     throws IOException JavaDoc
757   {
758     if (_refs != null) {
759       _refs.remove(obj);
760
761       return true;
762     }
763     else
764       return false;
765   }
766
767   /**
768    * Replaces a reference from one object to another.
769    */

770   public boolean replaceRef(Object JavaDoc oldRef, Object JavaDoc newRef)
771     throws IOException JavaDoc
772   {
773     Integer JavaDoc value = (Integer JavaDoc) _refs.remove(oldRef);
774
775     if (value != null) {
776       _refs.put(newRef, value);
777       return true;
778     }
779     else
780       return false;
781   }
782
783   /**
784    * Prints a string to the stream, encoded as UTF-8
785    *
786    * @param v the string to print.
787    */

788   public void printString(String JavaDoc v)
789     throws IOException JavaDoc
790   {
791     printString(v, 0, v.length());
792   }
793   
794   /**
795    * Prints a string to the stream, encoded as UTF-8
796    *
797    * @param v the string to print.
798    */

799   public void printString(String JavaDoc v, int offset, int length)
800     throws IOException JavaDoc
801   {
802     for (int i = 0; i < length; i++) {
803       char ch = v.charAt(i + offset);
804
805       if (ch == '<') {
806         os.write('&');
807         os.write('#');
808         os.write('6');
809         os.write('0');
810         os.write(';');
811       }
812       else if (ch == '&') {
813         os.write('&');
814         os.write('#');
815         os.write('3');
816         os.write('8');
817         os.write(';');
818       }
819       else if (ch < 0x80)
820         os.write(ch);
821       else if (ch < 0x800) {
822         os.write(0xc0 + ((ch >> 6) & 0x1f));
823         os.write(0x80 + (ch & 0x3f));
824       }
825       else {
826         os.write(0xe0 + ((ch >> 12) & 0xf));
827         os.write(0x80 + ((ch >> 6) & 0x3f));
828         os.write(0x80 + (ch & 0x3f));
829       }
830     }
831   }
832   
833   /**
834    * Prints a string to the stream, encoded as UTF-8
835    *
836    * @param v the string to print.
837    */

838   public void printString(char []v, int offset, int length)
839     throws IOException JavaDoc
840   {
841     for (int i = 0; i < length; i++) {
842       char ch = v[i + offset];
843
844       if (ch < 0x80)
845         os.write(ch);
846       else if (ch < 0x800) {
847         os.write(0xc0 + ((ch >> 6) & 0x1f));
848         os.write(0x80 + (ch & 0x3f));
849       }
850       else {
851         os.write(0xe0 + ((ch >> 12) & 0xf));
852         os.write(0x80 + ((ch >> 6) & 0x3f));
853         os.write(0x80 + (ch & 0x3f));
854       }
855     }
856   }
857   
858   /**
859    * Prints a date.
860    *
861    * @param date the date to print.
862    */

863   public void printDate(Calendar JavaDoc calendar)
864     throws IOException JavaDoc
865   {
866     int year = calendar.get(Calendar.YEAR);
867
868     os.write((char) ('0' + (year / 1000 % 10)));
869     os.write((char) ('0' + (year / 100 % 10)));
870     os.write((char) ('0' + (year / 10 % 10)));
871     os.write((char) ('0' + (year % 10)));
872
873     int month = calendar.get(Calendar.MONTH) + 1;
874     os.write((char) ('0' + (month / 10 % 10)));
875     os.write((char) ('0' + (month % 10)));
876
877     int day = calendar.get(Calendar.DAY_OF_MONTH);
878     os.write((char) ('0' + (day / 10 % 10)));
879     os.write((char) ('0' + (day % 10)));
880
881     os.write('T');
882
883     int hour = calendar.get(Calendar.HOUR_OF_DAY);
884     os.write((char) ('0' + (hour / 10 % 10)));
885     os.write((char) ('0' + (hour % 10)));
886
887     int minute = calendar.get(Calendar.MINUTE);
888     os.write((char) ('0' + (minute / 10 % 10)));
889     os.write((char) ('0' + (minute % 10)));
890
891     int second = calendar.get(Calendar.SECOND);
892     os.write((char) ('0' + (second / 10 % 10)));
893     os.write((char) ('0' + (second % 10)));
894
895     int ms = calendar.get(Calendar.MILLISECOND);
896     os.write('.');
897     os.write((char) ('0' + (ms / 100 % 10)));
898     os.write((char) ('0' + (ms / 10 % 10)));
899     os.write((char) ('0' + (ms % 10)));
900
901     os.write('Z');
902   }
903   
904   /**
905    * Prints a char to the stream.
906    *
907    * @param v the char to print.
908    */

909   protected void print(char v)
910     throws IOException JavaDoc
911   {
912     os.write(v);
913   }
914   
915   /**
916    * Prints an integer to the stream.
917    *
918    * @param v the integer to print.
919    */

920   protected void print(int v)
921     throws IOException JavaDoc
922   {
923     print(String.valueOf(v));
924   }
925
926   /**
927    * Prints a long to the stream.
928    *
929    * @param v the long to print.
930    */

931   protected void print(long v)
932     throws IOException JavaDoc
933   {
934     print(String.valueOf(v));
935   }
936
937   /**
938    * Prints a double to the stream.
939    *
940    * @param v the double to print.
941    */

942   protected void print(double v)
943     throws IOException JavaDoc
944   {
945     print(String.valueOf(v));
946   }
947
948   /**
949    * Prints a string as ascii to the stream. Used for tags, etc.
950    * that are known to the ascii.
951    *
952    * @param s the ascii string to print.
953    */

954   protected void print(String JavaDoc s)
955     throws IOException JavaDoc
956   {
957     int len = s.length();
958     for (int i = 0; i < len; i++) {
959       int ch = s.charAt(i);
960
961       os.write(ch);
962     }
963   }
964 }
965
Popular Tags