ic_cclient.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,213 行 · 第 1/3 页

ERL
1,213
字号
			     "malloc(oe_malloc_size)) == NULL) {\n"			     "      CORBA_exc_set(oe_env, "			     "CORBA_SYSTEM_EXCEPTION, NO_MEMORY, "			     "\"Cannot malloc\");\n" 			     "        return -1;"			     "    }\n"),			ic_cbe:emit_decoding_stmt(G, N, Fd, RetType, 						  "oe_return", "", 						  "oe_env->_inbuf", 1, 						  "&oe_outindex", 						  array_fix_ret, 						  Pars), 			emit(Fd, "  }\n"),			Pars;		    false ->			Pars = [],			%% The last parameter "oe_outindex" is not interesting 			%% in the static case.			ic_cbe:emit_decoding_stmt(G, N, Fd, RetType, 						  "oe_return", "", 						  "oe_env->_inbuf", 1, 						  "&oe_outindex", 						  caller, Pars), 			ic_codegen:nl(Fd),			Pars		end	end,     foldl(fun({{'void', _}, _, _}, Acc) ->		  Acc;	     ({T, A, N1}, Acc) ->		  emit_one_decoding(G, N, Fd, T, A, N1, Acc)	  end, APars, TypeAttrArgs),     ok.emit_one_decoding(G, N, Fd, T, A, N1, Acc) ->    IndOp = mk_ind_op(A),     case ic_cbe:is_variable_size(G, N, T) of	true ->	    emit_coding_comment(G, N, Fd, "Decode", IndOp, 				  T, N1), 	    emit(Fd, 		 "  {\n"		 "    int oe_size_count_index = oe_env->_iin;\n"		 "    int oe_malloc_size = 0;\n"		 "    void *oe_first = NULL;\n"),	    ic_cbe:emit_malloc_size_stmt(G, N, Fd, T, 					 "oe_env->_inbuf", 					 1, caller), 	    %% XXX Add malloc prefix from option	    emit(Fd, 		 "    OE_MALLOC_SIZE_CHECK(oe_env, oe_malloc_size);\n" 		 "    if ((~s~s = oe_first = "		 "malloc(oe_malloc_size)) == NULL) {\n", [IndOp, N1]),	    ic_cbe:emit_dealloc_stmts(Fd, "      ", Acc),	    emit(Fd,		 "      CORBA_exc_set(oe_env, CORBA_SYSTEM_EXCEPTION, "		 "NO_MEMORY, \"Cannot malloc\");\n" 		 "      return -1;\n"		 "    }\n"),	    NAcc = [IndOp ++ N1| Acc],  	    DecType = case ictype:isArray(G, N, T) of			  true ->			      array_dyn;			  false ->			      caller_dyn		      end,	    ic_cbe:emit_decoding_stmt(G, N, Fd, T,  				      "(" ++ IndOp				      ++ N1 ++ ")", "", 				      "oe_env->_inbuf", 1, 				      "&oe_outindex", 				      DecType, NAcc), 	    emit(Fd, "  }\n"),	    NAcc;	false ->	    case ictype:isArray(G, N, T) of		true ->		    emit_coding_comment(G, N, Fd, "Decode", "", 					  T, N1), 		    ic_cbe:emit_decoding_stmt(G, N, Fd, T, N1, 					      "", "oe_env->_inbuf", 					      1, "&oe_outindex", 					      array_fix_out, Acc), 		    ic_codegen:nl(Fd),		    [N1| Acc]; 		false ->		    %% The last parameter "oe_outindex" is		    %% not interesting in the static case, but		    %% must be present anyhow.		    emit_coding_comment(G, N, Fd, "Decode", 					  IndOp, T, N1), 		    ic_cbe:emit_decoding_stmt(G, N, Fd, T,  N1, 					      "", "oe_env->_inbuf", 					      1, "&oe_outindex", 					      caller, Acc), 		    ic_codegen:nl(Fd),		    Acc	    end    end.%%------------------------------------------------------------%% GENERATE PROTOTYPES%%------------------------------------------------------------%%------------------------------------------------------------%% Generate operation prototypes%%------------------------------------------------------------emit_operation_prototypes(G, Fd, N, Xs) ->    lists:foreach(      fun(X) when record(X, op) ->	      {ScopedName, ArgNames, RetParTypes} = 		  ic_cbe:extract_info(G, N, X), 	      {R, ParTypes, _} = RetParTypes, 	      IfName = ic_util:to_undersc(N), 	      RT = mk_ret_type(G, N, R), 	      ParList = 		  ic_util:chain(		    mk_par_type_list(G, N, X, [in, out], [types], 				     ParTypes, ArgNames), 		    ", "), 	      emit(Fd, "~s ~s(~s, ~sCORBA_Environment*);\n", 		   [RT, ScopedName, IfName, ParList]);	 (_) ->	      ok      end, Xs).%%------------------------------------------------------------%% Generate encoder prototypes%%------------------------------------------------------------emit_encoder_prototypes(G, Fd, N, Xs) ->    lists:foreach(      fun(X) when record(X, op) ->	      {ScopedName, ArgNames, RetParTypes} = 		  ic_cbe:extract_info(G, N, X), 	      {_R, ParTypes, _} = RetParTypes, 	      IfName = ic_util:to_undersc(N), 	      ParList = ic_util:chain(			  mk_par_type_list(G, N, X, [in], [types], 					   ParTypes, ArgNames), 			  ", "),	    emit(Fd, "int ~s__client_enc(~s, ~sCORBA_Environment*);\n", 		 [ScopedName, IfName, ParList]);	 (_) ->	      ok      end, Xs).%%------------------------------------------------------------%% Generate decoder prototypes%%------------------------------------------------------------emit_decoder_prototypes(G, Fd, N, Xs) ->    lists:foreach(      fun(X) when record(X, op) ->	      case ic_forms:is_oneway(X) of		  true ->		      true;		  false ->		      IfName = ic_util:to_undersc(N), 		      {ScopedName, ArgNames, RetParTypes} = 			  ic_cbe:extract_info(G, N, X), 		      {R, ParTypes, _} = RetParTypes, 		      ParList0 = 			  mk_par_type_list(G, N, X, [out], [types], 					   ParTypes, ArgNames), 		      PARLIST = case mk_ret_type(G, N, R) of				    "void" ->					ParList0;				    Else ->					[Else ++ "*"| ParList0]				end, 		      ParList = ic_util:chain(PARLIST, ", "),		      emit(Fd, "int ~s__client_dec(~s, ~s"			   "CORBA_Environment*);\n", 			   [ScopedName, IfName, ParList])	      end;	 (_) ->	      ok      end, Xs).%%------------------------------------------------------------%% PARAMETER TYPE LISTS%%------------------------------------------------------------%%------------------------------------------------------------%%  Make parameter type list%%%%  InOrOut = in | out | [in | out]%%  TypesOrArgs = types | args | [types | args]%%------------------------------------------------------------mk_par_type_list(G, N, X, InOrOut, TypesOrArgs, Types, Args) ->    TypeAttrArgs = 	filterzip(	  fun(_, {inout, Arg}) ->		  ic_error:error(G, {inout_spec_for_c, X, Arg}), 		  false;	     (Type, {Attr, Arg}) ->		  case lists:member(Attr, InOrOut) of		      true ->			  {true, {Type, Attr, Arg}}; 		      false ->			  false		  end	  end, Types, Args),    lists:map(      fun({Type, Attr, Arg}) ->	      Ctype = ic_cbe:mk_c_type(G, N, Type), 	      IsArray = ictype:isArray(G, N, Type), 	      IsStruct = ictype:isStruct(G, N, Type), 	      IsUnion = ictype:isUnion(G, N, Type), 	      Dyn = 		  case ic_cbe:is_variable_size(G, N, Type) of		      true ->			  if 			      record(Type, string) ->		"";			      Ctype == "CORBA_char *" -> 	"";			      record(Type, wstring) ->		"";			      Ctype == "CORBA_wchar *" ->	"";			      true ->				  case IsArray of				      true ->					  "_slice*";				      false ->					  "*"				  end			  end;		      false ->			  if 			      Attr == in, Ctype == "erlang_pid" ->				  "*";			      Attr == in, Ctype == "erlang_port" ->				  "*";			      Attr == in, Ctype == "erlang_ref" ->				  "*";			      Attr == in, IsStruct == true ->				  "*";			      Attr == in, IsUnion == true ->				  "*";			      Attr == in, IsArray == true ->				  "_slice*";			      Attr == out, IsArray == true ->				  "_slice";			      true ->				  ""			  end		  end, 	      IndOp = mk_ind_op(Attr),	      case {lists:member(types, TypesOrArgs), 		    lists:member(args, TypesOrArgs)} of		  {true, true} ->		      Ctype ++ Dyn ++ IndOp ++ " " ++ Arg; 		  {true, false} ->		      Ctype ++ Dyn ++ IndOp;		  {false, true} ->		      Arg;		  {false, false} ->		      ""	      end      end, TypeAttrArgs).%%------------------------------------------------------------%% ENCODER ARG LIST%%------------------------------------------------------------%%------------------------------------------------------------%% Make encoder argument list XXX%%------------------------------------------------------------mk_arg_list_for_encoder(G, _N, X, Types, Args) ->    filterzip(      fun(_, {out, _}) ->	      false;	 (_, {inout, Arg}) ->	      ic_error:error(G, {inout_spec_for_c, X, Arg}), 	      false;	 (_Type, {in, Arg}) ->	      {true, Arg}      end, Types, Args).%%------------------------------------------------------------%% DECODER ARG LIST%%------------------------------------------------------------%%------------------------------------------------------------%% Make decoder argument list XXX%%------------------------------------------------------------mk_arg_list_for_decoder(G, _N, X, Types, Args) ->    filterzip(fun(_, {in, _}) ->		      false;		 (_, {inout, Arg}) -> 		      ic_error:error(G, {inout_spec_for_c, X, Arg}), 		      false;		 (_, {out, Arg}) ->		      {true, Arg}	      end, Types, Args).%%------------------------------------------------------------%% MISC%%------------------------------------------------------------%%------------------------------------------------------------%% Make list of {Type, Attr, Arg}%%------------------------------------------------------------mk_type_attr_arg_list(Types, Args) ->    filterzip(fun(Type, {Attr, Arg}) ->		      {true, {Type, Attr, Arg}}	      end, Types, Args).%%------------------------------------------------------------%% Make return type%%------------------------------------------------------------mk_ret_type(G, N, Type) ->    Ctype = ic_cbe:mk_c_type(G, N, Type),     Dyn = case ic_cbe:is_variable_size(G, N, Type) of	      true ->		  if 		      record(Type, string) ->			  "";		      Ctype == "CORBA_char *" ->			  "";		      record(Type, wstring) ->  			  "";		      Ctype == "CORBA_wchar *" ->  			  "";		      true ->			  case ictype:isArray(G, N, Type) of			      true ->				  "_slice*";			      false ->				  "*"			  end		  end;	      false ->		  case ictype:isArray(G, N, Type) of		      true ->			  "_slice*";		      false ->			  ""		  end	  end,     Ctype ++ Dyn.%%------------------------------------------------------------%% Make indirection operator (to "*" or not to "*").%%------------------------------------------------------------mk_ind_op(in) ->    "";mk_ind_op(inout) ->    error;mk_ind_op(out) ->    "*".%%------------------------------------------------------------%% Emit encoding/decoding comment%%------------------------------------------------------------emit_coding_comment(G, N, Fd, String, RefOrVal, Type, Name) ->    emit(Fd, "  /* ~s parameter: ~s~s ~s */\n", 	 [String, ic_cbe:mk_c_type(G, N, Type), RefOrVal, Name]).%%------------------------------------------------------------%% User protocol prefix for generic functions%%------------------------------------------------------------get_user_proto(G, Default) ->    case ic_options:get_opt(G, user_protocol) of	false ->	    Default;	Pfx ->	    Pfx     end.%%------------------------------------------------------------%% Timeout. Returns a string (or Default).%%------------------------------------------------------------get_c_timeout(G, Default) ->    case ic_options:get_opt(G, c_timeout) of	Tmo when integer(Tmo) ->	    TmoStr = integer_to_list(Tmo),	    {TmoStr, TmoStr};	{SendTmo, RecvTmo}  when integer(SendTmo), integer(RecvTmo) ->	    {integer_to_list(SendTmo), integer_to_list(RecvTmo)};	false ->	    Default    end.%%------------------------------------------------------------%% ZIPPERS (merging of successive elements of two lists).%%------------------------------------------------------------%% zip([H1| T1], [H2| T2]) ->%%     [{H1, H2}| zip(T1, T2)];%% zip([], []) ->%%     [].filterzip(F, [H1| T1], [H2| T2]) ->    case F(H1, H2) of	false ->	    filterzip(F, T1, T2);	{true, Val} ->	    [Val| filterzip(F, T1, T2)]    end;filterzip(_, [], []) ->    [].    ifelse(true, A, _) ->    A;ifelse(false, _, B) ->    B.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?