29
29
(declare (usual-integrations))
31
(define (initialize-package!)
32
(set! output-string-port-type
33
(make-port-type `((WRITE-SELF ,operation/write-self)
34
(WRITE-CHAR ,operation/write-char)
35
(WRITE-SUBSTRING ,operation/write-substring))
38
31
(define (with-output-to-truncated-string max thunk)
39
32
(call-with-current-continuation
45
(make-output-string-state return max '() max)))
47
(make-port output-string-port-type state)
49
(output-string-state/accumulator state))))))))
34
(let ((state (make-astate k max (make-string (fix:min max 128)) 0)))
35
(with-output-to-port (make-port output-string-port-type state)
40
(string-head (astate-chars state)
41
(astate-index state)))))))))
51
43
(define output-string-port-type)
44
(define (initialize-package!)
45
(set! output-string-port-type
49
(guarantee-8-bit-char char)
50
(let ((state (port/state port)))
53
(let* ((n (astate-index state)))
54
(if (fix:< n (astate-max-length state))
55
(let ((n* (fix:+ n 1)))
56
(if (fix:= n (string-length (astate-chars state)))
57
(grow-accumulator! state n*))
58
(string-set! (astate-chars state) n char)
59
(set-astate-index! state n*))
60
((astate-return state)
61
(cons #t (string-copy (astate-chars state)))))))))
64
,(lambda (port output-port)
66
(write-string " to string (truncating)" output-port))))
53
(define-structure (output-string-state (type vector)
54
(conc-name output-string-state/))
70
(define-structure (astate (type vector))
55
71
(return #f read-only #t)
56
72
(max-length #f read-only #t)
60
(define (operation/write-char port char)
61
(let ((state (port/state port)))
62
(let ((accumulator (output-string-state/accumulator state))
63
(counter (output-string-state/counter state)))
65
((output-string-state/return state)
66
(cons #t (apply string-append (reverse! accumulator))))
68
(set-output-string-state/accumulator!
70
(cons (string char) accumulator))
71
(set-output-string-state/counter! state (-1+ counter)))))))
73
(define (operation/write-substring port string start end)
74
(let ((state (port/state port)))
76
(cons (substring string start end)
77
(output-string-state/accumulator state)))
78
(counter (- (output-string-state/counter state) (- end start))))
79
(if (negative? counter)
80
((output-string-state/return state)
82
(substring (apply string-append (reverse! accumulator))
84
(output-string-state/max-length state))))
86
(set-output-string-state/accumulator! state accumulator)
87
(set-output-string-state/counter! state counter))))))
89
(define (operation/write-self port output-port)
91
(write-string " to string (truncating)" output-port))
b'\\ No newline at end of file'
76
(define (grow-accumulator! state min-size)
77
(let* ((old (astate-chars state))
78
(n (string-length old))
81
(let loop ((n (fix:+ n n)))
82
(if (fix:>= n min-size)
83
(fix:min n (astate-max-length state))
84
(loop (fix:+ n n)))))))
85
(substring-move! old 0 n new 0)
86
(set-astate-chars! state new)))
b'\\ No newline at end of file'