tmedia_imageattr.rl 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. * Copyright (C) 2012-2015 Doubango Telecom <http://www.doubango.org>
  3. *
  4. * This file is part of Open Source Doubango Framework.
  5. *
  6. * DOUBANGO is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * DOUBANGO is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with DOUBANGO.
  18. *
  19. */
  20. /**@file tmedia_imageattr.c
  21. * @brief 'image-attr' parser as per RFC 6236
  22. */
  23. #include "tinymedia/tmedia_imageattr.h"
  24. #include "tsk_ragel_state.h"
  25. #include "tsk_debug.h"
  26. #include <stdlib.h>
  27. /***********************************
  28. * Ragel state machine.
  29. */
  30. %%{
  31. machine tmedia_machine_imageattr;
  32. # Includes
  33. include tmedia_machine_utils "./ragel/tmedia_machine_utils.rl";
  34. action tag{
  35. tag_start = p;
  36. }
  37. action is_send{
  38. sets = &self->send.sets[0];
  39. sets_count = &self->send.count;
  40. *sets_count = 0;
  41. }
  42. action is_recv{
  43. sets = &self->recv.sets[0];
  44. sets_count = &self->recv.count;
  45. *sets_count = 0;
  46. }
  47. action is_xrange{
  48. xyrange = (*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE) ? &sets[*sets_count].xrange : tsk_null;
  49. }
  50. action is_yrange{
  51. xyrange = (*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE) ? &sets[*sets_count].yrange : tsk_null;
  52. }
  53. action set_parsed{
  54. if(*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE) (*sets_count)++;
  55. }
  56. action set_is_not_range{
  57. if(xyrange) xyrange->is_range = 0;
  58. }
  59. action set_is_range{
  60. if(xyrange) xyrange->is_range = 1;
  61. }
  62. action parse_xyvalue_range_start{
  63. if(xyrange)xyrange->range.start = atoi(tag_start);
  64. }
  65. action parse_xyvalue_range_step{
  66. if(xyrange)xyrange->range.step = atoi(tag_start);
  67. }
  68. action parse_xyvalue_range_end{
  69. if(xyrange)xyrange->range.end = atoi(tag_start);
  70. }
  71. action parse_xyvalue_array_value{
  72. if(xyrange && xyrange->array.count < TMEDIA_imageattr_ARRAY_MAX_SIZE){
  73. xyrange->array.values[xyrange->array.count++] = atoi(tag_start);
  74. }
  75. }
  76. action set_parse_qvalue{
  77. if(*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE){
  78. sets[*sets_count].qvalue = atof(tag_start);
  79. }
  80. }
  81. action srange_is_array{
  82. if(srange) srange->is_range = 0;
  83. }
  84. action srange_is_not_array{
  85. if(srange) srange->is_range = 1;
  86. }
  87. action start_srange{
  88. srange = (*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE) ? &sets[*sets_count].srange : tsk_null;
  89. }
  90. action parse_srange_array_value{
  91. if(srange && srange->array.count < TMEDIA_imageattr_ARRAY_MAX_SIZE){
  92. srange->array.values[srange->array.count++] = atof(tag_start);
  93. }
  94. }
  95. action parse_srange_range_start{
  96. if(srange) srange->range.start = atof(tag_start);
  97. }
  98. action parse_srange_range_end{
  99. if(srange) srange->range.end = atof(tag_start);
  100. }
  101. action parse_prange_start{
  102. if(*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE) sets[*sets_count].prange.start = atof(tag_start);
  103. }
  104. action parse_prange_end{
  105. if(*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE) sets[*sets_count].prange.end = atof(tag_start), sets[*sets_count].prange.is_present = 1;
  106. }
  107. PT = DIGIT+ | "*";
  108. onetonine = "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";
  109. xyvalue = (onetonine DIGIT{,5});
  110. step = xyvalue;
  111. xyrange = ( "[" xyvalue>tag %parse_xyvalue_range_start ":" ( step>tag %parse_xyvalue_range_step ":" )? xyvalue>tag %parse_xyvalue_range_end "]" )%set_is_range | ( "[" xyvalue>tag %parse_xyvalue_array_value ( "," xyvalue>tag %parse_xyvalue_array_value )+ "]" )%set_is_not_range | xyvalue%set_is_not_range>tag %parse_xyvalue_array_value;
  112. spvalue = ( "0" "." onetonine DIGIT{,3} ) | ( onetonine "." DIGIT{1,4} );
  113. srange = (( "[" spvalue>tag %parse_srange_array_value ( "," spvalue>tag %parse_srange_array_value )+ "]" )%srange_is_array | ( "[" spvalue>tag %parse_srange_range_start "-" spvalue>tag %parse_srange_range_end "]" )%srange_is_not_array | spvalue>tag %parse_srange_array_value %srange_is_array)>start_srange;
  114. prange = ( "[" spvalue>tag %parse_prange_start "-" spvalue>tag %parse_prange_end "]" );
  115. _qvalue = (( "0" "." DIGIT{1,2} ) | ( "1" "." "0"{1,2} ))>tag %set_parse_qvalue; #qvalue collision
  116. key_value = ( "sar="i srange ) | ( "par="i prange ) | ( "q="i _qvalue );
  117. set = ("[" "x="i xyrange>is_xrange "," "y="i xyrange>is_yrange ( "," key_value )* "]")%set_parsed;
  118. attr_list = ( set ( WSP+ set )* ) | "*";
  119. imageattr = ( WSP* ( "send"i%is_send | "recv"i%is_recv ) WSP+ attr_list ){1,2};
  120. # Entry point
  121. main:= imageattr;
  122. }%%
  123. static int tmedia_imageattr_reset(tmedia_imageattr_xt* self)
  124. {
  125. if(self){
  126. tsk_size_t i;
  127. memset(self, 0, sizeof(*self));
  128. for(i = 0; i < TMEDIA_imageattr_ARRAY_MAX_SIZE; ++i){
  129. self->send.sets[i].qvalue = 0.5;
  130. self->recv.sets[i].qvalue = 0.5;
  131. }
  132. return 0;
  133. }
  134. TSK_DEBUG_ERROR("Invalid parameter");
  135. return -1;
  136. }
  137. int tmedia_imageattr_parse(tmedia_imageattr_xt* self, const void* in_data, tsk_size_t in_size)
  138. {
  139. int cs = 0;
  140. const char *p = in_data;
  141. const char *pe = p + in_size;
  142. const char *eof = pe;
  143. const char *tag_start = tsk_null;
  144. tmedia_imageattr_set_xt* sets = tsk_null;
  145. tsk_size_t* sets_count = tsk_null;
  146. tmedia_imageattr_xyrange_xt* xyrange = tsk_null;
  147. tmedia_imageattr_srange_xt* srange = tsk_null;
  148. TSK_RAGEL_DISABLE_WARNINGS_BEGIN()
  149. %%write data;
  150. (void)(eof);
  151. (void)(tmedia_machine_imageattr_first_final);
  152. (void)(tmedia_machine_imageattr_error);
  153. (void)(tmedia_machine_imageattr_en_main);
  154. %%write init;
  155. tmedia_imageattr_reset(self);
  156. %%write exec;
  157. TSK_RAGEL_DISABLE_WARNINGS_END()
  158. if( cs < %%{ write first_final; }%% ){
  159. TSK_DEBUG_ERROR("Parsing failed to parse image-attr=%s", (char*)in_data);
  160. return -1;
  161. }
  162. return 0;
  163. }