ic_cclient.erl

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

ERL
1,213
字号
/* *  Generic function, used to return received message information. *  Not used by oneways. Always generated. For backward compatibility only. */int ~s__receive_info(~s oe_obj, CORBA_Environment *oe_env){  return  ~s_prepare_reply_decoding(oe_env);}\n",         emit(Fd, Code, [IfName, IfName, UserProto])end.%%------------------------------------------------------------%% Emit constant%%------------------------------------------------------------emit_constant(G, N, ConstRecord) ->    case ic_genobj:is_hrlfile_open(G) of	false -> ok;	true ->	    Fd = ic_genobj:hrlfiled(G), 	    CName = ic_util:to_undersc(		      [ic_forms:get_id(ConstRecord#const.id)| N]), 	    UCName = ic_util:to_uppercase(CName), 	    emit(Fd, "\n#ifndef __~s__\n", [UCName]), 	    emit(Fd, "#define __~s__\n", [UCName]), 	    emit(Fd, "/* Constant: ~s */\n", [CName]), 	    if record(ConstRecord#const.type, wstring) -> 		    %% If wstring, add 'L' 		    emit(Fd, "#define ~s L~p\n", 			 [CName, ConstRecord#const.val]);	       true ->		    emit(Fd, "#define ~s ~p\n", 			 [CName, ConstRecord#const.val])	    end, 	    emit(Fd, "#endif\n\n")    end.%%------------------------------------------------------------%% Generate operation (for interface)%%------------------------------------------------------------%% N is the list of scoped ids of the *interface*. %% X is the operationgen_operation(G, N, X, OpName, ArgNames, RetParTypes) ->    case ic_genobj:is_stubfile_open(G) of	true ->	    do_gen_operation(G, N, X, OpName, ArgNames, RetParTypes);	false ->	    ok    end.do_gen_operation(G, N, X, OpName, ArgNames, RetParTypes) ->    Fd = ic_genobj:stubfiled(G),     IfName = ic_util:to_undersc(N),     IfNameUC = ic_util:to_uppercase(IfName),     {R, ParTypes, _} = RetParTypes,     IsOneway = ic_forms:is_oneway(X),    emit(Fd, "\n"	 "/***\n"	 " ***  Operation function \"~s\" ~s\n"	 " ***/\n\n", 	 [OpName, ifelse(IsOneway, "(oneway)", "")]),    RV = element(1, R),     Ret = case IsOneway of	      false ->		  if RV /= void -> 			  mk_ret_type(G, N, R);		     true -> 			  "void"		  end;	      true ->		  "void"	  end,     ParListStr = ic_util:chain(mk_par_type_list(G, N, X, [in, out], 						[types, args], 						ParTypes, ArgNames), ", "),    emit(Fd, 	 "~s ~s(~s, ~sCORBA_Environment *oe_env)\n{\n",	 [Ret, OpName, [IfName, " ", "oe_obj"], ParListStr]),     case IsOneway of	true ->	    ok;	false ->	    case ictype:isArray(G, N, R) of		true ->		    emit(Fd, "  ~s oe_return = NULL;\n\n", 			 [mk_ret_type(G, N, R)]);		false ->		    if RV /= void ->			    emit(Fd, "  ~s oe_return;\n\n", 				 [Ret]);		       true ->			    ok		    end	    end, 	    emit(Fd, 		 "  /* Initiating the message reference */\n" 		 "  ic_init_ref(oe_env, &oe_env->_unique);\n")    end,    emit(Fd, 	 "  /* Initiating exception indicator */ \n"	 "  oe_env->_major = CORBA_NO_EXCEPTION;\n"),    %% XXX Add pointer checks: checks of in-parameter    %% pointers, and non-variable out-parameter pointers.    emit(Fd,"  /* Creating ~s message */ \n", 	 [ifelse(IsOneway, "cast", "call")]),    EncParListStr = ic_util:chain(mk_arg_list_for_encoder(G, N, X, 							  ParTypes, ArgNames),				  ", "),    emit(Fd, 	 "  if (~s__client_enc(oe_obj, ~s""oe_env) < 0) {\n", 	 [OpName, EncParListStr]),    emit(Fd, 	 "    CORBA_exc_set(oe_env, CORBA_SYSTEM_EXCEPTION, "	 "DATA_CONVERSION, \"Cannot encode message\");\n"),     RetVar = ifelse(RV /= void, " oe_return", ""),    emit_c_enc_rpt(Fd, "    ", "client operation ~s\\n====\\n", [OpName]),    emit(Fd, "    return~s;\n  }\n", [RetVar]),    emit(Fd,"  /* Sending ~s message */ \n", 	 [ifelse(IsOneway, "cast", "call")]),    UserProto = get_user_proto(G, oe),    {Sfx, SendTmo, RecvTmo} = case get_c_timeout(G, "") of				  "" ->				      {"", "", ""};				  _ ->				      {"_tmo", 				       [", OE_", IfNameUC, "_SEND_TIMEOUT"], 				       [", OE_", IfNameUC, "_RECV_TIMEOUT"]} 			      end,    case IsOneway of	true ->	    emit(Fd, 		 "  if (~s_send_notification~s(oe_env~s) < 0)\n"		 "    return~s;\n", [UserProto, Sfx, SendTmo, RetVar]);	false ->	    emit(Fd, 		 "  if (~s_send_request_and_receive_reply~s(oe_env~s~s) < 0)\n"		 "    return~s;\n", 		 [UserProto, Sfx, SendTmo, RecvTmo, RetVar]),	    DecParList0 = mk_arg_list_for_decoder(G, N, X, 						  ParTypes, ArgNames), 	    DecParList1 = case mk_ret_type(G, N, R) of			      "void" ->				  DecParList0;			      _ ->				  ["&oe_return"| DecParList0]		end, 	    DecParListStr = ic_util:chain(DecParList1, ", "),	    %% YYY Extracting results	    emit(Fd, 		 "  /* Extracting result value(s) */ \n" 		 "  if (~s__client_dec(oe_obj, ~s""oe_env) < 0) {\n", 		 [OpName, DecParListStr]), 	    emit(Fd, 		 "    CORBA_exc_set(oe_env, "		 "CORBA_SYSTEM_EXCEPTION, DATA_CONVERSION, "		 "\"Bad result value(s)\");\n"),	    emit_c_dec_rpt(Fd, "    ", "client operation ~s\\n=====\\n", [OpName]),	    emit(Fd, 		 "    return~s;\n"		 "  }\n", [RetVar])    end,    emit(Fd, "  return~s;\n", [RetVar]),    emit(Fd, "}\n\n\n").%%------------------------------------------------------------%% Generate encoder %%------------------------------------------------------------%% N is the list of scoped ids of the *interface*. %% X is the operationgen_encoder(G, N, X, OpName, ArgNames, RetParTypes)->    case ic_genobj:is_stubfile_open(G) of	true ->	    Fd = ic_genobj:stubfiled(G), 	    IfName = ic_util:to_undersc(N), 	    {_R, ParTypes, _} = RetParTypes, 	    TypeAttrArgs = mk_type_attr_arg_list(ParTypes, ArgNames), 	    emit(Fd, "/*\n *  Encode operation input for \"~s\"\n */\n\n", 		 [OpName]), 	    ParList = ic_util:chain(			mk_par_type_list(G, N, X, [in], [types, args], 					 ParTypes, ArgNames), ", "), 	    emit(Fd, 		 "int ~s__client_enc(~s oe_obj, ~s"		 "CORBA_Environment *oe_env)\n{\n", 		 [OpName, IfName, ParList]),	    InTypeAttrArgs = lists:filter(fun({_, in, _}) -> true;					     ({_, _, _}) -> false					  end, TypeAttrArgs), 	    case InTypeAttrArgs of 		[] ->		    ok;		_ ->		    emit(Fd, 			 "  int oe_error_code = 0;\n\n")	    end, 	    emit_encodings(G, N, Fd, X, InTypeAttrArgs, 			   ic_forms:is_oneway(X)),  	    emit(Fd, "  return 0;\n}\n\n"), 	    ok;		false -> 	    ok    end.%%------------------------------------------------------------%% Generate decoder%%------------------------------------------------------------%% N is the list of scoped ids of the *interface*. %% X is the operationgen_decoder(G, N, X, OpName, ArgNames, RetParTypes)->    case ic_forms:is_oneway(X) of	true ->	    ok;	false ->	    case ic_genobj:is_stubfile_open(G) of		true ->		    Fd = ic_genobj:stubfiled(G), 		    IfName = ic_util:to_undersc(N), 		    {R, ParTypes, _} = RetParTypes, 		    TypeAttrArgs = mk_type_attr_arg_list(ParTypes, ArgNames), 		    emit(Fd, "/*\n *  Decode operation results for "			 "\"~s\"\n */\n\n", [OpName]), 		    ParList0 = mk_par_type_list(G, N, X, [out],						[types, args], 						ParTypes, ArgNames),		    PARLIST = case mk_ret_type(G, N, R) of				  "void" ->				      ParList0;				  Else ->    				      [Else ++ "* oe_return"| ParList0]			      end, 		    PLFCD = ic_util:chain(PARLIST, ", "), 		    emit(Fd, 			 "int ~s__client_dec(~s oe_obj, ~s"			 "CORBA_Environment *oe_env)\n{\n", 			 [OpName, IfName, PLFCD]),		    emit(Fd, "  int oe_error_code = 0;\n"), 		    OutTypeAttrArgs = lists:filter(fun({_, out, _}) -> true;						      ({_, _, _}) -> false						   end, TypeAttrArgs), 		    emit_decodings(G, N, Fd, R, OutTypeAttrArgs),		    emit(Fd, "  return 0;\n}\n\n"), 		    ok;				false -> 		    ok	    end    end.%%------------------------------------------------------------%% EMIT ENCODINGS/DECODINGS%%------------------------------------------------------------%%------------------------------------------------------------%% Emit encodings%%------------------------------------------------------------%% N is the list of scoped ids of the *interface*. %% X is the operation%% emit_encodings(G, N, Fd, X, TypeAttrArgs, IsOneWay) %%emit_encodings(G, N, Fd, X, TypeAttrArgs, true) ->    %% Cast    UserProto = get_user_proto(G, oe),    emit(Fd, 	 "  if (~s_prepare_notification_encoding(oe_env) < 0)\n"	 "    return -1;\n", [UserProto]),    emit_encodings_1(G, N, Fd, X, TypeAttrArgs);emit_encodings(G, N, Fd, X, TypeAttrArgs, false) ->    %% Call    UserProto = get_user_proto(G, oe),    emit(Fd, 	 "  if (~s_prepare_request_encoding(oe_env) < 0)\n"	 "    return -1;\n", [UserProto]),    emit_encodings_1(G, N, Fd, X, TypeAttrArgs).emit_encodings_1(G, N, Fd, X, TypeAttrArgs) ->    {ScopedName, _, _} = ic_cbe:extract_info(G, N, X),     Name = case ic_options:get_opt(G, scoped_op_calls) of 	       true -> 		   ScopedName;	       false ->		   ic_forms:get_id2(X)	   end,     if 	TypeAttrArgs /= [] -> 	    emit(Fd, "  if (oe_ei_encode_tuple_header(oe_env, ~p) < 0) {\n", 		 [length(TypeAttrArgs) + 1]), 	    emit_c_enc_rpt(Fd, "    ", "ei_encode_tuple_header", []),	    emit(Fd, "    return -1;\n  }\n");	true ->	    ok    end,    emit(Fd, "  if (oe_ei_encode_atom(oe_env, ~p) < 0) {\n", [Name]),     emit_c_enc_rpt(Fd, "    ", "oe_ei_encode_atom", []),    emit(Fd, "    return -1;\n  }\n"),    foreach(fun({{'void', _}, _, _}) ->		    ok;		({T1, A1, N1}) ->		    IndOp  = mk_ind_op(A1), 		    emit_coding_comment(G, N, Fd, "Encode", IndOp, 					  T1, N1), 		    ic_cbe:emit_encoding_stmt(G, N, X, Fd, T1, IndOp ++ N1,					      "oe_env->_outbuf")	    end, TypeAttrArgs),     ok.%%------------------------------------------------------------%% Emit dedodings%%------------------------------------------------------------%% XXX Unfortunately we have to retain the silly `oe_first' variable,%% since its name is hardcoded in other modules (icstruct, icunion,%% etc).%% N is the list of scoped ids of the *interface*. %% X is the operationemit_decodings(G, N, Fd, RetType, TypeAttrArgs) ->    if 	TypeAttrArgs /= [] ->	    %% Only if there are out parameters	    emit(Fd, "  if ((oe_error_code = ei_decode_tuple_header("		 "oe_env->_inbuf, &oe_env->_iin, "		 "&oe_env->_received)) < 0) {\n"), 	    emit_c_dec_rpt(Fd, "    ", "ei_decode_tuple_header", []),	    emit(Fd, "    return oe_error_code;\n    }\n"), 	    Len = length(TypeAttrArgs) + 1, 	    emit(Fd, "  if (oe_env->_received != ~p) {\n", [Len]),	    emit_c_dec_rpt(Fd, "    ", "tuple header size != ~p", [Len]),	    emit(Fd, "    return -1;\n    }\n"); 	true  ->	    ok    end,    %% Fetch the return value    emit_coding_comment(G, N, Fd, "Decode return value", "*", RetType, "oe_return"),     APars =	case ic_cbe:is_variable_size(G, N, RetType) of	    true ->		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, RetType, 					     "oe_env->_inbuf", 					     1, caller), 		%% XXX Add malloc prefix from option		emit(Fd, 		     "    OE_MALLOC_SIZE_CHECK(oe_env, oe_malloc_size);\n" 		     "    if ((*oe_return = oe_first = "		     "malloc(oe_malloc_size)) == NULL) {\n"		     "      CORBA_exc_set(oe_env, CORBA_SYSTEM_EXCEPTION, "		     "NO_MEMORY, \"Cannot malloc\");\n" 		     "      return -1;\n"		     "    }\n"),		Pars = ["*oe_return"],		DecType = case ictype:isArray(G, N, RetType) of			      true -> array_dyn;			      false -> caller_dyn			  end,		ic_cbe:emit_decoding_stmt(G, N, Fd, RetType, 					  "(*oe_return)", 					  "", "oe_env->_inbuf", 1, 					  "&oe_outindex", DecType,					  Pars), 		emit(Fd, "  }\n"),		Pars;	    false ->		case ictype:isArray(G, N, RetType) of		    true ->			Pars = ["*oe_return"],			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, RetType, 						     "oe_env->_inbuf", 						     1, caller), 			%% XXX Add malloc prefix from option			emit(Fd, 			     "    OE_MALLOC_SIZE_CHECK(oe_env, "			     "oe_malloc_size);\n" 			     "    if ((*oe_return = oe_first = "

⌨️ 快捷键说明

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