1 /* $NetBSD: citrus_mapper_serial.c,v 1.1 2003/06/25 09:51:46 tshiozak Exp $ */
4 * Copyright (c)2003 Citrus Project,
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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
29 #include <sys/cdefs.h>
30 #if defined(LIBC_SCCS) && !defined(lint)
31 __RCSID("$NetBSD: citrus_mapper_serial.c,v 1.1 2003/06/25 09:51:46 tshiozak Exp $");
32 #endif /* LIBC_SCCS and not lint */
40 #include <sys/queue.h>
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"
53 /* ---------------------------------------------------------------------- */
55 _CITRUS_MAPPER_DECLS(mapper_serial
);
56 _CITRUS_MAPPER_DEF_OPS(mapper_serial
);
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
,
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
73 /* ---------------------------------------------------------------------- */
76 SIMPLEQ_ENTRY(maplink
) ml_entry
;
77 struct _mapper
*ml_mapper
;
79 SIMPLEQ_HEAD(maplist
, maplink
);
81 struct _citrus_mapper_serial
{
82 struct maplist sr_mappers
;
86 _citrus_mapper_serial_mapper_getops(struct _citrus_mapper_ops
*ops
,
87 size_t lenops
, uint32_t expected_version
)
89 if (expected_version
<_CITRUS_MAPPER_ABI_VERSION
|| lenops
<sizeof(*ops
))
92 memcpy(ops
, &_citrus_mapper_serial_mapper_ops
,
93 sizeof(_citrus_mapper_serial_mapper_ops
));
99 _citrus_mapper_parallel_mapper_getops(struct _citrus_mapper_ops
*ops
,
100 size_t lenops
, uint32_t expected_version
)
102 if (expected_version
<_CITRUS_MAPPER_ABI_VERSION
|| lenops
<sizeof(*ops
))
105 memcpy(ops
, &_citrus_mapper_parallel_mapper_ops
,
106 sizeof(_citrus_mapper_parallel_mapper_ops
));
112 uninit(struct _citrus_mapper_serial
*sr
)
116 while ((ml
= SIMPLEQ_FIRST(&sr
->sr_mappers
)) != NULL
) {
117 SIMPLEQ_REMOVE_HEAD(&sr
->sr_mappers
, ml_entry
);
118 _mapper_close(ml
->ml_mapper
);
124 parse_var(struct _citrus_mapper_area
*__restrict ma
,
125 struct _citrus_mapper_serial
*sr
, struct _memstream
*ms
)
129 char mapname
[PATH_MAX
];
132 SIMPLEQ_INIT(&sr
->sr_mappers
);
134 /* remove beginning white spaces */
135 _memstream_skip_ws(ms
);
136 if (_memstream_iseof(ms
))
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
));
148 ret
= _mapper_open(ma
, &ml
->ml_mapper
, mapname
);
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) {
160 SIMPLEQ_INSERT_TAIL(&sr
->sr_mappers
, ml
, ml_entry
);
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
,
174 struct _citrus_mapper_serial
*sr
;
175 struct _memstream ms
;
178 _DIAGASSERT(cm
&& dir
&& mt
);
180 if (lenmt
<sizeof(*mt
))
183 sr
= malloc(sizeof(*sr
));
187 _region_init(&r
, (void *)var
, lenvar
);
188 _memstream_bind(&ms
, &r
);
189 if (parse_var(ma
, sr
, &ms
)) {
195 mt
->mt_src_max
= mt
->mt_dst_max
= 1; /* 1:1 converter */
196 mt
->mt_state_size
= 0; /* stateless */
203 _citrus_mapper_serial_mapper_uninit(struct _citrus_mapper
*cm
)
205 if (cm
&& cm
->cm_closure
) {
206 uninit(cm
->cm_closure
);
207 free(cm
->cm_closure
);
213 _citrus_mapper_serial_mapper_convert(struct _citrus_mapper
* __restrict cm
,
214 _index_t
* __restrict dst
, _index_t src
,
215 void * __restrict ps
)
218 struct _citrus_mapper_serial
*sr
;
221 _DIAGASSERT(cm
&& 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
)
230 return _MAPPER_CONVERT_SUCCESS
;
235 _citrus_mapper_parallel_mapper_convert(struct _citrus_mapper
* __restrict cm
,
236 _index_t
* __restrict dst
, _index_t src
,
237 void * __restrict ps
)
240 struct _citrus_mapper_serial
*sr
;
244 _DIAGASSERT(cm
&& 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
) {
251 return _MAPPER_CONVERT_SUCCESS
;
252 } else if (ret
== _MAPPER_CONVERT_ILSEQ
)
253 return _MAPPER_CONVERT_ILSEQ
;
255 return _MAPPER_CONVERT_NONIDENTICAL
;
260 _citrus_mapper_serial_mapper_init_state(struct _citrus_mapper
* __restrict cm
,
261 void * __restrict ps
)