icstruct.erl

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

ERL
1,915
字号
    emit(Fd, "  int oe_type = 0;\n",[]),    emit(Fd, "  int oe_array_size = 0;\n",[]),    {ok, RamFd} = ram_file:open([], [binary, write]),    emit_sizecount(array, G, N, nil, RamFd, {Name, Dim}, Type),    ic_cbe:emit_tmp_variables(Fd),    ic_codegen:nl(Fd),    %% Move data from ram file to output file.    {ok, Data} = ram_file:get_file(RamFd),    emit(Fd, Data),    ram_file:close(RamFd),    emit(Fd, "  return 0;\n\n",[]),    emit(Fd, "}\n",[]),    put(op_variable_count, 0),    put(tmp_declarations, []),    RefStr = get_refStr(Dim),    case TypeDefFlag of	typedef ->	    emit(HFd, "int ~s~s(CORBA_Environment *oe_env, ~s);\n",		 [ic_util:mk_oe_name(G, "encode_"), Name, Name]),	    emit(Fd, "int ~s~s(CORBA_Environment *oe_env, ~s oe_rec) {\n",		 [ic_util:mk_oe_name(G, "encode_"), Name, Name]);	no_typedef ->	    emit(HFd, "int ~s~s(CORBA_Environment *oe_env, ~s oe_rec~s);\n",		 [ic_util:mk_oe_name(G, "encode_"), 		  Name,  		  ic_cbe:mk_c_type(G, N, Type),		  RefStr]),	    emit(Fd, "int ~s~s(CORBA_Environment *oe_env, ~s oe_rec~s) {\n",		 [ic_util:mk_oe_name(G, "encode_"), 		  Name,		  ic_cbe:mk_c_type(G, N, Type),		  RefStr])    end,    emit(Fd, "  int oe_error_code = 0;\n",[]),    {ok, RamFd1} = ram_file:open([], [binary, write]),    case TypeDefFlag of	typedef ->	    emit_encode(array, G, N, nil, RamFd1, {Name, Dim}, Type);	no_typedef ->	    emit_encode(array_no_typedef, G, N, nil, RamFd1, {Name, Dim}, Type)    end,    ic_cbe:emit_tmp_variables(Fd),    ic_codegen:nl(Fd),    %% Move data from ram file to output file.    {ok, Data1} = ram_file:get_file(RamFd1),    emit(Fd, Data1),    ram_file:close(RamFd1),    emit(Fd, "  return 0;\n\n",[]),    emit(Fd, "}\n",[]),    put(op_variable_count, 0),    put(tmp_declarations, []),    case TypeDefFlag of	typedef ->	    emit(HFd, "int ~s~s(CORBA_Environment *oe_env, char *, "		 "int*, ~s);\n",		 [ic_util:mk_oe_name(G, "decode_"), Name, Name]), 	    emit(Fd, "int ~s~s(CORBA_Environment *oe_env, char *oe_first, "		 "int* oe_outindex, ~s oe_out) {\n",		 [ic_util:mk_oe_name(G, "decode_"), Name, Name]);	no_typedef ->	    emit(HFd, "int ~s~s(CORBA_Environment *oe_env, char *, int*, "		 "~s oe_rec~s);\n",		 [ic_util:mk_oe_name(G, "decode_"), 		  Name, 		  ic_cbe:mk_c_type(G, N, Type),		  RefStr]), 	    emit(Fd, "int ~s~s(CORBA_Environment *oe_env, char *oe_first, "		 "int* oe_outindex, ~s oe_out~s) {\n",		 [ic_util:mk_oe_name(G, "decode_"), 		  Name, 		  ic_cbe:mk_c_type(G, N, Type),		  RefStr])    end,    emit(Fd, "  int oe_error_code = 0;\n",[]),    emit(Fd, "  int oe_array_size = 0;\n",[]),    {ok, RamFd2} = ram_file:open([], [binary, write]),    case TypeDefFlag of	typedef ->	    emit_decode(array, G, N, nil, RamFd2, {Name, Dim}, Type);	no_typedef ->	    emit_decode(array_no_typedef, G, N, nil, RamFd2, {Name, Dim}, Type)    end,    ic_cbe:emit_tmp_variables(Fd),    ic_codegen:nl(Fd),    %% Move data from ram file to output file.    {ok, Data2} = ram_file:get_file(RamFd2),    emit(Fd, Data2),    ram_file:close(RamFd2),    emit(Fd, "  *oe_outindex = ~s;\n\n",[align("*oe_outindex")]),    emit(Fd, "  return 0;\n\n",[]),    emit(Fd, "}\n",[]),    file:close(Fd).get_refStr([]) ->    "";get_refStr([X|Xs]) ->    "[" ++ X ++ "]" ++ get_refStr(Xs).emit_sequence_head_def(G, N, X, T, c) ->    %% T is the sequence     case ic_genobj:is_hrlfile_open(G) of	true ->	    Fd = ic_genobj:hrlfiled(G),	    SeqName = ic_util:to_undersc([ic_forms:get_id2(X) | N]),	    emit(Fd, "\n#ifndef __~s__\n",[ic_util:to_uppercase(SeqName)]),	    emit(Fd, "#define __~s__\n",[ic_util:to_uppercase(SeqName)]),	    ic_codegen:mcomment_light(Fd,				      [io_lib:format("Struct definition:  ~s",						     [SeqName])],				      c),	    emit(Fd, "typedef struct {\n"),	    emit(Fd, "  CORBA_unsigned_long _maximum;\n"),	    emit(Fd, "  CORBA_unsigned_long _length;\n"),	    emit_seq_buffer(Fd, G, N, T#sequence.type),	    emit(Fd, "} ~s;\n\n", [SeqName]),	    create_c_struct_coding_file(G, N, X, T, SeqName, 					T#sequence.type, sequence_head),	    emit(Fd, "\n#endif\n\n");	false ->	    ok    end.emit_seq_buffer(Fd, G, N, Type) ->    emit(Fd, "  ~s* _buffer;\n",	 [ic_cbe:mk_c_type(G, N, Type)]).%%------------------------------------------------------------%%%% Emit decode bodies for functions in C for array, sequences and%% structs.%%%%------------------------------------------------------------emit_decode(array, G, N, _T, Fd, {_Name, Dim}, Type) ->    emit(Fd, "  if((char*) oe_out == oe_first)\n",[]),    AlignName = 	lists:concat(["*oe_outindex + ", dim_multiplication(Dim),		      " * sizeof(", ic_cbe:mk_c_type(G, N, Type),")"]),    emit(Fd, "    *oe_outindex = ~s;\n\n",[align(AlignName)]),    array_decode_dimension_loop(G, N, Fd, Dim, "", Type, array);emit_decode(array_no_typedef, G, N, _T, Fd, {_Name, Dim}, Type) ->    emit(Fd, "  if((char*) oe_out == oe_first)\n",[]),    AlignName = 	lists:concat(["*oe_outindex + ", dim_multiplication(Dim),		      " * sizeof(", ic_cbe:mk_c_type(G, N, Type),")"]),    emit(Fd, "    *oe_outindex = ~s;\n\n",[align(AlignName)]),    array_decode_dimension_loop(G, N, Fd, Dim, "", Type, array_no_typedef);emit_decode(sequence_head, G, N, T, Fd, SeqName, ElType) ->    ic_cbe:store_tmp_decl("  int oe_seq_len = 0;\n", []),    ic_cbe:store_tmp_decl("  int oe_seq_count = 0;\n", []),    ic_cbe:store_tmp_decl("  int oe_seq_dummy = 0;\n", []),    TmpBuf = 	case ictype:isBasicTypeOrEterm(G, N, ElType) of	    true ->		Tmp = "oe_seq_tmpbuf",		ic_cbe:store_tmp_decl("  char* ~s = 0;\n", [Tmp]),		Tmp;	    false ->		"NOT USED"	end,    MaxSize = get_seq_max(T),    emit(Fd, "  if((char*) oe_out == oe_first)\n",[]),    emit(Fd, "    *oe_outindex = ~s;\n\n",	 [align(["*oe_outindex + sizeof(", SeqName, ")"])]),    Ctype = ic_cbe:mk_c_type(G, N, ElType),    emit(Fd, "  if ((oe_error_code = ei_decode_list_header(oe_env->_inbuf, "	 "&oe_env->_iin, &oe_seq_len)) < 0) {\n"),    case ictype:isBasicTypeOrEterm(G, N, ElType) of	true ->	    emit(Fd, "    int oe_type = 0;\n"),	    emit(Fd, "    (int) ei_get_type(oe_env->_inbuf, &oe_env->_iin, "		 "&oe_type, &oe_seq_len);\n\n"),	    if 		MaxSize == infinity ->		    ok;		true ->		    emit(Fd, "  if (oe_seq_len > ~w) {\n", [MaxSize]),		    emit(Fd, "    CORBA_exc_set(oe_env, "			 "CORBA_SYSTEM_EXCEPTION, DATA_CONVERSION, "			 "\"Length of sequence `~s' out of bound\");\n"			 "    return -1;\n  }\n", [SeqName])	    end,	    emit(Fd, "    oe_out->_maximum = oe_seq_len;\n"),	    emit(Fd, "    oe_out->_length = oe_seq_len;\n"),	    emit(Fd, "    oe_out->_buffer = (void *) (oe_first + "		 "*oe_outindex);\n"),	    emit(Fd, "    *oe_outindex = ~s;\n",		 [align(["*oe_outindex + (sizeof(", Ctype, ") * "			 "oe_out->_length)"])]),	    emit(Fd, 		 "    if ((~s = malloc(oe_seq_len + 1)) == NULL) {\n" 		 "      CORBA_exc_set(oe_env, CORBA_SYSTEM_EXCEPTION, "		 "NO_MEMORY, \"Cannot malloc\");\n" 		 "      return -1;\n"		 "    }\n", [TmpBuf]),	    emit(Fd, "    if ((oe_error_code = ei_decode_string("		 "oe_env->_inbuf, &oe_env->_iin, ~s)) < 0) {\n", [TmpBuf]),	    emit(Fd, "      CORBA_free(~s);\n\n", [TmpBuf]),	    emit_c_dec_rpt(Fd, "      ", "string1", []),	    emit(Fd, "      return oe_error_code;\n    }\n"),	    emit(Fd, "    for (oe_seq_count = 0; "		 "oe_seq_count < oe_out->_length; oe_seq_count++)\n"), 	    case ictype:isBasicType(G, N, ElType) of		true -> 		    emit(Fd, "      oe_out->_buffer[oe_seq_count] = (unsigned char) "			 "~s[oe_seq_count];\n\n", [TmpBuf]);		false -> %% Term		    emit(Fd, "      oe_out->_buffer[oe_seq_count] = "			 "erl_mk_int(~s[oe_seq_count]);\n\n",[TmpBuf]) % XXXX What?	    end,	    emit(Fd, "    CORBA_free(~s);\n\n", [TmpBuf]);	false ->	    emit(Fd, "    return oe_error_code;\n")    end,    emit(Fd, "  } else {\n"),    if 	MaxSize == infinity ->	    ok;	true ->	    emit(Fd, "    if (oe_seq_len > ~w) {\n", [MaxSize]),	    emit(Fd, "      CORBA_exc_set(oe_env, "		 "CORBA_SYSTEM_EXCEPTION, DATA_CONVERSION, "		 "\"Length of sequence `~s' out of bound\");\n"		 "      return -1;\n  }\n", [SeqName])    end,    emit(Fd, "    oe_out->_maximum = oe_seq_len;\n"),    emit(Fd, "    oe_out->_length = oe_seq_len;\n"),    emit(Fd, "    oe_out->_buffer = (void *) (oe_first + *oe_outindex);\n"),    emit(Fd, "    *oe_outindex = ~s;\n\n",	 [align(["*oe_outindex + (sizeof(", Ctype, ") * oe_out->_length)"])]),    if	Ctype == "CORBA_char *" ->	    emit(Fd, "    for (oe_seq_count = 0; "		 "oe_seq_count < oe_out->_length; oe_seq_count++) {\n"),	    emit(Fd, "      oe_out->_buffer[oe_seq_count] = "		 "(void*) (oe_first + *oe_outindex);\n\n"),	    ic_cbe:emit_decoding_stmt(G, N, Fd, ElType, 				      "oe_out->_buffer[oe_seq_count]", 				      "", 				      "oe_env->_inbuf", 0, "", caller_dyn),            emit(Fd, "      *oe_outindex = ~s;",		 [align(["*oe_outindex + strlen(oe_out->_buffer["			 "oe_seq_count]) + 1"])]);	true ->	    emit(Fd, "    for (oe_seq_count = 0; "		 "oe_seq_count < oe_out->_length; oe_seq_count++) {\n"), 	    case ictype:isArray(G, N, ElType) of		%% XXX Silly. There is no real difference between the		%% C statements produced by the following calls.  		true ->		    ic_cbe:emit_decoding_stmt(G, N, Fd, ElType, 					      "oe_out->_buffer[oe_seq_count]",					      "", 					      "oe_env->_inbuf", 					      0, "oe_outindex", generator);		false ->		    ic_cbe:emit_decoding_stmt(G, N, Fd, ElType, 					      "oe_out->_buffer + oe_seq_count",					      "", 					      "oe_env->_inbuf", 					      0, "oe_outindex", generator)	    end    end,    emit(Fd, "    }\n"),    emit(Fd, "    if (oe_out->_length != 0) {\n"),    emit(Fd, "      if ((oe_error_code = ei_decode_list_header("	 "oe_env->_inbuf, &oe_env->_iin, &oe_seq_dummy)) < 0) {\n"),    emit_c_dec_rpt(Fd, "        ", "ei_decode_list_header", []),    emit(Fd, "        return oe_error_code;\n      }\n"),    emit(Fd, "    } else\n"),    emit(Fd, "        oe_out->_buffer = NULL;\n"),    emit(Fd, "  }\n");emit_decode(struct, G, N, _T, Fd, StructName, ElTypes) ->    Length = length(ElTypes) + 1,    Tname = ic_cbe:mk_variable_name(op_variable_count),    Tname1 = ic_cbe:mk_variable_name(op_variable_count),    ic_cbe:store_tmp_decl("  int ~s = 0;\n",[Tname]),    ic_cbe:store_tmp_decl("  char ~s[256];\n\n",[Tname1]),    emit(Fd, "  if((char*) oe_out == oe_first)\n",[]),    AlignName = lists:concat(["*oe_outindex + sizeof(",StructName,")"]),    emit(Fd, "    *oe_outindex = ~s;\n\n", [align(AlignName)]),    emit(Fd, "  if ((oe_error_code = ei_decode_tuple_header(oe_env->_inbuf, "	 "&oe_env->_iin, &~s)) < 0) {\n", [Tname]),    emit_c_dec_rpt(Fd, "    ", "ei_decode_tuple_header", []),    emit(Fd, "    return oe_error_code;\n  }\n"),    emit(Fd, "  if (~s != ~p) {\n",[Tname, Length]),    emit_c_dec_rpt(Fd, "      ", "tuple header size != ~p", [Length]),    emit(Fd, "    return -1;\n  }\n"),    emit(Fd, "  if ((oe_error_code = ei_decode_atom(oe_env->_inbuf, "	 "&oe_env->_iin, ~s)) < 0) {\n", [Tname1]),    emit_c_dec_rpt(Fd, "    ", "ei_decode_atom", []),    emit(Fd, "    return oe_error_code;\n  }\n"),    emit(Fd, "  if (strcmp(~s, ~p) != 0)\n",[Tname1, StructName]),    emit(Fd, "    return -1;\n\n"),    lists:foreach(      fun({ET, EN}) ->	      case ic_cbe:is_variable_size(G, N, ET) of		  true ->		      case ET of			  {struct, _, _, _} ->			      %% Sequence member = a struct			      ic_cbe:emit_decoding_stmt(G, N, Fd, 							StructName ++ "_" ++ 							ic_forms:get_id2(ET), 							"&oe_out->" ++ EN,							"", "oe_env->_inbuf", 							0, 							"oe_outindex", 							generator);			  {sequence, _, _} ->			      %% Sequence member = a struct XXX ??			      ic_cbe:emit_decoding_stmt(G, N, Fd, 							StructName ++ "_" ++ 							EN, 							"&oe_out->" ++ EN,							"", 							"oe_env->_inbuf", 							0, 							"oe_outindex", 							generator);			  {_,{array, _, _}} ->			      emit(Fd, "  oe_out->~s = (void *) "				   "(oe_first+*oe_outindex);\n\n",[EN]),			      ic_cbe:emit_decoding_stmt(G, N, Fd, 							StructName ++ "_" ++ 							EN, "oe_out->" ++ EN ,							"", 							"oe_env->_inbuf", 							0, 							"oe_outindex", 							generator);			  {union, _, _, _, _} ->			      %% Sequence member = a union			      ic_cbe:emit_decoding_stmt(G, N, Fd, 							StructName ++ "_" ++ 							ic_forms:get_id2(ET), 							"&oe_out->" ++ EN,							"", 							"oe_env->_inbuf", 							0, 							"oe_outindex", 							generator);			  {string,_} -> 			      ic_cbe:emit_decoding_stmt(G, N, Fd, 							ET, 							"oe_out->" ++ EN ,							"", 							"oe_env->_inbuf", 							0, 							"oe_outindex", 							generator_malloc);			  {scoped_id,_,_,_} ->			      case ictype:member2type(G,StructName,EN) of				  array ->				      ic_cbe:emit_decoding_stmt(G, N, Fd, 								ET, 								"oe_out->" ++ 								EN,								"", 								"oe_env->"								"_inbuf", 								0, 								"oe_outindex",								generator);				  struct ->				      ic_cbe:emit_decoding_stmt(G, N, Fd, 								ET, 								"&oe_out->" ++								EN ,								"", 								"oe_env->"								"_inbuf", 								0, 								"oe_outindex",								generator);				  sequence ->				      ic_cbe:emit_decoding_stmt(G, N, Fd, 								ET, 								"&oe_out->" ++								EN,								"", 								"oe_env->"								"_inbuf", 								0, 								"oe_outindex",								generator);				  union ->				      ic_cbe:emit_decoding_stmt(G, N, Fd, 								ET, 								"&oe_out->" ++								EN,								"", 								"oe_env->"								"_inbuf", 								0, 								"oe_outindex",								generator);				  _ ->				      ic_cbe:emit_decoding_stmt(G, N, Fd, 								ET, 								"oe_out->" ++ 								EN,								"", 								"oe_env->"								"_inbuf", 								0, 								"oe_outindex",								generator)			      end;			  _ ->			      emit(Fd, "  oe_out->~s = (void *) "				   "(oe_first+*oe_outindex);\n\n",[EN]),			      ic_cbe:emit_decoding_stmt(G, N, Fd, 							ET, 							"oe_out->" ++ EN ,							"", 							"oe_env->_inbuf", 							0, "oe_outindex", 							generator)		      end;		  false ->		      case ET of			  {struct, _, _, _} ->			      %% A struct member			      ic_cbe:emit_decoding_stmt(G, N, Fd, 							StructName ++ "_" ++ 							ic_forms:get_id2(ET), 							"&oe_out->" ++ EN ,							"", 							"oe_env->_inbuf", 

⌨️ 快捷键说明

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