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