Paste: ULZ Decoder

Author: CapitalEx
Mode: factor
Date: Thu, 16 Nov 2023 20:50:33
Plain Text |
! Copyright (C) 2023 CapitalEx.
! See https://factorcode.org/license.txt for BSD license.
USING: accessors combinators io.encodings.binary io.files kernel
math ranges sequences ;
IN: ulz

TUPLE: decoder data ip out ;

: <decoder> ( file -- decoder )
    binary file-contents 0 SBUF"" clone \ decoder boa ;

: copy-forward ( src to from -- )
    [a..b) dupd [ swap nth swap push ] 2with each ;

: next-by ( decoder length -- decoder ) '[ _ + ] change-ip ; inline
: next    ( decoder        -- decoder ) 1 next-by ; inline
: current ( decoder        -- byte    ) [ ip>> ] [ data>> ] bi ?nth ;

: current2 ( decoder -- dbyte )
    [ current 8 shift ] [ next current ] bi + ;

: lit ( decoder length -- )
    { [ drop out>> ] 
      [ drop ip>> ] 
      [ swap ip>> + ] 
      [ drop data>> ] } 2cleave subseq append! drop ;

: cpy-start ( decoder offset -- i ) neg swap out>> length + ;

: cpy ( decoder length offset -- )
    { [ 2drop out>> ] 
      [ nip cpy-start ] 
      [ swap [ cpy-start ] dip + ] } 3cleave copy-forward ;

GENERIC: interpret ( decoder -- decoder )

M: predicate{ decoder [ current 0xc0 bitand 0x00 = ] } interpret
    [ current ] [ next ] bi swap 1 + [ lit ] [ next-by ] 2bi ;

M: predicate{ decoder [ current 0xc0 bitand 0x80 = ] } interpret
    [ current 0x3F bitand 4 + ] 
    [ next current 1 + ] [ next ] tri -rot [ cpy ] keepdd ;

M: predicate{ decoder [ current 0xc0 bitand 0xc0 = ] } interpret
    [ current2 0x3FFF bitand 4 + ]
    [ next current 1 + ] [ next ] tri -rot [ cpy ] keepdd ;

: decode ( file -- string )
    <decoder> 
        [ dup current ] 
        [ interpret   ] 
    while out>> ;

Annotation: ULZ v2

Author: Capital
Mode: factor
Date: Thu, 16 Nov 2023 21:24:56
Plain Text |
USING: accessors combinators io io.encodings.binary io.files
kernel math ranges sbufs sequences strings ;
IN: ulz

: copy-forward ( buffer to from -- )
    [a..b) dupd [ swap nth swap push ] 2with each ;

: cpy-start ( decoder offset -- i ) neg swap length + ;

: cpy ( buffer length offset -- )
    swap [ dup ] [ cpy-start ] [ over + ] tri* copy-forward ;

: lit ( buffer op -- buffer )
    dupd 1 + [ read1 suffix! ] times drop ;

: cpy1 ( buffer op -- buffer )
    dupd 0x3F bitand 4 + read1 1 + cpy ;

: cpy2 ( buffer op -- buffer )
    dupd 8 shift 0x3FFF bitand 4 + read1 1 + cpy ;

: interpret ( buffer -- buffer )
    read1 [ 
        dup 0xc0 bitand {
            { 0x00 [ lit  ] }
            { 0x80 [ cpy1 ] }
            { 0xc0 [ cpy2 ] }
        } case interpret
    ] when* ; recursive 

: decode ( file -- string )
    binary <file-reader> [ 
        0 <sbuf> interpret 
    ] with-input-stream >string ;

Annotation: ULZ v3 (Fixed CPY2)

Author: CapitalEx
Mode: factor
Date: Thu, 16 Nov 2023 22:34:14
Plain Text |
USING: combinators io io.encodings.binary io.files kernel math
ranges sbufs sequences strings ;
IN: ulz

: copy-forward ( buffer to from -- )
    [a..b) dupd [ swap nth swap push ] 2with each ;

: cpy-start ( decoder offset -- i ) neg swap length + ;

: (cpy) ( buffer length offset -- )
    swap [ dup ] [ cpy-start ] [ over + ] tri* copy-forward ;

: lit ( buffer op -- buffer )
    dupd 1 + [ read1 suffix! ] times drop ;

: cpy ( buffer op -- buffer )
    dupd 0x3F 0xc0 [ bitand ] bi-curry@ bi 0xc0 = [
        8 shift read1 bitor
    ] when 4 + read1 1 + (cpy) ;

: interpret ( buffer -- buffer )
    read1 [ 
        dup 0xc0 bitand {
            { 0x00 [ lit ] }
            [ drop cpy ]
        } case interpret
    ] when* ; recursive 

: decode ( file -- string )
    binary <file-reader> [ 
        0 <sbuf> interpret 
    ] with-input-stream >string ;

Annotation: ULZ v3 (Remove unneeded case)

Author: CapitalEx
Mode: factor
Date: Thu, 16 Nov 2023 23:52:04
Plain Text |
USING: combinators io io.encodings.binary io.files kernel math
ranges sbufs sequences strings ;
IN: ulz

: copy-forward ( buffer to from -- )
    [a..b) dupd [ swap nth swap push ] 2with each ;

: cpy-start ( decoder offset -- i ) neg swap length + ;

: (cpy) ( buffer length offset -- )
    swap [ dup ] [ cpy-start ] [ over + ] tri* copy-forward ;

: lit ( buffer op -- buffer )
    dupd 1 + [ read1 suffix! ] times drop ;

: cpy ( buffer op -- buffer )
    dupd 0x3F 0xc0 [ bitand ] bi-curry@ bi 0xc0 = [
        8 shift read1 bitor
    ] when 4 + read1 1 + (cpy) ;

: interpret ( buffer -- buffer )
    read1 [ 
        dup 0xc0 bitand 0 = [ lit ] [ cpy ] if interpret
    ] when* ; recursive

: decode ( file -- string )
    binary <file-reader> [ 
        0 <sbuf> interpret 
    ] with-input-stream >string ;

Annotation: ULZ v4 (A Side of Fries)

Author: CapitalEx
Mode: factor
Date: Fri, 17 Nov 2023 05:51:23
Plain Text |
USING: combinators io io.encodings.binary io.files kernel math
ranges sbufs sequences strings ;
IN: ulz

: copy-forward ( sbuf to from -- )
    [a..b) dupd -rot '[ _ nth _ push ] each ;

: cpy-start ( decoder offset -- i ) neg swap length + ;

: (cpy) ( sbuf length offset -- )
    swap [ dup ] [ cpy-start ] [ over + ] tri* copy-forward ;

: lit ( sbuf op -- sbuf )
    1 + over '[ read1 _ push ] times ;

: cpy ( sbuf op -- sbuf )
    dupd 63 192 [ bitand ] bi-curry@ bi 0xc0 = [
        8 shift read1 bitor
    ] when 4 + read1 1 + (cpy) ;

: interpret ( sbuf -- sbuf )
    read1 [ 
        dup 63 bitand 0 = [ lit ] [ cpy ] if interpret
    ] when* ; recursive

: decode ( file -- string )
    binary <file-reader> [ 
        0 <sbuf> interpret 
    ] with-input-stream >string ;

New Annotation

Summary:
Author:
Mode:
Body: