KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > imagero > uio > io > BitInputStream


1 /*
2  * Copyright (c) Andrey Kuznetsov. All Rights Reserved.
3  *
4  * http://uio.imagero.com
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * o Redistributions of source code must retain the above copyright notice,
10  * this list of conditions and the following disclaimer.
11  *
12  * o Redistributions in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  *
16  * o Neither the name of imagero Andrei Kouznetsov nor the names of
17  * its contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */

32
33 package com.imagero.uio.io;
34
35 import java.io.FilterInputStream JavaDoc;
36 import java.io.IOException JavaDoc;
37 import java.io.InputStream JavaDoc;
38
39 /**
40  * adds ability to read streams bitewise and also to read predefined amount of bits every read() call
41  * @author Andrey Kuznetsov
42  */

43 public class BitInputStream extends FilterInputStream JavaDoc {
44
45     int vbits = 0;
46     int bitbuf = 0;
47
48     private int bitsToRead = 8;
49
50     public BitInputStream(InputStream JavaDoc in) {
51         super(in);
52     }
53
54     /**
55      * how much bits is read every read() call (default - 8)
56      * @return
57      */

58     public int getBitsToRead() {
59         return bitsToRead;
60     }
61
62     /**
63      * set how much bits is read every read() call (max 8)
64      * @param bitsToRead
65      */

66     public void setBitsToRead(int bitsToRead) {
67         if(bitsToRead > 8) {
68             throw new IllegalArgumentException JavaDoc();
69         }
70         this.bitsToRead = bitsToRead;
71     }
72
73     public int read() throws IOException JavaDoc {
74         return read(bitsToRead);
75     }
76
77     public int read(int nbits) throws IOException JavaDoc {
78         int ret;
79         //nothing to read
80
if (nbits == 0) {
81             return 0;
82         }
83         //too many bits requested
84
if (nbits > 8) {
85             throw new IllegalArgumentException JavaDoc("max 8 bits can be read at once");
86         }
87         //not anough bits in buffer
88
if (nbits > vbits) {
89             fillBuffer(nbits);
90         }
91         //buffer still empty => we are reached EOF
92
if (vbits == 0) {
93             return -1;
94         }
95         //we read some bits, but not anough => probably next time we'll reach EOF
96
// if (nbits > vbits) {
97
// vbits = nbits;
98
// }
99
ret = bitbuf << (32 - vbits) >>> (32 - nbits);
100         vbits -= nbits;
101
102         if(vbits < 0) {
103             vbits = 0;
104         }
105
106         return ret;
107     }
108
109     public int read(byte b[]) throws IOException JavaDoc {
110         return read(b, 0, b.length);
111     }
112
113     /**
114      * Reads data from input stream into an byte array.
115      *
116      * @param b the buffer into which the data is read.
117      * @param off the start offset of the data.
118      * @param len the maximum number of bytes read.
119      * @return the total number of bytes read into the buffer, or -1 if the EOF has been reached.
120      * @exception IOException if an I/O error occurs.
121      * @exception NullPointerException if supplied byte array is null
122      */

123     public int read(byte b[], int off, int len) throws IOException JavaDoc {
124         if (len <= 0) {
125             return 0;
126         }
127         int c = read();
128         if (c == -1) {
129             return -1;
130         }
131         b[off] = (byte) c;
132
133         int i = 1;
134         for (; i < len; ++i) {
135             c = read();
136             if (c == -1) {
137                 break;
138             }
139             b[off + i] = (byte) c;
140         }
141         return i;
142     }
143
144     /**
145      * empties bit buffer.
146      */

147     public void resetBuffer() {
148         vbits = 0;
149         bitbuf = 0;
150     }
151
152     /**
153      * Skips some bytes from the input stream.
154      * If bit buffer is not empty, n - (vbits + 8) / 8 bytes skipped,
155      * then buffer is resetted and filled with same amount of bits as it has before skipping.
156      * @param n the number of bytes to be skipped.
157      * @return the actual number of bytes skipped.
158      * @exception IOException if an I/O error occurs.
159      */

160     public long skip(long n) throws IOException JavaDoc {
161         if (vbits == 0) {
162             return in.skip(n);
163         }
164         else {
165             int b = (vbits + 8) / 8;
166             in.skip(n - b);
167             int vbits = this.vbits;
168             resetBuffer();
169             fillBuffer(vbits);
170             return n;
171         }
172     }
173
174     private void fillBuffer(int nbits) throws IOException JavaDoc {
175         int c;
176         while (vbits < nbits) {
177             c = in.read();
178             if (c == -1) {
179                 break;
180             }
181             bitbuf = (bitbuf << 8) + (c & 0xFF);
182             vbits += 8;
183         }
184     }
185
186     public int getBitOffset() {
187         return 7 - (vbits % 8);
188     }
189 }
190
Popular Tags