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

手机WAP编程

开发平台:

WINDOWS

  1. /* wsp_strings.c: lookup code for various tables defined by WSP standard
  2.  *
  3.  * This file provides functions to translate strings to numbers and numbers
  4.  * to strings according to the Assigned Numbers tables in appendix A
  5.  * of the WSP specification.
  6.  *
  7.  * The tables are in wsp_strings.def, in a special format suitable for
  8.  * use with the C preprocessor, which we abuse liberally to get the
  9.  * interface we want. 
  10.  *
  11.  * Richard Braakman
  12.  */
  13. #include "gwlib/gwlib.h"
  14. #include "wsp_strings.h"
  15. #define TABLE_SIZE(table) ((long)(sizeof(table) / sizeof(table[0])))
  16. static int initialized;
  17. /* The arrays in a table structure are all of equal length, and their
  18.  * elements correspond.  The number for string 0 is in numbers[0], etc.
  19.  * Table structures are initialized dynamically.
  20.  */
  21. struct table
  22. {
  23.     long size;          /* Nr of entries in each of the tables below */
  24.     Octstr **strings;   /* Immutable octstrs */
  25.     long *numbers;      /* Assigned numbers, or NULL for linear tables */
  26.     int linear;     /* True for tables defined as LINEAR */
  27. };
  28. struct element
  29. {
  30.     unsigned char *str;
  31.     long number;
  32. };
  33. /* Local functions */
  34. static Octstr *number_to_string(long number, struct table *table);
  35. static unsigned char *number_to_cstr(long number, struct table *table);
  36. static long string_to_number(Octstr *ostr, struct table *table);
  37. /* Declare the data.  For each table "foo", create a foo_strings array
  38.  * to hold the data, and a (still empty) foo_table structure. */
  39. #define LINEAR(name, strings) 
  40.     static const unsigned char *name##_strings[] = { strings }; 
  41.     static struct table name##_table;
  42. #define STRING(string) string,
  43. #define NUMBERED(name, strings) 
  44.     static const struct element name##_strings[] = { strings }; 
  45.     static struct table name##_table;
  46. #define ASSIGN(string, number) { string, number },
  47. #include "wsp_strings.def"
  48. /* Define the functions for translating number to Octstr */
  49. #define LINEAR(name, strings) 
  50. Octstr *wsp_##name##_to_string(long number) { 
  51.     return number_to_string(number, &name##_table); 
  52. }
  53. #include "wsp_strings.def"
  54. /* Define the functions for translating number to constant string */
  55. #define LINEAR(name, strings) 
  56. unsigned char *wsp_##name##_to_cstr(long number) { 
  57.     return number_to_cstr(number, &name##_table); 
  58. }
  59. #include "wsp_strings.def"
  60. #define LINEAR(name, strings) 
  61. long wsp_string_to_##name(Octstr *ostr) { 
  62.      return string_to_number(ostr, &name##_table); 
  63. }
  64. #include "wsp_strings.def"
  65. static Octstr *number_to_string(long number, struct table *table)
  66. {
  67.     long i;
  68.     gw_assert(initialized);
  69.     if (table->linear) {
  70. if (number >= 0 && number < table->size)
  71.     return octstr_duplicate(table->strings[number]);
  72.     } else {
  73. for (i = 0; i < table->size; i++) {
  74.          if (table->numbers[i] == number)
  75. return octstr_duplicate(table->strings[i]);
  76. }
  77.     }
  78.     return NULL;
  79. }
  80. static unsigned char *number_to_cstr(long number, struct table *table)
  81. {
  82.     long i;
  83.     gw_assert(initialized);
  84.     if (table->linear) {
  85. if (number >= 0 && number < table->size)
  86.     return octstr_get_cstr(table->strings[number]);
  87.     } else {
  88. for (i = 0; i < table->size; i++) {
  89.          if (table->numbers[i] == number)
  90. return octstr_get_cstr(table->strings[i]);
  91. }
  92.     }
  93.     return NULL;
  94. }
  95. /* Case-insensitive string lookup */
  96. static long string_to_number(Octstr *ostr, struct table *table)
  97. {
  98.     long i;
  99.     gw_assert(initialized);
  100.     for (i = 0; i < table->size; i++) {
  101. if (octstr_case_compare(ostr, table->strings[i]) == 0) {
  102.     return table->linear ? i : table->numbers[i];
  103. }
  104.     }
  105.     return -1;
  106. }
  107. static void construct_linear_table(struct table *table,
  108. const unsigned char **strings, long size)
  109. {
  110.     long i;
  111.     table->size = size;
  112.     table->strings = gw_malloc(size * (sizeof table->strings[0]));
  113.     table->numbers = NULL;
  114.     table->linear = 1;
  115.     for (i = 0; i < size; i++) {
  116. table->strings[i] = octstr_imm(strings[i]);
  117.     }
  118. }
  119. static void construct_numbered_table(struct table *table,
  120. const struct element *strings, long size)
  121. {
  122.     long i;
  123.     table->size = size;
  124.     table->strings = gw_malloc(size * (sizeof table->strings[0]));
  125.     table->numbers = gw_malloc(size * (sizeof table->numbers[0]));
  126.     table->linear = 0;
  127.     for (i = 0; i < size; i++) {
  128. table->strings[i] = octstr_imm(strings[i].str);
  129. table->numbers[i] = strings[i].number;
  130.     }
  131. }
  132. static void destroy_table(struct table *table)
  133. {
  134.     /* No need to call octstr_destroy on immutable octstrs */
  135.     gw_free(table->strings);
  136.     gw_free(table->numbers);
  137. }
  138. void wsp_strings_init(void)
  139. {
  140.     if (initialized > 0) {
  141.          initialized++;
  142.          return;
  143.     }
  144. #define LINEAR(name, strings) 
  145.     construct_linear_table(&name##_table, 
  146. name##_strings, TABLE_SIZE(name##_strings));
  147. #define NUMBERED(name, strings) 
  148.     construct_numbered_table(&name##_table, 
  149.         name##_strings, TABLE_SIZE(name##_strings));
  150. #include "wsp_strings.def"
  151.     initialized++;
  152. }
  153. void wsp_strings_shutdown(void)
  154. {
  155.     /* If we were initialized more than once, then wait for more than
  156.      * one shutdown. */
  157.     if (initialized > 1) {
  158.         initialized--;
  159.         return;
  160.     }
  161. #define LINEAR(name, strings) 
  162.     destroy_table(&name##_table);
  163. #include "wsp_strings.def"
  164.     initialized = 0;
  165. }