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:
parent
d40cbfcc0b
commit
04e58308a3
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
|
@ -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
|
|
@ -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)
|
||||
{
|
||||
}
|
|
@ -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
|
|
@ -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)
|
||||
{
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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)
|
||||
{
|
||||
}
|
|
@ -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
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
|
@ -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
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue