citrus_mapper_std.c revision 1.10.38.1 1 1.10.38.1 pgoyette /* $NetBSD: citrus_mapper_std.c,v 1.10.38.1 2018/06/25 07:25:34 pgoyette Exp $ */
2 1.1 tshiozak
3 1.1 tshiozak /*-
4 1.7 tnozaki * Copyright (c)2003, 2006 Citrus Project,
5 1.1 tshiozak * All rights reserved.
6 1.1 tshiozak *
7 1.1 tshiozak * Redistribution and use in source and binary forms, with or without
8 1.1 tshiozak * modification, are permitted provided that the following conditions
9 1.1 tshiozak * are met:
10 1.1 tshiozak * 1. Redistributions of source code must retain the above copyright
11 1.1 tshiozak * notice, this list of conditions and the following disclaimer.
12 1.1 tshiozak * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 tshiozak * notice, this list of conditions and the following disclaimer in the
14 1.1 tshiozak * documentation and/or other materials provided with the distribution.
15 1.1 tshiozak *
16 1.1 tshiozak * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 1.1 tshiozak * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 1.1 tshiozak * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 1.1 tshiozak * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 1.1 tshiozak * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 1.1 tshiozak * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 1.1 tshiozak * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 1.1 tshiozak * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 1.1 tshiozak * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 1.1 tshiozak * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 1.1 tshiozak * SUCH DAMAGE.
27 1.1 tshiozak */
28 1.1 tshiozak
29 1.1 tshiozak #include <sys/cdefs.h>
30 1.1 tshiozak #if defined(LIBC_SCCS) && !defined(lint)
31 1.10.38.1 pgoyette __RCSID("$NetBSD: citrus_mapper_std.c,v 1.10.38.1 2018/06/25 07:25:34 pgoyette Exp $");
32 1.1 tshiozak #endif /* LIBC_SCCS and not lint */
33 1.1 tshiozak
34 1.1 tshiozak #include <assert.h>
35 1.1 tshiozak #include <errno.h>
36 1.1 tshiozak #include <limits.h>
37 1.1 tshiozak #include <stdio.h>
38 1.1 tshiozak #include <stdlib.h>
39 1.1 tshiozak #include <stdint.h>
40 1.1 tshiozak #include <string.h>
41 1.5 dogcow #include <machine/endian.h>
42 1.2 tshiozak #include <sys/queue.h>
43 1.1 tshiozak
44 1.1 tshiozak #include "citrus_namespace.h"
45 1.1 tshiozak #include "citrus_types.h"
46 1.1 tshiozak #include "citrus_bcs.h"
47 1.1 tshiozak #include "citrus_region.h"
48 1.1 tshiozak #include "citrus_mmap.h"
49 1.1 tshiozak #include "citrus_module.h"
50 1.1 tshiozak #include "citrus_hash.h"
51 1.1 tshiozak #include "citrus_mapper.h"
52 1.1 tshiozak #include "citrus_db.h"
53 1.1 tshiozak #include "citrus_db_hash.h"
54 1.1 tshiozak
55 1.1 tshiozak #include "citrus_mapper_std.h"
56 1.1 tshiozak #include "citrus_mapper_std_file.h"
57 1.1 tshiozak
58 1.1 tshiozak /* ---------------------------------------------------------------------- */
59 1.1 tshiozak
60 1.1 tshiozak _CITRUS_MAPPER_DECLS(mapper_std);
61 1.1 tshiozak _CITRUS_MAPPER_DEF_OPS(mapper_std);
62 1.1 tshiozak
63 1.1 tshiozak
64 1.1 tshiozak /* ---------------------------------------------------------------------- */
65 1.1 tshiozak
66 1.1 tshiozak int
67 1.1 tshiozak _citrus_mapper_std_mapper_getops(struct _citrus_mapper_ops *ops, size_t lenops,
68 1.1 tshiozak u_int32_t expected_version)
69 1.1 tshiozak {
70 1.1 tshiozak if (expected_version<_CITRUS_MAPPER_ABI_VERSION || lenops<sizeof(*ops))
71 1.1 tshiozak return (EINVAL);
72 1.1 tshiozak
73 1.1 tshiozak memcpy(ops, &_citrus_mapper_std_mapper_ops,
74 1.1 tshiozak sizeof(_citrus_mapper_std_mapper_ops));
75 1.1 tshiozak
76 1.1 tshiozak return (0);
77 1.1 tshiozak }
78 1.1 tshiozak
79 1.1 tshiozak /* ---------------------------------------------------------------------- */
80 1.1 tshiozak
81 1.1 tshiozak static int
82 1.1 tshiozak /*ARGSUSED*/
83 1.1 tshiozak rowcol_convert(struct _citrus_mapper_std * __restrict ms,
84 1.1 tshiozak _index_t * __restrict dst, _index_t src,
85 1.1 tshiozak void * __restrict ps)
86 1.1 tshiozak {
87 1.7 tnozaki struct _citrus_mapper_std_rowcol *rc;
88 1.7 tnozaki size_t i;
89 1.7 tnozaki struct _citrus_mapper_std_linear_zone *lz;
90 1.7 tnozaki _index_t n, idx = 0;
91 1.1 tshiozak u_int32_t conv;
92 1.1 tshiozak
93 1.7 tnozaki _DIAGASSERT(ms != NULL);
94 1.8 tnozaki _DIAGASSERT(dst != NULL);
95 1.7 tnozaki /* ps may be unused */
96 1.7 tnozaki rc = &ms->ms_rowcol;
97 1.7 tnozaki
98 1.7 tnozaki for (i = rc->rc_src_rowcol_len * rc->rc_src_rowcol_bits,
99 1.7 tnozaki lz = &rc->rc_src_rowcol[0]; i > 0; ++lz) {
100 1.7 tnozaki i -= rc->rc_src_rowcol_bits;
101 1.7 tnozaki n = (src >> i) & rc->rc_src_rowcol_mask;
102 1.7 tnozaki if (n < lz->begin || n > lz->end) {
103 1.7 tnozaki switch (rc->rc_oob_mode) {
104 1.7 tnozaki case _CITRUS_MAPPER_STD_OOB_NONIDENTICAL:
105 1.7 tnozaki *dst = rc->rc_dst_invalid;
106 1.7 tnozaki return _MAPPER_CONVERT_NONIDENTICAL;
107 1.7 tnozaki case _CITRUS_MAPPER_STD_OOB_ILSEQ:
108 1.7 tnozaki return _MAPPER_CONVERT_ILSEQ;
109 1.7 tnozaki default:
110 1.7 tnozaki return _MAPPER_CONVERT_FATAL;
111 1.7 tnozaki }
112 1.3 tshiozak }
113 1.7 tnozaki idx = idx * lz->width + n - lz->begin;
114 1.1 tshiozak }
115 1.1 tshiozak switch (rc->rc_dst_unit_bits) {
116 1.1 tshiozak case 8:
117 1.1 tshiozak conv = _region_peek8(&rc->rc_table, idx);
118 1.1 tshiozak break;
119 1.1 tshiozak case 16:
120 1.1 tshiozak conv = be16toh(_region_peek16(&rc->rc_table, idx*2));
121 1.1 tshiozak break;
122 1.1 tshiozak case 32:
123 1.1 tshiozak conv = be32toh(_region_peek32(&rc->rc_table, idx*4));
124 1.1 tshiozak break;
125 1.6 christos default:
126 1.6 christos return _MAPPER_CONVERT_FATAL;
127 1.1 tshiozak }
128 1.1 tshiozak
129 1.1 tshiozak if (conv == rc->rc_dst_invalid) {
130 1.1 tshiozak *dst = rc->rc_dst_invalid;
131 1.3 tshiozak return _MAPPER_CONVERT_NONIDENTICAL;
132 1.1 tshiozak }
133 1.3 tshiozak if (conv == rc->rc_dst_ilseq)
134 1.3 tshiozak return _MAPPER_CONVERT_ILSEQ;
135 1.1 tshiozak
136 1.1 tshiozak *dst = conv;
137 1.1 tshiozak
138 1.1 tshiozak return _MAPPER_CONVERT_SUCCESS;
139 1.1 tshiozak }
140 1.1 tshiozak
141 1.7 tnozaki static __inline int
142 1.7 tnozaki set_linear_zone(struct _citrus_mapper_std_linear_zone *lz,
143 1.7 tnozaki u_int32_t begin, u_int32_t end)
144 1.7 tnozaki {
145 1.7 tnozaki _DIAGASSERT(lz != NULL);
146 1.7 tnozaki
147 1.7 tnozaki if (begin > end)
148 1.7 tnozaki return EFTYPE;
149 1.7 tnozaki
150 1.7 tnozaki lz->begin = begin;
151 1.7 tnozaki lz->end = end;
152 1.7 tnozaki lz->width= end - begin + 1;
153 1.7 tnozaki
154 1.7 tnozaki return 0;
155 1.7 tnozaki }
156 1.7 tnozaki
157 1.7 tnozaki static __inline int
158 1.7 tnozaki rowcol_parse_variable_compat(struct _citrus_mapper_std_rowcol *rc,
159 1.7 tnozaki struct _region *r)
160 1.7 tnozaki {
161 1.7 tnozaki const struct _citrus_mapper_std_rowcol_info_compat_x *rcx;
162 1.7 tnozaki struct _citrus_mapper_std_linear_zone *lz;
163 1.7 tnozaki u_int32_t m, n;
164 1.7 tnozaki int ret;
165 1.7 tnozaki
166 1.7 tnozaki _DIAGASSERT(rc != NULL);
167 1.7 tnozaki _DIAGASSERT(r != NULL && _region_size(r) == sizeof(*rcx));
168 1.7 tnozaki rcx = _region_head(r);
169 1.7 tnozaki
170 1.7 tnozaki rc->rc_dst_invalid = be32toh(rcx->rcx_dst_invalid);
171 1.7 tnozaki rc->rc_dst_unit_bits = be32toh(rcx->rcx_dst_unit_bits);
172 1.7 tnozaki m = be32toh(rcx->rcx_src_col_bits);
173 1.10.38.1 pgoyette n = 1U << (m - 1);
174 1.7 tnozaki n |= n - 1;
175 1.7 tnozaki rc->rc_src_rowcol_bits = m;
176 1.7 tnozaki rc->rc_src_rowcol_mask = n;
177 1.7 tnozaki
178 1.7 tnozaki rc->rc_src_rowcol = malloc(2 *
179 1.8 tnozaki sizeof(*rc->rc_src_rowcol));
180 1.7 tnozaki if (rc->rc_src_rowcol == NULL)
181 1.7 tnozaki return ENOMEM;
182 1.7 tnozaki lz = rc->rc_src_rowcol;
183 1.7 tnozaki rc->rc_src_rowcol_len = 1;
184 1.7 tnozaki m = be32toh(rcx->rcx_src_row_begin);
185 1.7 tnozaki n = be32toh(rcx->rcx_src_row_end);
186 1.7 tnozaki if (m + n > 0) {
187 1.7 tnozaki ret = set_linear_zone(lz, m, n);
188 1.10 tnozaki if (ret != 0) {
189 1.10 tnozaki free(rc->rc_src_rowcol);
190 1.10 tnozaki rc->rc_src_rowcol = NULL;
191 1.7 tnozaki return ret;
192 1.10 tnozaki }
193 1.7 tnozaki ++rc->rc_src_rowcol_len, ++lz;
194 1.7 tnozaki }
195 1.7 tnozaki m = be32toh(rcx->rcx_src_col_begin);
196 1.7 tnozaki n = be32toh(rcx->rcx_src_col_end);
197 1.7 tnozaki
198 1.7 tnozaki return set_linear_zone(lz, m, n);
199 1.7 tnozaki }
200 1.7 tnozaki
201 1.7 tnozaki static __inline int
202 1.7 tnozaki rowcol_parse_variable(struct _citrus_mapper_std_rowcol *rc,
203 1.7 tnozaki struct _region *r)
204 1.7 tnozaki {
205 1.7 tnozaki const struct _citrus_mapper_std_rowcol_info_x *rcx;
206 1.7 tnozaki struct _citrus_mapper_std_linear_zone *lz;
207 1.7 tnozaki u_int32_t m, n;
208 1.7 tnozaki size_t i;
209 1.7 tnozaki int ret;
210 1.7 tnozaki
211 1.7 tnozaki _DIAGASSERT(rc != NULL);
212 1.7 tnozaki _DIAGASSERT(r != NULL && _region_size(r) == sizeof(*rcx));
213 1.7 tnozaki rcx = _region_head(r);
214 1.7 tnozaki
215 1.7 tnozaki rc->rc_dst_invalid = be32toh(rcx->rcx_dst_invalid);
216 1.7 tnozaki rc->rc_dst_unit_bits = be32toh(rcx->rcx_dst_unit_bits);
217 1.7 tnozaki
218 1.7 tnozaki m = be32toh(rcx->rcx_src_rowcol_bits);
219 1.10.38.1 pgoyette n = 1U << (m - 1);
220 1.7 tnozaki n |= n - 1;
221 1.7 tnozaki rc->rc_src_rowcol_bits = m;
222 1.7 tnozaki rc->rc_src_rowcol_mask = n;
223 1.7 tnozaki
224 1.7 tnozaki rc->rc_src_rowcol_len = be32toh(rcx->rcx_src_rowcol_len);
225 1.7 tnozaki if (rc->rc_src_rowcol_len > _CITRUS_MAPPER_STD_ROWCOL_MAX)
226 1.7 tnozaki return EFTYPE;
227 1.7 tnozaki rc->rc_src_rowcol = malloc(rc->rc_src_rowcol_len *
228 1.8 tnozaki sizeof(*rc->rc_src_rowcol));
229 1.7 tnozaki if (rc->rc_src_rowcol == NULL)
230 1.7 tnozaki return ENOMEM;
231 1.7 tnozaki for (i = 0, lz = rc->rc_src_rowcol;
232 1.7 tnozaki i < rc->rc_src_rowcol_len; ++i, ++lz) {
233 1.7 tnozaki m = be32toh(rcx->rcx_src_rowcol[i].begin),
234 1.7 tnozaki n = be32toh(rcx->rcx_src_rowcol[i].end);
235 1.7 tnozaki ret = set_linear_zone(lz, m, n);
236 1.7 tnozaki if (ret != 0) {
237 1.7 tnozaki free(rc->rc_src_rowcol);
238 1.7 tnozaki rc->rc_src_rowcol = NULL;
239 1.7 tnozaki return ret;
240 1.7 tnozaki }
241 1.7 tnozaki }
242 1.7 tnozaki return 0;
243 1.7 tnozaki }
244 1.7 tnozaki
245 1.7 tnozaki static void
246 1.7 tnozaki rowcol_uninit(struct _citrus_mapper_std *ms)
247 1.7 tnozaki {
248 1.7 tnozaki struct _citrus_mapper_std_rowcol *rc;
249 1.7 tnozaki _DIAGASSERT(ms != NULL);
250 1.7 tnozaki
251 1.7 tnozaki rc = &ms->ms_rowcol;
252 1.7 tnozaki free(rc->rc_src_rowcol);
253 1.7 tnozaki }
254 1.1 tshiozak
255 1.1 tshiozak static int
256 1.1 tshiozak rowcol_init(struct _citrus_mapper_std *ms)
257 1.1 tshiozak {
258 1.1 tshiozak int ret;
259 1.7 tnozaki struct _citrus_mapper_std_rowcol *rc;
260 1.3 tshiozak const struct _citrus_mapper_std_rowcol_ext_ilseq_info_x *eix;
261 1.1 tshiozak struct _region r;
262 1.1 tshiozak u_int64_t table_size;
263 1.7 tnozaki size_t i;
264 1.7 tnozaki struct _citrus_mapper_std_linear_zone *lz;
265 1.1 tshiozak
266 1.7 tnozaki _DIAGASSERT(ms != NULL);
267 1.1 tshiozak ms->ms_convert = &rowcol_convert;
268 1.7 tnozaki ms->ms_uninit = &rowcol_uninit;
269 1.7 tnozaki rc = &ms->ms_rowcol;
270 1.1 tshiozak
271 1.1 tshiozak /* get table region */
272 1.1 tshiozak ret = _db_lookup_by_s(ms->ms_db, _CITRUS_MAPPER_STD_SYM_TABLE,
273 1.1 tshiozak &rc->rc_table, NULL);
274 1.1 tshiozak if (ret) {
275 1.1 tshiozak if (ret==ENOENT)
276 1.1 tshiozak ret = EFTYPE;
277 1.1 tshiozak return ret;
278 1.1 tshiozak }
279 1.1 tshiozak
280 1.1 tshiozak /* get table information */
281 1.1 tshiozak ret = _db_lookup_by_s(ms->ms_db, _CITRUS_MAPPER_STD_SYM_INFO, &r, NULL);
282 1.1 tshiozak if (ret) {
283 1.1 tshiozak if (ret==ENOENT)
284 1.3 tshiozak ret = EFTYPE;
285 1.1 tshiozak return ret;
286 1.1 tshiozak }
287 1.7 tnozaki switch (_region_size(&r)) {
288 1.7 tnozaki case _CITRUS_MAPPER_STD_ROWCOL_INFO_COMPAT_SIZE:
289 1.7 tnozaki ret = rowcol_parse_variable_compat(rc, &r);
290 1.7 tnozaki break;
291 1.7 tnozaki case _CITRUS_MAPPER_STD_ROWCOL_INFO_SIZE:
292 1.7 tnozaki ret = rowcol_parse_variable(rc, &r);
293 1.7 tnozaki break;
294 1.7 tnozaki default:
295 1.7 tnozaki return EFTYPE;
296 1.7 tnozaki }
297 1.7 tnozaki if (ret != 0)
298 1.7 tnozaki return ret;
299 1.7 tnozaki /* sanity check */
300 1.7 tnozaki switch (rc->rc_src_rowcol_bits) {
301 1.7 tnozaki case 8: case 16: case 32:
302 1.7 tnozaki if (rc->rc_src_rowcol_len <= 32 / rc->rc_src_rowcol_bits)
303 1.7 tnozaki break;
304 1.7 tnozaki /*FALLTHROUGH*/
305 1.7 tnozaki default:
306 1.1 tshiozak return EFTYPE;
307 1.7 tnozaki }
308 1.1 tshiozak
309 1.3 tshiozak /* ilseq extension */
310 1.3 tshiozak rc->rc_oob_mode = _CITRUS_MAPPER_STD_OOB_NONIDENTICAL;
311 1.3 tshiozak rc->rc_dst_ilseq = rc->rc_dst_invalid;
312 1.3 tshiozak ret = _db_lookup_by_s(ms->ms_db,
313 1.3 tshiozak _CITRUS_MAPPER_STD_SYM_ROWCOL_EXT_ILSEQ,
314 1.3 tshiozak &r, NULL);
315 1.3 tshiozak if (ret && ret != ENOENT)
316 1.3 tshiozak return ret;
317 1.3 tshiozak if (_region_size(&r) < sizeof(*eix))
318 1.3 tshiozak return EFTYPE;
319 1.3 tshiozak if (ret == 0) {
320 1.3 tshiozak eix = _region_head(&r);
321 1.3 tshiozak rc->rc_oob_mode = be32toh(eix->eix_oob_mode);
322 1.3 tshiozak rc->rc_dst_ilseq = be32toh(eix->eix_dst_ilseq);
323 1.3 tshiozak }
324 1.1 tshiozak
325 1.1 tshiozak /* calcurate expected table size */
326 1.7 tnozaki i = rc->rc_src_rowcol_len;
327 1.7 tnozaki lz = &rc->rc_src_rowcol[--i];
328 1.7 tnozaki table_size = lz->width;
329 1.7 tnozaki while (i > 0) {
330 1.7 tnozaki lz = &rc->rc_src_rowcol[--i];
331 1.7 tnozaki table_size *= lz->width;
332 1.7 tnozaki }
333 1.1 tshiozak table_size *= rc->rc_dst_unit_bits/8;
334 1.1 tshiozak
335 1.1 tshiozak if (table_size > UINT32_MAX ||
336 1.1 tshiozak _region_size(&rc->rc_table) < table_size)
337 1.1 tshiozak return EFTYPE;
338 1.1 tshiozak
339 1.1 tshiozak return 0;
340 1.1 tshiozak }
341 1.1 tshiozak
342 1.1 tshiozak typedef int (*initfunc_t)(struct _citrus_mapper_std *);
343 1.4 yamt static const struct {
344 1.1 tshiozak const char *t_name;
345 1.1 tshiozak initfunc_t t_init;
346 1.1 tshiozak } types[] = {
347 1.1 tshiozak { _CITRUS_MAPPER_STD_TYPE_ROWCOL, &rowcol_init },
348 1.1 tshiozak };
349 1.1 tshiozak #define NUM_OF_TYPES ((int)(sizeof(types)/sizeof(types[0])))
350 1.1 tshiozak
351 1.1 tshiozak static int
352 1.1 tshiozak /*ARGSUSED*/
353 1.1 tshiozak _citrus_mapper_std_mapper_init(struct _citrus_mapper_area *__restrict ma,
354 1.1 tshiozak struct _citrus_mapper * __restrict cm,
355 1.1 tshiozak const char * __restrict curdir,
356 1.1 tshiozak const void * __restrict var, size_t lenvar,
357 1.1 tshiozak struct _citrus_mapper_traits * __restrict mt,
358 1.1 tshiozak size_t lenmt)
359 1.1 tshiozak {
360 1.1 tshiozak char path[PATH_MAX];
361 1.1 tshiozak const char *type;
362 1.1 tshiozak int ret, id;
363 1.1 tshiozak struct _citrus_mapper_std *ms;
364 1.1 tshiozak
365 1.1 tshiozak /* set traits */
366 1.1 tshiozak if (lenmt<sizeof(*mt)) {
367 1.1 tshiozak ret = EINVAL;
368 1.1 tshiozak goto err0;
369 1.1 tshiozak }
370 1.1 tshiozak mt->mt_src_max = mt->mt_dst_max = 1; /* 1:1 converter */
371 1.1 tshiozak mt->mt_state_size = 0; /* stateless */
372 1.1 tshiozak
373 1.1 tshiozak /* alloc mapper std structure */
374 1.1 tshiozak ms = malloc(sizeof(*ms));
375 1.1 tshiozak if (ms==NULL) {
376 1.1 tshiozak ret = errno;
377 1.1 tshiozak goto err0;
378 1.1 tshiozak }
379 1.1 tshiozak
380 1.1 tshiozak /* open mapper file */
381 1.1 tshiozak snprintf(path, sizeof(path),
382 1.1 tshiozak "%s/%.*s", curdir, (int)lenvar, (const char *)var);
383 1.1 tshiozak ret = _map_file(&ms->ms_file, path);
384 1.1 tshiozak if (ret)
385 1.1 tshiozak goto err1;
386 1.1 tshiozak
387 1.1 tshiozak ret = _db_open(&ms->ms_db, &ms->ms_file, _CITRUS_MAPPER_STD_MAGIC,
388 1.1 tshiozak &_db_hash_std, NULL);
389 1.1 tshiozak if (ret)
390 1.1 tshiozak goto err2;
391 1.1 tshiozak
392 1.1 tshiozak /* get mapper type */
393 1.1 tshiozak ret = _db_lookupstr_by_s(ms->ms_db, _CITRUS_MAPPER_STD_SYM_TYPE,
394 1.1 tshiozak &type, NULL);
395 1.1 tshiozak if (ret) {
396 1.1 tshiozak if (ret==ENOENT)
397 1.1 tshiozak ret = EFTYPE;
398 1.1 tshiozak goto err3;
399 1.1 tshiozak }
400 1.1 tshiozak for (id=0; id<NUM_OF_TYPES; id++)
401 1.1 tshiozak if (_bcs_strcasecmp(type, types[id].t_name) == 0)
402 1.1 tshiozak break;
403 1.1 tshiozak
404 1.1 tshiozak if (id == NUM_OF_TYPES)
405 1.1 tshiozak goto err3;
406 1.1 tshiozak
407 1.1 tshiozak /* init the per-type structure */
408 1.1 tshiozak ret = (*types[id].t_init)(ms);
409 1.1 tshiozak if (ret)
410 1.1 tshiozak goto err3;
411 1.1 tshiozak
412 1.1 tshiozak cm->cm_closure = ms;
413 1.1 tshiozak
414 1.1 tshiozak return 0;
415 1.1 tshiozak
416 1.1 tshiozak err3:
417 1.1 tshiozak _db_close(ms->ms_db);
418 1.1 tshiozak err2:
419 1.1 tshiozak _unmap_file(&ms->ms_file);
420 1.1 tshiozak err1:
421 1.1 tshiozak free(ms);
422 1.1 tshiozak err0:
423 1.1 tshiozak return ret;
424 1.1 tshiozak }
425 1.1 tshiozak
426 1.1 tshiozak static void
427 1.1 tshiozak /*ARGSUSED*/
428 1.1 tshiozak _citrus_mapper_std_mapper_uninit(struct _citrus_mapper *cm)
429 1.1 tshiozak {
430 1.1 tshiozak struct _citrus_mapper_std *ms;
431 1.1 tshiozak
432 1.9 wiz _DIAGASSERT(cm!=NULL && cm->cm_closure!=NULL);
433 1.1 tshiozak
434 1.1 tshiozak ms = cm->cm_closure;
435 1.1 tshiozak if (ms->ms_uninit)
436 1.1 tshiozak (*ms->ms_uninit)(ms);
437 1.1 tshiozak _db_close(ms->ms_db);
438 1.1 tshiozak _unmap_file(&ms->ms_file);
439 1.1 tshiozak free(ms);
440 1.1 tshiozak }
441 1.1 tshiozak
442 1.1 tshiozak static void
443 1.1 tshiozak /*ARGSUSED*/
444 1.1 tshiozak _citrus_mapper_std_mapper_init_state(struct _citrus_mapper * __restrict cm,
445 1.1 tshiozak void * __restrict ps)
446 1.1 tshiozak {
447 1.1 tshiozak }
448 1.1 tshiozak
449 1.1 tshiozak static int
450 1.1 tshiozak /*ARGSUSED*/
451 1.1 tshiozak _citrus_mapper_std_mapper_convert(struct _citrus_mapper * __restrict cm,
452 1.1 tshiozak _index_t * __restrict dst, _index_t src,
453 1.1 tshiozak void * __restrict ps)
454 1.1 tshiozak {
455 1.1 tshiozak struct _citrus_mapper_std *ms;
456 1.1 tshiozak
457 1.1 tshiozak _DIAGASSERT(cm!=NULL && cm->cm_closure!=NULL);
458 1.1 tshiozak
459 1.1 tshiozak ms = cm->cm_closure;
460 1.1 tshiozak
461 1.1 tshiozak _DIAGASSERT(ms->ms_convert != NULL);
462 1.1 tshiozak
463 1.1 tshiozak return (*ms->ms_convert)(ms, dst, src, ps);
464 1.1 tshiozak }
465