Skip to content

Instantly share code, notes, and snippets.

@MagnificentPako
Last active March 19, 2017 15:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MagnificentPako/0c63a6b1e7394e8856cc229acc2a2c06 to your computer and use it in GitHub Desktop.
Save MagnificentPako/0c63a6b1e7394e8856cc229acc2a2c06 to your computer and use it in GitHub Desktop.
class BitWriter
var _content: Array[U8] = _content.create(1)
var _size: USize = 0
var _offset: USize = 0
fun ref done(): Array[U8] =>
var byte_amount: USize = (_content.size() / 8)
var output: Array[U8] ref = output.create(byte_amount)
if ((_content.size() % 8) != 0) then byte_amount = byte_amount + 1 end
while _content.size() > 0 do
var curr: Array[U8] = curr.create(8)
curr.push(_secure_pop(_content))
curr.push(_secure_pop(_content))
curr.push(_secure_pop(_content))
curr.push(_secure_pop(_content))
curr.push(_secure_pop(_content))
curr.push(_secure_pop(_content))
curr.push(_secure_pop(_content))
curr.push(_secure_pop(_content))
curr = curr.reverse()
output.push(_bits_to_byte(curr))
end
_content.reserve(1)
_size = 0
_offset = 0
output.reverse()
fun ref _check(size': USize) =>
if (_content.size() - _offset) < size' then
_content.undefined(_offset + size')
end
fun ref string(str: String) =>
for byte' in str.array().values() do
byte(byte')
end
fun ref byte_array(bytes: Array[U8]) =>
for byte' in bytes.values() do
byte(byte')
end
fun ref byte(byte': U8) =>
bit_array(_byte_to_bits(byte'))
fun ref bit_array(bits: Array[U8]) =>
_check(bits.size())
for bit' in bits.values() do
bit(bit')
end
fun ref bit(bit': U8) =>
try
_check(1)
_content(_offset) = (bit' and 0b00000001) //So it actually is just one bit
_offset = _offset + 1
_size = _size + 1
end
fun _byte_to_bits(byte': U8): Array[U8] =>
var bits: Array[U8] = bits.create(8)
var mask: U8 = 0b00000001
bits.push(((byte' >> 7) and mask))
bits.push(((byte' >> 6) and mask))
bits.push(((byte' >> 5) and mask))
bits.push(((byte' >> 4) and mask))
bits.push(((byte' >> 3) and mask))
bits.push(((byte' >> 2) and mask))
bits.push(((byte' >> 1) and mask))
bits.push((byte' and mask))
bits
fun _bits_to_byte(bits: Array[U8]): U8 =>
var res: U8 = 0
try
res = (bits.pop()) or
(bits.pop() << 1) or
(bits.pop() << 2) or
(bits.pop() << 3) or
(bits.pop() << 4) or
(bits.pop() << 5) or
(bits.pop() << 6) or
(bits.pop() << 7)
end
res
fun _secure_pop(ar: Array[U8]): U8 =>
var p: U8 = 0
try
var popped: (None | U8) = ar.pop()
p = match popped
| None => 0
else popped as U8 end
end
p
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment