1 /*===========================================================================
2 * Filename : module-srfi6.c
3 * About : SRFI-6 Basic String Ports
4 *
5 * Copyright (C) 2005 Kazuki Ohta <mover AT hct.zaq.ne.jp>
6 * Copyright (C) 2005-2006 Jun Inoue <jun.lambda AT gmail.com>
7 * Copyright (C) 2005-2006 YAMAMOTO Kengo <yamaken AT bp.iij4u.or.jp>
8 * Copyright (c) 2007-2008 SigScheme Project <uim-en AT googlegroups.com>
9 *
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 *
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. Neither the name of authors nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
26 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
27 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
29 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
32 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
34 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
35 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 ===========================================================================*/
37
38 #include <config.h>
39
40 #include <stdlib.h>
41
42 #include "sigscheme.h"
43 #include "sigschemeinternal.h"
44 #include "scmport-config.h"
45 #include "scmport.h"
46 #include "scmport-str.h"
47
48 /*=======================================
49 File Local Macro Definitions
50 =======================================*/
51
52 /*=======================================
53 File Local Type Definitions
54 =======================================*/
55
56 /*=======================================
57 Variable Definitions
58 =======================================*/
59 #include "functable-srfi6.c"
60
61 /*=======================================
62 File Local Function Declarations
63 =======================================*/
64 static void srfi6_istrport_finalize(char **str, scm_bool ownership,
65 void **opaque);
66
67 /*=======================================
68 Function Definitions
69 =======================================*/
70 SCM_EXPORT void
scm_initialize_srfi6(void)71 scm_initialize_srfi6(void)
72 {
73 scm_strport_init();
74
75 scm_register_funcs(scm_functable_srfi6);
76 }
77
78 static void
srfi6_istrport_finalize(char ** str,scm_bool ownership,void ** opaque)79 srfi6_istrport_finalize(char **str, scm_bool ownership, void **opaque)
80 {
81 SCM_ASSERT(!ownership);
82
83 scm_gc_unprotect((ScmObj *)opaque);
84 }
85
86 SCM_EXPORT ScmObj
scm_p_srfi6_open_input_string(ScmObj str)87 scm_p_srfi6_open_input_string(ScmObj str)
88 {
89 ScmObj *hold_str;
90 ScmBytePort *bport;
91 ScmCharPort *cport;
92 DECLARE_FUNCTION("open-input-string", procedure_fixed_1);
93
94 ENSURE_STRING(str);
95
96 bport = ScmInputStrPort_new_const(SCM_STRING_STR(str),
97 srfi6_istrport_finalize);
98 hold_str = (ScmObj *)ScmInputStrPort_ref_opaque(bport);
99 scm_gc_protect_with_init(hold_str, str);
100 cport = scm_make_char_port(bport);
101 return MAKE_PORT(cport, SCM_PORTFLAG_INPUT);
102 }
103
104 SCM_EXPORT ScmObj
scm_p_srfi6_open_output_string(void)105 scm_p_srfi6_open_output_string(void)
106 {
107 ScmBytePort *bport;
108 ScmCharPort *cport;
109 DECLARE_FUNCTION("open-output-string", procedure_fixed_0);
110
111 bport = ScmOutputStrPort_new(NULL);
112 cport = scm_make_char_port(bport);
113 return MAKE_PORT(cport, SCM_PORTFLAG_OUTPUT);
114 }
115
116 SCM_EXPORT ScmObj
scm_p_srfi6_get_output_string(ScmObj port)117 scm_p_srfi6_get_output_string(ScmObj port)
118 {
119 ScmBaseCharPort *cport;
120 const char *str;
121 char *new_str;
122 scm_int_t mb_len;
123 #if SCM_USE_NULL_CAPABLE_STRING
124 size_t size;
125 #endif
126 DECLARE_FUNCTION("get-output-string", procedure_fixed_1);
127
128 ENSURE_PORT(port);
129
130 SCM_ENSURE_LIVE_PORT(port);
131 cport = SCM_CHARPORT_DYNAMIC_CAST(ScmBaseCharPort, SCM_PORT_IMPL(port));
132
133 str = ScmOutputStrPort_str(cport->bport);
134 /* FIXME: incorrect length for null-capable string */
135 mb_len = scm_mb_bare_c_strlen(scm_port_codec(port), str);
136 #if SCM_USE_NULL_CAPABLE_STRING
137 size = ScmOutputStrPort_c_strlen(cport->bport) + sizeof("");
138 new_str = scm_malloc(size);
139 memcpy(new_str, str, size);
140 #else
141 new_str = scm_strdup(str);
142 #endif
143
144 return MAKE_STRING(new_str, mb_len);
145 }
146