#### Bzip2 Implementation
#### Copyright (C) 2023-2024 Remilia Scarlet
#### Copyright (c) 2022 drone1400
#### Copyright (C) 2015 Jaime Olivares
#### Copyright (c) 2011 Matthew Francis
#### MIT License
####
#### Ported from the Java implementation by Matthew Francis:
#### https://github.com/MateuszBartosiewicz/bzip2.
####
#### Modified by drone1400
####
#### Ported by Remilia Scarlet from the C# implementation by Jamie Olivares:
#### http://github.com/jaime-olivares/bzip2
module RemiLib::Compression::BZip2
private class BitWriter
protected getter io : IO
# A buffer of bits waiting to be written to the output stream.
@bitBuffer : UInt32 = 0
# The number of bits currently buffered in bitBuffer.
@bitCount : Int32 = 0
# Creates a new `BitWriter` instance that will write to the given `IO`.
def initialize(@io : IO)
end
@[AlwaysInline]
def writeBoolean(value : Bool) : Nil
@bitCount += 1
@bitBuffer |= (value ? 1u32 : 0u32) << (32 - @bitCount)
if @bitCount == 8
@io.write_byte((@bitBuffer >> 24).to_u8!)
@bitBuffer = 0
@bitCount = 0
end
end
@[AlwaysInline]
def writeUnary(value : Int) : Nil
while value > 0
writeBoolean(true)
value -= 1
end
writeBoolean(false)
end
@[AlwaysInline]
def writeBits(count : Int, value : Int32|UInt32)
@bitBuffer |= (value.to_u32! << (32 - count)) >> @bitCount
@bitCount += count
while @bitCount >= 8
@io.write_byte((@bitBuffer >> 24).to_u8!)
@bitBuffer <<= 8
@bitCount -= 8
end
end
@[AlwaysInline]
def writeInt32(value : Int32|UInt32) : Nil
writeBits(16, (value.to_u32! >> 16) & 0xFFFF)
writeBits(16, value.to_u32! & 0xFFFF)
end
@[AlwaysInline]
def flush : Nil
if @bitCount > 0
writeBits(8 - @bitCount, 0)
end
end
end
end
|