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