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