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