Sınıf şöyle olsun. Byte'lar yazacağımız için 8 tane mask yeterli.
Constructor metodlar şöylepublic class BitStream {protected byte[] data;protected byte[] sizeInBytes;protected int bitPosition;protected int bytePosition;static final int BYTE_LENGTH = 8;static final int DEFAULT_SIZE = 16;static final int GROW_SIZE = 16;static int[] MASKS = {0, //00x1, //10x3, //20x7, //30xf, //40x1f, //50x3f, //60x7f, //70xff, //8}...}
//For writing public BitStream { data = new byte[DEFAULT_SIZE]; sizeInBytes = data.length; } //For writing public BitStream(int capacity) { data = new byte[capacity]; sizeInBytes = data.length; } //For reading public BitStream(byte[] data { this.data = data; sizeInBytes = data.length; }
Bazı yardımcı metodlar şöyle
public void flipForReading(){data = toByteArray();bitPosition = 0;bytePosition = 0;}public void growCapacity() {data = Arrays.copyOf(data,data.length + GROW_SIZE);}//Compelete or partial readable bytes after write operationpublic int getReadableBytes() {if (bytePosition == 0 && bitPosition == 0) {return 0;}return bytePosition + 1;}public byte[] toByteArray() {int length = getReadableBytes();return Arrays.copyOf(data,length);}
readNBits metodu
Burada en fazla 32 bit okunabilir. Bit shift işlemleri integer olarak yapılıyor ancak sonuç unsigned olsun diye long olarak döndürülüyor.
- //1 ile işaretli yerde mask bitPosition sayısı kadar kaydırılır. Böylece doğru mask elde edilir. Buffer'dan istenilen bit sayısı okunduktan sonra elde edilen değer tekrar sağa kaydırılır.
- //2 ile işaretli yerde okunan değer toplam okunan bit sayısı kadar kaydırılır ve sonuca dahil edilir.
public long readNBits (int numBits) { if (numBits > 32) { throw new IllegalArgumentException(); } int result = 0; int bitsReadSoFar = 0; while (numBits > 0) { int bitsToRead = numBits; //It is ok to pass the buffer boundary if (bitPosition == BYTE_LENGTH) { gotoNextByte(); } if (numBits + bitPosition) > BYTE_LENGTH) { bitsToRead = BYTE_LENGTH - bitPosition; } numberOfBits -= bitsToRead; //1 int buf = ((MASKS [bitsToRead] << bitPosition) & data [bytePosition]) >> bitPosition; bitPosition += bitsToRead; //2 result |= (buf << bitsReadSoFar); bitsReadSoFar += bitsToRead; } //while return Integer.toUnsignedLong(result); }
gotoNextByte şöyle
protected void gotoNextByte() { ++bytePosition; bitPosition = 0; }writeNBits metodu
Şöyle
public void writeNBits(long value, int numBits) {if (numbits > 32) {throw new IllegalArgumentException();}while(numBits > 0) {int bitsToWrite = numBits;if (bitPosition == BYTE_LENGTH) {gotoNextByte();}if ((numBits + bitPosition) > BYTE_LENGTH) {bitToWrite = BYTE_LENGTH - bitPosition;}numBits -= bitsToWrite;data[bytePosition] &= (byte) ~(MASKS[bitsToWrite] << bitPosition);data[bytePosition] |= (byte) ((value & MASKS[bitsToWrite]) << bitPosition);bitPosition += bitsToWrite;value = (value >> bitsToWrite);}}
Elimizde bu iki metod olduktan sonra diğer tipleri yazıp okumak kolay. Şöyle yaparız
public boolean readBoolean() {int data = (int) readNBits (1);return data == 1;}public void writeBoolean(boolean value) {int data = value ? 1 : 0;writeNBits(data,1);}public float readFloat() {int intBits = (int) readNBits(32);return Float.intBitsToFloat(intBits);}public void writeFloat(float value) {int intBits = Float.floatToRawIntBits(value);writeNBits(intBits,32);}
Hiç yorum yok:
Yorum Gönder