cdr_encode.erl

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

ERL
1,146
字号
%%--------------------------------------------------------------------%% ``The contents of this file are subject to the Erlang Public License,%% Version 1.1, (the "License"); you may not use this file except in%% compliance with the License. You should have received a copy of the%% Erlang Public License along with this software. If not, it can be%% retrieved via the world wide web at http://www.erlang.org/.%% %% Software distributed under the License is distributed on an "AS IS"%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See%% the License for the specific language governing rights and limitations%% under the License.%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %%     $Id$%%%%-----------------------------------------------------------------%% File: cdr_encode.erl%% %% Description:%%    This file contains all encoding functions for the CDR%%    format.%%%% Creation date: 970115%%%%------------------------------------------------------------------module(cdr_encode).-include_lib("orber/include/corba.hrl").-include_lib("orber/src/orber_iiop.hrl").%%-----------------------------------------------------------------%% External exports%%------------------------------------------------------------------export([enc_giop_msg_type/1, 	 enc_request/1, enc_request_split/1, 	 enc_reply/1, enc_reply_split/1, 	 enc_type/3, enc_type/5, 	 enc_cancel_request/1,	 enc_locate_request/1, 	 enc_locate_reply/1, 	 enc_close_connection/1, 	 enc_message_error/1, 	 enc_fragment/1,	 enc_giop_message_header/5, 	 validate_request_body/1, 	 validate_reply_body/2]).%%-----------------------------------------------------------------%% Internal exports%%------------------------------------------------------------------export([]).%%-----------------------------------------------------------------%% Macros%%------------------------------------------------------------------define(DEBUG_LEVEL, 9).-define(ODD(N), (N rem 2) == 1).%%-----------------------------------------------------------------%% External functions%%-----------------------------------------------------------------%%-----------------------------------------------------------------%% Func: enc_giop_message_header/5%%-----------------------------------------------------------------%% The header size is known so we know that the size will be aligned.%% MessSize already includes the header length.%%-----------------------------------------------------------------enc_giop_message_header(#giop_env{version = {Major,Minor}}, MessType, 			_Flags, MessSize, Message) ->    Type = enc_giop_msg_type(MessType),    %% The Flag handling must be fixed, i.e., it's not correct to only use '0'.    %% If IIOP-1.0 a boolean (FALSE == 0), otherwise, IIOP-1.1 or 1.2,    %% an octet. The octet bits represents:    %% * The least significant the byteorder (0 eq. big-endian)    %% * The second least significant indicates if the message is fragmented.    %%   If set to 0 it's not fragmented.    %% * The most significant 6 bits are reserved. Hence, must be set to 0.    %% Since we currently don't support fragmented messages and we always    %% encode using big-endian it's ok to use '0' for now.    list_to_binary([ <<"GIOP",Major:8,Minor:8,0:8,		     Type:8,MessSize:32/big-unsigned-integer>> | Message]).enc_byte_order(Env, Message) ->    enc_type('tk_boolean', Env, 'false', Message, 0).%%-----------------------------------------------------------------%% Func: enc_parameters/2%%-----------------------------------------------------------------enc_parameters(_, [], [], Message, Len) ->    {Message, Len};enc_parameters(_, [], P, _, _) ->     orber:dbg("[~p] cdr_encode:encode_parameters(~p); to many parameters.", 	      [?LINE, P], ?DEBUG_LEVEL),    corba:raise(#'MARSHAL'{minor=(?ORBER_VMCID bor 17), completion_status=?COMPLETED_MAYBE});enc_parameters(_, _, [], TC, _) ->     orber:dbg("[~p] cdr_encode:encode_parameters(~p); to few parameters.", 	      [?LINE, TC], ?DEBUG_LEVEL),    corba:raise(#'MARSHAL'{minor=(?ORBER_VMCID bor 17), completion_status=?COMPLETED_MAYBE});enc_parameters(Env, [PT1 |TypeList], [ P1 | Parameters], Message, Len) ->    {Message1, Len1} = enc_type(PT1, Env, P1, Message, Len),    enc_parameters(Env, TypeList, Parameters, Message1, Len1).%%-----------------------------------------------------------------%% Func: enc_request/8%%-----------------------------------------------------------------%% ## NEW IIOP 1.2 ##enc_request(#giop_env{version = {1,2}} = Env) ->    Flags            = 1, %% LTH Not correct, just placeholder    {Message, Len}   = enc_request_id(Env, [], ?GIOP_HEADER_SIZE),    {Message1, Len1} = enc_response_flags(Env, Message, Len),    {Message2, Len2} = enc_reserved(Env, {0,0,0}, Message1, Len1),    {Message3, Len3} = enc_target_address(Env, Message2, Len2),    {Message4, Len4} = enc_operation(Env, Message3, Len3),    {Message5, Len5} = enc_service_context(Env, Message4, Len4),    {Message6, Len6} = enc_request_body(Env, Message5, Len5),    enc_giop_message_header(Env, 'request', Flags, Len6 - ?GIOP_HEADER_SIZE,			    lists:reverse(Message6));enc_request(#giop_env{version = Version} = Env) ->    Flags = 1, %% LTH Not correct, just placeholder    {Message0, Len0} = enc_service_context(Env, [], ?GIOP_HEADER_SIZE),    {Message, Len} = enc_request_id(Env, Message0, Len0),    {Message1, Len1} = enc_response(Env, Message, Len),    {Message1b, Len1b} =	if	    Version /= {1,0} ->		enc_reserved(Env, {0,0,0}, Message1, Len1);	    true ->		{Message1, Len1}	end,    {Message2, Len2} = enc_object_key(Env, Message1b, Len1b),    {Message3, Len3} = enc_operation(Env, Message2, Len2),    {Message4, Len4} = enc_principal(Env, Message3, Len3),    {Message5, Len5} = enc_request_body(Env, Message4, Len4),    enc_giop_message_header(Env, 'request', Flags, Len5 - ?GIOP_HEADER_SIZE,			    lists:reverse(Message5)).%% ## NEW IIOP 1.2 ##enc_request_split(#giop_env{version = {1,2}} = Env) ->    Flags            = 1, %% LTH Not correct, just placeholder    {Message, Len}   = enc_request_id(Env, [], ?GIOP_HEADER_SIZE),    {Message1, Len1} = enc_response_flags(Env, Message, Len),    {Message2, Len2} = enc_reserved(Env, {0,0,0}, Message1, Len1),    {Message3, Len3} = enc_target_address(Env, Message2, Len2),    {Message4, Len4} = enc_operation(Env, Message3, Len3),    {Message5, Len5} = enc_service_context(Env, Message4, Len4),    {Body, Len6}     = enc_request_body(Env, [], Len5),    {lists:reverse(Message5), list_to_binary(lists:reverse(Body)),      Len5 - ?GIOP_HEADER_SIZE, Len6-Len5, Flags};enc_request_split(#giop_env{version = Version} = Env) ->    Flags = 1, %% LTH Not correct, just placeholder    {Message0, Len0} = enc_service_context(Env, [], ?GIOP_HEADER_SIZE),    {Message, Len} = enc_request_id(Env, Message0, Len0),    {Message1, Len1} = enc_response(Env, Message, Len),    {Message1b, Len1b} =	if	    Version /= {1,0} ->		enc_reserved(Env, {0,0,0}, Message1, Len1);	    true ->		{Message1, Len1}	end,    {Message2, Len2} = enc_object_key(Env, Message1b, Len1b),    {Message3, Len3} = enc_operation(Env, Message2, Len2),    {Message4, Len4} = enc_principal(Env, Message3, Len3),    {Body, Len5}     = enc_request_body(Env, [], Len4),    {lists:reverse(Message4), list_to_binary(lists:reverse(Body)),      Len4 - ?GIOP_HEADER_SIZE, Len5-Len4, Flags}.enc_principal(Env, Mess, Len) ->    enc_type({'tk_string', 0}, Env, atom_to_list(node()), Mess, Len).enc_operation(Env, Mess, Len) ->    enc_type({'tk_string', 0}, Env, atom_to_list(Env#giop_env.op), Mess, Len).enc_object_key(Env, Mess, Len) ->    enc_type({'tk_sequence', 'tk_octet', 0}, Env, Env#giop_env.objkey, Mess, Len).enc_reserved(Env, Reserved, Mess, Len) ->    enc_type({'tk_array', 'tk_octet', 3}, Env, Reserved, Mess, Len).enc_response(Env, Mess, Len) ->    enc_type('tk_boolean', Env, Env#giop_env.response_expected, Mess, Len).    enc_request_id(Env, Mess, Len) ->      enc_type('tk_ulong', Env, Env#giop_env.request_id, Mess, Len).enc_service_context(Env, Message, Len) ->    Ctxs = enc_used_contexts(Env, Env#giop_env.ctx, []),    enc_type(?IOP_SERVICECONTEXT, Env, Ctxs, Message, Len).enc_used_contexts(_Env, [], Message) ->    Message;enc_used_contexts(#giop_env{version = {1, 0}} = Env, 		  [#'IOP_ServiceContext'{context_id=?IOP_CodeSets}|T], Ctxs) ->    %% Not supported by 1.0, drop it.    enc_used_contexts(Env, T, Ctxs);enc_used_contexts(Env, [#'IOP_ServiceContext'{context_id=?IOP_CodeSets,					      context_data = CodeSetCtx}|T], 		  Ctxs) ->    %% Encode ByteOrder    {Bytes0, Len0} = cdr_encode:enc_type('tk_octet', Env, 0, [], 0),    {Bytes1, _Len1} = enc_type(?CONV_FRAME_CODESETCONTEXT, Env, CodeSetCtx, 			       Bytes0, Len0),    Bytes = list_to_binary(lists:reverse(Bytes1)),    enc_used_contexts(Env, T, 		      [#'IOP_ServiceContext'{context_id=?IOP_CodeSets,					     context_data = Bytes}|Ctxs]);enc_used_contexts(Env, [#'IOP_ServiceContext'{context_id=?IOP_BI_DIR_IIOP,					      context_data = BiDirCtx}|T], 		  Ctxs) ->    %% Encode ByteOrder    {Bytes0, Len0} = cdr_encode:enc_type('tk_octet', Env, 0, [], 0),    {Bytes1, _Len1} = enc_type(?IIOP_BIDIRIIOPSERVICECONTEXT, Env, BiDirCtx, 			       Bytes0, Len0),    Bytes = list_to_binary(lists:reverse(Bytes1)),    enc_used_contexts(Env, T, 		      [#'IOP_ServiceContext'{context_id=?IOP_BI_DIR_IIOP,					     context_data = Bytes}|Ctxs]);enc_used_contexts(Env, [#'IOP_ServiceContext'{context_id=?IOP_FT_REQUEST,					      context_data = Ctx}|T], 		  Ctxs) ->    %% Encode ByteOrder    {Bytes0, Len0} = cdr_encode:enc_type('tk_octet', Env, 0, [], 0),    {Bytes1, _Len1} = enc_type(?FT_FTRequestServiceContext, Env, Ctx, 			       Bytes0, Len0),    Bytes = list_to_binary(lists:reverse(Bytes1)),    enc_used_contexts(Env, T, 		      [#'IOP_ServiceContext'{context_id=?IOP_FT_REQUEST,					     context_data = Bytes}|Ctxs]);enc_used_contexts(Env, [#'IOP_ServiceContext'{context_id=?IOP_FT_GROUP_VERSION,					      context_data = Ctx}|T], 		  Ctxs) ->    %% Encode ByteOrder    {Bytes0, Len0} = cdr_encode:enc_type('tk_octet', Env, 0, [], 0),    {Bytes1, _Len1} = enc_type(?FT_FTGroupVersionServiceContext, Env, Ctx, 			       Bytes0, Len0),    Bytes = list_to_binary(lists:reverse(Bytes1)),    enc_used_contexts(Env, T, 		      [#'IOP_ServiceContext'{context_id=?IOP_FT_GROUP_VERSION,					     context_data = Bytes}|Ctxs]);enc_used_contexts(Env, [#'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService,					      context_data = Ctx}|T], 		  Ctxs) ->    %% Encode ByteOrder    {Bytes0, Len0} = cdr_encode:enc_type('tk_octet', Env, 0, [], 0),    {Bytes1, _Len1} = enc_type(?CSI_SASContextBody, Env, Ctx, 			       Bytes0, Len0),    Bytes = list_to_binary(lists:reverse(Bytes1)),    enc_used_contexts(Env, T, 		      [#'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService,					     context_data = Bytes}|Ctxs]);enc_used_contexts(Env, [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID,					      context_data = {interface, _I}}|T], 		  Ctxs) ->    %% This shall not be forwarded.    enc_used_contexts(Env, T, Ctxs);enc_used_contexts(Env, [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID,					      context_data = Ctx}|T], 		  Ctxs) ->    %% Encode ByteOrder    {Bytes0, Len0} = cdr_encode:enc_type('tk_octet', Env, 0, [], 0),    {Bytes1, _Len1} = enc_type(?ORBER_GENERIC_CTX, Env, 			       binary_to_list(term_to_binary(Ctx)), 			       Bytes0, Len0),    Bytes = list_to_binary(lists:reverse(Bytes1)),    enc_used_contexts(Env, T, 		      [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID,					     context_data = Bytes}|Ctxs]);enc_used_contexts(Env, [H|T], Ctxs) ->    enc_used_contexts(Env, T, [H|Ctxs]).%% ## NEW IIOP 1.2 ##enc_target_address(#giop_env{objkey = TargetAddr} = Env, Mess, Len)   when record(TargetAddr, 'GIOP_TargetAddress') ->    enc_type(?TARGETADDRESS, Env, TargetAddr, Mess, Len);enc_target_address(#giop_env{objkey = IORInfo} = Env, Mess, Len)   when record(IORInfo, 'GIOP_IORAddressingInfo') ->    enc_type(?TARGETADDRESS, Env, #'GIOP_TargetAddress'{label = ?GIOP_ReferenceAddr, 							value = IORInfo}, 	     Mess, Len);enc_target_address(#giop_env{objkey = TP} = Env, Mess, Len)   when record(TP, 'IOP_TaggedProfile') ->    enc_type(?TARGETADDRESS, Env, #'GIOP_TargetAddress'{label = ?GIOP_ProfileAddr, 							value = TP}, 

⌨️ 快捷键说明

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