101 lines
2.6 KiB
Plaintext
101 lines
2.6 KiB
Plaintext
import "io" for File
|
|
|
|
class BitFilter {
|
|
construct new(name) {
|
|
_name = name
|
|
_accu = 0
|
|
_bits = 0
|
|
}
|
|
|
|
openWriter() {
|
|
_bw = File.create(_name)
|
|
}
|
|
|
|
openReader() {
|
|
_br = File.open(_name)
|
|
_offset = 0
|
|
}
|
|
|
|
write(buf, start, nBits, shift) {
|
|
var index = start + (shift/8).floor
|
|
shift = shift % 8
|
|
while (nBits != 0 || _bits >= 8) {
|
|
while (_bits >= 8) {
|
|
_bits = _bits - 8
|
|
_bw.writeBytes(String.fromByte((_accu >> _bits) & 255))
|
|
}
|
|
while (_bits < 8 && nBits != 0) {
|
|
var b = buf[index]
|
|
_accu = (_accu << 1) | (((128 >> shift) & b) >> (7 - shift))
|
|
nBits = nBits - 1
|
|
_bits = _bits + 1
|
|
shift = shift + 1
|
|
if (shift == 8) {
|
|
shift = 0
|
|
index = index + 1
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
read(buf, start, nBits, shift) {
|
|
var index = start + (shift/8).floor
|
|
shift = shift % 8
|
|
while (nBits != 0) {
|
|
while (_bits != 0 && nBits != 0) {
|
|
var mask = 128 >> shift
|
|
if ((_accu & (1 << (_bits - 1))) != 0) {
|
|
buf[index] = (buf[index] | mask) & 255
|
|
} else {
|
|
buf[index] = (buf[index] & ~mask) & 255
|
|
}
|
|
nBits = nBits - 1
|
|
_bits = _bits - 1
|
|
shift = shift + 1
|
|
if (shift >= 8) {
|
|
shift = 0
|
|
index = index + 1
|
|
}
|
|
}
|
|
if (nBits == 0) break
|
|
var byte = _br.readBytes(1, _offset).bytes[0]
|
|
_accu = (_accu << 8) | byte
|
|
_bits = _bits + 8
|
|
_offset = _offset + 1
|
|
}
|
|
}
|
|
|
|
closeWriter() {
|
|
if (_bits != 0) {
|
|
_accu = _accu << (8 - _bits)
|
|
_bw.writeBytes(String.fromByte(_accu & 255))
|
|
}
|
|
_bw.close()
|
|
_accu = 0
|
|
_bits = 0
|
|
}
|
|
|
|
closeReader() {
|
|
_br.close()
|
|
_accu = 0
|
|
_bits = 0
|
|
_offset = 0
|
|
}
|
|
}
|
|
|
|
var s = "abcdefghijk".bytes.toList
|
|
var f = "test.bin"
|
|
var bf = BitFilter.new(f)
|
|
|
|
/* for each byte in s, write 7 bits skipping 1 */
|
|
bf.openWriter()
|
|
for (i in 0...s.count) bf.write(s, i, 7, 1)
|
|
bf.closeWriter()
|
|
|
|
/* read 7 bits and expand to each byte of s2 skipping 1 bit */
|
|
bf.openReader()
|
|
var s2 = List.filled(s.count, 0)
|
|
for (i in 0...s2.count) bf.read(s2, i, 7, 1)
|
|
bf.closeReader()
|
|
System.print(s2.map { |b| String.fromByte(b) }.join())
|