KickJava   Java API By Example, From Geeks To Geeks.

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


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
53 import java.io.EOFException JavaDoc;
54
55 import java.io.IOException JavaDoc;
56
57 import java.io.UTFDataFormatException JavaDoc;
58 import java.io.UnsupportedEncodingException JavaDoc;
59 import java.nio.ByteBuffer JavaDoc;
60
61 /**
62  * ByteableInputStream - a input stream look alike that has the
63  * ability to read byteable objects
64  * @since Feb 12, 2004
65  * @version 1.0
66  * @author Amir Shevat
67  *
68  *
69  */

70 public class ByteableInputStream {
71     
72     private ByteBuffer JavaDoc buff = null;
73     
74     private int mark_pos;
75     
76     public ByteableInputStream(){
77         
78     }
79     
80     
81     /**
82      * this is an inhouse method that read to a given byte[] b
83      * @param b the destanation byte[]
84      * @param off the startpoint offset
85      * @param len the max number of bytes to read
86      * @return the number of bytes read
87      */

88     public final int read(byte b[], int off, int len) {
89         // we want to read len but len must not be more then buff.remaining()
90
int bytesToRead =len;
91         int bytesCanRead = buff.remaining();
92         if(bytesToRead >bytesCanRead)
93             bytesToRead =bytesCanRead;
94             
95         buff.get(b, off ,bytesToRead );
96         return bytesToRead;
97     }
98     
99     
100     public final void mark(int pos){
101         mark_pos = pos;
102     }
103     
104     
105     public final void reset() throws IOException JavaDoc{
106         buff.position(mark_pos);
107     }
108     
109     
110     /**
111      * Reads some number of bytes from the input stream and stores them into
112      * the buffer array <code>b</code>. The number of bytes actually read is
113      * returned as an integer. This method blocks until input data is
114      * available, end of file is detected, or an exception is thrown.
115      *
116      * <p> If <code>b</code> is <code>null</code>, a
117      * <code>NullPointerException</code> is thrown. If the length of
118      * <code>b</code> is zero, then no bytes are read and <code>0</code> is
119      * returned; otherwise, there is an attempt to read at least one byte. If
120      * no byte is available because the stream is at end of file, the value
121      * <code>-1</code> is returned; otherwise, at least one byte is read and
122      * stored into <code>b</code>.
123      *
124      * <p> The first byte read is stored into element <code>b[0]</code>, the
125      * next one into <code>b[1]</code>, and so on. The number of bytes read is,
126      * at most, equal to the length of <code>b</code>. Let <i>k</i> be the
127      * number of bytes actually read; these bytes will be stored in elements
128      * <code>b[0]</code> through <code>b[</code><i>k</i><code>-1]</code>,
129      * leaving elements <code>b[</code><i>k</i><code>]</code> through
130      * <code>b[b.length-1]</code> unaffected.
131      *
132      * <p> If the first byte cannot be read for any reason other than end of
133      * file, then an <code>IOException</code> is thrown. In particular, an
134      * <code>IOException</code> is thrown if the input stream has been closed.
135      *
136      * <p> The <code>read(b)</code> method for class <code>InputStream</code>
137      * has the same effect as: <pre><code> read(b, 0, b.length) </code></pre>
138      *
139      * @param b the buffer into which the data is read.
140      * @return the total number of bytes read into the buffer, or
141      * <code>-1</code> is there is no more data because the end of
142      * the stream has been reached.
143      * @exception IOException if an I/O error occurs.
144      * @exception NullPointerException if <code>b</code> is <code>null</code>.
145      * @see java.io.InputStream#read(byte[], int, int)
146      */

147     public final int read(byte b[]) throws IOException JavaDoc {
148         return read(b, 0, b.length);
149     }
150     /**
151      * trys to find a byteable in the byteable registry and invokes the factory method
152      * @return the result of the factory method
153      * @throws IOException if byteable not found
154      */

155     public final Byteable readByteable() throws IOException JavaDoc{
156         Byteable b = null;
157
158         String JavaDoc byteableName = readASCIIString();
159
160         if(!byteableName.equals(ByteableRegistry.NULL_NAME)){
161             Byteable factory = ByteableRegistry.getByteableFactory(byteableName);
162             if(factory != null){
163                 
164                 b = factory.createInstance(this);
165             }else{
166                 throw new IOException JavaDoc("Can not read object -no byteable for byteable name="+byteableName+" byteableRegistry="+ByteableRegistry.desc());
167             }
168         }
169         
170         return b;
171     }//readByteable
172

173     
174     public final int available() throws IOException JavaDoc {
175         return buff.remaining();// this.buff.length-this.pos;
176
}
177     
178     /**
179      * See the general contract of the <code>readUnsignedByte</code>
180      * method of <code>DataInput</code>.
181      * <p>
182      * Bytes
183      * for this operation are read from the contained
184      * input stream.
185      *
186      * @return the next byte of this input stream, interpreted as an
187      * unsigned 8-bit number.
188      * @exception EOFException if this input stream has reached the end.
189      * @exception IOException if an I/O error occurs.
190      * @see java.io.FilterInputStream#in
191      */

192     public final int readUnsignedByte() throws IOException JavaDoc {
193         int ch = read();
194         if (ch < 0)
195             throw new EOFException JavaDoc();
196         return ch;
197     }
198     /**
199      * See the general contract of the <code>readUnsignedShort</code>
200      * method of <code>DataInput</code>.
201      * <p>
202      * Bytes
203      * for this operation are read from the contained
204      * input stream.
205      *
206      * @return the next two bytes of this input stream, interpreted as an
207      * unsigned 16-bit integer.
208      * @exception EOFException if this input stream reaches the end before
209      * reading two bytes.
210      * @exception IOException if an I/O error occurs.
211      * @see java.io.FilterInputStream#in
212      */

213     public final int readUnsignedShort() throws IOException JavaDoc {
214         int ch1 = read();
215         int ch2 = read();
216         if ((ch1 | ch2) < 0)
217             throw new EOFException JavaDoc();
218         return (ch1 << 8) + (ch2 << 0);
219         
220     }
221     
222     
223     
224     
225     /**
226      * See the general contract of the <code>readFully</code>
227      * method of <code>DataInput</code>.
228      * <p>
229      * Bytes
230      * for this operation are read from the contained
231      * input stream.
232      *
233      * @param b the buffer into which the data is read.
234      * @exception EOFException if this input stream reaches the end before
235      * reading all the bytes.
236      * @exception IOException if an I/O error occurs.
237      * @see java.io.FilterInputStream#in
238      */

239     public final void readFully(byte b[]) throws IOException JavaDoc {
240         readFully(b, 0, b.length);
241     }
242
243     /**
244      * See the general contract of the <code>readFully</code>
245      * method of <code>DataInput</code>.
246      * <p>
247      * Bytes
248      * for this operation are read from the contained
249      * input stream.
250      *
251      * @param b the buffer into which the data is read.
252      * @param off the start offset of the data.
253      * @param len the number of bytes to read.
254      * @exception EOFException if this input stream reaches the end before
255      * reading all the bytes.
256      * @exception IOException if an I/O error occurs.
257      * @see java.io.FilterInputStream#in
258      */

259     public final void readFully(byte b[], int off, int len) throws IOException JavaDoc {
260         if (len < 0)
261             throw new IndexOutOfBoundsException JavaDoc();
262         int n = 0;
263         while (n < len) {
264             int count = read(b, off + n, len - n);
265             if (count <= 0)
266                 throw new EOFException JavaDoc();
267             n += count;
268         }
269     }
270     
271     
272     byte[] asciiTemp = new byte[1000];
273     char[] str = null;
274     /**
275      * the counter methos for writeASCIIString use only if you know your
276      * String is JUST ASCII
277      * @return a String from the underline buffer
278      * @throws IOException
279      */

280     public final String JavaDoc readASCIIString() throws IOException JavaDoc{
281         short length = readShort();
282
283         if(length == ByteableOutputStream.NULL_PLACE_HOLDER){
284             return null;
285         }
286
287         if (asciiTemp.length < length) {
288             asciiTemp = new byte[length];
289         }
290
291         readFully(asciiTemp , 0 , length);
292
293         try {
294             return new String JavaDoc(asciiTemp, 0, length, "ascii");
295         } catch (UnsupportedEncodingException JavaDoc e) {
296             // fat chance this will ever happen
297
}
298
299         if (str == null || str.length < asciiTemp.length) {
300             str = new char[asciiTemp.length];
301         }
302
303         int ch1 ;
304         int asciiTempIndex = 0;
305         for (int i = 0; i < length; i++) {
306             ch1 = asciiTemp[asciiTempIndex++] & 0xff;
307             //ch2 = asciiTemp[asciiTempIndex++] & 0xff;
308
str[i] =(char)ch1;//((ch1 << 8) + (ch2 << 0));
309
}
310         return new String JavaDoc(str , 0 ,length);
311     }
312     
313     
314     
315     
316     /**
317      * Reads from the
318      * stream <code>in</code> a representation
319      * of a Unicode character string encoded in
320      * Java modified UTF-8 format; this string
321      * of characters is then returned as a <code>String</code>.
322      * The details of the modified UTF-8 representation
323      * are exactly the same as for the <code>readUTF</code>
324      * method of <code>DataInput</code>.
325      *
326      * @return a Unicode string.
327      * @exception EOFException if the input stream reaches the end
328      * before all the bytes.
329      * @exception IOException if an I/O error occurs.
330      * @exception UTFDataFormatException if the bytes do not represent a
331      * valid Java modified UTF-8 encoding of a Unicode string.
332      * @see java.io.DataInputStream#readUnsignedShort()
333      */

334     public final String JavaDoc readUTF() throws IOException JavaDoc {
335         int utflen = readInt();
336         if(utflen ==ByteableOutputStream.NULL_PLACE_HOLDER){
337             return null;
338         }
339             
340         StringBuffer JavaDoc str = new StringBuffer JavaDoc(utflen);
341         byte bytearr [] = new byte[utflen];
342         int c, char2, char3;
343         int count = 0;
344
345         readFully(bytearr, 0, utflen);
346
347         while (count < utflen) {
348             c = (int) bytearr[count] & 0xff;
349             switch (c >> 4) {
350                 case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
351                     /* 0xxxxxxx*/
352                     count++;
353                     str.append((char)c);
354                     break;
355                 case 12: case 13:
356                     /* 110x xxxx 10xx xxxx*/
357                     count += 2;
358                     if (count > utflen)
359                         throw new UTFDataFormatException JavaDoc();
360                     char2 = (int) bytearr[count-1];
361                     if ((char2 & 0xC0) != 0x80)
362                         throw new UTFDataFormatException JavaDoc();
363                     str.append((char)(((c & 0x1F) << 6) | (char2 & 0x3F)));
364                     break;
365                 case 14:
366                     /* 1110 xxxx 10xx xxxx 10xx xxxx */
367                     count += 3;
368                     if (count > utflen)
369                         throw new UTFDataFormatException JavaDoc();
370                     char2 = (int) bytearr[count-2];
371                     char3 = (int) bytearr[count-1];
372                     if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
373                         throw new UTFDataFormatException JavaDoc();
374                     str.append((char)(((c & 0x0F) << 12) |
375                             ((char2 & 0x3F) << 6) |
376                             ((char3 & 0x3F) << 0)));
377                     break;
378                 default:
379                     /* 10xx xxxx, 1111 xxxx */
380                     throw new UTFDataFormatException JavaDoc();
381             }
382         }
383         // The number of chars produced may be less than utflen
384
String JavaDoc result = new String JavaDoc(str);
385         
386         return result;
387     }
388     
389     /**
390      * See the general contract of the <code>readChar</code>
391      * method of <code>DataInput</code>.
392      * <p>
393      * Bytes
394      * for this operation are read from the contained
395      * input stream.
396      *
397      * @return the next two bytes of this input stream as a Unicode
398      * character.
399      * @exception EOFException if this input stream reaches the end before
400      * reading two bytes.
401      * @exception IOException if an I/O error occurs.
402      * @see java.io.FilterInputStream#in
403      */

404     public final char readChar() throws IOException JavaDoc {
405         int ch1 = read();
406         int ch2 = read();
407         if ((ch1 | ch2) < 0)
408             throw new EOFException JavaDoc();
409         return (char)((ch1 << 8) + (ch2 << 0));
410     }
411     
412     /**
413      * See the general contract of the <code>readInt</code>
414      * method of <code>DataInput</code>.
415      * <p>
416      * Bytes
417      * for this operation are read from the contained
418      * input stream.
419      *
420      * @return the next four bytes of this input stream, interpreted as an
421      * <code>int</code>.
422      * @exception EOFException if this input stream reaches the end before
423      * reading four bytes.
424      * @exception IOException if an I/O error occurs.
425      * @see java.io.FilterInputStream#in
426      */

427     public final int readInt() throws IOException JavaDoc {
428         int ch1 = read();
429         int ch2 = read();
430         int ch3 = read();
431         int ch4 = read();
432         if ((ch1 | ch2 | ch3 | ch4) < 0)
433             throw new EOFException JavaDoc();
434         return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
435     }
436     
437     /**
438      * See the general contract of the <code>readByte</code>
439      * method of <code>DataInput</code>.
440      * <p>
441      * Bytes
442      * for this operation are read from the contained
443      * input stream.
444      *
445      * @return the next byte of this input stream as a signed 8-bit
446      * <code>byte</code>.
447      * @exception EOFException if this input stream has reached the end.
448      * @exception IOException if an I/O error occurs.
449      * @see java.io.FilterInputStream#in
450      */

451     public final byte readByte() throws IOException JavaDoc {
452         int ch = read();
453         if (ch < 0)
454             throw new EOFException JavaDoc();
455         return (byte)(ch);
456     }
457     
458     /**
459      * See the general contract of the <code>readBoolean</code>
460      * method of <code>DataInput</code>.
461      * <p>
462      * Bytes
463      * for this operation are read from the contained
464      * input stream.
465      *
466      * @return the <code>boolean</code> value read.
467      * @exception EOFException if this input stream has reached the end.
468      * @exception IOException if an I/O error occurs.
469      * @see java.io.FilterInputStream#in
470      */

471     public final boolean readBoolean() throws IOException JavaDoc {
472         int ch = read();
473         if (ch < 0)
474             throw new EOFException JavaDoc();
475         return (ch != 0);
476     }
477     
478     private byte readBuffer[] = new byte[8];
479
480     /**
481      * See the general contract of the <code>readLong</code>
482      * method of <code>DataInput</code>.
483      * <p>
484      * Bytes
485      * for this operation are read from the contained
486      * input stream.
487      *
488      * @return the next eight bytes of this input stream, interpreted as a
489      * <code>long</code>.
490      * @exception EOFException if this input stream reaches the end before
491      * reading eight bytes.
492      * @exception IOException if an I/O error occurs.
493      * @see java.io.FilterInputStream#in
494      */

495     public final long readLong() throws IOException JavaDoc {
496         readFully(readBuffer, 0, 8);
497         return (((long)readBuffer[0] << 56) +
498                 ((long)(readBuffer[1] & 255) << 48) +
499                 ((long)(readBuffer[2] & 255) << 40) +
500                 ((long)(readBuffer[3] & 255) << 32) +
501                 ((long)(readBuffer[4] & 255) << 24) +
502                 ((readBuffer[5] & 255) << 16) +
503                 ((readBuffer[6] & 255) << 8) +
504                 ((readBuffer[7] & 255) << 0));
505     }
506     
507     
508     /**
509      * See the general contract of the <code>readShort</code>
510      * method of <code>DataInput</code>.
511      * <p>
512      * Bytes
513      * for this operation are read from the contained
514      * input stream.
515      *
516      * @return the next two bytes of this input stream, interpreted as a
517      * signed 16-bit number.
518      * @exception EOFException if this input stream reaches the end before
519      * reading two bytes.
520      * @exception IOException if an I/O error occurs.
521      * @see java.io.FilterInputStream#in
522      */

523     public final short readShort() throws IOException JavaDoc {
524         int ch1 = read();
525         int ch2 = read();
526         if ((ch1 | ch2) < 0)
527             throw new EOFException JavaDoc();
528         return (short)((ch1 << 8) + (ch2 << 0));
529     }
530     
531     /**
532      * See the general contract of the <code>readDouble</code>
533      * method of <code>DataInput</code>.
534      * <p>
535      * Bytes
536      * for this operation are read from the contained
537      * input stream.
538      *
539      * @return the next eight bytes of this input stream, interpreted as a
540      * <code>double</code>.
541      * @exception EOFException if this input stream reaches the end before
542      * reading eight bytes.
543      * @exception IOException if an I/O error occurs.
544      * @see java.io.DataInputStream#readLong()
545      * @see java.lang.Double#longBitsToDouble(long)
546      */

547     public final double readDouble() throws IOException JavaDoc {
548         return Double.longBitsToDouble(readLong());
549     }
550     
551     /**
552      * See the general contract of the <code>readFloat</code>
553      * method of <code>DataInput</code>.
554      * <p>
555      * Bytes
556      * for this operation are read from the contained
557      * input stream.
558      *
559      * @return the next four bytes of this input stream, interpreted as a
560      * <code>float</code>.
561      * @exception EOFException if this input stream reaches the end before
562      * reading four bytes.
563      * @exception IOException if an I/O error occurs.
564      * @see java.io.DataInputStream#readInt()
565      * @see java.lang.Float#intBitsToFloat(int)
566      */

567     public final float readFloat() throws IOException JavaDoc {
568         return Float.intBitsToFloat(readInt());
569     }
570     
571     
572     
573     /**
574      * Reads the next byte of data from this input stream. The value
575      * byte is returned as an <code>int</code> in the range
576      * <code>0</code> to <code>255</code>. If no byte is available
577      * because the end of the stream has been reached, the value
578      * <code>-1</code> is returned.
579      * <p>
580      * This <code>read</code> method
581      * cannot block.
582      *
583      * @return the next byte of data, or <code>-1</code> if the end of the
584      * stream has been reached.
585      */

586     public final int read() throws IOException JavaDoc {
587         if(!buff.hasRemaining())
588             return -1;
589         else
590             return buff.get() & 0xff;
591                 
592     }
593     
594     
595     
596     public final void release() {
597         
598         buff = null;
599     
600         ByteableInputStreamPool.getInstance().releaseObject(this);
601     }//release
602

603     
604
605     /**
606      * @param buffer the buffer in a ready to read from state
607      */

608     public final void setUnderLine(ByteBuffer JavaDoc buffer) throws IOException JavaDoc {
609         buff = buffer;
610     
611     }
612
613     public final ByteBuffer JavaDoc getUnderlying() {
614         return this.buff;
615     }
616 }
617
Popular Tags