Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
parse.c
Go to the documentation of this file.
1 /* ====================================================================
2  * The Kannel Software License, Version 1.0
3  *
4  * Copyright (c) 2001-2016 Kannel Group
5  * Copyright (c) 1998-2001 WapIT Ltd.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Kannel Group (http://www.kannel.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Kannel" and "Kannel Group" must not be used to
28  * endorse or promote products derived from this software without
29  * prior written permission. For written permission, please
30  * contact org@kannel.org.
31  *
32  * 5. Products derived from this software may not be called "Kannel",
33  * nor may "Kannel" appear in their name, without prior written
34  * permission of the Kannel Group.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS
40  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
41  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
42  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
43  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
44  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
45  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
46  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Kannel Group. For more information on
51  * the Kannel Group, please see <http://www.kannel.org/>.
52  *
53  * Portions of this software are based upon software originally written at
54  * WapIT Ltd., Helsinki, Finland for the Kannel project.
55  */
56 
57 /*
58  * parse.c - implement parse.h interface
59  *
60  * Richard Braakman
61  */
62 
63 #include "gwlib/gwlib.h"
64 
65 struct context
66 {
68  long pos;
69  long limit;
71  int error;
72 };
73 
75 {
76  ParseContext *result;
77 
78  result = gw_malloc(sizeof(*result));
79  result->data = str;
80  result->pos = 0;
81  result->limit = octstr_len(str);
82  result->limit_stack = NULL;
83  result->error = 0;
84 
85  return result;
86 }
87 
89 {
90  gw_assert(context != NULL);
91 
92  if (context->limit_stack) {
93  while (gwlist_len(context->limit_stack) > 0)
94  gw_free(gwlist_extract_first(context->limit_stack));
95  gwlist_destroy(context->limit_stack, NULL);
96  }
97  gw_free(context);
98 }
99 
101 {
102  gw_assert(context != NULL);
103 
104  return context->error;
105 }
106 
108 {
109  gw_assert(context != NULL);
110 
111  context->error = 0;
112 }
113 
115 {
116  gw_assert(context != NULL);
117 
118  context->error = 1;
119 }
120 
121 int parse_limit(ParseContext *context, long length)
122 {
123  long *elem;
124 
125  gw_assert(context != NULL);
126 
127  if (context->pos + length > context->limit) {
128  context->error = 1;
129  return -1;
130  }
131 
132  if (context->limit_stack == NULL)
133  context->limit_stack = gwlist_create();
134 
135  elem = gw_malloc(sizeof(*elem));
136  *elem = context->limit;
137  gwlist_insert(context->limit_stack, 0, elem);
138  context->limit = context->pos + length;
139  return 0;
140 }
141 
143 {
144  long *elem;
145 
146  gw_assert(context != NULL);
147 
148  if (context->limit_stack == NULL || gwlist_len(context->limit_stack) == 0) {
149  context->error = 1;
150  return -1;
151  }
152 
153  elem = gwlist_extract_first(context->limit_stack);
154  context->limit = *elem;
155  gw_free(elem);
156  return 0;
157 }
158 
160 {
161  gw_assert(context != NULL);
162 
163  return context->limit - context->pos;
164 }
165 
166 int parse_skip(ParseContext *context, long count)
167 {
168  gw_assert(context != NULL);
169 
170  if (context->pos + count > context->limit) {
171  context->pos = context->limit;
172  context->error = 1;
173  return -1;
174  }
175 
176  context->pos += count;
177  return 0;
178 }
179 
181 {
182  gw_assert(context != NULL);
183 
184  context->pos = context->limit;
185 }
186 
188 {
189  gw_assert(context != NULL);
190 
191  if (pos < 0) {
192  context->error = 1;
193  return -1;
194  }
195 
196  if (pos > context->limit) {
197  context->pos = context->limit;
198  context->error = 1;
199  return -1;
200  }
201 
202  context->pos = pos;
203  return 0;
204 }
205 
207 {
208  gw_assert(context != NULL);
209 
210  if (context->pos == context->limit) {
211  context->error = 1;
212  return -1;
213  }
214 
215  return octstr_get_char(context->data, context->pos);
216 }
217 
219 {
220  gw_assert(context != NULL);
221 
222  if (context->pos == context->limit) {
223  context->error = 1;
224  return -1;
225  }
226 
227  return octstr_get_char(context->data, context->pos++);
228 }
229 
231 {
232  Octstr *result;
233 
234  gw_assert(context != NULL);
235 
236  if (context->pos + length > context->limit) {
237  context->error = 1;
238  return NULL;
239  }
240 
241  result = octstr_copy(context->data, context->pos, length);
242  context->pos += length;
243  return result;
244 }
245 
247 {
248  long pos;
249  unsigned long value;
250 
251  gw_assert(context != NULL);
252 
253  pos = octstr_extract_uintvar(context->data, &value, context->pos);
254  if (pos < 0 || pos > context->limit) {
255  context->error = 1;
256  return 0;
257  }
258 
259  context->pos = pos;
260  return value;
261 }
262 
264 {
265  Octstr *result;
266  long pos;
267 
268  gw_assert(context != NULL);
269 
270  pos = octstr_search_char(context->data, 0, context->pos);
271  if (pos < 0 || pos >= context->limit) {
272  context->error = 1;
273  return NULL;
274  }
275 
276  result = octstr_copy(context->data, context->pos, pos - context->pos);
277  context->pos = pos + 1;
278 
279  return result;
280 }
281 
283 {
284  Octstr *result;
285  long pos;
286 
287  gw_assert(context != NULL);
288 
289  pos = octstr_search_char(context->data, '\n', context->pos);
290  if (pos < 0 || pos >= context->limit) {
291  context->error = 1;
292  return NULL;
293  }
294 
295  result = octstr_copy(context->data, context->pos, pos - context->pos);
296  context->pos = pos + 1;
297 
298  octstr_strip_crlfs(result);
299 
300  return result;
301 }
302 
304 {
305  Octstr *result;
306  long spos, epos;
307 
308  gw_assert(context != NULL);
309  gw_assert(seperator != NULL);
310 
311  spos = octstr_search(context->data, seperator, context->pos);
312  if (spos < 0 || spos >= context->limit) {
313  context->error = 1;
314  return NULL;
315  }
316  epos = octstr_search(context->data, seperator, spos + octstr_len(seperator));
317  if (epos < 0 || epos >= context->limit) {
318  context->error = 1;
319  return NULL;
320  }
321 
322  spos = spos + octstr_len(seperator);
323  result = octstr_copy(context->data, spos, epos - spos);
324  context->pos = epos;
325 
326  return result;
327 }
328 
330 {
331  Octstr *rest;
332 
333  gw_assert(context != NULL);
334 
335  octstr_delete(context->data, 0, context->pos);
336  rest = octstr_duplicate(context->data);
337 
338  return rest;
339 }
Octstr * data
Definition: parse.c:67
Octstr * parse_get_seperated_block(ParseContext *context, Octstr *seperator)
Definition: parse.c:303
int parse_peek_char(ParseContext *context)
Definition: parse.c:206
int parse_get_char(ParseContext *context)
Definition: parse.c:218
Definition: parse.c:65
long gwlist_len(List *list)
Definition: list.c:166
Octstr * parse_get_line(ParseContext *context)
Definition: parse.c:282
long pos
Definition: parse.c:68
long limit
Definition: parse.c:69
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1068
void parse_skip_to_limit(ParseContext *context)
Definition: parse.c:180
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1010
int parse_pop_limit(ParseContext *context)
Definition: parse.c:142
void * gwlist_extract_first(List *list)
Definition: list.c:305
int error
Definition: parse.c:71
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1525
Octstr * parse_get_octets(ParseContext *context, long length)
Definition: parse.c:230
#define octstr_duplicate(ostr)
Definition: octstr.h:187
void parse_set_error(ParseContext *context)
Definition: parse.c:114
gw_assert(wtls_machine->packet_to_send!=NULL)
int parse_limit(ParseContext *context, long length)
Definition: parse.c:121
void gwlist_insert(List *list, long pos, void *item)
Definition: list.c:214
void octstr_strip_crlfs(Octstr *text)
Definition: octstr.c:1376
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
int parse_skip(ParseContext *context, long count)
Definition: parse.c:166
void parse_context_destroy(ParseContext *context)
Definition: parse.c:88
Definition: octstr.c:118
int parse_skip_to(ParseContext *context, long pos)
Definition: parse.c:187
Octstr * parse_get_nul_string(ParseContext *context)
Definition: parse.c:263
#define gwlist_create()
Definition: list.h:136
unsigned long parse_get_uintvar(ParseContext *context)
Definition: parse.c:246
List * limit_stack
Definition: parse.c:70
long octstr_extract_uintvar(Octstr *ostr, unsigned long *value, long pos)
Definition: octstr.c:1952
int parse_error(ParseContext *context)
Definition: parse.c:100
Octstr * parse_get_rest(ParseContext *context)
Definition: parse.c:329
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:404
void parse_clear_error(ParseContext *context)
Definition: parse.c:107
ParseContext * parse_context_create(Octstr *str)
Definition: parse.c:74
Definition: list.c:102
long parse_octets_left(ParseContext *context)
Definition: parse.c:159
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.