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