tsip_parser_header_From.rl 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /*
  2. * Copyright (C) 2010-2011 Mamadou Diop.
  3. *
  4. * Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
  5. *
  6. * This file is part of Open Source Doubango Framework.
  7. *
  8. * DOUBANGO is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * DOUBANGO is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with DOUBANGO.
  20. *
  21. */
  22. /**@file tsip_header_From.c
  23. * @brief SIP From/f header as per RFC 3261 subclause 20.20.
  24. *
  25. * @author Mamadou Diop <diopmamadou(at)doubango[dot]org>
  26. *
  27. */
  28. #include "tinysip/headers/tsip_header_From.h"
  29. #include "tinysip/parsers/tsip_parser_uri.h"
  30. #include "tsk_debug.h"
  31. #include "tsk_memory.h"
  32. /***********************************
  33. * Ragel state machine.
  34. */
  35. %%{
  36. machine tsip_machine_parser_header_From;
  37. # Includes
  38. include tsip_machine_utils "./ragel/tsip_machine_utils.rl";
  39. action tag{
  40. tag_start = p;
  41. }
  42. action parse_uri{
  43. int len = (int)(p - tag_start);
  44. if(hdr_from && !hdr_from->uri){
  45. if((hdr_from->uri = tsip_uri_parse(tag_start, (tsk_size_t)len)) && hdr_from->display_name){
  46. hdr_from->uri->display_name = tsk_strdup(hdr_from->display_name);
  47. }
  48. }
  49. }
  50. action parse_display_name{
  51. TSK_PARSER_SET_STRING(hdr_from->display_name);
  52. tsk_strunquote(&hdr_from->display_name);
  53. }
  54. action parse_tag{
  55. TSK_PARSER_SET_STRING(hdr_from->tag);
  56. }
  57. action parse_param{
  58. TSK_PARSER_ADD_PARAM(TSIP_HEADER_PARAMS(hdr_from));
  59. }
  60. action eob{
  61. }
  62. URI = (scheme HCOLON any+)>tag %parse_uri;
  63. display_name = (( token LWS )+ | quoted_string)>tag %parse_display_name;
  64. my_name_addr = display_name? :>LAQUOT<: URI :>RAQUOT;
  65. my_tag_param = "tag"i EQUAL token>tag %parse_tag;
  66. from_param = (my_tag_param)@1 | (generic_param)@0 >tag %parse_param;
  67. from_spec = ( my_name_addr | URI ) :> ( SEMI from_param )*;
  68. From = ( "From"i | "f"i ) HCOLON from_spec;
  69. # Entry point
  70. main := From :>CRLF @eob;
  71. }%%
  72. tsip_header_From_t* tsip_header_From_create(const char* display_name, const tsip_uri_t* uri, const char* tag)
  73. {
  74. return tsk_object_new(TSIP_HEADER_FROM_VA_ARGS(display_name, uri, tag));
  75. }
  76. int tsip_header_From_serialize(const tsip_header_t* header, tsk_buffer_t* output)
  77. {
  78. int ret = -1;
  79. if(header){
  80. const tsip_header_From_t *From = (const tsip_header_From_t *)header;
  81. /* Uri with hacked display-name*/
  82. if((ret = tsip_uri_serialize(From->uri, tsk_true, tsk_true, output))){
  83. return ret;
  84. }
  85. if(From->tag){
  86. ret = tsk_buffer_append_2(output, ";tag=%s", From->tag);
  87. }
  88. }
  89. return ret;
  90. }
  91. tsip_header_From_t *tsip_header_From_parse(const char *data, tsk_size_t size)
  92. {
  93. int cs = 0;
  94. const char *p = data;
  95. const char *pe = p + size;
  96. const char *eof = pe;
  97. tsip_header_From_t *hdr_from = tsip_header_From_create(tsk_null, tsk_null, tsk_null);
  98. const char *tag_start = tsk_null;
  99. %%write data;
  100. (void)(eof);
  101. (void)(tsip_machine_parser_header_From_first_final);
  102. (void)(tsip_machine_parser_header_From_error);
  103. (void)(tsip_machine_parser_header_From_en_main);
  104. %%write init;
  105. %%write exec;
  106. if( cs < %%{ write first_final; }%% ){
  107. TSK_DEBUG_ERROR("Failed to parse 'From' header.");
  108. TSK_OBJECT_SAFE_FREE(hdr_from);
  109. }
  110. return hdr_from;
  111. }
  112. //========================================================
  113. // From header object definition
  114. //
  115. static tsk_object_t* tsip_header_From_ctor(tsk_object_t *self, va_list * app)
  116. {
  117. tsip_header_From_t *From = self;
  118. if(From){
  119. const char* display_name = va_arg(*app, const char *);
  120. const tsip_uri_t* uri = va_arg(*app, const tsip_uri_t *);
  121. const char* tag = va_arg(*app, const char *);
  122. From->display_name = tsk_strdup(display_name);
  123. if(uri) From->uri = tsk_object_ref((void *)uri);
  124. From->tag = tsk_strdup(tag);
  125. TSIP_HEADER(From)->type = tsip_htype_From;
  126. TSIP_HEADER(From)->serialize = tsip_header_From_serialize;
  127. }
  128. else{
  129. TSK_DEBUG_ERROR("Failed to create new From header.");
  130. }
  131. return self;
  132. }
  133. static tsk_object_t* tsip_header_From_dtor(tsk_object_t *self)
  134. {
  135. tsip_header_From_t *From = self;
  136. if(From){
  137. TSK_FREE(From->display_name);
  138. TSK_FREE(From->tag);
  139. TSK_OBJECT_SAFE_FREE(From->uri);
  140. TSK_OBJECT_SAFE_FREE(TSIP_HEADER_PARAMS(From));
  141. }
  142. else{
  143. TSK_DEBUG_ERROR("Null From header.");
  144. }
  145. return self;
  146. }
  147. static const tsk_object_def_t tsip_header_From_def_s =
  148. {
  149. sizeof(tsip_header_From_t),
  150. tsip_header_From_ctor,
  151. tsip_header_From_dtor,
  152. tsk_null
  153. };
  154. const tsk_object_def_t *tsip_header_From_def_t = &tsip_header_From_def_s;