1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-29 19:30:36 +02:00
guile/module/ice-9/iconv.scm
Andy Wingo 0f42fef119 Add call-with-input-bytevector, call-with-output-bytevector
* module/ice-9/binary-ports.scm (call-with-input-bytevector):
  (call-with-output-bytevector): New functions.
* module/ice-9/iconv.scm: Remove superfluous copies of
  call-with-output-string* and call-with-output-bytevector*, now that
  the former closes the port and the latter exists.
  (call-with-encoded-output-string): Adapt.
* module/web/uri.scm: Use (ice-9 iconv) instead of local
  bytevector/string conversion procedures.
2021-01-12 12:09:19 +01:00

79 lines
3.2 KiB
Scheme

;;; Encoding and decoding byte representations of strings
;; Copyright (C) 2013, 2021 Free Software Foundation, Inc.
;;;; This library is free software; you can redistribute it and/or
;;;; modify it under the terms of the GNU Lesser General Public
;;;; License as published by the Free Software Foundation; either
;;;; version 3 of the License, or (at your option) any later version.
;;;;
;;;; This library is distributed in the hope that it will be useful,
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;;;; Lesser General Public License for more details.
;;;;
;;;; You should have received a copy of the GNU Lesser General Public
;;;; License along with this library; if not, write to the Free Software
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
;;; Code:
(define-module (ice-9 iconv)
#:use-module (rnrs bytevectors)
#:use-module (ice-9 binary-ports)
#:use-module ((ice-9 rdelim) #:select (read-string))
#:export (string->bytevector
bytevector->string
call-with-encoded-output-string))
(define* (call-with-encoded-output-string encoding proc
#:optional
(conversion-strategy 'error))
"Call PROC on a fresh port. Encode the resulting string as a
bytevector according to ENCODING, and return the bytevector."
(if (and (string-ci=? encoding "utf-8")
(eq? conversion-strategy 'error))
;; I don't know why, but this appears to be faster; at least for
;; serving examples/debug-sxml.scm (1464 reqs/s versus 850
;; reqs/s).
(string->utf8 (call-with-output-string proc))
(call-with-output-bytevector
(lambda (port)
(set-port-encoding! port encoding)
(if conversion-strategy
(set-port-conversion-strategy! port conversion-strategy))
(proc port)))))
;; TODO: Provide C implementations that call scm_from_stringn and
;; friends?
(define* (string->bytevector str encoding
#:optional (conversion-strategy 'error))
"Encode STRING according to ENCODING, which should be a string naming
a character encoding, like \"utf-8\"."
(if (and (string-ci=? encoding "utf-8")
(eq? conversion-strategy 'error))
(string->utf8 str)
(call-with-encoded-output-string
encoding
(lambda (port)
(display str port))
conversion-strategy)))
(define* (bytevector->string bv encoding
#:optional (conversion-strategy 'error))
"Decode the string represented by BV. The bytes in the bytevector
will be interpreted according to ENCODING, which should be a string
naming a character encoding, like \"utf-8\"."
(if (and (string-ci=? encoding "utf-8")
(eq? conversion-strategy 'error))
(utf8->string bv)
(let ((p (open-bytevector-input-port bv)))
(set-port-encoding! p encoding)
(if conversion-strategy
(set-port-conversion-strategy! p conversion-strategy))
(let ((res (read-string p)))
(close-port p)
(if (eof-object? res)
""
res)))))