1206360Sjoel/*- 2206361Sjoel * Copyright (c) 2000-2001 Boris Popov 375332Sbp * All rights reserved. 475332Sbp * 575332Sbp * Redistribution and use in source and binary forms, with or without 675332Sbp * modification, are permitted provided that the following conditions 775332Sbp * are met: 875332Sbp * 1. Redistributions of source code must retain the above copyright 975332Sbp * notice, this list of conditions and the following disclaimer. 1075332Sbp * 2. Redistributions in binary form must reproduce the above copyright 1175332Sbp * notice, this list of conditions and the following disclaimer in the 1275332Sbp * documentation and/or other materials provided with the distribution. 1375332Sbp * 1475332Sbp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1575332Sbp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1675332Sbp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1775332Sbp * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1875332Sbp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1975332Sbp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2075332Sbp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2175332Sbp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2275332Sbp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2375332Sbp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2475332Sbp * SUCH DAMAGE. 2575332Sbp */ 26116189Sobrien 27116189Sobrien#include <sys/cdefs.h> 28116189Sobrien__FBSDID("$FreeBSD: releng/10.3/sys/libkern/iconv_xlat.c 206361 2010-04-07 16:50:38Z joel $"); 29116189Sobrien 3075332Sbp#include <sys/param.h> 3175332Sbp#include <sys/kernel.h> 3275332Sbp#include <sys/systm.h> 3375332Sbp#include <sys/malloc.h> 3475332Sbp#include <sys/iconv.h> 3575332Sbp 3675332Sbp#include "iconv_converter_if.h" 3775332Sbp 3875332Sbp/* 3975332Sbp * "XLAT" converter 4075332Sbp */ 4175332Sbp 4275332Sbp#ifdef MODULE_DEPEND 43120492SfjoeMODULE_DEPEND(iconv_xlat, libiconv, 2, 2, 2); 4475332Sbp#endif 4575332Sbp 4675332Sbp/* 4775332Sbp * XLAT converter instance 4875332Sbp */ 4975332Sbpstruct iconv_xlat { 5075332Sbp KOBJ_FIELDS; 5175332Sbp u_char * d_table; 5275332Sbp struct iconv_cspair * d_csp; 5375332Sbp}; 5475332Sbp 5575332Sbpstatic int 5675332Sbpiconv_xlat_open(struct iconv_converter_class *dcp, 5775332Sbp struct iconv_cspair *csp, struct iconv_cspair *cspf, void **dpp) 5875332Sbp{ 5975332Sbp struct iconv_xlat *dp; 6075332Sbp 61111119Simp dp = (struct iconv_xlat *)kobj_create((struct kobj_class*)dcp, M_ICONV, M_WAITOK); 6275332Sbp dp->d_table = csp->cp_data; 6375332Sbp dp->d_csp = csp; 6475332Sbp csp->cp_refcount++; 6575332Sbp *dpp = (void*)dp; 6675332Sbp return 0; 6775332Sbp} 6875332Sbp 6975332Sbpstatic int 7075332Sbpiconv_xlat_close(void *data) 7175332Sbp{ 7275332Sbp struct iconv_xlat *dp = data; 7375332Sbp 7475332Sbp dp->d_csp->cp_refcount--; 7575332Sbp kobj_delete((struct kobj*)data, M_ICONV); 7675332Sbp return 0; 7775332Sbp} 7875332Sbp 7975332Sbpstatic int 8075332Sbpiconv_xlat_conv(void *d2p, const char **inbuf, 81120492Sfjoe size_t *inbytesleft, char **outbuf, size_t *outbytesleft, 82120492Sfjoe int convchar, int casetype) 8375332Sbp{ 8475332Sbp struct iconv_xlat *dp = (struct iconv_xlat*)d2p; 8575332Sbp const char *src; 8675332Sbp char *dst; 8775332Sbp int n, r; 8875332Sbp 8975332Sbp if (inbuf == NULL || *inbuf == NULL || outbuf == NULL || *outbuf == NULL) 9075332Sbp return 0; 91120492Sfjoe if (casetype != 0) 92120492Sfjoe return -1; 93120492Sfjoe if (convchar == 1) 94120492Sfjoe r = n = 1; 95120492Sfjoe else 96120492Sfjoe r = n = min(*inbytesleft, *outbytesleft); 9775332Sbp src = *inbuf; 9875332Sbp dst = *outbuf; 9975332Sbp while(r--) 10075332Sbp *dst++ = dp->d_table[(u_char)*src++]; 10175332Sbp *inbuf += n; 10275332Sbp *outbuf += n; 103120492Sfjoe *inbytesleft -= n; 10475332Sbp *outbytesleft -= n; 10575332Sbp return 0; 10675332Sbp} 10775332Sbp 10875332Sbpstatic const char * 10975332Sbpiconv_xlat_name(struct iconv_converter_class *dcp) 11075332Sbp{ 11175332Sbp return "xlat"; 11275332Sbp} 11375332Sbp 11475332Sbpstatic kobj_method_t iconv_xlat_methods[] = { 11575332Sbp KOBJMETHOD(iconv_converter_open, iconv_xlat_open), 11675332Sbp KOBJMETHOD(iconv_converter_close, iconv_xlat_close), 11775332Sbp KOBJMETHOD(iconv_converter_conv, iconv_xlat_conv), 11875332Sbp#if 0 11975332Sbp KOBJMETHOD(iconv_converter_init, iconv_xlat_init), 12075332Sbp KOBJMETHOD(iconv_converter_done, iconv_xlat_done), 12175332Sbp#endif 12275332Sbp KOBJMETHOD(iconv_converter_name, iconv_xlat_name), 12375332Sbp {0, 0} 12475332Sbp}; 12575332Sbp 12675332SbpKICONV_CONVERTER(xlat, sizeof(struct iconv_xlat)); 127