/******************************************************************************* * Copyright (c) 2005-2011, G. Weirich and Elexis * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * G. Weirich - initial implementation * *******************************************************************************/ package ch.rgw.io; import java.io.IOException; import java.io.InputStream; /** * An InputStream for bitwise reading. * * @author Gerry */ public class BitInputStream extends InputStream { public static final String Version(){ return "0.3.3"; } private int buffer; private int pos; InputStream stream; public BitInputStream(InputStream in){ stream = in; pos = 0; } /** * reads a byte, starting not at byte boundaries, but at the last read bit. * * @see java.io.InputStream#read() */ public int read() throws IOException{ return pullBits(8); } /** * reads up to 32 bits and returns them as int. * * @param bitnum * number of bits to read * @return the integer containing the requested bits (left-padded with zero) * @throws IOException */ public int pullBits(int bitnum) throws IOException{ int mask = 1 << (bitnum - 1); int ret = 0; while (mask != 0) { if (readBit() == true) { ret |= mask; } mask >>= 1; } return ret; } /** * reads a single bit * * @return true for an 1-Bit, false for a 0-Bit * @throws IOException */ public boolean readBit() throws IOException{ if (pos == 0) { buffer = stream.read(); pos = 128; } boolean res = (buffer & pos) == pos; pos >>= 1; return res; } /** * Tells whether one or more bits can be read without blocking. CAUTION: The returned number * does <b>not</b> accurately indicate the number of waiting bits (Only zero or non-zero is * guaranteed) */ public int available() throws IOException{ if (stream.available() > 0) return 1; if (pos > 0) return 1; return 0; } public void close() throws IOException{ stream.close(); } }