Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

parse.c

Go to the documentation of this file.
00001 /* ==================================================================== 
00002  * The Kannel Software License, Version 1.0 
00003  * 
00004  * Copyright (c) 2001-2008 Kannel Group  
00005  * Copyright (c) 1998-2001 WapIT Ltd.   
00006  * All rights reserved. 
00007  * 
00008  * Redistribution and use in source and binary forms, with or without 
00009  * modification, are permitted provided that the following conditions 
00010  * are met: 
00011  * 
00012  * 1. Redistributions of source code must retain the above copyright 
00013  *    notice, this list of conditions and the following disclaimer. 
00014  * 
00015  * 2. Redistributions in binary form must reproduce the above copyright 
00016  *    notice, this list of conditions and the following disclaimer in 
00017  *    the documentation and/or other materials provided with the 
00018  *    distribution. 
00019  * 
00020  * 3. The end-user documentation included with the redistribution, 
00021  *    if any, must include the following acknowledgment: 
00022  *       "This product includes software developed by the 
00023  *        Kannel Group (http://www.kannel.org/)." 
00024  *    Alternately, this acknowledgment may appear in the software itself, 
00025  *    if and wherever such third-party acknowledgments normally appear. 
00026  * 
00027  * 4. The names "Kannel" and "Kannel Group" must not be used to 
00028  *    endorse or promote products derived from this software without 
00029  *    prior written permission. For written permission, please  
00030  *    contact org@kannel.org. 
00031  * 
00032  * 5. Products derived from this software may not be called "Kannel", 
00033  *    nor may "Kannel" appear in their name, without prior written 
00034  *    permission of the Kannel Group. 
00035  * 
00036  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 
00037  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
00038  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
00039  * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS 
00040  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,  
00041  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  
00042  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR  
00043  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
00044  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE  
00045  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  
00046  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
00047  * ==================================================================== 
00048  * 
00049  * This software consists of voluntary contributions made by many 
00050  * individuals on behalf of the Kannel Group.  For more information on  
00051  * the Kannel Group, please see <http://www.kannel.org/>. 
00052  * 
00053  * Portions of this software are based upon software originally written at  
00054  * WapIT Ltd., Helsinki, Finland for the Kannel project.  
00055  */ 
00056 
00057 /*
00058  * parse.c - implement parse.h interface
00059  *
00060  * Richard Braakman
00061  */
00062 
00063 #include "gwlib/gwlib.h"
00064 
00065 struct context
00066 {
00067     Octstr *data;
00068     long pos;
00069     long limit;
00070     List *limit_stack;
00071     int error;
00072 };
00073 
00074 ParseContext *parse_context_create(Octstr *str)
00075 {
00076     ParseContext *result;
00077 
00078     result = gw_malloc(sizeof(*result));
00079     result->data = str;
00080     result->pos = 0;
00081     result->limit = octstr_len(str);
00082     result->limit_stack = NULL;
00083     result->error = 0;
00084 
00085     return result;
00086 }
00087 
00088 void parse_context_destroy(ParseContext *context)
00089 {
00090     gw_assert(context != NULL);
00091 
00092     if (context->limit_stack) {
00093         while (gwlist_len(context->limit_stack) > 0)
00094             gw_free(gwlist_extract_first(context->limit_stack));
00095         gwlist_destroy(context->limit_stack, NULL);
00096     }
00097     gw_free(context);
00098 }
00099 
00100 int parse_error(ParseContext *context)
00101 {
00102     gw_assert(context != NULL);
00103 
00104     return context->error;
00105 }
00106 
00107 void parse_clear_error(ParseContext *context)
00108 {
00109     gw_assert(context != NULL);
00110 
00111     context->error = 0;
00112 }
00113 
00114 void parse_set_error(ParseContext *context)
00115 {
00116     gw_assert(context != NULL);
00117 
00118     context->error = 1;
00119 }
00120 
00121 int parse_limit(ParseContext *context, long length)
00122 {
00123     long *elem;
00124 
00125     gw_assert(context != NULL);
00126 
00127     if (context->pos + length > context->limit) {
00128         context->error = 1;
00129         return -1;
00130     }
00131 
00132     if (context->limit_stack == NULL)
00133         context->limit_stack = gwlist_create();
00134 
00135     elem = gw_malloc(sizeof(*elem));
00136     *elem = context->limit;
00137     gwlist_insert(context->limit_stack, 0, elem);
00138     context->limit = context->pos + length;
00139     return 0;
00140 }
00141 
00142 int parse_pop_limit(ParseContext *context)
00143 {
00144     long *elem;
00145 
00146     gw_assert(context != NULL);
00147 
00148     if (context->limit_stack == NULL || gwlist_len(context->limit_stack) == 0) {
00149         context->error = 1;
00150         return -1;
00151     }
00152 
00153     elem = gwlist_extract_first(context->limit_stack);
00154     context->limit = *elem;
00155     gw_free(elem);
00156     return 0;
00157 }
00158 
00159 long parse_octets_left(ParseContext *context)
00160 {
00161     gw_assert(context != NULL);
00162 
00163     return context->limit - context->pos;
00164 }
00165 
00166 int parse_skip(ParseContext *context, long count)
00167 {
00168     gw_assert(context != NULL);
00169 
00170     if (context->pos + count > context->limit) {
00171         context->pos = context->limit;
00172         context->error = 1;
00173         return -1;
00174     }
00175 
00176     context->pos += count;
00177     return 0;
00178 }
00179 
00180 void parse_skip_to_limit(ParseContext *context)
00181 {
00182     gw_assert(context != NULL);
00183 
00184     context->pos = context->limit;
00185 }
00186 
00187 int parse_skip_to(ParseContext *context, long pos)
00188 {
00189     gw_assert(context != NULL);
00190 
00191     if (pos < 0) {
00192         context->error = 1;
00193         return -1;
00194     }
00195 
00196     if (pos > context->limit) {
00197         context->pos = context->limit;
00198         context->error = 1;
00199         return -1;
00200     }
00201 
00202     context->pos = pos;
00203     return 0;
00204 }
00205 
00206 int parse_peek_char(ParseContext *context)
00207 {
00208     gw_assert(context != NULL);
00209 
00210     if (context->pos == context->limit) {
00211         context->error = 1;
00212         return -1;
00213     }
00214 
00215     return octstr_get_char(context->data, context->pos);
00216 }
00217 
00218 int parse_get_char(ParseContext *context)
00219 {
00220     gw_assert(context != NULL);
00221 
00222     if (context->pos == context->limit) {
00223         context->error = 1;
00224         return -1;
00225     }
00226 
00227     return octstr_get_char(context->data, context->pos++);
00228 }
00229 
00230 Octstr *parse_get_octets(ParseContext *context, long length)
00231 {
00232     Octstr *result;
00233 
00234     gw_assert(context != NULL);
00235 
00236     if (context->pos + length > context->limit) {
00237         context->error = 1;
00238         return NULL;
00239     }
00240 
00241     result = octstr_copy(context->data, context->pos, length);
00242     context->pos += length;
00243     return result;
00244 }
00245 
00246 unsigned long parse_get_uintvar(ParseContext *context)
00247 {
00248     long pos;
00249     unsigned long value;
00250 
00251     gw_assert(context != NULL);
00252 
00253     pos = octstr_extract_uintvar(context->data, &value, context->pos);
00254     if (pos < 0 || pos > context->limit) {
00255         context->error = 1;
00256         return 0;
00257     }
00258 
00259     context->pos = pos;
00260     return value;
00261 }
00262 
00263 Octstr *parse_get_nul_string(ParseContext *context)
00264 {
00265     Octstr *result;
00266     long pos;
00267 
00268     gw_assert(context != NULL);
00269 
00270     pos = octstr_search_char(context->data, 0, context->pos);
00271     if (pos < 0 || pos >= context->limit) {
00272         context->error = 1;
00273         return NULL;
00274     }
00275 
00276     result = octstr_copy(context->data, context->pos, pos - context->pos);
00277     context->pos = pos + 1;
00278 
00279     return result;
00280 }
00281 
00282 Octstr *parse_get_line(ParseContext *context)
00283 {
00284     Octstr *result;
00285     long pos;
00286 
00287     gw_assert(context != NULL);
00288 
00289     pos = octstr_search_char(context->data, '\n', context->pos);
00290     if (pos < 0 || pos >= context->limit) {
00291         context->error = 1;
00292         return NULL;
00293     }
00294     
00295     result = octstr_copy(context->data, context->pos, pos - context->pos);
00296     context->pos = pos + 1;
00297 
00298     octstr_strip_crlfs(result);
00299 
00300     return result;
00301 }
00302 
00303 Octstr *parse_get_seperated_block(ParseContext *context, Octstr *seperator)
00304 {
00305     Octstr *result;
00306     long spos, epos;
00307 
00308     gw_assert(context != NULL);
00309     gw_assert(seperator != NULL);
00310 
00311     spos = octstr_search(context->data, seperator, context->pos);
00312     if (spos < 0 || spos >= context->limit) {
00313         context->error = 1;
00314         return NULL;
00315     }
00316     epos = octstr_search(context->data, seperator, spos + octstr_len(seperator));
00317     if (epos < 0 || epos >= context->limit) {
00318         context->error = 1;
00319         return NULL;
00320     }
00321 
00322     spos = spos + octstr_len(seperator);
00323     result = octstr_copy(context->data, spos, epos - spos);
00324     context->pos = epos;
00325 
00326     return result;
00327 }
00328 
00329 Octstr *parse_get_rest(ParseContext *context)
00330 {
00331     Octstr *rest;
00332     
00333     gw_assert(context != NULL);
00334     
00335     octstr_delete(context->data, 0, context->pos);
00336     rest = octstr_duplicate(context->data);   
00337     
00338     return rest;   
00339 }
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.