1c0587701SJoel Dahl /*-
2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
38a36da99SPedro F. Giffuni *
4d122d784SJoel Dahl * Copyright (c) 2000-2001 Boris Popov
56f2d8adbSBoris Popov * All rights reserved.
66f2d8adbSBoris Popov *
76f2d8adbSBoris Popov * Redistribution and use in source and binary forms, with or without
86f2d8adbSBoris Popov * modification, are permitted provided that the following conditions
96f2d8adbSBoris Popov * are met:
106f2d8adbSBoris Popov * 1. Redistributions of source code must retain the above copyright
116f2d8adbSBoris Popov * notice, this list of conditions and the following disclaimer.
126f2d8adbSBoris Popov * 2. Redistributions in binary form must reproduce the above copyright
136f2d8adbSBoris Popov * notice, this list of conditions and the following disclaimer in the
146f2d8adbSBoris Popov * documentation and/or other materials provided with the distribution.
156f2d8adbSBoris Popov *
166f2d8adbSBoris Popov * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
176f2d8adbSBoris Popov * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
186f2d8adbSBoris Popov * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
196f2d8adbSBoris Popov * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
206f2d8adbSBoris Popov * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
216f2d8adbSBoris Popov * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
226f2d8adbSBoris Popov * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
236f2d8adbSBoris Popov * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
246f2d8adbSBoris Popov * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
256f2d8adbSBoris Popov * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
266f2d8adbSBoris Popov * SUCH DAMAGE.
276f2d8adbSBoris Popov */
28ab0de15bSDavid E. O'Brien
296f2d8adbSBoris Popov #include <sys/param.h>
306f2d8adbSBoris Popov #include <sys/kernel.h>
316f2d8adbSBoris Popov #include <sys/systm.h>
326f2d8adbSBoris Popov #include <sys/malloc.h>
336f2d8adbSBoris Popov #include <sys/iconv.h>
346f2d8adbSBoris Popov
356f2d8adbSBoris Popov #include "iconv_converter_if.h"
366f2d8adbSBoris Popov
376f2d8adbSBoris Popov /*
386f2d8adbSBoris Popov * "XLAT" converter
396f2d8adbSBoris Popov */
406f2d8adbSBoris Popov
416f2d8adbSBoris Popov #ifdef MODULE_DEPEND
42c4f02a89SMax Khon MODULE_DEPEND(iconv_xlat, libiconv, 2, 2, 2);
436f2d8adbSBoris Popov #endif
446f2d8adbSBoris Popov
456f2d8adbSBoris Popov /*
466f2d8adbSBoris Popov * XLAT converter instance
476f2d8adbSBoris Popov */
486f2d8adbSBoris Popov struct iconv_xlat {
496f2d8adbSBoris Popov KOBJ_FIELDS;
506f2d8adbSBoris Popov u_char * d_table;
516f2d8adbSBoris Popov struct iconv_cspair * d_csp;
526f2d8adbSBoris Popov };
536f2d8adbSBoris Popov
546f2d8adbSBoris Popov static int
iconv_xlat_open(struct iconv_converter_class * dcp,struct iconv_cspair * csp,struct iconv_cspair * cspf,void ** dpp)556f2d8adbSBoris Popov iconv_xlat_open(struct iconv_converter_class *dcp,
566f2d8adbSBoris Popov struct iconv_cspair *csp, struct iconv_cspair *cspf, void **dpp)
576f2d8adbSBoris Popov {
586f2d8adbSBoris Popov struct iconv_xlat *dp;
596f2d8adbSBoris Popov
60a163d034SWarner Losh dp = (struct iconv_xlat *)kobj_create((struct kobj_class*)dcp, M_ICONV, M_WAITOK);
616f2d8adbSBoris Popov dp->d_table = csp->cp_data;
626f2d8adbSBoris Popov dp->d_csp = csp;
636f2d8adbSBoris Popov csp->cp_refcount++;
646f2d8adbSBoris Popov *dpp = (void*)dp;
656f2d8adbSBoris Popov return 0;
666f2d8adbSBoris Popov }
676f2d8adbSBoris Popov
686f2d8adbSBoris Popov static int
iconv_xlat_close(void * data)696f2d8adbSBoris Popov iconv_xlat_close(void *data)
706f2d8adbSBoris Popov {
716f2d8adbSBoris Popov struct iconv_xlat *dp = data;
726f2d8adbSBoris Popov
736f2d8adbSBoris Popov dp->d_csp->cp_refcount--;
746f2d8adbSBoris Popov kobj_delete((struct kobj*)data, M_ICONV);
756f2d8adbSBoris Popov return 0;
766f2d8adbSBoris Popov }
776f2d8adbSBoris Popov
786f2d8adbSBoris Popov static int
iconv_xlat_conv(void * d2p,const char ** inbuf,size_t * inbytesleft,char ** outbuf,size_t * outbytesleft,int convchar,int casetype)796f2d8adbSBoris Popov iconv_xlat_conv(void *d2p, const char **inbuf,
80c4f02a89SMax Khon size_t *inbytesleft, char **outbuf, size_t *outbytesleft,
81c4f02a89SMax Khon int convchar, int casetype)
826f2d8adbSBoris Popov {
836f2d8adbSBoris Popov struct iconv_xlat *dp = (struct iconv_xlat*)d2p;
846f2d8adbSBoris Popov const char *src;
856f2d8adbSBoris Popov char *dst;
866f2d8adbSBoris Popov int n, r;
876f2d8adbSBoris Popov
886f2d8adbSBoris Popov if (inbuf == NULL || *inbuf == NULL || outbuf == NULL || *outbuf == NULL)
896f2d8adbSBoris Popov return 0;
90c4f02a89SMax Khon if (casetype != 0)
91c4f02a89SMax Khon return -1;
92c4f02a89SMax Khon if (convchar == 1)
93c4f02a89SMax Khon r = n = 1;
94c4f02a89SMax Khon else
956f2d8adbSBoris Popov r = n = min(*inbytesleft, *outbytesleft);
966f2d8adbSBoris Popov src = *inbuf;
976f2d8adbSBoris Popov dst = *outbuf;
986f2d8adbSBoris Popov while(r--)
996f2d8adbSBoris Popov *dst++ = dp->d_table[(u_char)*src++];
1006f2d8adbSBoris Popov *inbuf += n;
1016f2d8adbSBoris Popov *outbuf += n;
102c4f02a89SMax Khon *inbytesleft -= n;
1036f2d8adbSBoris Popov *outbytesleft -= n;
1046f2d8adbSBoris Popov return 0;
1056f2d8adbSBoris Popov }
1066f2d8adbSBoris Popov
1076f2d8adbSBoris Popov static const char *
iconv_xlat_name(struct iconv_converter_class * dcp)1086f2d8adbSBoris Popov iconv_xlat_name(struct iconv_converter_class *dcp)
1096f2d8adbSBoris Popov {
1106f2d8adbSBoris Popov return "xlat";
1116f2d8adbSBoris Popov }
1126f2d8adbSBoris Popov
1136f2d8adbSBoris Popov static kobj_method_t iconv_xlat_methods[] = {
1146f2d8adbSBoris Popov KOBJMETHOD(iconv_converter_open, iconv_xlat_open),
1156f2d8adbSBoris Popov KOBJMETHOD(iconv_converter_close, iconv_xlat_close),
1166f2d8adbSBoris Popov KOBJMETHOD(iconv_converter_conv, iconv_xlat_conv),
1176f2d8adbSBoris Popov #if 0
1186f2d8adbSBoris Popov KOBJMETHOD(iconv_converter_init, iconv_xlat_init),
1196f2d8adbSBoris Popov KOBJMETHOD(iconv_converter_done, iconv_xlat_done),
1206f2d8adbSBoris Popov #endif
1216f2d8adbSBoris Popov KOBJMETHOD(iconv_converter_name, iconv_xlat_name),
1226f2d8adbSBoris Popov {0, 0}
1236f2d8adbSBoris Popov };
1246f2d8adbSBoris Popov
1256f2d8adbSBoris Popov KICONV_CONVERTER(xlat, sizeof(struct iconv_xlat));
126