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