Home | History | Annotate | Line # | Download | only in modules
      1 /*	$NetBSD: citrus_mapper_serial.c,v 1.2 2003/07/12 15:39:20 tshiozak Exp $	*/
      2 
      3 /*-
      4  * Copyright (c)2003 Citrus Project,
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #include <sys/cdefs.h>
     30 #if defined(LIBC_SCCS) && !defined(lint)
     31 __RCSID("$NetBSD: citrus_mapper_serial.c,v 1.2 2003/07/12 15:39:20 tshiozak Exp $");
     32 #endif /* LIBC_SCCS and not lint */
     33 
     34 #include <assert.h>
     35 #include <errno.h>
     36 #include <stdio.h>
     37 #include <stdlib.h>
     38 #include <string.h>
     39 #include <limits.h>
     40 #include <sys/queue.h>
     41 
     42 #include "citrus_namespace.h"
     43 #include "citrus_types.h"
     44 #include "citrus_bcs.h"
     45 #include "citrus_module.h"
     46 #include "citrus_region.h"
     47 #include "citrus_memstream.h"
     48 #include "citrus_mmap.h"
     49 #include "citrus_hash.h"
     50 #include "citrus_mapper.h"
     51 #include "citrus_mapper_serial.h"
     52 
     53 /* ---------------------------------------------------------------------- */
     54 
     55 _CITRUS_MAPPER_DECLS(mapper_serial);
     56 _CITRUS_MAPPER_DEF_OPS(mapper_serial);
     57 
     58 #define _citrus_mapper_parallel_mapper_init		\
     59 	_citrus_mapper_serial_mapper_init
     60 #define _citrus_mapper_parallel_mapper_uninit		\
     61 	_citrus_mapper_serial_mapper_uninit
     62 #define _citrus_mapper_parallel_mapper_init_state	\
     63 	_citrus_mapper_serial_mapper_init_state
     64 static int	_citrus_mapper_parallel_mapper_convert(
     65 	struct _citrus_mapper * __restrict, _index_t * __restrict, _index_t,
     66 	void * __restrict);
     67 _CITRUS_MAPPER_DEF_OPS(mapper_parallel);
     68 #undef _citrus_mapper_parallel_mapper_init
     69 #undef _citrus_mapper_parallel_mapper_uninit
     70 #undef _citrus_mapper_parallel_mapper_init_state
     71 
     72 
     73 /* ---------------------------------------------------------------------- */
     74 
     75 struct maplink {
     76 	SIMPLEQ_ENTRY(maplink)	ml_entry;
     77 	struct _mapper		*ml_mapper;
     78 };
     79 SIMPLEQ_HEAD(maplist, maplink);
     80 
     81 struct _citrus_mapper_serial {
     82 	struct maplist	sr_mappers;
     83 };
     84 
     85 int
     86 _citrus_mapper_serial_mapper_getops(struct _citrus_mapper_ops *ops,
     87 				    size_t lenops, uint32_t expected_version)
     88 {
     89 	if (expected_version<_CITRUS_MAPPER_ABI_VERSION || lenops<sizeof(*ops))
     90 		return EINVAL;
     91 
     92 	memcpy(ops, &_citrus_mapper_serial_mapper_ops,
     93 	       sizeof(_citrus_mapper_serial_mapper_ops));
     94 
     95 	return 0;
     96 }
     97 
     98 int
     99 _citrus_mapper_parallel_mapper_getops(struct _citrus_mapper_ops *ops,
    100 				      size_t lenops, uint32_t expected_version)
    101 {
    102 	if (expected_version<_CITRUS_MAPPER_ABI_VERSION || lenops<sizeof(*ops))
    103 		return EINVAL;
    104 
    105 	memcpy(ops, &_citrus_mapper_parallel_mapper_ops,
    106 	       sizeof(_citrus_mapper_parallel_mapper_ops));
    107 
    108 	return 0;
    109 }
    110 
    111 static void
    112 uninit(struct _citrus_mapper_serial *sr)
    113 {
    114 	struct maplink *ml;
    115 
    116 	while ((ml = SIMPLEQ_FIRST(&sr->sr_mappers)) != NULL) {
    117 		SIMPLEQ_REMOVE_HEAD(&sr->sr_mappers, ml_entry);
    118 		_mapper_close(ml->ml_mapper);
    119 		free(ml);
    120 	}
    121 }
    122 
    123 static int
    124 parse_var(struct _citrus_mapper_area *__restrict ma,
    125 	  struct _citrus_mapper_serial *sr, struct _memstream *ms)
    126 {
    127 	int ret;
    128 	struct _region r;
    129 	char mapname[PATH_MAX];
    130 	struct maplink *ml;
    131 
    132 	SIMPLEQ_INIT(&sr->sr_mappers);
    133 	while (1) {
    134 		/* remove beginning white spaces */
    135 		_memstream_skip_ws(ms);
    136 		if (_memstream_iseof(ms))
    137 			break;
    138 		/* cut down a mapper name */
    139 		_memstream_chr(ms, &r, ',');
    140 		snprintf(mapname, sizeof(mapname), "%.*s",
    141 			 (int)_region_size(&r), (char *)_region_head(&r));
    142 		/* remove trailing white spaces */
    143 		mapname[_bcs_skip_nonws(mapname)-mapname] = '\0';
    144 		/* create a new mapper record */
    145 		ml = malloc(sizeof(*ml));
    146 		if (ml == NULL)
    147 			return errno;
    148 		ret = _mapper_open(ma, &ml->ml_mapper, mapname);
    149 		if (ret) {
    150 			free(ml);
    151 			return ret;
    152 		}
    153 		/* support only 1:1 and stateless converter */
    154 		if (_mapper_get_src_max(ml->ml_mapper) != 1 ||
    155 		    _mapper_get_dst_max(ml->ml_mapper) != 1 ||
    156 		    _mapper_get_state_size(ml->ml_mapper) != 0) {
    157 			free(ml);
    158 			return EINVAL;
    159 		}
    160 		SIMPLEQ_INSERT_TAIL(&sr->sr_mappers, ml, ml_entry);
    161 	}
    162 	return 0;
    163 }
    164 
    165 static int
    166 /*ARGSUSED*/
    167 _citrus_mapper_serial_mapper_init(struct _citrus_mapper_area *__restrict ma,
    168 				  struct _citrus_mapper * __restrict cm,
    169 				  const char * __restrict dir,
    170 				  const void * __restrict var, size_t lenvar,
    171 				  struct _citrus_mapper_traits * __restrict mt,
    172 				  size_t lenmt)
    173 {
    174 	struct _citrus_mapper_serial *sr;
    175 	struct _memstream ms;
    176 	struct _region r;
    177 
    178 	_DIAGASSERT(cm && dir && mt);
    179 
    180 	if (lenmt<sizeof(*mt))
    181 		return EINVAL;
    182 
    183 	sr = malloc(sizeof(*sr));
    184 	if (sr == NULL)
    185 		return errno;
    186 
    187 	_region_init(&r, (void *)var, lenvar);
    188 	_memstream_bind(&ms, &r);
    189 	if (parse_var(ma, sr, &ms)) {
    190 		uninit(sr);
    191 		free(sr);
    192 		return EINVAL;
    193 	}
    194 	cm->cm_closure = sr;
    195 	mt->mt_src_max = mt->mt_dst_max = 1;	/* 1:1 converter */
    196 	mt->mt_state_size = 0;			/* stateless */
    197 
    198 	return 0;
    199 }
    200 
    201 static void
    202 /*ARGSUSED*/
    203 _citrus_mapper_serial_mapper_uninit(struct _citrus_mapper *cm)
    204 {
    205 	if (cm && cm->cm_closure) {
    206 		uninit(cm->cm_closure);
    207 		free(cm->cm_closure);
    208 	}
    209 }
    210 
    211 static int
    212 /*ARGSUSED*/
    213 _citrus_mapper_serial_mapper_convert(struct _citrus_mapper * __restrict cm,
    214 				     _index_t * __restrict dst, _index_t src,
    215 				     void * __restrict ps)
    216 {
    217 	int ret;
    218 	struct _citrus_mapper_serial *sr;
    219 	struct maplink *ml;
    220 
    221 	_DIAGASSERT(cm && cm->cm_closure);
    222 
    223 	sr = cm->cm_closure;
    224 	SIMPLEQ_FOREACH(ml, &sr->sr_mappers, ml_entry) {
    225 		ret = _mapper_convert(ml->ml_mapper, &src, src, NULL);
    226 		if (ret != _MAPPER_CONVERT_SUCCESS)
    227 			return ret;
    228 	}
    229 	*dst = src;
    230 	return _MAPPER_CONVERT_SUCCESS;
    231 }
    232 
    233 static int
    234 /*ARGSUSED*/
    235 _citrus_mapper_parallel_mapper_convert(struct _citrus_mapper * __restrict cm,
    236 				       _index_t * __restrict dst, _index_t src,
    237 				       void * __restrict ps)
    238 {
    239 	int ret;
    240 	struct _citrus_mapper_serial *sr;
    241 	struct maplink *ml;
    242 	_index_t tmp;
    243 
    244 	_DIAGASSERT(cm && cm->cm_closure);
    245 
    246 	sr = cm->cm_closure;
    247 	SIMPLEQ_FOREACH(ml, &sr->sr_mappers, ml_entry) {
    248 		ret = _mapper_convert(ml->ml_mapper, &tmp, src, NULL);
    249 		if (ret == _MAPPER_CONVERT_SUCCESS) {
    250 			*dst = tmp;
    251 			return _MAPPER_CONVERT_SUCCESS;
    252 		} else if (ret == _MAPPER_CONVERT_ILSEQ)
    253 			return _MAPPER_CONVERT_ILSEQ;
    254 	}
    255 	return _MAPPER_CONVERT_NONIDENTICAL;
    256 }
    257 
    258 static void
    259 /*ARGSUSED*/
    260 _citrus_mapper_serial_mapper_init_state(struct _citrus_mapper * __restrict cm,
    261 					void * __restrict ps)
    262 {
    263 }
    264