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 ; : ?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>> [ bits 1 - + ] keep bit-range reader [ bits + ] change-current-bit ?advance drop ; : bits-left ( reader -- n ) 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 ) 2dup current-bit>> + 8 < [ read-single-value ] [ read-multi-value ] if ;