123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- /*
- * Copyright (C) 2012-2015 Doubango Telecom <http://www.doubango.org>
- *
- * This file is part of Open Source Doubango Framework.
- *
- * DOUBANGO is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * DOUBANGO is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with DOUBANGO.
- *
- */
- /**@file tmedia_imageattr.c
- * @brief 'image-attr' parser as per RFC 6236
- */
- #include "tinymedia/tmedia_imageattr.h"
- #include "tsk_ragel_state.h"
- #include "tsk_debug.h"
- #include <stdlib.h>
- /***********************************
- * Ragel state machine.
- */
- %%{
- machine tmedia_machine_imageattr;
- # Includes
- include tmedia_machine_utils "./ragel/tmedia_machine_utils.rl";
- action tag{
- tag_start = p;
- }
- action is_send{
- sets = &self->send.sets[0];
- sets_count = &self->send.count;
- *sets_count = 0;
- }
- action is_recv{
- sets = &self->recv.sets[0];
- sets_count = &self->recv.count;
- *sets_count = 0;
- }
- action is_xrange{
- xyrange = (*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE) ? &sets[*sets_count].xrange : tsk_null;
- }
- action is_yrange{
- xyrange = (*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE) ? &sets[*sets_count].yrange : tsk_null;
- }
- action set_parsed{
- if(*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE) (*sets_count)++;
- }
- action set_is_not_range{
- if(xyrange) xyrange->is_range = 0;
- }
- action set_is_range{
- if(xyrange) xyrange->is_range = 1;
- }
- action parse_xyvalue_range_start{
- if(xyrange)xyrange->range.start = atoi(tag_start);
- }
- action parse_xyvalue_range_step{
- if(xyrange)xyrange->range.step = atoi(tag_start);
- }
- action parse_xyvalue_range_end{
- if(xyrange)xyrange->range.end = atoi(tag_start);
- }
- action parse_xyvalue_array_value{
- if(xyrange && xyrange->array.count < TMEDIA_imageattr_ARRAY_MAX_SIZE){
- xyrange->array.values[xyrange->array.count++] = atoi(tag_start);
- }
- }
- action set_parse_qvalue{
- if(*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE){
- sets[*sets_count].qvalue = atof(tag_start);
- }
- }
- action srange_is_array{
- if(srange) srange->is_range = 0;
- }
- action srange_is_not_array{
- if(srange) srange->is_range = 1;
- }
- action start_srange{
- srange = (*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE) ? &sets[*sets_count].srange : tsk_null;
- }
- action parse_srange_array_value{
- if(srange && srange->array.count < TMEDIA_imageattr_ARRAY_MAX_SIZE){
- srange->array.values[srange->array.count++] = atof(tag_start);
- }
- }
- action parse_srange_range_start{
- if(srange) srange->range.start = atof(tag_start);
- }
- action parse_srange_range_end{
- if(srange) srange->range.end = atof(tag_start);
- }
- action parse_prange_start{
- if(*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE) sets[*sets_count].prange.start = atof(tag_start);
- }
- action parse_prange_end{
- if(*sets_count < TMEDIA_imageattr_ARRAY_MAX_SIZE) sets[*sets_count].prange.end = atof(tag_start), sets[*sets_count].prange.is_present = 1;
- }
- PT = DIGIT+ | "*";
- onetonine = "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";
- xyvalue = (onetonine DIGIT{,5});
- step = xyvalue;
- 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;
- spvalue = ( "0" "." onetonine DIGIT{,3} ) | ( onetonine "." DIGIT{1,4} );
- 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;
- prange = ( "[" spvalue>tag %parse_prange_start "-" spvalue>tag %parse_prange_end "]" );
- _qvalue = (( "0" "." DIGIT{1,2} ) | ( "1" "." "0"{1,2} ))>tag %set_parse_qvalue; #qvalue collision
- key_value = ( "sar="i srange ) | ( "par="i prange ) | ( "q="i _qvalue );
- set = ("[" "x="i xyrange>is_xrange "," "y="i xyrange>is_yrange ( "," key_value )* "]")%set_parsed;
- attr_list = ( set ( WSP+ set )* ) | "*";
- imageattr = ( WSP* ( "send"i%is_send | "recv"i%is_recv ) WSP+ attr_list ){1,2};
- # Entry point
- main:= imageattr;
- }%%
- static int tmedia_imageattr_reset(tmedia_imageattr_xt* self)
- {
- if(self){
- tsk_size_t i;
- memset(self, 0, sizeof(*self));
- for(i = 0; i < TMEDIA_imageattr_ARRAY_MAX_SIZE; ++i){
- self->send.sets[i].qvalue = 0.5;
- self->recv.sets[i].qvalue = 0.5;
- }
- return 0;
- }
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- int tmedia_imageattr_parse(tmedia_imageattr_xt* self, const void* in_data, tsk_size_t in_size)
- {
- int cs = 0;
- const char *p = in_data;
- const char *pe = p + in_size;
- const char *eof = pe;
-
- const char *tag_start = tsk_null;
- tmedia_imageattr_set_xt* sets = tsk_null;
- tsk_size_t* sets_count = tsk_null;
- tmedia_imageattr_xyrange_xt* xyrange = tsk_null;
- tmedia_imageattr_srange_xt* srange = tsk_null;
- TSK_RAGEL_DISABLE_WARNINGS_BEGIN()
- %%write data;
- (void)(eof);
- (void)(tmedia_machine_imageattr_first_final);
- (void)(tmedia_machine_imageattr_error);
- (void)(tmedia_machine_imageattr_en_main);
- %%write init;
- tmedia_imageattr_reset(self);
- %%write exec;
- TSK_RAGEL_DISABLE_WARNINGS_END()
- if( cs < %%{ write first_final; }%% ){
- TSK_DEBUG_ERROR("Parsing failed to parse image-attr=%s", (char*)in_data);
- return -1;
- }
-
- return 0;
- }
|