lloda pushed a commit to branch main in repository guile. commit 4739eae499f35b0e87ed4dba8ebaf4548d2e8faa Author: Rob Browning <r...@defaultvalue.org> AuthorDate: Wed Sep 10 14:31:27 2025 -0500
bytevector->hex-string: avoid constructing intermediate strings Compute bytevector->hex-string result directly from a list of characters via to avoid having to construct intermediate strings for each byte. * module/srfi/srfi-207.scm (bytevector->hex-string): Build one string via list->string. * module/srfi/srfi-207/upstream/bytestrings-impl.scm (bytevector->hex-string): Move to srfi-207.scm. --- module/srfi/srfi-207.scm | 23 +++++++++++++++++++++- module/srfi/srfi-207/upstream/bytestrings-impl.scm | 15 -------------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/module/srfi/srfi-207.scm b/module/srfi/srfi-207.scm index a4c8ae104..56085d6be 100644 --- a/module/srfi/srfi-207.scm +++ b/module/srfi/srfi-207.scm @@ -25,7 +25,10 @@ (define-module (srfi srfi-207) #:use-module ((rnrs arithmetic bitwise) #:select (bitwise-and bitwise-ior)) #:use-module ((rnrs bytevectors) - #:select (bytevector->u8-list string->utf8 u8-list->bytevector)) + #:select (bytevector->u8-list + bytevector-u8-ref + string->utf8 + u8-list->bytevector)) #:use-module ((scheme base) #:select (binary-port? bytevector @@ -142,6 +145,24 @@ (make-bytestring! result 0 parts) result)) +(define (bytevector->hex-string bv) + (assume (bytevector? bv)) + (define (integer->hex-char n) + (case n + ((0) #\0) ((1) #\1) ((2) #\2) ((3) #\3) ((4) #\4) + ((5) #\5) ((6) #\6) ((7) #\7) ((8) #\8) ((9) #\9) + ((10) #\a) ((11) #\b) ((12) #\c) ((13) #\d) ((14) #\e) ((15) #\f) + (else (error "Should not be possible, half-byte out of hex range:" n)))) + (list->string + (let loop ((i (1- (bytevector-length bv))) (result '())) + (if (= i -1) + result + (let ((b (bytevector-u8-ref bv i))) + (loop (1- i) + (cons* (integer->hex-char (ash b -4)) + (integer->hex-char (logand b #x0f)) + result))))))) + (define read-textual-bytestring (case-lambda ((prefix) (read-textual-bytestring prefix (current-input-port))) diff --git a/module/srfi/srfi-207/upstream/bytestrings-impl.scm b/module/srfi/srfi-207/upstream/bytestrings-impl.scm index 23379813b..e5a8e443c 100644 --- a/module/srfi/srfi-207/upstream/bytestrings-impl.scm +++ b/module/srfi/srfi-207/upstream/bytestrings-impl.scm @@ -61,21 +61,6 @@ ;;; Hex string conversion -(define (integer->hex-string n) - (cond ((number->string n 16) => - (lambda (res) - (if (even? (string-length res)) - res - (string-append "0" res)))) - (else (bytestring-error "not an integer" n)))) - -(define (bytevector->hex-string bv) - (assume (bytevector? bv)) - (string-concatenate - (list-tabulate (bytevector-length bv) - (lambda (i) - (integer->hex-string (bytevector-u8-ref bv i)))))) - (define (hex-string->bytevector hex-str) (unless (string? hex-str) (bytestring-error "invalid hex-str argument" hex-str))