1 /* $FreeBSD: head/lib/libiconv_modules/mapper_serial/citrus_mapper_serial.c 219019 2011-02-25 00:04:39Z gabor $ */
2 /* $NetBSD: citrus_mapper_serial.c,v 1.2 2003/07/12 15:39:20 tshiozak Exp $ */
5 * Copyright (c)2003 Citrus Project,
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include <sys/cdefs.h>
31 #include <sys/queue.h>
40 #include "citrus_namespace.h"
41 #include "citrus_types.h"
42 #include "citrus_bcs.h"
43 #include "citrus_module.h"
44 #include "citrus_region.h"
45 #include "citrus_memstream.h"
46 #include "citrus_mmap.h"
47 #include "citrus_hash.h"
48 #include "citrus_mapper.h"
49 #include "citrus_mapper_serial.h"
51 /* ---------------------------------------------------------------------- */
53 _CITRUS_MAPPER_DECLS(mapper_serial
);
54 _CITRUS_MAPPER_DEF_OPS(mapper_serial
);
56 #define _citrus_mapper_parallel_mapper_init \
57 _citrus_mapper_serial_mapper_init
58 #define _citrus_mapper_parallel_mapper_uninit \
59 _citrus_mapper_serial_mapper_uninit
60 #define _citrus_mapper_parallel_mapper_init_state \
61 _citrus_mapper_serial_mapper_init_state
62 static int _citrus_mapper_parallel_mapper_convert(
63 struct _citrus_mapper
* __restrict
, _index_t
* __restrict
,
64 _index_t
, void * __restrict
);
65 _CITRUS_MAPPER_DEF_OPS(mapper_parallel
);
66 #undef _citrus_mapper_parallel_mapper_init
67 #undef _citrus_mapper_parallel_mapper_uninit
68 #undef _citrus_mapper_parallel_mapper_init_state
71 /* ---------------------------------------------------------------------- */
74 STAILQ_ENTRY(maplink
) ml_entry
;
75 struct _mapper
*ml_mapper
;
77 STAILQ_HEAD(maplist
, maplink
);
79 struct _citrus_mapper_serial
{
80 struct maplist sr_mappers
;
84 _citrus_mapper_serial_mapper_getops(struct _citrus_mapper_ops
*ops
)
87 memcpy(ops
, &_citrus_mapper_serial_mapper_ops
,
88 sizeof(_citrus_mapper_serial_mapper_ops
));
94 _citrus_mapper_parallel_mapper_getops(struct _citrus_mapper_ops
*ops
)
97 memcpy(ops
, &_citrus_mapper_parallel_mapper_ops
,
98 sizeof(_citrus_mapper_parallel_mapper_ops
));
104 uninit(struct _citrus_mapper_serial
*sr
)
108 while ((ml
= STAILQ_FIRST(&sr
->sr_mappers
)) != NULL
) {
109 STAILQ_REMOVE_HEAD(&sr
->sr_mappers
, ml_entry
);
110 _mapper_close(ml
->ml_mapper
);
116 parse_var(struct _citrus_mapper_area
*__restrict ma
,
117 struct _citrus_mapper_serial
*sr
, struct _memstream
*ms
)
121 char mapname
[PATH_MAX
];
124 STAILQ_INIT(&sr
->sr_mappers
);
126 /* remove beginning white spaces */
127 _memstream_skip_ws(ms
);
128 if (_memstream_iseof(ms
))
130 /* cut down a mapper name */
131 _memstream_chr(ms
, &r
, ',');
132 snprintf(mapname
, sizeof(mapname
), "%.*s",
133 (int)_region_size(&r
), (char *)_region_head(&r
));
134 /* remove trailing white spaces */
135 mapname
[_bcs_skip_nonws(mapname
)-mapname
] = '\0';
136 /* create a new mapper record */
137 ml
= malloc(sizeof(*ml
));
140 ret
= _mapper_open(ma
, &ml
->ml_mapper
, mapname
);
145 /* support only 1:1 and stateless converter */
146 if (_mapper_get_src_max(ml
->ml_mapper
) != 1 ||
147 _mapper_get_dst_max(ml
->ml_mapper
) != 1 ||
148 _mapper_get_state_size(ml
->ml_mapper
) != 0) {
152 STAILQ_INSERT_TAIL(&sr
->sr_mappers
, ml
, ml_entry
);
159 _citrus_mapper_serial_mapper_init(struct _citrus_mapper_area
*__restrict ma __unused
,
160 struct _citrus_mapper
* __restrict cm
, const char * __restrict dir __unused
,
161 const void * __restrict var
, size_t lenvar
,
162 struct _citrus_mapper_traits
* __restrict mt
, size_t lenmt
)
164 struct _citrus_mapper_serial
*sr
;
165 struct _memstream ms
;
168 if (lenmt
< sizeof(*mt
))
171 sr
= malloc(sizeof(*sr
));
175 _region_init(&r
, __DECONST(void *, var
), lenvar
);
176 _memstream_bind(&ms
, &r
);
177 if (parse_var(ma
, sr
, &ms
)) {
183 mt
->mt_src_max
= mt
->mt_dst_max
= 1; /* 1:1 converter */
184 mt
->mt_state_size
= 0; /* stateless */
191 _citrus_mapper_serial_mapper_uninit(struct _citrus_mapper
*cm
)
194 if (cm
&& cm
->cm_closure
) {
195 uninit(cm
->cm_closure
);
196 free(cm
->cm_closure
);
202 _citrus_mapper_serial_mapper_convert(struct _citrus_mapper
* __restrict cm
,
203 _index_t
* __restrict dst
, _index_t src
, void * __restrict ps __unused
)
205 struct _citrus_mapper_serial
*sr
;
210 STAILQ_FOREACH(ml
, &sr
->sr_mappers
, ml_entry
) {
211 ret
= _mapper_convert(ml
->ml_mapper
, &src
, src
, NULL
);
212 if (ret
!= _MAPPER_CONVERT_SUCCESS
)
216 return (_MAPPER_CONVERT_SUCCESS
);
221 _citrus_mapper_parallel_mapper_convert(struct _citrus_mapper
* __restrict cm
,
222 _index_t
* __restrict dst
, _index_t src
, void * __restrict ps __unused
)
224 struct _citrus_mapper_serial
*sr
;
230 STAILQ_FOREACH(ml
, &sr
->sr_mappers
, ml_entry
) {
231 ret
= _mapper_convert(ml
->ml_mapper
, &tmp
, src
, NULL
);
232 if (ret
== _MAPPER_CONVERT_SUCCESS
) {
234 return (_MAPPER_CONVERT_SUCCESS
);
235 } else if (ret
== _MAPPER_CONVERT_ILSEQ
)
236 return (_MAPPER_CONVERT_ILSEQ
);
238 return (_MAPPER_CONVERT_NONIDENTICAL
);
243 _citrus_mapper_serial_mapper_init_state(void)