citrus_stdenc.c revision 264497
1296177Sjhibbits/* $FreeBSD: stable/10/lib/libc/iconv/citrus_stdenc.c 264497 2014-04-15 09:49:44Z tijl $ */ 2296177Sjhibbits/* $NetBSD: citrus_stdenc.c,v 1.4 2011/11/19 18:39:58 tnozaki Exp $ */ 3296177Sjhibbits 4296177Sjhibbits/*- 5296177Sjhibbits * Copyright (c)2003 Citrus Project, 6296177Sjhibbits * All rights reserved. 7296177Sjhibbits * 8296177Sjhibbits * Redistribution and use in source and binary forms, with or without 9296177Sjhibbits * modification, are permitted provided that the following conditions 10296177Sjhibbits * are met: 11296177Sjhibbits * 1. Redistributions of source code must retain the above copyright 12296177Sjhibbits * notice, this list of conditions and the following disclaimer. 13296177Sjhibbits * 2. Redistributions in binary form must reproduce the above copyright 14296177Sjhibbits * notice, this list of conditions and the following disclaimer in the 15296177Sjhibbits * documentation and/or other materials provided with the distribution. 16296177Sjhibbits * 17296177Sjhibbits * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18296177Sjhibbits * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19296177Sjhibbits * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20296177Sjhibbits * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21296177Sjhibbits * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22296177Sjhibbits * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23296177Sjhibbits * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24296177Sjhibbits * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25296177Sjhibbits * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26296177Sjhibbits * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27296177Sjhibbits * SUCH DAMAGE. 28296177Sjhibbits */ 29296177Sjhibbits 30296177Sjhibbits#include <sys/cdefs.h> 31296177Sjhibbits 32296177Sjhibbits#include <assert.h> 33296177Sjhibbits#include <errno.h> 34296177Sjhibbits#include <stdlib.h> 35296177Sjhibbits#include <string.h> 36296177Sjhibbits 37296177Sjhibbits#include "citrus_namespace.h" 38296177Sjhibbits#include "citrus_types.h" 39296177Sjhibbits#include "citrus_module.h" 40296177Sjhibbits#include "citrus_none.h" 41296177Sjhibbits#include "citrus_stdenc.h" 42296177Sjhibbits 43296177Sjhibbitsstruct _citrus_stdenc _citrus_stdenc_default = { 44296177Sjhibbits &_citrus_NONE_stdenc_ops, /* ce_ops */ 45296177Sjhibbits NULL, /* ce_closure */ 46296177Sjhibbits NULL, /* ce_module */ 47296177Sjhibbits &_citrus_NONE_stdenc_traits, /* ce_traits */ 48296177Sjhibbits}; 49296177Sjhibbits 50296177Sjhibbitsint 51296177Sjhibbits_citrus_stdenc_open(struct _citrus_stdenc * __restrict * __restrict rce, 52296177Sjhibbits char const * __restrict encname, const void * __restrict variable, 53296177Sjhibbits size_t lenvar) 54296177Sjhibbits{ 55296177Sjhibbits struct _citrus_stdenc *ce; 56296177Sjhibbits _citrus_module_t handle; 57296177Sjhibbits _citrus_stdenc_getops_t getops; 58296177Sjhibbits int ret; 59296177Sjhibbits 60296177Sjhibbits if (!strcmp(encname, _CITRUS_DEFAULT_STDENC_NAME)) { 61296177Sjhibbits *rce = &_citrus_stdenc_default; 62296177Sjhibbits return (0); 63296177Sjhibbits } 64296177Sjhibbits ce = malloc(sizeof(*ce)); 65296177Sjhibbits if (ce == NULL) { 66296177Sjhibbits ret = errno; 67296177Sjhibbits goto bad; 68296177Sjhibbits } 69296177Sjhibbits ce->ce_ops = NULL; 70296177Sjhibbits ce->ce_closure = NULL; 71296177Sjhibbits ce->ce_module = NULL; 72296177Sjhibbits ce->ce_traits = NULL; 73296177Sjhibbits 74296177Sjhibbits ret = _citrus_load_module(&handle, encname); 75296177Sjhibbits if (ret) 76296177Sjhibbits goto bad; 77296177Sjhibbits 78296177Sjhibbits ce->ce_module = handle; 79296177Sjhibbits 80296177Sjhibbits getops = (_citrus_stdenc_getops_t)_citrus_find_getops(ce->ce_module, 81296177Sjhibbits encname, "stdenc"); 82296177Sjhibbits if (getops == NULL) { 83296177Sjhibbits ret = EINVAL; 84296177Sjhibbits goto bad; 85296177Sjhibbits } 86296177Sjhibbits 87296177Sjhibbits ce->ce_ops = (struct _citrus_stdenc_ops *)malloc(sizeof(*ce->ce_ops)); 88296177Sjhibbits if (ce->ce_ops == NULL) { 89296177Sjhibbits ret = errno; 90296177Sjhibbits goto bad; 91296177Sjhibbits } 92296177Sjhibbits 93296177Sjhibbits ret = (*getops)(ce->ce_ops, sizeof(*ce->ce_ops)); 94296177Sjhibbits if (ret) 95296177Sjhibbits goto bad; 96296177Sjhibbits 97296177Sjhibbits /* validation check */ 98296177Sjhibbits 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 125bad: 126 _citrus_stdenc_close(ce); 127 return (ret); 128} 129 130void 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