Citrus iconv support (1)

add core engine of Citrus iconv and some support routines.
  - iconv core (citrus_iconv)
  - coded character set mapper (csmapper)
  - encoding scheme database (esdb)
  - standard encoding scheme handler (stdenc)
  - basic character set manipulation utilities (bcs)
  - mmap based infrastructure (citrus_lookup/_mmap/_memstream/_db)
  - some source codes of new plugins (not built yet)
This commit is contained in:
tshiozak 2003-06-25 09:51:26 +00:00
parent d40cbfcc0b
commit 04e58308a3
79 changed files with 9325 additions and 147 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: paths.h,v 1.22 2003/05/03 03:24:01 lukem Exp $ */
/* $NetBSD: paths.h,v 1.23 2003/06/25 09:51:26 tshiozak Exp $ */
/*
* Copyright (c) 1989, 1993
@ -66,6 +66,9 @@
#define _PATH_DEVNULL "/dev/null"
#define _PATH_DRUM "/dev/drum"
#define _PATH_I18NMODULE "/usr/lib/i18n"
#define _PATH_ICONV "/usr/share/i18n/iconv"
#define _PATH_ESDB "/usr/share/i18n/esdb"
#define _PATH_CSMAPPER "/usr/share/i18n/csmapper"
#define _PATH_KMEM "/dev/kmem"
#define _PATH_KSYMS "/dev/ksyms"
#define _PATH_KVMDB "/var/db/kvm.db"

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile.inc,v 1.3 2003/03/05 20:18:15 tshiozak Exp $
# $NetBSD: Makefile.inc,v 1.4 2003/06/25 09:51:26 tshiozak Exp $
# sources
.PATH: ${ARCHDIR}/citrus ${.CURDIR}/citrus
@ -9,10 +9,10 @@ CITRUS?= yes
MODULE_SHLIB_MAJOR!= . ${NETBSDSRCDIR}/lib/i18n_module/shlib_version ; echo $$major
CPPFLAGS+= -DI18NMODULE_MAJOR=${MODULE_SHLIB_MAJOR}
SRCS+= citrus_ctype.c citrus_ctype_fallback.c citrus_module.c citrus_none.c
# to be dynamically loaded - see lib/i18n_module
#SRCS+= citrus_big5.c citrus_euc.c citrus_euctw.c citrus_iso2022.c \
# citrus_mskanji.c citrus_utf8.c
SRCS+= citrus_bcs.c citrus_csmapper.c citrus_ctype.c citrus_ctype_fallback.c \
citrus_db.c citrus_db_hash.c citrus_esdb.c citrus_hash.c \
citrus_iconv.c citrus_lookup.c \
citrus_mapper.c citrus_memstream.c citrus_mmap.c citrus_module.c \
citrus_none.c citrus_stdenc.c
.endif

View File

@ -0,0 +1,139 @@
/* $NetBSD: citrus_bcs.c,v 1.1 2003/06/25 09:51:26 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_bcs.c,v 1.1 2003/06/25 09:51:26 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#ifndef HOSTPROG
#include "namespace.h"
#endif
#include <assert.h>
#include <stdlib.h>
#include "citrus_namespace.h"
#include "citrus_bcs.h"
int
_citrus_bcs_strcasecmp(const char * __restrict str1,
const char * __restrict str2)
{
int c1=1, c2=1;
while (c1 && c2 && c1==c2) {
c1 = _bcs_toupper(*str1++);
c2 = _bcs_toupper(*str2++);
}
return ((c1==c2) ? 0 : ((c1>c2) ? 1:-1));
}
int
_citrus_bcs_strncasecmp(const char * __restrict str1,
const char * __restrict str2, size_t sz)
{
int c1=1, c2=1;
while (c1 && c2 && c1==c2 && sz!=0) {
c1 = _bcs_toupper(*str1++);
c2 = _bcs_toupper(*str2++);
sz--;
}
return ((c1==c2) ? 0 : ((c1>c2) ? 1:-1));
}
const char *
_citrus_bcs_skip_ws(const char *p)
{
while (*p && _bcs_isspace(*p))
p++;
return (p);
}
const char *
_citrus_bcs_skip_nonws(const char *p)
{
while (*p && !_bcs_isspace(*p))
p++;
return (p);
}
const char *
_citrus_bcs_skip_ws_len(const char * __restrict p, size_t * __restrict len)
{
while (*p && *len>0 && _bcs_isspace(*p)) {
p++;
(*len)--;
}
return (p);
}
const char *
_citrus_bcs_skip_nonws_len(const char * __restrict p, size_t * __restrict len)
{
while (*p && *len>0 && !_bcs_isspace(*p)) {
p++;
(*len)--;
}
return (p);
}
void
_citrus_bcs_trunc_rws_len(const char * __restrict p, size_t * __restrict len)
{
while (*len>0 && _bcs_isspace(p[*len-1]))
(*len)--;
}
void
_citrus_bcs_convert_to_lower(char *s)
{
while (*s) {
*s = _bcs_tolower(*s);
s++;
}
}
void _citrus_bcs_convert_to_upper(char *s)
{
while (*s) {
*s = _bcs_toupper(*s);
s++;
}
}

View File

@ -0,0 +1,80 @@
/* $NetBSD: citrus_bcs.h,v 1.1 2003/06/25 09:51:26 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_BCS_H_
#define _CITRUS_BCS_H_
/*
* predicate/conversion for basic character set.
*/
#define _CITRUS_BCS_PRED(_name_, _cond_) \
static __inline int _citrus_bcs_##_name_(u_int8_t c) { return (_cond_); }
_CITRUS_BCS_PRED(isblank, c==' ' || c=='\t')
_CITRUS_BCS_PRED(iseol, c=='\n' || c=='\r')
_CITRUS_BCS_PRED(isspace,
_citrus_bcs_isblank(c) || _citrus_bcs_iseol(c) ||
c=='\f' || c=='\v')
_CITRUS_BCS_PRED(isdigit, c>='0' && c<='9')
_CITRUS_BCS_PRED(isupper, c>='A' && c<='Z')
_CITRUS_BCS_PRED(islower, c>='a' && c<='z')
_CITRUS_BCS_PRED(isalpha, _citrus_bcs_isupper(c) || _citrus_bcs_islower(c))
_CITRUS_BCS_PRED(isalnum, _citrus_bcs_isdigit(c) || _citrus_bcs_isalpha(c))
_CITRUS_BCS_PRED(isxdigit,
_citrus_bcs_isdigit(c) ||
(c>='A' && c<='F') || (c>='a' && c<='f'))
static __inline u_int8_t
_citrus_bcs_toupper(u_int8_t c)
{
return (_citrus_bcs_islower(c) ? (c-'a'+'A') : c);
}
static __inline u_int8_t
_citrus_bcs_tolower(u_int8_t c)
{
return (_citrus_bcs_isupper(c) ? (c-'A'+'a') : c);
}
__BEGIN_DECLS
int _citrus_bcs_strcasecmp(const char * __restrict, const char * __restrict);
int _citrus_bcs_strncasecmp(const char * __restrict, const char * __restrict,
size_t);
const char *_citrus_bcs_skip_ws(const char * __restrict);
const char *_citrus_bcs_skip_nonws(const char * __restrict);
const char *_citrus_bcs_skip_ws_len(const char * __restrict,
size_t * __restrict);
const char *_citrus_bcs_skip_nonws_len(const char * __restrict,
size_t * __restrict);
void _citrus_bcs_trunc_rws_len(const char * __restrict, size_t * __restrict);
void _citrus_bcs_convert_to_lower(char *);
void _citrus_bcs_convert_to_upper(char *);
__END_DECLS
#endif

View File

@ -0,0 +1,384 @@
/* $NetBSD: citrus_csmapper.c,v 1.1 2003/06/25 09:51:27 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_csmapper.c,v 1.1 2003/06/25 09:51:27 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
#include "reentrant.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <paths.h>
#include <sys/types.h>
#include <sys/queue.h>
#include "citrus_namespace.h"
#include "citrus_types.h"
#include "citrus_bcs.h"
#include "citrus_region.h"
#include "citrus_memstream.h"
#include "citrus_mmap.h"
#include "citrus_module.h"
#include "citrus_hash.h"
#include "citrus_mapper.h"
#include "citrus_csmapper.h"
#include "citrus_pivot_file.h"
#include "citrus_db.h"
#include "citrus_db_hash.h"
#include "citrus_lookup.h"
#ifdef _REENTRANT
static rwlock_t lock = RWLOCK_INITIALIZER;
#endif
static struct _citrus_mapper_area *maparea = NULL;
#define CS_ALIAS _PATH_CSMAPPER "/charset.alias"
#define CS_PIVOT _PATH_CSMAPPER "/charset.pivot"
/* ---------------------------------------------------------------------- */
static int
get32(struct _region *r, u_int32_t *rval)
{
if (_region_size(r) != 4)
return EFTYPE;
memcpy(rval, _region_head(r), 4);
*rval = be32toh(*rval);
return 0;
}
static int
open_subdb(struct _citrus_db **subdb, struct _citrus_db *db, const char *src)
{
int ret;
struct _region r;
ret = _db_lookup_by_s(db, src, &r, NULL);
if (ret)
return ret;
ret = _db_open(subdb, &r, _CITRUS_PIVOT_SUB_MAGIC, _db_hash_std, NULL);
if (ret)
return ret;
return 0;
}
#define NO_SUCH_FILE EOPNOTSUPP
static int
find_best_pivot_pvdb(const char *src, const char *dst, char *pivot,
size_t pvlen, unsigned long *rnorm)
{
int ret, num, i;
struct _region fr, r1, r2;
struct _citrus_db *db1, *db2, *db3;
char buf[LINE_MAX];
unsigned long norm;
u_int32_t val32;
ret = _map_file(&fr, CS_PIVOT ".pvdb");
if (ret) {
if (ret == ENOENT)
ret = NO_SUCH_FILE;
return ret;
}
ret = _db_open(&db1, &fr, _CITRUS_PIVOT_MAGIC, _db_hash_std, NULL);
if (ret)
goto quit1;
ret = open_subdb(&db2, db1, src);
if (ret)
goto quit2;
num = _db_get_num_entries(db2);
*rnorm = ULONG_MAX;
for (i=0; i<num; i++) {
/* iterate each pivot */
ret = _db_get_entry(db2, i, &r1, &r2);
if (ret)
goto quit3;
/* r1:pivot name, r2:norm among src and pivot */
ret = get32(&r2, &val32);
if (ret)
goto quit3;
norm = val32;
snprintf(buf, sizeof(buf), "%.*s",
(int)_region_size(&r1), (char *)_region_head(&r1));
/* buf: pivot name */
ret = open_subdb(&db3, db1, buf);
if (ret)
goto quit3;
ret = _db_lookup_by_s(db3, dst, &r2, NULL);
if (ret)
goto quit4;
/* r2: norm among pivot and dst */
ret = get32(&r2, &val32);
if (ret)
goto quit4;
norm += val32;
/* judge minimum norm */
if (norm < *rnorm) {
*rnorm = norm;
strlcpy(pivot, buf, pvlen);
}
quit4:
_db_close(db3);
if (ret)
goto quit3;
}
quit3:
_db_close(db2);
quit2:
_db_close(db1);
quit1:
_unmap_file(&fr);
if (ret)
return ret;
if (*rnorm == ULONG_MAX)
return ENOENT;
return 0;
}
/* ---------------------------------------------------------------------- */
struct zone {
const char *begin, *end;
};
struct parse_arg {
char dst[PATH_MAX];
unsigned long norm;
};
static int
parse_line(struct parse_arg *pa, struct _region *r)
{
char buf[20];
struct zone z1, z2;
size_t len;
len = _region_size(r);
z1.begin = _bcs_skip_ws_len(_region_head(r), &len);
if (len == 0)
return EFTYPE;
z1.end = _bcs_skip_nonws_len(z1.begin, &len);
if (len == 0)
return EFTYPE;
z2.begin = _bcs_skip_ws_len(z1.end, &len);
if (len == 0)
return EFTYPE;
z2.end = _bcs_skip_nonws_len(z2.begin, &len);
/* z1 : dst name, z2 : norm */
snprintf(pa->dst, sizeof(pa->dst),
"%.*s", (int)(z1.end-z1.begin), z1.begin);
snprintf(buf, sizeof(buf),
"%.*s", (int)(z2.end-z2.begin), z2.begin);
pa->norm = strtoul(buf, NULL, 0);
return 0;
}
static int
find_dst(struct parse_arg *pasrc, const char *dst)
{
int ret;
struct parse_arg padst;
struct _lookup *cl;
struct _region data;
ret = _lookup_seq_open(&cl, CS_PIVOT);
if (ret)
return ret;
ret = _lookup_seq_lookup(cl, pasrc->dst, &data);
while (ret == 0) {
ret = parse_line(&padst, &data);
if (ret)
break;
if (strcmp(dst, padst.dst) == 0) {
pasrc->norm += padst.norm;
break;
}
ret = _lookup_seq_next(cl, NULL, &data);
}
_lookup_seq_close(cl);
return ret;
}
static int
find_best_pivot_lookup(const char *src, const char *dst, char *pivot,
size_t pvlen, unsigned long *rnorm)
{
int ret;
struct _lookup *cl;
struct _region data;
struct parse_arg pa;
unsigned long norm_min;
char pivot_min[PATH_MAX];
ret = _lookup_seq_open(&cl, CS_PIVOT);
if (ret)
return ret;
norm_min = ULONG_MAX;
/* find pivot code */
ret = _lookup_seq_lookup(cl, src, &data);
while (ret == 0) {
ret = parse_line(&pa, &data);
if (ret)
break;
ret = find_dst(&pa, dst);
if (ret)
break;
if (pa.norm < norm_min) {
norm_min = pa.norm;
strcpy(pivot_min, pa.dst);
}
ret = _lookup_seq_next(cl, NULL, &data);
}
_lookup_seq_close(cl);
if (ret != ENOENT)
return ret;
if (norm_min == ULONG_MAX)
return ENOENT;
strlcpy(pivot, pivot_min, pvlen);
if (rnorm)
*rnorm = norm_min;
return 0;
}
static int
find_best_pivot(const char *src, const char *dst, char *pivot, size_t pvlen,
unsigned long *rnorm)
{
int ret;
ret = find_best_pivot_pvdb(src, dst, pivot, pvlen, rnorm);
if (ret == NO_SUCH_FILE)
ret = find_best_pivot_lookup(src, dst, pivot, pvlen, rnorm);
return ret;
}
static __inline int
open_serial_mapper(struct _citrus_mapper_area *__restrict ma,
struct _citrus_mapper * __restrict * __restrict rcm,
const char *src, const char *pivot, const char *dst)
{
char buf[PATH_MAX];
snprintf(buf, sizeof(buf), "%s/%s,%s/%s", src, pivot, pivot, dst);
return _mapper_open_direct(ma, rcm, "mapper_serial", buf);
}
static struct _citrus_csmapper *csm_none = NULL;
static int
get_none(struct _citrus_mapper_area *__restrict ma,
struct _citrus_csmapper *__restrict *__restrict rcsm)
{
int ret;
rwlock_wrlock(&lock);
if (csm_none) {
*rcsm = csm_none;
ret = 0;
goto quit;
}
ret = _mapper_open_direct(ma, &csm_none, "mapper_none", "");
if (ret)
goto quit;
_mapper_set_persistent(csm_none);
*rcsm = csm_none;
ret = 0;
quit:
rwlock_unlock(&lock);
return ret;
}
int
_citrus_csmapper_open(struct _citrus_csmapper * __restrict * __restrict rcsm,
const char * __restrict src, const char * __restrict dst,
u_int32_t flags, unsigned long *rnorm)
{
int ret;
char buf1[PATH_MAX], buf2[PATH_MAX], key[PATH_MAX], pivot[PATH_MAX];
const char *realsrc, *realdst;
unsigned long norm;
ret = _citrus_mapper_create_area(&maparea, _PATH_CSMAPPER);
if (ret)
return ret;
realsrc = _lookup_alias(CS_ALIAS, src, buf1, sizeof(buf1));
realdst = _lookup_alias(CS_ALIAS, dst, buf2, sizeof(buf2));
if (!strcmp(realsrc, realdst)) {
ret = get_none(maparea, rcsm);
if (ret == 0 && rnorm != NULL)
*rnorm = 0;
return ret;
}
snprintf(key, sizeof(key), "%s/%s", realsrc, realdst);
ret = _mapper_open(maparea, rcsm, key);
if (ret == 0) {
if (rnorm != NULL)
*rnorm = 0;
return 0;
}
if (ret != ENOENT || (flags & _CSMAPPER_F_PREVENT_PIVOT)!=0)
return ret;
ret = find_best_pivot(realsrc, realdst, pivot, sizeof(pivot), &norm);
if (ret)
return ret;
ret = open_serial_mapper(maparea, rcsm, realsrc, pivot, realdst);
if (ret == 0 && rnorm != NULL)
*rnorm = norm;
return ret;
}

View File

@ -0,0 +1,48 @@
/* $NetBSD: citrus_csmapper.h,v 1.1 2003/06/25 09:51:27 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_CSMAPPER_H_
#define _CITRUS_CSMAPPER_H
#define _citrus_csmapper _citrus_mapper
#define _citrus_csmapper_close _citrus_mapper_close
#define _citrus_csmapper_convert _citrus_mapper_convert
#define _citrus_csmapper_init_state _citrus_mapper_init_state
#define _citrus_csmapper_get_state_size _citrus_mapper_get_state_size
#define _citrus_csmapper_get_src_max _citrus_mapper_get_src_max
#define _citrus_csmapper_get_dst_max _citrus_mapper_get_dst_max
#define _CITRUS_CSMAPPER_F_PREVENT_PIVOT 0x00000001
__BEGIN_DECLS
int _citrus_csmapper_open(struct _citrus_csmapper *__restrict *__restrict,
const char *__restrict,
const char *__restrict, u_int32_t,
unsigned long *);
__END_DECLS
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: citrus_ctype_template.h,v 1.21 2003/03/05 20:18:15 tshiozak Exp $ */
/* $NetBSD: citrus_ctype_template.h,v 1.22 2003/06/25 09:51:28 tshiozak Exp $ */
/*-
* Copyright (c)2002 Citrus Project,
@ -399,14 +399,14 @@ _FUNCNAME(ctype_init)(void ** __restrict cl,
*cl = (void *)cei;
return _FUNCNAME(stdencoding_init)(_CEI_TO_EI(cei), var, lenvar);
return _FUNCNAME(encoding_module_init)(_CEI_TO_EI(cei), var, lenvar);
}
static void
_FUNCNAME(ctype_uninit)(void *cl)
{
if (cl) {
_FUNCNAME(stdencoding_uninit)(_CEI_TO_EI(_TO_CEI(cl)));
_FUNCNAME(encoding_module_uninit)(_CEI_TO_EI(_TO_CEI(cl)));
free(cl);
}
}
@ -585,6 +585,8 @@ _FUNCNAME(ctype_wcrtomb)(void * __restrict cl, char * __restrict s, wchar_t wc,
err = _FUNCNAME(wcrtomb_priv)(_CEI_TO_EI(_TO_CEI(cl)), s,
_ENCODING_MB_CUR_MAX(_CEI_TO_EI(_TO_CEI(cl))),
wc, psenc, nresult);
if (err == E2BIG)
err = EINVAL;
_RESTART_END(wcrtomb, _TO_CEI(cl), pspriv, psenc);
return err;

342
lib/libc/citrus/citrus_db.c Normal file
View File

@ -0,0 +1,342 @@
/* $NetBSD: citrus_db.c,v 1.1 2003/06/25 09:51:28 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_db.c,v 1.1 2003/06/25 09:51:28 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <sys/types.h>
#include "citrus_namespace.h"
#include "citrus_bcs.h"
#include "citrus_region.h"
#include "citrus_memstream.h"
#include "citrus_mmap.h"
#include "citrus_db.h"
#include "citrus_db_file.h"
struct _citrus_db {
/* private */
struct _region db_region;
u_int32_t (*db_hashfunc)(void *, struct _citrus_region *);
void *db_hashfunc_closure;
};
int
_citrus_db_open(struct _citrus_db **rdb, struct _region *r, const char *magic,
u_int32_t (*hashfunc)(void *, struct _citrus_region *),
void *hashfunc_closure)
{
struct _memstream ms;
struct _citrus_db *db;
struct _citrus_db_header_x *dhx;
_memstream_bind(&ms, r);
/* sanity check */
dhx = _memstream_getregion(&ms, NULL, sizeof(*dhx));
if (dhx == NULL)
return EFTYPE;
if (strncmp(dhx->dhx_magic, magic, _CITRUS_DB_MAGIC_SIZE) != 0)
return EFTYPE;
if (_memstream_seek(&ms, be32toh(dhx->dhx_entry_offset), SEEK_SET))
return EFTYPE;
if (be32toh(dhx->dhx_num_entries)*_CITRUS_DB_ENTRY_SIZE >
_memstream_remainder(&ms))
return EFTYPE;
db = malloc(sizeof(*db));
if (db==NULL)
return errno;
db->db_region = *r;
db->db_hashfunc = hashfunc;
db->db_hashfunc_closure = hashfunc_closure;
*rdb = db;
return 0;
}
void
_citrus_db_close(struct _citrus_db *db)
{
free(db);
}
int
_citrus_db_lookup(struct _citrus_db *db, struct _citrus_region *key,
struct _citrus_region *data, struct _citrus_db_locator *dl)
{
u_int32_t hashval, num_entries;
size_t offset;
struct _memstream ms;
struct _citrus_db_header_x *dhx;
struct _citrus_db_entry_x *dex;
struct _citrus_region r;
_memstream_bind(&ms, &db->db_region);
dhx = _memstream_getregion(&ms, NULL, sizeof(*dhx));
_DIAGASSERT(dhx);
num_entries = be32toh(dhx->dhx_num_entries);
if (num_entries == 0)
return ENOENT;
if (dl != NULL && dl->dl_offset>0) {
hashval = dl->dl_hashval;
offset = dl->dl_offset;
if (offset >= _region_size(&db->db_region))
return ENOENT;
} else {
hashval =
db->db_hashfunc(db->db_hashfunc_closure, key)%num_entries;
offset =
be32toh(dhx->dhx_entry_offset) +
hashval * _CITRUS_DB_ENTRY_SIZE;
if (dl)
dl->dl_hashval = hashval;
}
do {
/* seek to the next entry */
if (_citrus_memory_stream_seek(&ms, offset, SEEK_SET))
return EFTYPE;
/* get the entry record */
dex = _memstream_getregion(&ms, NULL, _CITRUS_DB_ENTRY_SIZE);
if (dex == NULL)
return EFTYPE;
/* jump to next entry having the same hash value. */
offset = be32toh(dex->dex_next_offset);
/* save the current position */
if (dl) {
dl->dl_offset = offset;
if (offset==0)
dl->dl_offset = _region_size(&db->db_region);
}
/* compare hash value. */
if (be32toh(dex->dex_hash_value) != hashval)
/* not found */
break;
/* compare key length */
if (be32toh(dex->dex_key_size) == _region_size(key)) {
/* seek to the head of the key. */
if (_memstream_seek(&ms, be32toh(dex->dex_key_offset),
SEEK_SET))
return EFTYPE;
/* get the region of the key */
if (_memstream_getregion(&ms, &r,
_region_size(key)) == NULL)
return EFTYPE;
/* compare key byte stream */
if (memcmp(_region_head(&r), _region_head(key),
_region_size(key)) == 0) {
/* match */
if (_memstream_seek(
&ms, be32toh(dex->dex_data_offset),
SEEK_SET))
return EFTYPE;
if (_memstream_getregion(
&ms, data,
be32toh(dex->dex_data_size)) == NULL)
return EFTYPE;
return 0;
}
}
} while (offset != 0);
return ENOENT;
}
int
_citrus_db_lookup_by_string(struct _citrus_db *db, const char *key,
struct _citrus_region *data,
struct _citrus_db_locator *dl)
{
struct _region r;
/* LINTED: discard const */
_region_init(&r, (char *)key, strlen(key));
return _citrus_db_lookup(db, &r, data, dl);
}
int
_citrus_db_lookup8_by_string(struct _citrus_db *db, const char *key,
u_int8_t *rval, struct _citrus_db_locator *dl)
{
int ret;
struct _region r;
ret = _citrus_db_lookup_by_string(db, key, &r, dl);
if (ret)
return ret;
if (_region_size(&r) != 1)
return EFTYPE;
if (rval)
memcpy(rval, _region_head(&r), 1);
return 0;
}
int
_citrus_db_lookup16_by_string(struct _citrus_db *db, const char *key,
u_int16_t *rval, struct _citrus_db_locator *dl)
{
int ret;
struct _region r;
u_int16_t val;
ret = _citrus_db_lookup_by_string(db, key, &r, dl);
if (ret)
return ret;
if (_region_size(&r) != 2)
return EFTYPE;
if (rval) {
memcpy(&val, _region_head(&r), 2);
*rval = be16toh(val);
}
return 0;
}
int
_citrus_db_lookup32_by_string(struct _citrus_db *db, const char *key,
u_int32_t *rval, struct _citrus_db_locator *dl)
{
int ret;
struct _region r;
u_int32_t val;
ret = _citrus_db_lookup_by_string(db, key, &r, dl);
if (ret)
return ret;
if (_region_size(&r) != 4)
return EFTYPE;
if (rval) {
memcpy(&val, _region_head(&r), 4);
*rval = be32toh(val);
}
return 0;
}
int
_citrus_db_lookup_string_by_string(struct _citrus_db *db, const char *key,
const char **rdata,
struct _citrus_db_locator *dl)
{
int ret;
struct _region r;
ret = _citrus_db_lookup_by_string(db, key, &r, dl);
if (ret)
return ret;
if (_region_size(&r) == 0)
return EFTYPE;
/* check whether the string is null terminated */
if (*((const char*)_region_head(&r)+_region_size(&r)) != '\0')
return EFTYPE;
if (rdata)
*rdata = _region_head(&r);
return 0;
}
int
_citrus_db_get_number_of_entries(struct _citrus_db *db)
{
struct _memstream ms;
struct _citrus_db_header_x *dhx;
_memstream_bind(&ms, &db->db_region);
dhx = _memstream_getregion(&ms, NULL, sizeof(*dhx));
_DIAGASSERT(dhx);
return (int)be32toh(dhx->dhx_num_entries);
}
int
_citrus_db_get_entry(struct _citrus_db *db, int idx,
struct _region *key, struct _region *data)
{
u_int32_t num_entries;
size_t offset;
struct _memstream ms;
struct _citrus_db_header_x *dhx;
struct _citrus_db_entry_x *dex;
_memstream_bind(&ms, &db->db_region);
dhx = _memstream_getregion(&ms, NULL, sizeof(*dhx));
_DIAGASSERT(dhx);
num_entries = be32toh(dhx->dhx_num_entries);
if (idx<0 || (u_int32_t)idx>=num_entries)
return EINVAL;
/* seek to the next entry */
offset = be32toh(dhx->dhx_entry_offset) + idx * _CITRUS_DB_ENTRY_SIZE;
if (_citrus_memory_stream_seek(&ms, offset, SEEK_SET))
return EFTYPE;
/* get the entry record */
dex = _memstream_getregion(&ms, NULL, _CITRUS_DB_ENTRY_SIZE);
if (dex == NULL)
return EFTYPE;
/* seek to the head of the key. */
if (_memstream_seek(&ms, be32toh(dex->dex_key_offset), SEEK_SET))
return EFTYPE;
/* get the region of the key. */
if (_memstream_getregion(&ms, key, be32toh(dex->dex_key_size))==NULL)
return EFTYPE;
/* seek to the head of the data. */
if (_memstream_seek(&ms, be32toh(dex->dex_data_offset), SEEK_SET))
return EFTYPE;
/* get the region of the data. */
if (_memstream_getregion(&ms, data, be32toh(dex->dex_data_size))==NULL)
return EFTYPE;
return 0;
}

View File

@ -0,0 +1,74 @@
/* $NetBSD: citrus_db.h,v 1.1 2003/06/25 09:51:29 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_DB_H_
#define _CITRUS_DB_H_
struct _citrus_db;
struct _citrus_db_locator {
u_int32_t dl_hashval;
size_t dl_offset;
};
__BEGIN_DECLS
int _citrus_db_open(struct _citrus_db **, struct _citrus_region *,
const char *,
u_int32_t (*)(void *, struct _citrus_region *),
void *);
void _citrus_db_close(struct _citrus_db *);
int _citrus_db_lookup(struct _citrus_db *, struct _citrus_region *,
struct _citrus_region *,
struct _citrus_db_locator *);
int _citrus_db_lookup_by_string(struct _citrus_db *, const char *,
struct _citrus_region *,
struct _citrus_db_locator *);
int _citrus_db_lookup8_by_string(struct _citrus_db *, const char *,
u_int8_t *,
struct _citrus_db_locator *);
int _citrus_db_lookup16_by_string(struct _citrus_db *, const char *,
u_int16_t *,
struct _citrus_db_locator *);
int _citrus_db_lookup32_by_string(struct _citrus_db *, const char *,
u_int32_t *,
struct _citrus_db_locator *);
int _citrus_db_lookup_string_by_string(struct _citrus_db *, const char *,
const char **,
struct _citrus_db_locator *);
int _citrus_db_get_number_of_entries(struct _citrus_db *);
int _citrus_db_get_entry(struct _citrus_db *, int,
struct _citrus_region *, struct _citrus_region *);
__END_DECLS
static __inline void
_citrus_db_locator_init(struct _citrus_db_locator *dl)
{
dl->dl_hashval = 0;
dl->dl_offset = 0;
}
#endif

View File

@ -0,0 +1,351 @@
/* $NetBSD: citrus_db_factory.c,v 1.1 2003/06/25 09:51:29 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_db_factory.c,v 1.1 2003/06/25 09:51:29 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/queue.h>
#ifndef __packed
#define __packed /* ignored */
#endif
#include "citrus_namespace.h"
#include "citrus_region.h"
#include "citrus_db_file.h"
#include "citrus_db_factory.h"
struct _citrus_db_factory_entry {
SIMPLEQ_ENTRY(_citrus_db_factory_entry) de_entry;
struct _citrus_db_factory_entry *de_next;
u_int32_t de_hashvalue;
struct _region de_key;
int de_key_free;
struct _region de_data;
int de_data_free;
int de_idx;
};
struct _citrus_db_factory {
size_t df_num_entries;
SIMPLEQ_HEAD(, _citrus_db_factory_entry) df_entries;
size_t df_total_key_size;
size_t df_total_data_size;
u_int32_t (*df_hashfunc)(void *, struct _citrus_region *);
void *df_hashfunc_closure;
};
#define DB_ALIGN 16
int
_citrus_db_factory_create(struct _citrus_db_factory **rdf,
_citrus_db_hash_func_t hashfunc,
void *hashfunc_closure)
{
struct _citrus_db_factory *df;
df = malloc(sizeof(*df));
if (df == NULL)
return errno;
df->df_num_entries = 0;
df->df_total_key_size = df->df_total_data_size = 0;
SIMPLEQ_INIT(&df->df_entries);
df->df_hashfunc = hashfunc;
df->df_hashfunc_closure = hashfunc_closure;
*rdf = df;
return 0;
}
void
_citrus_db_factory_free(struct _citrus_db_factory *df)
{
struct _citrus_db_factory_entry *de;
while ((de = SIMPLEQ_FIRST(&df->df_entries)) != NULL) {
SIMPLEQ_REMOVE_HEAD(&df->df_entries, de_entry);
if (de->de_key_free)
free(_region_head(&de->de_key));
if (de->de_data_free)
free(_region_head(&de->de_data));
free(de);
}
free(df);
}
static __inline size_t
ceilto(size_t sz)
{
return (sz+DB_ALIGN-1) & ~(DB_ALIGN-1);
}
int
_citrus_db_factory_add(struct _citrus_db_factory *df,
struct _region *key, int keyfree,
struct _region *data, int datafree)
{
struct _citrus_db_factory_entry *de;
de = malloc(sizeof(*de));
if (de == NULL)
return -1;
de->de_hashvalue = df->df_hashfunc(df->df_hashfunc_closure, key);
de->de_key = *key;
de->de_key_free = keyfree;
de->de_data = *data;
de->de_data_free = datafree;
de->de_idx = -1;
SIMPLEQ_INSERT_TAIL(&df->df_entries, de, de_entry);
df->df_total_key_size += _region_size(key);
df->df_total_data_size += ceilto(_region_size(data));
df->df_num_entries++;
return 0;
}
int
_citrus_db_factory_add_by_string(struct _citrus_db_factory *df,
const char *key,
struct _citrus_region *data, int datafree)
{
struct _region r;
char *tmp;
tmp = strdup(key);
if (tmp == NULL)
return errno;
_region_init(&r, tmp, strlen(key));
return _citrus_db_factory_add(df, &r, 1, data, datafree);
}
int
_citrus_db_factory_add8_by_string(struct _citrus_db_factory *df,
const char *key, u_int8_t val)
{
struct _region r;
u_int8_t *p;
p = malloc(sizeof(*p));
if (p == NULL)
return errno;
*p = val;
_region_init(&r, p, 1);
return _citrus_db_factory_add_by_string(df, key, &r, 1);
}
int
_citrus_db_factory_add16_by_string(struct _citrus_db_factory *df,
const char *key, u_int16_t val)
{
struct _region r;
u_int16_t *p;
p = malloc(sizeof(*p));
if (p == NULL)
return errno;
*p = htons(val);
_region_init(&r, p, 2);
return _citrus_db_factory_add_by_string(df, key, &r, 1);
}
int
_citrus_db_factory_add32_by_string(struct _citrus_db_factory *df,
const char *key, u_int32_t val)
{
struct _region r;
u_int32_t *p;
p = malloc(sizeof(*p));
if (p == NULL)
return errno;
*p = htonl(val);
_region_init(&r, p, 4);
return _citrus_db_factory_add_by_string(df, key, &r, 1);
}
int
_citrus_db_factory_add_string_by_string(struct _citrus_db_factory *df,
const char *key, const char *data)
{
char *p;
struct _region r;
p = strdup(data);
if (p == NULL)
return errno;
_region_init(&r, p, strlen(p)+1);
return _citrus_db_factory_add_by_string(df, key, &r, 1);
}
size_t
_citrus_db_factory_calc_size(struct _citrus_db_factory *df)
{
size_t sz;
sz = ceilto(_CITRUS_DB_HEADER_SIZE);
sz += ceilto(_CITRUS_DB_ENTRY_SIZE * df->df_num_entries);
sz += ceilto(df->df_total_key_size);
sz += df->df_total_data_size;
return sz;
}
static __inline void
put8(struct _region *r, size_t *rofs, u_int8_t val)
{
*(u_int8_t *)_region_offset(r, *rofs) = val;
*rofs += 1;
}
static __inline void
put16(struct _region *r, size_t *rofs, u_int16_t val)
{
val = htons(val);
memcpy(_region_offset(r, *rofs), &val, 2);
*rofs += 2;
}
static __inline void
put32(struct _region *r, size_t *rofs, u_int32_t val)
{
val = htonl(val);
memcpy(_region_offset(r, *rofs), &val, 4);
*rofs += 4;
}
static __inline void
putpad(struct _region *r, size_t *rofs)
{
size_t i;
for (i=ceilto(*rofs)-*rofs; i>0; i--)
put8(r, rofs, 0);
}
static __inline void
dump_header(struct _region *r, const char *magic, size_t *rofs,
size_t num_entries)
{
while (*rofs<_CITRUS_DB_MAGIC_SIZE)
put8(r, rofs, *magic++);
put32(r, rofs, num_entries);
put32(r, rofs, _CITRUS_DB_HEADER_SIZE);
}
int
_citrus_db_factory_serialize(struct _citrus_db_factory *df, const char *magic,
struct _region *r)
{
size_t i, ofs, keyofs, dataofs, nextofs;
struct _citrus_db_factory_entry *de, **depp, *det;
ofs = 0;
/* check whether more than 0 entries exist */
if (df->df_num_entries == 0) {
dump_header(r, magic, &ofs, 0);
return 0;
}
/* allocate hash table */
depp = malloc(sizeof(*depp)*df->df_num_entries);
if (depp == NULL)
return -1;
for (i=0; i<df->df_num_entries; i++)
*depp = NULL;
/* step1: store the entries which are not conflicting */
SIMPLEQ_FOREACH(de, &df->df_entries, de_entry) {
de->de_hashvalue %= df->df_num_entries;
de->de_idx = -1;
de->de_next = NULL;
if (depp[de->de_hashvalue] == NULL) {
depp[de->de_hashvalue] = de;
de->de_idx = (int)de->de_hashvalue;
}
}
/* step2: resolve conflicts */
i = 0;
SIMPLEQ_FOREACH(de, &df->df_entries, de_entry) {
if (de->de_idx == -1) {
det = depp[de->de_hashvalue];
while (det->de_next != NULL)
det = det->de_next;
det->de_next = de;
while (depp[i] != NULL)
i++;
depp[i] = de;
de->de_idx = (int)i;
}
}
keyofs =
_CITRUS_DB_HEADER_SIZE +
ceilto(df->df_num_entries*_CITRUS_DB_ENTRY_SIZE);
dataofs = keyofs + ceilto(df->df_total_key_size);
/* dump header */
dump_header(r, magic, &ofs, df->df_num_entries);
/* dump entries */
for (i=0; i<df->df_num_entries; i++) {
de = depp[i];
nextofs = 0;
if (de->de_next) {
nextofs =
_CITRUS_DB_HEADER_SIZE +
de->de_next->de_idx * _CITRUS_DB_ENTRY_SIZE;
}
put32(r, &ofs, de->de_hashvalue);
put32(r, &ofs, nextofs);
put32(r, &ofs, keyofs);
put32(r, &ofs, _region_size(&de->de_key));
put32(r, &ofs, dataofs);
put32(r, &ofs, _region_size(&de->de_data));
memcpy(_region_offset(r, keyofs),
_region_head(&de->de_key), _region_size(&de->de_key));
keyofs += _region_size(&de->de_key);
memcpy(_region_offset(r, dataofs),
_region_head(&de->de_data), _region_size(&de->de_data));
dataofs += _region_size(&de->de_data);
putpad(r, &dataofs);
}
putpad(r, &ofs);
putpad(r, &keyofs);
free(depp);
return 0;
}

View File

@ -0,0 +1,58 @@
/* $NetBSD: citrus_db_factory.h,v 1.1 2003/06/25 09:51:30 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_DB_FACTORY_H_
#define _CITRUS_DB_FACTORY_H_
struct _citrus_db_factory;
typedef u_int32_t (*_citrus_db_hash_func_t)(void *, struct _citrus_region *);;
__BEGIN_DECLS
int _citrus_db_factory_create(struct _citrus_db_factory **,
_citrus_db_hash_func_t, void *);
void _citrus_db_factory_free(struct _citrus_db_factory *);
int _citrus_db_factory_add(struct _citrus_db_factory *,
struct _citrus_region *, int,
struct _citrus_region *, int);
int _citrus_db_factory_add_by_string(struct _citrus_db_factory *,
const char *,
struct _citrus_region *, int);
int _citrus_db_factory_add8_by_string(struct _citrus_db_factory *,
const char *, u_int8_t);
int _citrus_db_factory_add16_by_string(struct _citrus_db_factory *,
const char *, u_int16_t);
int _citrus_db_factory_add32_by_string(struct _citrus_db_factory *,
const char *, u_int32_t);
int _citrus_db_factory_add_string_by_string(struct _citrus_db_factory *,
const char *, const char *);
size_t _citrus_db_factory_calc_size(struct _citrus_db_factory *);
int _citrus_db_factory_serialize(struct _citrus_db_factory *,
const char *, struct _citrus_region *);
__END_DECLS
#endif

View File

@ -0,0 +1,84 @@
/* $NetBSD: citrus_db_file.h,v 1.1 2003/06/25 09:51:30 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_DB_FILE_H_
#define _CITRUS_DB_FILE_H_
/*
* db format:
* +---
* | header
* | - magic
* | - num entries
* +---
* | entry directory
* | +------------
* | | entry0
* | | - hash value
* | | - next entry
* | | - key offset
* | | - key len
* | | - data offset
* | | - data size
* | |---
* | | entry1
* | | ..
* | | entryN
* | +---
* +---
* | key table
* | - key0
* | ...
* | - keyN
* +---
* | data table
* | - data0
* | ...
* | - dataN
* +---
*/
#define _CITRUS_DB_MAGIC_SIZE 8
#define _CITRUS_DB_HEADER_SIZE 16
struct _citrus_db_header_x {
char dhx_magic[_CITRUS_DB_MAGIC_SIZE];
u_int32_t dhx_num_entries;
u_int32_t dhx_entry_offset;
} __packed;
struct _citrus_db_entry_x {
u_int32_t dex_hash_value;
u_int32_t dex_next_offset;
u_int32_t dex_key_offset;
u_int32_t dex_key_size;
u_int32_t dex_data_offset;
u_int32_t dex_data_size;
} __packed;
#define _CITRUS_DB_ENTRY_SIZE 24
#endif

View File

@ -0,0 +1,67 @@
/* $NetBSD: citrus_db_hash.c,v 1.1 2003/06/25 09:51:30 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_db_hash.c,v 1.1 2003/06/25 09:51:30 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#ifndef HOSTPROG
#include "namespace.h"
#endif
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include "citrus_namespace.h"
#include "citrus_types.h"
#include "citrus_bcs.h"
#include "citrus_region.h"
#include "citrus_db_hash.h"
u_int32_t
/*ARGSUSED*/
_citrus_db_hash_std(void *closure, struct _region *r)
{
const u_int8_t *p = _region_head(r);
u_int32_t hash = 0, tmp;
size_t i;
for (i=_region_size(r); i>0; i--) {
hash <<= 4;
hash += _bcs_tolower(*p);
tmp = hash & 0xF0000000;
if (tmp != 0) {
hash ^= tmp;
hash ^= tmp >> 24;
}
p++;
}
return hash;
}

View File

@ -0,0 +1,36 @@
/* $NetBSD: citrus_db_hash.h,v 1.1 2003/06/25 09:51:31 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_DB_HASH_H_
#define _CITRUS_DB_HASH_H_
__BEGIN_DECLS
u_int32_t _citrus_db_hash_std(void *, struct _citrus_region *);
__END_DECLS
#endif

View File

@ -0,0 +1,343 @@
/* $NetBSD: citrus_esdb.c,v 1.1 2003/06/25 09:51:31 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_esdb.c,v 1.1 2003/06/25 09:51:31 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <paths.h>
#include <sys/types.h>
#include "citrus_namespace.h"
#include "citrus_types.h"
#include "citrus_bcs.h"
#include "citrus_region.h"
#include "citrus_memstream.h"
#include "citrus_mmap.h"
#include "citrus_lookup.h"
#include "citrus_db.h"
#include "citrus_db_hash.h"
#include "citrus_esdb.h"
#include "citrus_esdb_file.h"
#define ESDB_DIR "esdb.dir"
#define ESDB_ALIAS "esdb.alias"
/*
* _citrus_esdb_alias:
* resolve encoding scheme name aliases.
*/
const char *
_citrus_esdb_alias(const char *esname, char *buf, size_t bufsize)
{
return _lookup_alias(_PATH_ESDB "/" ESDB_ALIAS, esname, buf, bufsize);
}
/*
* conv_esdb:
* external representation -> local structure.
*/
static int
conv_esdb(struct _citrus_esdb *esdb, struct _region *fr)
{
int ret;
struct _citrus_db *db;
u_int32_t version, num_charsets, csid, i, tmp;
char buf[100];
const char *str;
/* open db */
ret = _db_open(&db, fr, _CITRUS_ESDB_MAGIC, &_db_hash_std, NULL);
if (ret)
goto err0;
/* check version */
ret = _db_lookup32_by_s(db, _CITRUS_ESDB_SYM_VERSION, &version, NULL);
if (ret)
goto err1;
switch (version) {
case 0x00000001:
/* current version */
/* initial version */
break;
default:
ret = EFTYPE;
goto err1;
}
/* get encoding/variable */
ret = _db_lookupstr_by_s(db, _CITRUS_ESDB_SYM_ENCODING, &str, NULL);
if (ret)
goto err1;
esdb->db_encname = strdup(str);
if (esdb->db_encname == NULL) {
ret = errno;
goto err1;
}
esdb->db_len_variable = 0;
esdb->db_variable = NULL;
ret = _db_lookupstr_by_s(db, _CITRUS_ESDB_SYM_VARIABLE, &str, NULL);
if (ret==0) {
esdb->db_len_variable = strlen(str)+1;
esdb->db_variable = strdup(str);
if (esdb->db_variable == NULL) {
ret = errno;
goto err2;
}
} else if (ret != ENOENT)
goto err2;
/* get number of charsets */
ret = _db_lookup32_by_s(db, _CITRUS_ESDB_SYM_NUM_CHARSETS,
&num_charsets, NULL);
if (ret)
goto err3;
esdb->db_num_charsets = num_charsets;
/* get invalid character */
ret = _db_lookup32_by_s(db, _CITRUS_ESDB_SYM_INVALID, &tmp, NULL);
if (ret==0) {
esdb->db_use_invalid = 1;
esdb->db_invalid = tmp;
} else if (ret == ENOENT)
esdb->db_use_invalid = 0;
else
goto err3;
/* get charsets */
esdb->db_charsets = malloc(num_charsets * sizeof(*esdb->db_charsets));
if (esdb->db_charsets == NULL) {
ret = errno;
goto err3;
}
for (i=0; i<num_charsets; i++) {
sprintf(buf, _CITRUS_ESDB_SYM_CSID_PREFIX "%d", i);
ret = _db_lookup32_by_s(db, buf, &csid, NULL);
if (ret)
goto err4;
esdb->db_charsets[i].ec_csid = csid;
sprintf(buf, _CITRUS_ESDB_SYM_CSNAME_PREFIX "%d", i);
ret = _db_lookupstr_by_s(db, buf, &str, NULL);
if (ret)
goto err4;
esdb->db_charsets[i].ec_csname = strdup(str);
if (esdb->db_charsets[i].ec_csname == NULL) {
ret = errno;
goto err4;
}
}
_db_close(db);
return 0;
err4:
for (; i>0; i--)
free(esdb->db_charsets[i-1].ec_csname);
free(esdb->db_charsets);
err3:
free(esdb->db_variable);
err2:
free(esdb->db_encname);
err1:
_db_close(db);
if (ret == ENOENT)
ret = EFTYPE;
err0:
return ret;
}
/*
* _citrus_esdb_open:
* open an ESDB file.
*/
int
_citrus_esdb_open(struct _citrus_esdb *db, const char *esname)
{
int ret;
const char *realname, *encfile;
char buf1[PATH_MAX], buf2[PATH_MAX], path[PATH_MAX];
struct _region fr;
_DIAGASSERT(esname != NULL);
snprintf(path, sizeof(path), "%s/%s", _PATH_ESDB, ESDB_ALIAS);
realname = _lookup_alias(path, esname, buf1, sizeof(buf1));
snprintf(path, sizeof(path), "%s/%s", _PATH_ESDB, ESDB_DIR);
encfile = _lookup_simple(path, realname, buf2, sizeof(buf2));
if (encfile==NULL)
return ENOENT;
/* open file */
snprintf(path, sizeof(path), "%s/%s", _PATH_ESDB, encfile);
ret = _map_file(&fr, path);
if (ret)
return ret;
ret = conv_esdb(db, &fr);
_unmap_file(&fr);
return ret;
}
/*
* _citrus_esdb_close:
* free an ESDB.
*/
void
_citrus_esdb_close(struct _citrus_esdb *db)
{
int i;
_DIAGASSERT(db != NULL);
_DIAGASSERT(db->db_num_charsets == 0 || db->db_charsets != NULL);
for (i=0; i<db->db_num_charsets; i++)
free(db->db_charsets[i].ec_csname);
db->db_num_charsets = 0;
free(db->db_charsets); db->db_charsets = NULL;
free(db->db_encname); db->db_encname = NULL;
db->db_len_variable = 0;
free(db->db_variable); db->db_variable = NULL;
}
/*
* _citrus_esdb_free_list:
* free the list.
*/
void
_citrus_esdb_free_list(char **list, size_t num)
{
size_t i;
for (i=0; i<num; i++)
free(list[i]);
free(list);
}
/*
* _citrus_esdb_get_list:
* get esdb entries.
*/
int
_citrus_esdb_get_list(char ***rlist, size_t *rnum)
{
int ret;
struct _region key;
size_t num;
struct _citrus_lookup *cla, *cld;
char **list;
char buf[PATH_MAX];
num = 0;
ret = _lookup_seq_open(&cla, _PATH_ESDB "/" ESDB_ALIAS);
if (ret)
goto quit0;
ret = _lookup_seq_open(&cld, _PATH_ESDB "/" ESDB_DIR);
if (ret)
goto quit1;
/* count number of entries */
num = _lookup_get_num_entries(cla) + _lookup_get_num_entries(cld);
_lookup_seq_rewind(cla);
_lookup_seq_rewind(cld);
/* allocate list pointer space */
list = malloc(num * sizeof(char *));
num=0;
if (list == NULL) {
ret = errno;
goto quit3;
}
/* get alias entries */
while ((ret = _lookup_seq_next(cla, &key, NULL)) == 0) {
snprintf(buf, sizeof(buf), "%.*s",
(int)_region_size(&key),
(const char *)_region_head(&key));
_bcs_convert_to_lower(buf);
list[num] = strdup(buf);
if (list[num] == NULL) {
ret = errno;
goto quit3;
}
num++;
}
if (ret != ENOENT)
goto quit3;
/* get dir entries */
while ((ret = _lookup_seq_next(cld, &key, NULL)) == 0) {
/* check duplicated entry */
snprintf(buf, sizeof(buf), "%.*s",
(int)_region_size(&key),
(const char *)_region_head(&key));
_bcs_convert_to_lower(buf);
ret = _lookup_seq_lookup(cla, buf, NULL);
if (ret) {
if (ret != ENOENT)
goto quit3;
/* not duplicated */
list[num] = strdup(buf);
if (list[num] == NULL) {
ret = errno;
goto quit3;
}
num++;
}
}
if (ret != ENOENT)
goto quit3;
ret = 0;
list = realloc(list, num*sizeof(char *));
*rlist = list;
*rnum = num;
quit3:
if (ret)
_citrus_esdb_free_list(list, num);
_lookup_seq_close(cld);
quit1:
_lookup_seq_close(cla);
quit0:
return ret;
}

View File

@ -0,0 +1,55 @@
/* $NetBSD: citrus_esdb.h,v 1.1 2003/06/25 09:51:32 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_ESDB_H_
#define _CITRUS_ESDB_H_
struct _citrus_esdb_charset {
_citrus_csid_t ec_csid;
char *ec_csname;
};
struct _citrus_esdb {
char *db_encname;
void *db_variable;
size_t db_len_variable;
int db_num_charsets;
struct _citrus_esdb_charset *db_charsets;
int db_use_invalid;
_citrus_wc_t db_invalid;
};
__BEGIN_DECLS
const char *_citrus_esdb_alias(const char *, char *, size_t);
int _citrus_esdb_open(struct _citrus_esdb *, const char *);
void _citrus_esdb_close(struct _citrus_esdb *);
void _citrus_esdb_free_list(char **, size_t);
int _citrus_esdb_get_list(char ***, size_t *);
__END_DECLS
#endif

View File

@ -0,0 +1,44 @@
/* $NetBSD: citrus_esdb_file.h,v 1.1 2003/06/25 09:51:32 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_ESDB_FILE_H_
#define _CITRUS_ESDB_FILE_H_
#define _CITRUS_ESDB_MAGIC "ESDB\0\0\0\0"
#define _CITRUS_ESDB_SYM_VERSION "version"
#define _CITRUS_ESDB_SYM_ENCODING "encoding"
#define _CITRUS_ESDB_SYM_VARIABLE "variable"
#define _CITRUS_ESDB_SYM_NUM_CHARSETS "num_charsets"
#define _CITRUS_ESDB_SYM_INVALID "invalid"
#define _CITRUS_ESDB_SYM_CSNAME_PREFIX "csname_"
#define _CITRUS_ESDB_SYM_CSID_PREFIX "csid_"
#define _CITRUS_ESDB_VERSION 0x00000001
#endif

View File

@ -0,0 +1,55 @@
/* $NetBSD: citrus_hash.c,v 1.1 2003/06/25 09:51:32 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_hash.c,v 1.1 2003/06/25 09:51:32 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include "citrus_namespace.h"
#include "citrus_types.h"
#include "citrus_region.h"
#include "citrus_hash.h"
#include "citrus_db_hash.h"
int
_citrus_string_hash_func(const char *key, int hashsize)
{
struct _region r;
/* LINTED: discard const */
_region_init(&r, (char *)key, strlen(key));
return (int)(_db_hash_std(NULL, &r) % (u_int32_t)hashsize);
}

View File

@ -0,0 +1,72 @@
/* $NetBSD: citrus_hash.h,v 1.1 2003/06/25 09:51:33 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_HASH_H_
#define _CITRUS_HASH_H_
#define _CITRUS_HASH_ENTRY(type) \
struct { \
struct type *che_next, **che_pprev; \
}
#define _CITRUS_HASH_HEAD(headname, type, hashsize) \
struct headname { \
struct type *chh_table[hashsize]; \
}
#define _CITRUS_HASH_INIT(head, hashsize) \
do { \
int _ch_loop; \
for (_ch_loop=0; _ch_loop<hashsize; _ch_loop++) \
(head)->chh_table[_ch_loop] = NULL; \
} while (/*CONSTCOND*/0)
#define _CITRUS_HASH_REMOVE(elm, field) \
do { \
if ((elm)->field.che_next) \
(elm)->field.che_next->field.che_pprev = \
(elm)->field.che_pprev; \
*(elm)->field.che_pprev = (elm)->field.che_next; \
} while (/*CONSTCOND*/0)
#define _CITRUS_HASH_INSERT(head, elm, field, hashval) \
do { \
(elm)->field.che_pprev = &(head)->chh_table[hashval]; \
(elm)->field.che_next = (head)->chh_table[hashval]; \
(head)->chh_table[hashval] = (elm); \
} while (/*CONSTCOND*/0)
#define _CITRUS_HASH_SEARCH(head, elm, field, matchfunc, key, hashval) \
do { \
for ((elm)=(head)->chh_table[hashval]; \
(elm); \
(elm)=(elm)->field.che_next) \
if (matchfunc((elm), key)==0) \
break; \
} while (/*CONSTCOND*/0)
__BEGIN_DECLS
int _citrus_string_hash_func(const char *, int);
__END_DECLS
#endif

View File

@ -0,0 +1,210 @@
/* $NetBSD: citrus_iconv.c,v 1.1 2003/06/25 09:51:34 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_iconv.c,v 1.1 2003/06/25 09:51:34 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <unistd.h>
#include <paths.h>
#include <dirent.h>
#include <sys/types.h>
#include "citrus_namespace.h"
#include "citrus_bcs.h"
#include "citrus_region.h"
#include "citrus_memstream.h"
#include "citrus_mmap.h"
#include "citrus_module.h"
#include "citrus_lookup.h"
#include "citrus_iconv.h"
#define _CITRUS_ICONV_DIR "iconv.dir"
#define _CITRUS_ICONV_ALIAS "iconv.alias"
/*
* lookup_iconv_entry:
* lookup iconv.dir entry in the specified directory.
*
* line format of iconv.dir file:
* key module arg
* key : lookup key.
* module : iconv module name.
* arg : argument for the module (generally, description file name)
*
*/
static __inline int
lookup_iconv_entry(const char *curdir, const char *key,
char *linebuf, size_t linebufsize,
const char **module, const char **variable)
{
const char *cp, *cq;
char *p, path[PATH_MAX];
/* iconv.dir path */
snprintf(path, PATH_MAX, "%s/" _CITRUS_ICONV_DIR, curdir);
/* lookup db */
cp = p = _lookup_simple(path, key, linebuf, linebufsize);
if (p == NULL)
return ENOENT;
/* get module name */
*module = p;
cq = _bcs_skip_nonws(cp);
p[cq-cp] = '\0';
p += cq-cp+1;
cq++;
/* get variable */
cp = _bcs_skip_ws(cq);
*variable = p += cp - cq;
cq = _bcs_skip_nonws(cp);
p[cq-cp] = '\0';
return 0;
}
/*
* _citrus_iconv_open:
* open a converter for the specified in/out codes.
*/
int
_citrus_iconv_open(struct _citrus_iconv * __restrict * __restrict rci,
const char * __restrict basedir,
const char * __restrict src, const char * __restrict dst)
{
int ret;
struct _citrus_iconv *ci;
_citrus_iconv_getops_t getops;
char realsrc[PATH_MAX], realdst[PATH_MAX], key[PATH_MAX];
char linebuf[PATH_MAX], path[PATH_MAX];
const char *module, *variable;
/* resolve codeset name aliases */
snprintf(path, sizeof(path), "%s/%s", basedir, _CITRUS_ICONV_ALIAS);
strlcpy(realsrc, _lookup_alias(path, src, linebuf, PATH_MAX), PATH_MAX);
strlcpy(realdst, _lookup_alias(path, dst, linebuf, PATH_MAX), PATH_MAX);
/* sanity check */
if (strchr(realsrc, '/') != NULL || strchr(realdst, '/'))
return EINVAL;
/* search converter entry */
snprintf(key, sizeof(key), "%s/%s", realsrc, realdst);
ret = lookup_iconv_entry(basedir, key, linebuf, PATH_MAX,
&module, &variable);
if (ret) {
if (ret == ENOENT)
/* fallback */
ret = lookup_iconv_entry(basedir, "*",
linebuf, PATH_MAX,
&module, &variable);
if (ret)
return ret;
}
/* initialize iconv handle */
ci = malloc(sizeof(*ci));
if (!ci) {
ret = errno;
goto err;
}
ci->ci_module = NULL;
ci->ci_ops = NULL;
ci->ci_closure = NULL;
/* load module */
ret = _citrus_load_module(&ci->ci_module, module);
if (ret)
goto err;
/* get operators */
getops = (_citrus_iconv_getops_t)
_citrus_find_getops(ci->ci_module, module, "iconv");
if (!getops) {
ret = EOPNOTSUPP;
goto err;
}
ci->ci_ops = malloc(sizeof(*ci->ci_ops));
if (!ci->ci_ops) {
ret = errno;
goto err;
}
ret = (*getops)(ci->ci_ops, sizeof(*ci->ci_ops),
_CITRUS_ICONV_ABI_VERSION);
if (ret)
goto err;
if (!ci->ci_ops->io_init ||
!ci->ci_ops->io_uninit ||
!ci->ci_ops->io_convert)
goto err;
/* initialize the converter */
ret = (*ci->ci_ops->io_init)(ci, basedir, realsrc, realdst,
(const void *)variable,
strlen(variable)+1);
if (ret)
goto err;
*rci = ci;
return 0;
err:
_citrus_iconv_close(ci);
return ret;
}
/*
* _citrus_iconv_close:
* close the specified converter.
*/
void
_citrus_iconv_close(struct _citrus_iconv *ci)
{
if (ci) {
if (ci->ci_module) {
if (ci->ci_ops) {
if (ci->ci_closure)
(*ci->ci_ops->io_uninit)(ci);
free(ci->ci_ops);
}
_citrus_unload_module(ci->ci_module);
}
free(ci);
}
}

View File

@ -0,0 +1,69 @@
/* $NetBSD: citrus_iconv.h,v 1.1 2003/06/25 09:51:34 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_ICONV_H_
#define _CITRUS_ICONV_H_
struct _citrus_iconv;
struct _citrus_iconv_ops;
__BEGIN_DECLS
int _citrus_iconv_open(struct _citrus_iconv * __restrict * __restrict,
const char * __restrict,
const char * __restrict, const char * __restrict);
void _citrus_iconv_close(struct _citrus_iconv *);
__END_DECLS
#include "citrus_iconv_local.h"
#define _CITRUS_ICONV_F_HIDE_INVALID 0x0001
/*
* _citrus_iconv_convert:
* convert a string.
*/
static __inline int
_citrus_iconv_convert(struct _citrus_iconv * __restrict ci,
const char * __restrict * __restrict in,
size_t * __restrict inbytes,
char * __restrict * __restrict out,
size_t * __restrict outbytes, u_int32_t flags,
size_t * __restrict nresults)
{
int ret;
_DIAGASSERT(ci & ci->ci_ops && dst);
ret = (*ci->ci_ops->io_convert)(ci, in, inbytes, out, outbytes, flags,
nresults);
return ret;
}
#endif

View File

@ -0,0 +1,89 @@
/* $NetBSD: citrus_iconv_local.h,v 1.1 2003/06/25 09:51:34 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_ICONV_LOCAL_H_
#define _CITRUS_ICONV_LOCAL_H_
#define _CITRUS_ICONV_GETOPS_FUNC_BASE(_n_) \
int _n_(struct _citrus_iconv_ops *, size_t, u_int32_t)
#define _CITRUS_ICONV_GETOPS_FUNC(_n_) \
_CITRUS_ICONV_GETOPS_FUNC_BASE(_citrus_##_n_##_iconv_getops)
#define _CITRUS_ICONV_DECLS(_m_) \
static int _citrus_##_m_##_iconv_init \
(struct _citrus_iconv * __restrict, \
const char * __restrict, \
const char * __restrict, const char * __restrict, \
const void * __restrict, size_t); \
static void _citrus_##_m_##_iconv_uninit(struct _citrus_iconv *); \
static int _citrus_##_m_##_iconv_convert \
(struct _citrus_iconv * __restrict, \
const char * __restrict * __restrict, size_t * __restrict, \
char * __restrict * __restrict, size_t * __restrict outbytes, \
u_int32_t, size_t * __restrict)
#define _CITRUS_ICONV_DEF_OPS(_m_) \
struct _citrus_iconv_ops _citrus_##_m_##_iconv_ops = { \
/* io_abi_version */ _CITRUS_ICONV_ABI_VERSION, \
/* io_init */ &_citrus_##_m_##_iconv_init, \
/* io_uninit */ &_citrus_##_m_##_iconv_uninit, \
/* io_convert */ &_citrus_##_m_##_iconv_convert \
}
__BEGIN_DECLS
typedef _CITRUS_ICONV_GETOPS_FUNC_BASE((*_citrus_iconv_getops_t));
typedef int (*_citrus_iconv_init_t)(struct _citrus_iconv * __restrict,
const char * __restrict,
const char * __restrict,
const char * __restrict,
const void * __restrict, size_t);
typedef void (*_citrus_iconv_uninit_t)(struct _citrus_iconv *);
typedef int (*_citrus_iconv_convert_t)(struct _citrus_iconv * __restrict,
const char *__restrict* __restrict,
size_t * __restrict,
char * __restrict * __restrict,
size_t * __restrict, u_int32_t,
size_t * __restrict);
__END_DECLS
struct _citrus_iconv_ops {
u_int32_t io_abi_version;
_citrus_iconv_init_t io_init;
_citrus_iconv_uninit_t io_uninit;
_citrus_iconv_convert_t io_convert;
};
#define _CITRUS_ICONV_ABI_VERSION 1
struct _citrus_iconv {
struct _citrus_iconv_ops *ci_ops;
void *ci_closure;
_citrus_module_t ci_module;
};
#endif

View File

@ -0,0 +1,351 @@
/* $NetBSD: citrus_lookup.c,v 1.1 2003/06/25 09:51:34 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_lookup.c,v 1.1 2003/06/25 09:51:34 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include <paths.h>
#include <dirent.h>
#include <sys/types.h>
#include "citrus_namespace.h"
#include "citrus_bcs.h"
#include "citrus_region.h"
#include "citrus_memstream.h"
#include "citrus_mmap.h"
#include "citrus_db.h"
#include "citrus_db_hash.h"
#include "citrus_lookup.h"
#include "citrus_lookup_file.h"
struct _citrus_lookup {
union {
struct {
struct _citrus_db *db;
struct _citrus_region file;
int num, idx;
struct _db_locator locator;
} db;
struct {
struct _region r;
struct _memstream ms;
} plain;
} u;
#define cl_db u.db.db
#define cl_dbidx u.db.idx
#define cl_dbfile u.db.file
#define cl_dbnum u.db.num
#define cl_dblocator u.db.locator
#define cl_plainr u.plain.r
#define cl_plainms u.plain.ms
int cl_rewind;
char *cl_key;
size_t cl_keylen;
int (*cl_next)(struct _citrus_lookup *, struct _region *,
struct _region *);
int (*cl_lookup)(struct _citrus_lookup *, const char *,
struct _region *);
int (*cl_num_entries)(struct _citrus_lookup *);
void (*cl_close)(struct _citrus_lookup *);
};
static int
seq_get_num_entries_db(struct _citrus_lookup *cl)
{
return cl->cl_dbnum;
}
static int
seq_next_db(struct _citrus_lookup *cl,
struct _region *key, struct _region *data)
{
if (cl->cl_key) {
if (key)
_region_init(key, cl->cl_key, cl->cl_keylen);
return _db_lookup_by_s(cl->cl_db, cl->cl_key, data,
&cl->cl_dblocator);
}
if (cl->cl_rewind) {
cl->cl_dbidx = 0;
}
cl->cl_rewind = 0;
if (cl->cl_dbidx >= cl->cl_dbnum)
return ENOENT;
return _db_get_entry(cl->cl_db, cl->cl_dbidx++, key, data);
}
static int
seq_lookup_db(struct _citrus_lookup *cl, const char *key,
struct _region *data)
{
cl->cl_rewind = 0;
free(cl->cl_key);
cl->cl_key = strdup(key);
cl->cl_keylen = strlen(key);
_db_locator_init(&cl->cl_dblocator);
return _db_lookup_by_s(cl->cl_db, key, data, &cl->cl_dblocator);
}
static void
seq_close_db(struct _citrus_lookup *cl)
{
_db_close(cl->cl_db);
_unmap_file(&cl->cl_dbfile);
}
static int
seq_open_db(struct _citrus_lookup *cl, const char *name)
{
int ret;
struct _region r;
char path[PATH_MAX];
snprintf(path, sizeof(path), "%s.db", name);
ret = _map_file(&r, path);
if (ret)
return ret;
ret = _db_open(&cl->cl_db, &r, _CITRUS_LOOKUP_MAGIC,
_db_hash_std, NULL);
if (ret) {
_unmap_file(&r);
return ret;
}
cl->cl_dbfile = r;
cl->cl_dbnum = _db_get_num_entries(cl->cl_db);
cl->cl_dbidx = 0;
cl->cl_rewind = 1;
cl->cl_lookup = &seq_lookup_db;
cl->cl_next = &seq_next_db;
cl->cl_num_entries = &seq_get_num_entries_db;
cl->cl_close = &seq_close_db;
return 0;
}
#define T_COMM '#'
static int
seq_next_plain(struct _citrus_lookup *cl, struct _region *key,
struct _region *data)
{
const char *p, *q;
size_t len;
if (cl->cl_rewind)
_memstream_bind(&cl->cl_plainms, &cl->cl_plainr);
cl->cl_rewind = 0;
retry:
p = _memstream_getln(&cl->cl_plainms, &len);
if (p == NULL)
return ENOENT;
/* ignore comment */
q = memchr(p, T_COMM, len);
if (q) {
len = q-p;
}
/* ignore trailing spaces */
_bcs_trunc_rws_len(p, &len);
p = _bcs_skip_ws_len(p, &len);
q = _bcs_skip_nonws_len(p, &len);
if (p==q)
goto retry;
if (cl->cl_key && (q-p != cl->cl_keylen ||
memcmp(p, cl->cl_key, (size_t)(q-p)) != 0))
goto retry;
/* found a entry */
if (key)
/* LINTED: discard const */
_region_init(key, (char *)p, q-p);
p = _bcs_skip_ws_len(q, &len);
if (data)
/* LINTED: discard const */
_region_init(data, len ? (char *)p : NULL, len);
return 0;
}
static int
seq_get_num_entries_plain(struct _citrus_lookup *cl)
{
int num;
num = 0;
while (seq_next_plain(cl, NULL, NULL) == 0)
num++;
return num;
}
static int
seq_lookup_plain(struct _citrus_lookup *cl, const char *key,
struct _region *data)
{
size_t len;
const char *p;
cl->cl_rewind = 0;
_memstream_bind(&cl->cl_plainms, &cl->cl_plainr);
p = _memstream_matchline(&cl->cl_plainms, key, &len, 0);
if (p == NULL)
return ENOENT;
free(cl->cl_key);
cl->cl_key = strdup(key);
cl->cl_keylen = strlen(key);
if (data)
/* LINTED: discard const */
_region_init(data, (char *)p, len);
return 0;
}
static void
seq_close_plain(struct _citrus_lookup *cl)
{
_unmap_file(&cl->cl_plainr);
}
static int
seq_open_plain(struct _citrus_lookup *cl, const char *name)
{
int ret;
/* open read stream */
ret = _map_file(&cl->cl_plainr, name);
if (ret)
return ret;
cl->cl_rewind = 1;
cl->cl_next = &seq_next_plain;
cl->cl_lookup = &seq_lookup_plain;
cl->cl_num_entries = &seq_get_num_entries_plain;
cl->cl_close = &seq_close_plain;
return 0;
}
int
_citrus_lookup_seq_open(struct _citrus_lookup **rcl, const char *name)
{
int ret;
struct _citrus_lookup *cl;
cl = malloc(sizeof(*cl));
if (cl == NULL)
return errno;
cl->cl_key = NULL;
cl->cl_keylen = 0;
ret = seq_open_db(cl, name);
if (ret == ENOENT)
ret = seq_open_plain(cl, name);
if (!ret)
*rcl = cl;
else
free(cl);
return ret;
}
void
_citrus_lookup_seq_rewind(struct _citrus_lookup *cl)
{
cl->cl_rewind = 1;
free(cl->cl_key);
cl->cl_key = NULL;
cl->cl_keylen = 0;
}
int
_citrus_lookup_seq_next(struct _citrus_lookup *cl,
struct _region *key, struct _region *data)
{
return (*cl->cl_next)(cl, key, data);
}
int
_citrus_lookup_seq_lookup(struct _citrus_lookup *cl, const char *key,
struct _region *data)
{
return (*cl->cl_lookup)(cl, key, data);
}
int
_citrus_lookup_get_number_of_entries(struct _citrus_lookup *cl)
{
return (*cl->cl_num_entries)(cl);
}
void
_citrus_lookup_seq_close(struct _citrus_lookup *cl)
{
free(cl->cl_key);
(*cl->cl_close)(cl);
}
char *
_citrus_lookup_simple(const char *name, const char *key,
char *linebuf, size_t linebufsize)
{
int ret;
struct _citrus_lookup *cl;
struct _region data;
ret = _citrus_lookup_seq_open(&cl, name);
if (ret)
return NULL;
ret = _citrus_lookup_seq_lookup(cl, key, &data);
if (ret) {
_citrus_lookup_seq_close(cl);
return NULL;
}
snprintf(linebuf, linebufsize, "%.*s",
(int)_region_size(&data), (const char *)_region_head(&data));
_citrus_lookup_seq_close(cl);
return linebuf;
}

View File

@ -0,0 +1,57 @@
/* $NetBSD: citrus_lookup.h,v 1.1 2003/06/25 09:51:35 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_LOOKUP_H_
#define _CITRUS_LOOKUP_H_
struct _citrus_lookup;
__BEGIN_DECLS
char *_citrus_lookup_simple(const char *, const char *, char *, size_t);
int _citrus_lookup_seq_open(struct _citrus_lookup **, const char *);
void _citrus_lookup_seq_rewind(struct _citrus_lookup *);
int _citrus_lookup_seq_next(struct _citrus_lookup *,
struct _region *, struct _region *);
int _citrus_lookup_seq_lookup(struct _citrus_lookup *, const char *,
struct _region *);
int _citrus_lookup_get_number_of_entries(struct _citrus_lookup *);
void _citrus_lookup_seq_close(struct _citrus_lookup *);
__END_DECLS
static __inline const char *
_citrus_lookup_alias(const char *path, const char *key, char *buf, size_t n)
{
const char *ret;
ret = _citrus_lookup_simple(path, key, buf, n);
if (ret == NULL)
ret = key;
return ret;
}
#endif

View File

@ -0,0 +1,122 @@
/* $NetBSD: citrus_lookup_factory.c,v 1.1 2003/06/25 09:51:35 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_lookup_factory.c,v 1.1 2003/06/25 09:51:35 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <limits.h>
#include "citrus_namespace.h"
#include "citrus_region.h"
#include "citrus_bcs.h"
#include "citrus_db_factory.h"
#include "citrus_db_hash.h"
#include "citrus_lookup_factory.h"
#include "citrus_lookup_file.h"
#define T_COMM '#'
static int
convert_line(struct _citrus_db_factory *df, const char *line, size_t len)
{
const char *p;
char key[LINE_MAX], data[LINE_MAX];
/* cut off trailing comment */
p = memchr(line, T_COMM, len);
if (p)
len = p - line;
/* key */
line = _bcs_skip_ws_len(line, &len);
if (len == 0)
return 0;
p = _bcs_skip_nonws_len(line, &len);
if (p==line)
return 0;
snprintf(key, sizeof(key), "%.*s", (int)(p-line), line);
/* data */
line = _bcs_skip_ws_len(p, &len);
_bcs_trunc_rws_len(line, &len);
snprintf(data, sizeof(data), "%.*s", (int)len, line);
return _db_factory_addstr_by_s(df, key, data);
}
static int
dump_db(struct _citrus_db_factory *df, struct _region *r)
{
size_t size;
void *ptr;
size = _db_factory_calc_size(df);
ptr = malloc(size);
if (ptr == NULL)
return errno;
_region_init(r, ptr, size);
return _db_factory_serialize(df, _CITRUS_LOOKUP_MAGIC, r);
}
int
_citrus_lookup_factory_convert(FILE *out, FILE *in)
{
struct _citrus_db_factory *df;
struct _region r;
char *line;
size_t size;
int ret;
ret = _db_factory_create(&df, &_db_hash_std, NULL);
if (ret)
return ret;
while ((line = fgetln(in, &size)) != NULL)
if ((ret = convert_line(df, line, size))) {
_db_factory_free(df);
return ret;
}
ret = dump_db(df, &r);
_db_factory_free(df);
if (ret)
return ret;
if (fwrite(_region_head(&r), _region_size(&r), 1, out) != 1)
return errno;
return 0;
}

View File

@ -0,0 +1,36 @@
/* $NetBSD: citrus_lookup_factory.h,v 1.1 2003/06/25 09:51:35 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_LOOKUP_FACTORY_H_
#define _CITRUS_LOOKUP_FACTORY_H_
__BEGIN_DECLS
int _citrus_lookup_factory_convert(FILE *, FILE *);
__END_DECLS
#endif

View File

@ -0,0 +1,34 @@
/* $NetBSD: citrus_lookup_file.h,v 1.1 2003/06/25 09:51:36 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_LOOKUP_FILE_H_
#define _CITRUS_LOOKUP_FILE_H_
#define _CITRUS_LOOKUP_MAGIC "LOOKUP\0\0"
#endif

View File

@ -0,0 +1,393 @@
/* $NetBSD: citrus_mapper.c,v 1.1 2003/06/25 09:51:36 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_mapper.c,v 1.1 2003/06/25 09:51:36 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
#include "reentrant.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "citrus_namespace.h"
#include "citrus_types.h"
#include "citrus_region.h"
#include "citrus_memstream.h"
#include "citrus_bcs.h"
#include "citrus_mmap.h"
#include "citrus_module.h"
#include "citrus_hash.h"
#include "citrus_mapper.h"
#define _CITRUS_MAPPER_DIR "mapper.dir"
#define CM_HASH_SIZE 101
#define REFCOUNT_PERSISTENT -1
#ifdef _REENTRANT
static rwlock_t lock = RWLOCK_INITIALIZER;
#endif
struct _citrus_mapper_area {
_CITRUS_HASH_HEAD(, _citrus_mapper, CM_HASH_SIZE) ma_cache;
char *ma_dir;
};
/*
* _citrus_mapper_create_area:
* create mapper area
*/
int
_citrus_mapper_create_area(
struct _citrus_mapper_area *__restrict *__restrict rma,
const char *__restrict area)
{
struct stat st;
int ret;
char path[PATH_MAX];
struct _citrus_mapper_area *ma;
rwlock_wrlock(&lock);
if (*rma != NULL) {
ret = 0;
goto quit;
}
snprintf(path, PATH_MAX, "%s/%s", area, _CITRUS_MAPPER_DIR);
ret = stat(path, &st);
if (ret)
goto quit;
ma = malloc(sizeof(*ma));
if (ma == NULL) {
ret = errno;
goto quit;
}
ma->ma_dir = strdup(area);
if (ma->ma_dir == NULL) {
ret = errno;
free(ma->ma_dir);
goto quit;
}
_CITRUS_HASH_INIT(&ma->ma_cache, CM_HASH_SIZE);
*rma = ma;
ret = 0;
quit:
rwlock_unlock(&lock);
return ret;
}
/*
* lookup_mapper_entry:
* lookup mapper.dir entry in the specified directory.
*
* line format of iconv.dir file:
* mapper module arg
* mapper : mapper name.
* module : mapper module name.
* arg : argument for the module (generally, description file name)
*/
static int
lookup_mapper_entry(const char *dir, const char *mapname,
void *linebuf, size_t linebufsize,
const char **module, const char **variable)
{
struct _region r;
struct _memstream ms;
int ret;
const char *cp, *cq;
char *p;
size_t len;
char path[PATH_MAX];
/* create mapper.dir path */
snprintf(path, PATH_MAX, "%s/%s", dir, _CITRUS_MAPPER_DIR);
/* open read stream */
ret = _map_file(&r, path);
if (ret)
return ret;
_memstream_bind(&ms, &r);
/* search the line matching to the map name */
cp = _memstream_matchline(&ms, mapname, &len, 0);
if (!cp) {
ret = ENOENT;
goto quit;
}
if (!len || len>linebufsize-1) {
ret = EINVAL;
goto quit;
}
p = linebuf;
/* get module name */
*module = p;
cq = _bcs_skip_nonws_len(cp, &len);
strlcpy(p, cp, (size_t)(cq-cp+1));
p += cq-cp+1;
/* get variable */
*variable = p;
cp = _bcs_skip_ws_len(cq, &len);
strlcpy(p, cp, len+1);
ret = 0;
quit:
_unmap_file(&r);
return ret;
}
/*
* mapper_open:
*/
static int
mapper_open(struct _citrus_mapper_area *__restrict ma,
struct _citrus_mapper * __restrict * __restrict rcm,
const char * __restrict module,
const char * __restrict variable)
{
int ret;
struct _citrus_mapper *cm;
_citrus_mapper_getops_t getops;
/* initialize mapper handle */
cm = malloc(sizeof(*cm));
if (!cm)
return errno;
cm->cm_module = NULL;
cm->cm_ops = NULL;
cm->cm_closure = NULL;
cm->cm_traits = NULL;
cm->cm_refcount = 0;
cm->cm_key = NULL;
/* load module */
ret = _citrus_load_module(&cm->cm_module, module);
if (ret)
goto err;
/* get operators */
getops = (_citrus_mapper_getops_t)
_citrus_find_getops(cm->cm_module, module, "mapper");
if (!getops) {
ret = EOPNOTSUPP;
goto err;
}
cm->cm_ops = malloc(sizeof(*cm->cm_ops));
if (!cm->cm_ops) {
ret = errno;
goto err;
}
ret = (*getops)(cm->cm_ops, sizeof(*cm->cm_ops),
_CITRUS_MAPPER_ABI_VERSION);
if (ret)
goto err;
if (!cm->cm_ops->mo_init ||
!cm->cm_ops->mo_uninit ||
!cm->cm_ops->mo_convert ||
!cm->cm_ops->mo_init_state)
goto err;
/* allocate traits structure */
cm->cm_traits = malloc(sizeof(*cm->cm_traits));
if (cm->cm_traits == NULL) {
ret = errno;
goto err;
}
/* initialize the mapper */
ret = (*cm->cm_ops->mo_init)(ma, cm, ma->ma_dir,
(const void *)variable,
strlen(variable)+1,
cm->cm_traits, sizeof(*cm->cm_traits));
if (ret)
goto err;
*rcm = cm;
return 0;
err:
_citrus_mapper_close(cm);
return ret;
}
/*
* _citrus_mapper_open_direct:
* open a mapper.
*/
int
_citrus_mapper_open_direct(struct _citrus_mapper_area *__restrict ma,
struct _citrus_mapper * __restrict * __restrict rcm,
const char * __restrict module,
const char * __restrict variable)
{
return mapper_open(ma, rcm, module, variable);
}
/*
* hash_func
*/
static __inline int
hash_func(const char *key)
{
return _string_hash_func(key, CM_HASH_SIZE);
}
/*
* match_func
*/
static __inline int
match_func(struct _citrus_mapper *cm, const char *key)
{
return strcmp(cm->cm_key, key);
}
/*
* _citrus_mapper_open:
* open a mapper with looking up "mapper.dir".
*/
int
_citrus_mapper_open(struct _citrus_mapper_area *__restrict ma,
struct _citrus_mapper * __restrict * __restrict rcm,
const char * __restrict mapname)
{
int ret;
char linebuf[PATH_MAX];
const char *module, *variable;
struct _citrus_mapper *cm;
int hashval;
rwlock_wrlock(&lock);
/* search in the cache */
hashval = hash_func(mapname);
_CITRUS_HASH_SEARCH(&ma->ma_cache, cm, cm_entry, match_func, mapname,
hashval);
if (cm) {
/* found */
cm->cm_refcount++;
*rcm = cm;
ret = 0;
goto quit;
}
/* search mapper entry */
ret = lookup_mapper_entry(ma->ma_dir, mapname, linebuf, PATH_MAX,
&module, &variable);
if (ret)
goto quit;
/* open mapper */
ret = mapper_open(ma, &cm, module, variable);
if (ret)
goto quit;
cm->cm_key = strdup(mapname);
if (cm->cm_key == NULL) {
ret = errno;
rwlock_unlock(&lock);
_mapper_close(cm);
return ret;
}
/* insert to the cache */
cm->cm_refcount = 1;
_CITRUS_HASH_INSERT(&ma->ma_cache, cm, cm_entry, hashval);
*rcm = cm;
ret = 0;
quit:
rwlock_unlock(&lock);
return ret;
}
/*
* _citrus_mapper_close:
* close the specified mapper.
*/
void
_citrus_mapper_close(struct _citrus_mapper *cm)
{
if (cm) {
rwlock_wrlock(&lock);
if (cm->cm_refcount == REFCOUNT_PERSISTENT) {
rwlock_unlock(&lock);
return;
}
if (cm->cm_refcount > 0) {
if (--cm->cm_refcount > 0) {
rwlock_unlock(&lock);
return;
} else {
_CITRUS_HASH_REMOVE(cm, cm_entry);
}
}
if (cm->cm_module) {
if (cm->cm_ops) {
if (cm->cm_closure)
(*cm->cm_ops->mo_uninit)(cm);
free(cm->cm_ops);
}
_citrus_unload_module(cm->cm_module);
}
free(cm->cm_key);
free(cm->cm_traits);
free(cm);
rwlock_unlock(&lock);
}
}
/*
* _citrus_mapper_set_persistent:
* set persistent count.
*/
void
_citrus_mapper_set_persistent(struct _citrus_mapper * __restrict cm)
{
rwlock_wrlock(&lock);
cm->cm_refcount = REFCOUNT_PERSISTENT;
rwlock_unlock(&lock);
}

View File

@ -0,0 +1,142 @@
/* $NetBSD: citrus_mapper.h,v 1.1 2003/06/25 09:51:36 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_MAPPER_H_
#define _CITRUS_MAPPER_H_
struct _citrus_mapper_area;
struct _citrus_mapper;
struct _citrus_mapper_ops;
struct _citrus_mapper_traits;
__BEGIN_DECLS
int _citrus_mapper_create_area(
struct _citrus_mapper_area *__restrict *__restrict,
const char *__restrict);
int _citrus_mapper_open(struct _citrus_mapper_area *__restrict,
struct _citrus_mapper *__restrict *__restrict,
const char *__restrict);
int _citrus_mapper_open_direct(
struct _citrus_mapper_area *__restrict,
struct _citrus_mapper *__restrict *__restrict,
const char *__restrict, const char *__restrict);
void _citrus_mapper_close(struct _citrus_mapper *);
void _citrus_mapper_set_persistent(struct _citrus_mapper * __restrict);
__END_DECLS
#include "citrus_mapper_local.h"
/* return values of _citrus_mapper_convert */
#define _CITRUS_MAPPER_CONVERT_SUCCESS (0)
#define _CITRUS_MAPPER_CONVERT_INVAL (1)
#define _CITRUS_MAPPER_CONVERT_SRC_MORE (2)
#define _CITRUS_MAPPER_CONVERT_DST_MORE (3)
#define _CITRUS_MAPPER_CONVERT_ILSEQ (4)
#define _CITRUS_MAPPER_CONVERT_FATAL (5)
/*
* _citrus_mapper_convert:
* convert an index.
* - if the converter supports M:1 converter, the function may return
* _CITRUS_MAPPER_CONVERT_SRC_MORE and the storage pointed by dst
* may be unchanged in this case, although the internal status of
* the mapper is affected.
* - if the converter supports 1:N converter, the function may return
* _CITRUS_MAPPER_CONVERT_DST_MORE. In this case, the contiguous
* call of this function ignores src and changes the storage pointed
* by dst.
* - if the converter supports M:N converter, the function may behave
* the combination of the above.
*
*/
static __inline int
_citrus_mapper_convert(struct _citrus_mapper * __restrict cm,
_citrus_index_t * __restrict dst,
_citrus_index_t src,
void * __restrict ps)
{
_DIAGASSERT(cm && cm->cm_ops && cm->cm_ops->mo_convert && dst);
return (*cm->cm_ops->mo_convert)(cm, dst, src, ps);
}
/*
* _citrus_mapper_init_state:
* initialize the state.
*/
static __inline void
_citrus_mapper_init_state(struct _citrus_mapper * __restrict cm,
void * __restrict ps)
{
_DIAGASSERT(cm && cm->cm_ops && cm->cm_ops_mo_init_state);
(*cm->cm_ops->mo_init_state)(cm, ps);
}
/*
* _citrus_mapper_get_state_size:
* get the size of state storage.
*/
static __inline size_t
_citrus_mapper_get_state_size(struct _citrus_mapper * __restrict cm)
{
_DIAGASSERT(cm && cm->cm_traits);
return cm->cm_traits->mt_state_size;
}
/*
* _citrus_mapper_get_src_max:
* get the maximum number of suspended sources.
*/
static __inline size_t
_citrus_mapper_get_src_max(struct _citrus_mapper * __restrict cm)
{
_DIAGASSERT(cm && cm->cm_traits);
return cm->cm_traits->mt_src_max;
}
/*
* _citrus_mapper_get_dst_max:
* get the maximum number of suspended destinations.
*/
static __inline size_t
_citrus_mapper_get_dst_max(struct _citrus_mapper * __restrict cm)
{
_DIAGASSERT(cm && cm->cm_traits);
return cm->cm_traits->mt_dst_max;
}
#endif

View File

@ -0,0 +1,105 @@
/* $NetBSD: citrus_mapper_local.h,v 1.1 2003/06/25 09:51:36 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_MAPPER_LOCAL_H_
#define _CITRUS_MAPPER_LOCAL_H_
#define _CITRUS_MAPPER_GETOPS_FUNC_BASE(_n_) \
int _n_(struct _citrus_mapper_ops *, size_t, u_int32_t)
#define _CITRUS_MAPPER_GETOPS_FUNC(_n_) \
_CITRUS_MAPPER_GETOPS_FUNC_BASE(_citrus_##_n_##_mapper_getops)
#define _CITRUS_MAPPER_DECLS(_m_) \
static int _citrus_##_m_##_mapper_init \
(struct _citrus_mapper_area *__restrict, \
struct _citrus_mapper * __restrict, const char * __restrict, \
const void * __restrict, size_t, \
struct _citrus_mapper_traits * __restrict, size_t); \
static void _citrus_##_m_##_mapper_uninit(struct _citrus_mapper *); \
static int _citrus_##_m_##_mapper_convert \
(struct _citrus_mapper * __restrict, \
_citrus_index_t * __restrict, _citrus_index_t, \
void * __restrict); \
static void _citrus_##_m_##_mapper_init_state \
(struct _citrus_mapper * __restrict, void * __restrict);
#define _CITRUS_MAPPER_DEF_OPS(_m_) \
struct _citrus_mapper_ops _citrus_##_m_##_mapper_ops = { \
/* mo_abi_version */ _CITRUS_MAPPER_ABI_VERSION, \
/* mo_init */ &_citrus_##_m_##_mapper_init, \
/* mo_uninit */ &_citrus_##_m_##_mapper_uninit, \
/* mo_convert */ &_citrus_##_m_##_mapper_convert, \
/* mo_init_state */ &_citrus_##_m_##_mapper_init_state \
}
typedef _CITRUS_MAPPER_GETOPS_FUNC_BASE((*_citrus_mapper_getops_t));
typedef int (*_citrus_mapper_init_t)(
struct _citrus_mapper_area *__restrict,
struct _citrus_mapper *__restrict, const char *__restrict,
const void *__restrict, size_t,
struct _citrus_mapper_traits * __restrict, size_t);
typedef void (*_citrus_mapper_uninit_t)(struct _citrus_mapper *);
typedef int (*_citrus_mapper_convert_t)(struct _citrus_mapper * __restrict,
_citrus_index_t * __restrict,
_citrus_index_t,
void * __restrict);
typedef void (*_citrus_mapper_init_state_t)(
struct _citrus_mapper * __restrict, void * __restrict);
/*
* ABI version change log
* 0x00000001
* initial version
*/
#define _CITRUS_MAPPER_ABI_VERSION 0x00000001
struct _citrus_mapper_ops {
uint32_t mo_abi_version;
/* version 0x00000001 */
_citrus_mapper_init_t mo_init;
_citrus_mapper_uninit_t mo_uninit;
_citrus_mapper_convert_t mo_convert;
_citrus_mapper_init_state_t mo_init_state;
};
struct _citrus_mapper_traits {
/* version 0x00000001 */
size_t mt_state_size;
size_t mt_src_max;
size_t mt_dst_max;
};
struct _citrus_mapper {
struct _citrus_mapper_ops *cm_ops;
void *cm_closure;
_citrus_module_t cm_module;
struct _citrus_mapper_traits *cm_traits;
_CITRUS_HASH_ENTRY(_citrus_mapper) cm_entry;
int cm_refcount;
char *cm_key;
};
#endif

View File

@ -0,0 +1,153 @@
/* $NetBSD: citrus_memstream.c,v 1.1 2003/06/25 09:51:37 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_memstream.c,v 1.1 2003/06/25 09:51:37 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "citrus_namespace.h"
#include "citrus_region.h"
#include "citrus_memstream.h"
#include "citrus_bcs.h"
const char *
_citrus_memory_stream_getln(struct _citrus_memory_stream * __restrict ms,
size_t * __restrict rlen)
{
int i;
const u_int8_t *h, *p;
size_t ret;
if (ms->ms_pos>=_region_size(&ms->ms_region))
return (NULL);
h = p = (uint8_t *)_region_offset(&ms->ms_region, ms->ms_pos);
ret = 0;
for (i=_region_size(&ms->ms_region)-ms->ms_pos; i>0; i--) {
ret++;
if (_bcs_iseol(*p))
break;
p++;
}
ms->ms_pos += ret;
*rlen = ret;
return ((const char *)h);
}
#define T_COMM '#'
const char *
_citrus_memory_stream_matchline(struct _citrus_memory_stream * __restrict ms,
const char * __restrict key,
size_t * __restrict rlen,
int iscasesensitive)
{
const char *p, *q;
size_t len, keylen;
keylen = strlen(key);
while (/*CONSTCOND*/ 1) {
p = _citrus_memory_stream_getln(ms, &len);
if (p == NULL)
return (NULL);
/* ignore comment */
q = memchr(p, T_COMM, len);
if (q) {
len = q-p;
}
/* ignore trailing white space and newline */
_bcs_trunc_rws_len(p, &len);
if (len == 0)
continue; /* ignore null line */
/* skip white spaces at the head of the line */
p = _bcs_skip_ws_len(p, &len);
q = _bcs_skip_nonws_len(p, &len);
if (q-p == keylen) {
if (iscasesensitive) {
if (memcmp(key, p, keylen) == 0)
break; /* match */
} else {
if (_bcs_strncasecmp(key, p, keylen) == 0)
break; /* match */
}
}
}
p = _bcs_skip_ws_len(q, &len);
*rlen = len;
return (p);
}
void *
_citrus_memory_stream_chr(struct _citrus_memory_stream *ms,
struct _citrus_region *r, char ch)
{
void *head, *chr;
size_t sz;
if (ms->ms_pos >= _region_size(&ms->ms_region))
return NULL;
head = _region_offset(&ms->ms_region, ms->ms_pos);
chr = memchr(head, ch, _memstream_remainder(ms));
if (chr == NULL) {
_region_init(r, head, _memstream_remainder(ms));
ms->ms_pos = _region_size(&ms->ms_region);
return NULL;
}
sz = (char *)chr - (char *)head;
_region_init(r, head, sz);
ms->ms_pos += sz+1;
return chr;
}
void
_citrus_memory_stream_skip_ws(struct _citrus_memory_stream *ms)
{
int ch;
while ((ch = _memstream_peek(ms)) != EOF) {
if (!_bcs_isspace(ch))
break;
_memstream_getc(ms);
}
}

View File

@ -0,0 +1,177 @@
/* $NetBSD: citrus_memstream.h,v 1.1 2003/06/25 09:51:37 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#ifndef _CITRUS_MEMSTREAM_H_
#define _CITRUS_MEMSTREAM_H_
struct _citrus_memory_stream {
struct _citrus_region ms_region;
size_t ms_pos;
};
__BEGIN_DECLS
const char * _citrus_memory_stream_getln(
struct _citrus_memory_stream * __restrict, size_t * __restrict);
const char * _citrus_memory_stream_matchline(
struct _citrus_memory_stream * __restrict, const char * __restrict,
size_t * __restrict, int);
void * _citrus_memory_stream_chr(struct _citrus_memory_stream *,
struct _citrus_region *, char);
void _citrus_memory_stream_skip_ws(struct _citrus_memory_stream *);
__END_DECLS
static __inline int
_citrus_memory_stream_iseof(struct _citrus_memory_stream *ms)
{
return ms->ms_pos >= _citrus_region_size(&ms->ms_region);
}
static __inline void
_citrus_memory_stream_bind(struct _citrus_memory_stream * __restrict ms,
const struct _citrus_region * __restrict r)
{
ms->ms_region = *r;
ms->ms_pos = 0;
}
static __inline void
_citrus_memory_stream_rewind(struct _citrus_memory_stream *ms)
{
ms->ms_pos = 0;
}
static __inline size_t
_citrus_memory_stream_remainder(struct _citrus_memory_stream *ms)
{
size_t sz;
sz = _citrus_region_size(&ms->ms_region);
if (ms->ms_pos>sz)
return 0;
return sz-ms->ms_pos;
}
static __inline int
_citrus_memory_stream_seek(struct _citrus_memory_stream *ms, size_t pos, int w)
{
int sz;
sz = _citrus_region_size(&ms->ms_region);
switch (w) {
case SEEK_SET:
if (pos>=sz)
return -1;
ms->ms_pos = pos;
break;
case SEEK_CUR:
pos += ms->ms_pos;
if (pos>=sz)
return -1;
break;
case SEEK_END:
if (sz<pos)
return -1;
ms->ms_pos = sz - pos;
break;
}
return 0;
}
static __inline int
_citrus_memory_stream_getc(struct _citrus_memory_stream *ms)
{
if (_citrus_memory_stream_iseof(ms))
return (EOF);
return _citrus_region_peek8(&ms->ms_region, ms->ms_pos++);
}
static __inline int
_citrus_memory_stream_peek(struct _citrus_memory_stream *ms)
{
if (_citrus_memory_stream_iseof(ms))
return (EOF);
return _citrus_region_peek8(&ms->ms_region, ms->ms_pos);
}
static __inline void *
_citrus_memory_stream_getregion(struct _citrus_memory_stream *ms,
struct _citrus_region *r, size_t sz)
{
void *ret;
if (ms->ms_pos + sz > _citrus_region_size(&ms->ms_region))
return NULL;
ret = _citrus_region_offset(&ms->ms_region, ms->ms_pos);
ms->ms_pos += sz;
if (r)
_citrus_region_init(r, ret, sz);
return ret;
}
static __inline int
_citrus_memory_stream_get8(struct _citrus_memory_stream *ms, uint8_t *rval)
{
if (ms->ms_pos + 1 > _citrus_region_size(&ms->ms_region))
return -1;
*rval = _citrus_region_peek8(&ms->ms_region, ms->ms_pos);
ms->ms_pos += 2;
return 0;
}
static __inline int
_citrus_memory_stream_get16(struct _citrus_memory_stream *ms, uint16_t *rval)
{
if (ms->ms_pos + 2 > _citrus_region_size(&ms->ms_region))
return -1;
*rval = _citrus_region_peek16(&ms->ms_region, ms->ms_pos);
ms->ms_pos += 2;
return 0;
}
static __inline int
_citrus_memory_stream_get32(struct _citrus_memory_stream *ms, uint32_t *rval)
{
if (ms->ms_pos + 4 > _citrus_region_size(&ms->ms_region))
return -1;
*rval = _citrus_region_peek32(&ms->ms_region, ms->ms_pos);
ms->ms_pos += 4;
return 0;
}
#endif

View File

@ -0,0 +1,95 @@
/* $NetBSD: citrus_mmap.c,v 1.1 2003/06/25 09:51:37 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_mmap.c,v 1.1 2003/06/25 09:51:37 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/mman.h>
#include "citrus_namespace.h"
#include "citrus_region.h"
#include "citrus_mmap.h"
int
_citrus_map_file(struct _citrus_region * __restrict r,
const char * __restrict path)
{
int fd, ret;
struct stat st;
void *head;
_DIAGASSERT(r != NULL);
_region_init(r, NULL, 0);
fd = open(path, O_RDONLY);
if (fd<0)
return (errno);
if (fstat(fd, &st)) {
ret = errno;
close(fd);
return ret;
}
if ((st.st_mode & S_IFMT) != S_IFREG) {
close(fd);
return EOPNOTSUPP;
}
head = mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_FILE|MAP_PRIVATE,
fd, (off_t)0);
if (!head) {
ret = errno;
close(fd);
return ret;
}
_region_init(r, head, (size_t)st.st_size);
close(fd);
return 0;
}
void
_citrus_unmap_file(struct _citrus_region *r)
{
_DIAGASSERT(r != NULL);
if (_region_head(r) != NULL) {
munmap(_region_head(r), _region_size(r));
_region_init(r, NULL, 0);
}
}

View File

@ -0,0 +1,39 @@
/* $NetBSD: citrus_mmap.h,v 1.1 2003/06/25 09:51:38 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#ifndef _CITRUS_MMAP_H_
#define _CITRUS_MMAP_H_
__BEGIN_DECLS
int _citrus_map_file(struct _citrus_region * __restrict,
const char * __restrict);
void _citrus_unmap_file(struct _citrus_region *);
__END_DECLS
#endif

View File

@ -0,0 +1,220 @@
/* $NetBSD: citrus_namespace.h,v 1.1 2003/06/25 09:51:38 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_NAMESPACE_H_
#define _CITRUS_NAMESPACE_H_
/* citrus_alias */
#ifndef _CITRUS_ALIAS_NO_NAMESPACE
#define _alias_lookup _citrus_alias_lookup
#endif /* _CITRUS_ALIAS_NO_NAMESPACE */
/* citrus_bcs */
#ifndef _CITRUS_BCS_NO_NAMESPACE
#define _bcs_isalnum _citrus_bcs_isalnum
#define _bcs_isalpha _citrus_bcs_isalpha
#define _bcs_isblank _citrus_bcs_isblank
#define _bcs_isdigit _citrus_bcs_isdigit
#define _bcs_islower _citrus_bcs_islower
#define _bcs_iseol _citrus_bcs_iseol
#define _bcs_isspace _citrus_bcs_isspace
#define _bcs_isupper _citrus_bcs_isupper
#define _bcs_isxdigit _citrus_bcs_isxdigit
#define _bcs_skip_nonws _citrus_bcs_skip_nonws
#define _bcs_skip_nonws_len _citrus_bcs_skip_nonws_len
#define _bcs_skip_ws _citrus_bcs_skip_ws
#define _bcs_skip_ws_len _citrus_bcs_skip_ws_len
#define _bcs_strcasecmp _citrus_bcs_strcasecmp
#define _bcs_strncasecmp _citrus_bcs_strncasecmp
#define _bcs_tolower _citrus_bcs_tolower
#define _bcs_toupper _citrus_bcs_toupper
#define _bcs_trunc_rws_len _citrus_bcs_trunc_rws_len
#define _bcs_convert_to_lower _citrus_bcs_convert_to_lower
#define _bcs_convert_to_upper _citrus_bcs_convert_to_upper
#endif /* _CITRUS_BCS_NO_NAMESPACE */
/* citrus_csmapper */
#ifndef _CITRUS_CSMAPPER_NO_NAMESPACE
#define _csmapper _citrus_csmapper
#define _csmapper_open _citrus_csmapper_open
#define _csmapper_close _citrus_csmapper_close
#define _csmapper_convert _citrus_csmapper_convert
#define _csmapper_init_state _citrus_csmapper_init_state
#define _csmapper_get_state_size _citrus_csmapper_get_state_size
#define _csmapper_get_src_max _citrus_csmapper_get_src_max
#define _csmapper_get_dst_max _citrus_csmapper_get_dst_max
#define _CSMAPPER_F_PREVENT_PIVOT _CITRUS_CSMAPPER_F_PREVENT_PIVOT
#endif /* _CITRUS_CSMAPPER_NO_NAMESPACE */
/* citrus_db */
#ifndef _CITRUS_DB_NO_NAMESPACE
#define _db_open _citrus_db_open
#define _db_close _citrus_db_close
#define _db_lookup _citrus_db_lookup
#define _db_lookup_by_s _citrus_db_lookup_by_string
#define _db_lookup8_by_s _citrus_db_lookup8_by_string
#define _db_lookup16_by_s _citrus_db_lookup16_by_string
#define _db_lookup32_by_s _citrus_db_lookup32_by_string
#define _db_lookupstr_by_s _citrus_db_lookup_string_by_string
#define _db_hash_std _citrus_db_hash_std
#define _db_get_num_entries _citrus_db_get_number_of_entries
#define _db_get_entry _citrus_db_get_entry
#define _db_locator _citrus_db_locator
#define _db_locator_init _citrus_db_locator_init
#endif /* _CITRUS_DB_NO_NAMESPACE */
/* citrus_db_factory */
#ifndef _CITRUS_DB_FACTORY_NO_NAMESPACE
#define _db_factory _citrus_db_factory
#define _db_factory_create _citrus_db_factory_create
#define _db_factory_free _citrus_db_factory_free
#define _db_factory_add _citrus_db_factory_add
#define _db_factory_add_by_s _citrus_db_factory_add_by_string
#define _db_factory_add8_by_s _citrus_db_factory_add8_by_string
#define _db_factory_add16_by_s _citrus_db_factory_add16_by_string
#define _db_factory_add32_by_s _citrus_db_factory_add32_by_string
#define _db_factory_addstr_by_s _citrus_db_factory_add_string_by_string
#define _db_factory_calc_size _citrus_db_factory_calc_size
#define _db_factory_serialize _citrus_db_factory_serialize
#endif /* _CITRUS_DB_FACTORY_NO_NAMESPACE */
/* citrus_lookup */
#ifndef _CITRUS_DB_NO_NAMESPACE
#define _lookup _citrus_lookup
#define _lookup_simple _citrus_lookup_simple
#define _lookup_alias _citrus_lookup_alias
#define _lookup_seq_open _citrus_lookup_seq_open
#define _lookup_seq_rewind _citrus_lookup_seq_rewind
#define _lookup_seq_next _citrus_lookup_seq_next
#define _lookup_seq_lookup _citrus_lookup_seq_lookup
#define _lookup_get_num_entries _citrus_lookup_get_number_of_entries
#define _lookup_seq_close _citrus_lookup_seq_close
#define _lookup_factory_convert _citrus_lookup_factory_convert
#endif /* _CITRUS_DB_NO_NAMESPACE */
/* citrus_esdb */
#ifndef _CITRUS_ESDB_NO_NAMESPACE
#define _esdb _citrus_esdb
#define _esdb_charset _citrus_esdb_charset
#define _esdb_open _citrus_esdb_open
#define _esdb_close _citrus_esdb_close
#define _esdb_get_list _citrus_esdb_get_list
#define _esdb_free_list _citrus_esdb_free_list
#endif /* _CITRUS_ESDB_NO_NAMESPACE */
/* citrus_hash */
#ifndef _CITRUS_HASH_NO_NAMESPACE
#define _citrus_string_hash_func _string_hash_func
#endif /* _CITRUS_HASH_NO_NAMESPACE */
/* citrus_mapper */
#ifndef _CITRUS_MAPPER_NO_NAMESPACE
#define _mapper _citrus_mapper
#define _mapper_ops _citrus_mapper_ops
#define _mapper_traits _citrus_mapper_traits
#define _mapper_open _citrus_mapper_open
#define _mapper_open_direct _citrus_mapper_open_direct
#define _mapper_close _citrus_mapper_close
#define _MAPPER_CONVERT_SUCCESS _CITRUS_MAPPER_CONVERT_SUCCESS
#define _MAPPER_CONVERT_INVAL _CITRUS_MAPPER_CONVERT_INVAL
#define _MAPPER_CONVERT_SRC_MORE _CITRUS_MAPPER_CONVERT_SRC_MORE
#define _MAPPER_CONVERT_DST_MORE _CITRUS_MAPPER_CONVERT_DST_MORE
#define _MAPPER_CONVERT_ILSEQ _CITRUS_MAPPER_CONVERT_ILSEQ
#define _MAPPER_CONVERT_FATAL _CITRUS_MAPPER_CONVERT_FATAL
#define _mapper_convert _citrus_mapper_convert
#define _mapper_init_state _citrus_mapper_init_state
#define _mapper_get_state_size _citrus_mapper_get_state_size
#define _mapper_get_src_max _citrus_mapper_get_src_max
#define _mapper_get_dst_max _citrus_mapper_get_dst_max
#define _mapper_set_persistent _citrus_mapper_set_persistent
#endif /* _CITRUS_MAPPER_NO_NAMESPACE */
/* citrus_memstream */
#ifndef _CITRUS_MEMSTREAM_NO_NAMESPACE
#define _memstream _citrus_memory_stream
#define _memstream_getln _citrus_memory_stream_getln
#define _memstream_matchline _citrus_memory_stream_matchline
#define _memstream_chr _citrus_memory_stream_chr
#define _memstream_skip_ws _citrus_memory_stream_skip_ws
#define _memstream_iseof _citrus_memory_stream_iseof
#define _memstream_bind _citrus_memory_stream_bind
#define _memstream_seek _citrus_memory_stream_seek
#define _memstream_rewind _citrus_memory_stream_rewind
#define _memstream_remainder _citrus_memory_stream_remainder
#define _memstream_getc _citrus_memory_stream_getc
#define _memstream_peek _citrus_memory_stream_peek
#define _memstream_getregion _citrus_memory_stream_getregion
#endif /* _CITRUS_MEMSTREAM_NO_NAMESPACE */
/* citrus_mmap */
#ifndef _CITRUS_MMAP_NO_NAMESPACE
#define _map_file _citrus_map_file
#define _unmap_file _citrus_unmap_file
#endif /* _CITRUS_MMAP_NO_NAMESPACE */
#ifndef _CITRUS_PIVOT_NO_NAMESPACE
#define _pivot_factory_convert _citrus_pivot_factory_convert
#endif /* _CITRUS_PIVOT_NO_NAMESPACE */
/* citrus_region.h */
#ifndef _CITRUS_REGION_NO_NAMESPACE
#define _region _citrus_region
#define _region_init _citrus_region_init
#define _region_head _citrus_region_head
#define _region_size _citrus_region_size
#define _region_check _citrus_region_check
#define _region_offset _citrus_region_offset
#define _region_peek8 _citrus_region_peek8
#define _region_peek16 _citrus_region_peek16
#define _region_peek32 _citrus_region_peek32
#endif /* _CITRUS_REGION_NO_NAMESPACE */
/* citrus_stdenc.h */
#ifndef _CITRUS_STDENC_NO_NAMESPACE
#define _stdenc _citrus_stdenc
#define _stdenc_ops _citrus_stdenc_ops
#define _stdenc_traits _citrus_stdenc_traits
#define _stdenc_open _citrus_stdenc_open
#define _stdenc_close _citrus_stdenc_close
#define _stdenc_init_state _citrus_stdenc_init_state
#define _stdenc_mbtocs _citrus_stdenc_mbtocs
#define _stdenc_cstomb _citrus_stdenc_cstomb
#define _stdenc_mbtowc _citrus_stdenc_mbtowc
#define _stdenc_wctomb _citrus_stdenc_wctomb
#define _stdenc_get_state_size _citrus_stdenc_get_state_size
#define _stdenc_get_mb_cur_max _citrus_stdenc_get_mb_cur_max
#endif /* _CITRUS_STDENC_NO_NAMESPACE */
/* citrus_types.h */
#ifndef _CITRUS_TYPES_NO_NAMESPACE
#define _index_t _citrus_index_t
#define _csid_t _citrus_csid_t
#define _wc_t _citrus_wc_t
#endif /* _CITRUS_TYPES_NO_NAMESPACE */
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: citrus_none.c,v 1.8 2003/03/05 20:18:16 tshiozak Exp $ */
/* $NetBSD: citrus_none.c,v 1.9 2003/06/25 09:51:38 tshiozak Exp $ */
/*-
* Copyright (c)2002 Citrus Project,
@ -28,7 +28,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_none.c,v 1.8 2003/03/05 20:18:16 tshiozak Exp $");
__RCSID("$NetBSD: citrus_none.c,v 1.9 2003/06/25 09:51:38 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include <assert.h>
@ -40,9 +40,13 @@ __RCSID("$NetBSD: citrus_none.c,v 1.8 2003/03/05 20:18:16 tshiozak Exp $");
#include <locale.h>
#include <wchar.h>
#include <sys/types.h>
#include "citrus_namespace.h"
#include "citrus_types.h"
#include "citrus_module.h"
#include "citrus_ctype.h"
#include "citrus_none.h"
#include "citrus_stdenc.h"
/* ---------------------------------------------------------------------- */
@ -329,3 +333,135 @@ _citrus_NONE_ctype_wctob(_citrus_ctype_rec_t * __restrict cc,
*cresult = (int)wc;
return (0);
}
/* ---------------------------------------------------------------------- */
_CITRUS_STDENC_DECLS(NONE);
_CITRUS_STDENC_DEF_OPS(NONE);
struct _citrus_stdenc_traits _citrus_NONE_stdenc_traits = {
0, /* et_state_size */
1, /* mb_cur_max */
};
static int
/*ARGSUSED*/
_citrus_NONE_stdenc_init(struct _citrus_stdenc * __restrict ce,
const void *var, size_t lenvar,
struct _citrus_stdenc_traits * __restrict et)
{
et->et_state_size = 0;
et->et_mb_cur_max = 1;
ce->ce_closure = NULL;
return (0);
}
static void
/*ARGSUSED*/
_citrus_NONE_stdenc_uninit(struct _citrus_stdenc *ce)
{
}
static int
/*ARGSUSED*/
_citrus_NONE_stdenc_init_state(struct _citrus_stdenc * __restrict ce,
void * __restrict ps)
{
return (0);
}
static int
/*ARGSUSED*/
_citrus_NONE_stdenc_mbtocs(struct _citrus_stdenc * __restrict ce,
_csid_t *csid, _index_t *idx,
const char **s, size_t n,
void *ps, size_t *nresult)
{
_DIAGASSERT(csid != NULL && idx != NULL);
if (n<1) {
*nresult = (size_t)-2;
return (0);
}
*csid = 0;
*idx = (_index_t)(unsigned char)*(*s)++;
*nresult = *idx == 0 ? 0 : 1;
return (0);
}
static int
/*ARGSUSED*/
_citrus_NONE_stdenc_cstomb(struct _citrus_stdenc * __restrict ce,
char *s, size_t n,
_csid_t csid, _index_t idx,
void *ps, size_t *nresult)
{
if (csid == _CITRUS_CSID_INVALID) {
*nresult = 0;
return (0);
}
if (n<1) {
*nresult = (size_t)-2;
return (0);
}
if (csid != 0 || (idx&0xFF) != idx)
return (EILSEQ);
*s = (char)idx;
*nresult = 1;
return (0);
}
static int
/*ARGSUSED*/
_citrus_NONE_stdenc_mbtowc(struct _citrus_stdenc * __restrict ce,
_wc_t * __restrict pwc,
const char ** __restrict s, size_t n,
void * __restrict pspriv,
size_t * __restrict nresult)
{
if (s == NULL) {
*nresult = 0;
return (0);
}
if (n == 0) {
*nresult = (size_t)-2;
return (0);
}
if (pwc != NULL)
*pwc = (_wc_t)(unsigned char) **s;
*nresult = *s == '\0' ? 0 : 1;
return (0);
}
static int
/*ARGSUSED*/
_citrus_NONE_stdenc_wctomb(struct _citrus_stdenc * __restrict ce,
char * __restrict s, size_t n,
_wc_t wc, void * __restrict pspriv,
size_t * __restrict nresult)
{
if ((wc&~0xFFU) != 0) {
*nresult = (size_t)-1;
return (EILSEQ);
}
if (n==0) {
*nresult = (size_t)-2;
return (0);
}
*nresult = 1;
if (s!=NULL && n>0)
*s = (char)wc;
return (0);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: citrus_none.h,v 1.2 2003/03/05 20:18:16 tshiozak Exp $ */
/* $NetBSD: citrus_none.h,v 1.3 2003/06/25 09:51:38 tshiozak Exp $ */
/*-
* Copyright (c)2002 Citrus Project,
@ -29,7 +29,8 @@
#ifndef _CITRUS_NONE_H_
#define _CITRUS_NONE_H_
extern struct _citrus_ctype_ops_rec _citrus_NONE_ctype_ops;
extern struct _citrus_iconv_stdencoding_ops_rec _citrus_NONE_iconv_stdencoding_ops;
extern struct _citrus_ctype_ops_rec _citrus_NONE_ctype_ops;
extern struct _citrus_stdenc_ops _citrus_NONE_stdenc_ops;
extern struct _citrus_stdenc_traits _citrus_NONE_stdenc_traits;
#endif

View File

@ -0,0 +1,225 @@
/* $NetBSD: citrus_pivot_factory.c,v 1.1 2003/06/25 09:51:39 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_pivot_factory.c,v 1.1 2003/06/25 09:51:39 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <limits.h>
#include <sys/queue.h>
#include "citrus_namespace.h"
#include "citrus_region.h"
#include "citrus_bcs.h"
#include "citrus_db_factory.h"
#include "citrus_db_hash.h"
#include "citrus_pivot_file.h"
#include "citrus_pivot_factory.h"
struct src_entry {
char *se_name;
struct _citrus_db_factory *se_df;
SIMPLEQ_ENTRY(src_entry) se_entry;
};
SIMPLEQ_HEAD(src_head, src_entry);
static int
find_src(struct src_head *sh, struct src_entry **rse, const char *name)
{
int ret;
struct src_entry *se;
SIMPLEQ_FOREACH(se, sh, se_entry) {
if (_bcs_strcasecmp(se->se_name, name) == 0) {
*rse = se;
return 0;
}
}
se = malloc(sizeof(*se));
if (se == NULL)
return errno;
se->se_name = strdup(name);
if (se->se_name == NULL) {
ret = errno;
free(se);
return ret;
}
ret = _db_factory_create(&se->se_df, &_db_hash_std, NULL);
if (ret) {
free(se->se_name);
free(se);
return ret;
}
SIMPLEQ_INSERT_TAIL(sh, se, se_entry);
*rse = se;
return 0;
}
static void
free_src(struct src_head *sh)
{
struct src_entry *se;
while((se = SIMPLEQ_FIRST(sh)) != NULL) {
SIMPLEQ_REMOVE_HEAD(sh, se_entry);
_db_factory_free(se->se_df);
free(se->se_name);
free(se);
}
}
#define T_COMM '#'
static int
convert_line(struct src_head *sh, const char *line, size_t len)
{
int ret;
struct src_entry *se;
const char *p;
char key1[LINE_MAX], key2[LINE_MAX], data[LINE_MAX];
u_int32_t val;
/* cut off trailing comment */
p = memchr(line, T_COMM, len);
if (p)
len = p - line;
/* key1 */
line = _bcs_skip_ws_len(line, &len);
if (len == 0)
return 0;
p = _bcs_skip_nonws_len(line, &len);
if (p==line)
return 0;
snprintf(key1, sizeof(key1), "%.*s", (int)(p-line), line);
/* key2 */
line = _bcs_skip_ws_len(p, &len);
if (len == 0)
return 0;
p = _bcs_skip_nonws_len(line, &len);
if (p==line)
return 0;
snprintf(key2, sizeof(key2), "%.*s", (int)(p-line), line);
/* data */
line = _bcs_skip_ws_len(p, &len);
_bcs_trunc_rws_len(line, &len);
snprintf(data, sizeof(data), "%.*s", (int)len, line);
/* LINTED: discard const */
val = strtoul(data, (char **)&p, 0);
if (*p != '\0')
return EFTYPE;
/* insert to DB */
ret = find_src(sh, &se, key1);
if (ret)
return ret;
return _db_factory_add32_by_s(se->se_df, key2, val);
}
static int
dump_db(struct src_head *sh, struct _region *r)
{
int ret;
struct _db_factory *df;
struct src_entry *se;
size_t size;
void *ptr;
struct _region subr;
ret = _db_factory_create(&df, &_db_hash_std, NULL);
if (ret)
return ret;
SIMPLEQ_FOREACH(se, sh, se_entry) {
size = _db_factory_calc_size(se->se_df);
ptr = malloc(size);
if (ptr == NULL)
goto quit;
_region_init(&subr, ptr, size);
ret = _db_factory_serialize(se->se_df, _CITRUS_PIVOT_SUB_MAGIC,
&subr);
if (ret)
goto quit;
ret = _db_factory_add_by_s(df, se->se_name, &subr, 1);
if (ret)
goto quit;
}
size = _db_factory_calc_size(df);
ptr = malloc(size);
if (ptr == NULL)
goto quit;
_region_init(r, ptr, size);
ret = _db_factory_serialize(df, _CITRUS_PIVOT_MAGIC, r);
ptr = NULL;
quit:
free(ptr);
_db_factory_free(df);
return ret;
}
int
_citrus_pivot_factory_convert(FILE *out, FILE *in)
{
struct src_head sh;
struct _region r;
char *line;
size_t size;
int ret;
SIMPLEQ_INIT(&sh);
while ((line = fgetln(in, &size)) != NULL)
if ((ret = convert_line(&sh, line, size))) {
free_src(&sh);
return ret;
}
ret = dump_db(&sh, &r);
free_src(&sh);
if (ret)
return ret;
if (fwrite(_region_head(&r), _region_size(&r), 1, out) != 1)
return errno;
return 0;
}

View File

@ -0,0 +1,36 @@
/* $NetBSD: citrus_pivot_factory.h,v 1.1 2003/06/25 09:51:39 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_PIVOT_FACTORY_H_
#define _CITRUS_PIVOT_FACTORY_H_
__BEGIN_DECLS
int _citrus_pivot_factory_convert(FILE *, FILE *);
__END_DECLS
#endif

View File

@ -0,0 +1,35 @@
/* $NetBSD: citrus_pivot_file.h,v 1.1 2003/06/25 09:51:39 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_PIVOT_FILE_H_
#define _CITRUS_PIVOT_FILE_H_
#define _CITRUS_PIVOT_MAGIC "CSPIVOT\0"
#define _CITRUS_PIVOT_SUB_MAGIC "CSPIVSUB"
#endif

View File

@ -0,0 +1,93 @@
/* $NetBSD: citrus_region.h,v 1.1 2003/06/25 09:51:39 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#ifndef _CITRUS_REGION_H_
#define _CITRUS_REGION_H_
struct _citrus_region {
/* private: */
void *r_head;
size_t r_size;
};
static __inline void
_citrus_region_init(struct _citrus_region *r, void *h, size_t sz)
{
_DIAGASSERT(r);
r->r_head = h;
r->r_size = sz;
}
static __inline void *
_citrus_region_head(const struct _citrus_region *r)
{
return r->r_head;
}
static __inline size_t
_citrus_region_size(const struct _citrus_region *r)
{
return r->r_size;
}
static __inline int
_citrus_region_check(const struct _citrus_region *r, size_t ofs, size_t sz)
{
return r->r_size >= ofs + sz ? 0 : -1;
}
static __inline void *
_citrus_region_offset(const struct _citrus_region *r, size_t pos)
{
return (void *)((uint8_t *)r->r_head + pos);
}
static __inline uint8_t
_citrus_region_peek8(const struct _citrus_region *r, size_t pos)
{
return *(uint8_t *)_citrus_region_offset(r, pos);
}
static __inline uint16_t
_citrus_region_peek16(const struct _citrus_region *r, size_t pos)
{
uint16_t val;
memcpy(&val, _citrus_region_offset(r, pos), 2);
return val;
}
static __inline uint32_t
_citrus_region_peek32(const struct _citrus_region *r, size_t pos)
{
uint32_t val;
memcpy(&val, _citrus_region_offset(r, pos), 4);
return val;
}
#endif

View File

@ -0,0 +1,183 @@
/* $NetBSD: citrus_stdenc.c,v 1.1 2003/06/25 09:51:40 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_stdenc.c,v 1.1 2003/06/25 09:51:40 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "citrus_namespace.h"
#include "citrus_types.h"
#include "citrus_module.h"
#include "citrus_stdenc.h"
#include "citrus_none.h"
struct _citrus_stdenc _citrus_stdenc_default = {
&_citrus_NONE_stdenc_ops, /* ce_ops */
NULL, /* ce_closure */
NULL, /* ce_module */
&_citrus_NONE_stdenc_traits, /* ce_traits */
};
#ifdef _I18N_DYNAMIC
int
_citrus_stdenc_open(struct _citrus_stdenc * __restrict * __restrict rce,
char const * __restrict encname,
const void * __restrict variable, size_t lenvar)
{
int ret;
_citrus_module_t handle;
struct _citrus_stdenc *ce;
_citrus_stdenc_getops_t getops;
_DIAGASSERT(encname != NULL);
_DIAGASSERT(!lenvar || variable!=NULL);
_DIAGASSERT(rcc != NULL);
if (!strcmp(encname, _CITRUS_DEFAULT_STDENC_NAME)) {
*rce = &_citrus_stdenc_default;
return (0);
}
ce = malloc(sizeof(*ce));
if (ce==NULL) {
ret = errno;
goto bad;
}
ce->ce_ops = NULL;
ce->ce_closure = NULL;
ce->ce_module = NULL;
ce->ce_traits = NULL;
ret = _citrus_load_module(&handle, encname);
if (ret)
goto bad;
ce->ce_module = handle;
getops =
(_citrus_stdenc_getops_t)_citrus_find_getops(ce->ce_module,
encname, "stdenc");
if (getops == NULL) {
ret = EINVAL;
goto bad;
}
ce->ce_ops = (struct _citrus_stdenc_ops *)malloc(sizeof(*ce->ce_ops));
if (ce->ce_ops == NULL) {
ret = errno;
goto bad;
}
ret = (*getops)(ce->ce_ops, sizeof(*ce->ce_ops),
_CITRUS_STDENC_ABI_VERSION);
if (ret)
goto bad;
/* If return ABI version is not expected, should fixup it */
/* validation check */
if (ce->ce_ops->eo_init == NULL ||
ce->ce_ops->eo_uninit == NULL ||
ce->ce_ops->eo_init_state == NULL ||
ce->ce_ops->eo_mbtocs == NULL ||
ce->ce_ops->eo_cstomb == NULL ||
ce->ce_ops->eo_mbtowc == NULL ||
ce->ce_ops->eo_wctomb == NULL)
goto bad;
/* allocate traits */
ce->ce_traits = malloc(sizeof(*ce->ce_traits));
if (ce->ce_traits == NULL) {
ret = errno;
goto bad;
}
/* init and get closure */
ret = (*ce->ce_ops->eo_init)(ce, variable, lenvar, ce->ce_traits);
if (ret)
goto bad;
*rce = ce;
return (0);
bad:
_citrus_stdenc_close(ce);
return (ret);
}
void
_citrus_stdenc_close(struct _citrus_stdenc *ce)
{
_DIAGASSERT(ci != NULL);
if (ce == &_citrus_stdenc_default)
return;
if (ce->ce_module) {
if (ce->ce_ops) {
if (ce->ce_closure && ce->ce_ops->eo_uninit)
(*ce->ce_ops->eo_uninit)(ce);
free(ce->ce_ops);
}
free(ce->ce_traits);
_citrus_unload_module(ce->ce_module);
}
free(ce);
}
#else
/* !_I18N_DYNAMIC */
int
/*ARGSUSED*/
_citrus_stdenc_open(struct _citrus_stdenc * __restrict * __restrict rce,
char const * __restrict encname,
const void * __restrict variable, size_t lenvar)
{
if (!strcmp(encname, _CITRUS_DEFAULT_STDENC_NAME)) {
*rce = &_citrus_stdenc_default;
return (0);
}
return (EINVAL);
}
void
/*ARGSUSED*/
_citrus_stdenc_close(struct _citrus_stdenc *ce)
{
}
#endif

View File

@ -0,0 +1,108 @@
/* $NetBSD: citrus_stdenc.h,v 1.1 2003/06/25 09:51:40 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#ifndef _CITRUS_STDENC_H_
#define _CITRUS_STDENC_H_
struct _citrus_stdenc;
struct _citrus_stdenc_ops;
struct _citrus_stdenc_traits;
#include "citrus_stdenc_local.h"
__BEGIN_DECLS
int _citrus_stdenc_open(struct _citrus_stdenc * __restrict * __restrict,
char const * __restrict,
const void * __restrict, size_t);
void _citrus_stdenc_close(struct _citrus_stdenc *);
__END_DECLS
static __inline int
_citrus_stdenc_init_state(struct _citrus_stdenc * __restrict ce,
void * __restrict ps)
{
_DIAGASSERT(ce && ce->ci_ops && ce->ce_ops->eo_init_state);
return (*ce->ce_ops->eo_init_state)(ce, ps);
}
static __inline int
_citrus_stdenc_mbtocs(struct _citrus_stdenc * __restrict ce,
_citrus_csid_t * __restrict csid,
_citrus_index_t * __restrict idx,
const char ** __restrict s, size_t n,
void * __restrict ps, size_t * __restrict nresult)
{
_DIAGASSERT(ce && ce->ce_ops && ce->ce_ops->eo_mbtocs);
return (*ce->ce_ops->eo_mbtocs)(ce, csid, idx, s, n, ps, nresult);
}
static __inline int
_citrus_stdenc_cstomb(struct _citrus_stdenc * __restrict ce,
char * __restrict s, size_t n,
_citrus_csid_t csid, _citrus_index_t idx,
void * __restrict ps, size_t * __restrict nresult)
{
_DIAGASSERT(ce && ce->ce_ops && ce->ce_ops->eo_cstomb);
return (*ce->ce_ops->eo_cstomb)(ce, s, n, csid, idx, ps, nresult);
}
static __inline int
_citrus_stdenc_mbtowc(struct _citrus_stdenc * __restrict ce,
_citrus_wc_t * __restrict wc,
const char ** __restrict s, size_t n,
void * __restrict ps, size_t * __restrict nresult)
{
_DIAGASSERT(ce && ce->ce_ops && ce->ce_ops->eo_mbtocs);
return (*ce->ce_ops->eo_mbtowc)(ce, wc, s, n, ps, nresult);
}
static __inline int
_citrus_stdenc_wctomb(struct _citrus_stdenc * __restrict ce,
char * __restrict s, size_t n, _citrus_wc_t wc,
void * __restrict ps, size_t * __restrict nresult)
{
_DIAGASSERT(ce && ce->ce_ops && ce->ce_ops->eo_cstomb);
return (*ce->ce_ops->eo_wctomb)(ce, s, n, wc, ps, nresult);
}
static __inline size_t
_citrus_stdenc_get_state_size(struct _citrus_stdenc *ce)
{
_DIAGASSERT(ce && ce->ce_traits);
return ce->ce_traits->et_state_size;
}
static __inline size_t
_citrus_stdenc_get_mb_cur_max(struct _citrus_stdenc *ce)
{
_DIAGASSERT(ce && ce->ce_traits);
return ce->ce_traits->et_mb_cur_max;
}
#endif

View File

@ -0,0 +1,137 @@
/* $NetBSD: citrus_stdenc_local.h,v 1.1 2003/06/25 09:51:40 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#ifndef _CITRUS_STDENC_LOCAL_H_
#define _CITRUS_STDENC_LOCAL_H_
#define _CITRUS_STDENC_GETOPS_FUNC_BASE(n) \
int n(struct _citrus_stdenc_ops *, size_t, u_int32_t)
#define _CITRUS_STDENC_GETOPS_FUNC(_e_) \
_CITRUS_STDENC_GETOPS_FUNC_BASE(_citrus_##_e_##_stdenc_getops)
typedef _CITRUS_STDENC_GETOPS_FUNC_BASE((*_citrus_stdenc_getops_t));
#define _CITRUS_STDENC_DECLS(_e_) \
static int _citrus_##_e_##_stdenc_init \
(struct _citrus_stdenc * __restrict, const void * __restrict, \
size_t, struct _citrus_stdenc_traits * __restrict); \
static void _citrus_##_e_##_stdenc_uninit(struct _citrus_stdenc *); \
static int _citrus_##_e_##_stdenc_init_state \
(struct _citrus_stdenc * __restrict, void * __restrict); \
static int _citrus_##_e_##_stdenc_mbtocs \
(struct _citrus_stdenc * __restrict, \
_citrus_csid_t * __restrict, _citrus_index_t * __restrict, \
const char ** __restrict, size_t, \
void * __restrict, size_t * __restrict); \
static int _citrus_##_e_##_stdenc_cstomb \
(struct _citrus_stdenc * __restrict, char * __restrict, \
size_t, _citrus_csid_t, _citrus_index_t, \
void * __restrict, size_t * __restrict); \
static int _citrus_##_e_##_stdenc_mbtowc \
(struct _citrus_stdenc * __restrict, \
_citrus_wc_t * __restrict, \
const char ** __restrict, size_t, \
void * __restrict, size_t * __restrict); \
static int _citrus_##_e_##_stdenc_wctomb \
(struct _citrus_stdenc * __restrict, char * __restrict, size_t, \
_citrus_wc_t, void * __restrict, size_t * __restrict)
#define _CITRUS_STDENC_DEF_OPS(_e_) \
struct _citrus_stdenc_ops _citrus_##_e_##_stdenc_ops = { \
/* eo_abi_version */ _CITRUS_STDENC_ABI_VERSION, \
/* eo_init */ &_citrus_##_e_##_stdenc_init, \
/* eo_uninit */ &_citrus_##_e_##_stdenc_uninit, \
/* eo_init_state */ &_citrus_##_e_##_stdenc_init_state, \
/* eo_mbtocs */ &_citrus_##_e_##_stdenc_mbtocs, \
/* eo_cstomb */ &_citrus_##_e_##_stdenc_cstomb, \
/* eo_mbtowc */ &_citrus_##_e_##_stdenc_mbtowc, \
/* eo_wctomb */ &_citrus_##_e_##_stdenc_wctomb, \
}
typedef int (*_citrus_stdenc_init_t)
(struct _citrus_stdenc * __reatrict, const void * __restrict , size_t,
struct _citrus_stdenc_traits * __restrict);
typedef void (*_citrus_stdenc_uninit_t)(struct _citrus_stdenc * __restrict);
typedef int (*_citrus_stdenc_init_state_t)
(struct _citrus_stdenc * __restrict, void * __restrict);
typedef int (*_citrus_stdenc_mbtocs_t)
(struct _citrus_stdenc * __restrict,
_citrus_csid_t * __restrict, _citrus_index_t * __restrict,
const char ** __restrict, size_t,
void * __restrict, size_t * __restrict);
typedef int (*_citrus_stdenc_cstomb_t)
(struct _citrus_stdenc *__restrict, char * __restrict, size_t,
_citrus_csid_t, _citrus_index_t, void * __restrict,
size_t * __restrict);
typedef int (*_citrus_stdenc_mbtowc_t)
(struct _citrus_stdenc * __restrict,
_citrus_wc_t * __restrict,
const char ** __restrict, size_t,
void * __restrict, size_t * __restrict);
typedef int (*_citrus_stdenc_wctomb_t)
(struct _citrus_stdenc *__restrict, char * __restrict, size_t,
_citrus_wc_t, void * __restrict, size_t * __restrict);
/*
* ABI version change log
* 0x00000001
* initial version
*/
#define _CITRUS_STDENC_ABI_VERSION 0x00000001
struct _citrus_stdenc_ops {
u_int32_t eo_abi_version;
/* version 0x00000001 */
_citrus_stdenc_init_t eo_init;
_citrus_stdenc_uninit_t eo_uninit;
_citrus_stdenc_init_state_t eo_init_state;
_citrus_stdenc_mbtocs_t eo_mbtocs;
_citrus_stdenc_cstomb_t eo_cstomb;
_citrus_stdenc_mbtowc_t eo_mbtowc;
_citrus_stdenc_wctomb_t eo_wctomb;
};
struct _citrus_stdenc_traits {
/* version 0x00000001 */
size_t et_state_size;
size_t et_mb_cur_max;
};
struct _citrus_stdenc {
/* public */
/* version 0x00000001 */
struct _citrus_stdenc_ops *ce_ops;
void *ce_closure;
/* private */
_citrus_module_t ce_module;
struct _citrus_stdenc_traits *ce_traits;
};
#define _CITRUS_DEFAULT_STDENC_NAME "NONE"
#endif

View File

@ -0,0 +1,171 @@
/* $NetBSD: citrus_stdenc_template.h,v 1.1 2003/06/25 09:51:41 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* CAUTION: THIS IS NOT STANDALONE FILE
*
* function templates of iconv standard encoding handler for each encodings.
*
*/
/*
* macros
*/
#undef _TO_EI
#undef _CE_TO_EI
#undef _TO_STATE
#define _TO_EI(_cl_) ((_ENCODING_INFO*)(_cl_))
#define _CE_TO_EI(_ce_) (_TO_EI((_ce_)->ce_closure))
#define _TO_STATE(_ps_) ((_ENCODING_STATE*)(_ps_))
/* ----------------------------------------------------------------------
* templates for public functions
*/
int
_FUNCNAME(stdenc_getops)(struct _citrus_stdenc_ops *ops, size_t lenops,
u_int32_t expected_version)
{
if (expected_version<_CITRUS_STDENC_ABI_VERSION || lenops<sizeof(*ops))
return (EINVAL);
memcpy(ops, &_FUNCNAME(stdenc_ops), sizeof(_FUNCNAME(stdenc_ops)));
return (0);
}
static int
_FUNCNAME(stdenc_init)(struct _citrus_stdenc * __restrict ce,
const void * __restrict var, size_t lenvar,
struct _citrus_stdenc_traits * __restrict et)
{
int ret;
_ENCODING_INFO *ei;
ei = NULL;
if (sizeof(_ENCODING_INFO) > 0) {
ei = calloc(1, sizeof(_ENCODING_INFO));
if (ei == NULL) {
return errno;
}
}
ret = _FUNCNAME(encoding_module_init)(ei, var, lenvar);
if (ret) {
free((void *)ei);
return ret;
}
ce->ce_closure = ei;
et->et_state_size = sizeof(_ENCODING_STATE);
et->et_mb_cur_max = _ENCODING_MB_CUR_MAX(_CE_TO_EI(ce));
return 0;
}
static void
_FUNCNAME(stdenc_uninit)(struct _citrus_stdenc * __restrict ce)
{
if (ce) {
_FUNCNAME(encoding_module_uninit)(_CE_TO_EI(ce));
free(ce->ce_closure);
}
}
static int
_FUNCNAME(stdenc_init_state)(struct _citrus_stdenc * __restrict ce,
void * __restrict ps)
{
_FUNCNAME(init_state)(_CE_TO_EI(ce), _TO_STATE(ps));
return 0;
}
static int
_FUNCNAME(stdenc_mbtocs)(struct _citrus_stdenc * __restrict ce,
_citrus_csid_t * __restrict csid,
_citrus_index_t * __restrict idx,
const char ** __restrict s, size_t n,
void * __restrict ps, size_t * __restrict nresult)
{
int ret;
wchar_t wc;
_DIAGASSERT(nresult != NULL);
ret = _FUNCNAME(mbrtowc_priv)(_CE_TO_EI(ce), &wc, s, n,
_TO_STATE(ps), nresult);
if (!ret && *nresult != (size_t)-2)
_FUNCNAME(stdenc_wctocs)(_CE_TO_EI(ce), csid, idx, wc);
return ret;
}
static int
_FUNCNAME(stdenc_cstomb)(struct _citrus_stdenc * __restrict ce,
char * __restrict s, size_t n,
_citrus_csid_t csid, _citrus_index_t idx,
void * __restrict ps, size_t * __restrict nresult)
{
int ret;
wchar_t wc;
_DIAGASSERT(nresult != NULL);
wc = 0;
if (csid != _CITRUS_CSID_INVALID) {
ret = _FUNCNAME(stdenc_cstowc)(_CE_TO_EI(ce), &wc, csid, idx);
if (ret)
return ret;
}
return _FUNCNAME(wcrtomb_priv)(_CE_TO_EI(ce), s, n, wc, _TO_STATE(ps),
nresult);
}
static int
_FUNCNAME(stdenc_mbtowc)(struct _citrus_stdenc * __restrict ce,
_citrus_wc_t * __restrict wc,
const char ** __restrict s, size_t n,
void * __restrict ps, size_t * __restrict nresult)
{
return _FUNCNAME(mbrtowc_priv)(_CE_TO_EI(ce), wc, s, n,
_TO_STATE(ps), nresult);
}
static int
_FUNCNAME(stdenc_wctomb)(struct _citrus_stdenc * __restrict ce,
char * __restrict s, size_t n, _citrus_wc_t wc,
void * __restrict ps, size_t * __restrict nresult)
{
return _FUNCNAME(wcrtomb_priv)(_CE_TO_EI(ce), s, n, wc, _TO_STATE(ps),
nresult);
}

View File

@ -0,0 +1,37 @@
/* $NetBSD: citrus_types.h,v 1.1 2003/06/25 09:51:41 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_TYPES_H_
#define _CITRUS_TYPES_H_
typedef uint32_t _citrus_wc_t;
typedef uint32_t _citrus_index_t;
typedef uint32_t _citrus_csid_t;
#define _CITRUS_CSID_INVALID ((_citrus_csid_t)-1)
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: citrus_big5.c,v 1.5 2002/03/28 10:53:48 yamt Exp $ */
/* $NetBSD: citrus_big5.c,v 1.6 2003/06/25 09:51:41 tshiozak Exp $ */
/*-
* Copyright (c)2002 Citrus Project,
@ -64,7 +64,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_big5.c,v 1.5 2002/03/28 10:53:48 yamt Exp $");
__RCSID("$NetBSD: citrus_big5.c,v 1.6 2003/06/25 09:51:41 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include <assert.h>
@ -77,8 +77,12 @@ __RCSID("$NetBSD: citrus_big5.c,v 1.5 2002/03/28 10:53:48 yamt Exp $");
#include <wchar.h>
#include <sys/types.h>
#include <limits.h>
#include "citrus_namespace.h"
#include "citrus_types.h"
#include "citrus_module.h"
#include "citrus_ctype.h"
#include "citrus_stdenc.h"
#include "citrus_big5.h"
/* ----------------------------------------------------------------------
@ -166,8 +170,8 @@ _citrus_BIG5_check2(u_int c)
static int
/*ARGSUSED*/
_citrus_BIG5_stdencoding_init(_BIG5EncodingInfo * __restrict ei,
const void * __restrict var, size_t lenvar)
_citrus_BIG5_encoding_module_init(_BIG5EncodingInfo * __restrict ei,
const void * __restrict var, size_t lenvar)
{
_DIAGASSERT(ei != NULL);
@ -178,7 +182,7 @@ _citrus_BIG5_stdencoding_init(_BIG5EncodingInfo * __restrict ei,
static void
/*ARGSUSED*/
_citrus_BIG5_stdencoding_uninit(_BIG5EncodingInfo *ei)
_citrus_BIG5_encoding_module_uninit(_BIG5EncodingInfo *ei)
{
}
@ -281,30 +285,43 @@ _citrus_BIG5_wcrtomb_priv(_BIG5EncodingInfo * __restrict ei,
size_t n, wchar_t wc, _BIG5State * __restrict psenc,
size_t * __restrict nresult)
{
int l;
int l, ret;
_DIAGASSERT(ei != NULL);
_DIAGASSERT(nresult != 0);
_DIAGASSERT(s != NULL);
/* reset state */
if (wc == 0) {
*nresult = 0; /* stateless */
return 0;
}
/* check invalid sequence */
if (wc & ~0xffff)
goto ilseq;
if (wc & ~0xffff) {
ret = EILSEQ;
goto err;
}
if (wc & 0x8000) {
if (_citrus_BIG5_check((wc >> 8) & 0xff) != 2 ||
!_citrus_BIG5_check2(wc & 0xff))
goto ilseq;
!_citrus_BIG5_check2(wc & 0xff)) {
ret = EILSEQ;
goto err;
}
l = 2;
} else {
if (wc & ~0xff || !_citrus_BIG5_check(wc & 0xff))
goto ilseq;
if (wc & ~0xff || !_citrus_BIG5_check(wc & 0xff)) {
ret = EILSEQ;
goto err;
}
l = 1;
}
if (n < l) {
/* bound check failure */
goto ilseq;
ret = E2BIG;
goto err;
}
if (l == 2) {
@ -315,13 +332,62 @@ _citrus_BIG5_wcrtomb_priv(_BIG5EncodingInfo * __restrict ei,
*nresult = l;
return (0);
return 0;
ilseq:
err:
*nresult = (size_t)-1;
return (EILSEQ);
return ret;
}
static __inline int
/*ARGSUSED*/
_citrus_BIG5_stdenc_wctocs(_BIG5EncodingInfo * __restrict ei,
_csid_t * __restrict csid,
_index_t * __restrict idx, wchar_t wc)
{
_DIAGASSERT(csid != NULL && idx != NULL);
if (wc<0x100)
*csid = 0;
else
*csid = 1;
*idx = (_index_t)wc;
return 0;
}
static __inline int
/*ARGSUSED*/
_citrus_BIG5_stdenc_cstowc(_BIG5EncodingInfo * __restrict ei,
wchar_t * __restrict wc,
_csid_t csid, _index_t idx)
{
u_int8_t h, l;
_DIAGASSERT(wc != NULL);
switch (csid) {
case 0:
if (idx>=0x80U)
return EILSEQ;
*wc = (wchar_t)idx;
break;
case 1:
if (idx>=0x10000U)
return EILSEQ;
h = idx >> 8;
l = idx;
if (h<0xA1 || h>0xF9 || l<0x40 || l>0xFE)
return EILSEQ;
*wc = (wchar_t)idx;
break;
default:
return EILSEQ;
}
return 0;
}
/* ----------------------------------------------------------------------
* public interface for ctype
@ -331,3 +397,13 @@ _CITRUS_CTYPE_DECLS(BIG5);
_CITRUS_CTYPE_DEF_OPS(BIG5);
#include "citrus_ctype_template.h"
/* ----------------------------------------------------------------------
* public interface for stdenc
*/
_CITRUS_STDENC_DECLS(BIG5);
_CITRUS_STDENC_DEF_OPS(BIG5);
#include "citrus_stdenc_template.h"

View File

@ -1,4 +1,4 @@
/* $NetBSD: citrus_big5.h,v 1.1 2002/03/17 22:14:22 tshiozak Exp $ */
/* $NetBSD: citrus_big5.h,v 1.2 2003/06/25 09:51:41 tshiozak Exp $ */
/*-
* Copyright (c)2002 Citrus Project,
@ -31,6 +31,7 @@
__BEGIN_DECLS
_CITRUS_CTYPE_GETOPS_FUNC(BIG5);
_CITRUS_STDENC_GETOPS_FUNC(BIG5);
__END_DECLS
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: citrus_euc.c,v 1.5 2002/03/28 10:53:48 yamt Exp $ */
/* $NetBSD: citrus_euc.c,v 1.6 2003/06/25 09:51:42 tshiozak Exp $ */
/*-
* Copyright (c)2002 Citrus Project,
@ -64,7 +64,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_euc.c,v 1.5 2002/03/28 10:53:48 yamt Exp $");
__RCSID("$NetBSD: citrus_euc.c,v 1.6 2003/06/25 09:51:42 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include <assert.h>
@ -77,8 +77,12 @@ __RCSID("$NetBSD: citrus_euc.c,v 1.5 2002/03/28 10:53:48 yamt Exp $");
#include <wchar.h>
#include <sys/types.h>
#include <limits.h>
#include "citrus_namespace.h"
#include "citrus_types.h"
#include "citrus_module.h"
#include "citrus_ctype.h"
#include "citrus_stdenc.h"
#include "citrus_euc.h"
@ -299,12 +303,18 @@ _citrus_EUC_wcrtomb_priv(_EUCEncodingInfo *ei, char *s, size_t n, wchar_t wc,
_EUCState *psenc, size_t *nresult)
{
wchar_t m, nm;
int cs, i;
int cs, i, ret;
_DIAGASSERT(ei != NULL);
_DIAGASSERT(nresult != 0);
_DIAGASSERT(s != NULL);
/* reset state */
if (wc == 0) {
*nresult = 0; /* stateless */
return 0;
}
m = wc & ei->mask;
nm = wc & ~m;
@ -319,8 +329,10 @@ _citrus_EUC_wcrtomb_priv(_EUCEncodingInfo *ei, char *s, size_t n, wchar_t wc,
cs = 1;
i = ei->count[cs];
if (n < i)
goto ilseq;
if (n < i) {
ret = E2BIG;
goto err;
}
m = (cs % 2) ? 0x80 : 0x00;
switch (cs) {
case 2:
@ -339,15 +351,51 @@ _citrus_EUC_wcrtomb_priv(_EUCEncodingInfo *ei, char *s, size_t n, wchar_t wc,
*nresult = (size_t)ei->count[cs];
return 0;
ilseq:
err:
*nresult = (size_t)-1;
return EILSEQ; /*XXX*/
return ret;
}
static __inline int
/*ARGSUSED*/
_citrus_EUC_stdenc_wctocs(_EUCEncodingInfo * __restrict ei,
_csid_t * __restrict csid,
_index_t * __restrict idx, wchar_t wc)
{
wchar_t m, nm;
_DIAGASSERT(ei != NULL && csid != NULL && idx != NULL);
m = wc & ei->mask;
nm = wc & ~m;
*csid = (_citrus_csid_t)m;
*idx = (_citrus_index_t)nm;
return (0);
}
static __inline int
/*ARGSUSED*/
_citrus_EUC_stdenc_cstowc(_EUCEncodingInfo * __restrict ei,
wchar_t * __restrict wc,
_csid_t csid, _index_t idx)
{
_DIAGASSERT(ei != NULL && wc != NULL);
if ((csid & ~ei->mask) != 0 || (idx & ei->mask) != 0)
return (EINVAL);
*wc = (wchar_t)csid | (wchar_t)idx;
return (0);
}
static int
/*ARGSUSED*/
_citrus_EUC_stdencoding_init(_EUCEncodingInfo * __restrict ei,
const void * __restrict var, size_t lenvar)
_citrus_EUC_encoding_module_init(_EUCEncodingInfo * __restrict ei,
const void * __restrict var, size_t lenvar)
{
_DIAGASSERT(ei != NULL);
@ -357,7 +405,7 @@ _citrus_EUC_stdencoding_init(_EUCEncodingInfo * __restrict ei,
static void
/*ARGSUSED*/
_citrus_EUC_stdencoding_uninit(_EUCEncodingInfo * __restrict ei)
_citrus_EUC_encoding_module_uninit(_EUCEncodingInfo * __restrict ei)
{
}
@ -369,3 +417,12 @@ _CITRUS_CTYPE_DECLS(EUC);
_CITRUS_CTYPE_DEF_OPS(EUC);
#include "citrus_ctype_template.h"
/* ----------------------------------------------------------------------
* public interface for stdenc
*/
_CITRUS_STDENC_DECLS(EUC);
_CITRUS_STDENC_DEF_OPS(EUC);
#include "citrus_stdenc_template.h"

View File

@ -1,4 +1,4 @@
/* $NetBSD: citrus_euc.h,v 1.1 2002/03/17 22:14:22 tshiozak Exp $ */
/* $NetBSD: citrus_euc.h,v 1.2 2003/06/25 09:51:42 tshiozak Exp $ */
/*-
* Copyright (c)2002 Citrus Project,
@ -31,6 +31,7 @@
__BEGIN_DECLS
_CITRUS_CTYPE_GETOPS_FUNC(EUC);
_CITRUS_STDENC_GETOPS_FUNC(EUC);
__END_DECLS
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: citrus_euctw.c,v 1.5 2002/03/28 10:53:48 yamt Exp $ */
/* $NetBSD: citrus_euctw.c,v 1.6 2003/06/25 09:51:42 tshiozak Exp $ */
/*-
* Copyright (c)2002 Citrus Project,
@ -56,7 +56,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_euctw.c,v 1.5 2002/03/28 10:53:48 yamt Exp $");
__RCSID("$NetBSD: citrus_euctw.c,v 1.6 2003/06/25 09:51:42 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include <assert.h>
@ -69,8 +69,12 @@ __RCSID("$NetBSD: citrus_euctw.c,v 1.5 2002/03/28 10:53:48 yamt Exp $");
#include <wchar.h>
#include <sys/types.h>
#include <limits.h>
#include "citrus_namespace.h"
#include "citrus_types.h"
#include "citrus_module.h"
#include "citrus_ctype.h"
#include "citrus_stdenc.h"
#include "citrus_euctw.h"
@ -168,8 +172,8 @@ _citrus_EUCTW_unpack_state(_EUCTWEncodingInfo * __restrict ei,
static int
/*ARGSUSED*/
_citrus_EUCTW_stdencoding_init(_EUCTWEncodingInfo * __restrict ei,
const void * __restrict var, size_t lenvar)
_citrus_EUCTW_encoding_module_init(_EUCTWEncodingInfo * __restrict ei,
const void * __restrict var, size_t lenvar)
{
_DIAGASSERT(ei != NULL);
@ -181,7 +185,7 @@ _citrus_EUCTW_stdencoding_init(_EUCTWEncodingInfo * __restrict ei,
static void
/*ARGSUSED*/
_citrus_EUCTW_stdencoding_uninit(_EUCTWEncodingInfo *ei)
_citrus_EUCTW_encoding_module_uninit(_EUCTWEncodingInfo *ei)
{
}
@ -295,12 +299,18 @@ _citrus_EUCTW_wcrtomb_priv(_EUCTWEncodingInfo * __restrict ei,
{
wchar_t cs = wc & 0x7f000080;
wchar_t v;
int i, len, clen;
int i, len, clen, ret;
_DIAGASSERT(ei != NULL);
_DIAGASSERT(nresult != 0);
_DIAGASSERT(s != NULL);
/* reset state */
if (wc == 0) {
*nresult = 0; /* stateless */
return 0;
}
clen = 1;
if (wc & 0x00007f00)
clen = 2;
@ -310,38 +320,86 @@ _citrus_EUCTW_wcrtomb_priv(_EUCTWEncodingInfo * __restrict ei,
if (clen == 1 && cs == 0x00000000) {
/* ASCII */
len = 1;
if (n < len)
goto ilseq;
if (n < len) {
ret = E2BIG;
goto err;
}
v = wc & 0x0000007f;
} else if (clen == 2 && cs == ('G' << 24)) {
/* CNS-11643-1 */
len = 2;
if (n < len)
goto ilseq;
if (n < len) {
ret = E2BIG;
goto err;
}
v = wc & 0x00007f7f;
v |= 0x00008080;
} else if (clen == 2 && 'H' <= (cs >> 24) && (cs >> 24) <= 'M') {
/* CNS-11643-[2-7] */
len = 4;
if (n < len)
goto ilseq;
if (n < len) {
ret = E2BIG;
goto err;
}
*s++ = _SS2;
*s++ = (cs >> 24) - 'H' + 0xa2;
v = wc & 0x00007f7f;
v |= 0x00008080;
} else
goto ilseq;
} else {
ret = EILSEQ;
goto err;
}
i = clen;
while (i-- > 0)
*s++ = (v >> (i << 3)) & 0xff;
*nresult = len;
return (0);
return 0;
ilseq:
err:
*nresult = (size_t)-1;
return (EILSEQ);
return ret;
}
static __inline int
/*ARGSUSED*/
_citrus_EUCTW_stdenc_wctocs(_EUCTWEncodingInfo * __restrict ei,
_csid_t * __restrict csid,
_index_t * __restrict idx, wchar_t wc)
{
_DIAGASSERT(ei != NULL && csid != NULL && idx != NULL);
*csid = (_csid_t)(wc >> 24) & 0xFF;
*idx = (_index_t)(wc & 0x7F7F);
return (0);
}
static __inline int
/*ARGSUSED*/
_citrus_EUCTW_stdenc_cstowc(_EUCTWEncodingInfo * __restrict ei,
wchar_t * __restrict wc,
_csid_t csid, _index_t idx)
{
_DIAGASSERT(ei != NULL && wc != NULL);
if (csid > 7 || (idx & ~0x7F7F) != 0)
return (EINVAL);
if (csid==0) {
if ((idx & ~0x7F) != 0)
return (EINVAL);
*wc = (wchar_t)idx;
} else {
if ((idx & ~0x7F7F) != 0)
return (EINVAL);
*wc = (wchar_t)idx | ((wchar_t)csid<<24);
}
return (0);
}
/* ----------------------------------------------------------------------
@ -352,3 +410,12 @@ _CITRUS_CTYPE_DECLS(EUCTW);
_CITRUS_CTYPE_DEF_OPS(EUCTW);
#include "citrus_ctype_template.h"
/* ----------------------------------------------------------------------
* public interface for stdenc
*/
_CITRUS_STDENC_DECLS(EUCTW);
_CITRUS_STDENC_DEF_OPS(EUCTW);
#include "citrus_stdenc_template.h"

View File

@ -1,4 +1,4 @@
/* $NetBSD: citrus_euctw.h,v 1.1 2002/03/17 22:14:23 tshiozak Exp $ */
/* $NetBSD: citrus_euctw.h,v 1.2 2003/06/25 09:51:42 tshiozak Exp $ */
/*-
* Copyright (c)2002 Citrus Project,
@ -31,6 +31,7 @@
__BEGIN_DECLS
_CITRUS_CTYPE_GETOPS_FUNC(EUCTW);
_CITRUS_STDENC_GETOPS_FUNC(EUCTW);
__END_DECLS
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: citrus_gbk2k.c,v 1.2 2003/05/08 20:42:39 petrov Exp $ */
/* $NetBSD: citrus_gbk2k.c,v 1.3 2003/06/25 09:51:42 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
@ -28,7 +28,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_gbk2k.c,v 1.2 2003/05/08 20:42:39 petrov Exp $");
__RCSID("$NetBSD: citrus_gbk2k.c,v 1.3 2003/06/25 09:51:42 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include <assert.h>
@ -41,8 +41,13 @@ __RCSID("$NetBSD: citrus_gbk2k.c,v 1.2 2003/05/08 20:42:39 petrov Exp $");
#include <wchar.h>
#include <sys/types.h>
#include <limits.h>
#include "citrus_namespace.h"
#include "citrus_types.h"
#include "citrus_bcs.h"
#include "citrus_module.h"
#include "citrus_ctype.h"
#include "citrus_stdenc.h"
#include "citrus_gbk2k.h"
@ -56,8 +61,9 @@ typedef struct _GBK2KState {
} _GBK2KState;
typedef struct {
int dummy;
int ei_mode;
} _GBK2KEncodingInfo;
#define _MODE_2BYTE 0x0001
typedef struct {
_GBK2KEncodingInfo ei;
@ -217,7 +223,8 @@ _citrus_GBK2K_mbrtowc_priv(_GBK2KEncodingInfo * __restrict ei,
case 2:
if (_mb_trailbyte (_PSENC))
goto convert;
if (_mb_surrogate (_PSENC))
if ((ei->ei_mode & _MODE_2BYTE) == 0 &&
_mb_surrogate (_PSENC))
continue;
goto ilseq;
case 3:
@ -267,35 +274,52 @@ _citrus_GBK2K_wcrtomb_priv(_GBK2KEncodingInfo * __restrict ei,
_GBK2KState * __restrict psenc,
size_t * __restrict nresult)
{
int len;
int len, ret;
_DIAGASSERT(ei != NULL);
_DIAGASSERT(s != NULL);
_DIAGASSERT(psenc != NULL);
if (psenc->chlen != 0)
goto invalid;
if (psenc->chlen != 0) {
ret = EINVAL;
goto err;
}
/* reset state */
if (wc == 0) {
*nresult = 0; /* stateless */
return 0;
}
len = _mb_count(wc);
if (n < len)
goto ilseq;
if (n < len) {
ret = E2BIG;
goto err;
}
switch (len) {
case 1:
if (!_mb_singlebyte(_PUSH_PSENC(wc )))
goto ilseq;
if (!_mb_singlebyte(_PUSH_PSENC(wc ))) {
ret = EILSEQ;
goto err;
}
break;
case 2:
if (!_mb_leadbyte (_PUSH_PSENC(wc >> 8)) ||
!_mb_trailbyte (_PUSH_PSENC(wc )))
goto ilseq;
!_mb_trailbyte (_PUSH_PSENC(wc ))) {
ret = EILSEQ;
goto err;
}
break;
case 4:
if (!_mb_leadbyte (_PUSH_PSENC(wc >> 24)) ||
if ((ei->ei_mode & _MODE_2BYTE) != 0 ||
!_mb_leadbyte (_PUSH_PSENC(wc >> 24)) ||
!_mb_surrogate (_PUSH_PSENC(wc >> 16)) ||
!_mb_leadbyte (_PUSH_PSENC(wc >> 8)) ||
!_mb_surrogate (_PUSH_PSENC(wc )))
goto ilseq;
!_mb_surrogate (_PUSH_PSENC(wc ))) {
ret = EILSEQ;
goto err;
}
break;
}
@ -308,28 +332,117 @@ _citrus_GBK2K_wcrtomb_priv(_GBK2KEncodingInfo * __restrict ei,
return (0);
invalid:
return (EINVAL);
ilseq:
err:
*nresult = (size_t)-1;
return (EILSEQ);
return ret;
}
static __inline int
/*ARGSUSED*/
_citrus_GBK2K_stdenc_wctocs(_GBK2KEncodingInfo * __restrict ei,
_csid_t * __restrict csid,
_index_t * __restrict idx, wchar_t wc)
{
u_int8_t ch, cl;
_DIAGASSERT(csid != NULL && idx != NULL);
if ((u_int32_t)wc<0x80) {
/* ISO646 */
*csid = 0;
*idx = (_index_t)wc;
} else if ((u_int32_t)wc>=0x10000) {
/* GBKUCS : XXX */
*csid = 3;
*idx = (_index_t)wc;
} else {
ch = (u_int8_t)(wc >> 8);
cl = (u_int8_t)wc;
if (ch>=0xA1 && cl>=0xA1) {
/* EUC G1 */
*csid = 1;
*idx = (_index_t)wc & 0x7F7FU;
} else {
/* extended area (0x8140-) */
*csid = 2;
*idx = (_index_t)wc;
}
}
return 0;
}
static __inline int
/*ARGSUSED*/
_citrus_GBK2K_stdenc_cstowc(_GBK2KEncodingInfo * __restrict ei,
wchar_t * __restrict wc,
_csid_t csid, _index_t idx)
{
_DIAGASSERT(wc != NULL);
switch (csid) {
case 0:
/* ISO646 */
*wc = (wchar_t)idx;
break;
case 1:
/* EUC G1 */
*wc = (wchar_t)idx | 0x8080U;
break;
case 2:
/* extended area */
*wc = (wchar_t)idx;
break;
case 3:
/* GBKUCS : XXX */
if ((ei->ei_mode & _MODE_2BYTE) != 0)
return EINVAL;
*wc = (wchar_t)idx;
break;
default:
return EILSEQ;
}
return 0;
}
static int
/*ARGSUSED*/
_citrus_GBK2K_stdencoding_init(_GBK2KEncodingInfo * __restrict ei,
const void * __restrict var, size_t lenvar)
_citrus_GBK2K_encoding_module_init(_GBK2KEncodingInfo * __restrict ei,
const void * __restrict var, size_t lenvar)
{
const char *p;
_DIAGASSERT(ei != NULL);
p = var;
#define MATCH(x, act) \
do { \
if (lenvar >= (sizeof(#x)-1) && \
_bcs_strncasecmp(p, #x, sizeof(#x)-1) == 0) { \
act; \
lenvar -= sizeof(#x)-1; \
p += sizeof(#x)-1; \
} \
} while (/*CONSTCOND*/0)
while (lenvar>0) {
switch (_bcs_tolower(*p)) {
case '2':
MATCH("2byte", ei->ei_mode |= _MODE_2BYTE);
break;
}
p++;
lenvar--;
}
memset((void *)ei, 0, sizeof(*ei));
return (0);
}
static void
/*ARGSUSED*/
_citrus_GBK2K_stdencoding_uninit(_GBK2KEncodingInfo *ei)
_citrus_GBK2K_encoding_module_uninit(_GBK2KEncodingInfo *ei)
{
}
@ -342,3 +455,12 @@ _CITRUS_CTYPE_DECLS(GBK2K);
_CITRUS_CTYPE_DEF_OPS(GBK2K);
#include "citrus_ctype_template.h"
/* ----------------------------------------------------------------------
* public interface for stdenc
*/
_CITRUS_STDENC_DECLS(GBK2K);
_CITRUS_STDENC_DEF_OPS(GBK2K);
#include "citrus_stdenc_template.h"

View File

@ -1,4 +1,4 @@
/* $NetBSD: citrus_gbk2k.h,v 1.1 2003/03/25 18:26:54 tshiozak Exp $ */
/* $NetBSD: citrus_gbk2k.h,v 1.2 2003/06/25 09:51:43 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
@ -31,6 +31,7 @@
__BEGIN_DECLS
_CITRUS_CTYPE_GETOPS_FUNC(GBK2K);
_CITRUS_STDENC_GETOPS_FUNC(GBK2K);
__END_DECLS
#endif

View File

@ -0,0 +1,111 @@
/* $NetBSD: citrus_iconv_none.c,v 1.1 2003/06/25 09:51:43 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_iconv_none.c,v 1.1 2003/06/25 09:51:43 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "citrus_types.h"
#include "citrus_module.h"
#include "citrus_iconv.h"
#include "citrus_iconv_none.h"
/* ---------------------------------------------------------------------- */
_CITRUS_ICONV_DECLS(iconv_none);
_CITRUS_ICONV_DEF_OPS(iconv_none);
/* ---------------------------------------------------------------------- */
int
_citrus_iconv_none_iconv_getops(struct _citrus_iconv_ops *ops, size_t lenops,
uint32_t expected_version)
{
if (expected_version<_CITRUS_ICONV_ABI_VERSION || lenops<sizeof(*ops))
return (EINVAL);
memcpy(ops, &_citrus_iconv_none_iconv_ops,
sizeof(_citrus_iconv_none_iconv_ops));
return (0);
}
static int
/*ARGSUSED*/
_citrus_iconv_none_iconv_init(struct _citrus_iconv * __restrict ci,
const char * __restrict curdir,
const char * __restrict in,
const char * __restrict out,
const void * __restrict var, size_t lenvar)
{
ci->ci_closure = NULL;
return (0);
}
static void
/*ARGSUSED*/
_citrus_iconv_none_iconv_uninit(struct _citrus_iconv * __restrict ci)
{
}
static int
/*ARGSUSED*/
_citrus_iconv_none_iconv_convert(struct _citrus_iconv * __restrict ci,
const char * __restrict * __restrict in,
size_t * __restrict inbytes,
char * __restrict * __restrict out,
size_t * __restrict outbytes,
u_int32_t flags, size_t * __restrict invalids)
{
int e2big;
size_t len;
len = *inbytes;
e2big = 0;
if (*outbytes<len) {
e2big = 1;
len = *outbytes;
}
memcpy(*out, *in, len);
in += len;
*inbytes -= len;
out+=len;
*outbytes -= len;
*invalids = 0;
if (e2big) {
return (E2BIG);
}
return (0);
}

View File

@ -0,0 +1,36 @@
/* $NetBSD: citrus_iconv_none.h,v 1.1 2003/06/25 09:51:43 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_ICONV_NONE_H_
#define _CITRUS_ICONV_NONE_H_
__BEGIN_DECLS
_CITRUS_ICONV_GETOPS_FUNC(iconv_none);
__END_DECLS
#endif

View File

@ -0,0 +1,533 @@
/* $NetBSD: citrus_iconv_std.c,v 1.1 2003/06/25 09:51:43 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_iconv_std.c,v 1.1 2003/06/25 09:51:43 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include <assert.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/endian.h>
#include <sys/queue.h>
#include "citrus_namespace.h"
#include "citrus_types.h"
#include "citrus_module.h"
#include "citrus_region.h"
#include "citrus_mmap.h"
#include "citrus_iconv.h"
#include "citrus_stdenc.h"
#include "citrus_hash.h"
#include "citrus_mapper.h"
#include "citrus_csmapper.h"
#include "citrus_memstream.h"
#include "citrus_iconv_std.h"
#include "citrus_esdb.h"
/* ---------------------------------------------------------------------- */
_CITRUS_ICONV_DECLS(iconv_std);
_CITRUS_ICONV_DEF_OPS(iconv_std);
/* ---------------------------------------------------------------------- */
int
_citrus_iconv_std_iconv_getops(struct _citrus_iconv_ops *ops, size_t lenops,
u_int32_t expected_version)
{
if (expected_version<_CITRUS_ICONV_ABI_VERSION || lenops<sizeof(*ops))
return (EINVAL);
memcpy(ops, &_citrus_iconv_std_iconv_ops,
sizeof(_citrus_iconv_std_iconv_ops));
return (0);
}
/* ---------------------------------------------------------------------- */
/*
* convenience routines for stdenc.
*/
static __inline void
save_encoding_state(struct _citrus_iconv_std_encoding *se)
{
if (se->se_ps)
memcpy(se->se_pssaved, se->se_ps,
_stdenc_get_state_size(se->se_handle));
}
static __inline void
restore_encoding_state(struct _citrus_iconv_std_encoding *se)
{
if (se->se_ps)
memcpy(se->se_ps, se->se_pssaved,
_stdenc_get_state_size(se->se_handle));
}
static __inline void
init_encoding_state(struct _citrus_iconv_std_encoding *se)
{
if (se->se_ps)
_stdenc_init_state(se->se_handle, se->se_ps);
}
static __inline int
mbtocsx(struct _citrus_iconv_std_encoding *se,
_csid_t *csid, _index_t *idx, const char **s, size_t n,
size_t *nresult)
{
return _stdenc_mbtocs(se->se_handle, csid, idx, s, n, se->se_ps,
nresult);
}
static __inline int
cstombx(struct _citrus_iconv_std_encoding *se,
char *s, size_t n, _csid_t csid, _index_t idx, size_t *nresult)
{
return _stdenc_cstomb(se->se_handle, s, n, csid, idx, se->se_ps,
nresult);
}
static __inline int
wctombx(struct _citrus_iconv_std_encoding *se,
char *s, size_t n, _wc_t wc, size_t *nresult)
{
return _stdenc_wctomb(se->se_handle, s, n, wc, se->se_ps, nresult);
}
/*
* open/close an encoding.
*/
static __inline void
close_encoding(struct _citrus_iconv_std_encoding *se)
{
free(se->se_ps); se->se_ps = NULL;
free(se->se_pssaved); se->se_pssaved = NULL;
}
static __inline int
open_encoding(struct _citrus_iconv_std_encoding *se, struct _esdb *db)
{
int ret;
se->se_ps = se->se_pssaved = NULL;
ret = _stdenc_open(&se->se_handle, db->db_encname,
db->db_variable, db->db_len_variable);
if (ret)
return ret;
if (_stdenc_get_state_size(se->se_handle) == 0)
return 0;
se->se_ps = malloc(_stdenc_get_state_size(se->se_handle));
if (se->se_ps == NULL) {
ret = errno;
goto err;
}
ret = _stdenc_init_state(se->se_handle, se->se_ps);
if (ret)
goto err;
se->se_pssaved = malloc(_stdenc_get_state_size(se->se_handle));
if (se->se_pssaved == NULL) {
ret = errno;
goto err;
}
ret = _stdenc_init_state(se->se_handle, se->se_pssaved);
if (ret)
goto err;
return 0;
err:
close_encoding(se);
return ret;
}
static int
open_csmapper(struct _csmapper **rcm, const char *src, const char *dst,
unsigned long *rnorm)
{
int ret;
struct _csmapper *cm;
ret = _csmapper_open(&cm, src, dst, 0, rnorm);
if (ret)
return ret;
if (_csmapper_get_src_max(cm) != 1 || _csmapper_get_dst_max(cm) != 1 ||
_csmapper_get_state_size(cm) != 0) {
_csmapper_close(cm);
return EINVAL;
}
*rcm = cm;
return 0;
}
static void
close_dsts(struct _citrus_iconv_std_dst_list *dl)
{
struct _citrus_iconv_std_dst *sd;
while ((sd=TAILQ_FIRST(dl)) != NULL) {
TAILQ_REMOVE(dl, sd, sd_entry);
_csmapper_close(sd->sd_mapper);
free(sd);
}
}
static int
open_dsts(struct _citrus_iconv_std_dst_list *dl,
struct _esdb_charset *ec, struct _esdb *dbdst)
{
int i, ret;
struct _citrus_iconv_std_dst *sd, *sdtmp;
unsigned long norm;
sd = malloc(sizeof(*sd));
if (sd == NULL)
return errno;
for (i=0; i<dbdst->db_num_charsets; i++) {
ret = open_csmapper(&sd->sd_mapper,ec->ec_csname,
dbdst->db_charsets[i].ec_csname, &norm);
if (ret == 0) {
sd->sd_csid = dbdst->db_charsets[i].ec_csid;
sd->sd_norm = norm;
/* insert this mapper by sorted order. */
TAILQ_FOREACH(sdtmp, dl, sd_entry) {
if (sdtmp->sd_norm > norm) {
TAILQ_INSERT_BEFORE(sdtmp, sd,
sd_entry);
sd = NULL;
break;
}
}
if (sd)
TAILQ_INSERT_TAIL(dl, sd, sd_entry);
sd = malloc(sizeof(*sd));
if (sd == NULL) {
ret = errno;
close_dsts(dl);
return ret;
}
} else if (ret != ENOENT) {
close_dsts(dl);
free(sd);
return ret;
}
}
free(sd);
return 0;
}
static void
close_srcs(struct _citrus_iconv_std_src_list *sl)
{
struct _citrus_iconv_std_src *ss;
while ((ss=TAILQ_FIRST(sl)) != NULL) {
TAILQ_REMOVE(sl, ss, ss_entry);
close_dsts(&ss->ss_dsts);
free(ss);
}
}
static int
open_srcs(struct _citrus_iconv_std_src_list *sl,
struct _esdb *dbsrc, struct _esdb *dbdst)
{
int i, ret, count = 0;
struct _citrus_iconv_std_src *ss;
ss = malloc(sizeof(*ss));
if (ss == NULL)
return errno;
TAILQ_INIT(&ss->ss_dsts);
for (i=0; i<dbsrc->db_num_charsets; i++) {
ret = open_dsts(&ss->ss_dsts, &dbsrc->db_charsets[i], dbdst);
if (ret)
goto err;
if (!TAILQ_EMPTY(&ss->ss_dsts)) {
ss->ss_csid = dbsrc->db_charsets[i].ec_csid;
TAILQ_INSERT_TAIL(sl, ss, ss_entry);
ss = malloc(sizeof(*ss));
if (ss == NULL) {
ret = errno;
goto err;
}
count++;
TAILQ_INIT(&ss->ss_dsts);
}
}
free(ss);
return count ? 0 : ENOENT;
err:
free(ss);
close_srcs(sl);
return ret;
}
/* do convert a character */
#define E_NO_CORRESPONDING_CHAR ENOENT /* XXX */
static int
do_conv(struct _citrus_iconv_std *is, _csid_t *csid, _index_t *idx)
{
_index_t tmpidx;
int ret;
struct _citrus_iconv_std_src *ss;
struct _citrus_iconv_std_dst *sd;
TAILQ_FOREACH(ss, &is->is_srcs, ss_entry) {
if (ss->ss_csid == *csid) {
TAILQ_FOREACH(sd, &ss->ss_dsts, sd_entry) {
ret = _csmapper_convert(sd->sd_mapper,
&tmpidx, *idx, NULL);
switch (ret) {
case _CITRUS_MAPPER_CONVERT_SUCCESS:
*csid = sd->sd_csid;
*idx = tmpidx;
return 0;
case _CITRUS_MAPPER_CONVERT_INVAL:
break;
case _CITRUS_MAPPER_CONVERT_SRC_MORE:
/*FALLTHROUGH*/
case _CITRUS_MAPPER_CONVERT_DST_MORE:
/*FALLTHROUGH*/
case _CITRUS_MAPPER_CONVERT_FATAL:
return EINVAL;
case _CITRUS_MAPPER_CONVERT_ILSEQ:
return EILSEQ;
}
}
break;
}
}
return E_NO_CORRESPONDING_CHAR;
}
/* ---------------------------------------------------------------------- */
static int
/*ARGSUSED*/
_citrus_iconv_std_iconv_init(struct _citrus_iconv *ci,
const char * __restrict curdir,
const char * __restrict src,
const char * __restrict dst,
const void * __restrict var, size_t lenvar)
{
int ret;
struct _citrus_iconv_std *is;
struct _citrus_esdb esdbsrc, esdbdst;
is = malloc(sizeof(*is));
if (is==NULL) {
ret = errno;
goto err0;
}
ret = _citrus_esdb_open(&esdbsrc, src);
if (ret)
goto err1;
ret = _citrus_esdb_open(&esdbdst, dst);
if (ret)
goto err2;
ret = open_encoding(&is->is_src_encoding, &esdbsrc);
if (ret)
goto err3;
ret = open_encoding(&is->is_dst_encoding, &esdbdst);
if (ret)
goto err4;
is->is_use_invalid = esdbdst.db_use_invalid;
is->is_invalid = esdbdst.db_invalid;
TAILQ_INIT(&is->is_srcs);
ret = open_srcs(&is->is_srcs, &esdbsrc, &esdbdst);
if (ret)
goto err5;
_esdb_close(&esdbsrc);
_esdb_close(&esdbdst);
ci->ci_closure = is;
return 0;
err5:
close_encoding(&is->is_dst_encoding);
err4:
close_encoding(&is->is_src_encoding);
err3:
_esdb_close(&esdbdst);
err2:
_esdb_close(&esdbsrc);
err1:
free(is);
err0:
return ret;
}
static void
/*ARGSUSED*/
_citrus_iconv_std_iconv_uninit(struct _citrus_iconv *ci)
{
struct _citrus_iconv_std *is;
if (ci->ci_closure == NULL)
return;
is = ci->ci_closure;
close_encoding(&is->is_src_encoding);
close_encoding(&is->is_dst_encoding);
close_srcs(&is->is_srcs);
free(is);
}
static int
/*ARGSUSED*/
_citrus_iconv_std_iconv_convert(struct _citrus_iconv * __restrict ci,
const char * __restrict * __restrict in,
size_t * __restrict inbytes,
char * __restrict * __restrict out,
size_t * __restrict outbytes, u_int32_t flags,
size_t * __restrict invalids)
{
struct _citrus_iconv_std *is = ci->ci_closure;
_index_t idx;
_csid_t csid;
int ret;
size_t szrin, szrout;
size_t inval;
const char *tmpin;
inval = 0;
if (in==NULL || *in==NULL) {
/* special cases */
if (out!=NULL && *out!=NULL) {
/* init output state */
save_encoding_state(&is->is_src_encoding);
save_encoding_state(&is->is_dst_encoding);
szrout = 0;
ret = cstombx(&is->is_dst_encoding,
*out, *outbytes,
_CITRUS_CSID_INVALID,
0, &szrout);
if (ret)
goto err;
if (szrout == (size_t)-2) {
/* too small to store the character */
ret = EINVAL;
goto err;
}
*out += szrout;
*outbytes -= szrout;
}
*invalids = 0;
init_encoding_state(&is->is_src_encoding);
return 0;
}
/* normal case */
for (;;) {
/* save the encoding states for the error recovery */
save_encoding_state(&is->is_src_encoding);
save_encoding_state(&is->is_dst_encoding);
/* mb -> csid/index */
tmpin = *in;
szrin = szrout = 0;
ret = mbtocsx(&is->is_src_encoding, &csid, &idx,
&tmpin, *inbytes, &szrin);
if (ret)
goto err;
if (szrin == (size_t)-2) {
/* incompleted character */
ret = EINVAL;
goto err;
}
/* convert the character */
ret = do_conv(is, &csid, &idx);
if (ret) {
if (ret == E_NO_CORRESPONDING_CHAR) {
inval ++;
if ((flags&_CITRUS_ICONV_F_HIDE_INVALID)==0 &&
is->is_use_invalid) {
ret = wctombx(&is->is_dst_encoding,
*out, *outbytes,
is->is_invalid,
&szrout);
if (ret)
goto err;
}
goto next;
} else {
goto err;
}
}
/* csid/index -> mb */
ret = cstombx(&is->is_dst_encoding,
*out, *outbytes, csid, idx, &szrout);
if (ret)
goto err;
next:
_DIAGASSERT(*inbytes>=szrin && *outbytes>=szrout);
*inbytes -= tmpin-*in; /* szrin is insufficient on \0. */
*in = tmpin;
*outbytes -= szrout;
*out += szrout;
if (*inbytes==0)
break;
if (*outbytes == 0) {
ret = E2BIG;
goto err_norestore;
}
}
*invalids = inval;
return 0;
err:
restore_encoding_state(&is->is_src_encoding);
restore_encoding_state(&is->is_dst_encoding);
err_norestore:
*invalids = inval;
return ret;
}

View File

@ -0,0 +1,36 @@
/* $NetBSD: citrus_iconv_std.h,v 1.1 2003/06/25 09:51:44 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_ICONV_STD_H_
#define _CITRUS_ICONV_STD_H_
#include "citrus_iconv_std_local.h"
_CITRUS_ICONV_GETOPS_FUNC(iconv_std);
#endif

View File

@ -0,0 +1,73 @@
/* $NetBSD: citrus_iconv_std_local.h,v 1.1 2003/06/25 09:51:44 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_ICONV_STD_LOCAL_H_
#define _CITRUS_ICONV_STD_LOCAL_H_
/*
* encoding
*/
struct _citrus_iconv_std_encoding {
struct _citrus_stdenc *se_handle;
void *se_ps;
void *se_pssaved;
};
/*
* dst
*/
struct _citrus_iconv_std_dst {
TAILQ_ENTRY(_citrus_iconv_std_dst) sd_entry;
_citrus_csid_t sd_csid;
unsigned long sd_norm;
struct _citrus_csmapper *sd_mapper;
};
TAILQ_HEAD(_citrus_iconv_std_dst_list, _citrus_iconv_std_dst);
/*
* src
*/
struct _citrus_iconv_std_src {
TAILQ_ENTRY(_citrus_iconv_std_src) ss_entry;
_citrus_csid_t ss_csid;
struct _citrus_iconv_std_dst_list ss_dsts;
};
TAILQ_HEAD(_citrus_iconv_std_src_list, _citrus_iconv_std_src);
/*
* iconv_std handle
*/
struct _citrus_iconv_std {
struct _citrus_iconv_std_encoding is_src_encoding;
struct _citrus_iconv_std_encoding is_dst_encoding;
struct _citrus_iconv_std_src_list is_srcs;
int is_use_invalid;
_citrus_wc_t is_invalid;
};
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: citrus_iso2022.c,v 1.6 2002/03/28 10:53:49 yamt Exp $ */
/* $NetBSD: citrus_iso2022.c,v 1.7 2003/06/25 09:51:44 tshiozak Exp $ */
/*-
* Copyright (c)1999, 2002 Citrus Project,
@ -30,7 +30,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_iso2022.c,v 1.6 2002/03/28 10:53:49 yamt Exp $");
__RCSID("$NetBSD: citrus_iso2022.c,v 1.7 2003/06/25 09:51:44 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include <assert.h>
@ -43,8 +43,12 @@ __RCSID("$NetBSD: citrus_iso2022.c,v 1.6 2002/03/28 10:53:49 yamt Exp $");
#include <wchar.h>
#include <sys/types.h>
#include <limits.h>
#include "citrus_namespace.h"
#include "citrus_types.h"
#include "citrus_module.h"
#include "citrus_ctype.h"
#include "citrus_stdenc.h"
#include "citrus_iso2022.h"
@ -364,13 +368,13 @@ _citrus_ISO2022_parse_variable(_ISO2022EncodingInfo * __restrict ei,
e = v;
while (*e && *e != ' ' && *e != '\t')
++e;
if (*e) {
len = e-v;
if (len>=sizeof(buf))
goto parsefail;
sprintf(buf, "%.*s", len, v);
++e;
}
len = e-v;
if (len == 0)
break;
if (len>=sizeof(buf))
goto parsefail;
sprintf(buf, "%.*s", len, v);
if ((ret = get_recommend(ei, buf)) != _NOTMATCH)
;
@ -441,8 +445,9 @@ _citrus_ISO2022_unpack_state(_ISO2022EncodingInfo * __restrict ei,
static int
/*ARGSUSED*/
_citrus_ISO2022_stdencoding_init(_ISO2022EncodingInfo * __restrict ei,
const void * __restrict var, size_t lenvar)
_citrus_ISO2022_encoding_module_init(_ISO2022EncodingInfo * __restrict ei,
const void * __restrict var,
size_t lenvar)
{
_DIAGASSERT(ei != NULL);
@ -452,7 +457,7 @@ _citrus_ISO2022_stdencoding_init(_ISO2022EncodingInfo * __restrict ei,
static void
/*ARGSUSED*/
_citrus_ISO2022_stdencoding_uninit(_ISO2022EncodingInfo *ei)
_citrus_ISO2022_encoding_module_uninit(_ISO2022EncodingInfo *ei)
{
}
@ -996,7 +1001,7 @@ recommendation(_ISO2022EncodingInfo * __restrict ei,
}
static int
_ISO2022_sputwchar(_ISO2022EncodingInfo * __restrict ei, wchar_t c,
_ISO2022_sputwchar(_ISO2022EncodingInfo * __restrict ei, wchar_t wc,
char * __restrict string, size_t n,
char ** __restrict result,
_ISO2022State * __restrict psenc)
@ -1014,13 +1019,13 @@ _ISO2022_sputwchar(_ISO2022EncodingInfo * __restrict ei, wchar_t c,
/* result may be NULL */
/* state appears to be unused */
if (iscntl(c & 0xff)) {
if (iscntl(wc & 0xff)) {
/* go back to ASCII on control chars */
cs.type = CS94;
cs.final = 'B';
cs.interm = '\0';
} else if (!(c & ~0xff)) {
if (c & 0x80) {
} else if (!(wc & ~0xff)) {
if (wc & 0x80) {
/* special treatment for ISO-8859-1 */
cs.type = CS96;
cs.final = 'A';
@ -1032,15 +1037,15 @@ _ISO2022_sputwchar(_ISO2022EncodingInfo * __restrict ei, wchar_t c,
cs.interm = '\0';
}
} else {
cs.final = (c >> 24) & 0x7f;
if ((c >> 16) & 0x80)
cs.interm = (c >> 16) & 0x7f;
cs.final = (wc >> 24) & 0x7f;
if ((wc >> 16) & 0x80)
cs.interm = (wc >> 16) & 0x7f;
else
cs.interm = '\0';
if (c & 0x80)
cs.type = (c & 0x00007f00) ? CS96MULTI : CS96;
if (wc & 0x80)
cs.type = (wc & 0x00007f00) ? CS96MULTI : CS96;
else
cs.type = (c & 0x00007f00) ? CS94MULTI : CS94;
cs.type = (wc & 0x00007f00) ? CS94MULTI : CS94;
}
target = recommendation(ei, &cs);
p = tmp;
@ -1071,7 +1076,6 @@ _ISO2022_sputwchar(_ISO2022EncodingInfo * __restrict ei, wchar_t c,
psenc->g[target].interm = cs.interm;
planeok:
/* invoke the plane onto GL or GR. */
if (psenc->gl == target)
goto sideok;
@ -1146,8 +1150,9 @@ sideok:
i = isthree(cs.final) ? 3 : 2;
break;
}
while (i-- > 0)
*p++ = ((c >> (i << 3)) & 0x7f) | mask;
if (wc != 0)
while (i-- > 0)
*p++ = ((wc >> (i << 3)) & 0x7f) | mask;
/* reset single shift state */
psenc->singlegl = psenc->singlegr = -1;
@ -1172,7 +1177,7 @@ _citrus_ISO2022_wcrtomb_priv(_ISO2022EncodingInfo * __restrict ei,
{
char buf[MB_LEN_MAX];
char *result;
int len;
int len, ret;
_DIAGASSERT(ei != NULL);
_DIAGASSERT(nresult != 0);
@ -1182,17 +1187,62 @@ _citrus_ISO2022_wcrtomb_priv(_ISO2022EncodingInfo * __restrict ei,
len = _ISO2022_sputwchar(ei, wc, buf, sizeof(buf), &result, psenc);
if (sizeof(buf) < len || n < len) {
/* XXX should recover state? */
goto ilseq;
ret = E2BIG;
goto err;
}
memcpy(s, buf, len);
*nresult = (size_t)len;
return (0);
ilseq:
err:
/* bound check failure */
*nresult = (size_t)-1;
return (EILSEQ);
return ret;
}
static __inline int
/*ARGSUSED*/
_citrus_ISO2022_stdenc_wctocs(_ISO2022EncodingInfo * __restrict ei,
_csid_t * __restrict csid,
_index_t * __restrict idx, wchar_t wc)
{
wchar_t m, nm;
_DIAGASSERT(csid != NULL && idx != NULL);
m = wc & 0x7FFF8080;
nm = wc & 0x007F7F7F;
if (m & 0x00800000) {
nm &= 0x00007F7F;
} else {
m &= 0x7F008080;
}
if (nm & 0x007F0000) {
/* ^3 mark */
m |= 0x007F0000;
} else if (nm & 0x00007F00) {
/* ^2 mark */
m |= 0x00007F00;
}
*csid = (_csid_t)m;
*idx = (_index_t)nm;
return (0);
}
static __inline int
/*ARGSUSED*/
_citrus_ISO2022_stdenc_cstowc(_ISO2022EncodingInfo * __restrict ei,
wchar_t * __restrict wc,
_csid_t csid, _index_t idx)
{
_DIAGASSERT(ei != NULL && wc != NULL);
*wc = (wchar_t)(csid & 0x7F808080) | (wchar_t)idx;
return (0);
}
/* ----------------------------------------------------------------------
@ -1203,3 +1253,12 @@ _CITRUS_CTYPE_DECLS(ISO2022);
_CITRUS_CTYPE_DEF_OPS(ISO2022);
#include "citrus_ctype_template.h"
/* ----------------------------------------------------------------------
* public interface for stdenc
*/
_CITRUS_STDENC_DECLS(ISO2022);
_CITRUS_STDENC_DEF_OPS(ISO2022);
#include "citrus_stdenc_template.h"

View File

@ -1,4 +1,4 @@
/* $NetBSD: citrus_iso2022.h,v 1.1 2002/03/17 22:14:23 tshiozak Exp $ */
/* $NetBSD: citrus_iso2022.h,v 1.2 2003/06/25 09:51:44 tshiozak Exp $ */
/*-
* Copyright (c)2002 Citrus Project,
@ -31,6 +31,7 @@
__BEGIN_DECLS
_CITRUS_CTYPE_GETOPS_FUNC(ISO2022);
_CITRUS_STDENC_GETOPS_FUNC(ISO2022);
__END_DECLS
#endif

View File

@ -0,0 +1,257 @@
/* $NetBSD: citrus_mapper_646.c,v 1.1 2003/06/25 09:51:45 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_mapper_646.c,v 1.1 2003/06/25 09:51:45 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include "citrus_namespace.h"
#include "citrus_types.h"
#include "citrus_bcs.h"
#include "citrus_module.h"
#include "citrus_region.h"
#include "citrus_memstream.h"
#include "citrus_mmap.h"
#include "citrus_hash.h"
#include "citrus_mapper.h"
#include "citrus_mapper_646.h"
/* ---------------------------------------------------------------------- */
_CITRUS_MAPPER_DECLS(mapper_646);
_CITRUS_MAPPER_DEF_OPS(mapper_646);
/* ---------------------------------------------------------------------- */
#define INVALID 0xFFFFFFFF
#define SPECIALS(x) \
x(0x23) \
x(0x24) \
x(0x40) \
x(0x5B) \
x(0x5C) \
x(0x5D) \
x(0x5E) \
x(0x60) \
x(0x7B) \
x(0x7C) \
x(0x7D) \
x(0x7E)
#define INDEX(x) INDEX_##x,
enum {
SPECIALS(INDEX)
NUM_OF_SPECIALS
};
struct _citrus_mapper_646 {
int m6_forward;
_index_t m6_map[NUM_OF_SPECIALS];
};
int
_citrus_mapper_646_mapper_getops(struct _citrus_mapper_ops *ops,
size_t lenops, uint32_t expected_version)
{
if (expected_version<_CITRUS_MAPPER_ABI_VERSION || lenops<sizeof(*ops))
return EINVAL;
memcpy(ops, &_citrus_mapper_646_mapper_ops,
sizeof(_citrus_mapper_646_mapper_ops));
return 0;
}
#define T_COMM '#'
static int
parse_file(struct _citrus_mapper_646 *m6, const char *path)
{
int ret, i;
struct _region r;
struct _memstream ms;
const char *p;
size_t len;
char buf[PATH_MAX];
ret = _map_file(&r, path);
if (ret)
return ret;
_memstream_bind(&ms, &r);
for (i=0; i<NUM_OF_SPECIALS; i++) {
retry:
p = _memstream_getln(&ms, &len);
if (p==NULL) {
ret = EINVAL;
break;
}
p = _bcs_skip_ws_len(p, &len);
if (*p == T_COMM || len==0)
goto retry;
if (!_bcs_isdigit(*p)) {
ret = EINVAL;
break;
}
snprintf(buf, sizeof(buf), "%.*s", (int)len, p);
m6->m6_map[i] = strtoul(buf, (char **)&p, 0);
p = _bcs_skip_ws(buf);
if (*p != T_COMM && !*p) {
ret = EINVAL;
break;
}
}
_unmap_file(&r);
return ret;
};
static int
parse_var(struct _citrus_mapper_646 *m6, struct _memstream *ms,
const char *dir)
{
struct _region r;
char path[PATH_MAX];
m6->m6_forward = 1;
_memstream_skip_ws(ms);
/* whether backward */
if (_memstream_peek(ms) == '!') {
_memstream_getc(ms);
m6->m6_forward = 0;
}
/* get description file path */
_memstream_getregion(ms, &r, _memstream_remainder(ms));
snprintf(path, sizeof(path), "%s/%.*s",
dir, (int)_region_size(&r), (char *)_region_head(&r));
/* remove trailing white spaces */
path[_bcs_skip_nonws(path)-path] = '\0';
return parse_file(m6, path);
}
static int
/*ARGSUSED*/
_citrus_mapper_646_mapper_init(struct _citrus_mapper_area *__restrict ma,
struct _citrus_mapper * __restrict cm,
const char * __restrict dir,
const void * __restrict var, size_t lenvar,
struct _citrus_mapper_traits * __restrict mt,
size_t lenmt)
{
struct _citrus_mapper_646 *m6;
struct _memstream ms;
struct _region r;
int ret;
_DIAGASSERT(cm && dir && mt);
if (lenmt<sizeof(*mt))
return EINVAL;
m6 = malloc(sizeof(*m6));
if (m6 == NULL)
return errno;
_region_init(&r, (void *)var, lenvar);
_memstream_bind(&ms, &r);
ret = parse_var(m6, &ms, dir);
if (ret) {
free(m6);
return ret;
}
cm->cm_closure = m6;
mt->mt_src_max = mt->mt_dst_max = 1; /* 1:1 converter */
mt->mt_state_size = 0; /* stateless */
return 0;
}
static void
/*ARGSUSED*/
_citrus_mapper_646_mapper_uninit(struct _citrus_mapper *cm)
{
if (cm && cm->cm_closure) {
free(cm->cm_closure);
}
}
static int
/*ARGSUSED*/
_citrus_mapper_646_mapper_convert(struct _citrus_mapper * __restrict cm,
_index_t * __restrict dst, _index_t src,
void * __restrict ps)
{
struct _citrus_mapper_646 *m6;
_DIAGASSERT(cm && cm->cm_closure);
m6 = cm->cm_closure;
if (m6->m6_forward) {
/* forward */
if (src>=0x80)
return _MAPPER_CONVERT_INVAL;
#define FORWARD(x) \
if (src==(x)) { \
if (m6->m6_map[INDEX_##x]==INVALID) \
return _MAPPER_CONVERT_INVAL; \
*dst = m6->m6_map[INDEX_##x]; \
return 0; \
} else
SPECIALS(FORWARD);
*dst = src;
} else {
/* backward */
#define BACKWARD(x) \
if (m6->m6_map[INDEX_##x]!=INVALID && src==m6->m6_map[INDEX_##x]) { \
*dst = (x); \
return 0; \
} else if (src==(x)) \
return _MAPPER_CONVERT_INVAL; \
else
SPECIALS(BACKWARD);
if (src>=0x80)
return _MAPPER_CONVERT_INVAL;
*dst = src;
}
return _MAPPER_CONVERT_SUCCESS;
}
static void
/*ARGSUSED*/
_citrus_mapper_646_mapper_init_state(struct _citrus_mapper * __restrict cm,
void * __restrict ps)
{
}

View File

@ -0,0 +1,37 @@
/* $NetBSD: citrus_mapper_646.h,v 1.1 2003/06/25 09:51:45 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_MAPPER_646_H_
#define _CITRUS_MAPPER_646_H_
__BEGIN_DECLS
_CITRUS_MAPPER_GETOPS_FUNC(mapper_646);
_CITRUS_MAPPER_GETOPS_FUNC(mapper_646);
__END_DECLS
#endif

View File

@ -0,0 +1,110 @@
/* $NetBSD: citrus_mapper_none.c,v 1.1 2003/06/25 09:51:45 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_mapper_none.c,v 1.1 2003/06/25 09:51:45 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "citrus_namespace.h"
#include "citrus_types.h"
#include "citrus_module.h"
#include "citrus_hash.h"
#include "citrus_mapper.h"
#include "citrus_mapper_none.h"
/* ---------------------------------------------------------------------- */
_CITRUS_MAPPER_DECLS(mapper_none);
_CITRUS_MAPPER_DEF_OPS(mapper_none);
/* ---------------------------------------------------------------------- */
int
_citrus_mapper_none_mapper_getops(struct _citrus_mapper_ops *ops,
size_t lenops, uint32_t expected_version)
{
if (expected_version<_CITRUS_MAPPER_ABI_VERSION || lenops<sizeof(*ops))
return (EINVAL);
memcpy(ops, &_citrus_mapper_none_mapper_ops,
sizeof(_citrus_mapper_none_mapper_ops));
return 0;
}
static int
/*ARGSUSED*/
_citrus_mapper_none_mapper_init(struct _citrus_mapper_area *__restrict ma,
struct _citrus_mapper * __restrict cm,
const char * __restrict dir,
const void * __restrict var, size_t lenvar,
struct _citrus_mapper_traits * __restrict mt,
size_t lenmt)
{
_DIAGASSERT(cm && dir && mt);
if (lenmt<sizeof(*mt))
return (EINVAL);
cm->cm_closure = NULL;
mt->mt_src_max = mt->mt_dst_max = 1; /* 1:1 converter */
mt->mt_state_size = 0; /* stateless */
return 0;
}
static void
/*ARGSUSED*/
_citrus_mapper_none_mapper_uninit(struct _citrus_mapper *cm)
{
}
static int
/*ARGSUSED*/
_citrus_mapper_none_mapper_convert(struct _citrus_mapper * __restrict cm,
_citrus_index_t * __restrict dst,
_citrus_index_t src, void * __restrict ps)
{
*dst = src;
return _CITRUS_MAPPER_CONVERT_SUCCESS;
}
static void
/*ARGSUSED*/
_citrus_mapper_none_mapper_init_state(struct _citrus_mapper * __restrict cm,
void * __restrict ps)
{
}

View File

@ -0,0 +1,36 @@
/* $NetBSD: citrus_mapper_none.h,v 1.1 2003/06/25 09:51:45 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_MAPPER_NONE_H_
#define _CITRUS_MAPPER_NONE_H_
__BEGIN_DECLS
_CITRUS_MAPPER_GETOPS_FUNC(mapper_none);
__END_DECLS
#endif

View File

@ -0,0 +1,262 @@
/* $NetBSD: citrus_mapper_serial.c,v 1.1 2003/06/25 09:51:46 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_mapper_serial.c,v 1.1 2003/06/25 09:51:46 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <sys/queue.h>
#include "citrus_namespace.h"
#include "citrus_types.h"
#include "citrus_bcs.h"
#include "citrus_module.h"
#include "citrus_region.h"
#include "citrus_memstream.h"
#include "citrus_mmap.h"
#include "citrus_hash.h"
#include "citrus_mapper.h"
#include "citrus_mapper_serial.h"
/* ---------------------------------------------------------------------- */
_CITRUS_MAPPER_DECLS(mapper_serial);
_CITRUS_MAPPER_DEF_OPS(mapper_serial);
#define _citrus_mapper_parallel_mapper_init \
_citrus_mapper_serial_mapper_init
#define _citrus_mapper_parallel_mapper_uninit \
_citrus_mapper_serial_mapper_uninit
#define _citrus_mapper_parallel_mapper_init_state \
_citrus_mapper_serial_mapper_init_state
static int _citrus_mapper_parallel_mapper_convert(
struct _citrus_mapper * __restrict, _index_t * __restrict, _index_t,
void * __restrict);
_CITRUS_MAPPER_DEF_OPS(mapper_parallel);
#undef _citrus_mapper_parallel_mapper_init
#undef _citrus_mapper_parallel_mapper_uninit
#undef _citrus_mapper_parallel_mapper_init_state
/* ---------------------------------------------------------------------- */
struct maplink {
SIMPLEQ_ENTRY(maplink) ml_entry;
struct _mapper *ml_mapper;
};
SIMPLEQ_HEAD(maplist, maplink);
struct _citrus_mapper_serial {
struct maplist sr_mappers;
};
int
_citrus_mapper_serial_mapper_getops(struct _citrus_mapper_ops *ops,
size_t lenops, uint32_t expected_version)
{
if (expected_version<_CITRUS_MAPPER_ABI_VERSION || lenops<sizeof(*ops))
return EINVAL;
memcpy(ops, &_citrus_mapper_serial_mapper_ops,
sizeof(_citrus_mapper_serial_mapper_ops));
return 0;
}
int
_citrus_mapper_parallel_mapper_getops(struct _citrus_mapper_ops *ops,
size_t lenops, uint32_t expected_version)
{
if (expected_version<_CITRUS_MAPPER_ABI_VERSION || lenops<sizeof(*ops))
return EINVAL;
memcpy(ops, &_citrus_mapper_parallel_mapper_ops,
sizeof(_citrus_mapper_parallel_mapper_ops));
return 0;
}
static void
uninit(struct _citrus_mapper_serial *sr)
{
struct maplink *ml;
while ((ml = SIMPLEQ_FIRST(&sr->sr_mappers)) != NULL) {
SIMPLEQ_REMOVE_HEAD(&sr->sr_mappers, ml_entry);
_mapper_close(ml->ml_mapper);
free(ml);
}
}
static int
parse_var(struct _citrus_mapper_area *__restrict ma,
struct _citrus_mapper_serial *sr, struct _memstream *ms)
{
int ret;
struct _region r;
char mapname[PATH_MAX];
struct maplink *ml;
SIMPLEQ_INIT(&sr->sr_mappers);
while (1) {
/* remove beginning white spaces */
_memstream_skip_ws(ms);
if (_memstream_iseof(ms))
break;
/* cut down a mapper name */
_memstream_chr(ms, &r, ',');
snprintf(mapname, sizeof(mapname), "%.*s",
(int)_region_size(&r), (char *)_region_head(&r));
/* remove trailing white spaces */
mapname[_bcs_skip_nonws(mapname)-mapname] = '\0';
/* create a new mapper record */
ml = malloc(sizeof(*ml));
if (ml == NULL)
return errno;
ret = _mapper_open(ma, &ml->ml_mapper, mapname);
if (ret) {
free(ml);
return ret;
}
/* support only 1:1 and stateless converter */
if (_mapper_get_src_max(ml->ml_mapper) != 1 ||
_mapper_get_dst_max(ml->ml_mapper) != 1 ||
_mapper_get_state_size(ml->ml_mapper) != 0) {
free(ml);
return EINVAL;
}
SIMPLEQ_INSERT_TAIL(&sr->sr_mappers, ml, ml_entry);
}
return 0;
}
static int
/*ARGSUSED*/
_citrus_mapper_serial_mapper_init(struct _citrus_mapper_area *__restrict ma,
struct _citrus_mapper * __restrict cm,
const char * __restrict dir,
const void * __restrict var, size_t lenvar,
struct _citrus_mapper_traits * __restrict mt,
size_t lenmt)
{
struct _citrus_mapper_serial *sr;
struct _memstream ms;
struct _region r;
_DIAGASSERT(cm && dir && mt);
if (lenmt<sizeof(*mt))
return EINVAL;
sr = malloc(sizeof(*sr));
if (sr == NULL)
return errno;
_region_init(&r, (void *)var, lenvar);
_memstream_bind(&ms, &r);
if (parse_var(ma, sr, &ms)) {
uninit(sr);
free(sr);
return EINVAL;
}
cm->cm_closure = sr;
mt->mt_src_max = mt->mt_dst_max = 1; /* 1:1 converter */
mt->mt_state_size = 0; /* stateless */
return 0;
}
static void
/*ARGSUSED*/
_citrus_mapper_serial_mapper_uninit(struct _citrus_mapper *cm)
{
if (cm && cm->cm_closure) {
uninit(cm->cm_closure);
free(cm->cm_closure);
}
}
static int
/*ARGSUSED*/
_citrus_mapper_serial_mapper_convert(struct _citrus_mapper * __restrict cm,
_index_t * __restrict dst, _index_t src,
void * __restrict ps)
{
int ret;
struct _citrus_mapper_serial *sr;
struct maplink *ml;
_DIAGASSERT(cm && cm->cm_closure);
sr = cm->cm_closure;
SIMPLEQ_FOREACH(ml, &sr->sr_mappers, ml_entry) {
ret = _mapper_convert(ml->ml_mapper, &src, src, NULL);
if (ret != _MAPPER_CONVERT_SUCCESS)
return ret;
}
*dst = src;
return _MAPPER_CONVERT_SUCCESS;
}
static int
/*ARGSUSED*/
_citrus_mapper_parallel_mapper_convert(struct _citrus_mapper * __restrict cm,
_index_t * __restrict dst, _index_t src,
void * __restrict ps)
{
int ret;
struct _citrus_mapper_serial *sr;
struct maplink *ml;
_index_t tmp;
_DIAGASSERT(cm && cm->cm_closure);
sr = cm->cm_closure;
SIMPLEQ_FOREACH(ml, &sr->sr_mappers, ml_entry) {
ret = _mapper_convert(ml->ml_mapper, &tmp, src, NULL);
if (ret == _MAPPER_CONVERT_SUCCESS) {
*dst = tmp;
return _MAPPER_CONVERT_SUCCESS;
}
}
return _MAPPER_CONVERT_INVAL;
}
static void
/*ARGSUSED*/
_citrus_mapper_serial_mapper_init_state(struct _citrus_mapper * __restrict cm,
void * __restrict ps)
{
}

View File

@ -0,0 +1,37 @@
/* $NetBSD: citrus_mapper_serial.h,v 1.1 2003/06/25 09:51:46 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_MAPPER_SERIAL_H_
#define _CITRUS_MAPPER_SERIAL_H_
__BEGIN_DECLS
_CITRUS_MAPPER_GETOPS_FUNC(mapper_serial);
_CITRUS_MAPPER_GETOPS_FUNC(mapper_parallel);
__END_DECLS
#endif

View File

@ -0,0 +1,319 @@
/* $NetBSD: citrus_mapper_std.c,v 1.1 2003/06/25 09:51:47 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_mapper_std.c,v 1.1 2003/06/25 09:51:47 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include <assert.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/endian.h>
#include "citrus_namespace.h"
#include "citrus_types.h"
#include "citrus_bcs.h"
#include "citrus_region.h"
#include "citrus_mmap.h"
#include "citrus_module.h"
#include "citrus_hash.h"
#include "citrus_mapper.h"
#include "citrus_db.h"
#include "citrus_db_hash.h"
#include "citrus_mapper_std.h"
#include "citrus_mapper_std_file.h"
/* ---------------------------------------------------------------------- */
_CITRUS_MAPPER_DECLS(mapper_std);
_CITRUS_MAPPER_DEF_OPS(mapper_std);
/* ---------------------------------------------------------------------- */
int
_citrus_mapper_std_mapper_getops(struct _citrus_mapper_ops *ops, size_t lenops,
u_int32_t expected_version)
{
if (expected_version<_CITRUS_MAPPER_ABI_VERSION || lenops<sizeof(*ops))
return (EINVAL);
memcpy(ops, &_citrus_mapper_std_mapper_ops,
sizeof(_citrus_mapper_std_mapper_ops));
return (0);
}
/* ---------------------------------------------------------------------- */
static int
/*ARGSUSED*/
rowcol_convert(struct _citrus_mapper_std * __restrict ms,
_index_t * __restrict dst, _index_t src,
void * __restrict ps)
{
struct _citrus_mapper_std_rowcol *rc = &ms->ms_rowcol;
_index_t row, col, idx;
u_int32_t conv;
if (rc->rc_src_col_bits == 32) {
row = 0;
col = src;
} else {
row = src >> rc->rc_src_col_bits;
col = src & ((1U<<rc->rc_src_col_bits)-1);
}
if (row < rc->rc_src_row_begin || row > rc->rc_src_row_end ||
col < rc->rc_src_col_begin || col > rc->rc_src_col_end) {
*dst = rc->rc_dst_invalid;
return _MAPPER_CONVERT_INVAL;
}
idx =
(row - rc->rc_src_row_begin)*rc->rc_src_col_width +
(col - rc->rc_src_col_begin);
switch (rc->rc_dst_unit_bits) {
case 8:
conv = _region_peek8(&rc->rc_table, idx);
break;
case 16:
conv = be16toh(_region_peek16(&rc->rc_table, idx*2));
break;
case 32:
conv = be32toh(_region_peek32(&rc->rc_table, idx*4));
break;
}
if (conv == rc->rc_dst_invalid) {
*dst = rc->rc_dst_invalid;
return _MAPPER_CONVERT_INVAL;
}
*dst = conv;
return _MAPPER_CONVERT_SUCCESS;
}
static int
rowcol_init(struct _citrus_mapper_std *ms)
{
int ret;
struct _citrus_mapper_std_rowcol *rc = &ms->ms_rowcol;
const struct _citrus_mapper_std_rowcol_info_x *rcx;
struct _region r;
u_int64_t table_size;
ms->ms_convert = &rowcol_convert;
ms->ms_uninit = NULL;
/* get table region */
ret = _db_lookup_by_s(ms->ms_db, _CITRUS_MAPPER_STD_SYM_TABLE,
&rc->rc_table, NULL);
if (ret) {
if (ret==ENOENT)
ret = EFTYPE;
return ret;
}
/* get table information */
ret = _db_lookup_by_s(ms->ms_db, _CITRUS_MAPPER_STD_SYM_INFO, &r, NULL);
if (ret) {
if (ret==ENOENT)
ret =EFTYPE;
return ret;
}
if (_region_size(&r) < sizeof(*rcx))
return EFTYPE;
rcx = _region_head(&r);
/* convert */
#define CONV_ROWCOL(rc, rcx, elem) \
do { \
(rc)->rc_##elem = be32toh((rcx)->rcx_##elem); \
} while (/*CONSTCOND*/0)
CONV_ROWCOL(rc, rcx, src_col_bits);
CONV_ROWCOL(rc, rcx, dst_invalid);
CONV_ROWCOL(rc, rcx, src_row_begin);
CONV_ROWCOL(rc, rcx, src_row_end);
CONV_ROWCOL(rc, rcx, src_col_begin);
CONV_ROWCOL(rc, rcx, src_col_end);
CONV_ROWCOL(rc, rcx, dst_unit_bits);
rc->rc_src_col_width = rc->rc_src_col_end - rc->rc_src_col_begin +1;
/* validation checks */
if (rc->rc_src_col_end < rc->rc_src_col_begin ||
rc->rc_src_row_end < rc->rc_src_row_begin ||
!(rc->rc_dst_unit_bits==8 || rc->rc_dst_unit_bits==16 ||
rc->rc_dst_unit_bits==32) ||
!(rc->rc_src_col_bits >= 0 && rc->rc_src_col_bits <= 32))
return EFTYPE;
/* calcurate expected table size */
table_size = rc->rc_src_row_end - rc->rc_src_row_begin + 1;
table_size *= rc->rc_src_col_width;
table_size *= rc->rc_dst_unit_bits/8;
if (table_size > UINT32_MAX ||
_region_size(&rc->rc_table) < table_size)
return EFTYPE;
return 0;
}
typedef int (*initfunc_t)(struct _citrus_mapper_std *);
static struct {
const char *t_name;
initfunc_t t_init;
} types[] = {
{ _CITRUS_MAPPER_STD_TYPE_ROWCOL, &rowcol_init },
};
#define NUM_OF_TYPES ((int)(sizeof(types)/sizeof(types[0])))
static int
/*ARGSUSED*/
_citrus_mapper_std_mapper_init(struct _citrus_mapper_area *__restrict ma,
struct _citrus_mapper * __restrict cm,
const char * __restrict curdir,
const void * __restrict var, size_t lenvar,
struct _citrus_mapper_traits * __restrict mt,
size_t lenmt)
{
char path[PATH_MAX];
const char *type;
int ret, id;
struct _citrus_mapper_std *ms;
/* set traits */
if (lenmt<sizeof(*mt)) {
ret = EINVAL;
goto err0;
}
mt->mt_src_max = mt->mt_dst_max = 1; /* 1:1 converter */
mt->mt_state_size = 0; /* stateless */
/* alloc mapper std structure */
ms = malloc(sizeof(*ms));
if (ms==NULL) {
ret = errno;
goto err0;
}
/* open mapper file */
snprintf(path, sizeof(path),
"%s/%.*s", curdir, (int)lenvar, (const char *)var);
ret = _map_file(&ms->ms_file, path);
if (ret)
goto err1;
ret = _db_open(&ms->ms_db, &ms->ms_file, _CITRUS_MAPPER_STD_MAGIC,
&_db_hash_std, NULL);
if (ret)
goto err2;
/* get mapper type */
ret = _db_lookupstr_by_s(ms->ms_db, _CITRUS_MAPPER_STD_SYM_TYPE,
&type, NULL);
if (ret) {
if (ret==ENOENT)
ret = EFTYPE;
goto err3;
}
for (id=0; id<NUM_OF_TYPES; id++)
if (_bcs_strcasecmp(type, types[id].t_name) == 0)
break;
if (id == NUM_OF_TYPES)
goto err3;
/* init the per-type structure */
ret = (*types[id].t_init)(ms);
if (ret)
goto err3;
cm->cm_closure = ms;
return 0;
err3:
_db_close(ms->ms_db);
err2:
_unmap_file(&ms->ms_file);
err1:
free(ms);
err0:
return ret;
}
static void
/*ARGSUSED*/
_citrus_mapper_std_mapper_uninit(struct _citrus_mapper *cm)
{
struct _citrus_mapper_std *ms;
_DIAGASSERT(cm!=NULL & cm->cm_closure!=NULL);
ms = cm->cm_closure;
if (ms->ms_uninit)
(*ms->ms_uninit)(ms);
_db_close(ms->ms_db);
_unmap_file(&ms->ms_file);
free(ms);
}
static void
/*ARGSUSED*/
_citrus_mapper_std_mapper_init_state(struct _citrus_mapper * __restrict cm,
void * __restrict ps)
{
}
static int
/*ARGSUSED*/
_citrus_mapper_std_mapper_convert(struct _citrus_mapper * __restrict cm,
_index_t * __restrict dst, _index_t src,
void * __restrict ps)
{
struct _citrus_mapper_std *ms;
_DIAGASSERT(cm!=NULL && cm->cm_closure!=NULL);
ms = cm->cm_closure;
_DIAGASSERT(ms->ms_convert != NULL);
return (*ms->ms_convert)(ms, dst, src, ps);
}

View File

@ -0,0 +1,38 @@
/* $NetBSD: citrus_mapper_std.h,v 1.1 2003/06/25 09:51:47 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_MAPPER_STD_H_
#define _CITRUS_MAPPER_STD_H_
#include "citrus_mapper_std_local.h"
__BEGIN_DECLS
_CITRUS_MAPPER_GETOPS_FUNC(mapper_std);
__END_DECLS
#endif

View File

@ -0,0 +1,51 @@
/* $NetBSD: citrus_mapper_std_file.h,v 1.1 2003/06/25 09:51:47 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_MAPPER_STD_FILE_H_
#define _CITRUS_MAPPER_STD_FILE_H_
#define _CITRUS_MAPPER_STD_MAGIC "MAPPER\0\0"
#define _CITRUS_MAPPER_STD_SYM_TYPE "type"
#define _CITRUS_MAPPER_STD_SYM_INFO "info"
#define _CITRUS_MAPPER_STD_SYM_TABLE "table"
#define _CITRUS_MAPPER_STD_TYPE_ROWCOL "rowcol"
struct _citrus_mapper_std_rowcol_info_x {
u_int32_t rcx_src_col_bits;
u_int32_t rcx_dst_invalid;
u_int32_t rcx_src_row_begin;
u_int32_t rcx_src_row_end;
u_int32_t rcx_src_col_begin;
u_int32_t rcx_src_col_end;
u_int32_t rcx_dst_unit_bits;
u_int32_t rcx_pad;
} __packed;
#define _CITRUS_MAPPER_STD_ROWCOL_INFO_SIZE 32
#endif

View File

@ -0,0 +1,64 @@
/* $NetBSD: citrus_mapper_std_local.h,v 1.1 2003/06/25 09:51:47 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_MAPPER_STD_LOCAL_H_
#define _CITRUS_MAPPER_STD_LOCAL_H_
typedef u_int32_t (*_citrus_mapper_std_getvalfunc_t)(const void *, u_int32_t);
struct _citrus_mapper_std_rowcol {
struct _citrus_region rc_table;
int rc_src_col_bits;
_citrus_index_t rc_dst_invalid;
_citrus_index_t rc_src_row_begin;
_citrus_index_t rc_src_row_end;
_citrus_index_t rc_src_col_begin;
_citrus_index_t rc_src_col_end;
_citrus_index_t rc_src_col_width;
_citrus_index_t rc_dst_unit_bits;
};
struct _citrus_mapper_std;
typedef int (*_citrus_mapper_std_convert_t)(
struct _citrus_mapper_std *__restrict,
_index_t *__restrict, _index_t, void *__restrict);
typedef void (*_citrus_mapper_std_uninit_t)(struct _citrus_mapper_std *);
struct _citrus_mapper_std {
struct _citrus_region ms_file;
struct _citrus_db *ms_db;
_citrus_mapper_std_convert_t ms_convert;
_citrus_mapper_std_uninit_t ms_uninit;
union {
struct _citrus_mapper_std_rowcol rowcol;
} u;
#define ms_rowcol u.rowcol
};
#endif

View File

@ -0,0 +1,394 @@
/* $NetBSD: citrus_mapper_zone.c,v 1.1 2003/06/25 09:51:48 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_mapper_zone.c,v 1.1 2003/06/25 09:51:48 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "citrus_namespace.h"
#include "citrus_types.h"
#include "citrus_bcs.h"
#include "citrus_module.h"
#include "citrus_region.h"
#include "citrus_memstream.h"
#include "citrus_mmap.h"
#include "citrus_hash.h"
#include "citrus_mapper.h"
#include "citrus_mapper_zone.h"
/* ---------------------------------------------------------------------- */
_CITRUS_MAPPER_DECLS(mapper_zone);
_CITRUS_MAPPER_DEF_OPS(mapper_zone);
/* ---------------------------------------------------------------------- */
struct _zone {
u_int32_t z_begin;
u_int32_t z_end;
};
struct _citrus_mapper_zone {
struct _zone mz_row;
struct _zone mz_col;
int mz_col_bits;
int32_t mz_row_offset;
int32_t mz_col_offset;
};
struct _parse_state {
enum { S_BEGIN, S_OFFSET } ps_state;
union {
u_int32_t u_imm;
int32_t s_imm;
struct _zone zone;
} u;
#define ps_u_imm u.u_imm
#define ps_s_imm u.s_imm
#define ps_zone u.zone
int ps_top;
};
int
_citrus_mapper_zone_mapper_getops(struct _citrus_mapper_ops *ops,
size_t lenops, uint32_t expected_version)
{
if (expected_version<_CITRUS_MAPPER_ABI_VERSION || lenops<sizeof(*ops))
return EINVAL;
memcpy(ops, &_citrus_mapper_zone_mapper_ops,
sizeof(_citrus_mapper_zone_mapper_ops));
return 0;
}
#define BUFSIZE 20
#define T_ERR 0x100
#define T_IMM 0x101
static int
get_imm(struct _memstream *ms, struct _parse_state *ps)
{
int sign = 0;
int c, i;
char buf[BUFSIZE+1], *p;
for (i=0; i<BUFSIZE; i++) {
retry:
c = _memstream_peek(ms);
if (i==0) {
if (sign == 0 && (c == '+' || c == '-')) {
sign = c;
_memstream_getc(ms);
goto retry;
} else if (!_bcs_isdigit(c))
break;
} else if (!_bcs_isxdigit(c))
if (!(i==1 && c == 'x'))
break;
buf[i] = _memstream_getc(ms);
}
buf[i] = '\0';
ps->ps_u_imm = strtoul(buf, &p, 0);
if ((p-buf) != i)
return T_ERR;
if (sign == '-')
ps->ps_u_imm = (unsigned long)-(long)ps->ps_u_imm;
return T_IMM;
}
static int
get_tok(struct _memstream *ms, struct _parse_state *ps)
{
int c;
loop:
c = _memstream_peek(ms);
if (c==0x00)
return EOF;
if (_bcs_isspace(c)) {
_memstream_getc(ms);
goto loop;
}
switch (ps->ps_state) {
case S_BEGIN:
switch (c) {
case ':':
case '-':
case '/':
_memstream_getc(ms);
return c;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return get_imm(ms, ps);
}
break;
case S_OFFSET:
switch (c) {
case '/':
_memstream_getc(ms);
return c;
case '+':
case '-':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return get_imm(ms, ps);
}
break;
}
return T_ERR;
}
static int
parse_zone(struct _memstream *ms, struct _parse_state *ps, struct _zone *z)
{
if (get_tok(ms, ps) != T_IMM)
return -1;
z->z_begin = ps->ps_u_imm;
if (get_tok(ms, ps) != '-')
return -1;
if (get_tok(ms, ps) != T_IMM)
return -1;
z->z_end = ps->ps_u_imm;
if (z->z_begin > z->z_end)
return -1;
return 0;
}
static int
check_rowcol(struct _zone *z, int32_t ofs, uint32_t maxval)
{
u_int32_t remain;
if (maxval != 0 && z->z_end >= maxval)
return -1;
if (ofs > 0) {
if (maxval == 0) {
/* this should 0x100000000 - z->z_end */
if (z->z_end == 0) {
remain = 0xFFFFFFFF;
} else {
remain = 0xFFFFFFFF - z->z_end + 1;
}
} else
remain = maxval - z->z_end;
if ((u_int32_t)ofs > remain)
return -1;
} else if (ofs < 0) {
if (z->z_begin < (u_int32_t)-ofs)
return -1;
}
return 0;
}
static int
parse_var(struct _citrus_mapper_zone *mz, struct _memstream *ms)
{
struct _parse_state ps;
int ret, isrc;
uint32_t rowmax, colmax;
ps.ps_state = S_BEGIN;
if (parse_zone(ms, &ps, &mz->mz_col))
return -1;
ret = get_tok(ms, &ps);
if (ret == '/') {
/* rowzone / colzone / bits */
isrc = 1;
mz->mz_row = mz->mz_col;
if (parse_zone(ms, &ps, &mz->mz_col))
return -1;
if (get_tok(ms, &ps) != '/')
return -1;
if (get_tok(ms, &ps) != T_IMM)
return -1;
mz->mz_col_bits = ps.ps_u_imm;
if (mz->mz_col_bits<0 || mz->mz_col_bits>32)
return -1;
ret = get_tok(ms, &ps);
} else {
/* colzone */
isrc = 0;
mz->mz_col_bits = 32;
mz->mz_row.z_begin = mz->mz_row.z_end = 0;
}
if (ret == ':') {
/* offset */
ps.ps_state = S_OFFSET;
if (get_tok(ms, &ps) != T_IMM)
return -1;
mz->mz_col_offset = ps.ps_s_imm;
if (isrc) {
/* row/col */
mz->mz_row_offset = mz->mz_col_offset;
if (get_tok(ms, &ps) != '/')
return -1;
if (get_tok(ms, &ps) != T_IMM)
return -1;
mz->mz_col_offset = ps.ps_s_imm;
} else
mz->mz_row_offset = 0;
ret = get_tok(ms, &ps);
}
if (ret != EOF)
return -1;
/* sanity check */
if (mz->mz_col_bits==32)
colmax = 0;
else
colmax = 1 << mz->mz_col_bits;
if (mz->mz_col_bits==0)
rowmax = 0;
else
rowmax = 1 << (32-mz->mz_col_bits);
if (check_rowcol(&mz->mz_col, mz->mz_col_offset, colmax))
return -1;
if (check_rowcol(&mz->mz_row, mz->mz_row_offset, rowmax))
return -1;
return 0;
}
static int
/*ARGSUSED*/
_citrus_mapper_zone_mapper_init(struct _citrus_mapper_area *__restrict ma,
struct _citrus_mapper * __restrict cm,
const char * __restrict dir,
const void * __restrict var, size_t lenvar,
struct _citrus_mapper_traits * __restrict mt,
size_t lenmt)
{
struct _citrus_mapper_zone *mz;
struct _memstream ms;
struct _region r;
_DIAGASSERT(cm && dir && mt);
if (lenmt<sizeof(*mt))
return EINVAL;
mz = malloc(sizeof(*mz));
if (mz == NULL)
return errno;
_region_init(&r, (void *)var, lenvar);
_memstream_bind(&ms, &r);
if (parse_var(mz, &ms)) {
free(mz);
return EINVAL;
}
cm->cm_closure = mz;
mt->mt_src_max = mt->mt_dst_max = 1; /* 1:1 converter */
mt->mt_state_size = 0; /* stateless */
return 0;
}
static void
/*ARGSUSED*/
_citrus_mapper_zone_mapper_uninit(struct _citrus_mapper *cm)
{
}
static int
/*ARGSUSED*/
_citrus_mapper_zone_mapper_convert(struct _citrus_mapper * __restrict cm,
_citrus_index_t * __restrict dst,
_citrus_index_t src, void * __restrict ps)
{
u_int32_t row, col;
struct _citrus_mapper_zone *mz = cm->cm_closure;
if (mz->mz_col_bits == 32) {
col = src;
row = 0;
if (col < mz->mz_col.z_begin || col > mz->mz_col.z_end)
return _CITRUS_MAPPER_CONVERT_INVAL;
if (mz->mz_col_offset>0)
col += (u_int32_t)mz->mz_col_offset;
else
col -= (u_int32_t)-mz->mz_col_offset;
*dst = col;
} else {
col = src & (((u_int32_t)1<<mz->mz_col_bits)-1);
row = src >> mz->mz_col_bits;
if (row < mz->mz_row.z_begin || row > mz->mz_row.z_end ||
col < mz->mz_col.z_begin || col > mz->mz_col.z_end)
return _CITRUS_MAPPER_CONVERT_INVAL;
if (mz->mz_col_offset>0)
col += (u_int32_t)mz->mz_col_offset;
else
col -= (u_int32_t)-mz->mz_col_offset;
if (mz->mz_row_offset>0)
row += (u_int32_t)mz->mz_row_offset;
else
row -= (u_int32_t)-mz->mz_row_offset;
*dst = col | (row << mz->mz_col_bits);
}
return _CITRUS_MAPPER_CONVERT_SUCCESS;
}
static void
/*ARGSUSED*/
_citrus_mapper_zone_mapper_init_state(struct _citrus_mapper * __restrict cm,
void * __restrict ps)
{
}

View File

@ -0,0 +1,36 @@
/* $NetBSD: citrus_mapper_zone.h,v 1.1 2003/06/25 09:51:48 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_MAPPER_ZONE_H_
#define _CITRUS_MAPPER_ZONE_H_
__BEGIN_DECLS
_CITRUS_MAPPER_GETOPS_FUNC(mapper_zone);
__END_DECLS
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: citrus_mskanji.c,v 1.5 2002/03/28 10:53:49 yamt Exp $ */
/* $NetBSD: citrus_mskanji.c,v 1.6 2003/06/25 09:51:48 tshiozak Exp $ */
/*-
* Copyright (c)2002 Citrus Project,
@ -62,7 +62,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_mskanji.c,v 1.5 2002/03/28 10:53:49 yamt Exp $");
__RCSID("$NetBSD: citrus_mskanji.c,v 1.6 2003/06/25 09:51:48 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include <assert.h>
@ -75,8 +75,12 @@ __RCSID("$NetBSD: citrus_mskanji.c,v 1.5 2002/03/28 10:53:49 yamt Exp $");
#include <wchar.h>
#include <sys/types.h>
#include <limits.h>
#include "citrus_namespace.h"
#include "citrus_types.h"
#include "citrus_module.h"
#include "citrus_ctype.h"
#include "citrus_stdenc.h"
#include "citrus_mskanji.h"
@ -265,45 +269,167 @@ _citrus_MSKanji_wcrtomb_priv(_MSKanjiEncodingInfo * __restrict ei,
_MSKanjiState * __restrict psenc,
size_t * __restrict nresult)
{
int ret;
_DIAGASSERT(ei != NULL);
_DIAGASSERT(psenc != NULL);
_DIAGASSERT(s != NULL);
/* reset state */
if (wc == 0) {
*nresult = 0; /* stateless */
return 0;
}
/* check invalid sequence */
if (wc & ~0xffff)
goto ilseq;
if (wc & ~0xffff) {
ret = EILSEQ;
goto err;
}
if (wc & 0xff00) {
if (n < 2)
goto ilseq;
if (n < 2) {
ret = E2BIG;
goto err;
}
s[0] = (wc >> 8) & 0xff;
s[1] = wc & 0xff;
if (!_mskanji1(s[0] & 0xff) || !_mskanji2(s[1] & 0xff))
goto ilseq;
if (!_mskanji1(s[0] & 0xff) || !_mskanji2(s[1] & 0xff)) {
ret = EILSEQ;
goto err;
}
*nresult = 2;
return (0);
return 0;
} else {
s[0] = wc & 0xff;
if (_mskanji1(s[0] & 0xff))
goto ilseq;
if (_mskanji1(s[0] & 0xff)) {
ret = EILSEQ;
goto err;
}
*nresult = 1;
return (0);
return 0;
}
ilseq:
err:
*nresult = (size_t)-1;
return EILSEQ;
return ret;
}
static __inline int
/*ARGSUSED*/
_citrus_MSKanji_stdenc_wctocs(_MSKanjiEncodingInfo * __restrict ei,
_csid_t * __restrict csid,
_index_t * __restrict idx, wchar_t wc)
{
_index_t row, col;
_DIAGASSERT(csid != NULL && idx != NULL);
if ((_wc_t)wc < 0x80) {
/* ISO-646 */
*csid = 0;
*idx = (_index_t)wc;
} else if ((_wc_t)wc < 0x100) {
/* KANA */
*csid = 1;
*idx = (_index_t)wc & 0x7F;
} else if ((0x8140 <= (_wc_t)wc && (_wc_t)wc <= 0x9FFC) ||
(0xE040 <= (_wc_t)wc && (_wc_t)wc <= 0xFCFC)) {
/* Kanji (containing Gaiji zone) */
/*
* 94^2 zone (contains a part of Gaiji (0xED40 - 0xEEFC)):
* 0x8140 - 0x817E -> 0x2121 - 0x215F
* 0x8180 - 0x819E -> 0x2160 - 0x217E
* 0x819F - 0x81FC -> 0x2221 - 0x227E
*
* 0x8240 - 0x827E -> 0x2321 - 0x235F
* ...
* 0x9F9F - 0x9FFc -> 0x5E21 - 0x5E7E
*
* 0xE040 - 0xE07E -> 0x5F21 - 0x5F5F
* ...
* 0xEF9F - 0xEFFC -> 0x7E21 - 0x7E7E
*
* extended Gaiji zone:
* 0xF040 - 0xFCFC
*/
*csid = 2;
row = ((_wc_t)wc >> 8) - 0x81;
if (row >= 0x5F)
row -= 0x40;
row = row * 2 + 0x21;
col = (wc & 0xFF) - 0x1F;
if (col >= 0x61)
col -= 1;
if (col > 0x7E) {
row += 1;
col -= 0x5E;
}
*idx = ((_index_t)row << 8) | col;
} else
return EILSEQ;
return 0;
}
static __inline int
/*ARGSUSED*/
_citrus_MSKanji_stdenc_cstowc(_MSKanjiEncodingInfo * __restrict ei,
wchar_t * __restrict wc,
_csid_t csid, _index_t idx)
{
u_int32_t row, col;
_DIAGASSERT(wc != NULL);
switch (csid) {
case 0:
/* ISO-646 */
if (idx >= 0x80)
return EILSEQ;
*wc = (wchar_t)idx;
break;
case 1:
/* kana */
if (idx >= 0x80)
return EILSEQ;
*wc = (wchar_t)idx + 0x80;
break;
case 2:
/* kanji */
row = (idx >> 8);
col = idx & 0x7F;
if (row<0x21 || row>0x97 || col<0x21 || col>0x7E)
return EILSEQ;
row -= 0x21; col -= 0x21;
if ((row & 1)==0) {
col += 0x40;
if (col>=0x7F)
col += 1;
} else
col += 0x9F;
if (row<0x3E)
row = row/2 + 0x81;
else
row = row/2 + 0xc1;
*wc = ((wchar_t)row << 8) | col;
break;
default:
return EILSEQ;
}
return 0;
}
static int
/*ARGSUSED*/
_citrus_MSKanji_stdencoding_init(_MSKanjiEncodingInfo * __restrict ei,
const void * __restrict var, size_t lenvar)
_citrus_MSKanji_encoding_module_init(_MSKanjiEncodingInfo * __restrict ei,
const void * __restrict var,
size_t lenvar)
{
_DIAGASSERT(cl != NULL);
@ -312,7 +438,7 @@ _citrus_MSKanji_stdencoding_init(_MSKanjiEncodingInfo * __restrict ei,
}
static void
_citrus_MSKanji_stdencoding_uninit(_MSKanjiEncodingInfo *ei)
_citrus_MSKanji_encoding_module_uninit(_MSKanjiEncodingInfo *ei)
{
}
@ -324,3 +450,12 @@ _CITRUS_CTYPE_DECLS(MSKanji);
_CITRUS_CTYPE_DEF_OPS(MSKanji);
#include "citrus_ctype_template.h"
/* ----------------------------------------------------------------------
* public interface for stdenc
*/
_CITRUS_STDENC_DECLS(MSKanji);
_CITRUS_STDENC_DEF_OPS(MSKanji);
#include "citrus_stdenc_template.h"

View File

@ -1,4 +1,4 @@
/* $NetBSD: citrus_mskanji.h,v 1.1 2002/03/17 22:14:23 tshiozak Exp $ */
/* $NetBSD: citrus_mskanji.h,v 1.2 2003/06/25 09:51:48 tshiozak Exp $ */
/*-
* Copyright (c)2002 Citrus Project,
@ -31,6 +31,7 @@
__BEGIN_DECLS
_CITRUS_CTYPE_GETOPS_FUNC(MSKanji);
_CITRUS_STDENC_GETOPS_FUNC(MSKanji);
__END_DECLS
#endif

View File

@ -0,0 +1,444 @@
/* $NetBSD $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_utf1632.c,v 1.1 2003/06/25 09:51:49 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <locale.h>
#include <limits.h>
#include <wchar.h>
#include <sys/types.h>
#include <sys/endian.h>
#include "citrus_namespace.h"
#include "citrus_types.h"
#include "citrus_module.h"
#include "citrus_stdenc.h"
#include "citrus_bcs.h"
#include "citrus_utf1632.h"
/* ----------------------------------------------------------------------
* private stuffs used by templates
*/
typedef struct {
u_int8_t ch[4];
int chlen;
int current_endian;
} _UTF1632State;
typedef struct {
int preffered_endian;
unsigned int cur_max;
#define _ENDIAN_UNKNOWN 0
#define _ENDIAN_BIG 1
#define _ENDIAN_LITTLE 2
u_int32_t mode;
#define _MODE_UTF32 0x00000001U
#define _MODE_FORCE_ENDIAN 0x00000002U
} _UTF1632EncodingInfo;
#define _FUNCNAME(m) _citrus_UTF1632_##m
#define _ENCODING_INFO _UTF1632EncodingInfo
#define _ENCODING_STATE _UTF1632State
#define _ENCODING_MB_CUR_MAX(_ei_) ((_ei_)->cur_max)
#define _ENCODING_IS_STATE_DEPENDENT 0
#define _STATE_NEEDS_EXPLICIT_INIT(_ps_) 0
static __inline void
/*ARGSUSED*/
_citrus_UTF1632_init_state(_UTF1632EncodingInfo *ei, _UTF1632State *s)
{
memset(s, 0, sizeof(*s));
}
static int
_citrus_UTF1632_mbrtowc_priv(_UTF1632EncodingInfo *ei, wchar_t *pwc,
const char **s, size_t n, _UTF1632State *psenc,
size_t *nresult)
{
int chlenbak, endian, needlen;
wchar_t wc;
size_t result;
const char *s0;
_DIAGASSERT(nresult != 0);
_DIAGASSERT(ei != NULL);
_DIAGASSERT(s != NULL);
_DIAGASSERT(psenc != NULL);
s0 = *s;
if (s0 == NULL) {
_citrus_UTF1632_init_state(ei, psenc);
*nresult = 0; /* state independent */
return (0);
}
result = 0;
chlenbak = psenc->chlen;
refetch:
if ((ei->mode & _MODE_UTF32) != 0 || chlenbak>=2)
needlen = 4;
else
needlen = 2;
while (chlenbak < needlen) {
if (n==0)
goto restart;
psenc->ch[chlenbak++] = *s0++;
n--;
result++;
}
/* judge endian marker */
if ((ei->mode & _MODE_UTF32) == 0) {
/* UTF16 */
if (psenc->ch[0]==0xFE && psenc->ch[1]==0xFF) {
psenc->current_endian = _ENDIAN_BIG;
chlenbak = 0;
goto refetch;
} else if (psenc->ch[0]==0xFF && psenc->ch[1]==0xFE) {
psenc->current_endian = _ENDIAN_LITTLE;
chlenbak = 0;
goto refetch;
}
} else {
/* UTF32 */
if (psenc->ch[0]==0x00 && psenc->ch[1]==0x00 &&
psenc->ch[2]==0xFE && psenc->ch[3]==0xFF) {
psenc->current_endian = _ENDIAN_BIG;
chlenbak = 0;
goto refetch;
} else if (psenc->ch[0]==0xFF && psenc->ch[1]==0xFE &&
psenc->ch[2]==0x00 && psenc->ch[3]==0x00) {
psenc->current_endian = _ENDIAN_LITTLE;
chlenbak = 0;
goto refetch;
}
}
if ((ei->mode & _MODE_FORCE_ENDIAN) != 0 ||
psenc->current_endian == _ENDIAN_UNKNOWN)
endian = ei->preffered_endian;
else
endian = psenc->current_endian;
/* get wc */
if ((ei->mode & _MODE_UTF32) == 0) {
/* UTF16 */
if (needlen==2) {
switch (endian) {
case _ENDIAN_LITTLE:
wc = (psenc->ch[0] |
((wchar_t)psenc->ch[1] << 8));
break;
case _ENDIAN_BIG:
wc = (psenc->ch[1] |
((wchar_t)psenc->ch[0] << 8));
break;
}
if (wc >= 0xD800 && wc <= 0xDBFF) {
/* surrogate high */
needlen=4;
goto refetch;
}
} else {
/* surrogate low */
wc -= 0xD800; /* wc : surrogate high (see above) */
wc <<= 10;
switch (endian) {
case _ENDIAN_LITTLE:
if (psenc->ch[2]<0xDC || psenc->ch[2]>0xDF)
goto ilseq;
wc |= psenc->ch[2];
wc |= (wchar_t)(psenc->ch[3] & 3) << 8;
break;
case _ENDIAN_BIG:
if (psenc->ch[3]<0xDC || psenc->ch[3]>0xDF)
goto ilseq;
wc |= psenc->ch[3];
wc |= (wchar_t)(psenc->ch[2] & 3) << 8;
break;
}
wc += 0x10000;
}
} else {
/* UTF32 */
switch (endian) {
case _ENDIAN_LITTLE:
wc = (psenc->ch[0] |
((wchar_t)psenc->ch[1] << 8) |
((wchar_t)psenc->ch[2] << 16) |
((wchar_t)psenc->ch[3] << 24));
break;
case _ENDIAN_BIG:
wc = (psenc->ch[3] |
((wchar_t)psenc->ch[2] << 8) |
((wchar_t)psenc->ch[1] << 16) |
((wchar_t)psenc->ch[0] << 24));
break;
}
}
*pwc = wc;
psenc->chlen = 0;
*nresult = result;
*s = s0;
return (0);
ilseq:
*nresult = (size_t)-1;
psenc->chlen = 0;
return (EILSEQ);
restart:
*nresult = (size_t)-2;
psenc->chlen = chlenbak;
*s = s0;
return (0);
}
static int
_citrus_UTF1632_wcrtomb_priv(_UTF1632EncodingInfo *ei, char *s, size_t n,
wchar_t wc, _UTF1632State *psenc,
size_t *nresult)
{
int ret;
wchar_t wc2;
_DIAGASSERT(ei != NULL);
_DIAGASSERT(nresult != 0);
_DIAGASSERT(s != NULL);
/* reset state */
if (wc == 0) {
*nresult = 0; /* stateless */
return 0;
}
wc2 = 0;
if ((ei->mode & _MODE_UTF32)==0) {
/* UTF16 */
if (wc>0xFFFF) {
/* surrogate */
if (wc>0x10FFFF) {
ret = EILSEQ;
goto err;
}
if (n < 4) {
ret = E2BIG;
goto err;
}
wc -= 0x10000;
wc2 = (wc & 0x3FF) | 0xDC00;
wc = (wc>>10) | 0xD800;
*nresult = (size_t)4;
} else {
if (n < 2) {
ret = E2BIG;
goto err;
}
*nresult = (size_t)2;
}
surrogate:
switch (ei->preffered_endian) {
case _ENDIAN_BIG:
s[1] = wc;
s[0] = (wc >>= 8);
break;
case _ENDIAN_LITTLE:
s[0] = wc;
s[1] = (wc >>= 8);
break;
}
if (wc2!=0) {
wc = wc2;
wc2 = 0;
s += 2;
goto surrogate;
}
} else {
/* UTF32 */
if (n < 4) {
ret = E2BIG;
goto err;
}
switch (ei->preffered_endian) {
case _ENDIAN_BIG:
s[3] = wc;
s[2] = (wc >>= 8);
s[1] = (wc >>= 8);
s[0] = (wc >>= 8);
break;
case _ENDIAN_LITTLE:
s[0] = wc;
s[1] = (wc >>= 8);
s[2] = (wc >>= 8);
s[3] = (wc >>= 8);
break;
}
*nresult = (size_t)4;
}
return 0;
err:
*nresult = (size_t)-1;
return ret;
}
static void
parse_variable(_UTF1632EncodingInfo * __restrict ei,
const void * __restrict var, size_t lenvar)
{
#define MATCH(x, act) \
do { \
if (lenvar >= (sizeof(#x)-1) && \
_bcs_strncasecmp(p, #x, sizeof(#x)-1) == 0) { \
act; \
lenvar -= sizeof(#x)-1; \
p += sizeof(#x)-1; \
} \
} while (/*CONSTCOND*/0)
const char *p;
p = var;
while (lenvar>0) {
switch (*p) {
case 'B':
case 'b':
MATCH(big, ei->preffered_endian = _ENDIAN_BIG);
break;
case 'L':
case 'l':
MATCH(little, ei->preffered_endian = _ENDIAN_LITTLE);
break;
case 'F':
case 'f':
MATCH(force, ei->mode |= _MODE_FORCE_ENDIAN);
break;
case 'U':
case 'u':
MATCH(utf32, ei->mode |= _MODE_UTF32);
break;
}
p++;
lenvar--;
}
}
static int
/*ARGSUSED*/
_citrus_UTF1632_encoding_module_init(_UTF1632EncodingInfo * __restrict ei,
const void * __restrict var,
size_t lenvar)
{
_DIAGASSERT(ei != NULL);
memset((void *)ei, 0, sizeof(*ei));
parse_variable(ei, var, lenvar);
if ((ei->mode&_MODE_UTF32)==0)
ei->cur_max = 6; /* endian + surrogate */
else
ei->cur_max = 8; /* endian + normal */
if (ei->preffered_endian == _ENDIAN_UNKNOWN) {
#if BYTE_ORDER == BIG_ENDIAN
ei->preffered_endian = _ENDIAN_BIG;
#else
ei->preffered_endian = _ENDIAN_LITTLE;
#endif
}
return (0);
}
static void
/*ARGSUSED*/
_citrus_UTF1632_encoding_module_uninit(_UTF1632EncodingInfo *ei)
{
}
static __inline int
/*ARGSUSED*/
_citrus_UTF1632_stdenc_wctocs(_UTF1632EncodingInfo * __restrict ei,
_csid_t * __restrict csid,
_index_t * __restrict idx,
_wc_t wc)
{
_DIAGASSERT(csid != NULL && idx != NULL);
*csid = 0;
*idx = (_index_t)wc;
return (0);
}
static __inline int
/*ARGSUSED*/
_citrus_UTF1632_stdenc_cstowc(_UTF1632EncodingInfo * __restrict ei,
_wc_t * __restrict wc,
_csid_t csid, _index_t idx)
{
_DIAGASSERT(wc != NULL);
if (csid != 0)
return (EILSEQ);
*wc = (_wc_t)idx;
return (0);
}
/* ----------------------------------------------------------------------
* public interface for stdenc
*/
_CITRUS_STDENC_DECLS(UTF1632);
_CITRUS_STDENC_DEF_OPS(UTF1632);
#include "citrus_stdenc_template.h"

View File

@ -0,0 +1,36 @@
/* $NetBSD: citrus_utf1632.h,v 1.1 2003/06/25 09:51:49 tshiozak Exp $ */
/*-
* Copyright (c)2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _CITRUS_UTF1632_H_
#define _CITRUS_UTF1632_H_
__BEGIN_DECLS
_CITRUS_STDENC_GETOPS_FUNC(UTF1632);
__END_DECLS
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: citrus_utf8.c,v 1.7 2003/03/25 17:35:36 tshiozak Exp $ */
/* $NetBSD: citrus_utf8.c,v 1.8 2003/06/25 09:51:49 tshiozak Exp $ */
/*-
* Copyright (c)2002 Citrus Project,
@ -64,7 +64,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: citrus_utf8.c,v 1.7 2003/03/25 17:35:36 tshiozak Exp $");
__RCSID("$NetBSD: citrus_utf8.c,v 1.8 2003/06/25 09:51:49 tshiozak Exp $");
#endif /* LIBC_SCCS and not lint */
#include <assert.h>
@ -77,8 +77,12 @@ __RCSID("$NetBSD: citrus_utf8.c,v 1.7 2003/03/25 17:35:36 tshiozak Exp $");
#include <wchar.h>
#include <sys/types.h>
#include <limits.h>
#include "citrus_namespace.h"
#include "citrus_types.h"
#include "citrus_module.h"
#include "citrus_ctype.h"
#include "citrus_stdenc.h"
#include "citrus_utf8.h"
@ -102,6 +106,7 @@ typedef struct {
typedef struct {
} _UTF8EncodingInfo;
typedef struct {
_UTF8EncodingInfo ei;
struct {
@ -289,21 +294,29 @@ static int
_citrus_UTF8_wcrtomb_priv(_UTF8EncodingInfo *ei, char *s, size_t n, wchar_t wc,
_UTF8State *psenc, size_t *nresult)
{
int cnt, i;
int cnt, i, ret;
wchar_t c;
_DIAGASSERT(ei != NULL);
_DIAGASSERT(nresult != 0);
_DIAGASSERT(s != NULL);
/* reset state */
if (wc == 0) {
*nresult = 0; /* stateless */
return 0;
}
cnt = _UTF8_findlen(wc);
if (cnt <= 0 || cnt > 6) {
/* invalid UCS4 value */
goto ilseq;
ret = EILSEQ;
goto err;
}
if (n < cnt) {
/* bound check failure */
goto ilseq;
ret = E2BIG;
goto err;
}
c = wc;
@ -322,30 +335,62 @@ _citrus_UTF8_wcrtomb_priv(_UTF8EncodingInfo *ei, char *s, size_t n, wchar_t wc,
}
*nresult = (size_t)cnt;
return (0);
return 0;
ilseq:
err:
*nresult = (size_t)-1;
return (EILSEQ);
return ret;
}
static __inline int
/*ARGSUSED*/
_citrus_UTF8_stdenc_wctocs(_UTF8EncodingInfo * __restrict ei,
_csid_t * __restrict csid,
_index_t * __restrict idx,
wchar_t wc)
{
_DIAGASSERT(csid != NULL && idx != NULL);
*csid = 0;
*idx = (_citrus_index_t)wc;
return (0);
}
static __inline int
/*ARGSUSED*/
_citrus_UTF8_stdenc_cstowc(_UTF8EncodingInfo * __restrict ei,
wchar_t * __restrict wc,
_csid_t csid, _index_t idx)
{
_DIAGASSERT(wc != NULL);
if (csid != 0)
return (EILSEQ);
*wc = (wchar_t)idx;
return (0);
}
static int
/*ARGSUSED*/
_citrus_UTF8_stdencoding_init(_UTF8EncodingInfo * __restrict ei,
const void * __restrict var, size_t lenvar)
_citrus_UTF8_encoding_module_init(_UTF8EncodingInfo * __restrict ei,
const void * __restrict var, size_t lenvar)
{
_DIAGASSERT(ei != NULL);
_UTF8_init_count();
memset((void *)ei, 0, sizeof(*ei));
return (0);
return 0;
}
static void
/*ARGSUSED*/
_citrus_UTF8_stdencoding_uninit(_UTF8EncodingInfo *ei)
_citrus_UTF8_encoding_module_uninit(_UTF8EncodingInfo *ei)
{
}
@ -358,3 +403,12 @@ _CITRUS_CTYPE_DECLS(UTF8);
_CITRUS_CTYPE_DEF_OPS(UTF8);
#include "citrus_ctype_template.h"
/* ----------------------------------------------------------------------
* public interface for stdenc
*/
_CITRUS_STDENC_DECLS(UTF8);
_CITRUS_STDENC_DEF_OPS(UTF8);
#include "citrus_stdenc_template.h"

View File

@ -1,4 +1,4 @@
/* $NetBSD: citrus_utf8.h,v 1.1 2002/03/17 22:14:24 tshiozak Exp $ */
/* $NetBSD: citrus_utf8.h,v 1.2 2003/06/25 09:51:49 tshiozak Exp $ */
/*-
* Copyright (c)2002 Citrus Project,
@ -31,6 +31,7 @@
__BEGIN_DECLS
_CITRUS_CTYPE_GETOPS_FUNC(UTF8);
_CITRUS_STDENC_GETOPS_FUNC(UTF8);
__END_DECLS
#endif