slot-ref, slot-set! et al bypass "using-class" variants
[bpt/guile.git] / module / ice-9 / iconv.scm
CommitLineData
f05bb849
AW
1;;; Encoding and decoding byte representations of strings
2
3;; Copyright (C) 2013 Free Software Foundation, Inc.
4
5;;;; This library is free software; you can redistribute it and/or
6;;;; modify it under the terms of the GNU Lesser General Public
7;;;; License as published by the Free Software Foundation; either
8;;;; version 3 of the License, or (at your option) any later version.
9;;;;
10;;;; This library is distributed in the hope that it will be useful,
11;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13;;;; Lesser General Public License for more details.
14;;;;
15;;;; You should have received a copy of the GNU Lesser General Public
16;;;; License along with this library; if not, write to the Free Software
17;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
19;;; Code:
20
21(define-module (ice-9 iconv)
22 #:use-module (rnrs bytevectors)
23 #:use-module (ice-9 binary-ports)
5a35d42a 24 #:use-module ((ice-9 rdelim) #:select (read-string))
f05bb849
AW
25 #:export (string->bytevector
26 bytevector->string
27 call-with-encoded-output-string))
28
29;; Like call-with-output-string, but actually closes the port.
30(define (call-with-output-string* proc)
31 (let ((port (open-output-string)))
32 (proc port)
33 (let ((str (get-output-string port)))
34 (close-port port)
35 str)))
36
37(define (call-with-output-bytevector* proc)
38 (call-with-values (lambda () (open-bytevector-output-port))
39 (lambda (port get-bytevector)
40 (proc port)
41 (let ((bv (get-bytevector)))
42 (close-port port)
43 bv))))
44
45(define* (call-with-encoded-output-string encoding proc
5ed4ea90
AW
46 #:optional
47 (conversion-strategy 'error))
18c5bffe
AW
48 "Call PROC on a fresh port. Encode the resulting string as a
49bytevector according to ENCODING, and return the bytevector."
e211d69d
AW
50 (if (and (string-ci=? encoding "utf-8")
51 (eq? conversion-strategy 'error))
f05bb849
AW
52 ;; I don't know why, but this appears to be faster; at least for
53 ;; serving examples/debug-sxml.scm (1464 reqs/s versus 850
54 ;; reqs/s).
55 (string->utf8 (call-with-output-string* proc))
56 (call-with-output-bytevector*
57 (lambda (port)
58 (set-port-encoding! port encoding)
59 (if conversion-strategy
60 (set-port-conversion-strategy! port conversion-strategy))
61 (proc port)))))
62
63;; TODO: Provide C implementations that call scm_from_stringn and
64;; friends?
65
5ed4ea90
AW
66(define* (string->bytevector str encoding
67 #:optional (conversion-strategy 'error))
18c5bffe
AW
68 "Encode STRING according to ENCODING, which should be a string naming
69a character encoding, like \"utf-8\"."
e211d69d
AW
70 (if (and (string-ci=? encoding "utf-8")
71 (eq? conversion-strategy 'error))
f05bb849
AW
72 (string->utf8 str)
73 (call-with-encoded-output-string
74 encoding
75 (lambda (port)
76 (display str port))
5ed4ea90 77 conversion-strategy)))
f05bb849 78
5ed4ea90
AW
79(define* (bytevector->string bv encoding
80 #:optional (conversion-strategy 'error))
18c5bffe
AW
81 "Decode the string represented by BV. The bytes in the bytevector
82will be interpreted according to ENCODING, which should be a string
83naming a character encoding, like \"utf-8\"."
e211d69d
AW
84 (if (and (string-ci=? encoding "utf-8")
85 (eq? conversion-strategy 'error))
f05bb849
AW
86 (utf8->string bv)
87 (let ((p (open-bytevector-input-port bv)))
88 (set-port-encoding! p encoding)
89 (if conversion-strategy
90 (set-port-conversion-strategy! p conversion-strategy))
5a35d42a 91 (let ((res (read-string p)))
f05bb849
AW
92 (close-port p)
93 (if (eof-object? res)
94 ""
95 res)))))