1*ad30f8e7SGabor Kovesdan /* $FreeBSD$ */ 2*ad30f8e7SGabor Kovesdan /* $NetBSD: citrus_none.c,v 1.18 2008/06/14 16:01:07 tnozaki Exp $ */ 3*ad30f8e7SGabor Kovesdan 4*ad30f8e7SGabor Kovesdan /*- 5*ad30f8e7SGabor Kovesdan * Copyright (c) 2002 Citrus Project, 6*ad30f8e7SGabor Kovesdan * Copyright (c) 2010 Gabor Kovesdan <gabor@FreeBSD.org>, 7*ad30f8e7SGabor Kovesdan * All rights reserved. 8*ad30f8e7SGabor Kovesdan * 9*ad30f8e7SGabor Kovesdan * Redistribution and use in source and binary forms, with or without 10*ad30f8e7SGabor Kovesdan * modification, are permitted provided that the following conditions 11*ad30f8e7SGabor Kovesdan * are met: 12*ad30f8e7SGabor Kovesdan * 1. Redistributions of source code must retain the above copyright 13*ad30f8e7SGabor Kovesdan * notice, this list of conditions and the following disclaimer. 14*ad30f8e7SGabor Kovesdan * 2. Redistributions in binary form must reproduce the above copyright 15*ad30f8e7SGabor Kovesdan * notice, this list of conditions and the following disclaimer in the 16*ad30f8e7SGabor Kovesdan * documentation and/or other materials provided with the distribution. 17*ad30f8e7SGabor Kovesdan * 18*ad30f8e7SGabor Kovesdan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19*ad30f8e7SGabor Kovesdan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20*ad30f8e7SGabor Kovesdan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21*ad30f8e7SGabor Kovesdan * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22*ad30f8e7SGabor Kovesdan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23*ad30f8e7SGabor Kovesdan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24*ad30f8e7SGabor Kovesdan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25*ad30f8e7SGabor Kovesdan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26*ad30f8e7SGabor Kovesdan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27*ad30f8e7SGabor Kovesdan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28*ad30f8e7SGabor Kovesdan * SUCH DAMAGE. 29*ad30f8e7SGabor Kovesdan */ 30*ad30f8e7SGabor Kovesdan 31*ad30f8e7SGabor Kovesdan #include <sys/cdefs.h> 32*ad30f8e7SGabor Kovesdan #include <sys/types.h> 33*ad30f8e7SGabor Kovesdan 34*ad30f8e7SGabor Kovesdan #include <assert.h> 35*ad30f8e7SGabor Kovesdan #include <errno.h> 36*ad30f8e7SGabor Kovesdan #include <iconv.h> 37*ad30f8e7SGabor Kovesdan #include <stddef.h> 38*ad30f8e7SGabor Kovesdan #include <stdio.h> 39*ad30f8e7SGabor Kovesdan #include <stdlib.h> 40*ad30f8e7SGabor Kovesdan #include <string.h> 41*ad30f8e7SGabor Kovesdan #include <wchar.h> 42*ad30f8e7SGabor Kovesdan 43*ad30f8e7SGabor Kovesdan #include "citrus_namespace.h" 44*ad30f8e7SGabor Kovesdan #include "citrus_types.h" 45*ad30f8e7SGabor Kovesdan #include "citrus_module.h" 46*ad30f8e7SGabor Kovesdan #include "citrus_none.h" 47*ad30f8e7SGabor Kovesdan #include "citrus_stdenc.h" 48*ad30f8e7SGabor Kovesdan 49*ad30f8e7SGabor Kovesdan _CITRUS_STDENC_DECLS(NONE); 50*ad30f8e7SGabor Kovesdan _CITRUS_STDENC_DEF_OPS(NONE); 51*ad30f8e7SGabor Kovesdan struct _citrus_stdenc_traits _citrus_NONE_stdenc_traits = { 52*ad30f8e7SGabor Kovesdan 0, /* et_state_size */ 53*ad30f8e7SGabor Kovesdan 1, /* mb_cur_max */ 54*ad30f8e7SGabor Kovesdan }; 55*ad30f8e7SGabor Kovesdan 56*ad30f8e7SGabor Kovesdan static int 57*ad30f8e7SGabor Kovesdan _citrus_NONE_stdenc_init(struct _citrus_stdenc * __restrict ce, 58*ad30f8e7SGabor Kovesdan const void *var __unused, size_t lenvar __unused, 59*ad30f8e7SGabor Kovesdan struct _citrus_stdenc_traits * __restrict et) 60*ad30f8e7SGabor Kovesdan { 61*ad30f8e7SGabor Kovesdan 62*ad30f8e7SGabor Kovesdan et->et_state_size = 0; 63*ad30f8e7SGabor Kovesdan et->et_mb_cur_max = 1; 64*ad30f8e7SGabor Kovesdan 65*ad30f8e7SGabor Kovesdan ce->ce_closure = NULL; 66*ad30f8e7SGabor Kovesdan 67*ad30f8e7SGabor Kovesdan return (0); 68*ad30f8e7SGabor Kovesdan } 69*ad30f8e7SGabor Kovesdan 70*ad30f8e7SGabor Kovesdan static void 71*ad30f8e7SGabor Kovesdan _citrus_NONE_stdenc_uninit(struct _citrus_stdenc *ce __unused) 72*ad30f8e7SGabor Kovesdan { 73*ad30f8e7SGabor Kovesdan 74*ad30f8e7SGabor Kovesdan } 75*ad30f8e7SGabor Kovesdan 76*ad30f8e7SGabor Kovesdan static int 77*ad30f8e7SGabor Kovesdan _citrus_NONE_stdenc_init_state(struct _citrus_stdenc * __restrict ce __unused, 78*ad30f8e7SGabor Kovesdan void * __restrict ps __unused) 79*ad30f8e7SGabor Kovesdan { 80*ad30f8e7SGabor Kovesdan 81*ad30f8e7SGabor Kovesdan return (0); 82*ad30f8e7SGabor Kovesdan } 83*ad30f8e7SGabor Kovesdan 84*ad30f8e7SGabor Kovesdan static int 85*ad30f8e7SGabor Kovesdan _citrus_NONE_stdenc_mbtocs(struct _citrus_stdenc * __restrict ce __unused, 86*ad30f8e7SGabor Kovesdan _csid_t *csid, _index_t *idx, char **s, size_t n, 87*ad30f8e7SGabor Kovesdan void *ps __unused, size_t *nresult, struct iconv_hooks *hooks) 88*ad30f8e7SGabor Kovesdan { 89*ad30f8e7SGabor Kovesdan 90*ad30f8e7SGabor Kovesdan if (n < 1) { 91*ad30f8e7SGabor Kovesdan *nresult = (size_t)-2; 92*ad30f8e7SGabor Kovesdan return (0); 93*ad30f8e7SGabor Kovesdan } 94*ad30f8e7SGabor Kovesdan 95*ad30f8e7SGabor Kovesdan *csid = 0; 96*ad30f8e7SGabor Kovesdan *idx = (_index_t)(unsigned char)*(*s)++; 97*ad30f8e7SGabor Kovesdan *nresult = *idx == 0 ? 0 : 1; 98*ad30f8e7SGabor Kovesdan 99*ad30f8e7SGabor Kovesdan if ((hooks != NULL) && (hooks->uc_hook != NULL)) 100*ad30f8e7SGabor Kovesdan hooks->uc_hook((unsigned int)*idx, hooks->data); 101*ad30f8e7SGabor Kovesdan 102*ad30f8e7SGabor Kovesdan return (0); 103*ad30f8e7SGabor Kovesdan } 104*ad30f8e7SGabor Kovesdan 105*ad30f8e7SGabor Kovesdan static int 106*ad30f8e7SGabor Kovesdan _citrus_NONE_stdenc_cstomb(struct _citrus_stdenc * __restrict ce __unused, 107*ad30f8e7SGabor Kovesdan char *s, size_t n, _csid_t csid, _index_t idx, void *ps __unused, 108*ad30f8e7SGabor Kovesdan size_t *nresult, struct iconv_hooks *hooks __unused) 109*ad30f8e7SGabor Kovesdan { 110*ad30f8e7SGabor Kovesdan 111*ad30f8e7SGabor Kovesdan if (csid == _CITRUS_CSID_INVALID) { 112*ad30f8e7SGabor Kovesdan *nresult = 0; 113*ad30f8e7SGabor Kovesdan return (0); 114*ad30f8e7SGabor Kovesdan } 115*ad30f8e7SGabor Kovesdan if (csid != 0) 116*ad30f8e7SGabor Kovesdan return (EILSEQ); 117*ad30f8e7SGabor Kovesdan 118*ad30f8e7SGabor Kovesdan if ((idx & 0x000000FF) == idx) { 119*ad30f8e7SGabor Kovesdan if (n < 1) { 120*ad30f8e7SGabor Kovesdan *nresult = (size_t)-1; 121*ad30f8e7SGabor Kovesdan return (E2BIG); 122*ad30f8e7SGabor Kovesdan } 123*ad30f8e7SGabor Kovesdan *s = (char)idx; 124*ad30f8e7SGabor Kovesdan *nresult = 1; 125*ad30f8e7SGabor Kovesdan } else if ((idx & 0x0000FFFF) == idx) { 126*ad30f8e7SGabor Kovesdan if (n < 2) { 127*ad30f8e7SGabor Kovesdan *nresult = (size_t)-1; 128*ad30f8e7SGabor Kovesdan return (E2BIG); 129*ad30f8e7SGabor Kovesdan } 130*ad30f8e7SGabor Kovesdan s[0] = (char)idx; 131*ad30f8e7SGabor Kovesdan /* XXX: might be endian dependent */ 132*ad30f8e7SGabor Kovesdan s[1] = (char)(idx >> 8); 133*ad30f8e7SGabor Kovesdan *nresult = 2; 134*ad30f8e7SGabor Kovesdan } else if ((idx & 0x00FFFFFF) == idx) { 135*ad30f8e7SGabor Kovesdan if (n < 3) { 136*ad30f8e7SGabor Kovesdan *nresult = (size_t)-1; 137*ad30f8e7SGabor Kovesdan return (E2BIG); 138*ad30f8e7SGabor Kovesdan } 139*ad30f8e7SGabor Kovesdan s[0] = (char)idx; 140*ad30f8e7SGabor Kovesdan /* XXX: might be endian dependent */ 141*ad30f8e7SGabor Kovesdan s[1] = (char)(idx >> 8); 142*ad30f8e7SGabor Kovesdan s[2] = (char)(idx >> 16); 143*ad30f8e7SGabor Kovesdan *nresult = 3; 144*ad30f8e7SGabor Kovesdan } else { 145*ad30f8e7SGabor Kovesdan if (n < 3) { 146*ad30f8e7SGabor Kovesdan *nresult = (size_t)-1; 147*ad30f8e7SGabor Kovesdan return (E2BIG); 148*ad30f8e7SGabor Kovesdan } 149*ad30f8e7SGabor Kovesdan s[0] = (char)idx; 150*ad30f8e7SGabor Kovesdan /* XXX: might be endian dependent */ 151*ad30f8e7SGabor Kovesdan s[1] = (char)(idx >> 8); 152*ad30f8e7SGabor Kovesdan s[2] = (char)(idx >> 16); 153*ad30f8e7SGabor Kovesdan s[3] = (char)(idx >> 24); 154*ad30f8e7SGabor Kovesdan *nresult = 4; 155*ad30f8e7SGabor Kovesdan } 156*ad30f8e7SGabor Kovesdan 157*ad30f8e7SGabor Kovesdan return (0); 158*ad30f8e7SGabor Kovesdan } 159*ad30f8e7SGabor Kovesdan 160*ad30f8e7SGabor Kovesdan static int 161*ad30f8e7SGabor Kovesdan _citrus_NONE_stdenc_mbtowc(struct _citrus_stdenc * __restrict ce __unused, 162*ad30f8e7SGabor Kovesdan _wc_t * __restrict pwc, char ** __restrict s, size_t n, 163*ad30f8e7SGabor Kovesdan void * __restrict pspriv __unused, size_t * __restrict nresult, 164*ad30f8e7SGabor Kovesdan struct iconv_hooks *hooks) 165*ad30f8e7SGabor Kovesdan { 166*ad30f8e7SGabor Kovesdan 167*ad30f8e7SGabor Kovesdan if (s == NULL) { 168*ad30f8e7SGabor Kovesdan *nresult = 0; 169*ad30f8e7SGabor Kovesdan return (0); 170*ad30f8e7SGabor Kovesdan } 171*ad30f8e7SGabor Kovesdan if (n == 0) { 172*ad30f8e7SGabor Kovesdan *nresult = (size_t)-2; 173*ad30f8e7SGabor Kovesdan return (0); 174*ad30f8e7SGabor Kovesdan } 175*ad30f8e7SGabor Kovesdan 176*ad30f8e7SGabor Kovesdan if (pwc != NULL) 177*ad30f8e7SGabor Kovesdan *pwc = (_wc_t)(unsigned char) **s; 178*ad30f8e7SGabor Kovesdan 179*ad30f8e7SGabor Kovesdan *nresult = *s == '\0' ? 0 : 1; 180*ad30f8e7SGabor Kovesdan 181*ad30f8e7SGabor Kovesdan if ((hooks != NULL) && (hooks->wc_hook != NULL)) 182*ad30f8e7SGabor Kovesdan hooks->wc_hook(*pwc, hooks->data); 183*ad30f8e7SGabor Kovesdan 184*ad30f8e7SGabor Kovesdan return (0); 185*ad30f8e7SGabor Kovesdan } 186*ad30f8e7SGabor Kovesdan 187*ad30f8e7SGabor Kovesdan static int 188*ad30f8e7SGabor Kovesdan _citrus_NONE_stdenc_wctomb(struct _citrus_stdenc * __restrict ce __unused, 189*ad30f8e7SGabor Kovesdan char * __restrict s, size_t n, _wc_t wc, 190*ad30f8e7SGabor Kovesdan void * __restrict pspriv __unused, size_t * __restrict nresult, 191*ad30f8e7SGabor Kovesdan struct iconv_hooks *hooks __unused) 192*ad30f8e7SGabor Kovesdan { 193*ad30f8e7SGabor Kovesdan int ret; 194*ad30f8e7SGabor Kovesdan 195*ad30f8e7SGabor Kovesdan if ((wc & ~0xFFU) != 0) { 196*ad30f8e7SGabor Kovesdan *nresult = (size_t)-1; 197*ad30f8e7SGabor Kovesdan return (EILSEQ); 198*ad30f8e7SGabor Kovesdan } 199*ad30f8e7SGabor Kovesdan if (n == 0) { 200*ad30f8e7SGabor Kovesdan *nresult = (size_t)-1; 201*ad30f8e7SGabor Kovesdan ret = E2BIG; 202*ad30f8e7SGabor Kovesdan } 203*ad30f8e7SGabor Kovesdan 204*ad30f8e7SGabor Kovesdan *nresult = 1; 205*ad30f8e7SGabor Kovesdan if (s != NULL && n > 0) 206*ad30f8e7SGabor Kovesdan *s = (char)wc; 207*ad30f8e7SGabor Kovesdan 208*ad30f8e7SGabor Kovesdan return (0); 209*ad30f8e7SGabor Kovesdan } 210*ad30f8e7SGabor Kovesdan 211*ad30f8e7SGabor Kovesdan static int 212*ad30f8e7SGabor Kovesdan _citrus_NONE_stdenc_put_state_reset(struct _citrus_stdenc * __restrict ce __unused, 213*ad30f8e7SGabor Kovesdan char * __restrict s __unused, size_t n __unused, 214*ad30f8e7SGabor Kovesdan void * __restrict pspriv __unused, size_t * __restrict nresult) 215*ad30f8e7SGabor Kovesdan { 216*ad30f8e7SGabor Kovesdan 217*ad30f8e7SGabor Kovesdan *nresult = 0; 218*ad30f8e7SGabor Kovesdan 219*ad30f8e7SGabor Kovesdan return (0); 220*ad30f8e7SGabor Kovesdan } 221*ad30f8e7SGabor Kovesdan 222*ad30f8e7SGabor Kovesdan static int 223*ad30f8e7SGabor Kovesdan _citrus_NONE_stdenc_get_state_desc(struct _stdenc * __restrict ce __unused, 224*ad30f8e7SGabor Kovesdan void * __restrict ps __unused, int id, 225*ad30f8e7SGabor Kovesdan struct _stdenc_state_desc * __restrict d) 226*ad30f8e7SGabor Kovesdan { 227*ad30f8e7SGabor Kovesdan int ret = 0; 228*ad30f8e7SGabor Kovesdan 229*ad30f8e7SGabor Kovesdan switch (id) { 230*ad30f8e7SGabor Kovesdan case _STDENC_SDID_GENERIC: 231*ad30f8e7SGabor Kovesdan d->u.generic.state = _STDENC_SDGEN_INITIAL; 232*ad30f8e7SGabor Kovesdan break; 233*ad30f8e7SGabor Kovesdan default: 234*ad30f8e7SGabor Kovesdan ret = EOPNOTSUPP; 235*ad30f8e7SGabor Kovesdan } 236*ad30f8e7SGabor Kovesdan 237*ad30f8e7SGabor Kovesdan return (ret); 238*ad30f8e7SGabor Kovesdan } 239