parse.c
上传用户:gzpyjq
上传日期:2013-01-31
资源大小:1852k
文件大小:4k
源码类别:

手机WAP编程

开发平台:

WINDOWS

  1. /*
  2.  * parse.c - implement parse.h interface
  3.  *
  4.  * Richard Braakman
  5.  */
  6. #include "gwlib/gwlib.h"
  7. struct context
  8. {
  9.     Octstr *data;
  10.     long pos;
  11.     long limit;
  12.     List *limit_stack;
  13.     int error;
  14. };
  15. ParseContext *parse_context_create(Octstr *str)
  16. {
  17.     ParseContext *result;
  18.     result = gw_malloc(sizeof(*result));
  19.     result->data = str;
  20.     result->pos = 0;
  21.     result->limit = octstr_len(str);
  22.     result->limit_stack = NULL;
  23.     result->error = 0;
  24.     return result;
  25. }
  26. void parse_context_destroy(ParseContext *context)
  27. {
  28.     gw_assert(context != NULL);
  29.     if (context->limit_stack) {
  30.         while (list_len(context->limit_stack) > 0)
  31.             gw_free(list_extract_first(context->limit_stack));
  32.         list_destroy(context->limit_stack, NULL);
  33.     }
  34.     gw_free(context);
  35. }
  36. int parse_error(ParseContext *context)
  37. {
  38.     gw_assert(context != NULL);
  39.     return context->error;
  40. }
  41. void parse_clear_error(ParseContext *context)
  42. {
  43.     gw_assert(context != NULL);
  44.     context->error = 0;
  45. }
  46. void parse_set_error(ParseContext *context)
  47. {
  48.     gw_assert(context != NULL);
  49.     context->error = 1;
  50. }
  51. int parse_limit(ParseContext *context, long length)
  52. {
  53.     long *elem;
  54.     gw_assert(context != NULL);
  55.     if (context->pos + length > context->limit) {
  56.         context->error = 1;
  57.         return -1;
  58.     }
  59.     if (context->limit_stack == NULL)
  60.         context->limit_stack = list_create();
  61.     elem = gw_malloc(sizeof(*elem));
  62.     *elem = context->limit;
  63.     list_insert(context->limit_stack, 0, elem);
  64.     context->limit = context->pos + length;
  65.     return 0;
  66. }
  67. int parse_pop_limit(ParseContext *context)
  68. {
  69.     long *elem;
  70.     gw_assert(context != NULL);
  71.     if (context->limit_stack == NULL || list_len(context->limit_stack) == 0) {
  72.         context->error = 1;
  73.         return -1;
  74.     }
  75.     elem = list_extract_first(context->limit_stack);
  76.     context->limit = *elem;
  77.     gw_free(elem);
  78.     return 0;
  79. }
  80. long parse_octets_left(ParseContext *context)
  81. {
  82.     gw_assert(context != NULL);
  83.     return context->limit - context->pos;
  84. }
  85. int parse_skip(ParseContext *context, long count)
  86. {
  87.     gw_assert(context != NULL);
  88.     if (context->pos + count > context->limit) {
  89.         context->pos = context->limit;
  90.         context->error = 1;
  91.         return -1;
  92.     }
  93.     context->pos += count;
  94.     return 0;
  95. }
  96. void parse_skip_to_limit(ParseContext *context)
  97. {
  98.     gw_assert(context != NULL);
  99.     context->pos = context->limit;
  100. }
  101. int parse_skip_to(ParseContext *context, long pos)
  102. {
  103.     gw_assert(context != NULL);
  104.     if (pos < 0) {
  105.         context->error = 1;
  106.         return -1;
  107.     }
  108.     if (pos > context->limit) {
  109.         context->pos = context->limit;
  110.         context->error = 1;
  111.         return -1;
  112.     }
  113.     context->pos = pos;
  114.     return 0;
  115. }
  116. int parse_peek_char(ParseContext *context)
  117. {
  118.     gw_assert(context != NULL);
  119.     if (context->pos == context->limit) {
  120.         context->error = 1;
  121.         return -1;
  122.     }
  123.     return octstr_get_char(context->data, context->pos);
  124. }
  125. int parse_get_char(ParseContext *context)
  126. {
  127.     gw_assert(context != NULL);
  128.     if (context->pos == context->limit) {
  129.         context->error = 1;
  130.         return -1;
  131.     }
  132.     return octstr_get_char(context->data, context->pos++);
  133. }
  134. Octstr *parse_get_octets(ParseContext *context, long length)
  135. {
  136.     Octstr *result;
  137.     gw_assert(context != NULL);
  138.     if (context->pos + length > context->limit) {
  139.         context->error = 1;
  140.         return NULL;
  141.     }
  142.     result = octstr_copy(context->data, context->pos, length);
  143.     context->pos += length;
  144.     return result;
  145. }
  146. unsigned long parse_get_uintvar(ParseContext *context)
  147. {
  148.     long pos;
  149.     unsigned long value;
  150.     gw_assert(context != NULL);
  151.     pos = octstr_extract_uintvar(context->data, &value, context->pos);
  152.     if (pos < 0 || pos > context->limit) {
  153.         context->error = 1;
  154.         return 0;
  155.     }
  156.     context->pos = pos;
  157.     return value;
  158. }
  159. Octstr *parse_get_nul_string(ParseContext *context)
  160. {
  161.     Octstr *result;
  162.     long pos;
  163.     gw_assert(context != NULL);
  164.     pos = octstr_search_char(context->data, 0, context->pos);
  165.     if (pos < 0 || pos >= context->limit) {
  166.         context->error = 1;
  167.         return NULL;
  168.     }
  169.     result = octstr_copy(context->data, context->pos, pos - context->pos);
  170.     context->pos = pos + 1;
  171.     return result;
  172. }
  173. Octstr *parse_get_rest(ParseContext *context)
  174. {
  175.     Octstr *rest;
  176.     
  177.     gw_assert(context != NULL);
  178.     
  179.     octstr_delete(context->data, 0, context->pos);
  180.     rest = octstr_duplicate(context->data);   
  181.     
  182.     return rest;   
  183. }