Warning: session_start(): open(/var/lib/php/sessions/sess_av7epkk1aiqvkrvhoj6d048bf3, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
sclass BitHead > ByteHead {
gettable int align = 8;
gettable int currentByte;
replace SomethingIO with BitIO.
*() {}
*(InputStream inputStream) { super(inputStream); }
*(OutputStream outputStream) { super(outputStream); }
bool writeArraysSlowly() { false; }
// choose fast or slow version depending on alignment
void write(byte[] data) {
if (align == 0 && !writeArraysSlowly())
super.write(data);
else
for (b : data) write(b);
}
void writeByte(int i) {
if (align == 0)
super.writeByte(i);
else {
currentByte |= i << align;
super.writeByte(currentByte);
currentByte = i >> (8-align);
}
}
void writeBit(int i) {
writeBit((i & 1) != 0);
}
void writeBit(bool b) {
align &= 7;
if (b) currentByte |= 1 << align;
if (align == 7) {
super.writeByte(currentByte);
currentByte = align = 0;
} else
++align;
}
int readByte() {
print("readByte: align=" + align + ", byteCounter=" + byteCounter);
byte value;
if (align == 0) {
value = currentByte;
align = 8;
} else if (align == 8)
value = super.readByte();
else {
value = currentByte >> align;
int align = this.align;
bufferNextByte();
if (isEOF()) ret -1;
value |= (currentByte << (8-align)) & 0xFF;
}
print("value: " + value);
ret value;
}
bool readBit() {
bool bitSet = peekBit();
advanceBit();
ret bitSet;
}
bool peekBit() {
if (currentByte < 0)
fail("eof");
if (align == 8)
bufferNextByte();
ret (currentByte & (1 << align)) != 0;
}
void bufferNextByte {
currentByte = super.readByte();
align = 0;
}
void advanceBit {
if (currentByte < 0) ret;
if (align == 8)
bufferNextByte();
++align;
}
bool byteAligned() {
ret align == 0;
}
void completeByte aka flushBits aka finishByte aka finish(bool padWithOnes default false) {
if (byteAligned()) ret;
print("Finishing byte " + byteCounter + " (align " + align + ")");
if (writeMode()) {
if (padWithOnes) currentByte |= 0xFF << align;
super.writeByte(currentByte);
}
currentByte = align = 0;
}
// TODO: switch to more compact version saving 5 bits on average
void writeTrailingBitCount aka trailingBitCount(bool padWithOnes default false) {
if (!writeMode()) ret;
int bitCount = modRange_incl(align(), 1, 8);
completeByte(padWithOnes);
writeByte(bitCount);
}
void exchange(SomethingIO writable) {
if (writable != null) writable.readWrite(this);
}
void exchangeBit(IF0 getter, IVF1 setter) {
if (writeMode())
writeBit(getter!);
if (readMode())
setter.get(readBit());
}
void exchangeBit(int i) { exchangeBit(odd(i)); }
void exchangeBit(bool i) {
exchangeBit(-> i, j -> assertEquals(i, j));
}
void exchange(BitIO getter, Runnable setter) {
if (writeMode())
getter.readWrite(this);
if (readMode())
setter.run();
}
bool isEOF() { ret currentByte < 0; }
}