1 /*=========================================================================== 2 * Filename : scmport.h 3 * About : Abstract base of port implementation 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 and don't 38 * merge into another file. 39 */ 40 41 #ifndef __SCM_SCMPORT_H 42 #define __SCM_SCMPORT_H 43 44 #include <stddef.h> 45 #if (HAVE_ASSERT_H && !SCM_SOFT_ASSERT) 46 #include <assert.h> 47 #endif 48 49 #include "scmint.h" 50 #include "global.h" 51 #if SCM_USE_MULTIBYTE_CHAR 52 #include "encoding.h" 53 #else 54 #include "encoding-dummy.h" 55 #endif 56 57 #ifdef __cplusplus 58 extern "C" { 59 #endif 60 61 /*======================================= 62 Macro Definitions 63 =======================================*/ 64 #ifndef SCM_DEBUG_PORT 65 #define SCM_DEBUG_PORT 0 66 #endif 67 68 #define SCM_ERRMSG_OPEN_PORT "failed to open port" 69 #define SCM_ERRMSG_CLOSE_PORT "failed to close port" 70 #define SCM_ERRMSG_READ_FROM_PORT "failed to read from port" 71 #define SCM_ERRMSG_WRITE_TO_PORT "failed to write to port" 72 73 #if SCM_SCMPORT_USE_WITH_SIGSCHEME 74 #define SCM_PORT_ASSERT(exp) (SCM_ASSERT(exp)) 75 #elif HAVE_ASSERT_H 76 #define SCM_PORT_ASSERT(exp) (assert(exp)) 77 #else 78 #define SCM_PORT_ASSERT(exp) SCM_EMPTY_EXPR 79 #endif 80 81 #define SCM_PORT_ERROR_INVALID_TYPE(klass, port, type) \ 82 SCM_##klass##PORT_ERROR((port), #type ": invalid object is passed to") 83 #define SCM_PORT_ERROR_INVALID_OPERATION(klass, port, type) \ 84 SCM_##klass##PORT_ERROR((port), #type ": invalid operation") 85 #define SCM_PORT_ERROR_NOMEM(klass, port, type) \ 86 SCM_##klass##PORT_ERROR((port), #type ": Out of memory") 87 88 /* 89 * To allow safe method invocation (includes from subclasses), all non-standard 90 * method must call SCM_PORT_*DYNAMIC_CAST() explicitly. 91 */ 92 #define SCM_CHARPORT_DYNAMIC_CAST(type, obj) \ 93 (SCM_PORT_DYNAMIC_CAST(CHAR, type, (obj))) 94 #define SCM_BYTEPORT_DYNAMIC_CAST(type, obj) \ 95 (SCM_PORT_DYNAMIC_CAST(BYTE, type, (obj))) 96 #define SCM_PORT_DYNAMIC_CAST(klass, type, obj) \ 97 ((SCM_PORT_TRY_DYNAMIC_CAST(type, (obj))) ? \ 98 ((type *)(obj)) : (SCM_PORT_ERROR_INVALID_TYPE(klass, (obj), type), NULL)) 99 #define SCM_PORT_TRY_DYNAMIC_CAST(type, obj) \ 100 ((type *)(*(obj)->vptr->dyn_cast)((obj), type##_vptr)) 101 102 #define SCM_CHARPORT_CLOSE(cport) ((*(cport)->vptr->close)(cport)) 103 #define SCM_CHARPORT_CODEC(cport) ((*(cport)->vptr->codec)(cport)) 104 #if SCM_USE_MULTIBYTE_CHAR 105 #define SCM_CHARPORT_ENCODING(cport) \ 106 (SCM_CHARCODEC_ENCODING(SCM_CHARPORT_CODEC(cport))) 107 #define SCM_CHARPORT_CCS(cport) \ 108 (SCM_CHARCODEC_CCS(SCM_CHARPORT_CODEC(cport))) 109 #else /* SCM_USE_MULTIBYTE_CHAR */ 110 #define SCM_CHARPORT_ENCODING(cport) ("ISO-8859-1") 111 #define SCM_CHARPORT_CCS(cport) (SCM_CCS_ISO8859_1) 112 #endif /* SCM_USE_MULTIBYTE_CHAR */ 113 #define SCM_CHARPORT_INSPECT(cport) ((*(cport)->vptr->inspect)(cport)) 114 #define SCM_CHARPORT_GET_CHAR(cport) ((*(cport)->vptr->get_char)(cport)) 115 #define SCM_CHARPORT_PEEK_CHAR(cport) ((*(cport)->vptr->peek_char)(cport)) 116 #define SCM_CHARPORT_CHAR_READYP(cport) ((*(cport)->vptr->char_readyp)(cport)) 117 #define SCM_CHARPORT_PUTS(cport, str) \ 118 ((*(cport)->vptr->puts)((cport), (str))) 119 #define SCM_CHARPORT_PUT_CHAR(cport, ch) \ 120 ((*(cport)->vptr->put_char)((cport), (ch))) 121 #define SCM_CHARPORT_FLUSH(cport) ((*(cport)->vptr->flush)(cport)) 122 123 #define SCM_BYTEPORT_CLOSE(bport) ((*(bport)->vptr->close)(bport)) 124 #define SCM_BYTEPORT_INSPECT(bport) ((*(bport)->vptr->inspect)(bport)) 125 #define SCM_BYTEPORT_GET_BYTE(bport) ((*(bport)->vptr->get_byte)(bport)) 126 #define SCM_BYTEPORT_PEEK_BYTE(bport) ((*(bport)->vptr->peek_byte)(bport)) 127 #define SCM_BYTEPORT_BYTE_READYP(bport) ((*(bport)->vptr->byte_readyp)(bport)) 128 #define SCM_BYTEPORT_PUTS(bport, str) \ 129 ((*(bport)->vptr->puts)((bport), (str))) 130 #define SCM_BYTEPORT_WRITE(bport, nbytes, buf) \ 131 ((*(bport)->vptr->write)((bport), (nbytes), (buf))) 132 #define SCM_BYTEPORT_FLUSH(bport) ((*(bport)->vptr->flush)(bport)) 133 134 /*======================================= 135 Type Definitions 136 =======================================*/ 137 typedef struct ScmCharPortVTbl_ ScmCharPortVTbl; 138 typedef struct ScmCharPort_ ScmCharPort; 139 typedef struct ScmBaseCharPort_ ScmBaseCharPort; 140 typedef struct ScmBytePortVTbl_ ScmBytePortVTbl; 141 typedef struct ScmBytePort_ ScmBytePort; 142 143 /* 144 * char port 145 */ 146 typedef ScmCharPort *(*ScmCharPortMethod_dyn_cast)(ScmCharPort *cport, const ScmCharPortVTbl *dst_vptr); 147 typedef void (*ScmCharPortMethod_close)(ScmCharPort *cport); 148 typedef ScmCharCodec *(*ScmCharPortMethod_codec)(ScmCharPort *cport); 149 /* returns brief information */ 150 typedef char *(*ScmCharPortMethod_inspect)(ScmCharPort *cport); 151 152 /* input */ 153 typedef scm_ichar_t (*ScmCharPortMethod_get_char)(ScmCharPort *cport); 154 typedef scm_ichar_t (*ScmCharPortMethod_peek_char)(ScmCharPort *cport); 155 typedef scm_bool (*ScmCharPortMethod_char_readyp)(ScmCharPort *cport); 156 157 /* output */ 158 typedef void (*ScmCharPortMethod_puts)(ScmCharPort *cport, const char *str); 159 typedef void (*ScmCharPortMethod_put_char)(ScmCharPort *cport, scm_ichar_t ch); 160 typedef void (*ScmCharPortMethod_flush)(ScmCharPort *cport); 161 162 struct ScmCharPortVTbl_ { 163 ScmCharPortMethod_dyn_cast dyn_cast; 164 ScmCharPortMethod_close close; 165 ScmCharPortMethod_codec codec; 166 ScmCharPortMethod_inspect inspect; 167 ScmCharPortMethod_get_char get_char; 168 ScmCharPortMethod_peek_char peek_char; 169 ScmCharPortMethod_char_readyp char_readyp; 170 ScmCharPortMethod_puts puts; 171 ScmCharPortMethod_put_char put_char; 172 ScmCharPortMethod_flush flush; 173 }; 174 175 struct ScmCharPort_ { 176 const ScmCharPortVTbl *vptr; 177 }; 178 179 struct ScmBaseCharPort_ { /* inherits ScmCharPort */ 180 const ScmCharPortVTbl *vptr; 181 182 ScmBytePort *bport; /* protected */ 183 size_t linenum; /* protected */ 184 }; 185 186 /* 187 * byte port 188 */ 189 typedef ScmBytePort *(*ScmBytePortMethod_dyn_cast)(ScmBytePort *bport, const ScmBytePortVTbl *dst_vptr); 190 typedef void (*ScmBytePortMethod_close)(ScmBytePort *bport); 191 /* returns brief information */ 192 typedef char *(*ScmBytePortMethod_inspect)(ScmBytePort *bport); 193 194 /* input */ 195 typedef scm_ichar_t (*ScmBytePortMethod_get_byte)(ScmBytePort *bport); 196 typedef scm_ichar_t (*ScmBytePortMethod_peek_byte)(ScmBytePort *bport); 197 typedef scm_bool (*ScmBytePortMethod_byte_readyp)(ScmBytePort *bport); 198 199 /* output */ 200 typedef void (*ScmBytePortMethod_puts)(ScmBytePort *bport, const char *str); 201 typedef void (*ScmBytePortMethod_write)(ScmBytePort *bport, 202 size_t nbytes, const char *buf); 203 typedef void (*ScmBytePortMethod_flush)(ScmBytePort *bport); 204 205 struct ScmBytePortVTbl_ { 206 ScmBytePortMethod_dyn_cast dyn_cast; 207 ScmBytePortMethod_close close; 208 ScmBytePortMethod_inspect inspect; 209 ScmBytePortMethod_get_byte get_byte; 210 ScmBytePortMethod_peek_byte peek_byte; 211 ScmBytePortMethod_byte_readyp byte_readyp; 212 ScmBytePortMethod_puts puts; 213 ScmBytePortMethod_write write; 214 ScmBytePortMethod_flush flush; 215 }; 216 217 struct ScmBytePort_ { 218 const ScmBytePortVTbl *vptr; 219 }; 220 221 /*======================================= 222 Variable Declarations 223 =======================================*/ 224 SCM_EXTERN(const ScmCharPortVTbl *const ScmBaseCharPort_vptr); 225 226 /*======================================= 227 Function Declarations 228 =======================================*/ 229 SCM_EXPORT void ScmBaseCharPort_construct(ScmBaseCharPort *port, 230 const ScmCharPortVTbl *vptr, 231 ScmBytePort *bport); 232 SCM_EXPORT char *ScmBaseCharPort_inspect(ScmBaseCharPort *port, 233 const char *header); 234 SCM_EXPORT size_t ScmBaseCharPort_line_number(ScmBaseCharPort *port); 235 236 237 #ifdef __cplusplus 238 } 239 #endif 240 241 #endif /* __SCM_SCMPORT_H */ 242