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