1 /* $FreeBSD: stable/12/lib/libc/iconv/citrus_memstream.h 326193 2017-11-25 17:12:48Z pfg $ */
2 /* $NetBSD: citrus_memstream.h,v 1.3 2005/05/14 17:55:42 tshiozak Exp $ */
3
4 /*-
5 * SPDX-License-Identifier: BSD-2-Clause
6 *
7 * Copyright (c)2003 Citrus Project,
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 */
32
33 #ifndef _CITRUS_MEMSTREAM_H_
34 #define _CITRUS_MEMSTREAM_H_
35
36 struct _citrus_memory_stream {
37 struct _citrus_region ms_region;
38 size_t ms_pos;
39 };
40
41 __BEGIN_DECLS
42 const char *_citrus_memory_stream_getln(
43 struct _citrus_memory_stream * __restrict,
44 size_t * __restrict);
45 const char *_citrus_memory_stream_matchline(
46 struct _citrus_memory_stream * __restrict,
47 const char * __restrict, size_t * __restrict, int);
48 void *_citrus_memory_stream_chr(struct _citrus_memory_stream *,
49 struct _citrus_region *, char);
50 void _citrus_memory_stream_skip_ws(struct _citrus_memory_stream *);
51 __END_DECLS
52
53 static __inline int
_citrus_memory_stream_iseof(struct _citrus_memory_stream * ms)54 _citrus_memory_stream_iseof(struct _citrus_memory_stream *ms)
55 {
56
57 return (ms->ms_pos >= _citrus_region_size(&ms->ms_region));
58 }
59
60 static __inline void
_citrus_memory_stream_bind(struct _citrus_memory_stream * __restrict ms,const struct _citrus_region * __restrict r)61 _citrus_memory_stream_bind(struct _citrus_memory_stream * __restrict ms,
62 const struct _citrus_region * __restrict r)
63 {
64
65 ms->ms_region = *r;
66 ms->ms_pos = 0;
67 }
68
69 static __inline void
_citrus_memory_stream_bind_ptr(struct _citrus_memory_stream * __restrict ms,void * ptr,size_t sz)70 _citrus_memory_stream_bind_ptr(struct _citrus_memory_stream * __restrict ms,
71 void *ptr, size_t sz)
72 {
73 struct _citrus_region r;
74
75 _citrus_region_init(&r, ptr, sz);
76 _citrus_memory_stream_bind(ms, &r);
77 }
78
79 static __inline void
_citrus_memory_stream_rewind(struct _citrus_memory_stream * ms)80 _citrus_memory_stream_rewind(struct _citrus_memory_stream *ms)
81 {
82
83 ms->ms_pos = 0;
84 }
85
86 static __inline size_t
_citrus_memory_stream_tell(struct _citrus_memory_stream * ms)87 _citrus_memory_stream_tell(struct _citrus_memory_stream *ms)
88 {
89
90 return (ms->ms_pos);
91 }
92
93 static __inline size_t
_citrus_memory_stream_remainder(struct _citrus_memory_stream * ms)94 _citrus_memory_stream_remainder(struct _citrus_memory_stream *ms)
95 {
96 size_t sz;
97
98 sz = _citrus_region_size(&ms->ms_region);
99 if (ms->ms_pos>sz)
100 return (0);
101 return (sz-ms->ms_pos);
102 }
103
104 static __inline int
_citrus_memory_stream_seek(struct _citrus_memory_stream * ms,size_t pos,int w)105 _citrus_memory_stream_seek(struct _citrus_memory_stream *ms, size_t pos, int w)
106 {
107 size_t sz;
108
109 sz = _citrus_region_size(&ms->ms_region);
110
111 switch (w) {
112 case SEEK_SET:
113 if (pos >= sz)
114 return (-1);
115 ms->ms_pos = pos;
116 break;
117 case SEEK_CUR:
118 pos += (ssize_t)ms->ms_pos;
119 if (pos >= sz)
120 return (-1);
121 ms->ms_pos = pos;
122 break;
123 case SEEK_END:
124 if (sz < pos)
125 return (-1);
126 ms->ms_pos = sz - pos;
127 break;
128 }
129 return (0);
130 }
131
132 static __inline int
_citrus_memory_stream_getc(struct _citrus_memory_stream * ms)133 _citrus_memory_stream_getc(struct _citrus_memory_stream *ms)
134 {
135
136 if (_citrus_memory_stream_iseof(ms))
137 return (EOF);
138 return (_citrus_region_peek8(&ms->ms_region, ms->ms_pos++));
139 }
140
141 static __inline void
_citrus_memory_stream_ungetc(struct _citrus_memory_stream * ms,int ch)142 _citrus_memory_stream_ungetc(struct _citrus_memory_stream *ms, int ch)
143 {
144
145 if (ch != EOF && ms->ms_pos > 0)
146 ms->ms_pos--;
147 }
148
149 static __inline int
_citrus_memory_stream_peek(struct _citrus_memory_stream * ms)150 _citrus_memory_stream_peek(struct _citrus_memory_stream *ms)
151 {
152
153 if (_citrus_memory_stream_iseof(ms))
154 return (EOF);
155 return (_citrus_region_peek8(&ms->ms_region, ms->ms_pos));
156 }
157
158 static __inline void *
_citrus_memory_stream_getregion(struct _citrus_memory_stream * ms,struct _citrus_region * r,size_t sz)159 _citrus_memory_stream_getregion(struct _citrus_memory_stream *ms,
160 struct _citrus_region *r, size_t sz)
161 {
162 void *ret;
163
164 if (ms->ms_pos + sz > _citrus_region_size(&ms->ms_region))
165 return (NULL);
166
167 ret = _citrus_region_offset(&ms->ms_region, ms->ms_pos);
168 ms->ms_pos += sz;
169 if (r)
170 _citrus_region_init(r, ret, sz);
171
172 return (ret);
173 }
174
175 static __inline int
_citrus_memory_stream_get8(struct _citrus_memory_stream * ms,uint8_t * rval)176 _citrus_memory_stream_get8(struct _citrus_memory_stream *ms, uint8_t *rval)
177 {
178
179 if (ms->ms_pos + 1 > _citrus_region_size(&ms->ms_region))
180 return (-1);
181
182 *rval = _citrus_region_peek8(&ms->ms_region, ms->ms_pos);
183 ms->ms_pos += 2;
184
185 return (0);
186 }
187
188 static __inline int
_citrus_memory_stream_get16(struct _citrus_memory_stream * ms,uint16_t * rval)189 _citrus_memory_stream_get16(struct _citrus_memory_stream *ms, uint16_t *rval)
190 {
191
192 if (ms->ms_pos + 2 > _citrus_region_size(&ms->ms_region))
193 return (-1);
194
195 *rval = _citrus_region_peek16(&ms->ms_region, ms->ms_pos);
196 ms->ms_pos += 2;
197
198 return (0);
199 }
200
201 static __inline int
_citrus_memory_stream_get32(struct _citrus_memory_stream * ms,uint32_t * rval)202 _citrus_memory_stream_get32(struct _citrus_memory_stream *ms, uint32_t *rval)
203 {
204
205 if (ms->ms_pos + 4 > _citrus_region_size(&ms->ms_region))
206 return (-1);
207
208 *rval = _citrus_region_peek32(&ms->ms_region, ms->ms_pos);
209 ms->ms_pos += 4;
210
211 return (0);
212 }
213
214 static __inline int
_citrus_memory_stream_getln_region(struct _citrus_memory_stream * ms,struct _citrus_region * r)215 _citrus_memory_stream_getln_region(struct _citrus_memory_stream *ms,
216 struct _citrus_region *r)
217 {
218 const char *ptr;
219 size_t sz;
220
221 ptr = _citrus_memory_stream_getln(ms, &sz);
222 if (ptr)
223 _citrus_region_init(r, __DECONST(void *, ptr), sz);
224
225 return (ptr == NULL);
226 }
227
228 #endif
229