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