1 /* $NetBSD: src/lib/libc/citrus/citrus_stdenc.c,v 1.2 2003/07/10 08:50:44 tshiozak Exp $ */ 2 /* $DragonFly: src/lib/libc/citrus/citrus_stdenc.c,v 1.1 2005/03/11 23:33:53 joerg Exp $ */ 3 4 /*- 5 * Copyright (c)2003 Citrus Project, 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #include <sys/types.h> 31 #include <assert.h> 32 #include <errno.h> 33 #include <stdlib.h> 34 #include <string.h> 35 36 #include "citrus_namespace.h" 37 #include "citrus_types.h" 38 #include "citrus_module.h" 39 #include "citrus_stdenc.h" 40 #include "citrus_none.h" 41 42 struct _citrus_stdenc _citrus_stdenc_default = { 43 &_citrus_NONE_stdenc_ops, /* ce_ops */ 44 NULL, /* ce_closure */ 45 NULL, /* ce_module */ 46 &_citrus_NONE_stdenc_traits, /* ce_traits */ 47 }; 48 49 #ifdef _I18N_DYNAMIC 50 51 int 52 _citrus_stdenc_open(struct _citrus_stdenc * __restrict * __restrict rce, 53 char const * __restrict encname, 54 const void * __restrict variable, size_t lenvar) 55 { 56 int ret; 57 _citrus_module_t handle; 58 struct _citrus_stdenc *ce; 59 _citrus_stdenc_getops_t getops; 60 61 _DIAGASSERT(encname != NULL); 62 _DIAGASSERT(!lenvar || variable!=NULL); 63 _DIAGASSERT(rce != NULL); 64 65 if (!strcmp(encname, _CITRUS_DEFAULT_STDENC_NAME)) { 66 *rce = &_citrus_stdenc_default; 67 return (0); 68 } 69 ce = malloc(sizeof(*ce)); 70 if (ce==NULL) { 71 ret = errno; 72 goto bad; 73 } 74 ce->ce_ops = NULL; 75 ce->ce_closure = NULL; 76 ce->ce_module = NULL; 77 ce->ce_traits = NULL; 78 79 ret = _citrus_load_module(&handle, encname); 80 if (ret) 81 goto bad; 82 83 ce->ce_module = handle; 84 85 getops = 86 (_citrus_stdenc_getops_t)_citrus_find_getops(ce->ce_module, 87 encname, "stdenc"); 88 if (getops == NULL) { 89 ret = EINVAL; 90 goto bad; 91 } 92 93 ce->ce_ops = (struct _citrus_stdenc_ops *)malloc(sizeof(*ce->ce_ops)); 94 if (ce->ce_ops == NULL) { 95 ret = errno; 96 goto bad; 97 } 98 99 ret = (*getops)(ce->ce_ops, sizeof(*ce->ce_ops), 100 _CITRUS_STDENC_ABI_VERSION); 101 if (ret) 102 goto bad; 103 104 /* If return ABI version is not expected, should fixup it */ 105 106 /* validation check */ 107 if (ce->ce_ops->eo_init == NULL || 108 ce->ce_ops->eo_uninit == NULL || 109 ce->ce_ops->eo_init_state == NULL || 110 ce->ce_ops->eo_mbtocs == NULL || 111 ce->ce_ops->eo_cstomb == NULL || 112 ce->ce_ops->eo_mbtowc == NULL || 113 ce->ce_ops->eo_wctomb == NULL) 114 goto bad; 115 116 /* allocate traits */ 117 ce->ce_traits = malloc(sizeof(*ce->ce_traits)); 118 if (ce->ce_traits == NULL) { 119 ret = errno; 120 goto bad; 121 } 122 /* init and get closure */ 123 ret = (*ce->ce_ops->eo_init)(ce, variable, lenvar, ce->ce_traits); 124 if (ret) 125 goto bad; 126 127 *rce = ce; 128 129 return (0); 130 131 bad: 132 _citrus_stdenc_close(ce); 133 return (ret); 134 } 135 136 void 137 _citrus_stdenc_close(struct _citrus_stdenc *ce) 138 { 139 140 _DIAGASSERT(ce != NULL); 141 142 if (ce == &_citrus_stdenc_default) 143 return; 144 145 if (ce->ce_module) { 146 if (ce->ce_ops) { 147 if (ce->ce_closure && ce->ce_ops->eo_uninit) 148 (*ce->ce_ops->eo_uninit)(ce); 149 free(ce->ce_ops); 150 } 151 free(ce->ce_traits); 152 _citrus_unload_module(ce->ce_module); 153 } 154 free(ce); 155 } 156 157 #else 158 /* !_I18N_DYNAMIC */ 159 160 int 161 /*ARGSUSED*/ 162 _citrus_stdenc_open(struct _citrus_stdenc * __restrict * __restrict rce, 163 char const * __restrict encname, 164 const void * __restrict variable, size_t lenvar) 165 { 166 if (!strcmp(encname, _CITRUS_DEFAULT_STDENC_NAME)) { 167 *rce = &_citrus_stdenc_default; 168 return (0); 169 } 170 return (EINVAL); 171 } 172 173 void 174 /*ARGSUSED*/ 175 _citrus_stdenc_close(struct _citrus_stdenc *ce) 176 { 177 } 178 179 #endif 180