1 /*===========================================================================
2  *  Filename : scmport-sbchar.c
3  *  About    : A ScmCharPort implementation for singlebyte character stream
4  *
5  *  Copyright (C) 2005-2006 YAMAMOTO Kengo <yamaken AT bp.iij4u.or.jp>
6  *  Copyright (c) 2007-2008 SigScheme Project <uim-en AT googlegroups.com>
7  *
8  *  All rights reserved.
9  *
10  *  Redistribution and use in source and binary forms, with or without
11  *  modification, are permitted provided that the following conditions
12  *  are met:
13  *
14  *  1. Redistributions of source code must retain the above copyright
15  *     notice, this list of conditions and the following disclaimer.
16  *  2. Redistributions in binary form must reproduce the above copyright
17  *     notice, this list of conditions and the following disclaimer in the
18  *     documentation and/or other materials provided with the distribution.
19  *  3. Neither the name of authors nor the names of its contributors
20  *     may be used to endorse or promote products derived from this software
21  *     without specific prior written permission.
22  *
23  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
24  *  IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25  *  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26  *  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
27  *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28  *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29  *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
30  *  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31  *  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32  *  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
33  *  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 ===========================================================================*/
35 
36 /*
37  * - This file is intended to be portable. Don't depend on SigScheme.
38  * - To isolate and hide implementation-dependent things, don't merge this file
39  *   into another
40  */
41 
42 #include <config.h>
43 
44 #include <stdlib.h>
45 
46 #include "scmint.h"
47 #include "scmport-config.h"
48 #include "scmport.h"
49 #include "scmport-sbchar.h"
50 
51 /*=======================================
52   File Local Macro Definitions
53 =======================================*/
54 
55 /*=======================================
56   File Local Type Definitions
57 =======================================*/
58 struct ScmSingleByteCharPort_ {  /* inherits ScmBaseCharPort */
59     const ScmCharPortVTbl *vptr;
60 
61     ScmBytePort *bport;  /* protected */
62     size_t linenum;      /* protected */
63 };
64 
65 /*=======================================
66   File Local Function Declarations
67 =======================================*/
68 static ScmCharPort *sbcport_dyn_cast(ScmCharPort *cport,
69                                      const ScmCharPortVTbl *dst_vptr);
70 static ScmCharCodec *sbcport_codec(ScmSingleByteCharPort *port);
71 static char *sbcport_inspect(ScmSingleByteCharPort *port);
72 static void sbcport_put_char(ScmSingleByteCharPort *port, scm_ichar_t ch);
73 
74 /*=======================================
75   Variable Definitions
76 =======================================*/
77 SCM_GLOBAL_VARS_BEGIN(static_scmport_sbchar);
78 #define static
79 static ScmCharCodec *l_sbc_codec;
80 
81 static ScmCharPortVTbl l_ScmSingleByteCharPort_vtbl;
82 #undef static
83 SCM_GLOBAL_VARS_END(static_scmport_sbchar);
84 #define l_sbc_codec SCM_GLOBAL_VAR(static_scmport_sbchar, l_sbc_codec)
85 #define l_ScmSingleByteCharPort_vtbl                                         \
86     SCM_GLOBAL_VAR(static_scmport_sbchar, l_ScmSingleByteCharPort_vtbl)
87 SCM_DEFINE_STATIC_VARS(static_scmport_sbchar);
88 
89 SCM_EXPORT const ScmCharPortVTbl *ScmSingleByteCharPort_vptr;
90 
91 /*=======================================
92   Function Definitions
93 =======================================*/
94 SCM_EXPORT void
scm_sbcport_init(void)95 scm_sbcport_init(void)
96 {
97     ScmCharPortVTbl *vptr;
98 
99     SCM_GLOBAL_VARS_INIT(static_scmport_sbchar);
100 
101     l_ScmSingleByteCharPort_vtbl = *ScmBaseCharPort_vptr;
102 
103     vptr = &l_ScmSingleByteCharPort_vtbl;
104     vptr->dyn_cast = (ScmCharPortMethod_dyn_cast)&sbcport_dyn_cast;
105     vptr->codec    = (ScmCharPortMethod_codec)&sbcport_codec;
106     vptr->inspect  = (ScmCharPortMethod_inspect)&sbcport_inspect;
107     vptr->put_char = (ScmCharPortMethod_put_char)&sbcport_put_char;
108     ScmSingleByteCharPort_vptr = vptr;
109 
110     l_sbc_codec = scm_mb_find_codec("ISO-8859-1");
111 }
112 
113 SCM_EXPORT void
ScmSingleByteCharPort_construct(ScmSingleByteCharPort * port,const ScmCharPortVTbl * vptr,ScmBytePort * bport)114 ScmSingleByteCharPort_construct(ScmSingleByteCharPort *port,
115                                 const ScmCharPortVTbl *vptr,
116                                 ScmBytePort *bport)
117 {
118     ScmBaseCharPort_construct((ScmBaseCharPort *)port, vptr, bport);
119 }
120 
121 SCM_EXPORT ScmCharPort *
ScmSingleByteCharPort_new(ScmBytePort * bport)122 ScmSingleByteCharPort_new(ScmBytePort *bport)
123 {
124     ScmSingleByteCharPort *cport;
125 
126     cport = SCM_PORT_MALLOC(sizeof(ScmSingleByteCharPort));
127     ScmSingleByteCharPort_construct(cport, ScmSingleByteCharPort_vptr, bport);
128 
129     return (ScmCharPort *)cport;
130 }
131 
132 static ScmCharPort *
sbcport_dyn_cast(ScmCharPort * cport,const ScmCharPortVTbl * dst_vptr)133 sbcport_dyn_cast(ScmCharPort *cport, const ScmCharPortVTbl *dst_vptr)
134 {
135     return (dst_vptr == ScmBaseCharPort_vptr
136             || dst_vptr == ScmSingleByteCharPort_vptr) ? cport : NULL;
137 }
138 
139 static ScmCharCodec *
sbcport_codec(ScmSingleByteCharPort * port)140 sbcport_codec(ScmSingleByteCharPort *port)
141 {
142     return l_sbc_codec;
143 }
144 
145 static char *
sbcport_inspect(ScmSingleByteCharPort * port)146 sbcport_inspect(ScmSingleByteCharPort *port)
147 {
148     return ScmBaseCharPort_inspect((ScmBaseCharPort *)port, "sb");
149 }
150 
151 static void
sbcport_put_char(ScmSingleByteCharPort * port,scm_ichar_t ch)152 sbcport_put_char(ScmSingleByteCharPort *port, scm_ichar_t ch)
153 {
154     char buf[1];
155 
156     buf[0] = ch;
157     SCM_BYTEPORT_WRITE(port->bport, sizeof(buf), buf);
158 }
159