001: /*
002: This source file is part of Smyle, a database library.
003: For up-to-date information, see http://www.drjava.de/smyle
004: Copyright (C) 2001 Stefan Reich (doc@drjava.de)
005:
006: This library is free software; you can redistribute it and/or
007: modify it under the terms of the GNU Lesser General Public
008: License as published by the Free Software Foundation; either
009: version 2.1 of the License, or (at your option) any later version.
010:
011: This library is distributed in the hope that it will be useful,
012: but WITHOUT ANY WARRANTY; without even the implied warranty of
013: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: Lesser General Public License for more details.
015:
016: You should have received a copy of the GNU Lesser General Public
017: License along with this library; if not, write to the Free Software
018: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019:
020: For full license text, see doc/license/lgpl.txt in this distribution
021: */
022:
023: package drjava.smyle.core;
024:
025: import org.artsProject.mcop.*;
026:
027: /** stores individual bits in a byte buffer and reads them back again.
028: You should only use each BitBuffer instance for reading OR writing. */
029: public class BitBuffer {
030: Buffer buffer;
031: Buffer offstream;
032: int b, bit, rbit = 8;
033:
034: public BitBuffer(Buffer buffer) {
035: this .buffer = buffer;
036: }
037:
038: public void writeBits(int data, int len) {
039: while (bit + len >= 8) {
040: buffer.writeByte((byte) (b | (data << bit)));
041: flushOffstream();
042: data >>= 8 - bit;
043: len -= 8 - bit;
044: bit = b = 0;
045: }
046:
047: b |= data << bit;
048: bit += len;
049: }
050:
051: void flushOffstream() {
052: if (offstream != null) {
053: buffer.writeBuffer(offstream);
054: offstream = null;
055: }
056: }
057:
058: public void writeOffstreamByte(byte b) {
059: if (bit == 0)
060: buffer.writeByte(b);
061: else {
062: if (offstream == null)
063: offstream = new Buffer();
064: offstream.writeByte(b);
065: }
066: }
067:
068: public void close() {
069: if (bit != 0) {
070: buffer.writeByte((byte) b);
071: bit = b = 0;
072: }
073: flushOffstream();
074: }
075:
076: /** returns the bits or -1 if end of stream is reached */
077: public int readBits(int len) {
078: // fetch new byte if necessary
079: if (rbit == 8) {
080: if (buffer.remaining() == 0)
081: return -1;
082: b = buffer.readByte() & 0xFF;
083: rbit = 0;
084: }
085:
086: int n = 0, bb = 0;
087: while (rbit + len > 8) {
088: n |= (b >> rbit) << bb;
089: b = buffer.readByte() & 0xFF;
090: bb += 8 - rbit;
091: len -= 8 - rbit;
092: rbit = 0;
093: }
094: n |= ((b >> rbit) & ((1 << len) - 1)) << bb;
095: rbit += len;
096: return n;
097: }
098:
099: /** returns a byte (0..255) or -1 if end of stream is reached */
100: public int readOffstreamByte() {
101: if (buffer.remaining() == 0)
102: return -1;
103: return buffer.readByte() & 0xFF;
104: }
105: }
|