/*
 * Copyright 2014 The Netty Project
 *
 * The Netty Project licenses this file to you under the Apache License,
 * version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
package io.netty.handler.codec.compression;

import io.netty.buffer.ByteBuf;

An bit reader that allows the reading of single bit booleans, bit strings of arbitrary length (up to 32 bits), and bit aligned 32-bit integers. A single byte at a time is read from the ByteBuf when more bits are required.
/** * An bit reader that allows the reading of single bit booleans, bit strings of * arbitrary length (up to 32 bits), and bit aligned 32-bit integers. A single byte * at a time is read from the {@link ByteBuf} when more bits are required. */
class Bzip2BitReader {
Maximum count of possible readable bytes to check.
/** * Maximum count of possible readable bytes to check. */
private static final int MAX_COUNT_OF_READABLE_BYTES = Integer.MAX_VALUE >>> 3;
The ByteBuf from which to read data.
/** * The {@link ByteBuf} from which to read data. */
private ByteBuf in;
A buffer of bits read from the input stream that have not yet been returned.
/** * A buffer of bits read from the input stream that have not yet been returned. */
private long bitBuffer;
The number of bits currently buffered in bitBuffer.
/** * The number of bits currently buffered in {@link #bitBuffer}. */
private int bitCount;
Set the ByteBuf from which to read data.
/** * Set the {@link ByteBuf} from which to read data. */
void setByteBuf(ByteBuf in) { this.in = in; }
Reads up to 32 bits from the ByteBuf.
Params:
  • count – The number of bits to read (maximum 32 as a size of int)
Returns:The bits requested, right-aligned within the integer
/** * Reads up to 32 bits from the {@link ByteBuf}. * @param count The number of bits to read (maximum {@code 32} as a size of {@code int}) * @return The bits requested, right-aligned within the integer */
int readBits(final int count) { if (count < 0 || count > 32) { throw new IllegalArgumentException("count: " + count + " (expected: 0-32 )"); } int bitCount = this.bitCount; long bitBuffer = this.bitBuffer; if (bitCount < count) { long readData; int offset; switch (in.readableBytes()) { case 1: { readData = in.readUnsignedByte(); offset = 8; break; } case 2: { readData = in.readUnsignedShort(); offset = 16; break; } case 3: { readData = in.readUnsignedMedium(); offset = 24; break; } default: { readData = in.readUnsignedInt(); offset = 32; break; } } bitBuffer = bitBuffer << offset | readData; bitCount += offset; this.bitBuffer = bitBuffer; } this.bitCount = bitCount -= count; return (int) (bitBuffer >>> bitCount & (count != 32 ? (1 << count) - 1 : 0xFFFFFFFFL)); }
Reads a single bit from the ByteBuf.
Returns:true if the bit read was 1, otherwise false
/** * Reads a single bit from the {@link ByteBuf}. * @return {@code true} if the bit read was {@code 1}, otherwise {@code false} */
boolean readBoolean() { return readBits(1) != 0; }
Reads 32 bits of input as an integer.
Returns:The integer read
/** * Reads 32 bits of input as an integer. * @return The integer read */
int readInt() { return readBits(32); }
Refill the ByteBuf by one byte.
/** * Refill the {@link ByteBuf} by one byte. */
void refill() { int readData = in.readUnsignedByte(); bitBuffer = bitBuffer << 8 | readData; bitCount += 8; }
Checks that at least one bit is available for reading.
Returns:true if one bit is available for reading, otherwise false
/** * Checks that at least one bit is available for reading. * @return {@code true} if one bit is available for reading, otherwise {@code false} */
boolean isReadable() { return bitCount > 0 || in.isReadable(); }
Checks that the specified number of bits available for reading.
Params:
  • count – The number of bits to check
Returns:true if count bits are available for reading, otherwise false
/** * Checks that the specified number of bits available for reading. * @param count The number of bits to check * @return {@code true} if {@code count} bits are available for reading, otherwise {@code false} */
boolean hasReadableBits(int count) { if (count < 0) { throw new IllegalArgumentException("count: " + count + " (expected value greater than 0)"); } return bitCount >= count || (in.readableBytes() << 3 & Integer.MAX_VALUE) >= count - bitCount; }
Checks that the specified number of bytes available for reading.
Params:
  • count – The number of bytes to check
Returns:true if count bytes are available for reading, otherwise false
/** * Checks that the specified number of bytes available for reading. * @param count The number of bytes to check * @return {@code true} if {@code count} bytes are available for reading, otherwise {@code false} */
boolean hasReadableBytes(int count) { if (count < 0 || count > MAX_COUNT_OF_READABLE_BYTES) { throw new IllegalArgumentException("count: " + count + " (expected: 0-" + MAX_COUNT_OF_READABLE_BYTES + ')'); } return hasReadableBits(count << 3); } }