USING: kernel locals accessors math sequences math.bitwise ; TUPLE: bit-reader byte-array current-pos current-bit ; : ( bytearray -- bitreader ) 0 0 bit-reader boa ; : advance ( reader -- reader ) 0 >>current-bit [ 1 + ] change-current-pos ; : check-advance ( reader -- reader ) dup current-bit>> 8 = [ advance ] when ; :: read-single-value ( bits reader -- result ) reader current-pos>> reader byte-array>> nth reader current-bit>> dup bits 1 - + swap bit-range reader [ bits + ] change-current-bit check-advance drop ; : bits-left ( reader -- result ) current-bit>> 8 swap - ; DEFER: read-bits :: read-multi-value ( bits reader -- result ) reader bits-left :> extra-bits extra-bits reader read-single-value bits extra-bits - reader read-bits extra-bits shift + ; :: read-bits ( bits reader -- result ) reader current-bit>> bits + 8 < [ bits reader read-single-value ] [ bits reader read-multi-value ] if ;