You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
typesetting/xenomorph/xenomorph/helper.rkt

73 lines
3.0 KiB
Racket

#lang debug racket/base
(require racket/private/generic-methods
racket/dict
racket/port
racket/class
"generic.rkt")
(provide (all-defined-out))
(define private-keys '(parent _startOffset _currentOffset _length))
(define (dump-mutable x)
(define h (make-hasheq))
(for ([(k v) (in-dict (dump x))])
(hash-set! h k v))
h)
(define (dump x)
(cond
[(input-port? x) (port->bytes x)]
[(output-port? x) (get-output-bytes x)]
[(dict? x) (for/hasheq ([(k v) (in-dict x)]
#:unless (memq k private-keys))
(values k v))]
[(list? x) (map dump x)]
[else x]))
(define (pos p [new-pos #f])
(when new-pos
(file-position p new-pos))
(file-position p))
(define xenomorphic<%>
(interface* ()
([(generic-property gen:xenomorphic)
(generic-method-table gen:xenomorphic
(define (decode xo [port-arg (current-input-port)] #:parent [parent #f])
(define port
(cond
[(input-port? port-arg) port-arg]
[(bytes? port-arg) (open-input-bytes port-arg)]
[else (raise-argument-error 'decode "byte string or input port" port-arg)]))
(send xo xxdecode port parent))
(define (encode xo val [port-arg (current-output-port)]
#:parent [parent #f])
(define port (if (output-port? port-arg) port-arg (open-output-bytes)))
(send xo xxencode val port parent)
(unless port-arg (get-output-bytes port)))
(define (size xo [val #f] #:parent [parent #f])
(send xo xxsize val parent)))])))
(define (xenomorphic-type? x) (is-a? x xenobase%))
(define xenobase%
(class* object% (xenomorphic<%>)
(super-new)
(define/pubment (xxdecode input-port [parent #f])
(post-decode (inner (error 'xxdecode-not-augmented) xxdecode input-port parent)))
(define/pubment (xxencode val output-port [parent #f])
(define encode-result (inner (error 'xxencode-not-augmented) xxencode (pre-encode val) output-port parent))
(when (bytes? encode-result) (write-bytes encode-result output-port)))
(define/pubment (xxsize [val #f] [parent #f])
(define size (inner 0 xxsize val parent))
(unless (and (integer? size) (not (negative? size)))
(raise-argument-error 'size "nonnegative integer" size))
size)
(define/public (post-decode val) val)
(define/public (pre-encode val) val)))