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

手机WAP编程

开发平台:

WINDOWS

  1. /*
  2.  * msg.c - manipulate messages
  3.  *
  4.  * This file contains implementations of the functions that create, destroy,
  5.  * pack, and unpack messages.
  6.  *
  7.  * Lars Wirzenius <liw@wapit.com>
  8.  */
  9. #include <errno.h>
  10. #include <stdlib.h>
  11. #include <sys/types.h>
  12. #include <netinet/in.h>
  13. #include "msg.h"
  14. #include "gwlib/gwlib.h"
  15. /**********************************************************************
  16.  * Prototypes for private functions.
  17.  */
  18. static void append_integer(Octstr *os, long i);
  19. static void append_string(Octstr *os, Octstr *field);
  20. static int parse_integer(long *i, Octstr *packed, int *off);
  21. static int parse_string(Octstr **os, Octstr *packed, int *off);
  22. static char *type_as_str(Msg *msg);
  23. /**********************************************************************
  24.  * Implementations of the exported functions.
  25.  */
  26. Msg *msg_create(enum msg_type type)
  27. {
  28.     Msg *msg;
  29.     msg = gw_malloc(sizeof(Msg));
  30.     msg->type = type;
  31. #define INTEGER(name) p->name = 0
  32. #define OCTSTR(name) p->name = NULL
  33. #define MSG(type, stmt) { struct type *p = &msg->type; stmt }
  34. #include "msg-decl.h"
  35.     return msg;
  36. }
  37. Msg *msg_duplicate(Msg *msg)
  38. {
  39.     Msg *new;
  40.     new = msg_create(msg->type);
  41. #define INTEGER(name) p->name = q->name
  42. #define OCTSTR(name) 
  43.     if (q->name == NULL) p->name = NULL; 
  44.     else p->name = octstr_duplicate(q->name);
  45. #define MSG(type, stmt) { 
  46.     struct type *p = &new->type; 
  47.     struct type *q = &msg->type; 
  48.     stmt }
  49. #include "msg-decl.h"
  50.     return new;
  51. }
  52. void msg_destroy(Msg *msg)
  53. {
  54.     if (msg == NULL)
  55.         return;
  56. #define INTEGER(name) p->name = 0
  57. #define OCTSTR(name) octstr_destroy(p->name)
  58. #define MSG(type, stmt) { struct type *p = &msg->type; stmt }
  59. #include "msg-decl.h"
  60.     gw_free(msg);
  61. }
  62. void msg_destroy_item(void *msg)
  63. {
  64.     msg_destroy(msg);
  65. }
  66. void msg_dump(Msg *msg, int level)
  67. {
  68.     debug("gw.msg", 0, "%*sMsg object at %p:", level, "", (void *) msg);
  69.     debug("gw.msg", 0, "%*s type: %s", level, "", type_as_str(msg));
  70. #define INTEGER(name) 
  71.     debug("gw.msg", 0, "%*s %s.%s: %ld", level, "", t, #name, (long) p->name)
  72. #define OCTSTR(name) 
  73.     debug("gw.msg", 0, "%*s %s.%s:", level, "", t, #name); 
  74.     octstr_dump(p->name, level + 1)
  75. #define MSG(tt, stmt) 
  76.     if (tt == msg->type) 
  77.         { char *t = #tt; struct tt *p = &msg->tt; stmt }
  78. #include "msg-decl.h"
  79.     debug("gw.msg", 0, "Msg object ends.");
  80. }
  81. enum msg_type msg_type(Msg *msg)
  82. {
  83.     return msg->type;
  84. }
  85. Octstr *msg_pack(Msg *msg)
  86. {
  87.     Octstr *os;
  88.     os = octstr_create("");
  89.     append_integer(os, msg->type);
  90. #define INTEGER(name) append_integer(os, p->name)
  91. #define OCTSTR(name) append_string(os, p->name)
  92. #define MSG(type, stmt) 
  93.     case type: { struct type *p = &msg->type; stmt } break;
  94.     switch (msg->type) {
  95. #include "msg-decl.h"
  96.     default:
  97.         panic(0, "Internal error: unknown message type %d",
  98.               msg->type);
  99.     }
  100.     return os;
  101. }
  102. Msg *msg_unpack(Octstr *os)
  103. {
  104.     Msg *msg;
  105.     int off;
  106.     long i;
  107.     msg = msg_create(0);
  108.     if (msg == NULL)
  109.         goto error;
  110.     off = 0;
  111.     if (parse_integer(&i, os, &off) == -1)
  112.         goto error;
  113.     msg->type = i;
  114. #define INTEGER(name) 
  115.     if (parse_integer(&(p->name), os, &off) == -1) goto error
  116. #define OCTSTR(name) 
  117.     if (parse_string(&(p->name), os, &off) == -1) goto error
  118. #define MSG(type, stmt) 
  119.     case type: { struct type *p = &(msg->type); stmt } break;
  120.     switch (msg->type) {
  121. #include "msg-decl.h"
  122.     default:
  123.         panic(0, "Internal error: unknown message type: %d",
  124.               msg->type);
  125.     }
  126.     return msg;
  127. error:
  128.     error(0, "Msg packet was invalid.");
  129.     return NULL;
  130. }
  131. /**********************************************************************
  132.  * Implementations of private functions.
  133.  */
  134. static void append_integer(Octstr *os, long i)
  135. {
  136.     unsigned char buf[4];
  137.     encode_network_long(buf, i);
  138.     octstr_append_data(os, buf, 4);
  139. }
  140. static void append_string(Octstr *os, Octstr *field)
  141. {
  142.     if (field == NULL)
  143.         append_integer(os, -1);
  144.     else {
  145.         append_integer(os, octstr_len(field));
  146.         octstr_insert(os, field, octstr_len(os));
  147.     }
  148. }
  149. static int parse_integer(long *i, Octstr *packed, int *off)
  150. {
  151.     unsigned char buf[4];
  152.     gw_assert(*off >= 0);
  153.     if (*off + 4 > octstr_len(packed)) {
  154.         error(0, "Packet too short while unpacking Msg.");
  155.         return -1;
  156.     }
  157.     octstr_get_many_chars(buf, packed, *off, 4);
  158.     *i = decode_network_long(buf);
  159.     *off += 4;
  160.     return 0;
  161. }
  162. static int parse_string(Octstr **os, Octstr *packed, int *off)
  163. {
  164.     long len;
  165.     if (parse_integer(&len, packed, off) == -1)
  166.         return -1;
  167.     if (len == -1) {
  168.         *os = NULL;
  169.         return 0;
  170.     }
  171.     /* XXX check that len is ok */
  172.     *os = octstr_copy(packed, *off, len);
  173.     if (*os == NULL)
  174.         return -1;
  175.     *off += len;
  176.     return 0;
  177. }
  178. static char *type_as_str(Msg *msg)
  179. {
  180.     switch (msg->type) {
  181. #define MSG(t, stmt) case t: return #t;
  182. #include "msg-decl.h"
  183.     default:
  184.         return "unknown type";
  185.     }
  186. }