mirror of
https://github.com/tsolomko/SWCompression.git
synced 2026-06-23 14:56:41 +00:00
Also changes were made to adopt this removal. This was done to improve behavior in some corner cases as well as enforce intentional usage of particular integer types.
167 lines
4.0 KiB
Swift
167 lines
4.0 KiB
Swift
// Copyright (c) 2017 Timofey Solomko
|
|
// Licensed under MIT License
|
|
//
|
|
// See LICENSE for license information
|
|
|
|
import Foundation
|
|
|
|
class BitReader: DataWithPointer {
|
|
|
|
enum BitOrder {
|
|
case straight
|
|
case reversed
|
|
}
|
|
|
|
let bitOrder: BitOrder
|
|
private(set) var bitMask: UInt8
|
|
|
|
convenience init(array: inout [UInt8], bitOrder: BitOrder) {
|
|
self.init(data: Data(bytes: array), bitOrder: bitOrder)
|
|
}
|
|
|
|
init(data: Data, bitOrder: BitOrder) {
|
|
self.bitOrder = bitOrder
|
|
switch self.bitOrder {
|
|
case .reversed:
|
|
self.bitMask = 1
|
|
case .straight:
|
|
self.bitMask = 128
|
|
}
|
|
super.init(data: data)
|
|
}
|
|
|
|
func bits(count: Int) -> [UInt8] {
|
|
guard count > 0 else {
|
|
return []
|
|
}
|
|
|
|
var array: [UInt8] = Array(repeating: 0, count: count)
|
|
for i in 0..<count {
|
|
array[i] = self.data[self.index] & self.bitMask > 0 ? 1 : 0
|
|
|
|
switch self.bitOrder {
|
|
case .reversed:
|
|
if self.bitMask == 128 {
|
|
self.index += 1
|
|
self.bitMask = 1
|
|
} else {
|
|
self.bitMask <<= 1
|
|
}
|
|
case .straight:
|
|
if self.bitMask == 1 {
|
|
self.index += 1
|
|
self.bitMask = 128
|
|
} else {
|
|
self.bitMask >>= 1
|
|
}
|
|
}
|
|
}
|
|
|
|
return array
|
|
}
|
|
|
|
func intFromBits(count: Int) -> Int {
|
|
guard count > 0 else {
|
|
return 0
|
|
}
|
|
|
|
var result = 0
|
|
for i in 0..<count {
|
|
let power: Int
|
|
switch self.bitOrder {
|
|
case .straight:
|
|
power = count - i - 1
|
|
case .reversed:
|
|
power = i
|
|
}
|
|
|
|
let bit = self.data[self.index] & self.bitMask > 0 ? 1 : 0
|
|
result += (1 << power) * bit
|
|
|
|
switch self.bitOrder {
|
|
case .reversed:
|
|
if self.bitMask == 128 {
|
|
self.index += 1
|
|
self.bitMask = 1
|
|
} else {
|
|
self.bitMask <<= 1
|
|
}
|
|
case .straight:
|
|
if self.bitMask == 1 {
|
|
self.index += 1
|
|
self.bitMask = 128
|
|
} else {
|
|
self.bitMask >>= 1
|
|
}
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
func bit() -> Int {
|
|
let bit = self.data[self.index] & self.bitMask > 0 ? 1 : 0
|
|
|
|
switch self.bitOrder {
|
|
case .reversed:
|
|
if self.bitMask == 128 {
|
|
self.index += 1
|
|
self.bitMask = 1
|
|
} else {
|
|
self.bitMask <<= 1
|
|
}
|
|
case .straight:
|
|
if self.bitMask == 1 {
|
|
self.index += 1
|
|
self.bitMask = 128
|
|
} else {
|
|
self.bitMask >>= 1
|
|
}
|
|
}
|
|
|
|
return bit
|
|
}
|
|
|
|
func skipUntilNextByte() {
|
|
switch self.bitOrder {
|
|
case .reversed:
|
|
guard self.bitMask != 1 else {
|
|
return
|
|
}
|
|
self.bitMask = 1
|
|
case .straight:
|
|
guard self.bitMask != 128 else {
|
|
return
|
|
}
|
|
self.bitMask = 128
|
|
}
|
|
self.index += 1
|
|
}
|
|
|
|
override func byte() -> UInt8 {
|
|
self.skipUntilNextByte()
|
|
return super.byte()
|
|
}
|
|
|
|
override func bytes(count: Int) -> [UInt8] {
|
|
self.skipUntilNextByte()
|
|
return super.bytes(count: count)
|
|
}
|
|
|
|
override func uint64(count: UInt64 = 8) -> UInt64 {
|
|
self.skipUntilNextByte()
|
|
return super.uint64(count: count)
|
|
}
|
|
|
|
override func uint32(count: UInt32 = 4) -> UInt32 {
|
|
self.skipUntilNextByte()
|
|
return super.uint32(count: count)
|
|
}
|
|
|
|
override func uint16(count: UInt16 = 2) -> UInt16 {
|
|
self.skipUntilNextByte()
|
|
return super.uint16(count: count)
|
|
}
|
|
|
|
}
|