First code commit
diff --git a/doc/Thrift_TP_Gen_CNL113785_1551.doc b/doc/Thrift_TP_Gen_CNL113785_1551.doc
new file mode 100644
index 0000000..e0f5e82
--- /dev/null
+++ b/doc/Thrift_TP_Gen_CNL113785_1551.doc
Binary files differ
diff --git a/doc/Thrift_TP_Gen_CNL113785_PRI.doc b/doc/Thrift_TP_Gen_CNL113785_PRI.doc
new file mode 100644
index 0000000..2283fb1
--- /dev/null
+++ b/doc/Thrift_TP_Gen_CNL113785_PRI.doc
Binary files differ
diff --git a/src/TTPG.awk b/src/TTPG.awk
new file mode 100644
index 0000000..b4dfcce
--- /dev/null
+++ b/src/TTPG.awk
@@ -0,0 +1,2120 @@
+#/******************************************************************************
+#* Copyright (c) 2000-2018 Ericsson Telecom AB
+#* All rights reserved. This program and the accompanying materials
+#* are made available under the terms of the Eclipse Public License v2.0
+#* which accompanies this distribution, and is available at
+#* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+#*
+#******************************************************************************/
+
+
+function cc_prefix_thrift_type(typename,orig_module, type_module,dot_pos,tn,prefix,enum_suffix){
+ dot_pos=index(typename,".")
+ if(dot_pos>0){
+ type_module=substr(typename,1,dot_pos-1)
+ tn=substr(typename,dot_pos+1)
+ } else {
+ type_module=orig_module
+ tn=typename
+ }
+ if(is_basetype(tn,type_module)!=0){
+ if( type_module SUBSEP "TYPEDEF" SUBSEP tn in AST){
+ if(type_module SUBSEP "NAMESPACE" in AST){
+ prefix="::" dot_to_colon(AST[type_module SUBSEP "NAMESPACE"]) "::"
+ } else {
+ prefix="::"
+ }
+ } else {
+ prefix=""
+ }
+ } else if ( type_module SUBSEP "LIST_TYPES" SUBSEP tn in AST ) {
+ return "std::vector<" cc_prefix_thrift_type(AST[type_module SUBSEP "LIST_TYPES" SUBSEP tn],type_module) ">"
+ } else {
+ if(type_module SUBSEP "NAMESPACE" in AST){
+ prefix="::" dot_to_colon(AST[type_module SUBSEP "NAMESPACE"]) "::"
+ } else {
+ prefix="::"
+ }
+ if(is_enum(tn,type_module)!=0){
+ enum_suffix="::type"
+ } else {
+ enum_suffix=""
+ }
+ }
+
+ return prefix get_basetype(tn) enum_suffix
+}
+function basename(pn) {
+ sub(/^.*\//, "", pn)
+ return pn
+}
+
+
+function gen_outgoing_hh(services_data,s,module_name,temp_serv_name,temp_serv,serv_mod,dot_ind,func_data,func_num){
+ delete func_data
+ get_subarray(services_data,"FUNCS",func_data)
+ func_num=get_array_length(func_data)
+ for(i=1;i<=func_num;i++){
+ print " void outgoing_call(const "double_und(s)"__"double_und(func_data[i SUBSEP "NAME"])"_call& call_par," >> hh_file_name
+ print " const INTEGER *destination_address);" >> hh_file_name
+ print " void outgoing_reply(const "double_und(s)"__"double_und(func_data[i SUBSEP "NAME"])"_reply& reply_par," >> hh_file_name
+ print " const INTEGER *destination_address);" >> hh_file_name
+ print " void outgoing_raise(const "double_und(s)"__"double_und(func_data[i SUBSEP "NAME"])"_exception& raise_par," >> hh_file_name
+ print " const INTEGER *destination_address);" >> hh_file_name
+
+ }
+ if("EXTENDS" in services_data){
+ delete temp_serv
+ dot_ind=index(services_data["EXTENDS"],".")
+ if(dot_ind>0){
+ serv_mod=substr(services_data["EXTENDS"],1,dot_ind-1)
+ temp_serv_name=substr(services_data["EXTENDS"],dot_ind+1)
+ } else {
+ serv_mod=module_name
+ temp_serv_name=services_data["EXTENDS"]
+ }
+ get_subarray(AST,serv_mod SUBSEP "SERVICES" SUBSEP temp_serv_name,temp_serv)
+ gen_outgoing_hh(temp_serv,s,serv_mod)
+ }
+}
+
+function gen_service_hh(services_data,s,module_name,i,k,exception_data,comm,temp_serv_name,temp_serv,serv_mod,dot_ind,func_data,arg_data,func_num,arg_num,except_num,temp_cc_prefix,ret_name,first_arg,ref){
+ delete func_data
+ get_subarray(services_data,"FUNCS",func_data)
+
+ func_num=get_array_length(func_data)
+ for(i=1;i<=func_num;i++){
+ print "" >> hh_file_name
+
+ delete arg_data
+ get_subarray(func_data,i SUBSEP "FIELDS",arg_data)
+ arg_num=get_array_length(arg_data)
+ if (func_data[i SUBSEP "RETTYPE"] != "void") {
+ if(is_basetype(func_data[i SUBSEP "RETTYPE"],module_name) == 1){
+ ret_name=get_basetype(func_data[i SUBSEP "RETTYPE"]) " "
+ first_arg=""
+ } else {
+ if(arg_num==0){
+ comm = ""
+ } else {
+ comm =", "
+ }
+ ret_name="void "
+ first_arg=cc_prefix_thrift_type(func_data[i SUBSEP "RETTYPE"],module_name) "& " comm
+ }
+ } else {
+ ret_name="void "
+ first_arg=""
+ }
+
+ print " " ret_name " " func_data[i SUBSEP "NAME"] " ( " first_arg >> hh_file_name
+
+ for(k=1;k<=arg_num;k++){
+ if(k==arg_num){
+ comm = ""
+ } else {
+ comm =","
+ }
+ if((is_basetype(arg_data[k SUBSEP "TYPE"],module_name)==1) || (is_enum(arg_data[k SUBSEP "TYPE"],module_name)==1)){
+ ref = ""
+ } else {
+ ref = "&"
+ }
+ print " const " cc_prefix_thrift_type(arg_data[k SUBSEP "TYPE"],module_name) ref comm >> hh_file_name
+ }
+ print " );" >> hh_file_name
+ }
+ if("EXTENDS" in services_data){
+ delete temp_serv
+ dot_ind=index(services_data["EXTENDS"],".")
+ if(dot_ind>0){
+ serv_mod=substr(services_data["EXTENDS"],1,dot_ind-1)
+ temp_serv_name=substr(services_data["EXTENDS"],dot_ind+1)
+ } else {
+ serv_mod=module_name
+ temp_serv_name=services_data["EXTENDS"]
+ }
+ get_subarray(AST,serv_mod SUBSEP "SERVICES" SUBSEP temp_serv_name,temp_serv)
+ gen_service_hh(temp_serv,s,serv_mod)
+ }
+}
+function gen_service_event_call_cc(services_data,s,module_name,func_num_base,i,k,exception_data,comm,temp_serv_name,temp_serv,serv_mod,dot_ind,func_data,arg_data,func_num,arg_num,except_num,temp_cc_prefix,ret_name,first_arg,ref){
+
+ delete func_data
+ get_subarray(services_data,"FUNCS",func_data)
+
+ func_num=get_array_length(func_data)
+ for(i=1;i<=func_num;i++){
+ print "" >> cc_file_name
+
+ delete arg_data
+ get_subarray(func_data,i SUBSEP "FIELDS",arg_data)
+ arg_num=get_array_length(arg_data)
+
+ print " case "func_num_base+i":{" >> cc_file_name
+ print " "double_und(s)"__"double_und(func_data[i SUBSEP "NAME"])"_call call_par;" >> cc_file_name
+
+ for(k=1;k<=arg_num;k++){
+ print " conv_thrift_ttcn(*(("cc_prefix_thrift_type(arg_data[k SUBSEP "TYPE"],module_name)"*)(_push_data["k-1"])),call_par."double_und(arg_data[k SUBSEP "NAME"])"());" >> cc_file_name
+ }
+ print " incoming_call(call_par,&addr);" >> cc_file_name
+ print " }" >> cc_file_name
+ print " break;" >> cc_file_name
+ }
+ if("EXTENDS" in services_data){
+ delete temp_serv
+ dot_ind=index(services_data["EXTENDS"],".")
+ if(dot_ind>0){
+ serv_mod=substr(services_data["EXTENDS"],1,dot_ind-1)
+ temp_serv_name=substr(services_data["EXTENDS"],dot_ind+1)
+ } else {
+ serv_mod=module_name
+ temp_serv_name=services_data["EXTENDS"]
+ }
+ get_subarray(AST,serv_mod SUBSEP "SERVICES" SUBSEP temp_serv_name,temp_serv)
+ gen_service_event_call_cc(temp_serv,s,serv_mod,func_num_base+func_num)
+ }
+}
+function gen_service_outgoing_cc(services_data,s,module_name,func_num_base,i,k,exception_data,comm,temp_serv_name,temp_serv,serv_mod,dot_ind,func_data,arg_data,func_num,arg_num,except_num,temp_cc_prefix,ret_name,first_arg,ref){
+
+ delete func_data
+ get_subarray(services_data,"FUNCS",func_data)
+
+ func_num=get_array_length(func_data)
+ for(i=1;i<=func_num;i++){
+
+ print "void "double_und(s)"__PT::outgoing_call(const "double_und(s)"__"double_und(func_data[i SUBSEP "NAME"])"_call& call_par," >> cc_file_name
+ print " const INTEGER * /*destination_address*/)" >> cc_file_name
+ print "{" >> cc_file_name
+ print " if(port_mode!=1){" >> cc_file_name
+ print " Thrift__Common::Thrift__port__error error_exception;" >> cc_file_name
+ print " error_exception.error__code()=1;" >> cc_file_name
+ print " error_exception.error__text()=\"The port is not in client mode\";" >> cc_file_name
+ print " "double_und(s)"__"double_und(func_data[i SUBSEP "NAME"])"_exception ex(error_exception);" >> cc_file_name
+ print " incoming_exception(ex,NULL);" >> cc_file_name
+ print " return;" >> cc_file_name
+ print " }" >> cc_file_name
+ print "" >> cc_file_name
+
+ delete arg_data
+ get_subarray(func_data,i SUBSEP "FIELDS",arg_data)
+ arg_num=get_array_length(arg_data)
+ for(k=1;k<=arg_num;k++){
+ print " " cc_prefix_thrift_type(arg_data[k SUBSEP "TYPE"],module_name) " " arg_data[k SUBSEP "NAME"] ";" >> cc_file_name
+ print " conv_ttcn_thrift(call_par." double_und(arg_data[k SUBSEP "NAME"]) "()," arg_data[k SUBSEP "NAME"] ");" >> cc_file_name
+
+ }
+ if (func_data[i SUBSEP "RETTYPE"] != "void") {
+ print " "cc_prefix_thrift_type(func_data[i SUBSEP "RETTYPE"],module_name)" _return_val;" >> cc_file_name
+ }
+ print " " >> cc_file_name
+
+ print "" >> cc_file_name
+ print " try{" >> cc_file_name
+ first_arg=""
+ if (func_data[i SUBSEP "RETTYPE"] != "void") {
+ if(is_basetype(func_data[i SUBSEP "RETTYPE"],module_name)==1){
+ print " _return_val=" >> cc_file_name
+ } else {
+ if(arg_num==0){
+ comm = ""
+ } else {
+ comm =", "
+ }
+ first_arg=" _return_val" comm
+ }
+ }
+ print " client_handler->"func_data[i SUBSEP "NAME"]"(" first_arg >> cc_file_name
+ for(k=1;k<=arg_num;k++){
+ if(k==arg_num){
+ comm = ""
+ } else {
+ comm =", "
+ }
+ print " "arg_data[k SUBSEP "NAME"] comm >> cc_file_name
+ }
+ print " );" >> cc_file_name
+
+ delete exception_data
+ get_subarray(func_data,i SUBSEP "THROWS",exception_data)
+ except_num=get_array_length(exception_data)
+ for(k=1;k<=except_num;k++){
+ print " } catch ( " cc_prefix_thrift_type(exception_data[k SUBSEP "TYPE"],module_name) " " exception_data[k SUBSEP "NAME"] " ) {" >> cc_file_name
+ print " "double_und(exception_data[k SUBSEP "TYPE"])" _"exception_data[k SUBSEP "NAME"]";" >> cc_file_name
+ print " conv_thrift_ttcn("exception_data[k SUBSEP "NAME"]",_"exception_data[k SUBSEP "NAME"]");" >> cc_file_name
+ print " " >> cc_file_name
+ print " "double_und(s)"__"double_und(func_data[i SUBSEP "NAME"])"_exception ex(_ouch);" >> cc_file_name
+ print " incoming_exception(ex,NULL);" >> cc_file_name
+ print " return;" >> cc_file_name
+ }
+ print " } catch (...) {" >> cc_file_name
+ print " Thrift__Common::Thrift__port__error error_exception;" >> cc_file_name
+ print " error_exception.error__code()=1;" >> cc_file_name
+ print " error_exception.error__text()=\"The Thrift libary have thrown an exception\";" >> cc_file_name
+ print " "double_und(s)"__"double_und(func_data[i SUBSEP "NAME"])"_exception ex(error_exception);" >> cc_file_name
+ print " incoming_exception(ex,NULL);" >> cc_file_name
+ print " return;" >> cc_file_name
+ print " }" >> cc_file_name
+ print "" >> cc_file_name
+ print " "double_und(s)"__"double_und(func_data[i SUBSEP "NAME"])"_reply _reply;" >> cc_file_name
+ if (func_data[i SUBSEP "RETTYPE"] != "void") {
+ print " conv_thrift_ttcn(_return_val,_reply.return_value());" >> cc_file_name
+ }
+ print " incoming_reply(_reply,NULL);" >> cc_file_name
+ print "}" >> cc_file_name
+ print "" >> cc_file_name
+
+
+ print "void "double_und(s)"__PT::outgoing_reply(const "double_und(s)"__"double_und(func_data[i SUBSEP "NAME"])"_reply& reply_par," >> cc_file_name
+ print " const INTEGER * destination_address)" >> cc_file_name
+ print "{" >> cc_file_name
+ print " if(destination_address==NULL){" >> cc_file_name
+ print " TTCN_error(\"Reply can not be sent. There address is missing\");" >> cc_file_name
+ print " }" >> cc_file_name
+ print " int cp=*destination_address;" >> cc_file_name
+ print " if(clients.count(cp)==0){" >> cc_file_name
+ print " TTCN_error(\"Reply can not be sent. Wrong address %d\",cp);" >> cc_file_name
+ print " }" >> cc_file_name
+ print "" >> cc_file_name
+ print " std::map<int,void*>::iterator it=client_data.find(cp);" >> cc_file_name
+ print " " >> cc_file_name
+ print " if(it==client_data.end()){" >> cc_file_name
+ print " TTCN_error(\"Reply can not be sent. Wrong address %d\",cp);" >> cc_file_name
+ print " }" >> cc_file_name
+ print "" >> cc_file_name
+ print " struct internal_comm_struct *comm_buff=(struct internal_comm_struct *)it->second;" >> cc_file_name
+ print " comm_buff->code=0;" >> cc_file_name
+ if (func_data[i SUBSEP "RETTYPE"] != "void") {
+ print " conv_ttcn_thrift(reply_par.return_value(),*("cc_prefix_thrift_type(func_data[i SUBSEP "RETTYPE"],module_name)"*)comm_buff->data["arg_num"]);" >> cc_file_name
+ }
+ print " write(cp,&comm_buff,sizeof(void*));" >> cc_file_name
+ print " client_data.erase(it);" >> cc_file_name
+ print "}" >> cc_file_name
+
+ print "void "double_und(s)"__PT::outgoing_raise(const "double_und(s)"__"double_und(func_data[i SUBSEP "NAME"])"_exception& raise_exception," >> cc_file_name
+ print " const INTEGER * destination_address)" >> cc_file_name
+ print "{" >> cc_file_name
+ print " if(destination_address==NULL){" >> cc_file_name
+ print " TTCN_error(\"Exception can not be sent. There address is missing\");" >> cc_file_name
+ print " }" >> cc_file_name
+ print " int cp=*destination_address;" >> cc_file_name
+ print " if(clients.count(cp)==0){" >> cc_file_name
+ print " TTCN_error(\"Exception can not be sent. Wrong address %d\",cp);" >> cc_file_name
+ print " }" >> cc_file_name
+ print "" >> cc_file_name
+ print " std::map<int,void*>::iterator it=client_data.find(cp);" >> cc_file_name
+ print " " >> cc_file_name
+ print " if(it==client_data.end()){" >> cc_file_name
+ print " TTCN_error(\"Exception can not be sent. Wrong address %d\",cp);" >> cc_file_name
+ print " }" >> cc_file_name
+ print "" >> cc_file_name
+ print " switch(raise_exception.get_selection()){" >> cc_file_name
+
+ for(k=1;k<=except_num;k++){
+ print " case "double_und(s)"__"double_und(func_data[i SUBSEP "NAME"])"_exception::ALT_"double_und(f)"__TypesAndPorts_"double_und(exception_data[k SUBSEP "TYPE"])":{" >> cc_file_name
+ print " struct internal_comm_struct *comm_buff=(struct internal_comm_struct *)it->second;" >> cc_file_name
+ print "" >> cc_file_name
+ print " comm_buff->code=1;" >> cc_file_name
+ print " conv_ttcn_thrift(raise_exception."double_und(f)"__TypesAndPorts_"double_und(exception_data[k SUBSEP "TYPE"])"_field(),*(" cc_prefix_thrift_type(exception_data[k SUBSEP "TYPE"],module_name)"*)comm_buff->data["arg_num+k"]);" >> cc_file_name
+ print " write(cp,&comm_buff,sizeof(void*));" >> cc_file_name
+ print " client_data.erase(it);" >> cc_file_name
+ print " }" >> cc_file_name
+ print " break;" >> cc_file_name
+ }
+
+ print " default:" >> cc_file_name
+ print " TTCN_error(\"Invalid exception was sent.\");" >> cc_file_name
+ print " break;" >> cc_file_name
+ print " }" >> cc_file_name
+ print "}" >> cc_file_name
+
+ }
+
+ if("EXTENDS" in services_data){
+ delete temp_serv
+ dot_ind=index(services_data["EXTENDS"],".")
+ if(dot_ind>0){
+ serv_mod=substr(services_data["EXTENDS"],1,dot_ind-1)
+ temp_serv_name=substr(services_data["EXTENDS"],dot_ind+1)
+ } else {
+ serv_mod=module_name
+ temp_serv_name=services_data["EXTENDS"]
+ }
+ get_subarray(AST,serv_mod SUBSEP "SERVICES" SUBSEP temp_serv_name,temp_serv)
+ gen_service_outgoing_cc(temp_serv,s,serv_mod,func_num_base+func_num)
+ }
+}
+
+function gen_service_cc(services_data,s,module_name,func_num_base,i,k,exception_data,comm,temp_serv_name,temp_serv,serv_mod,dot_ind,func_data,arg_data,func_num,arg_num,except_num,temp_cc_prefix,ret_name,first_arg,ref){
+ delete func_data
+ get_subarray(services_data,"FUNCS",func_data)
+
+ func_num=get_array_length(func_data)
+ for(i=1;i<=func_num;i++){
+ print "" >> cc_file_name
+
+ delete arg_data
+ get_subarray(func_data,i SUBSEP "FIELDS",arg_data)
+ arg_num=get_array_length(arg_data)
+ if (func_data[i SUBSEP "RETTYPE"] != "void") {
+ if(is_basetype(func_data[i SUBSEP "RETTYPE"],module_name) == 1){
+ ret_name=get_basetype(func_data[i SUBSEP "RETTYPE"]) " "
+ first_arg=""
+ } else {
+ if(arg_num==0){
+ comm = ""
+ } else {
+ comm =", "
+ }
+ ret_name="void "
+ first_arg=cc_prefix_thrift_type(func_data[i SUBSEP "RETTYPE"],module_name) "& _ret_val" comm
+ }
+ } else {
+ ret_name="void "
+ first_arg=""
+ }
+
+ print " " ret_name " "s"Handler::" func_data[i SUBSEP "NAME"] " ( " first_arg >> cc_file_name
+
+ for(k=1;k<=arg_num;k++){
+ if(k==arg_num){
+ comm = ""
+ } else {
+ comm =","
+ }
+ if((is_basetype(arg_data[k SUBSEP "TYPE"],module_name)==1) || (is_enum(arg_data[k SUBSEP "TYPE"],module_name)==1)){
+ ref = ""
+ } else {
+ ref = "&"
+ }
+ print " const " cc_prefix_thrift_type(arg_data[k SUBSEP "TYPE"],module_name) ref " " arg_data[k SUBSEP "NAME"] comm >> cc_file_name
+ }
+ print " ){" >> cc_file_name
+ is_return=0
+ if (func_data[i SUBSEP "RETTYPE"] != "void") {
+ if(is_basetype(func_data[i SUBSEP "RETTYPE"],module_name) == 1){
+ print " " get_basetype(func_data[i SUBSEP "RETTYPE"]) " _ret_val;" >> cc_file_name
+ is_return=1
+ }
+ } else {
+ is_return=2
+ }
+
+ delete exception_data
+ get_subarray(func_data,i SUBSEP "THROWS",exception_data)
+ except_num=get_array_length(exception_data)
+ for(k=1;k<=except_num;k++){
+ print " " cc_prefix_thrift_type(exception_data[k SUBSEP "TYPE"],module_name) " " exception_data[k SUBSEP "NAME"] ";" >> cc_file_name
+ }
+ print "" >> cc_file_name
+ print " int _s=connect();" >> cc_file_name
+ print " void * _push_data["arg_num+1+except_num"];" >> cc_file_name
+ print " struct internal_comm_struct _comm_buff;" >> cc_file_name
+ print "" >> cc_file_name
+ for(k=1;k<=arg_num;k++){
+ print " _push_data["k-1"]=(void*)&"arg_data[k SUBSEP "NAME"]";" >> cc_file_name
+ }
+ if(is_return!=2){
+ print " _push_data["arg_num"]=(void*)&_ret_val;" >> cc_file_name
+ }
+ for(k=1;k<=except_num;k++){
+ print " _push_data["k+arg_num"]=(void*)&"exception_data[k SUBSEP "NAME"]";" >> cc_file_name
+ }
+ print "" >> cc_file_name
+ print " _comm_buff.code="func_num_base+i";" >> cc_file_name
+ print " _comm_buff.data=(void **)&_push_data;" >> cc_file_name
+ print "" >> cc_file_name
+
+ print " void *_dp=(void*)&_comm_buff;" >> cc_file_name
+ print " write(_s,&_dp,sizeof(void *));" >> cc_file_name
+ print " read(_s,&_dp,sizeof(void *));" >> cc_file_name
+ print "" >> cc_file_name
+ print " int code=((struct internal_comm_struct*)_dp)->code;" >> cc_file_name
+ print "" >> cc_file_name
+ print " switch(code){" >> cc_file_name
+ print " case 0:" >> cc_file_name
+ print " break;" >> cc_file_name
+ for(k=1;k<=except_num;k++){
+ print " case "k":" >> cc_file_name
+ print " throw "exception_data[k SUBSEP "NAME"]";" >> cc_file_name
+ print " break;" >> cc_file_name
+ }
+
+
+ print " default:" >> cc_file_name
+ print " break;" >> cc_file_name
+ print " }" >> cc_file_name
+ print " close(_s);" >> cc_file_name
+
+
+ if(is_return==1){
+ print " return _ret_val;" >> cc_file_name
+ }
+ print "}" >> cc_file_name
+ }
+ if("EXTENDS" in services_data){
+ delete temp_serv
+ dot_ind=index(services_data["EXTENDS"],".")
+ if(dot_ind>0){
+ serv_mod=substr(services_data["EXTENDS"],1,dot_ind-1)
+ temp_serv_name=substr(services_data["EXTENDS"],dot_ind+1)
+ } else {
+ serv_mod=module_name
+ temp_serv_name=services_data["EXTENDS"]
+ }
+ get_subarray(AST,serv_mod SUBSEP "SERVICES" SUBSEP temp_serv_name,temp_serv)
+ gen_service_cc(temp_serv,s,serv_mod,func_num_base+func_num)
+ }
+}
+
+function is_basetype(tn,module,type_list, type_module,dot_pos,typename){
+ type_list["bool"]=1
+ type_list["byte"]=1
+ type_list["i16"]=1
+ type_list["i32"]=1
+ type_list["i64"]=1
+ type_list["double"]=1
+ type_list["string"]=2
+ type_list["binary"]=2
+
+ if(tn in type_list ){
+ return type_list[tn]
+ } else {
+ typename=tn
+ dot_pos=index(typename,".")
+ if(dot_pos>0){
+ type_module=substr(typename,1,dot_pos-1)
+ tn=substr(typename,dot_pos+1)
+ return is_basetype(tn,type_module)
+ } else {
+ if( module SUBSEP "TYPEDEF" SUBSEP tn in AST){
+ return is_basetype(AST[module SUBSEP "TYPEDEF" SUBSEP tn],module)
+ }
+ }
+
+ return 0
+ }
+}
+function is_enum(tn,module, type_module,dot_pos){
+ if(is_basetype(tn,module)!=0){
+ return 0
+ } else {
+ dot_pos=index(typename,".")
+ if(dot_pos>0){
+ type_module=substr(typename,1,dot_pos-1)
+ tn=substr(typename,dot_pos+1)
+ return is_enum(tn,type_module)
+ } else {
+ if( module SUBSEP "ENUMS" SUBSEP tn SUBSEP "NAME" in AST){
+ return 1
+ }
+ }
+
+ return 0
+ }
+}
+function is_basetype_ttcn(tn,type_list){
+ type_list["bool"]=1
+ type_list["byte"]=1
+ type_list["i16"]=1
+ type_list["i32"]=1
+ type_list["i64"]=1
+ type_list["double"]=1
+ type_list["string"]=1
+ type_list["binary"]=1
+
+ if(tn in type_list ){
+ return 1
+ } else {
+ return 0
+ }
+}
+
+function get_basetype(tn,type_list){
+ type_list["bool"]="bool"
+ type_list["byte"]="int8_t"
+ type_list["i16"]="int16_t"
+ type_list["i32"]="int32_t"
+ type_list["i64"]="int64_t"
+ type_list["double"]="double"
+ type_list["string"]="std::string"
+ type_list["binary"]="std::string"
+
+
+ if(tn in type_list ){
+ return type_list[tn]
+ } else {
+ return tn
+ }
+}
+
+function prefix_type(typename,orig_module, type_module,dot_pos,tn){
+ dot_pos=index(typename,".")
+ if(dot_pos>0){
+ type_module=substr(typename,1,dot_pos-1)
+ tn=substr(typename,dot_pos+1)
+ } else {
+ type_module=orig_module
+ tn=typename
+ }
+ if(is_basetype_ttcn(tn)==1){
+ type_module=f
+ }
+ if(type_module!=f){
+ return type_module "_TypesAndPorts." res_word(tn)
+ } else {
+ return res_word(tn)
+ }
+}
+
+function gen_service(services_data,s,module_name,i,k,exception_data,comm,temp_serv_name,temp_serv,serv_mod,dot_ind,func_data,arg_data,func_num,arg_num,except_num){
+ print "" >> file_name
+ delete func_data
+ get_subarray(services_data,"FUNCS",func_data)
+ func_num=get_array_length(func_data)
+ for(i=1;i<=func_num;i++){
+ print " signature " s "_" func_data[i SUBSEP "NAME"] " ( " >> file_name
+ delete arg_data
+ get_subarray(func_data,i SUBSEP "FIELDS",arg_data)
+ arg_num=get_array_length(arg_data)
+ for(k=1;k<=arg_num;k++){
+ if(k==arg_num){
+ comm = ""
+ } else {
+ comm =","
+ }
+ print " in " prefix_type(arg_data[k SUBSEP "TYPE"],module_name) " " res_word(arg_data[k SUBSEP "NAME"]) comm >> file_name
+ }
+ print " )" >> file_name
+ if( func_data[i SUBSEP "RETTYPE"] != "void") {
+ print " return " prefix_type(func_data[i SUBSEP "RETTYPE"],module_name) >> file_name
+ }
+ delete exception_data
+ get_subarray(func_data,i SUBSEP "THROWS",exception_data)
+
+ except_num=get_array_length(exception_data)
+
+ print " exception (" >> file_name
+
+ if(except_num>0){
+ comm = ","
+ } else {
+ comm =""
+ }
+ print " Thrift_port_error" comm >> file_name
+ if(except_num>0){
+ for(k=1;k<=except_num;k++){
+ if(k==except_num){
+ comm = ""
+ } else {
+ comm =","
+ }
+ print " " prefix_type(exception_data[k SUBSEP "TYPE"],module_name) comm >> file_name
+ }
+ }
+ print " )" >> file_name
+ print "" >> file_name
+ }
+ if("EXTENDS" in services_data){
+ delete temp_serv
+ dot_ind=index(services_data["EXTENDS"],".")
+ if(dot_ind>0){
+ serv_mod=substr(services_data["EXTENDS"],1,dot_ind-1)
+ temp_serv_name=substr(services_data["EXTENDS"],dot_ind+1)
+ } else {
+ serv_mod=module_name
+ temp_serv_name=services_data["EXTENDS"]
+ }
+ get_subarray(AST,serv_mod SUBSEP "SERVICES" SUBSEP temp_serv_name,temp_serv)
+ gen_service(temp_serv,s,serv_mod)
+ }
+}
+
+function gen_port_proc(services_data,s,module_name,temp_serv_name,temp_serv,serv_mod,dot_ind,func_data,func_num){
+ delete func_data
+ get_subarray(services_data,"FUNCS",func_data)
+ func_num=get_array_length(func_data)
+ for(i=1;i<=func_num;i++){
+ print " inout " s "_" func_data[i SUBSEP "NAME"] >> file_name
+ }
+ if("EXTENDS" in services_data){
+ delete temp_serv
+ dot_ind=index(services_data["EXTENDS"],".")
+ if(dot_ind>0){
+ serv_mod=substr(services_data["EXTENDS"],1,dot_ind-1)
+ temp_serv_name=substr(services_data["EXTENDS"],dot_ind+1)
+ } else {
+ serv_mod=module_name
+ temp_serv_name=services_data["EXTENDS"]
+ }
+ get_subarray(AST,serv_mod SUBSEP "SERVICES" SUBSEP temp_serv_name,temp_serv)
+ gen_port_proc(temp_serv,s,serv_mod)
+ }
+}
+
+function res_word(data,map){
+ map["value"]="value_"
+
+ if(data in map){
+ return map[data]
+ } else {
+ return data
+ }
+}
+
+function double_und(orig,ret_val){
+ ret_val=orig;
+ gsub(/_/,"__",ret_val);
+ return ret_val;
+}
+function dot_to_colon(orig,ret_val){
+ ret_val=orig;
+ gsub(/\./,"::",ret_val);
+ return ret_val;
+}
+
+function get_subarray(arr, ind, ret_val,x){
+# ret_val[1]=1;
+# delete ret_val;
+
+ for(x in arr){
+ match(x,"^"ind SUBSEP )
+ if(RSTART > 0 ){
+ ret_val[substr(x,RLENGTH+1)]=arr[x]
+ }
+ }
+# return ret_val;
+}
+
+
+function get_array_length(arr,ret_val,a,x){
+ delete ret_val
+ for(x in arr){
+ split(x,a,SUBSEP);
+ ret_val[a[1]]=a[1]
+ }
+ return length(ret_val)
+}
+
+function push_state(new_state){
+ ++state_stack_level;
+ state_stack[state_stack_level]=parser_state;
+ parser_state=new_state;
+# print "push " state_stack_level, " " state_stack[state_stack_level]
+}
+ function walk_array(arr, name, i,k,l,p)
+ {
+#print "walk array start " name
+ delete p
+ for (i in arr) {
+#print "process " i
+ split(i,k,SUBSEP)
+ if(length(k)>1){
+#print "subaaray found"
+ if(!(k[1] in p)){
+#print "subaaray process"
+ delete l;
+ get_subarray(arr,k[1],l)
+ walk_array(l, name "[" k[1] "]")
+ p[k[1]]=k[1]
+ }
+ } else {
+ printf("%s[%s] = %s\n", name, i, arr[i])
+ }
+ }
+#print "walk array end " name
+ }
+
+function pop_state(){
+ parser_state=state_stack[state_stack_level];
+ --state_stack_level;
+# print "pop " state_stack_level, " " state_stack[state_stack_level]
+}
+
+function start_state(){
+ parser_state="START";
+ state_stack_level=1;
+}
+
+ BEGIN {
+ comment= 0;
+ parser_state="START";
+ processed_files[ARGV[1]]=ARGV[1];
+ state_stack_level=1;
+ state_stack[1]="NONE"
+ definition_type_name=""
+ const_name=""
+ enum_name=""
+ field_id=""
+ fieldReq=""
+ fieldName=""
+ struct_name=""
+ save_def_val=0;
+ oneway=0;
+ if(!myserver){
+ myserver_name="TThreadedServer";
+ myserver_include="<thrift/server/TThreadedServer.h>"
+ } else {
+ myserver_name="myTThreadedServer";
+ myserver_include="\"myTThreadedServer.h\""
+ }
+ for(i=1;i<ARGC;i++){
+ match(ARGV[i],/\.thrift/)
+ AST["FILES" SUBSEP basename(substr(ARGV[i],1,RSTART-1))]=basename(substr(ARGV[i],1,RSTART-1));
+ }
+ }
+{
+# print " !!! ", $0
+ match(FILENAME,/\.thrift/)
+ t_file=basename(substr(FILENAME,1,RSTART-1))
+ while($0) # Get fields by pattern, not by delimiter
+ {
+ # should be run with gawk < 4.0.0 so FPAT can not be used
+ match($0, "((//)|[#]|([/][\\*])|([\\*]/)|[,]|[=]|(\"[^\"]+\")|('[^']+')|[{]|[}]|[<]|[>]|[:]|[(]|[)]|[;]|([[:alnum:]._+-]+))") # Find a token
+ if(RSTART > 0) { # token found
+ token = substr($0, RSTART, RLENGTH) # Get the located token
+ if(token ~ /(\"[^\"]+\")|('[^']+')/){
+ token=substr(token,2,RLENGTH-2)
+ }
+# printf("$0 before = <%s>\n",$0)
+# printf("token = <%s>\n",token)
+# print "RSTART = ",RSTART, " RLENGTH = " ,RLENGTH;
+ if( token ~ "(//)|[#]" ) { # Skip line comments
+ next;
+ } else if ( token ~ "[/][*].*" ){ # Skip block comment
+ comment = 1;
+ } else if (token ~ ".*[*][/].*" ) { # end of block comment
+ comment = 0;
+ } else if (comment == 0) { # process the token
+# printf("%s = <%s>\n",parser_state , token)
+ if(!( token ~ /[,]|[;]/ ) ){ # always skip the list separator
+
+ if(parser_state== "START"){
+ if ( token == "include"){
+ push_state("INCLUDE")
+
+ } else if ( token == "cpp_include"){
+ } else if ( token == "php_namespace"){
+ } else if ( token == "xsd_namespace"){
+ } else if ( token == "smalltalk.category"){
+ } else if ( token == "smalltalk.prefix"){
+ push_state("SKIP_1")
+
+ } else if ( token == "namespace"){
+ push_state("NAMESPACE");
+
+ } else if ( token == "typedef"){
+ push_state("TYPEDEF");
+ push_state("DEFINITIONTYPE")
+
+ } else if ( token == "const"){
+ push_state("CONSTDEF");
+ push_state("DEFINITIONTYPE")
+
+ } else if ( token == "enum"){
+ push_state("ENUMNAME");
+ enum_senum="ENUMS"
+
+ } else if ( token == "senum"){
+ push_state("ENUMNAME");
+ enum_senum="SENUMS"
+
+ } else if ( token == "struct"){
+ push_state("STRUCTNAME");
+ struct_execption="STRUCTS"
+
+ } else if ( token == "exception"){
+ push_state("STRUCTNAME");
+ struct_execption="EXCEPTIONS"
+
+ } else if ( token == "service"){
+ push_state("SERVICE_ID")
+
+ } #default{
+
+
+ } else if (parser_state== "SERVICE_ID"){
+ if ( token == "extends"){
+ pop_state()
+ push_state("SERVICE_EXTENDS")
+
+ } else if ( token == "{"){
+ func_num=0;
+ pop_state()
+ push_state("SERVICE_FUNCTIONS")
+
+ } else {
+ service_name=token;
+ AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "NAME"]=service_name;
+ }
+
+
+ } else if (parser_state== "SERVICE_EXTENDS"){
+ if(token == "{" ){
+ func_num=0;
+ pop_state()
+ push_state("SERVICE_FUNCTIONS")
+ } else {
+ AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "EXTENDS"]=token;
+ }
+
+ } else if (parser_state== "SERVICE_FUNCTIONS"){
+ if ( token == "oneway"){
+ oneway=1;
+
+ } else if ( token == "throws"){
+ push_state("THROWS")
+
+ } else if ( token == "}"){
+ pop_state()
+
+ } else if ( token == "map"){
+ print "map is unsupported"
+ definition_type_name="dummy";
+ push_state("FUNCNAME")
+ push_state("MAP_END");
+
+ } else if ( token == "list"){
+ push_state("FUNCNAME")
+ push_state("LIST_BEGIN");
+
+ } else if ( token == "set"){
+ push_state("FUNCNAME")
+ push_state("SET_BEGIN");
+
+ } else {
+ definition_type_name=token;
+ push_state("FUNCNAME")
+ }
+
+
+
+ } else if (parser_state== "FUNCNAME"){
+ if(token=="("){
+ filed_num=0
+ pop_state()
+ push_state("FUNCFIELD")
+ } else {
+ func_num++
+ if(oneway==1) {
+ AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "FUNCS" SUBSEP func_num SUBSEP "ONEWAY"]=fieldReq
+ oneway=0
+ }
+ AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "FUNCS" SUBSEP func_num SUBSEP "RETTYPE"]=definition_type_name
+ definition_type_name=""
+ AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "FUNCS" SUBSEP func_num SUBSEP "NAME"]=token
+ }
+
+ } else if (parser_state== "FUNCFIELD"){
+ if(save_def_val == 1){
+ save_def_val=0;
+ AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "FUNCS" SUBSEP func_num SUBSEP "FIELDS" SUBSEP filed_num SUBSEP "DEFVAL"]=builded_const
+ builded_const="";
+ }
+ if ( token ~ /^[0-9+-]+$/ ){
+ field_id=token
+
+ } else if ( token == ":"){ # just skip it
+
+ } else if ( token == "optional"){
+ fieldReq=token
+ } else if ( token == "required"){
+ fieldReq=token
+
+ } else if ( token == "="){
+ save_def_val=1;
+ push_state("CONST_VALUE_BUILD")
+
+ } else if ( token == ")"){
+ pop_state()
+
+ } else if ( token == "map"){
+ print "map is unsupported"
+ definition_type_name="dummy";
+ pop_state()
+ push_state("FUNCFIELDNAME")
+ push_state("MAP_END");
+
+ } else if ( token == "list"){
+ pop_state()
+ push_state("FUNCFIELDNAME")
+ push_state("LIST_BEGIN");
+
+ } else if ( token == "set"){
+ pop_state()
+ push_state("FUNCFIELDNAME")
+ push_state("SET_BEGIN");
+
+ } else {
+ definition_type_name=token;
+ pop_state()
+ push_state("FUNCFIELDNAME")
+ }
+
+
+ } else if (parser_state== "FUNCFIELDNAME"){
+ filed_num++
+ AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "FUNCS" SUBSEP func_num SUBSEP "FIELDS" SUBSEP filed_num SUBSEP "ID"]=field_id
+ field_id=""
+ if(fieldReq!="optional") {fieldReq="required"}
+ AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "FUNCS" SUBSEP func_num SUBSEP "FIELDS" SUBSEP filed_num SUBSEP "REQ"]=fieldReq
+ fieldReq=""
+ AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "FUNCS" SUBSEP func_num SUBSEP "FIELDS" SUBSEP filed_num SUBSEP "TYPE"]=definition_type_name
+ definition_type_name=""
+ AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "FUNCS" SUBSEP func_num SUBSEP "FIELDS" SUBSEP filed_num SUBSEP "NAME"]=token
+ pop_state()
+ push_state("FUNCFIELD")
+
+ } else if (parser_state== "THROWS"){
+ if(token=="("){
+ filed_num=0
+ pop_state()
+ push_state("THROWSFIELD")
+ }
+
+ } else if (parser_state== "THROWSFIELD"){
+ if(save_def_val == 1){
+ save_def_val=0;
+ AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "FUNCS" SUBSEP func_num SUBSEP "THROWS" SUBSEP filed_num SUBSEP "DEFVAL"]=builded_const
+ builded_const="";
+ }
+ if ( token ~ /^[0-9+-]+$/ ){
+ field_id=token
+
+ } else if ( token == ":"){ # just skip it
+
+ } else if ( token == "optional"){
+ fieldReq=token
+ } else if ( token == "required"){
+ fieldReq=token
+
+ } else if ( token == "="){
+ save_def_val=1;
+ push_state("CONST_VALUE_BUILD")
+
+ } else if ( token == ")"){
+ pop_state()
+
+ } else if ( token == "map"){
+ print "map is unsupported"
+ definition_type_name="dummy";
+ pop_state()
+ push_state("THROWSFIELDNAME")
+ push_state("MAP_END");
+
+ } else if ( token == "list"){
+ pop_state()
+ push_state("THROWSFIELDNAME")
+ push_state("LIST_BEGIN");
+
+ } else if ( token == "set"){
+ pop_state()
+ push_state("THROWSFIELDNAME")
+ push_state("SET_BEGIN");
+
+ } else {
+ definition_type_name=token;
+ pop_state()
+ push_state("THROWSFIELDNAME")
+
+
+ }
+
+ } else if (parser_state== "THROWSFIELDNAME"){
+ filed_num++
+ AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "FUNCS" SUBSEP func_num SUBSEP "THROWS" SUBSEP filed_num SUBSEP "ID"]=field_id
+ field_id=""
+ if(fieldReq!="optional") {fieldReq="required"}
+ AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "FUNCS" SUBSEP func_num SUBSEP "THROWS" SUBSEP filed_num SUBSEP "REQ"]=fieldReq
+ fieldReq=""
+ AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "FUNCS" SUBSEP func_num SUBSEP "THROWS" SUBSEP filed_num SUBSEP "TYPE"]=definition_type_name
+ definition_type_name=""
+ AST[t_file SUBSEP "SERVICES" SUBSEP service_name SUBSEP "FUNCS" SUBSEP func_num SUBSEP "THROWS" SUBSEP filed_num SUBSEP "NAME"]=token
+ pop_state()
+ push_state("THROWSFIELD")
+
+ } else if (parser_state== "STRUCTNAME"){
+ if (token == "{") {
+ pop_state()
+ push_state("FIELDTYPE")
+ filed_num=0;
+ } else {
+ struct_name=token
+ AST[t_file SUBSEP struct_execption SUBSEP struct_name SUBSEP "NAME"]=struct_name
+ }
+
+ } else if (parser_state== "FIELDTYPE"){
+ if(save_def_val == 1){
+ save_def_val=0;
+ AST[t_file SUBSEP struct_execption SUBSEP struct_name SUBSEP "FIELDS" SUBSEP filed_num SUBSEP "DEFVAL"]=builded_const
+ builded_const="";
+ }
+ if ( token ~ /^[0-9+-]+$/ ){
+ field_id=token
+
+ } else if ( token == ":"){ # just skip it
+
+ } else if ( token == "optional"){
+ fieldReq=token
+ } else if ( token == "required"){
+ fieldReq=token
+
+ } else if ( token == "="){
+ save_def_val=1;
+ push_state("CONST_VALUE_BUILD")
+
+ } else if ( token == "}"){
+ pop_state()
+
+ } else if ( token == "map"){
+ print "map is unsupported"
+ definition_type_name="dummy";
+ pop_state()
+ push_state("FIELDNAME")
+ push_state("MAP_END");
+
+ } else if ( token == "list"){
+ pop_state()
+ push_state("FIELDNAME")
+ push_state("LIST_BEGIN");
+
+ } else if ( token == "set"){
+ pop_state()
+ push_state("FIELDNAME")
+ push_state("SET_BEGIN");
+
+ } else {
+ definition_type_name=token;
+ pop_state()
+ push_state("FIELDNAME")
+ }
+
+
+ } else if (parser_state== "FIELDNAME"){
+ filed_num++
+ AST[t_file SUBSEP struct_execption SUBSEP struct_name SUBSEP "FIELDS" SUBSEP filed_num SUBSEP "ID"]=field_id
+ field_id=""
+ if(fieldReq!="optional") {fieldReq="required"}
+ AST[t_file SUBSEP struct_execption SUBSEP struct_name SUBSEP "FIELDS" SUBSEP filed_num SUBSEP "REQ"]=fieldReq
+ fieldReq=""
+ AST[t_file SUBSEP struct_execption SUBSEP struct_name SUBSEP "FIELDS" SUBSEP filed_num SUBSEP "TYPE"]=definition_type_name
+ definition_type_name=""
+ AST[t_file SUBSEP struct_execption SUBSEP struct_name SUBSEP "FIELDS" SUBSEP filed_num SUBSEP "NAME"]=token
+ pop_state()
+ push_state("FIELDTYPE")
+
+ } else if (parser_state== "ENUMNAME"){
+ if(token == "{"){
+ pop_state();
+ push_state("ENUM_VALUE")
+ } else {
+ AST[t_file SUBSEP enum_senum SUBSEP token SUBSEP "NAME"]=token
+ enum_name=token
+ enum_id=0
+ }
+
+ } else if (parser_state== "ENUM_VALUE"){
+ if ( token == "}"){
+ pop_state();
+
+ } else if ( token == "="){
+ push_state("ENUM_VALUE_VAL");
+
+ } else {
+ enum_id++;
+ AST[t_file SUBSEP enum_senum SUBSEP enum_name SUBSEP "VALUES" SUBSEP enum_id SUBSEP "NAME"]=token;
+
+ }
+
+ } else if (parser_state== "ENUM_VALUE_VAL"){
+ AST[t_file SUBSEP enum_senum SUBSEP enum_name SUBSEP "VALUES" SUBSEP enum_id SUBSEP "VAL"]=token;
+ pop_state();
+
+ } else if (parser_state== "CONSTDEF"){
+ if(token == "="){
+ pop_state();
+ push_state("CONST_VALUE")
+ } else {
+ AST[t_file SUBSEP "CONSTS" SUBSEP token SUBSEP "TYPE"]=definition_type_name
+ definition_type_name=""
+ const_name=token
+ }
+
+ } else if (parser_state== "CONST_VALUE"){
+ if ( token == "{"){
+ print "Map constatnt is not supported"
+ pop_state();
+ push_state("MAP_CONST_END")
+
+ } else if ( token == "["){
+ pop_state();
+ builded_const="{"
+ push_state("LIST_CONST_END")
+
+ } else {
+ AST[t_file SUBSEP "CONSTS" SUBSEP const_name SUBSEP "VALUE"]=token
+ pop_state();
+ }
+
+ } else if (parser_state== "CONST_VALUE_BUILD"){
+ if ( token == "{"){
+ print "Map constatnt is not supported"
+ pop_state();
+ push_state("MAP_CONST_BUILD_END")
+
+ } else if ( token == "["){
+ pop_state();
+ push_state("LIST_CONST_BUILD_END")
+ push_state("CONST_VALUE_BUILD")
+
+ } else {
+ builded_const=token
+ pop_state();
+ }
+
+ } else if (parser_state== "MAP_CONST_END"){
+ if(token == "}"){
+ AST[t_file SUBSEP "CONSTS" SUBSEP const_name SUBSEP "VALUE"]="dummy_map_const"
+ pop_state();
+ }
+
+ } else if (parser_state== "LIST_CONST_END"){
+ if(token == "]"){
+ AST[t_file SUBSEP "CONSTS" SUBSEP const_name SUBSEP "VALUE"]=builded_const"}";
+ pop_state();
+ } else {
+ lb=length(builded_const);
+ if(substr(builded_const,lb,1)=="{"){
+ comm=""
+ } else {
+ comm=", "
+ }
+ if ( token == "{"){
+ print "Map constatnt is not supported"
+ push_state("MAP_CONST_BUILD_END")
+
+ } else if ( token == "["){
+ builded_const=comm"{"
+ push_state("LIST_CONST_BUILD_END")
+
+ } else {
+
+ AST[t_file SUBSEP "CONSTS" SUBSEP const_name SUBSEP "VALUE"]=token
+ pop_state();
+ }
+ }
+
+ } else if (parser_state== "LIST_CONST_BUILD_END"){
+ if(token == "}"){
+ builded_const=builded_const"}";
+ pop_state();
+ } else {
+ lb=length(builded_const);
+ if(substr(builded_const,lb,1)=="{"){
+ comm=""
+ } else {
+ comm=", "
+ }
+ if ( token == "{"){
+ print "Map constatnt is not supported"
+ push_state("MAP_CONST_BUILD_END")
+
+ } else if ( token == "["){
+ builded_const=comm"{"
+ push_state("LIST_CONST_BUILD_END")
+
+ } else {
+
+ builded_const=comm token
+ pop_state();
+ }
+ }
+
+ } else if (parser_state== "MAP_CONST_BUILD_END"){
+ if(token == "}"){
+ lb=length(builded_const);
+ if(substr(builded_const,lb,1)=="{"){
+ comm=""
+ } else {
+ comm=", "
+ }
+ builded_const=comm"dummy_map_const"
+ pop_state();
+ }
+
+ } else if (parser_state== "INCLUDE"){
+ match(token,/\.thrift/)
+ AST[t_file SUBSEP "INCLUDES" SUBSEP substr(token,1,RSTART-1)]=substr(token,1,RSTART-1)
+ if( ! (token in processed_files )){
+ ARGV[ARGC]=token;
+ ARGC++;
+ processed_files[token]=token
+ AST["FILES" SUBSEP basename(substr(token,1,RSTART-1))]=basename(substr(token,1,RSTART-1));
+ }
+ pop_state();
+
+ } else if (parser_state== "NAMESPACE"){
+ if(token ~ /[*]|cpp/){
+ push_state("NAMESPACE_ID");
+ } else {
+ push_state("SKIP_1")
+ }
+
+ } else if (parser_state== "NAMESPACE_ID"){
+ AST[t_file SUBSEP "NAMESPACE"]=token
+
+ start_state();
+
+ } else if (parser_state== "DEFINITIONTYPE"){
+ if ( token == "map"){
+ print "map is unsupported"
+ definition_type_name="dummy";
+ pop_state()
+ push_state("MAP_END");
+
+ } else if ( token == "list"){
+ pop_state()
+ push_state("LIST_BEGIN");
+
+ } else if ( token == "set"){
+ pop_state()
+ push_state("SET_BEGIN");
+
+ } else {
+ definition_type_name=token;
+ pop_state()
+ }
+
+ } else if (parser_state== "LIST_BEGIN"){
+ if(token == "<"){
+ pop_state();
+ push_state("LIST_END")
+ push_state("DEFINITIONTYPE")
+ }
+
+
+ } else if (parser_state== "SET_BEGIN"){
+ if(token == "<"){
+ pop_state();
+ push_state("SET_END")
+ push_state("DEFINITIONTYPE")
+ }
+
+
+ } else if (parser_state== "LIST_END"){
+ pop_state();
+ if(token == ">"){
+ AST[t_file SUBSEP "LIST_TYPES" SUBSEP definition_type_name "_list"]=definition_type_name
+ definition_type_name = definition_type_name "_list"
+ } else {
+ printf "invalid token: ", token
+ definition_type_name="dummy";
+ }
+
+ } else if (parser_state== "SET_END"){
+ pop_state();
+ if(token == ">"){
+ AST[t_file SUBSEP "SET_TYPES" SUBSEP definition_type_name "_set"]=definition_type_name
+ definition_type_name = definition_type_name "_set"
+ } else {
+ printf "invalid token: ", token
+ definition_type_name="dummy";
+ }
+
+ } else if (parser_state== "MAP_END"){
+ if(token == ">"){
+ pop_state();
+ }
+
+ } else if (parser_state== "TYPEDEF"){
+ AST[t_file SUBSEP "TYPEDEF" SUBSEP token]=definition_type_name
+ definition_type_name=""
+ pop_state()
+
+ } else if (parser_state ~ /SKIP_[0-9]+/){
+ num_to_skip=substr(parser_state,6);
+ if(num_to_skip == 1){
+ start_state();
+ } else {
+ pop_state()
+ num_to_skip--
+ push_state("SKIP_"num_to_skip)
+ }
+
+ } else{
+ # do nothing
+
+ }
+ }
+# printf("new state %s \n",parser_state )
+ }
+ $0 = substr($0, RSTART+RLENGTH ) # Remove processed text from the raw data
+# printf("$0 after = <%s>\n",$0)
+ } else {
+ next;
+ }
+ }
+}
+
+END {
+
+# walk_array(AST, "AST")
+
+ delete files;
+ get_array_length(AST,files)
+ for(f in files){
+ if(f == "FILES"){
+ continue
+ }
+
+ file_name= f "_TypesAndPorts.ttcn"
+ print "module " f "_TypesAndPorts {" > file_name
+
+
+
+ delete module_data
+ get_subarray(AST,f,module_data);
+ print "" >> file_name
+
+ delete include_data
+ get_subarray(module_data,"INCLUDES",include_data)
+ for(i in include_data){
+ print " import from " i "_TypesAndPorts all" >> file_name
+ }
+
+ print " import from Thrift_Common all" >> file_name
+ print "" >> file_name
+ print " type integer address" >> file_name
+ print "" >> file_name
+ print "// Typedefs" >> file_name
+
+ delete typedef_data
+ get_subarray(module_data,"TYPEDEF",typedef_data)
+ for(t in typedef_data){
+ print " type " prefix_type(typedef_data[t],f) " " res_word(t) >> file_name
+ }
+
+ print "" >> file_name
+ print "// List/Set types" >> file_name
+
+ delete list_types
+ get_subarray(module_data,"LIST_TYPES",list_types)
+ for(l in list_types){
+ print " type record of " prefix_type(list_types[l],f) " " l >> file_name
+ }
+ delete list_types
+ get_subarray(module_data,"SET_TYPES",list_types)
+ for(l in list_types){
+ print " type set of " prefix_type(list_types[l],f) " " l >> file_name
+ }
+
+ print "" >> file_name
+ print "// Constants" >> file_name
+
+ delete const_data
+ get_subarray(module_data,"CONSTS",const_data)
+ delete const_lists
+ get_array_length(const_data,const_lists)
+
+ for(c in const_lists){
+ print " const " prefix_type(const_data[c SUBSEP "TYPE"],f) " " res_word(c) " := " const_data[c SUBSEP "VALUE"]>> file_name
+ }
+
+ print "" >> file_name
+ print "// Enumerations" >> file_name
+
+ delete enum_data
+ get_subarray(module_data,"ENUMS",enum_data)
+ delete enum_list
+ get_array_length(enum_data,enum_list)
+ for(e in enum_list){
+ print " type enumerated " res_word(e) " {" >> file_name
+
+ delete enum_val_list
+ get_subarray(enum_data,e SUBSEP "VALUES",enum_val_list)
+ ev_num=get_array_length(enum_val_list)
+ for ( i=1; i<=ev_num; i++){
+ if(i==ev_num){
+ comm = ""
+ } else {
+ comm =","
+ }
+ if (e SUBSEP "VALUES" SUBSEP i SUBSEP "VAL" in enum_data){
+ print " " res_word(enum_data[e SUBSEP "VALUES" SUBSEP i SUBSEP "NAME"]) " (" enum_data[e SUBSEP "VALUES" SUBSEP i SUBSEP "VAL"] ")" comm >> file_name
+ } else {
+ print " " res_word(enum_data[e SUBSEP "VALUES" SUBSEP i SUBSEP "NAME"]) comm >> file_name
+ }
+ }
+ print " }" >> file_name
+ print "" >> file_name
+
+ }
+
+ print "" >> file_name
+ print "// Structs" >> file_name
+
+ delete struct_data
+ get_subarray(module_data,"STRUCTS",struct_data)
+ delete struct_list
+ get_array_length(struct_data,struct_list)
+
+ for(s in struct_list){
+ print " type record " res_word(s) " {" >> file_name
+
+ delete struct_fields
+ get_subarray(struct_data,s SUBSEP "FIELDS",struct_fields)
+ f_num=get_array_length(struct_fields)
+ for ( i=1; i<=f_num; i++){
+ if(i==f_num){
+ comm = ""
+ } else {
+ comm =","
+ }
+ if( struct_fields[i SUBSEP "REQ"] == "optional"){
+ opt=" optional"
+ } else {
+ opt=""
+ }
+ print " " prefix_type(struct_fields[i SUBSEP "TYPE"],f) " " res_word(struct_fields[i SUBSEP "NAME"]) opt comm>> file_name
+ }
+ print " }" >> file_name
+ print "" >> file_name
+ }
+
+ print "" >> file_name
+ print "// Exception types" >> file_name
+
+ delete struct_data
+ get_subarray(module_data,"EXCEPTIONS",struct_data)
+ delete struct_list
+ get_array_length(struct_data,struct_list)
+
+ for(s in struct_list){
+ print " type record " res_word(s) " {" >> file_name
+
+ delete struct_fields
+ get_subarray(struct_data,s SUBSEP "FIELDS",struct_fields)
+ f_num=get_array_length(struct_fields)
+ for ( i=1; i<=f_num; i++){
+ if(i==f_num){
+ comm = ""
+ } else {
+ comm =","
+ }
+ if( struct_fields[i SUBSEP "REQ"] == "optional"){
+ opt=" optional"
+ } else {
+ opt=""
+ }
+ print " " prefix_type(struct_fields[i SUBSEP "TYPE"],f) " " res_word(struct_fields[i SUBSEP "NAME"]) opt comm>> file_name
+ }
+ print " }" >> file_name
+ print "" >> file_name
+ }
+
+
+ print "" >> file_name
+ print "// Services" >> file_name
+
+ delete services_data
+ delete services_list
+ get_subarray(module_data,"SERVICES",services_data)
+ get_array_length(services_data,services_list)
+ for(s in services_list){
+ delete serv_data
+ get_subarray(services_data,s,serv_data)
+ print "// Signatures for " s >> file_name
+ gen_service(serv_data,s,f)
+ }
+
+ print "" >> file_name
+ print "// Port definition for Services" >> file_name
+ print "" >> file_name
+
+ for(s in services_list){
+ delete serv_data
+ get_subarray(services_data,s,serv_data)
+ print " type port " s "_PT procedure {" >> file_name
+ print " out Thrift_control" >> file_name
+ gen_port_proc(serv_data,s,f)
+ print " } with { extension \"address\" }" >> file_name
+ print "" >> file_name
+ }
+
+ print "} with { encode \"XER\" }" >> file_name
+
+# generate converter functions
+ cc_file_name = f "_Converter.cc"
+ hh_file_name = f "_Converter.hh"
+
+ if("NAMESPACE" in module_data){
+ cc_namespace=dot_to_colon(module_data["NAMESPACE"] "::")
+ } else {
+ cc_namespace=""
+ }
+
+ print "#include \"" f "_TypesAndPorts.hh\"" > hh_file_name
+ print "#include \"" f "_types.h\"" > hh_file_name
+ print "#include \"Thrift_Common_Converter.hh\"" > hh_file_name
+ print "#include \"" f "_Converter.hh\"" > cc_file_name
+
+ for(i in include_data){
+ print "#include \"" i "_TypesAndPorts.hh\"" >> hh_file_name
+ print "#include \"" i "_Converter.hh\"" >> hh_file_name
+ }
+ print "" >> cc_file_name
+ print "" >> hh_file_name
+ print "// Enumerations" >> cc_file_name
+ print "// Enumerations" >> hh_file_name
+
+ for(e in enum_list){
+ print "void conv_ttcn_thrift(const " double_und(f) "__TypesAndPorts::" double_und(res_word(e))"& in," cc_namespace e "::type& out);" >> hh_file_name
+ print "void conv_thrift_ttcn(const " cc_namespace e "::type& in,"double_und(f) "__TypesAndPorts::" double_und(res_word(e))"& out);" >> hh_file_name
+
+ print "void conv_ttcn_thrift(const " double_und(f) "__TypesAndPorts::" double_und(res_word(e))"& in," cc_namespace e "::type& out){" >> cc_file_name
+ print " out=("cc_namespace e "::type)(int)in;" >> cc_file_name
+ print "}" >> cc_file_name
+ print "void conv_thrift_ttcn(const " cc_namespace e "::type& in,"double_und(f) "__TypesAndPorts::" double_und(res_word(e))"& out){" >> cc_file_name
+ print " out=(int)in;" >> cc_file_name
+ print "}" >> cc_file_name
+ }
+ delete list_types
+ get_subarray(module_data,"LIST_TYPES",list_types)
+ for(l in list_types){
+ if(is_basetype(list_types[l],f)!=0){
+ lt=get_basetype(list_types[l])
+ } else {
+ lt=cc_namespace list_types[l]
+ }
+ print "void conv_ttcn_thrift(const " double_und(f) "__TypesAndPorts::" double_und(res_word(l))"& in, std::vector<" lt ">& out);" >> hh_file_name
+ print "void conv_thrift_ttcn(const std::vector<" lt ">& in,"double_und(f) "__TypesAndPorts::" double_und(res_word(l))"& out);" >> hh_file_name
+ print "void conv_ttcn_thrift(const " double_und(f) "__TypesAndPorts::" double_und(res_word(l))"& in, std::vector<" lt ">& out){" >> cc_file_name
+ print " out.empty();" >> cc_file_name
+ print " size_t s=in.size_of();" >> cc_file_name
+ print " if(s>0){" >> cc_file_name
+ print " out.resize(s);" >> cc_file_name
+ print " for(size_t i=s;i>0; i--){" >> cc_file_name
+ print " conv_ttcn_thrift(in[i-1],out[i-1]);" >> cc_file_name
+ print " }" >> cc_file_name
+ print " }" >> cc_file_name
+
+ print "}" >> cc_file_name
+ print "void conv_thrift_ttcn(const std::vector<" lt ">& in,"double_und(f) "__TypesAndPorts::" double_und(res_word(l))"& out){" >> cc_file_name
+ print " out=NULL_VALUE;" >> cc_file_name
+ print " for(size_t i=in.size();i>0; i--){" >> cc_file_name
+ print " conv_thrift_ttcn(in[i-1],out[i-1]);" >> cc_file_name
+ print " }" >> cc_file_name
+ print "}" >> cc_file_name
+ }
+ delete list_types
+ get_subarray(module_data,"SET_TYPES",list_types)
+ for(l in list_types){
+ if(is_basetype(list_types[l],f)!=0){
+ lt=get_basetype(list_types[l])
+ } else {
+ lt=cc_namespace list_types[l]
+ }
+ print "void conv_ttcn_thrift(const " double_und(f) "__TypesAndPorts::" double_und(res_word(l))"& in, std::set<" lt ">& out);" >> hh_file_name
+ print "void conv_thrift_ttcn(const std::set<" lt ">& in,"double_und(f) "__TypesAndPorts::" double_und(res_word(l))"& out);" >> hh_file_name
+
+ print "void conv_ttcn_thrift(const " double_und(f) "__TypesAndPorts::" double_und(res_word(l))"& in, std::set<" lt ">& out){" >> cc_file_name
+ print "}" >> cc_file_name
+ print "void conv_thrift_ttcn(const std::set<" lt ">& in,"double_und(f) "__TypesAndPorts::" double_und(res_word(l))"& out){" >> cc_file_name
+ print " out=NULL_VALUE;" >> cc_file_name
+ print " std::set<" lt ">::iterator it=in.begin();" >> cc_file_name
+ print " for(size_t i=in.size();i>0; i--){" >> cc_file_name
+ print " conv_thrift_ttcn(*it,out[i-1]);" >> cc_file_name
+ print " it++;" >> cc_file_name
+ print " }" >> cc_file_name
+ print "}" >> cc_file_name
+
+ }
+
+ delete struct_data
+ get_subarray(module_data,"STRUCTS",struct_data)
+ delete struct_list
+ get_array_length(struct_data,struct_list)
+
+ for(s in struct_list){
+ print "void conv_ttcn_thrift(const " double_und(f) "__TypesAndPorts::" double_und(res_word(s))"& in, " cc_namespace s "& out);" >> hh_file_name
+ print "void conv_thrift_ttcn(const " cc_namespace s "& in,"double_und(f) "__TypesAndPorts::" double_und(res_word(s))"& out);" >> hh_file_name
+
+ print "void conv_ttcn_thrift(const " double_und(f) "__TypesAndPorts::" double_und(res_word(s))"& in, " cc_namespace s "& out){" >> cc_file_name
+
+ delete struct_fields
+ get_subarray(struct_data,s SUBSEP "FIELDS",struct_fields)
+ f_num=get_array_length(struct_fields)
+ for ( i=1; i<=f_num; i++){
+ if( struct_fields[i SUBSEP "REQ"] == "optional"){
+ print " if( in."double_und(res_word(struct_fields[i SUBSEP "NAME"]))"().ispresent()){" >> cc_file_name
+ print " conv_ttcn_thrift( in." double_und(res_word(struct_fields[i SUBSEP "NAME"])) "()(),out." struct_fields[i SUBSEP "NAME"] ");" >> cc_file_name
+ print " out.__isset." struct_fields[i SUBSEP "NAME"]"=true;" >> cc_file_name
+ print " } else {" >> cc_file_name
+ print " out.__isset." struct_fields[i SUBSEP "NAME"]"=false;" >> cc_file_name
+ print " }" >> cc_file_name
+ } else {
+ print " conv_ttcn_thrift( in." double_und(res_word(struct_fields[i SUBSEP "NAME"])) "(),out." struct_fields[i SUBSEP "NAME"] ");" >> cc_file_name
+ }
+ }
+ print "}" >> cc_file_name
+ print "void conv_thrift_ttcn(const " cc_namespace s "& in,"double_und(f) "__TypesAndPorts::" double_und(res_word(s))"& out){" >> cc_file_name
+ for ( i=1; i<=f_num; i++){
+ if( struct_fields[i SUBSEP "REQ"] == "optional"){
+ print " if( in.__isset."struct_fields[i SUBSEP "NAME"]"){" >> cc_file_name
+ print " conv_thrift_ttcn( in." struct_fields[i SUBSEP "NAME"] ",out." double_und(res_word(struct_fields[i SUBSEP "NAME"]))"()());" >> cc_file_name
+ print " } else {" >> cc_file_name
+ print " out." double_und(res_word(struct_fields[i SUBSEP "NAME"]))"()=OMIT_VALUE;" >> cc_file_name
+ print " }" >> cc_file_name
+ } else {
+ print " conv_thrift_ttcn( in." struct_fields[i SUBSEP "NAME"] ",out." double_und(res_word(struct_fields[i SUBSEP "NAME"]))"());" >> cc_file_name
+ }
+ }
+ print "}" >> cc_file_name
+
+ }
+ delete struct_data
+ get_subarray(module_data,"EXCEPTIONS",struct_data)
+ delete struct_list
+ get_array_length(struct_data,struct_list)
+
+ for(s in struct_list){
+ print "void conv_ttcn_thrift(const " double_und(f) "__TypesAndPorts::" double_und(res_word(s))"& in, " cc_namespace s "& out);" >> hh_file_name
+ print "void conv_thrift_ttcn(const " cc_namespace s "& in,"double_und(f) "__TypesAndPorts::" double_und(res_word(s))"& out);" >> hh_file_name
+
+ print "void conv_ttcn_thrift(const " double_und(f) "__TypesAndPorts::" double_und(res_word(s))"& in, " cc_namespace s "& out){" >> cc_file_name
+ delete struct_fields
+ get_subarray(struct_data,s SUBSEP "FIELDS",struct_fields)
+ f_num=get_array_length(struct_fields)
+ for ( i=1; i<=f_num; i++){
+ if( struct_fields[i SUBSEP "REQ"] == "optional"){
+ print " if( in."double_und(res_word(struct_fields[i SUBSEP "NAME"]))"().ispresent()){" >> cc_file_name
+ print " conv_ttcn_thrift( in." double_und(res_word(struct_fields[i SUBSEP "NAME"])) "()(),out." struct_fields[i SUBSEP "NAME"] ");" >> cc_file_name
+ print " out.__isset." struct_fields[i SUBSEP "NAME"]"=true;" >> cc_file_name
+ print " } else {" >> cc_file_name
+ print " out.__isset." struct_fields[i SUBSEP "NAME"]"=false;" >> cc_file_name
+ print " }" >> cc_file_name
+ } else {
+ print " conv_ttcn_thrift( in." double_und(res_word(struct_fields[i SUBSEP "NAME"])) "(),out." struct_fields[i SUBSEP "NAME"] ");" >> cc_file_name
+ }
+ }
+ print "}" >> cc_file_name
+ print "void conv_thrift_ttcn(const " cc_namespace s "& in,"double_und(f) "__TypesAndPorts::" double_und(res_word(s))"& out){" >> cc_file_name
+ for ( i=1; i<=f_num; i++){
+ if( struct_fields[i SUBSEP "REQ"] == "optional"){
+ print " if( in.__isset."struct_fields[i SUBSEP "NAME"]"){" >> cc_file_name
+ print " conv_thrift_ttcn( in." struct_fields[i SUBSEP "NAME"] ",out." double_und(res_word(struct_fields[i SUBSEP "NAME"]))"()());" >> cc_file_name
+ print " } else {" >> cc_file_name
+ print " out." double_und(res_word(struct_fields[i SUBSEP "NAME"]))"()=OMIT_VALUE;" >> cc_file_name
+ print " }" >> cc_file_name
+ } else {
+ print " conv_thrift_ttcn( in." struct_fields[i SUBSEP "NAME"] ",out." double_und(res_word(struct_fields[i SUBSEP "NAME"]))"());" >> cc_file_name
+ }
+ }
+ print "}" >> cc_file_name
+
+
+
+ }
+ ## test port files
+
+ for(s in services_list){
+ delete serv_data
+ get_subarray(services_data,s,serv_data)
+ cc_file_name=s"_PT.cc"
+ hh_file_name=s"_PT.hh"
+
+ ## _PT.hh
+
+ print "#ifndef "s"__PT_HH" > hh_file_name
+ print "#define "s"__PT_HH" >> hh_file_name
+
+ print "#include <arpa/inet.h>" >> hh_file_name
+ print "#include <pthread.h>" >> hh_file_name
+ print "#include \""f"_TypesAndPorts.hh\"" >> hh_file_name
+ print "#include \""f"_Converter.hh\"" >> hh_file_name
+ print "#include \""f"_types.h\"" >> hh_file_name
+ print "#include \""s".h\"" >> hh_file_name
+ print "" >> hh_file_name
+ print "#include <thrift/protocol/TBinaryProtocol.h>" >> hh_file_name
+ print "#include <thrift/transport/TServerSocket.h>" >> hh_file_name
+ print "#include <thrift/transport/TBufferTransports.h>" >> hh_file_name
+ print "#include <thrift/transport/TSocket.h>" >> hh_file_name
+ print "#include " myserver_include >> hh_file_name
+ print "" >> hh_file_name
+ print "namespace "double_und(f)"__TypesAndPorts {" >> hh_file_name
+ print "" >> hh_file_name
+ print "class "s"Handler : virtual public ::" cc_namespace s "If {" >> hh_file_name
+ print " public:" >> hh_file_name
+ print " "s"Handler(const char *);" >> hh_file_name
+ print " ~"s"Handler();" >> hh_file_name
+ print " const char *uds_name;" >> hh_file_name
+ print "" >> hh_file_name
+ print " int connect();" >> hh_file_name
+ print " void* get_data();" >> hh_file_name
+
+ gen_service_hh(serv_data,s,f)
+
+ print "};" >> hh_file_name
+
+ print "" >> hh_file_name
+ print "class "double_und(s)"__PT : public "double_und(s)"__PT_BASE {" >> hh_file_name
+ print "public:" >> hh_file_name
+ print " "double_und(s)"__PT(const char *par_port_name = NULL);" >> hh_file_name
+ print " ~"double_und(s)"__PT();" >> hh_file_name
+ print "" >> hh_file_name
+ print " void set_parameter(const char *parameter_name," >> hh_file_name
+ print " const char *parameter_value);" >> hh_file_name
+ print "" >> hh_file_name
+ print " void Handle_Fd_Event_Error(int fd);" >> hh_file_name
+ print " void Handle_Fd_Event_Writable(int fd);" >> hh_file_name
+ print " void Handle_Fd_Event_Readable(int fd);" >> hh_file_name
+ print "" >> hh_file_name
+ print " char *uds_name;" >> hh_file_name
+ print " int server_socket;" >> hh_file_name
+ print " " >> hh_file_name
+ print " ::std::set<int> clients;" >> hh_file_name
+ print " ::std::map<int,void*> client_data;" >> hh_file_name
+ print " " >> hh_file_name
+ print " int port_mode; // 0-not set, 1-client, 2-server" >> hh_file_name
+ print "" >> hh_file_name
+ print " boost::shared_ptr<"s"Handler> service_handler;" >> hh_file_name
+ print " boost::shared_ptr< ::apache::thrift::TProcessor> server_processor;" >> hh_file_name
+ print " boost::shared_ptr< ::apache::thrift::transport::TServerTransport> server_Transport;" >> hh_file_name
+ print " boost::shared_ptr< ::apache::thrift::transport::TTransportFactory> server_transportFactory;" >> hh_file_name
+ print " boost::shared_ptr< ::apache::thrift::protocol::TProtocolFactory> server_protocolFactory;" >> hh_file_name
+ print " boost::shared_ptr< ::apache::thrift::transport::TSocket> client_socket;" >> hh_file_name
+ print " boost::shared_ptr< ::apache::thrift::transport::TTransport> client_transport;" >> hh_file_name
+ print " boost::shared_ptr< ::apache::thrift::protocol::TProtocol> client_protocol;" >> hh_file_name
+ print "" >> hh_file_name
+ print " ::apache::thrift::server::" myserver_name " *server_handler;" >> hh_file_name
+ print " "cc_namespace s"Client *client_handler;" >> hh_file_name
+ print "" >> hh_file_name
+ print " void clean_up();" >> hh_file_name
+ print " pthread_t server_thread;" >> hh_file_name
+ print "protected:" >> hh_file_name
+ print " void user_map(const char *system_port);" >> hh_file_name
+ print " void user_unmap(const char *system_port);" >> hh_file_name
+ print "" >> hh_file_name
+ print " void user_start();" >> hh_file_name
+ print " void user_stop();" >> hh_file_name
+ print "" >> hh_file_name
+ print " void outgoing_call(const Thrift__Common::Thrift__control_call& call_par," >> hh_file_name
+ print " const INTEGER *destination_address);" >> hh_file_name
+ print "" >> hh_file_name
+ gen_outgoing_hh(serv_data,s,f)
+ print "};" >> hh_file_name
+ print "" >> hh_file_name
+ print "}" >> hh_file_name
+ print "#endif" >> hh_file_name
+
+ ## _PT.cc
+ print "#include <stdio.h>" > cc_file_name
+ print "#include <sys/socket.h>" >> cc_file_name
+ print "#include <sys/un.h>" >> cc_file_name
+ print "#include <unistd.h>" >> cc_file_name
+ print "#include <string.h>" >> cc_file_name
+ print "#include <errno.h>" >> cc_file_name
+ print "" >> cc_file_name
+ print "#include \"" s "_PT.hh\"" >> cc_file_name
+ print "" >> cc_file_name
+ print "using namespace ::apache::thrift;" >> cc_file_name
+ print "using namespace ::apache::thrift::protocol;" >> cc_file_name
+ print "using namespace ::apache::thrift::transport;" >> cc_file_name
+ print "using namespace ::apache::thrift::server;" >> cc_file_name
+ print "using boost::shared_ptr;" >> cc_file_name
+ print "using namespace Thrift__Common;" >> cc_file_name
+ print "namespace "double_und(f)"__TypesAndPorts {" >> cc_file_name
+ print s "Handler::"s"Handler(const char *uds){" >> cc_file_name
+ print " uds_name=uds;" >> cc_file_name
+ print "}" >> cc_file_name
+ print s "Handler::~"s"Handler(){}" >> cc_file_name
+ print "" >> cc_file_name
+ print "int "s"Handler::connect(){" >> cc_file_name
+ print " struct sockaddr_un serv_addr;" >> cc_file_name
+ print "" >> cc_file_name
+ print " memset(&serv_addr, 0, sizeof(struct sockaddr_un));" >> cc_file_name
+ print " serv_addr.sun_family = AF_UNIX;" >> cc_file_name
+ print " strcpy(serv_addr.sun_path, uds_name);" >> cc_file_name
+ print " int len=strlen(serv_addr.sun_path) + sizeof(serv_addr.sun_family);" >> cc_file_name
+ print "#ifdef LINUX" >> cc_file_name
+ print " serv_addr.sun_path[0]='\\0';" >> cc_file_name
+ print "#endif" >> cc_file_name
+ print " int client_socket = socket(PF_UNIX, SOCK_STREAM, 0);" >> cc_file_name
+ print " ::connect(client_socket,(const sockaddr*)&serv_addr,len);" >> cc_file_name
+ print " " >> cc_file_name
+ print " return client_socket; " >> cc_file_name
+ print "}" >> cc_file_name
+ gen_service_cc(serv_data,s,f,0)
+
+ print "" >> cc_file_name
+
+ print "void "s"__PT::clean_up(){" >> cc_file_name
+ print " if(port_mode==1){" >> cc_file_name
+ print " client_transport->close();" >> cc_file_name
+ print " delete client_handler;" >> cc_file_name
+ print " client_protocol.reset();" >> cc_file_name
+ print " client_transport.reset();" >> cc_file_name
+ print " client_socket.reset();" >> cc_file_name
+ print " port_mode=0;" >> cc_file_name
+ print " } else if(port_mode ==2) {" >> cc_file_name
+ print " server_handler->stop();" >> cc_file_name
+ print " void *a;" >> cc_file_name
+ print " pthread_join(server_thread,&a);" >> cc_file_name
+ print " delete server_handler;" >> cc_file_name
+ print " server_protocolFactory.reset();" >> cc_file_name
+ print " server_transportFactory.reset();" >> cc_file_name
+ print " server_Transport.reset();" >> cc_file_name
+ print " server_processor.reset();" >> cc_file_name
+ print " service_handler.reset();" >> cc_file_name
+ print " Handler_Remove_Fd_Read(server_socket);" >> cc_file_name
+ print " close(server_socket);" >> cc_file_name
+ print " server_socket=-1;" >> cc_file_name
+ print " }" >> cc_file_name
+ print " if(uds_name){" >> cc_file_name
+ print "#ifndef LINUX" >> cc_file_name
+ print " unlink(uds_name);" >> cc_file_name
+ print "#endif" >> cc_file_name
+ print " Free(uds_name);" >> cc_file_name
+ print " uds_name=NULL;" >> cc_file_name
+ print " }" >> cc_file_name
+ print " port_mode=0;" >> cc_file_name
+ print "}" >> cc_file_name
+ print "" >> cc_file_name
+ print ""double_und(s)"__PT::"double_und(s)"__PT(const char *par_port_name)" >> cc_file_name
+ print " : "double_und(s)"__PT_BASE(par_port_name)" >> cc_file_name
+ print "{" >> cc_file_name
+ print " server_socket=-1;" >> cc_file_name
+ print " port_mode=0;" >> cc_file_name
+ print " client_handler=NULL;" >> cc_file_name
+ print " uds_name=NULL;" >> cc_file_name
+ print "}" >> cc_file_name
+ print "" >> cc_file_name
+ print ""double_und(s)"__PT::~"double_und(s)"__PT()" >> cc_file_name
+ print "{" >> cc_file_name
+ print " clean_up(); " >> cc_file_name
+ print "}" >> cc_file_name
+ print "" >> cc_file_name
+ print "void "double_und(s)"__PT::set_parameter(const char * /*parameter_name*/," >> cc_file_name
+ print " const char * /*parameter_value*/)" >> cc_file_name
+ print "{" >> cc_file_name
+ print "" >> cc_file_name
+ print "}" >> cc_file_name
+
+ print "" >> cc_file_name
+ print "void "double_und(s)"__PT::Handle_Fd_Event_Error(int /*fd*/)" >> cc_file_name
+ print "{" >> cc_file_name
+ print "" >> cc_file_name
+ print "}" >> cc_file_name
+ print "" >> cc_file_name
+ print "void "double_und(s)"__PT::Handle_Fd_Event_Writable(int /*fd*/)" >> cc_file_name
+ print "{" >> cc_file_name
+
+ print "}" >> cc_file_name
+ print "" >> cc_file_name
+ print "void "double_und(s)"__PT::Handle_Fd_Event_Readable(int fd)" >> cc_file_name
+ print "{" >> cc_file_name
+ print "" >> cc_file_name
+ print " if(fd==server_socket){" >> cc_file_name
+ print " struct sockaddr_un client_addr;" >> cc_file_name
+ print " memset(&client_addr, 0, sizeof(struct sockaddr_un));" >> cc_file_name
+ print " socklen_t client_addr_len;" >> cc_file_name
+ print " int new_socket=accept(fd,(struct sockaddr *) &client_addr,&client_addr_len);" >> cc_file_name
+ print " Handler_Add_Fd_Read(new_socket);" >> cc_file_name
+ print " clients.insert(new_socket);" >> cc_file_name
+ print " " >> cc_file_name
+ print " } else {" >> cc_file_name
+ print " void *read_data;" >> cc_file_name
+ print " int read_len=read(fd,&read_data,sizeof(read_data));" >> cc_file_name
+ print "" >> cc_file_name
+ print " if(read_len>0){" >> cc_file_name
+ print " int func_num=((struct internal_comm_struct*)read_data)->code;" >> cc_file_name
+ print " client_data.insert(std::pair<int,void*>(fd,read_data));" >> cc_file_name
+ print " INTEGER addr=fd;" >> cc_file_name
+ print " void **_push_data=((struct internal_comm_struct*)read_data)->data;" >> cc_file_name
+ print " switch(func_num){" >> cc_file_name
+
+ gen_service_event_call_cc(serv_data,s,f,0)
+
+ print " default:" >> cc_file_name
+ print " break;" >> cc_file_name
+ print " }" >> cc_file_name
+ print " return;" >> cc_file_name
+ print " } else {" >> cc_file_name
+ print " Handler_Remove_Fd_Read(fd);" >> cc_file_name
+ print " clients.erase(fd);" >> cc_file_name
+ print " close(fd);" >> cc_file_name
+ print " }" >> cc_file_name
+ print " }" >> cc_file_name
+
+
+ print "}" >> cc_file_name
+ print "" >> cc_file_name
+
+ print "void "double_und(s)"__PT::user_map(const char * /*system_port*/)" >> cc_file_name
+ print "{" >> cc_file_name
+ print "" >> cc_file_name
+ print "}" >> cc_file_name
+
+ print "void "double_und(s)"__PT::user_unmap(const char * /*system_port*/)" >> cc_file_name
+ print "{" >> cc_file_name
+ print " clean_up(); " >> cc_file_name
+
+ print "}" >> cc_file_name
+
+ print "void "double_und(s)"__PT::user_start()" >> cc_file_name
+ print "{" >> cc_file_name
+
+ print "}" >> cc_file_name
+
+ print "void "double_und(s)"__PT::user_stop()" >> cc_file_name
+ print "{" >> cc_file_name
+
+ print "}" >> cc_file_name
+
+ print "static void *server_runner_main( void * ptr){" >> cc_file_name
+ print " (("double_und(s)"__PT*)ptr)->server_handler->serve();" >> cc_file_name
+ print " return NULL;" >> cc_file_name
+ print "}" >> cc_file_name
+ print "" >> cc_file_name
+
+
+ print "void "double_und(s)"__PT::outgoing_call(const Thrift__Common::Thrift__control_call& call_par," >> cc_file_name
+ print " const INTEGER * /*destination_address*/)" >> cc_file_name
+ print "{" >> cc_file_name
+ print " Thrift__Common::Thrift__control_reply reply;" >> cc_file_name
+ print " if(port_mode && call_par.operation()!=Thrift__Common::Thrift__port__operation::OP__CLOSE){" >> cc_file_name
+ print " reply.return_value().result__code()=Thrift__Common::Thrift__control__code::CTRL__RES__ERR;" >> cc_file_name
+ print " reply.return_value().result__desc()().error__code()=1;" >> cc_file_name
+ print " reply.return_value().result__desc()().error__text()=\"The port is aleady connected\";" >> cc_file_name
+ print " incoming_reply(reply,NULL);" >> cc_file_name
+ print " return;" >> cc_file_name
+ print " }" >> cc_file_name
+
+ print " switch(call_par.operation()){" >> cc_file_name
+ print " case Thrift__Common::Thrift__port__operation::OP__CLOSE:" >> cc_file_name
+ print " clean_up(); " >> cc_file_name
+ print " reply.return_value().result__code()=Thrift__Common::Thrift__control__code::CRTL__RES__OK;" >> cc_file_name
+ print " reply.return_value().result__desc()=OMIT_VALUE;" >> cc_file_name
+ print " break;" >> cc_file_name
+ print " case Thrift__Common::Thrift__port__operation::OP__OPEN:" >> cc_file_name
+ print " if(call_par.port__mode() == Thrift__Common::Thrift__port__mode::MODE__CLIENT){" >> cc_file_name
+ print " if(call_par.conn__data().transport()().get_selection()==Thrift__Common::Thrift__transport__data::ALT_socket){" >> cc_file_name
+ print " client_socket.reset(new ::apache::thrift::transport::TSocket(" >> cc_file_name
+ print " call_par.conn__data().transport()().socket().host__name().ispresent()?(const char*)call_par.conn__data().transport()().socket().host__name()():\"localhost\"," >> cc_file_name
+ print " (int)call_par.conn__data().transport()().socket().port__num()" >> cc_file_name
+ print " ));" >> cc_file_name
+ print " client_transport.reset(new ::apache::thrift::transport::TBufferedTransport(client_socket)) ;" >> cc_file_name
+ print " } else if(call_par.conn__data().transport()().get_selection()==Thrift__Common::Thrift__transport__data::ALT_framed){" >> cc_file_name
+ print " client_socket.reset(new ::apache::thrift::transport::TSocket(" >> cc_file_name
+ print " call_par.conn__data().transport()().framed().host__name().ispresent()?(const char*)call_par.conn__data().transport()().framed().host__name()():\"localhost\"," >> cc_file_name
+ print " (int)call_par.conn__data().transport()().framed().port__num()" >> cc_file_name
+ print " ));" >> cc_file_name
+ print " client_transport.reset(new ::apache::thrift::transport::TFramedTransport(client_socket)) ;" >> cc_file_name
+ print " }" >> cc_file_name
+ print " if(call_par.conn__data().protocol()().get_selection()==Thrift__Common::Thrift__protocol__data::ALT_binary){" >> cc_file_name
+ print " client_protocol.reset(new ::apache::thrift::protocol::TBinaryProtocol(client_transport));" >> cc_file_name
+ print " }" >> cc_file_name
+ print " client_handler=new "cc_namespace s"Client(client_protocol);" >> cc_file_name
+ print " " >> cc_file_name
+ print " try{" >> cc_file_name
+ print " client_transport->open();" >> cc_file_name
+ print " } catch (...) {" >> cc_file_name
+ print " delete client_handler;" >> cc_file_name
+ print " client_protocol.reset();" >> cc_file_name
+ print " client_transport.reset();" >> cc_file_name
+ print " client_socket.reset();" >> cc_file_name
+ print " reply.return_value().result__code()=Thrift__Common::Thrift__control__code::CTRL__RES__ERR;" >> cc_file_name
+ print " reply.return_value().result__desc()().error__code()=1;" >> cc_file_name
+ print " reply.return_value().result__desc()().error__text()=\"There is an error reported by the Thrift\";" >> cc_file_name
+ print " incoming_reply(reply,NULL);" >> cc_file_name
+ print " return;" >> cc_file_name
+ print " }" >> cc_file_name
+ print " " >> cc_file_name
+ print " reply.return_value().result__code()=Thrift__Common::Thrift__control__code::CRTL__RES__OK;" >> cc_file_name
+ print " reply.return_value().result__desc()=OMIT_VALUE;" >> cc_file_name
+ print " port_mode=1;" >> cc_file_name
+ print " } else {" >> cc_file_name
+ print " if(!uds_name){" >> cc_file_name
+ print "#ifdef LINUX" >> cc_file_name
+ print " uds_name=mprintf(\"#thriftPTXXXXXX\");" >> cc_file_name
+ print "#else" >> cc_file_name
+ print " uds_name=mprintf(\"/tmp/thriftPTXXXXXX\");" >> cc_file_name
+ print "#endif" >> cc_file_name
+ print " mktemp(uds_name);" >> cc_file_name
+ print " }" >> cc_file_name
+ print " struct sockaddr_un serv_addr;" >> cc_file_name
+ print "" >> cc_file_name
+ print " memset(&serv_addr, 0, sizeof(struct sockaddr_un));" >> cc_file_name
+ print " serv_addr.sun_family = AF_UNIX;" >> cc_file_name
+ print " strcpy(serv_addr.sun_path, uds_name);" >> cc_file_name
+ print " int len=strlen(serv_addr.sun_path) + sizeof(serv_addr.sun_family);" >> cc_file_name
+ print "#ifdef LINUX" >> cc_file_name
+ print " serv_addr.sun_path[0]='\\0';" >> cc_file_name
+ print "#else" >> cc_file_name
+ print " unlink(uds_name);" >> cc_file_name
+ print "#endif" >> cc_file_name
+ print " server_socket = socket(PF_UNIX, SOCK_STREAM, 0);" >> cc_file_name
+ print " if(bind(server_socket, (struct sockaddr *)&serv_addr, len) == -1){" >> cc_file_name
+ print " reply.return_value().result__code()=Thrift__Common::Thrift__control__code::CTRL__RES__ERR;" >> cc_file_name
+ print " reply.return_value().result__desc()().error__code()=errno;" >> cc_file_name
+ print " reply.return_value().result__desc()().error__text()=strerror(errno);" >> cc_file_name
+ print " incoming_reply(reply,NULL);" >> cc_file_name
+ print " close(server_socket);" >> cc_file_name
+ print " server_socket=-1;" >> cc_file_name
+ print " Free(uds_name);" >> cc_file_name
+ print " uds_name=NULL;" >> cc_file_name
+ print " return;" >> cc_file_name
+ print " }" >> cc_file_name
+ print " if(listen(server_socket, 10) == -1){" >> cc_file_name
+ print " reply.return_value().result__code()=Thrift__Common::Thrift__control__code::CTRL__RES__ERR;" >> cc_file_name
+ print " reply.return_value().result__desc()().error__code()=errno;" >> cc_file_name
+ print " reply.return_value().result__desc()().error__text()=strerror(errno);" >> cc_file_name
+ print " incoming_reply(reply,NULL);" >> cc_file_name
+ print " close(server_socket);" >> cc_file_name
+ print " server_socket=-1;" >> cc_file_name
+ print " Free(uds_name);" >> cc_file_name
+ print " uds_name=NULL;" >> cc_file_name
+ print " return;" >> cc_file_name
+ print " }" >> cc_file_name
+ print " Handler_Add_Fd_Read(server_socket);" >> cc_file_name
+ print "" >> cc_file_name
+ print " if(call_par.conn__data().transport()().get_selection()==Thrift__Common::Thrift__transport__data::ALT_socket){" >> cc_file_name
+ print " server_Transport.reset(new TServerSocket((int)call_par.conn__data().transport()().socket().port__num()));" >> cc_file_name
+ print " server_transportFactory.reset(new TBufferedTransportFactory());" >> cc_file_name
+ print " } else if(call_par.conn__data().transport()().get_selection()==Thrift__Common::Thrift__transport__data::ALT_framed){" >> cc_file_name
+ print " server_Transport.reset(new TServerSocket((int)call_par.conn__data().transport()().framed().port__num()));" >> cc_file_name
+ print " server_transportFactory.reset(new TFramedTransportFactory());" >> cc_file_name
+ print " }" >> cc_file_name
+ print " if(call_par.conn__data().protocol()().get_selection()==Thrift__Common::Thrift__protocol__data::ALT_binary){" >> cc_file_name
+ print " server_protocolFactory.reset(new TBinaryProtocolFactory());" >> cc_file_name
+ print " }" >> cc_file_name
+ print "" >> cc_file_name
+ print " service_handler.reset(new "s"Handler(uds_name));" >> cc_file_name
+ print " server_processor.reset(new " cc_namespace s"Processor(service_handler));" >> cc_file_name
+ print " " >> cc_file_name
+ print " reply.return_value().result__code()=Thrift__Common::Thrift__control__code::CRTL__RES__OK;" >> cc_file_name
+ print " reply.return_value().result__desc()=OMIT_VALUE;" >> cc_file_name
+ print " server_handler=new "myserver_name"(server_processor,server_Transport,server_transportFactory,server_protocolFactory);" >> cc_file_name
+ print "" >> cc_file_name
+ print " port_mode=2;" >> cc_file_name
+ print " pthread_create(&server_thread,NULL,server_runner_main,this);" >> cc_file_name
+ print " }" >> cc_file_name
+ print "" >> cc_file_name
+ print " break;" >> cc_file_name
+ print " default:" >> cc_file_name
+ print " break;" >> cc_file_name
+ print " }" >> cc_file_name
+ print " incoming_reply(reply,NULL);" >> cc_file_name
+ print "" >> cc_file_name
+ print "}" >> cc_file_name
+ print "" >> cc_file_name
+
+ gen_service_outgoing_cc(serv_data,s,f,0)
+
+ print "} // namespace" >> cc_file_name
+ }
+
+ } ## for(f in files)
+
+
+}
diff --git a/src/Thrift_Common.ttcn b/src/Thrift_Common.ttcn
new file mode 100644
index 0000000..04eef1b
--- /dev/null
+++ b/src/Thrift_Common.ttcn
@@ -0,0 +1,59 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2018 Ericsson Telecom AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v2.0
+// which accompanies this distribution, and is available at
+// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+///////////////////////////////////////////////////////////////////////////////
+
+module Thrift_Common{
+
+ type boolean bool
+ type integer byte
+ type integer i16
+ type integer i32
+ type integer i64
+ type charstring string
+ type octetstring binary
+
+ type enumerated Thrift_port_operation { OP_OPEN(0),OP_CLOSE(1) }
+ type enumerated Thrift_port_mode { MODE_CLIENT(0),MODE_SERVER(1) }
+ type record Thrift_conn_data {
+ Thrift_transport_data transport optional,
+ Thrift_protocol_data protocol optional
+ }
+
+ type union Thrift_transport_data{
+ Thrift_socket_transport socket,
+ Thrift_socket_transport framed
+ }
+
+ type union Thrift_protocol_data{
+ Thrift_binary_protocol binary
+ }
+
+ type record Thrift_socket_transport {
+ charstring host_name optional,
+ integer port_num
+ }
+
+ type record Thrift_binary_protocol {
+ }
+
+ type enumerated Thrift_control_code{ CRTL_RES_OK(0), CTRL_RES_FAIL(1), CTRL_RES_ERR(2)}
+ type record Thrift_control_result {
+ Thrift_control_code result_code,
+ Thrift_port_error result_desc optional
+ }
+
+ signature Thrift_control(in Thrift_port_operation operation,
+ in Thrift_port_mode port_mode,
+ in Thrift_conn_data conn_data) return Thrift_control_result
+
+
+ type record Thrift_port_error{
+ integer error_code,
+ charstring error_text
+ }
+
+}
diff --git a/src/Thrift_Common_Converter.cc b/src/Thrift_Common_Converter.cc
new file mode 100644
index 0000000..6ea5855
--- /dev/null
+++ b/src/Thrift_Common_Converter.cc
@@ -0,0 +1,59 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2018 Ericsson Telecom AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v2.0
+// which accompanies this distribution, and is available at
+// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+//////////////////////////////////////////////////////////////////////////////
+
+
+#include "Thrift_Common.hh"
+#include "Thrift_Common_Converter.hh"
+
+void conv_ttcn_thrift(const Thrift__Common::bool_& in,bool& out){
+ out=in;
+}
+void conv_ttcn_thrift(const Thrift__Common::byte& in,int8_t& out){
+ out=(int)in;
+}
+void conv_ttcn_thrift(const Thrift__Common::i16& in,int16_t& out){
+ out=(int)in;
+}
+void conv_ttcn_thrift(const Thrift__Common::i32& in,int32_t& out){
+ out=(int)in;
+}
+void conv_ttcn_thrift(const Thrift__Common::i64& in,int64_t& out){
+ out=in.get_long_long_val();
+}
+void conv_ttcn_thrift(const Thrift__Common::string& in,std::string& out){
+ out=std::string((const char*)in,in.lengthof());
+}
+void conv_ttcn_thrift(const Thrift__Common::binary& in,std::string& out){
+ out=std::string((const char*)(const unsigned char*)in,in.lengthof());
+}
+
+void conv_thrift_ttcn(const bool& in,Thrift__Common::bool_& out){
+ out=in;
+}
+
+void conv_thrift_ttcn(const int8_t& in,Thrift__Common::byte& out){
+ out=in;
+}
+
+void conv_thrift_ttcn(const int16_t& in,Thrift__Common::i16& out){
+ out=in;
+}
+
+void conv_thrift_ttcn(const int32_t& in,Thrift__Common::i32& out){
+ out=in;
+}
+
+void conv_thrift_ttcn(const int64_t& in,Thrift__Common::i64& out){
+ out.set_long_long_val(in);
+}
+void conv_thrift_ttcn(const std::string& in,Thrift__Common::string& out){
+ out=Thrift__Common::string(in.size(),in.data());
+}
+void conv_thrift_ttcn(const std::string& in,Thrift__Common::binary& out){
+ out=Thrift__Common::binary(in.size(),(const unsigned char*)in.data());
+}
diff --git a/src/Thrift_Common_Converter.hh b/src/Thrift_Common_Converter.hh
new file mode 100644
index 0000000..f9dab8e
--- /dev/null
+++ b/src/Thrift_Common_Converter.hh
@@ -0,0 +1,38 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2000-2018 Ericsson Telecom AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v2.0
+// which accompanies this distribution, and is available at
+// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
+//////////////////////////////////////////////////////////////////////////////
+
+
+#ifndef Thrift_Common_Converter_H
+#define Thrift_Common_Converter_H
+
+#include <thrift/Thrift.h>
+#include "Thrift_Common.hh"
+
+
+struct internal_comm_struct{
+ int code;
+ void** data;
+};
+
+
+void conv_ttcn_thrift(const Thrift__Common::bool_& in,bool& out);
+void conv_ttcn_thrift(const Thrift__Common::byte& in,int8_t& out);
+void conv_ttcn_thrift(const Thrift__Common::i16& in,int16_t& out);
+void conv_ttcn_thrift(const Thrift__Common::i32& in,int32_t& out);
+void conv_ttcn_thrift(const Thrift__Common::i64& in,int64_t& out);
+void conv_ttcn_thrift(const Thrift__Common::string& in,std::string& out);
+void conv_ttcn_thrift(const Thrift__Common::binary& in,std::string& out);
+void conv_thrift_ttcn(const bool& in,Thrift__Common::bool_& out);
+void conv_thrift_ttcn(const int8_t& in,Thrift__Common::byte& out);
+void conv_thrift_ttcn(const int16_t& in,Thrift__Common::i16& out);
+void conv_thrift_ttcn(const int32_t& in,Thrift__Common::i32& out);
+void conv_thrift_ttcn(const int64_t& in,Thrift__Common::i64& out);
+void conv_thrift_ttcn(const std::string& in,Thrift__Common::string& out);
+void conv_thrift_ttcn(const std::string& in,Thrift__Common::binary& out);
+
+#endif
diff --git a/test/sapc.thrift b/test/sapc.thrift
new file mode 100644
index 0000000..9f6bde4
--- /dev/null
+++ b/test/sapc.thrift
@@ -0,0 +1,409 @@
+#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Data Structures
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+typedef i32 ScfId
+typedef i32 TenantId
+typedef i32 ServChainId
+typedef i32 PortId
+typedef i32 NexthopId
+typedef i32 Priority
+typedef i32 SubFilterId
+typedef i32 ApplFilterId
+typedef i16 SubProfileId
+typedef i16 ApplProfileId
+typedef i16 VlanId
+
+typedef byte IpProtocol
+
+typedef string TenantName
+
+typedef i64 MacAddress
+
+enum Afi {
+ AFI_IPV4,
+ AFI_IPV6,
+}
+
+struct IpAddress {
+ 1: required Afi afi,
+ 2: optional i32 ipv4Address,
+ 3: optional binary ipv6Address,
+}
+
+struct IpSubnet {
+ 1: required Afi afi,
+ 2: optional i32 ipv4Prefix,
+ 3: optional binary ipv6Prefix,
+ 4: required byte prefixLength,
+}
+
+enum DpnState {
+ DPN_STATE_UNKNOWN = 0,
+ DPN_STATE_UNCONFIGURED = 1,
+ DPN_STATE_PRECONFIGURED = 2,
+ DPN_STATE_CONNECTED = 3,
+ DPN_STATE_READY = 4,
+ DPN_STATE_DISCONNECTED = 5,
+}
+
+enum PortState {
+ PORT_STATE_UNKNOWN = 0,
+ PORT_STATE_UNCONFIGURED = 1,
+ PORT_STATE_PRECONFIGURED = 2,
+ PORT_STATE_UP = 3,
+ PORT_STATE_DOWN = 4,
+ PORT_STATE_SHUT = 5,
+}
+
+enum LogicalPortUse {
+ PORT_USE_UNKNOWN = 0,
+ PORT_USE_FREE = 1,
+ PORT_USE_SEIZED = 2,
+ PORT_USE_BUSY = 3,
+}
+
+struct LogicalPortInfo {
+ 1: required LogicalPortUse portUse,
+ 2: optional VlanId vlanId,
+ 3: optional string displayName,
+}
+
+struct PortInfo {
+ 1: optional i64 dpId,
+ 2: required string portName,
+ 3: required PortState portState,
+ 4: optional i32 portNo,
+ 5: optional list<LogicalPortInfo> logicalPorts,
+}
+
+struct DpnInfo {
+ 1: required i64 dpId,
+ 2: optional string dpnName,
+ 3: optional list<PortInfo> ports,
+ 4: required DpnState dpnState,
+}
+
+struct DomainInfo {
+ 1: optional string domainName,
+ 2: required list<DpnInfo> dpns,
+}
+
+
+struct TenantInfo {
+ 1: required TenantName tenantName,
+ 2: optional IpAddress tenantIpAddress,
+ 3: optional i16 tcpPortNo,
+ 4: optional i16 cookie,
+}
+
+enum SubEventType {
+ CREATE = 0,
+ UPDATE = 1,
+ DELETE = 2,
+}
+
+enum SubObjectType {
+ DPN = 0,
+ PORT = 1,
+}
+
+struct SubItem {
+ 1: required SubEventType subEventType,
+ 2: required SubObjectType subObjectType,
+}
+
+struct LogicalPort {
+ 1: required i64 dpId,
+ 2: required string portName,
+ 3: optional VlanId vlanId,
+ 4: optional string displayName,
+}
+
+struct ServiceChain {
+ 1: optional string displayName,
+}
+
+
+enum Direction {
+ UP = 1,
+ DOWN = 2,
+
+}
+
+
+struct SubFilterInfo {
+ 1: optional string displayName,
+ 2: optional IpSubnet srcIpPrefix,
+ 3: optional Priority priority,
+ 4: optional SubProfileId subProfileId,
+}
+
+struct ApplFilterInfo {
+ 1: optional string displayName
+ 2: optional IpSubnet dstIpPrefix,
+ 3: optional IpProtocol ipProtocol,
+ 4: optional i32 destPortNo,
+ 5: optional Priority priority,
+ 6: optional ApplProfileId applProfileId,
+}
+
+
+typedef list<NexthopId> NextHops
+
+struct IndirectNexthop {
+ 1: optional string displayName,
+ 2: optional NextHops nextHops,
+}
+
+struct DirectNexthop {
+ 1: optional string displayName,
+ 2: optional PortId egressPort,
+ 3: optional IpAddress ipAddress,
+ 4: optional MacAddress macAddress,
+}
+
+enum Result{
+ UNSUCCESSFUL = 0,
+ SUCCESSFUL = 1,
+}
+
+struct ScfResult {
+ 1: required Result result,
+ 2: optional TenantId tenantId, /* Response to register_tenant() */
+ 3: optional i16 genId, /* Response to register_tenant(), create_scf_instance(), seize_logical_port(), add_logical_port, create_service_chain(), start_recovery(), recovery_completed() */
+ 4: optional i32 revisionId, /* Response to register_tenant(), create_scf_instance(), seize_logical_port(), add_logical_port, create_service_chain(), start_recovery(), recovery_completed() */
+ 5: optional PortInfo portInfo, /* Response to seize_port(), get_port() */
+ 6: optional DpnInfo dpnInfo, /* Response to get_dpn() */
+}
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Service Definition
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+service TenantService {
+
+ # Tenant handling
+
+ ScfResult register_tenant (1: TenantInfo tenantInfo),
+
+ ScfResult deregister_tenant (1: TenantId tenantId),
+
+ ScfResult start_recovery (1: TenantInfo tenantInfo),
+
+ ScfResult recovery_completed (1: TenantInfo tenantInfo),
+
+ ScfResult subscribe_nw_events (1: TenantId tenantId,
+ 2: SubItem subItem),
+
+ ScfResult unsubscribe_nw_events (1: TenantId tenantId,
+ 2: SubItem subItem),
+
+ # Logical Port handling
+
+ ScfResult seize_logical_port (1: TenantId tenantId,
+ 2: PortId portId,
+ 3: LogicalPort logicalPort),
+
+ ScfResult update_logical_port (1: TenantId tenantId,
+ 2: PortId portId,
+ 3: LogicalPort logicalPort),
+
+ ScfResult release_logical_port (1: TenantId tenantId,
+ 2: PortId portId),
+}
+
+
+service NetworkInfoService {
+
+ # Domain information retrieval
+
+ DomainInfo get_domain (),
+
+ ScfResult get_dpn (1: i64 dpId),
+
+ ScfResult get_port (1: i64 dpId,
+ 2: string portName),
+
+}
+
+
+service ServiceChainProvisioning {
+
+ #SCF Instance handling
+
+ ScfResult create_scf_instance (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: string displayName),
+
+ ScfResult delete_scf_instance (1: TenantId tenantId,
+ 2: ScfId scfId),
+
+ ScfResult add_logical_port (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: PortId portId,
+ 4: Direction direction)
+
+ ScfResult remove_logical_port (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: PortId portId)
+
+
+
+ # Service Chain handling
+ ScfResult create_service_chain (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: ServChainId servChainId,
+ 4: ServiceChain serviceChain),
+
+ ScfResult update_service_chain (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: ServChainId servChainId,
+ 4: ServiceChain serviceChain),
+
+ ScfResult delete_service_chain (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: ServChainId servChainId),
+
+
+ # SCF nexthop handling
+
+ ScfResult create_repl_nexthop (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: NexthopId nexthopId
+ 4: IndirectNexthop replNexthop),
+
+ ScfResult update_repl_nexthop (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: NexthopId nexthopId
+ 4: IndirectNexthop replNexthop),
+
+ ScfResult create_lb_nexthop (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: NexthopId nexthopId,
+ 4: IndirectNexthop lbNexthop),
+
+ ScfResult update_lb_nexthop (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: NexthopId nexthopId,
+ 4: IndirectNexthop lbNexthops),
+
+ ScfResult create_direct_nexthop (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: NexthopId nexthopId,
+ 4: DirectNexthop directNexthop),
+
+ ScfResult update_direct_nexthop (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: NexthopId nexthopId,
+ 4: DirectNexthop directNexthop),
+
+ ScfResult delete_nexthop (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: NexthopId nexthopId),
+
+ # SC Hop handling
+ ScfResult create_sc_hop (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: ServChainId servChainId,
+ 4: PortId ingressPort,
+ 5: NexthopId nexthopId),
+
+ ScfResult update_sc_hop (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: ServChainId servChainId,
+ 4: PortId ingressPort,
+ 5: NexthopId nexthopId),
+
+ ScfResult delete_sc_hop (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: ServChainId servChainId,
+ 4: PortId ingressPort),
+}
+
+
+service FlowMapping {
+ # Profile handling
+ ScfResult create_sub_profile (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: SubProfileId subProfileId,
+ 4: string displayName),
+
+ ScfResult delete_sub_profile (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: SubProfileId subProfileId),
+
+ ScfResult create_app_profile (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: ApplProfileId applProfileId,
+ 4: string displayName),
+
+ ScfResult delete_app_profile (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: ApplProfileId applProfileId),
+
+ # SCF Service Chain mapping
+
+ ScfResult create_profile_map (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: SubProfileId subProfileId, /* Change to struct? */
+ 4: ApplProfileId applProfileId,
+ 5: ServChainId servChainId),
+
+ ScfResult update_profile_map (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: SubProfileId subProfileId,
+ 4: ApplProfileId applProfileId,
+ 5: ServChainId servChainId),
+
+ ScfResult delete_profile_map (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: SubProfileId subProfileId,
+ 4: ApplProfileId applProfileId),
+
+ # Filters
+ ScfResult create_exc_filter (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: IpAddress srcIp,
+ 4: IpAddress destIp,
+ 5: IpProtocol ipProtocol,
+ 6: PortId srcPort,
+ 7: PortId destPort,
+ 8: ServChainId servChainId),
+
+ ScfResult delete_exc_filter (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: IpAddress srcIp,
+ 4: IpAddress destIp,
+ 5: IpProtocol ipProtocol,
+ 6: PortId srcPort,
+ 7: PortId destPort),
+
+ ScfResult create_sub_filter (1: TenantId tenantId
+ 2: ScfId scfId,
+ 3: SubFilterId subFilterId,
+ 4: SubFilterInfo subFilterInfo),
+
+ ScfResult update_sub_filter (1: TenantId tenantId
+ 2: ScfId scfId,
+ 3: SubFilterId subFilterId,
+ 4: SubFilterInfo subFilterInfo),
+
+ ScfResult delete_sub_filter (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: SubFilterId subFilterId ),
+
+ ScfResult create_app_filter (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: ApplFilterId applFilterId,
+ 4: ApplFilterInfo applFilterInfo ),
+
+ ScfResult update_app_filter (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: ApplFilterId applFilterId,
+ 4: ApplFilterInfo applFilterInfo ),
+
+ ScfResult delete_app_filter (1: TenantId tenantId,
+ 2: ScfId scfId,
+ 3: ApplFilterId applFilterId ),
+
+}