KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mr > core > util > byteable > ByteableOutputStream


1 /*
2  * Copyright 2002 by
3  * <a HREF="http://www.coridan.com">Coridan</a>
4  * <a HREF="mailto: support@coridan.com ">support@coridan.com</a>
5  *
6  * The contents of this file are subject to the Mozilla Public License Version
7  * 1.1 (the "License"); you may not use this file except in compliance with the
8  * License. You may obtain a copy of the License at
9  * http://www.mozilla.org/MPL/
10  *
11  * Software distributed under the License is distributed on an "AS IS" basis,
12  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13  * for the specific language governing rights and limitations under the
14  * License.
15  *
16  * The Original Code is "MantaRay" (TM).
17  *
18  * The Initial Developer of the Original Code is Amir Shevat.
19  * Portions created by the Initial Developer are Copyright (C) 2006
20  * Coridan Inc. All Rights Reserved.
21  *
22  * Contributor(s): all the names of the contributors are added in the source
23  * code where applicable.
24  *
25  * Alternatively, the contents of this file may be used under the terms of the
26  * LGPL license (the "GNU LESSER GENERAL PUBLIC LICENSE"), in which case the
27  * provisions of LGPL are applicable instead of those above. If you wish to
28  * allow use of your version of this file only under the terms of the LGPL
29  * License and not to allow others to use your version of this file under
30  * the MPL, indicate your decision by deleting the provisions above and
31  * replace them with the notice and other provisions required by the LGPL.
32  * If you do not delete the provisions above, a recipient may use your version
33  * of this file under either the MPL or the GNU LESSER GENERAL PUBLIC LICENSE.
34  
35  *
36  * This library is free software; you can redistribute it and/or modify it
37  * under the terms of the MPL as stated above or under the terms of the GNU
38  * Lesser General Public License as published by the Free Software Foundation;
39  * either version 2.1 of the License, or any later version.
40  *
41  * This library is distributed in the hope that it will be useful, but WITHOUT
42  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
43  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
44  * License for more details.
45  */

46 /*
47  * Created on Feb 12, 2004
48  * Manta LTD
49  */

50 package org.mr.core.util.byteable;
51
52 import java.io.IOException JavaDoc;
53 import java.nio.ByteBuffer JavaDoc;
54
55
56
57 /**
58  * ByteableOutputStream a output stream look alike that knows how to write byteable
59  * objects and works with an underline NIO
60  * @since Feb 12, 2004
61  * @version 1.0
62  * @author Amir Shevat
63  *
64  *
65  */

66 public class ByteableOutputStream {
67
68    //a null value
69
public static final int NULL_PLACE_HOLDER = -5;
70    // the underline object
71
ByteBuffer JavaDoc buff= null;
72     ByteBufferFactory myBufferPool = null;
73     public ByteableOutputStream(ByteBufferFactory pool ) {
74         myBufferPool = pool;
75 // //if we have pool get from pool else allocate new
76
if(myBufferPool != null){
77             buff = myBufferPool.getBuffer(myBufferPool.getSmallBufferSize());
78         }else{
79             buff = ByteBuffer.allocate(myBufferPool.getSmallBufferSize());
80         }
81             
82     }
83     
84     /**
85      * writes the type of the byteable and then delegetes the writting to the byteable
86      * @param byteable the object to be written
87      * @throws IOException
88      */

89     public final void writeByteable(Byteable byteable) throws IOException JavaDoc{
90         if(byteable == null){
91             writeASCIIString(ByteableRegistry.NULL_NAME);
92         }else{
93             writeASCIIString(byteable.getByteableName());
94             byteable.toBytes(this);
95         }
96         
97     }
98     
99     
100     
101     
102     
103     /**
104      * @returns the bytes written up to now
105      */

106     public final ByteBuffer JavaDoc getByteBuffer(){
107         buff.flip();
108         return buff;
109     }
110     
111     
112     /**
113      * Writes the specified byte (the low eight bits of the argument
114      * <code>b</code>) to the underlying output stream. If no exception
115      * is thrown, the counter <code>written</code> is incremented by
116      * <code>1</code>.
117      * <p>
118      * Implements the <code>write</code> method of <code>OutputStream</code>.
119      *
120      * @param b the <code>byte</code> to be written.
121      * @exception IOException if an I/O error occurs.
122      * @see java.io.FilterOutputStream#out
123      */

124     public final void write(byte b) throws IOException JavaDoc {
125         increaseBufferSizeIfNeeded(1);
126         buff.put(b);
127     }
128     
129     /**
130      * checks if we need to write to the buffer more then it can hold and if that
131      * is the case makes the buffer bigger
132      * @param sizeNeeded the amount of space needed
133      */

134     public final void increaseBufferSizeIfNeeded(int sizeNeeded){
135         if(buff.remaining()< sizeNeeded){
136             if(sizeNeeded < buff.capacity()){
137                 sizeNeeded = buff.capacity()*2;
138             }else{
139                 sizeNeeded = buff.capacity()+sizeNeeded;
140             }
141             ByteBuffer JavaDoc newBuff ;
142             //if we have pool get from pool else allocate new
143
if(myBufferPool != null){
144                 newBuff = myBufferPool.getBuffer(sizeNeeded);
145             }else{
146                 newBuff = ByteBuffer.allocate(sizeNeeded);
147             }
148             buff.flip();
149             newBuff.put(buff);
150             myBufferPool.release(buff);
151             buff = newBuff;
152         }
153     }
154     
155     /**
156      * added to support JSM object DO NOT USE
157      * @param otherBuff
158      * @throws IOException
159      */

160     public final void write(ByteBuffer JavaDoc otherBuff) throws IOException JavaDoc {
161         //otherBuff.flip();
162
while(otherBuff.hasRemaining()){
163             write(otherBuff.get());
164         }
165         
166     }
167     
168     
169
170     /**
171      * Writes <code>len</code> bytes from the specified byte array
172      * starting at offset <code>off</code> to the underlying output stream.
173      * If no exception is thrown, the counter <code>written</code> is
174      * incremented by <code>len</code>.
175      *
176      * @param b the data.
177      * @param off the start offset in the data.
178      * @param len the number of bytes to write.
179      * @exception IOException if an I/O error occurs.
180      * @see java.io.FilterOutputStream#out
181      */

182     public final void write(byte b[], int off, int len)
183     throws IOException JavaDoc
184     {
185         int bytesNeeded =len - off;
186         increaseBufferSizeIfNeeded(bytesNeeded);
187         buff.put( b, off, len);
188         //int end = off + len;
189
//for (int i = off; i < end; i++)
190
// write(b[i]);
191

192     }
193     
194     public final void write(byte b[])
195     throws IOException JavaDoc
196     {
197         write(b , 0 , b.length);
198         
199     }
200
201     
202     final static byte trueByte = 1;
203     final static byte falseByte = 0;
204     /**
205      * Writes a <code>boolean</code> to the underlying output stream as
206      * a 1-byte value. The value <code>true</code> is written out as the
207      * value <code>(byte)1</code>; the value <code>false</code> is
208      * written out as the value <code>(byte)0</code>. If no exception is
209      * thrown, the counter <code>written</code> is incremented by
210      * <code>1</code>.
211      *
212      * @param v a <code>boolean</code> value to be written.
213      * @exception IOException if an I/O error occurs.
214      * @see java.io.FilterOutputStream#out
215      */

216     public final void writeBoolean(boolean v) throws IOException JavaDoc {
217         if( v){
218             write(trueByte);
219         }else{
220             write(falseByte);
221         }
222         
223         
224     }
225     
226     // psado implementation
227
public void flush(){
228         
229     }
230
231     /**
232      * Writes out a <code>byte</code> to the underlying output stream as
233      * a 1-byte value. If no exception is thrown, the counter
234      * <code>written</code> is incremented by <code>1</code>.
235      *
236      * @param v a <code>byte</code> value to be written.
237      * @exception IOException if an I/O error occurs.
238      * @see java.io.FilterOutputStream#out
239      */

240     public final void writeByte(byte v) throws IOException JavaDoc {
241         write(v);
242         
243     }
244
245     /**
246      * Writes a <code>short</code> to the underlying output stream as two
247      * bytes, high byte first. If no exception is thrown, the counter
248      * <code>written</code> is incremented by <code>2</code>.
249      *
250      * @param v a <code>short</code> to be written.
251      * @exception IOException if an I/O error occurs.
252      * @see java.io.FilterOutputStream#out
253      */

254     public final void writeShort(int v) throws IOException JavaDoc {
255         write((byte)((v >>> 8) & 0xFF));
256         write((byte)((v >>> 0) & 0xFF));
257         
258     }
259
260     /**
261      * Writes a <code>char</code> to the underlying output stream as a
262      * 2-byte value, high byte first. If no exception is thrown, the
263      * counter <code>written</code> is incremented by <code>2</code>.
264      *
265      * @param v a <code>char</code> value to be written.
266      * @exception IOException if an I/O error occurs.
267      * @see java.io.FilterOutputStream#out
268      */

269     public final void writeChar(int v) throws IOException JavaDoc {
270         writeShort(v);
271         //write((v >>> 8) & 0xFF);
272
//write((v >>> 0) & 0xFF);
273

274     }
275
276     /**
277      * Writes an <code>int</code> to the underlying output stream as four
278      * bytes, high byte first. If no exception is thrown, the counter
279      * <code>written</code> is incremented by <code>4</code>.
280      *
281      * @param v an <code>int</code> to be written.
282      * @exception IOException if an I/O error occurs.
283      * @see java.io.FilterOutputStream#out
284      */

285     public final void writeInt(int v) throws IOException JavaDoc {
286         write((byte)((v >>> 24) & 0xFF));
287         write((byte)((v >>> 16) & 0xFF));
288         write((byte)((v >>> 8) & 0xFF));
289         write((byte)((v >>> 0) & 0xFF));
290         
291     }
292
293     
294
295     /**
296      * Writes a <code>long</code> to the underlying output stream as eight
297      * bytes, high byte first. In no exception is thrown, the counter
298      * <code>written</code> is incremented by <code>8</code>.
299      *
300      * @param v a <code>long</code> to be written.
301      * @exception IOException if an I/O error occurs.
302      * @see java.io.FilterOutputStream#out
303      */

304     public final void writeLong(long v) throws IOException JavaDoc {
305         write((byte)(v >>> 56));
306         write((byte)(v >>> 48));
307         write((byte)(v >>> 40));
308         write((byte)(v >>> 32));
309         write((byte)(v >>> 24));
310         write((byte)(v >>> 16));
311         write((byte)(v >>> 8));
312         write((byte)(v >>> 0));
313         
314     }
315
316     /**
317      * Converts the float argument to an <code>int</code> using the
318      * <code>floatToIntBits</code> method in class <code>Float</code>,
319      * and then writes that <code>int</code> value to the underlying
320      * output stream as a 4-byte quantity, high byte first. If no
321      * exception is thrown, the counter <code>written</code> is
322      * incremented by <code>4</code>.
323      *
324      * @param v a <code>float</code> value to be written.
325      * @exception IOException if an I/O error occurs.
326      * @see java.io.FilterOutputStream#out
327      * @see java.lang.Float#floatToIntBits(float)
328      */

329     public final void writeFloat(float v) throws IOException JavaDoc {
330         writeInt(Float.floatToIntBits(v));
331     }
332
333     /**
334      * Converts the double argument to a <code>long</code> using the
335      * <code>doubleToLongBits</code> method in class <code>Double</code>,
336      * and then writes that <code>long</code> value to the underlying
337      * output stream as an 8-byte quantity, high byte first. If no
338      * exception is thrown, the counter <code>written</code> is
339      * incremented by <code>8</code>.
340      *
341      * @param v a <code>double</code> value to be written.
342      * @exception IOException if an I/O error occurs.
343      * @see java.io.FilterOutputStream#out
344      * @see java.lang.Double#doubleToLongBits(double)
345      */

346     public final void writeDouble(double v) throws IOException JavaDoc {
347         writeLong(Double.doubleToLongBits(v));
348     }
349
350     /**
351      * Writes out the string to the underlying output stream as a
352      * sequence of bytes. Each character in the string is written out, in
353      * sequence, by discarding its high eight bits. If no exception is
354      * thrown, the counter <code>written</code> is incremented by the
355      * length of <code>s</code>.
356      *
357      * @param s a string of bytes to be written.
358      * @exception IOException if an I/O error occurs.
359      * @see java.io.FilterOutputStream#out
360      */

361     public final void writeBytes(String JavaDoc s) throws IOException JavaDoc {
362         int len = s.length();
363         for (int i = 0 ; i < len ; i++) {
364             write((byte)s.charAt(i));
365         }
366         
367     }
368
369     /**
370      * Writes a string to the underlying output stream as a sequence of
371      * characters. Each character is written to the data output stream as
372      * if by the <code>writeChar</code> method. If no exception is
373      * thrown, the counter <code>written</code> is incremented by twice
374      * the length of <code>s</code>.
375      *
376      * @param s a <code>String</code> value to be written.
377      * @exception IOException if an I/O error occurs.
378      * @see java.io.DataOutputStream#writeChar(int)
379      * @see java.io.FilterOutputStream#out
380      */

381     public final void writeChars(String JavaDoc s) throws IOException JavaDoc {
382         int len = s.length();
383         for (int i = 0 ; i < len ; i++) {
384             int v = s.charAt(i);
385             writeChar(v);
386             //write((v >>> 8) & 0xFF);
387
//write((v >>> 0) & 0xFF);
388
}
389         
390     }
391     
392     
393     byte[] asciiTemp = new byte[1000];
394     /**
395      * use only if you know the string you hold is plain text no UTF or UNICODE data is passed
396      * @param s the ASCII string to be written
397      * @throws IOException
398      */

399     public final void writeASCIIString(String JavaDoc s) throws IOException JavaDoc{
400         if (s==null){
401             writeShort(ByteableOutputStream.NULL_PLACE_HOLDER);
402             return;
403         }
404             
405         short length =(short) s.length();
406         writeShort(length);
407         int asciiTempIndex = 0;
408         char v;
409         for(int index =0 ; index<length ; index++){
410             v=s.charAt(index);
411             asciiTemp[asciiTempIndex++]= (byte)v;//((v >>> 8) & 0xFF);
412

413         }
414         write(asciiTemp , 0 ,asciiTempIndex );
415     }
416
417     
418     /**
419      * Writes a string to the specified DataOutput using Java modified UTF-8
420      * encoding in a machine-independent manner.
421      * <p>
422      * First, two bytes are written to out as if by the <code>writeShort</code>
423      * method giving the number of bytes to follow. This value is the number of
424      * bytes actually written out, not the length of the string. Following the
425      * length, each character of the string is output, in sequence, using the
426      * modified UTF-8 encoding for the character. If no exception is thrown, the
427      * counter <code>written</code> is incremented by the total number of
428      * bytes written to the output stream. This will be at least two
429      * plus the length of <code>str</code>, and at most two plus
430      * thrice the length of <code>str</code>.
431      *
432      * @param str a string to be written.
433      * @param out destination to write to
434      * @return The number of bytes written out.
435      * @exception IOException if an I/O error occurs.
436      */

437     public final int writeUTF(String JavaDoc str) throws IOException JavaDoc {
438         if (str==null){
439             writeInt(ByteableOutputStream.NULL_PLACE_HOLDER);
440             return 1;
441         }
442            
443         int strlen = str.length();
444         int utflen = 0;
445         char[] charr = new char[strlen];
446         int c, count = 0;
447
448         str.getChars(0, strlen, charr, 0);
449         
450         for (int i = 0; i < strlen; i++) {
451             c = charr[i];
452             if ((c >= 0x0001) && (c <= 0x007F)) {
453                 utflen++;
454             } else if (c > 0x07FF) {
455                 utflen += 3;
456             } else {
457                 utflen += 2;
458             }
459         }
460
461         //if (utflen > 65535)
462
//throw new UTFDataFormatException();
463

464         byte[] bytearr = new byte[utflen];
465         writeInt(utflen);
466         
467         for (int i = 0; i < strlen; i++) {
468             c = charr[i];
469             if ((c >= 0x0001) && (c <= 0x007F)) {
470                 bytearr[count++] = (byte) c;
471             } else if (c > 0x07FF) {
472                 bytearr[count++] = (byte) (0xE0 | ((c >> 12) & 0x0F));
473                 bytearr[count++] = (byte) (0x80 | ((c >> 6) & 0x3F));
474                 bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
475             } else {
476                 bytearr[count++] = (byte) (0xC0 | ((c >> 6) & 0x1F));
477                 bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
478             }
479         }
480         write(bytearr , 0 ,count);
481         return utflen ;
482     }
483     
484     
485     public final void release() {
486         if(buff!= null){
487             myBufferPool.release(buff);
488             buff = null;
489         }
490     }//release
491
}
492
Popular Tags