ic_jbe.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,486 行 · 第 1/4 页
ERL
1,486 行
end; _ -> case ReceiveNr > 0 of true -> ic_codegen:emit(Fd, " // Extracting return/output values\n"), ic_codegen:emit(Fd, " __is.read_tuple_head();\n"), case ic_java_type:isBasicType(G,N,R) of true -> ic_codegen:emit(Fd, " ~s _result = __is~s;\n", [RT,ic_java_type:unMarshalFun(G, N, X, R)]); false -> ic_codegen:emit(Fd, " ~s _result = ~s.unmarshal(__is);\n", [RT, ic_java_type:getUnmarshalType(G,N,X,R)]) end, emit_op_decode_loop(G, N, X, ParamTypes, ArgNames, 1, Fd), ic_codegen:nl(Fd), ic_codegen:emit(Fd, " return _result;\n"); false -> ic_codegen:emit(Fd, " // Extracting return value\n"), case ic_java_type:isBasicType(G,N,R) of true -> ic_codegen:emit(Fd, " return __is~s;\n", [ic_java_type:unMarshalFun(G, N, X, R)]); false -> ic_codegen:emit(Fd, " return ~s.unmarshal(__is);\n", [ic_java_type:getUnmarshalType(G,N,X,R)]) end end end.emit_op_decode_loop(_,_,_,_,[],_,_Fd) -> ok;emit_op_decode_loop(G, N, X, [_Type|Types], [{in, _Arg}|Args], Counter, Fd) -> emit_op_decode_loop(G, N, X, Types, Args, Counter, Fd);emit_op_decode_loop(G, N, X, [Type|Types], [{_, Arg}|Args], Counter, Fd) -> case ic_java_type:isBasicType(G,N,Type) of true -> ic_codegen:emit(Fd, " ~s.value = __is~s;\n", [Arg, ic_java_type:unMarshalFun(G, N, X, Type)]); false -> ic_codegen:emit(Fd, " ~s.value = ~s.unmarshal(__is);\n", [Arg, ic_java_type:getUnmarshalType(G, N, X, Type)]) end, emit_op_decode_loop(G, N, X, Types, Args, Counter+1, Fd).emit_message_reference_extraction(Fd) -> ic_codegen:emit(Fd, " // Returns call reference\n"), ic_codegen:emit(Fd, " public ~sOtpErlangRef __getRef()\n", [?ERLANGPACKAGE]), ic_codegen:emit(Fd, " throws java.lang.Exception {\n"), ic_codegen:emit(Fd, " return _env.received_ref();\n"), ic_codegen:emit(Fd, " }\n\n").emit_servers_object_access(Fd) -> ic_codegen:emit(Fd, " // Returns the server\n"), ic_codegen:emit(Fd, " public java.lang.Object __server() {\n"), ic_codegen:emit(Fd, " return _env.server();\n"), ic_codegen:emit(Fd, " }\n\n").emit_client_connection_close(Fd) -> ic_codegen:emit(Fd, " // Closes connection\n"), ic_codegen:emit(Fd, " public void __disconnect() {\n"), ic_codegen:emit(Fd, " _env.disconnect();\n"), ic_codegen:emit(Fd, " }\n\n").emit_client_connection_reconnect(Fd) -> ic_codegen:emit(Fd, " // Reconnects client\n"), ic_codegen:emit(Fd, " public void __reconnect()\n"), ic_codegen:emit(Fd, " throws java.lang.Exception {\n"), ic_codegen:emit(Fd, " _env.reconnect();\n"), ic_codegen:emit(Fd, " }\n\n").emit_client_destroy(Fd) -> ic_codegen:emit(Fd, " // Destroy server\n"), ic_codegen:emit(Fd, " public void __stop()\n"), ic_codegen:emit(Fd, " throws java.lang.Exception {\n"), ic_codegen:emit(Fd, " _env.client_stop_server();\n"), ic_codegen:emit(Fd, " }\n\n").%%%----------------------------------------------------%%%%%% Generates the server code%%%%%%----------------------------------------------------emit_skel(G, N, X, Fd) -> InterfaceName = ic_forms:get_java_id(X), FullInterfaceName = ic_util:to_dot([InterfaceName|N]), ic_codegen:emit(Fd, "public abstract class _~sImplBase implements ~s {\n\n", [InterfaceName,FullInterfaceName]), ic_codegen:emit(Fd, " // Server data\n"), ic_codegen:emit(Fd, " protected ~sEnvironment _env = null;\n\n",[?ICPACKAGE]), ic_codegen:emit(Fd, " // Constructors\n"), ic_codegen:emit(Fd, " public _~sImplBase() {\n",[InterfaceName]), ic_codegen:emit(Fd, " }\n\n"), emit_caller_pid(G, N, X, Fd), %% Emit operation dictionary emit_dictionary(G, N, X, Fd), %% Emit server switch emit_server_switch(G, N, X, Fd), ic_codegen:emit(Fd, "}\n").emit_server_switch(G, N, X, Fd) -> IFCName = ic_forms:get_id2(X), %% Internal Interface Name Body = ic_forms:get_body(X), Counter = 0, ic_codegen:emit(Fd, " // Operation invokation\n"), ic_codegen:emit(Fd, " public ~sOtpOutputStream invoke(~sOtpInputStream _in)\n", [?ERLANGPACKAGE,?ERLANGPACKAGE]), ic_codegen:emit(Fd, " throws java.lang.Exception {\n\n"), ic_codegen:emit(Fd, " // Create a new environment if needed\n"), ic_codegen:emit(Fd, " if (_env == null)\n"), ic_codegen:emit(Fd, " _env = new com.ericsson.otp.ic.Environment();\n\n"), ic_codegen:emit(Fd, " // Unmarshal head\n"), ic_codegen:emit(Fd, " _env.uHead(_in);\n\n"), ic_codegen:emit(Fd, " // Switch over operation\n"), ic_codegen:emit(Fd, " return __switch(_env);\n"), ic_codegen:emit(Fd, " }\n\n"), ic_codegen:emit(Fd, " // Operation switch\n"), ic_codegen:emit(Fd, " public ~sOtpOutputStream __switch(~sEnvironment __env)\n", [?ERLANGPACKAGE,?ICPACKAGE]), ic_codegen:emit(Fd, " throws java.lang.Exception {\n\n"), ic_codegen:emit(Fd, " // Setup streams and operation label\n"), ic_codegen:emit(Fd, " ~sOtpOutputStream __os = __env.getOs();\n",[?ERLANGPACKAGE]), ic_codegen:emit(Fd, " __os.reset();\n"), ic_codegen:emit(Fd, " int __label = __env.uLabel(__operations);\n\n"), ic_codegen:emit(Fd, " // Switch over operation\n"), ic_codegen:emit(Fd, " switch(__label) {\n\n"), OpNr = emit_server_op_switch_loop(G, [IFCName|N], [{x, Body} | X#interface.inherit_body], Counter, Fd), ic_codegen:emit(Fd, " case ~p: { // Standard stop operation\n\n",[OpNr]), ic_codegen:emit(Fd, " __env.server_stop_server();\n\n"), ic_codegen:emit(Fd, " } break;\n\n"), ic_codegen:emit(Fd, " default: // It will never come down here \n"), ic_codegen:emit(Fd, " throw new java.lang.Exception(\"BAD OPERATION\");\n\n", []), ic_codegen:emit(Fd, " }\n\n"), ic_codegen:emit(Fd, " if(__os.count() > 0)\n"), ic_codegen:emit(Fd, " return __os;\n\n"), ic_codegen:emit(Fd, " return null;\n"), ic_codegen:emit(Fd, " }\n\n").emit_server_op_switch_loop(_G, _N, [], C, _Fd) -> C;emit_server_op_switch_loop(G, N, [{_,X}|Xs], C, Fd) -> C1 = emit_server_op_switch(G, N, X, C, Fd), emit_server_op_switch_loop(G, N, Xs, C1, Fd).emit_server_op_switch(G, N, [X|Xs], C, Fd) when record(X, op) -> OpName = ic_forms:get_java_id(X), ic_codegen:emit(Fd, " case ~p: { // Operation ~s\n\n",[C,ic_util:to_dot([OpName|N])]), emit_invoke(G, N, X, Fd), ic_codegen:emit(Fd, " } break;\n\n"), emit_server_op_switch(G, N, Xs, C+1, Fd);emit_server_op_switch(G, N, [X |Xs], C, Fd) when record(X, attr) -> C1 = ic_attribute_java:emit_attribute_switch_case(G,N,X,Fd,C), emit_server_op_switch(G, N, Xs, C1, Fd);emit_server_op_switch(G, N, [_X|Xs], C, Fd) -> emit_server_op_switch(G, N, Xs, C, Fd);emit_server_op_switch(_G, _N, [], C, _Fd) -> C.emit_caller_pid(_G, _N, _X, Fd) -> ic_codegen:emit(Fd, " // Extracts caller identity\n"), ic_codegen:emit(Fd, " public ~sOtpErlangPid __getCallerPid() {\n", [?ERLANGPACKAGE]), ic_codegen:emit(Fd, " return _env.getScaller();\n"), ic_codegen:emit(Fd, " }\n\n"), ic_codegen:emit(Fd, " public ~sOtpErlangPid __getCallerPid(~sEnvironment __env) {\n", [?ERLANGPACKAGE, ?ICPACKAGE]), ic_codegen:emit(Fd, " return __env.getScaller();\n"), ic_codegen:emit(Fd, " }\n\n"), ic_codegen:emit(Fd, " public boolean __isStopped() {\n"), ic_codegen:emit(Fd, " return _env.isStopped();\n"), ic_codegen:emit(Fd, " }\n\n"), ic_codegen:emit(Fd, " public boolean __isStopped(~sEnvironment __env) {\n", [?ICPACKAGE]), ic_codegen:emit(Fd, " return __env.isStopped();\n"), ic_codegen:emit(Fd, " }\n\n"). %% Creates an operation dictionaryemit_dictionary(G, N, X, Fd) -> Counter = 0, Body = ic_forms:get_body(X), ic_codegen:emit(Fd, " // Operation dictionary\n"), ic_codegen:emit(Fd, " private static java.util.Dictionary __operations = new java.util.Hashtable();\n"), ic_codegen:emit(Fd, " static {\n"), emit_dictionary_loop(G, [ic_forms:get_id2(X)|N], [{x, Body} | X#interface.inherit_body], Counter, Fd), ic_codegen:emit(Fd, " }\n\n"), ic_codegen:emit(Fd, " // Operation dictionary access\n"), ic_codegen:emit(Fd, " public static java.util.Dictionary __operations() {\n"), ic_codegen:emit(Fd, " return __operations;\n"), ic_codegen:emit(Fd, " }\n\n").emit_dictionary_loop(_G, _N, [], C, Fd) -> ic_codegen:emit(Fd, " __operations.put(~p, new java.lang.Integer(~p));\n", ["stop",C]);emit_dictionary_loop(G, N, [{_,X}|Xs], C, Fd) -> C1 = emit_dictionary(G, N, X, C, Fd), emit_dictionary_loop(G, N, Xs, C1, Fd).emit_dictionary(G, N, [X|Xs], C, Fd) when record(X, op) -> OpName = case ic_options:get_opt(G, scoped_op_calls) of true -> ic_util:to_undersc([ic_forms:get_id2(X)|N]); false -> ic_forms:get_id2(X) end, ic_codegen:emit(Fd, " __operations.put(~p, new java.lang.Integer(~p));\n", [OpName,C]), emit_dictionary(G, N, Xs, C+1, Fd);emit_dictionary(G, N, [X |Xs], C, Fd) when record(X, attr) -> C1 = ic_attribute_java:emit_atrribute_on_dictionary(G, N, X, Fd, C), emit_dictionary(G, N, Xs, C1, Fd);emit_dictionary(G, N, [_X|Xs], C, Fd) -> emit_dictionary(G, N, Xs, C, Fd);emit_dictionary(_G, _N, [], C, _Fd) -> C.emit_invoke(G, N, X, Fd) -> {_, ArgNames, TypeList} = extract_info(G, N, X), {R, ParamTypes, _} = TypeList, OpName = ic_forms:get_java_id(X), RT = ic_java_type:getParamType(G,N,R,ret), PL = ic_util:mk_list(gen_cb_arg_list(ArgNames)), OutParamNr = count_server_send(ArgNames), case count_server_receive(ArgNames) of 0 -> ok; _C -> ic_codegen:emit(Fd, " // Preparing input\n"), ic_codegen:emit(Fd, " ~sOtpInputStream __is = __env.getIs();\n", [?ERLANGPACKAGE]), emit_server_unmarshal_loop(G, N, X, ParamTypes, ArgNames, 1, Fd) end, ic_codegen:emit(Fd, " // Calling implementation function\n"), case RT of "void" -> ic_codegen:emit(Fd, " this.~s(~s);\n\n", [OpName,PL]); _ -> ic_codegen:emit(Fd, " ~s _result = this.~s(~s);\n\n", [RT, OpName, PL]) end, case ic_forms:is_oneway(X) of true -> ok; false -> ic_codegen:emit(Fd, " // Marshaling output\n"), ic_codegen:emit(Fd, " ~sOtpErlangRef __ref = __env.getSref();\n",[?ERLANGPACKAGE]), case RT of "void" -> case OutParamNr > 0 of true -> ic_codegen:emit(Fd, " __os.write_tuple_head(2);\n"), ic_codegen:emit(Fd, " __os.write_ref(__ref.node(),__ref.ids(),__ref.creation()); // Call reference\n"), ic_codegen:emit(Fd, " __os.write_tuple_head(~p);\n",[OutParamNr+1]), ic_codegen:emit(Fd, " __os.write_atom(\"ok\");\n"), emit_server_marshal_loop(G, N, X, ParamTypes,ArgNames,1,Fd); false -> ic_codegen:emit(Fd, " __os.write_tuple_head(2);\n"), ic_codegen:emit(Fd, " __os.write_ref(__ref.node(),__ref.ids(),__ref.creation()); // Call reference\n"), ic_codegen:emit(Fd, " __os.write_atom(\"ok\");\n\n") end; _ -> case OutParamNr > 0 of true -> ic_codegen:emit(Fd, " __os.write_tuple_head(2);\n"), ic_codegen:emit(Fd, " __os.write_ref(__ref.node(),__ref.ids(),__ref.creation()); // Call reference\n"), ic_codegen:emit(Fd, " __os.write_tuple_head(~p);\n",[OutParamNr+1]), case ic_java_type:isBasicType(G,N,R) of true -> ic_codegen:emit(Fd, " __os~s(_result); // Return value\n", [ic_java_type:marshalFun(G,N,X,R)]); false -> ic_codegen:emit(Fd, " ~s(__os,_result); // Return value\n", [ic_java_type:marshalFun(G,N,X,R)]) end, emit_server_marshal_loop(G, N, X, ParamTypes,ArgNames,1,Fd); false -> ic_codegen:emit(Fd, " __os.write_tuple_head(2);\n"), ic_codegen:emit(Fd, " __os.write_ref(__ref.node(),__ref.ids(),__ref.creation()); // Call reference\n"), case ic_java_type:isBasicType(G,N,R) of true -> ic_codegen:emit(Fd, " __os~s(_result); // Return value\n\n", [ic_java_type:marshalFun(G,N,X,R)]); false -> ic_codegen:emit(Fd, " ~s(__os,_result); // Return value\n\n", [ic_java_type:marshalFun(G,N,X,R)]) end end end, ic_codegen:nl(Fd) end.emit_server_unmarshal_loop(_,_,_,_,[],_,Fd) -> ic_codegen:nl(Fd);emit_server_unmarshal_loop(G, N, X, [Type|Types], [{in, Arg}|Args], Counter, Fd) -> case ic_java_type:isBasicType(G,N,Type) of
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?