00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
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.