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 + -
显示快捷键?