xref: /freebsd/lib/libc/iconv/citrus_memstream.h (revision a7623790fb345e6dc986dfd31df0ace115e6f2e4)
1 /* $FreeBSD$ */
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
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
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
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
80 _citrus_memory_stream_rewind(struct _citrus_memory_stream *ms)
81 {
82 
83 	ms->ms_pos = 0;
84 }
85 
86 static __inline size_t
87 _citrus_memory_stream_tell(struct _citrus_memory_stream *ms)
88 {
89 
90 	return (ms->ms_pos);
91 }
92 
93 static __inline size_t
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
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
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
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
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 *
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
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
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
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
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