Home | History | Annotate | Line # | Download | only in citrus
citrus_none.c revision 1.18
      1 /*	$NetBSD: citrus_none.c,v 1.18 2008/06/14 16:01:07 tnozaki Exp $	*/
      2 
      3 /*-
      4  * Copyright (c)2002 Citrus Project,
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #include <sys/cdefs.h>
     30 #if defined(LIBC_SCCS) && !defined(lint)
     31 __RCSID("$NetBSD: citrus_none.c,v 1.18 2008/06/14 16:01:07 tnozaki Exp $");
     32 #endif /* LIBC_SCCS and not lint */
     33 
     34 #include <assert.h>
     35 #include <errno.h>
     36 #include <string.h>
     37 #include <stdio.h>
     38 #include <stdlib.h>
     39 #include <stddef.h>
     40 #include <wchar.h>
     41 #include <sys/types.h>
     42 
     43 #include "citrus_namespace.h"
     44 #include "citrus_types.h"
     45 #include "citrus_module.h"
     46 #include "citrus_ctype.h"
     47 #include "citrus_none.h"
     48 #include "citrus_stdenc.h"
     49 
     50 /* ---------------------------------------------------------------------- */
     51 
     52 _CITRUS_CTYPE_DECLS(NONE);
     53 _CITRUS_CTYPE_DEF_OPS(NONE);
     54 
     55 
     56 /* ---------------------------------------------------------------------- */
     57 
     58 static int
     59 /*ARGSUSED*/
     60 _citrus_NONE_ctype_init(void ** __restrict cl, void * __restrict var,
     61 			size_t lenvar, size_t lenps)
     62 {
     63 	*cl = NULL;
     64 	return (0);
     65 }
     66 
     67 static void
     68 /*ARGSUSED*/
     69 _citrus_NONE_ctype_uninit(void *cl)
     70 {
     71 }
     72 
     73 static unsigned
     74 /*ARGSUSED*/
     75 _citrus_NONE_ctype_get_mb_cur_max(void *cl)
     76 {
     77 	return (1);
     78 }
     79 
     80 static int
     81 /*ARGSUSED*/
     82 _citrus_NONE_ctype_mblen(void * __restrict cl, const char * __restrict s,
     83 			 size_t n, int * __restrict nresult)
     84 {
     85 	if (!s) {
     86 		*nresult = 0; /* state independent */
     87 		return (0);
     88 	}
     89 	if (n==0) {
     90 		*nresult = -1;
     91 		return (EILSEQ);
     92 	}
     93 	*nresult = (*s == 0) ? 0 : 1;
     94 	return (0);
     95 }
     96 
     97 static int
     98 /*ARGSUSED*/
     99 _citrus_NONE_ctype_mbrlen(void * __restrict cl, const char * __restrict s,
    100 			  size_t n, void * __restrict pspriv,
    101 			  size_t * __restrict nresult)
    102 {
    103 	if (!s) {
    104 		*nresult = 0;
    105 		return (0);
    106 	}
    107 	if (n==0) {
    108 		*nresult = (size_t)-2;
    109 		return (0);
    110 	}
    111 	*nresult = (*s == 0) ? 0 : 1;
    112 	return (0);
    113 }
    114 
    115 static int
    116 /*ARGSUSED*/
    117 _citrus_NONE_ctype_mbrtowc(void * __restrict cl, wchar_t * __restrict pwc,
    118 			   const char * __restrict s, size_t n,
    119 			   void * __restrict pspriv,
    120 			   size_t * __restrict nresult)
    121 {
    122 	if (s == NULL) {
    123 		*nresult = 0;
    124 		return (0);
    125 	}
    126 	if (n == 0) {
    127 		*nresult = (size_t)-2;
    128 		return (0);
    129 	}
    130 
    131 	if (pwc != NULL)
    132 		*pwc = (wchar_t)(unsigned char) *s;
    133 
    134 	*nresult = *s == '\0' ? 0 : 1;
    135 	return (0);
    136 }
    137 
    138 static int
    139 /*ARGSUSED*/
    140 _citrus_NONE_ctype_mbsinit(void * __restrict cl,
    141 			   const void * __restrict pspriv,
    142 			   int * __restrict nresult)
    143 {
    144 	*nresult = 1;  /* always initial state */
    145 	return (0);
    146 }
    147 
    148 static int
    149 /*ARGSUSED*/
    150 _citrus_NONE_ctype_mbsrtowcs(void * __restrict cl, wchar_t * __restrict pwcs,
    151 			     const char ** __restrict s, size_t n,
    152 			     void * __restrict pspriv,
    153 			     size_t * __restrict nresult)
    154 {
    155 	int cnt;
    156 	const char *s0;
    157 
    158 	/* if pwcs is NULL, ignore n */
    159 	if (pwcs == NULL)
    160 		n = 1; /* arbitrary >0 value */
    161 
    162 	cnt = 0;
    163 	s0 = *s; /* to keep *s unchanged for now, use copy instead. */
    164 	while (n > 0) {
    165 		if (pwcs != NULL) {
    166 			*pwcs = (wchar_t)(unsigned char)*s0;
    167 		}
    168 		if (*s0 == '\0') {
    169 			s0 = NULL;
    170 			break;
    171 		}
    172 		s0++;
    173 		if (pwcs != NULL) {
    174 			pwcs++;
    175 			n--;
    176 		}
    177 		cnt++;
    178 	}
    179 	if (pwcs)
    180 		*s = s0;
    181 
    182 	*nresult = (size_t)cnt;
    183 
    184 	return (0);
    185 }
    186 
    187 static int
    188 _citrus_NONE_ctype_mbstowcs(void * __restrict cl, wchar_t * __restrict wcs,
    189 			    const char * __restrict s, size_t n,
    190 			    size_t * __restrict nresult)
    191 {
    192 	const char *rs = s;
    193 
    194 	return (_citrus_NONE_ctype_mbsrtowcs(cl, wcs, &rs, n, NULL, nresult));
    195 }
    196 
    197 static int
    198 /*ARGSUSED*/
    199 _citrus_NONE_ctype_mbtowc(void * __restrict cl, wchar_t * __restrict pwc,
    200 			  const char * __restrict s, size_t n,
    201 			  int * __restrict nresult)
    202 {
    203 
    204 	if (s == NULL) {
    205 		*nresult = 0; /* state independent */
    206 		return (0);
    207 	}
    208 	if (n == 0) {
    209 		return (EILSEQ);
    210 	}
    211 	if (pwc == NULL) {
    212 		if (*s == '\0') {
    213 			*nresult = 0;
    214 		} else {
    215 			*nresult = 1;
    216 		}
    217 		return (0);
    218 	}
    219 
    220 	*pwc = (wchar_t)(unsigned char)*s;
    221 	*nresult = *s == '\0' ? 0 : 1;
    222 
    223 	return (0);
    224 }
    225 
    226 static int
    227 /*ARGSUSED*/
    228 _citrus_NONE_ctype_wcrtomb(void * __restrict cl, char * __restrict s,
    229 			   wchar_t wc, void * __restrict pspriv,
    230 			   size_t * __restrict nresult)
    231 {
    232 	if ((wc&~0xFFU) != 0) {
    233 		*nresult = (size_t)-1;
    234 		return (EILSEQ);
    235 	}
    236 
    237 	*nresult = 1;
    238 	if (s!=NULL)
    239 		*s = (char)wc;
    240 
    241 	return (0);
    242 }
    243 
    244 static int
    245 /*ARGSUSED*/
    246 _citrus_NONE_ctype_wcsrtombs(void * __restrict cl, char * __restrict s,
    247 			     const wchar_t ** __restrict pwcs, size_t n,
    248 			     void * __restrict pspriv,
    249 			     size_t * __restrict nresult)
    250 {
    251 	size_t count;
    252 	const wchar_t *pwcs0;
    253 
    254 	pwcs0 = *pwcs;
    255 	count = 0;
    256 
    257 	if (s == NULL)
    258 		n = 1;
    259 
    260 	while (n > 0) {
    261 		if ((*pwcs0 & ~0xFFU) != 0) {
    262 			*nresult = (size_t)-1;
    263 			return (EILSEQ);
    264 		}
    265 		if (s != NULL) {
    266 			*s++ = (char)*pwcs0;
    267 			n--;
    268 		}
    269 		if (*pwcs0 == L'\0') {
    270 			pwcs0 = NULL;
    271 			break;
    272 		}
    273 		count++;
    274 		pwcs0++;
    275 	}
    276 	if (s != NULL)
    277 		*pwcs = pwcs0;
    278 
    279 	*nresult = count;
    280 
    281 	return (0);
    282 }
    283 
    284 static int
    285 _citrus_NONE_ctype_wcstombs(void * __restrict cl, char * __restrict s,
    286 			    const wchar_t * __restrict pwcs, size_t n,
    287 			    size_t * __restrict nresult)
    288 {
    289 	const wchar_t *rpwcs = pwcs;
    290 
    291 	return (_citrus_NONE_ctype_wcsrtombs(cl, s, &rpwcs, n, NULL, nresult));
    292 }
    293 
    294 static int
    295 _citrus_NONE_ctype_wctomb(void * __restrict cl, char * __restrict s,
    296 			  wchar_t wc, int * __restrict nresult)
    297 {
    298 	int ret;
    299 	size_t nr;
    300 
    301 	if (s == 0) {
    302 		/*
    303 		 * initialize state here.
    304 		 * (nothing to do for us.)
    305 		 */
    306 		*nresult = 0; /* we're state independent */
    307 		return (0);
    308 	}
    309 
    310 	ret = _citrus_NONE_ctype_wcrtomb(cl, s, wc, NULL, &nr);
    311 	*nresult = (int)nr;
    312 
    313 	return (ret);
    314 }
    315 
    316 static int
    317 /*ARGSUSED*/
    318 _citrus_NONE_ctype_btowc(_citrus_ctype_rec_t * __restrict cc,
    319 			 int c, wint_t * __restrict wcresult)
    320 {
    321 	if (c == EOF || c & ~0xFF)
    322 		*wcresult = WEOF;
    323 	else
    324 		*wcresult = (wint_t)c;
    325 	return (0);
    326 }
    327 
    328 static int
    329 /*ARGSUSED*/
    330 _citrus_NONE_ctype_wctob(_citrus_ctype_rec_t * __restrict cc,
    331 			 wint_t wc, int * __restrict cresult)
    332 {
    333 	if (wc == WEOF || wc & ~0xFF)
    334 		*cresult = EOF;
    335 	else
    336 		*cresult = (int)wc;
    337 	return (0);
    338 }
    339 
    340 /* ---------------------------------------------------------------------- */
    341 
    342 _CITRUS_STDENC_DECLS(NONE);
    343 _CITRUS_STDENC_DEF_OPS(NONE);
    344 struct _citrus_stdenc_traits _citrus_NONE_stdenc_traits = {
    345 	0,	/* et_state_size */
    346 	1,	/* mb_cur_max */
    347 };
    348 
    349 static int
    350 /*ARGSUSED*/
    351 _citrus_NONE_stdenc_init(struct _citrus_stdenc * __restrict ce,
    352 			 const void *var, size_t lenvar,
    353 			 struct _citrus_stdenc_traits * __restrict et)
    354 {
    355 
    356 	et->et_state_size = 0;
    357 	et->et_mb_cur_max = 1;
    358 
    359 	ce->ce_closure = NULL;
    360 
    361 	return (0);
    362 }
    363 
    364 static void
    365 /*ARGSUSED*/
    366 _citrus_NONE_stdenc_uninit(struct _citrus_stdenc *ce)
    367 {
    368 }
    369 
    370 static int
    371 /*ARGSUSED*/
    372 _citrus_NONE_stdenc_init_state(struct _citrus_stdenc * __restrict ce,
    373 			       void * __restrict ps)
    374 {
    375 	return (0);
    376 }
    377 
    378 static int
    379 /*ARGSUSED*/
    380 _citrus_NONE_stdenc_mbtocs(struct _citrus_stdenc * __restrict ce,
    381 			   _csid_t *csid, _index_t *idx,
    382 			   const char **s, size_t n,
    383 			   void *ps, size_t *nresult)
    384 {
    385 
    386 	_DIAGASSERT(csid != NULL && idx != NULL);
    387 
    388 	if (n<1) {
    389 		*nresult = (size_t)-2;
    390 		return (0);
    391 	}
    392 
    393 	*csid = 0;
    394 	*idx = (_index_t)(unsigned char)*(*s)++;
    395 	*nresult = *idx == 0 ? 0 : 1;
    396 
    397 	return (0);
    398 }
    399 
    400 static int
    401 /*ARGSUSED*/
    402 _citrus_NONE_stdenc_cstomb(struct _citrus_stdenc * __restrict ce,
    403 			   char *s, size_t n,
    404 			   _csid_t csid, _index_t idx,
    405 			   void *ps, size_t *nresult)
    406 {
    407 
    408 	if (csid == _CITRUS_CSID_INVALID) {
    409 		*nresult = 0;
    410 		return (0);
    411 	}
    412 	if (n<1) {
    413 		*nresult = (size_t)-1;
    414 		return (E2BIG);
    415 	}
    416 	if (csid != 0 || (idx&0xFF) != idx)
    417 		return (EILSEQ);
    418 
    419 	*s = (char)idx;
    420 	*nresult = 1;
    421 
    422 	return (0);
    423 }
    424 
    425 static int
    426 /*ARGSUSED*/
    427 _citrus_NONE_stdenc_mbtowc(struct _citrus_stdenc * __restrict ce,
    428 			   _wc_t * __restrict pwc,
    429 			   const char ** __restrict s, size_t n,
    430 			   void * __restrict pspriv,
    431 			   size_t * __restrict nresult)
    432 {
    433 	if (s == NULL) {
    434 		*nresult = 0;
    435 		return (0);
    436 	}
    437 	if (n == 0) {
    438 		*nresult = (size_t)-2;
    439 		return (0);
    440 	}
    441 
    442 	if (pwc != NULL)
    443 		*pwc = (_wc_t)(unsigned char) **s;
    444 
    445 	*nresult = *s == '\0' ? 0 : 1;
    446 	return (0);
    447 }
    448 
    449 static int
    450 /*ARGSUSED*/
    451 _citrus_NONE_stdenc_wctomb(struct _citrus_stdenc * __restrict ce,
    452 			   char * __restrict s, size_t n,
    453 			   _wc_t wc, void * __restrict pspriv,
    454 			   size_t * __restrict nresult)
    455 {
    456 	if ((wc&~0xFFU) != 0) {
    457 		*nresult = (size_t)-1;
    458 		return (EILSEQ);
    459 	}
    460 	if (n==0) {
    461 		*nresult = (size_t)-1;
    462 		return (E2BIG);
    463 	}
    464 
    465 	*nresult = 1;
    466 	if (s!=NULL && n>0)
    467 		*s = (char)wc;
    468 
    469 	return (0);
    470 }
    471 
    472 static int
    473 /*ARGSUSED*/
    474 _citrus_NONE_stdenc_put_state_reset(struct _citrus_stdenc * __restrict ce,
    475 				    char * __restrict s, size_t n,
    476 				    void * __restrict pspriv,
    477 				    size_t * __restrict nresult)
    478 {
    479 
    480 	*nresult = 0;
    481 
    482 	return (0);
    483 }
    484 
    485 static int
    486 /*ARGSUSED*/
    487 _citrus_NONE_stdenc_get_state_desc(struct _stdenc * __restrict ce,
    488 				   void * __restrict ps,
    489 				   int id,
    490 				   struct _stdenc_state_desc * __restrict d)
    491 {
    492 	int ret = 0;
    493 
    494 	switch (id) {
    495 	case _STDENC_SDID_GENERIC:
    496 		d->u.generic.state = _STDENC_SDGEN_INITIAL;
    497 		break;
    498 	default:
    499 		ret = EOPNOTSUPP;
    500 	}
    501 
    502 	return ret;
    503 }
    504