xref: /dflybsd-src/lib/i18n_module/mapper_std/citrus_mapper_std.c (revision 45203ddb84bcdfc677c5202871cff6f81dc2aff0)
1*45203ddbSJohn Marino /* $FreeBSD: head/lib/libiconv_modules/mapper_std/citrus_mapper_std.c 263986 2014-04-01 10:36:11Z tijl $ */
2*45203ddbSJohn Marino /*	$NetBSD: citrus_mapper_std.c,v 1.10 2011/11/19 18:48:39 tnozaki Exp $	*/
30d5acd74SJohn Marino 
40d5acd74SJohn Marino /*-
50d5acd74SJohn Marino  * Copyright (c)2003, 2006 Citrus Project,
60d5acd74SJohn Marino  * All rights reserved.
70d5acd74SJohn Marino  *
80d5acd74SJohn Marino  * Redistribution and use in source and binary forms, with or without
90d5acd74SJohn Marino  * modification, are permitted provided that the following conditions
100d5acd74SJohn Marino  * are met:
110d5acd74SJohn Marino  * 1. Redistributions of source code must retain the above copyright
120d5acd74SJohn Marino  *    notice, this list of conditions and the following disclaimer.
130d5acd74SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
140d5acd74SJohn Marino  *    notice, this list of conditions and the following disclaimer in the
150d5acd74SJohn Marino  *    documentation and/or other materials provided with the distribution.
160d5acd74SJohn Marino  *
170d5acd74SJohn Marino  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
180d5acd74SJohn Marino  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
190d5acd74SJohn Marino  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
200d5acd74SJohn Marino  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
210d5acd74SJohn Marino  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
220d5acd74SJohn Marino  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
230d5acd74SJohn Marino  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
240d5acd74SJohn Marino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
250d5acd74SJohn Marino  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
260d5acd74SJohn Marino  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
270d5acd74SJohn Marino  * SUCH DAMAGE.
280d5acd74SJohn Marino  */
290d5acd74SJohn Marino 
300d5acd74SJohn Marino #include <sys/cdefs.h>
310d5acd74SJohn Marino #include <sys/endian.h>
320d5acd74SJohn Marino #include <sys/queue.h>
330d5acd74SJohn Marino 
340d5acd74SJohn Marino #include <assert.h>
350d5acd74SJohn Marino #include <errno.h>
360d5acd74SJohn Marino #include <limits.h>
370d5acd74SJohn Marino #include <stdint.h>
380d5acd74SJohn Marino #include <stdio.h>
390d5acd74SJohn Marino #include <stdlib.h>
400d5acd74SJohn Marino #include <string.h>
410d5acd74SJohn Marino 
420d5acd74SJohn Marino #include "citrus_namespace.h"
430d5acd74SJohn Marino #include "citrus_types.h"
440d5acd74SJohn Marino #include "citrus_bcs.h"
450d5acd74SJohn Marino #include "citrus_region.h"
460d5acd74SJohn Marino #include "citrus_mmap.h"
470d5acd74SJohn Marino #include "citrus_module.h"
480d5acd74SJohn Marino #include "citrus_hash.h"
490d5acd74SJohn Marino #include "citrus_mapper.h"
500d5acd74SJohn Marino #include "citrus_db.h"
510d5acd74SJohn Marino #include "citrus_db_hash.h"
520d5acd74SJohn Marino 
530d5acd74SJohn Marino #include "citrus_mapper_std.h"
540d5acd74SJohn Marino #include "citrus_mapper_std_file.h"
550d5acd74SJohn Marino 
560d5acd74SJohn Marino /* ---------------------------------------------------------------------- */
570d5acd74SJohn Marino 
580d5acd74SJohn Marino _CITRUS_MAPPER_DECLS(mapper_std);
590d5acd74SJohn Marino _CITRUS_MAPPER_DEF_OPS(mapper_std);
600d5acd74SJohn Marino 
610d5acd74SJohn Marino 
620d5acd74SJohn Marino /* ---------------------------------------------------------------------- */
630d5acd74SJohn Marino 
640d5acd74SJohn Marino int
_citrus_mapper_std_mapper_getops(struct _citrus_mapper_ops * ops)650d5acd74SJohn Marino _citrus_mapper_std_mapper_getops(struct _citrus_mapper_ops *ops)
660d5acd74SJohn Marino {
670d5acd74SJohn Marino 
680d5acd74SJohn Marino 	memcpy(ops, &_citrus_mapper_std_mapper_ops,
690d5acd74SJohn Marino 	    sizeof(_citrus_mapper_std_mapper_ops));
700d5acd74SJohn Marino 
710d5acd74SJohn Marino 	return (0);
720d5acd74SJohn Marino }
730d5acd74SJohn Marino 
740d5acd74SJohn Marino /* ---------------------------------------------------------------------- */
750d5acd74SJohn Marino 
760d5acd74SJohn Marino static int
770d5acd74SJohn Marino /*ARGSUSED*/
rowcol_convert(struct _citrus_mapper_std * __restrict ms,_index_t * __restrict dst,_index_t src,void * __restrict ps __unused)780d5acd74SJohn Marino rowcol_convert(struct _citrus_mapper_std * __restrict ms,
790d5acd74SJohn Marino     _index_t * __restrict dst, _index_t src, void * __restrict ps __unused)
800d5acd74SJohn Marino {
810d5acd74SJohn Marino 	struct _citrus_mapper_std_linear_zone *lz;
820d5acd74SJohn Marino 	struct _citrus_mapper_std_rowcol *rc;
830d5acd74SJohn Marino 	_index_t idx = 0, n;
840d5acd74SJohn Marino 	size_t i;
850d5acd74SJohn Marino 	uint32_t conv;
860d5acd74SJohn Marino 
870d5acd74SJohn Marino 	/* ps may be unused */
880d5acd74SJohn Marino 	rc = &ms->ms_rowcol;
890d5acd74SJohn Marino 
900d5acd74SJohn Marino 	for (i = rc->rc_src_rowcol_len * rc->rc_src_rowcol_bits,
910d5acd74SJohn Marino 	    lz = &rc->rc_src_rowcol[0]; i > 0; ++lz) {
920d5acd74SJohn Marino 		i -= rc->rc_src_rowcol_bits;
930d5acd74SJohn Marino 		n = (src >> i) & rc->rc_src_rowcol_mask;
940d5acd74SJohn Marino 		if (n < lz->begin || n > lz->end) {
950d5acd74SJohn Marino 			switch (rc->rc_oob_mode) {
960d5acd74SJohn Marino 			case _CITRUS_MAPPER_STD_OOB_NONIDENTICAL:
970d5acd74SJohn Marino 				*dst = rc->rc_dst_invalid;
980d5acd74SJohn Marino 				return (_MAPPER_CONVERT_NONIDENTICAL);
990d5acd74SJohn Marino 			case _CITRUS_MAPPER_STD_OOB_ILSEQ:
1000d5acd74SJohn Marino 				return (_MAPPER_CONVERT_ILSEQ);
1010d5acd74SJohn Marino 			default:
1020d5acd74SJohn Marino 				return (_MAPPER_CONVERT_FATAL);
1030d5acd74SJohn Marino 			}
1040d5acd74SJohn Marino 		}
1050d5acd74SJohn Marino 		idx = idx * lz->width + n - lz->begin;
1060d5acd74SJohn Marino 	}
1070d5acd74SJohn Marino 	switch (rc->rc_dst_unit_bits) {
1080d5acd74SJohn Marino 	case 8:
1090d5acd74SJohn Marino 		conv = _region_peek8(&rc->rc_table, idx);
1100d5acd74SJohn Marino 		break;
1110d5acd74SJohn Marino 	case 16:
1120d5acd74SJohn Marino 		conv = be16toh(_region_peek16(&rc->rc_table, idx*2));
1130d5acd74SJohn Marino 		break;
1140d5acd74SJohn Marino 	case 32:
1150d5acd74SJohn Marino 		conv = be32toh(_region_peek32(&rc->rc_table, idx*4));
1160d5acd74SJohn Marino 		break;
1170d5acd74SJohn Marino 	default:
1180d5acd74SJohn Marino 		return (_MAPPER_CONVERT_FATAL);
1190d5acd74SJohn Marino 	}
1200d5acd74SJohn Marino 
1210d5acd74SJohn Marino 	if (conv == rc->rc_dst_invalid) {
1220d5acd74SJohn Marino 		*dst = rc->rc_dst_invalid;
1230d5acd74SJohn Marino 		return (_MAPPER_CONVERT_NONIDENTICAL);
1240d5acd74SJohn Marino 	}
1250d5acd74SJohn Marino 	if (conv == rc->rc_dst_ilseq)
1260d5acd74SJohn Marino 		return (_MAPPER_CONVERT_ILSEQ);
1270d5acd74SJohn Marino 
1280d5acd74SJohn Marino 	*dst = conv;
1290d5acd74SJohn Marino 
1300d5acd74SJohn Marino 	return (_MAPPER_CONVERT_SUCCESS);
1310d5acd74SJohn Marino }
1320d5acd74SJohn Marino 
1330d5acd74SJohn Marino static __inline int
set_linear_zone(struct _citrus_mapper_std_linear_zone * lz,uint32_t begin,uint32_t end)1340d5acd74SJohn Marino set_linear_zone(struct _citrus_mapper_std_linear_zone *lz,
1350d5acd74SJohn Marino     uint32_t begin, uint32_t end)
1360d5acd74SJohn Marino {
1370d5acd74SJohn Marino 
1380d5acd74SJohn Marino 	if (begin > end)
1390d5acd74SJohn Marino 		return (EFTYPE);
1400d5acd74SJohn Marino 
1410d5acd74SJohn Marino 	lz->begin = begin;
1420d5acd74SJohn Marino 	lz->end = end;
1430d5acd74SJohn Marino 	lz->width= end - begin + 1;
1440d5acd74SJohn Marino 
1450d5acd74SJohn Marino 	return (0);
1460d5acd74SJohn Marino }
1470d5acd74SJohn Marino 
1480d5acd74SJohn Marino static __inline int
rowcol_parse_variable_compat(struct _citrus_mapper_std_rowcol * rc,struct _region * r)1490d5acd74SJohn Marino rowcol_parse_variable_compat(struct _citrus_mapper_std_rowcol *rc,
1500d5acd74SJohn Marino     struct _region *r)
1510d5acd74SJohn Marino {
1520d5acd74SJohn Marino 	const struct _citrus_mapper_std_rowcol_info_compat_x *rcx;
1530d5acd74SJohn Marino 	struct _citrus_mapper_std_linear_zone *lz;
1540d5acd74SJohn Marino 	uint32_t m, n;
1550d5acd74SJohn Marino 	int ret;
1560d5acd74SJohn Marino 
1570d5acd74SJohn Marino 	rcx = _region_head(r);
1580d5acd74SJohn Marino 
1590d5acd74SJohn Marino 	rc->rc_dst_invalid = be32toh(rcx->rcx_dst_invalid);
1600d5acd74SJohn Marino 	rc->rc_dst_unit_bits = be32toh(rcx->rcx_dst_unit_bits);
1610d5acd74SJohn Marino 	m = be32toh(rcx->rcx_src_col_bits);
1620d5acd74SJohn Marino 	n = 1 << (m - 1);
1630d5acd74SJohn Marino 	n |= n - 1;
1640d5acd74SJohn Marino 	rc->rc_src_rowcol_bits = m;
1650d5acd74SJohn Marino 	rc->rc_src_rowcol_mask = n;
1660d5acd74SJohn Marino 
1670d5acd74SJohn Marino 	rc->rc_src_rowcol = malloc(2 *
1680d5acd74SJohn Marino 	    sizeof(*rc->rc_src_rowcol));
1690d5acd74SJohn Marino 	if (rc->rc_src_rowcol == NULL)
1700d5acd74SJohn Marino 		return (ENOMEM);
1710d5acd74SJohn Marino 	lz = rc->rc_src_rowcol;
1720d5acd74SJohn Marino 	rc->rc_src_rowcol_len = 1;
1730d5acd74SJohn Marino 	m = be32toh(rcx->rcx_src_row_begin);
1740d5acd74SJohn Marino 	n = be32toh(rcx->rcx_src_row_end);
1750d5acd74SJohn Marino 	if (m + n > 0) {
1760d5acd74SJohn Marino 		ret = set_linear_zone(lz, m, n);
177*45203ddbSJohn Marino 		if (ret != 0) {
178*45203ddbSJohn Marino 			free(rc->rc_src_rowcol);
179*45203ddbSJohn Marino 			rc->rc_src_rowcol = NULL;
1800d5acd74SJohn Marino 			return (ret);
181*45203ddbSJohn Marino 		}
1820d5acd74SJohn Marino 		++rc->rc_src_rowcol_len, ++lz;
1830d5acd74SJohn Marino 	}
1840d5acd74SJohn Marino 	m = be32toh(rcx->rcx_src_col_begin);
1850d5acd74SJohn Marino 	n = be32toh(rcx->rcx_src_col_end);
1860d5acd74SJohn Marino 
1870d5acd74SJohn Marino 	return (set_linear_zone(lz, m, n));
1880d5acd74SJohn Marino }
1890d5acd74SJohn Marino 
1900d5acd74SJohn Marino static __inline int
rowcol_parse_variable(struct _citrus_mapper_std_rowcol * rc,struct _region * r)1910d5acd74SJohn Marino rowcol_parse_variable(struct _citrus_mapper_std_rowcol *rc,
1920d5acd74SJohn Marino     struct _region *r)
1930d5acd74SJohn Marino {
1940d5acd74SJohn Marino 	const struct _citrus_mapper_std_rowcol_info_x *rcx;
1950d5acd74SJohn Marino 	struct _citrus_mapper_std_linear_zone *lz;
1960d5acd74SJohn Marino 	size_t i;
1970d5acd74SJohn Marino 	uint32_t m, n;
1980d5acd74SJohn Marino 	int ret;
1990d5acd74SJohn Marino 
2000d5acd74SJohn Marino 	rcx = _region_head(r);
2010d5acd74SJohn Marino 
2020d5acd74SJohn Marino 	rc->rc_dst_invalid = be32toh(rcx->rcx_dst_invalid);
2030d5acd74SJohn Marino 	rc->rc_dst_unit_bits = be32toh(rcx->rcx_dst_unit_bits);
2040d5acd74SJohn Marino 
2050d5acd74SJohn Marino 	m = be32toh(rcx->rcx_src_rowcol_bits);
2060d5acd74SJohn Marino 	n = 1 << (m - 1);
2070d5acd74SJohn Marino 	n |= n - 1;
2080d5acd74SJohn Marino 	rc->rc_src_rowcol_bits = m;
2090d5acd74SJohn Marino 	rc->rc_src_rowcol_mask = n;
2100d5acd74SJohn Marino 
2110d5acd74SJohn Marino 	rc->rc_src_rowcol_len = be32toh(rcx->rcx_src_rowcol_len);
2120d5acd74SJohn Marino 	if (rc->rc_src_rowcol_len > _CITRUS_MAPPER_STD_ROWCOL_MAX)
2130d5acd74SJohn Marino 		return (EFTYPE);
2140d5acd74SJohn Marino 	rc->rc_src_rowcol = malloc(rc->rc_src_rowcol_len *
2150d5acd74SJohn Marino 	    sizeof(*rc->rc_src_rowcol));
2160d5acd74SJohn Marino 	if (rc->rc_src_rowcol == NULL)
2170d5acd74SJohn Marino 		return (ENOMEM);
2180d5acd74SJohn Marino 	for (i = 0, lz = rc->rc_src_rowcol;
2190d5acd74SJohn Marino 	    i < rc->rc_src_rowcol_len; ++i, ++lz) {
2200d5acd74SJohn Marino 		m = be32toh(rcx->rcx_src_rowcol[i].begin),
2210d5acd74SJohn Marino 		n = be32toh(rcx->rcx_src_rowcol[i].end);
2220d5acd74SJohn Marino 		ret = set_linear_zone(lz, m, n);
2230d5acd74SJohn Marino 		if (ret != 0) {
2240d5acd74SJohn Marino 			free(rc->rc_src_rowcol);
2250d5acd74SJohn Marino 			rc->rc_src_rowcol = NULL;
2260d5acd74SJohn Marino 			return (ret);
2270d5acd74SJohn Marino 		}
2280d5acd74SJohn Marino 	}
2290d5acd74SJohn Marino 	return (0);
2300d5acd74SJohn Marino }
2310d5acd74SJohn Marino 
2320d5acd74SJohn Marino static void
rowcol_uninit(struct _citrus_mapper_std * ms)2330d5acd74SJohn Marino rowcol_uninit(struct _citrus_mapper_std *ms)
2340d5acd74SJohn Marino {
2350d5acd74SJohn Marino 	struct _citrus_mapper_std_rowcol *rc;
2360d5acd74SJohn Marino 
2370d5acd74SJohn Marino 	rc = &ms->ms_rowcol;
2380d5acd74SJohn Marino 	free(rc->rc_src_rowcol);
2390d5acd74SJohn Marino }
2400d5acd74SJohn Marino 
2410d5acd74SJohn Marino static int
rowcol_init(struct _citrus_mapper_std * ms)2420d5acd74SJohn Marino rowcol_init(struct _citrus_mapper_std *ms)
2430d5acd74SJohn Marino {
2440d5acd74SJohn Marino 	struct _citrus_mapper_std_linear_zone *lz;
2450d5acd74SJohn Marino 	struct _citrus_mapper_std_rowcol *rc;
2460d5acd74SJohn Marino 	const struct _citrus_mapper_std_rowcol_ext_ilseq_info_x *eix;
2470d5acd74SJohn Marino 	struct _region r;
2480d5acd74SJohn Marino 	uint64_t table_size;
2490d5acd74SJohn Marino 	size_t i;
2500d5acd74SJohn Marino 	int ret;
2510d5acd74SJohn Marino 
2520d5acd74SJohn Marino 	ms->ms_convert = &rowcol_convert;
2530d5acd74SJohn Marino 	ms->ms_uninit = &rowcol_uninit;
2540d5acd74SJohn Marino 	rc = &ms->ms_rowcol;
2550d5acd74SJohn Marino 
2560d5acd74SJohn Marino 	/* get table region */
2570d5acd74SJohn Marino 	ret = _db_lookup_by_s(ms->ms_db, _CITRUS_MAPPER_STD_SYM_TABLE,
2580d5acd74SJohn Marino 	    &rc->rc_table, NULL);
2590d5acd74SJohn Marino 	if (ret) {
2600d5acd74SJohn Marino 		if (ret == ENOENT)
2610d5acd74SJohn Marino 			ret = EFTYPE;
2620d5acd74SJohn Marino 		return (ret);
2630d5acd74SJohn Marino 	}
2640d5acd74SJohn Marino 
2650d5acd74SJohn Marino 	/* get table information */
2660d5acd74SJohn Marino 	ret = _db_lookup_by_s(ms->ms_db, _CITRUS_MAPPER_STD_SYM_INFO, &r, NULL);
2670d5acd74SJohn Marino 	if (ret) {
2680d5acd74SJohn Marino 		if (ret == ENOENT)
2690d5acd74SJohn Marino 			ret = EFTYPE;
2700d5acd74SJohn Marino 		return (ret);
2710d5acd74SJohn Marino 	}
2720d5acd74SJohn Marino 	switch (_region_size(&r)) {
2730d5acd74SJohn Marino 	case _CITRUS_MAPPER_STD_ROWCOL_INFO_COMPAT_SIZE:
2740d5acd74SJohn Marino 		ret = rowcol_parse_variable_compat(rc, &r);
2750d5acd74SJohn Marino 		break;
2760d5acd74SJohn Marino 	case _CITRUS_MAPPER_STD_ROWCOL_INFO_SIZE:
2770d5acd74SJohn Marino 		ret = rowcol_parse_variable(rc, &r);
2780d5acd74SJohn Marino 		break;
2790d5acd74SJohn Marino 	default:
2800d5acd74SJohn Marino 		return (EFTYPE);
2810d5acd74SJohn Marino 	}
2820d5acd74SJohn Marino 	if (ret != 0)
2830d5acd74SJohn Marino 		return (ret);
2840d5acd74SJohn Marino 	/* sanity check */
2850d5acd74SJohn Marino 	switch (rc->rc_src_rowcol_bits) {
2860d5acd74SJohn Marino 	case 8: case 16: case 32:
2870d5acd74SJohn Marino 		if (rc->rc_src_rowcol_len <= 32 / rc->rc_src_rowcol_bits)
2880d5acd74SJohn Marino 			break;
2890d5acd74SJohn Marino 	/*FALLTHROUGH*/
2900d5acd74SJohn Marino 	default:
2910d5acd74SJohn Marino 		return (EFTYPE);
2920d5acd74SJohn Marino 	}
2930d5acd74SJohn Marino 
2940d5acd74SJohn Marino 	/* ilseq extension */
2950d5acd74SJohn Marino 	rc->rc_oob_mode = _CITRUS_MAPPER_STD_OOB_NONIDENTICAL;
2960d5acd74SJohn Marino 	rc->rc_dst_ilseq = rc->rc_dst_invalid;
2970d5acd74SJohn Marino 	ret = _db_lookup_by_s(ms->ms_db,
2980d5acd74SJohn Marino 	    _CITRUS_MAPPER_STD_SYM_ROWCOL_EXT_ILSEQ, &r, NULL);
2990d5acd74SJohn Marino 	if (ret && ret != ENOENT)
3000d5acd74SJohn Marino 		return (ret);
3010d5acd74SJohn Marino 	if (_region_size(&r) < sizeof(*eix))
3020d5acd74SJohn Marino 		return (EFTYPE);
3030d5acd74SJohn Marino 	if (ret == 0) {
3040d5acd74SJohn Marino 		eix = _region_head(&r);
3050d5acd74SJohn Marino 		rc->rc_oob_mode = be32toh(eix->eix_oob_mode);
3060d5acd74SJohn Marino 		rc->rc_dst_ilseq = be32toh(eix->eix_dst_ilseq);
3070d5acd74SJohn Marino 	}
3080d5acd74SJohn Marino 
3090d5acd74SJohn Marino 	/* calcurate expected table size */
3100d5acd74SJohn Marino 	i = rc->rc_src_rowcol_len;
3110d5acd74SJohn Marino 	lz = &rc->rc_src_rowcol[--i];
3120d5acd74SJohn Marino 	table_size = lz->width;
3130d5acd74SJohn Marino 	while (i > 0) {
3140d5acd74SJohn Marino 		lz = &rc->rc_src_rowcol[--i];
3150d5acd74SJohn Marino 		table_size *= lz->width;
3160d5acd74SJohn Marino 	}
3170d5acd74SJohn Marino 	table_size *= rc->rc_dst_unit_bits/8;
3180d5acd74SJohn Marino 
3190d5acd74SJohn Marino 	if (table_size > UINT32_MAX ||
3200d5acd74SJohn Marino 	    _region_size(&rc->rc_table) < table_size)
3210d5acd74SJohn Marino 		return (EFTYPE);
3220d5acd74SJohn Marino 
3230d5acd74SJohn Marino 	return (0);
3240d5acd74SJohn Marino }
3250d5acd74SJohn Marino 
3260d5acd74SJohn Marino typedef int (*initfunc_t)(struct _citrus_mapper_std *);
3270d5acd74SJohn Marino static const struct {
3280d5acd74SJohn Marino 	initfunc_t			 t_init;
3290d5acd74SJohn Marino 	const char			*t_name;
3300d5acd74SJohn Marino } types[] = {
3310d5acd74SJohn Marino 	{ &rowcol_init, _CITRUS_MAPPER_STD_TYPE_ROWCOL },
3320d5acd74SJohn Marino };
3330d5acd74SJohn Marino #define NUM_OF_TYPES ((int)(sizeof(types)/sizeof(types[0])))
3340d5acd74SJohn Marino 
3350d5acd74SJohn Marino static int
3360d5acd74SJohn Marino /*ARGSUSED*/
_citrus_mapper_std_mapper_init(struct _citrus_mapper_area * __restrict ma __unused,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)3370d5acd74SJohn Marino _citrus_mapper_std_mapper_init(struct _citrus_mapper_area *__restrict ma __unused,
3380d5acd74SJohn Marino     struct _citrus_mapper * __restrict cm, const char * __restrict curdir,
3390d5acd74SJohn Marino     const void * __restrict var, size_t lenvar,
3400d5acd74SJohn Marino     struct _citrus_mapper_traits * __restrict mt, size_t lenmt)
3410d5acd74SJohn Marino {
3420d5acd74SJohn Marino 	struct _citrus_mapper_std *ms;
3430d5acd74SJohn Marino 	char path[PATH_MAX];
3440d5acd74SJohn Marino 	const char *type;
3450d5acd74SJohn Marino 	int id, ret;
3460d5acd74SJohn Marino 
3470d5acd74SJohn Marino 	/* set traits */
3480d5acd74SJohn Marino 	if (lenmt < sizeof(*mt)) {
3490d5acd74SJohn Marino 		ret = EINVAL;
3500d5acd74SJohn Marino 		goto err0;
3510d5acd74SJohn Marino 	}
3520d5acd74SJohn Marino 	mt->mt_src_max = mt->mt_dst_max = 1;	/* 1:1 converter */
3530d5acd74SJohn Marino 	mt->mt_state_size = 0;			/* stateless */
3540d5acd74SJohn Marino 
3550d5acd74SJohn Marino 	/* alloc mapper std structure */
3560d5acd74SJohn Marino 	ms = malloc(sizeof(*ms));
3570d5acd74SJohn Marino 	if (ms == NULL) {
3580d5acd74SJohn Marino 		ret = errno;
3590d5acd74SJohn Marino 		goto err0;
3600d5acd74SJohn Marino 	}
3610d5acd74SJohn Marino 
3620d5acd74SJohn Marino 	/* open mapper file */
3630d5acd74SJohn Marino 	snprintf(path, sizeof(path), "%s/%.*s", curdir, (int)lenvar,
3640d5acd74SJohn Marino 	    (const char *)var);
3650d5acd74SJohn Marino 	ret = _map_file(&ms->ms_file, path);
3660d5acd74SJohn Marino 	if (ret)
3670d5acd74SJohn Marino 		goto err1;
3680d5acd74SJohn Marino 
3690d5acd74SJohn Marino 	ret = _db_open(&ms->ms_db, &ms->ms_file, _CITRUS_MAPPER_STD_MAGIC,
3700d5acd74SJohn Marino 	    &_db_hash_std, NULL);
3710d5acd74SJohn Marino 	if (ret)
3720d5acd74SJohn Marino 		goto err2;
3730d5acd74SJohn Marino 
3740d5acd74SJohn Marino 	/* get mapper type */
3750d5acd74SJohn Marino 	ret = _db_lookupstr_by_s(ms->ms_db, _CITRUS_MAPPER_STD_SYM_TYPE,
3760d5acd74SJohn Marino 	    &type, NULL);
3770d5acd74SJohn Marino 	if (ret) {
3780d5acd74SJohn Marino 		if (ret == ENOENT)
3790d5acd74SJohn Marino 			ret = EFTYPE;
3800d5acd74SJohn Marino 		goto err3;
3810d5acd74SJohn Marino 	}
3820d5acd74SJohn Marino 	for (id = 0; id < NUM_OF_TYPES; id++)
3830d5acd74SJohn Marino 		if (_bcs_strcasecmp(type, types[id].t_name) == 0)
3840d5acd74SJohn Marino 			break;
3850d5acd74SJohn Marino 
3860d5acd74SJohn Marino 	if (id == NUM_OF_TYPES)
3870d5acd74SJohn Marino 		goto err3;
3880d5acd74SJohn Marino 
3890d5acd74SJohn Marino 	/* init the per-type structure */
3900d5acd74SJohn Marino 	ret = (*types[id].t_init)(ms);
3910d5acd74SJohn Marino 	if (ret)
3920d5acd74SJohn Marino 		goto err3;
3930d5acd74SJohn Marino 
3940d5acd74SJohn Marino 	cm->cm_closure = ms;
3950d5acd74SJohn Marino 
3960d5acd74SJohn Marino 	return (0);
3970d5acd74SJohn Marino 
3980d5acd74SJohn Marino err3:
3990d5acd74SJohn Marino 	_db_close(ms->ms_db);
4000d5acd74SJohn Marino err2:
4010d5acd74SJohn Marino 	_unmap_file(&ms->ms_file);
4020d5acd74SJohn Marino err1:
4030d5acd74SJohn Marino 	free(ms);
4040d5acd74SJohn Marino err0:
4050d5acd74SJohn Marino 	return (ret);
4060d5acd74SJohn Marino }
4070d5acd74SJohn Marino 
4080d5acd74SJohn Marino static void
4090d5acd74SJohn Marino /*ARGSUSED*/
_citrus_mapper_std_mapper_uninit(struct _citrus_mapper * cm)4100d5acd74SJohn Marino _citrus_mapper_std_mapper_uninit(struct _citrus_mapper *cm)
4110d5acd74SJohn Marino {
4120d5acd74SJohn Marino 	struct _citrus_mapper_std *ms;
4130d5acd74SJohn Marino 
4140d5acd74SJohn Marino 	ms = cm->cm_closure;
4150d5acd74SJohn Marino 	if (ms->ms_uninit)
4160d5acd74SJohn Marino 		(*ms->ms_uninit)(ms);
4170d5acd74SJohn Marino 	_db_close(ms->ms_db);
4180d5acd74SJohn Marino 	_unmap_file(&ms->ms_file);
4190d5acd74SJohn Marino 	free(ms);
4200d5acd74SJohn Marino }
4210d5acd74SJohn Marino 
4220d5acd74SJohn Marino static void
4230d5acd74SJohn Marino /*ARGSUSED*/
_citrus_mapper_std_mapper_init_state(void)4240d5acd74SJohn Marino _citrus_mapper_std_mapper_init_state(void)
4250d5acd74SJohn Marino {
4260d5acd74SJohn Marino 
4270d5acd74SJohn Marino }
4280d5acd74SJohn Marino 
4290d5acd74SJohn Marino static int
4300d5acd74SJohn Marino /*ARGSUSED*/
_citrus_mapper_std_mapper_convert(struct _citrus_mapper * __restrict cm,_index_t * __restrict dst,_index_t src,void * __restrict ps)4310d5acd74SJohn Marino _citrus_mapper_std_mapper_convert(struct _citrus_mapper * __restrict cm,
4320d5acd74SJohn Marino     _index_t * __restrict dst, _index_t src, void * __restrict ps)
4330d5acd74SJohn Marino {
4340d5acd74SJohn Marino 	struct _citrus_mapper_std *ms;
4350d5acd74SJohn Marino 
4360d5acd74SJohn Marino 	ms = cm->cm_closure;
4370d5acd74SJohn Marino 	return ((*ms->ms_convert)(ms, dst, src, ps));
4380d5acd74SJohn Marino }
439