1219019Sgabor/* $FreeBSD$ */
2219019Sgabor/* $NetBSD: citrus_memstream.h,v 1.3 2005/05/14 17:55:42 tshiozak Exp $ */
3219019Sgabor
4219019Sgabor/*-
5219019Sgabor * Copyright (c)2003 Citrus Project,
6219019Sgabor * All rights reserved.
7219019Sgabor *
8219019Sgabor * Redistribution and use in source and binary forms, with or without
9219019Sgabor * modification, are permitted provided that the following conditions
10219019Sgabor * are met:
11219019Sgabor * 1. Redistributions of source code must retain the above copyright
12219019Sgabor *    notice, this list of conditions and the following disclaimer.
13219019Sgabor * 2. Redistributions in binary form must reproduce the above copyright
14219019Sgabor *    notice, this list of conditions and the following disclaimer in the
15219019Sgabor *    documentation and/or other materials provided with the distribution.
16219019Sgabor *
17219019Sgabor * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18219019Sgabor * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19219019Sgabor * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20219019Sgabor * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21219019Sgabor * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22219019Sgabor * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23219019Sgabor * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24219019Sgabor * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25219019Sgabor * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26219019Sgabor * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27219019Sgabor * SUCH DAMAGE.
28219019Sgabor *
29219019Sgabor */
30219019Sgabor
31219019Sgabor#ifndef _CITRUS_MEMSTREAM_H_
32219019Sgabor#define _CITRUS_MEMSTREAM_H_
33219019Sgabor
34219019Sgaborstruct _citrus_memory_stream {
35219019Sgabor	struct _citrus_region	ms_region;
36219019Sgabor	size_t			ms_pos;
37219019Sgabor};
38219019Sgabor
39219019Sgabor__BEGIN_DECLS
40219019Sgaborconst char	*_citrus_memory_stream_getln(
41219019Sgabor		    struct _citrus_memory_stream * __restrict,
42219019Sgabor		    size_t * __restrict);
43219019Sgaborconst char	*_citrus_memory_stream_matchline(
44219019Sgabor		    struct _citrus_memory_stream * __restrict,
45219019Sgabor		    const char * __restrict, size_t * __restrict, int);
46219019Sgaborvoid		*_citrus_memory_stream_chr(struct _citrus_memory_stream *,
47219019Sgabor		    struct _citrus_region *, char);
48219019Sgaborvoid		_citrus_memory_stream_skip_ws(struct _citrus_memory_stream *);
49219019Sgabor__END_DECLS
50219019Sgabor
51219019Sgaborstatic __inline int
52219019Sgabor_citrus_memory_stream_iseof(struct _citrus_memory_stream *ms)
53219019Sgabor{
54219019Sgabor
55219019Sgabor	return (ms->ms_pos >= _citrus_region_size(&ms->ms_region));
56219019Sgabor}
57219019Sgabor
58219019Sgaborstatic __inline void
59219019Sgabor_citrus_memory_stream_bind(struct _citrus_memory_stream * __restrict ms,
60219019Sgabor    const struct _citrus_region * __restrict r)
61219019Sgabor{
62219019Sgabor
63219019Sgabor	ms->ms_region = *r;
64219019Sgabor	ms->ms_pos = 0;
65219019Sgabor}
66219019Sgabor
67219019Sgaborstatic __inline void
68219019Sgabor_citrus_memory_stream_bind_ptr(struct _citrus_memory_stream * __restrict ms,
69219019Sgabor    void *ptr, size_t sz)
70219019Sgabor{
71219019Sgabor	struct _citrus_region r;
72219019Sgabor
73219019Sgabor	_citrus_region_init(&r, ptr, sz);
74219019Sgabor	_citrus_memory_stream_bind(ms, &r);
75219019Sgabor}
76219019Sgabor
77219019Sgaborstatic __inline void
78219019Sgabor_citrus_memory_stream_rewind(struct _citrus_memory_stream *ms)
79219019Sgabor{
80219019Sgabor
81219019Sgabor	ms->ms_pos = 0;
82219019Sgabor}
83219019Sgabor
84219019Sgaborstatic __inline size_t
85219019Sgabor_citrus_memory_stream_tell(struct _citrus_memory_stream *ms)
86219019Sgabor{
87219019Sgabor
88219019Sgabor	return (ms->ms_pos);
89219019Sgabor}
90219019Sgabor
91219019Sgaborstatic __inline size_t
92219019Sgabor_citrus_memory_stream_remainder(struct _citrus_memory_stream *ms)
93219019Sgabor{
94219019Sgabor	size_t sz;
95219019Sgabor
96219019Sgabor	sz = _citrus_region_size(&ms->ms_region);
97219019Sgabor	if (ms->ms_pos>sz)
98219019Sgabor		return (0);
99219019Sgabor	return (sz-ms->ms_pos);
100219019Sgabor}
101219019Sgabor
102219019Sgaborstatic __inline int
103219019Sgabor_citrus_memory_stream_seek(struct _citrus_memory_stream *ms, size_t pos, int w)
104219019Sgabor{
105219019Sgabor	size_t sz;
106219019Sgabor
107219019Sgabor	sz = _citrus_region_size(&ms->ms_region);
108219019Sgabor
109219019Sgabor	switch (w) {
110219019Sgabor	case SEEK_SET:
111219019Sgabor		if (pos >= sz)
112219019Sgabor			return (-1);
113219019Sgabor		ms->ms_pos = pos;
114219019Sgabor		break;
115219019Sgabor	case SEEK_CUR:
116219019Sgabor		pos += (ssize_t)ms->ms_pos;
117219019Sgabor		if (pos >= sz)
118219019Sgabor			return (-1);
119219019Sgabor		ms->ms_pos = pos;
120219019Sgabor		break;
121219019Sgabor	case SEEK_END:
122219019Sgabor		if (sz < pos)
123219019Sgabor			return (-1);
124219019Sgabor		ms->ms_pos = sz - pos;
125219019Sgabor		break;
126219019Sgabor	}
127219019Sgabor	return (0);
128219019Sgabor}
129219019Sgabor
130219019Sgaborstatic __inline int
131219019Sgabor_citrus_memory_stream_getc(struct _citrus_memory_stream *ms)
132219019Sgabor{
133219019Sgabor
134219019Sgabor	if (_citrus_memory_stream_iseof(ms))
135219019Sgabor		return (EOF);
136219019Sgabor	return (_citrus_region_peek8(&ms->ms_region, ms->ms_pos++));
137219019Sgabor}
138219019Sgabor
139219019Sgaborstatic __inline void
140219019Sgabor_citrus_memory_stream_ungetc(struct _citrus_memory_stream *ms, int ch)
141219019Sgabor{
142219019Sgabor
143219019Sgabor	if (ch != EOF && ms->ms_pos > 0)
144219019Sgabor		ms->ms_pos--;
145219019Sgabor}
146219019Sgabor
147219019Sgaborstatic __inline int
148219019Sgabor_citrus_memory_stream_peek(struct _citrus_memory_stream *ms)
149219019Sgabor{
150219019Sgabor
151219019Sgabor	if (_citrus_memory_stream_iseof(ms))
152219019Sgabor		return (EOF);
153219019Sgabor	return (_citrus_region_peek8(&ms->ms_region, ms->ms_pos));
154219019Sgabor}
155219019Sgabor
156219019Sgaborstatic __inline void *
157219019Sgabor_citrus_memory_stream_getregion(struct _citrus_memory_stream *ms,
158219019Sgabor    struct _citrus_region *r, size_t sz)
159219019Sgabor{
160219019Sgabor	void *ret;
161219019Sgabor
162219019Sgabor	if (ms->ms_pos + sz > _citrus_region_size(&ms->ms_region))
163219019Sgabor		return (NULL);
164219019Sgabor
165219019Sgabor	ret = _citrus_region_offset(&ms->ms_region, ms->ms_pos);
166219019Sgabor	ms->ms_pos += sz;
167219019Sgabor	if (r)
168219019Sgabor		_citrus_region_init(r, ret, sz);
169219019Sgabor
170219019Sgabor	return (ret);
171219019Sgabor}
172219019Sgabor
173219019Sgaborstatic __inline int
174219019Sgabor_citrus_memory_stream_get8(struct _citrus_memory_stream *ms, uint8_t *rval)
175219019Sgabor{
176219019Sgabor
177219019Sgabor	if (ms->ms_pos + 1 > _citrus_region_size(&ms->ms_region))
178219019Sgabor		return (-1);
179219019Sgabor
180219019Sgabor	*rval = _citrus_region_peek8(&ms->ms_region, ms->ms_pos);
181219019Sgabor	ms->ms_pos += 2;
182219019Sgabor
183219019Sgabor	return (0);
184219019Sgabor}
185219019Sgabor
186219019Sgaborstatic __inline int
187219019Sgabor_citrus_memory_stream_get16(struct _citrus_memory_stream *ms, uint16_t *rval)
188219019Sgabor{
189219019Sgabor
190219019Sgabor	if (ms->ms_pos + 2 > _citrus_region_size(&ms->ms_region))
191219019Sgabor		return (-1);
192219019Sgabor
193219019Sgabor	*rval = _citrus_region_peek16(&ms->ms_region, ms->ms_pos);
194219019Sgabor	ms->ms_pos += 2;
195219019Sgabor
196219019Sgabor	return (0);
197219019Sgabor}
198219019Sgabor
199219019Sgaborstatic __inline int
200219019Sgabor_citrus_memory_stream_get32(struct _citrus_memory_stream *ms, uint32_t *rval)
201219019Sgabor{
202219019Sgabor
203219019Sgabor	if (ms->ms_pos + 4 > _citrus_region_size(&ms->ms_region))
204219019Sgabor		return (-1);
205219019Sgabor
206219019Sgabor	*rval = _citrus_region_peek32(&ms->ms_region, ms->ms_pos);
207219019Sgabor	ms->ms_pos += 4;
208219019Sgabor
209219019Sgabor	return (0);
210219019Sgabor}
211219019Sgabor
212219019Sgaborstatic __inline int
213219019Sgabor_citrus_memory_stream_getln_region(struct _citrus_memory_stream *ms,
214219019Sgabor    struct _citrus_region *r)
215219019Sgabor{
216219019Sgabor	const char *ptr;
217219019Sgabor	size_t sz;
218219019Sgabor
219219019Sgabor	ptr = _citrus_memory_stream_getln(ms, &sz);
220219019Sgabor	if (ptr)
221219019Sgabor		_citrus_region_init(r, __DECONST(void *, ptr), sz);
222219019Sgabor
223219019Sgabor	return (ptr == NULL);
224219019Sgabor}
225219019Sgabor
226219019Sgabor#endif
227