diff options
Diffstat (limited to 'lib/orber/src/cdr_decode.erl')
-rw-r--r-- | lib/orber/src/cdr_decode.erl | 1536 |
1 files changed, 0 insertions, 1536 deletions
diff --git a/lib/orber/src/cdr_decode.erl b/lib/orber/src/cdr_decode.erl deleted file mode 100644 index fd021988c9..0000000000 --- a/lib/orber/src/cdr_decode.erl +++ /dev/null @@ -1,1536 +0,0 @@ -%%-------------------------------------------------------------------- -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1997-2015. All Rights Reserved. -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. -%% -%% %CopyrightEnd% -%% -%% -%%----------------------------------------------------------------- -%% File: cdr_decode.erl -%% -%% Description: -%% This file contains all decoding functions for the CDR -%% format. -%% -%%----------------------------------------------------------------- --module(cdr_decode). - --include_lib("orber/src/orber_iiop.hrl"). --include_lib("orber/include/ifr_types.hrl"). --include_lib("orber/include/corba.hrl"). - --include_lib("orber/src/ifr_objects.hrl"). - -%%----------------------------------------------------------------- -%% External exports -%%----------------------------------------------------------------- --export([dec_giop_message_header/1, dec_reply_header/4, - dec_reply_body/6, dec_locate_reply_header/4, - dec_locate_reply_body/5, dec_message_header/3, dec_request_body/6, - dec_octet_sequence_bin/6, dec_message/2, peek_request_id/2]). - -%%----------------------------------------------------------------- -%% Functions which only are exported for the testcases. -%%----------------------------------------------------------------- --export([dec_type/5, dec_byte_order/1, dec_system_exception/4, dec_user_exception/4, - dec_byte_order_list/1]). - -%%----------------------------------------------------------------- -%% Internal exports -%%----------------------------------------------------------------- - -%%----------------------------------------------------------------- -%% Macros -%%----------------------------------------------------------------- --define(DEBUG_LEVEL, 9). - --define(ODD(N), (N rem 2) == 1). - -%%----------------------------------------------------------------- -%% Func: dec_message/3 -%% Args: -%% TypeCodes - is the type_codes of the return value and out parameters -%% when one decodes a reply. -%% Bytes - is the the message as a byte sequence. -%% Returns: -%% A tupple which contains the decoded message, -%% {ok, Header, Parameters, TypeCodes}. -%%----------------------------------------------------------------- -dec_message(TypeCodes, Bytes) -> - Message = dec_giop_message_header(Bytes), - case Message#giop_message.message_type of - ?GIOP_MSG_REQUEST -> - {Version, ReqHdr, Rest, Len, ByteOrder} = - dec_request_header(Message#giop_message.giop_version, - Message#giop_message.message, ?GIOP_HEADER_SIZE, - Message#giop_message.byte_order, Bytes), - dec_request_body(Version, ReqHdr, Rest, Len, ByteOrder, Bytes); - ?GIOP_MSG_REPLY -> - dec_reply(Message#giop_message.giop_version, - TypeCodes, Message#giop_message.message, ?GIOP_HEADER_SIZE, - Message#giop_message.byte_order); - ?GIOP_MSG_CANCEL_REQUEST -> - dec_cancel_request(Message#giop_message.giop_version, - Message#giop_message.message, ?GIOP_HEADER_SIZE, - Message#giop_message.byte_order); - ?GIOP_MSG_LOCATE_REQUEST -> - dec_locate_request(Message#giop_message.giop_version, - Message#giop_message.message, ?GIOP_HEADER_SIZE, - Message#giop_message.byte_order); - ?GIOP_MSG_LOCATE_REPLY -> - dec_locate_reply(Message#giop_message.giop_version, - Message#giop_message.message, ?GIOP_HEADER_SIZE, - Message#giop_message.byte_order); - ?GIOP_MSG_CLOSE_CONNECTION -> - 'close_connection'; - ?GIOP_MSG_MESSAGE_ERROR -> - 'message_error'; - ?GIOP_MSG_FRAGMENT -> - dec_fragment_header(Message#giop_message.giop_version, - Message#giop_message.message, ?GIOP_HEADER_SIZE, - Message#giop_message.byte_order, Bytes) - end. - -%%----------------------------------------------------------------- -%% Func: dec_giop_message_header/1 -%% Args: -%% Bytes - is the the message as a byte sequence. -%% Returns: -%% A giop_message record. -%%----------------------------------------------------------------- -%% Magic|Version|BO| Type | Size | Body -dec_giop_message_header(<<"GIOP",1:8,0:8,1:8,MessType:8, - MessSize:32/little-unsigned-integer,Message/binary>>) -> - #giop_message{magic = "GIOP", giop_version = {1,0}, - byte_order = little, message_type = MessType, - message_size = MessSize, message = Message}; -dec_giop_message_header(<<"GIOP",1:8,0:8,0:8,MessType:8, - MessSize:32/big-unsigned-integer,Message/binary>>) -> - #giop_message{magic = "GIOP", giop_version = {1,0}, - byte_order = big, message_type = MessType, - message_size = MessSize, message = Message}; -dec_giop_message_header(<<"GIOP",1:8,Minor:8,Flags:8,MessType:8, - MessSize:32/little-unsigned-integer,Message/binary>>) when - ((Flags band 16#01) == 16#01) -> - #giop_message{magic = "GIOP", giop_version = {1,Minor}, - byte_order = little, fragments = ((Flags band 16#02) == 16#02), - message_type = MessType, message_size = MessSize, message = Message}; -dec_giop_message_header(<<"GIOP",1:8,Minor:8,Flags:8,MessType:8, - MessSize:32/big-unsigned-integer,Message/binary>>) -> - #giop_message{magic = "GIOP", giop_version = {1,Minor}, - byte_order = big, fragments = ((Flags band 16#02) == 16#02), - message_type = MessType, message_size = MessSize, message = Message}; -dec_giop_message_header(<<Hdr:?GIOP_HEADER_SIZE/binary, _Body/binary>>) -> - orber:dbg("[~p] cdr_decode:dec_giop_message_header(~p);~n" - "Orber cannot decode the GIOP-header.", [?LINE, Hdr], ?DEBUG_LEVEL), - exit(message_error); -dec_giop_message_header(Other) -> - orber:dbg("[~p] cdr_decode:dec_giop_message_header(~p);~n" - "Orber cannot decode the GIOP-header.", [?LINE, Other], ?DEBUG_LEVEL), - exit(message_error). - - -peek_request_id(big, <<ReqId:32/big-unsigned-integer,_/binary>>) -> - ReqId; -peek_request_id(little, <<ReqId:32/little-unsigned-integer,_/binary>>) -> - ReqId. - -%%----------------------------------------------------------------- -%% Func: dec_message_header/2 -%% Args: -%% Header - #giop_message{} -%% Bytes - is the the message body as a byte sequence. -%% Returns: -%%----------------------------------------------------------------- -dec_message_header(TypeCodes, Message, Bytes) -> - case Message#giop_message.message_type of - ?GIOP_MSG_REQUEST -> - dec_request_header(Message#giop_message.giop_version, - Message#giop_message.message, ?GIOP_HEADER_SIZE, - Message#giop_message.byte_order, Bytes); - ?GIOP_MSG_REPLY -> - dec_reply(Message#giop_message.giop_version, - TypeCodes, Message#giop_message.message, ?GIOP_HEADER_SIZE, - Message#giop_message.byte_order); - ?GIOP_MSG_CANCEL_REQUEST -> - dec_cancel_request(Message#giop_message.giop_version, - Message#giop_message.message, ?GIOP_HEADER_SIZE, - Message#giop_message.byte_order); - ?GIOP_MSG_LOCATE_REQUEST -> - dec_locate_request(Message#giop_message.giop_version, - Message#giop_message.message, ?GIOP_HEADER_SIZE, - Message#giop_message.byte_order); - ?GIOP_MSG_LOCATE_REPLY -> - dec_locate_reply(Message#giop_message.giop_version, - Message#giop_message.message, ?GIOP_HEADER_SIZE, - Message#giop_message.byte_order); - ?GIOP_MSG_CLOSE_CONNECTION -> - 'close_connection'; - ?GIOP_MSG_MESSAGE_ERROR -> - 'message_error'; - ?GIOP_MSG_FRAGMENT -> - dec_fragment_header(Message#giop_message.giop_version, - Message#giop_message.message, ?GIOP_HEADER_SIZE, - Message#giop_message.byte_order, Bytes) - end. - - -%%----------------------------------------------------------------- -%% Func: dec_byte_order/1 -%% Args: -%% The message as a byte sequence. -%% Returns: -%% A tuple {Endianness, Rest} where Endianness is big or little. -%% Rest is the remaining message byte sequence. -%%----------------------------------------------------------------- -dec_byte_order(<<0:8,T/binary>>) -> - {big, T}; -dec_byte_order(<<1:8,T/binary>>) -> - {little, T}. - -%%----------------------------------------------------------------- -%% Func: dec_byte_order_list/1 -%% Args: -%% The message as a byte sequence. -%% Returns: -%% A tuple {Endianness, Rest} where Endianness is big or little. -%% Rest is the remaining message byte sequence. -%%----------------------------------------------------------------- -dec_byte_order_list([0|T]) -> - {big, T}; -dec_byte_order_list([1|T]) -> - {little, T}. - -%%----------------------------------------------------------------- -%% Func : dec_response_flags -%% Args : -%% Returns : boolean -%%----------------------------------------------------------------- -%% FIX ME!! Not correct flag handling. -dec_response_flags(_Version, <<0:8, Rest/binary>>, Len) -> - {false, Rest, Len+1}; -dec_response_flags(_Version, <<1:8, Rest/binary>>, Len) -> - {true_oneway, Rest, Len+1}; -dec_response_flags(_Version, <<3:8, Rest/binary>>, Len) -> - {true, Rest, Len+1}; -dec_response_flags(_Version, <<X:8, Rest/binary>>, Len) -> - %% Not only the Response flag is set, test which. - if - %% Since the 6 most significant bits are unused we'll accept this for now. - ((X band 16#03) == 16#03) -> - {true, Rest, Len+1}; - ((X band 16#01) == 16#01) -> - {true_oneway, Rest, Len+1}; - true -> - {false, Rest, Len+1} - end. - -%%----------------------------------------------------------------- -%% Func : dec_target_addr -%% Args : Octet -%% Returns : boolean -%%----------------------------------------------------------------- -dec_target_addr(Version, Message, Len, ByteOrder, RequestId, Type) -> - case dec_type(?TARGETADDRESS, Version, Message, Len, ByteOrder, [], 0) of - {#'GIOP_TargetAddress'{label = ?GIOP_KeyAddr, value = KeyAddr}, Rest3, Len3, C} -> - {dec_target_key(KeyAddr, RequestId, Version, Type), Rest3, Len3, C}; - {#'GIOP_TargetAddress'{label = ?GIOP_ProfileAddr, - value = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, - profile_data=PA}}, - Rest3, Len3, C} -> - {dec_target_key(PA, RequestId, Version, Type), Rest3, Len3, C}; - {#'GIOP_TargetAddress'{label = ?GIOP_ReferenceAddr, - value = #'GIOP_IORAddressingInfo'{ - selected_profile_index = _PI, - ior = IOR}}, Rest3, Len3, C} -> - {dec_target_key(iop_ior:get_objkey(IOR), RequestId, Version, Type), - Rest3, Len3, C}; - Other -> - orber:dbg("[~p] cdr_decode:dec_target_addr(~p);~n" - "Unsupported TargetAddress.", [?LINE, Other], ?DEBUG_LEVEL), - corba:raise(#'MARSHAL'{minor=(?ORBER_VMCID bor 12), completion_status=?COMPLETED_MAYBE}) - end. - -%%----------------------------------------------------------------- -%% Func : dec_target_key -%% Args : Octet -%% Returns : boolean -%%----------------------------------------------------------------- -dec_target_key(Key, RequestId, Version, Type) -> - %% The Type argument is used as an identifier of which operation it is. - %% We need it to be able to tell the difference if it's, for example, - %% a request or locate-request. - case corba:string_to_objkey_local(Key) of - {location_forward, Object} -> - throw({Type, Object, RequestId, Version, Key}); - ObjRef -> - ObjRef - end. - -%%----------------------------------------------------------------- -%% Func: dec_request_header/3 -%% Args: -%% Message - The message -%% Len0 - Number of bytes already read. -%% ByteOrder - little or big -%% Returns: -%%----------------------------------------------------------------- -dec_request_header(Version, Message, Len0, ByteOrder, _Buffer) when Version == {1,2} -> - {Request_id, Rest1, Len1, _} = dec_type('tk_ulong', Version, Message, Len0, - ByteOrder, [], 0), - {ResponseFlags, Rest2, Len2} = dec_response_flags(Version, Rest1, Len1), - {_, Rest2b, Len2b, _} = dec_type({'tk_array', 'tk_octet', 3}, Version, Rest2, Len2, ByteOrder, [], 0), - {Object_key, Rest3, Len3, _} = dec_target_addr(Version, Rest2b, Len2b, ByteOrder, Request_id, - 'location_forward'), - {Operation, Rest4, Len4, _} = dec_type({'tk_string', 0}, Version, Rest3, Len3, ByteOrder, [], 0), - {Context, Rest5, Len5} = dec_service_context(Version, Rest4, Len4, ByteOrder), - {Version, #request_header{service_context=Context, - request_id=Request_id, - response_expected=ResponseFlags, - object_key=Object_key, - operation=list_to_atom(Operation), - requesting_principal=""}, Rest5, Len5, ByteOrder}; -dec_request_header(Version, Message, Len0, ByteOrder, _Buffer) -> - {Context, Rest1, Len1} = dec_service_context(Version, Message, Len0, ByteOrder), - {Request_id, Rest2, Len2, _} = dec_type('tk_ulong', Version, Rest1, Len1, ByteOrder, [], 0), - {Response_expected, Rest3, Len3, _} = dec_type('tk_boolean', Version, Rest2, Len2, - ByteOrder, [], 0), - {ObjKey, Rest4, Len4, _} = dec_type({'tk_sequence', 'tk_octet', 0}, Version, Rest3, - Len3, ByteOrder, [], 0), - Object_key = dec_target_key(ObjKey, Request_id, Version, 'location_forward'), - {Operation, Rest5, Len5, _} = dec_type({'tk_string', 0}, Version, Rest4, Len4, ByteOrder, [], 0), - {Principal, Rest, Len, _} = dec_type({'tk_string', 0}, Version, Rest5,Len5, ByteOrder, [], 0), - {Version, #request_header{service_context=Context, - request_id=Request_id, - response_expected=Response_expected, - object_key=Object_key, - operation=list_to_atom(Operation), - requesting_principal=Principal}, Rest, Len, ByteOrder}. - - -%%----------------------------------------------------------------- -%% Func: dec_service_context/4 -%% Args: Version - e.g. 1.2 -%% Message - The message -%% Len - Number of bytes already read. -%% ByteOrder - little or big -%% Returns: -%%----------------------------------------------------------------- -dec_service_context(Version, Message, Len, ByteOrder) -> - {Context, Rest, Len1} = dec_type(?IOP_SERVICECONTEXT, Version, Message, - Len, ByteOrder), - {dec_used_contexts(Version, Context, []), Rest, Len1}. - -dec_used_contexts(_Version, [], Ctxs) -> - Ctxs; -dec_used_contexts({1,0}, [#'IOP_ServiceContext'{context_id=?IOP_CodeSets}|T], Ctxs) -> - %% Not supported by 1.0, drop it. - dec_used_contexts({1,0}, T, Ctxs); -dec_used_contexts(Version, [#'IOP_ServiceContext'{context_id=?IOP_CodeSets, - context_data = Bytes}|T], Ctxs) -> - {ByteOrder, Rest} = dec_byte_order(list_to_binary(Bytes)), - {CodeCtx, _, _} = dec_type(?CONV_FRAME_CODESETCONTEXT, Version, - Rest, 1, ByteOrder), - dec_used_contexts(Version, T, - [#'IOP_ServiceContext'{context_id=?IOP_CodeSets, - context_data = CodeCtx}|Ctxs]); -dec_used_contexts(Version, [#'IOP_ServiceContext'{context_id=?IOP_BI_DIR_IIOP, - context_data = Bytes}|T], Ctxs) -> - {ByteOrder, Rest} = dec_byte_order(list_to_binary(Bytes)), - {BiDirCtx, _, _} = dec_type(?IIOP_BIDIRIIOPSERVICECONTEXT, Version, - Rest, 1, ByteOrder), - dec_used_contexts(Version, T, - [#'IOP_ServiceContext'{context_id=?IOP_BI_DIR_IIOP, - context_data = BiDirCtx}|Ctxs]); -dec_used_contexts(Version, [#'IOP_ServiceContext'{context_id=?IOP_FT_REQUEST, - context_data = Bytes}|T], Ctxs) -> - {ByteOrder, Rest} = dec_byte_order(list_to_binary(Bytes)), - {Ctx, _, _} = dec_type(?FT_FTRequestServiceContext, Version, - Rest, 1, ByteOrder), - dec_used_contexts(Version, T, - [#'IOP_ServiceContext'{context_id=?IOP_FT_REQUEST, - context_data = Ctx}|Ctxs]); -dec_used_contexts(Version, [#'IOP_ServiceContext'{context_id=?IOP_FT_GROUP_VERSION, - context_data = Bytes}|T], Ctxs) -> - {ByteOrder, Rest} = dec_byte_order(list_to_binary(Bytes)), - {Ctx, _, _} = dec_type(?FT_FTGroupVersionServiceContext, Version, - Rest, 1, ByteOrder), - dec_used_contexts(Version, T, - [#'IOP_ServiceContext'{context_id=?IOP_FT_GROUP_VERSION, - context_data = Ctx}|Ctxs]); -dec_used_contexts(Version, [#'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, - context_data = Bytes}|T], Ctxs) -> - {ByteOrder, Rest} = dec_byte_order(list_to_binary(Bytes)), - {Ctx, _, _} = dec_type(?CSI_SASContextBody, Version, - Rest, 1, ByteOrder), - dec_used_contexts(Version, T, - [#'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, - context_data = Ctx}|Ctxs]); -dec_used_contexts(Version, [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, - context_data = Bytes}|T], Ctxs) -> - {ByteOrder, Rest} = dec_byte_order(list_to_binary(Bytes)), - {Ctx, _, _} = dec_type(?ORBER_GENERIC_CTX, Version, - Rest, 1, ByteOrder), - dec_used_contexts(Version, T, - [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, - context_data = binary_to_term(list_to_binary(Ctx))}|Ctxs]); -dec_used_contexts(Version, [H|T], Ctxs) -> - dec_used_contexts(Version, T, [H|Ctxs]). - -%%----------------------------------------------------------------- -%% Func: dec_request_body -%% Args: Version - e.g. 1.2 -%% Returns: -%%----------------------------------------------------------------- -dec_request_body(Version, ReqHdr, Rest, Len, ByteOrder, Buffer) -> - {Parameters, TypeCodes, _} = - dec_request_body(Version, ReqHdr#request_header.object_key, - ReqHdr#request_header.operation, - Rest, Len, ByteOrder, Buffer, Len), - {Version, ReqHdr, Parameters, TypeCodes}. - -dec_request_body(Version, Object_key, Operation, Body, Len, ByteOrder, Buffer, Counter) - when Version == {1,2} -> - case orber_typedefs:get_op_def(Object_key, Operation) of - {RetType, [], OutParameters} -> - {[], {RetType, [], OutParameters}, Len}; - {RetType, InParameters, OutParameters} -> - {Rest, Len1, NewC} = dec_align(Body, Len, 8, Counter), - {Parameters, Len2} = dec_parameters(Version, InParameters, Rest, Len1, - ByteOrder, Buffer, NewC), - {Parameters, {RetType, InParameters, OutParameters}, Len2} - end; -dec_request_body(Version, Object_key, Operation, Body, Len, ByteOrder, Buffer, Counter) -> - {RetType, InParameters, OutParameters} = - orber_typedefs:get_op_def(Object_key, Operation), - {Parameters, Len1} = dec_parameters(Version, InParameters, Body, Len, ByteOrder, Buffer, Counter), - {Parameters, {RetType, InParameters, OutParameters}, Len1}. - -dec_parameters(_, [], _, Len, _, _, _) -> - {[], Len}; -dec_parameters(Version, [P1 |InParList], Body, Len, ByteOrder, Buffer, Counter) -> - {Object, Rest, Len1, NewCounter} = dec_type(P1, Version, Body, Len, ByteOrder, Buffer, Counter), - {List, Len2} = dec_parameters(Version, InParList, Rest, Len1, ByteOrder, Buffer, NewCounter), - {[Object | List], Len2}. - -%%----------------------------------------------------------------- -%% Func: dec_reply/5 -%% Args: -%% Message - The message -%% Len0 - Number of bytes already read. -%% ByteOrder - little or big -%% Returns: -%% A tuple {ReplyHeader, Result} where ReplyHeader is a -%% reply_header record and Result the decode result. -%%----------------------------------------------------------------- -dec_reply(Version, TypeCodes, Message, Len0, ByteOrder) -> - {ReplyHeader, Rest, Len} = dec_reply_header(Version, Message, Len0, ByteOrder), - {Result, Par} = - case ReplyHeader#reply_header.reply_status of - 'no_exception' -> - {R, P, _} = dec_reply_body(Version, TypeCodes, Rest, Len, ByteOrder, Message), - {R, P}; - 'system_exception' -> - {R, _} = dec_system_exception(Version, Rest, Len, ByteOrder), - {R, []}; - 'user_exception' -> - {R, _} = dec_user_exception(Version, Rest, Len, ByteOrder), - {R, []}; - 'location_forward' -> - {R, _, _} = dec_reply_body(Version, {{'tk_objref', "", ""}, [],[]}, - Rest, Len, ByteOrder, Message), - {R, []}; - %% This is deprecated in later version than CORBA-2.3.1. We'll leave it for - %% now. - 'location_forward_perm' -> - {R, _, _} = dec_reply_body(Version, {{'tk_objref', "", ""}, [],[]}, - Rest, Len, ByteOrder, Message), - {R, []}; - 'needs_addressing_mode' -> - {R, _, _} = dec_reply_body(Version, {'tk_short', [],[]}, - Rest, Len, ByteOrder, Message), - {R, []} - end, - {ReplyHeader, Result, Par}. - - -%% ## NEW IIOP 1.2 ## -dec_reply_header(Version, Message, Len0, ByteOrder) when Version == {1,2} -> - {Request_id, Rest1, Len1} = dec_type('tk_ulong', Version, Message, Len0, ByteOrder), - {ReplyStatus, Rest2, Len2} = dec_reply_status(Version, Rest1, Len1, ByteOrder), - {Context, Rest, Len3} = dec_service_context(Version, Rest2, Len2, ByteOrder), - {#reply_header{service_context=Context, request_id=Request_id, reply_status=ReplyStatus}, - Rest, Len3}; - -dec_reply_header(Version, Message, Len0, ByteOrder) -> - {Context, Rest1, Len1} = dec_service_context(Version, Message, Len0, ByteOrder), - {Request_id, Rest2, Len2} = dec_type('tk_ulong', Version, Rest1, Len1, ByteOrder), - {ReplyStatus, Rest, Len3} = dec_reply_status(Version, Rest2, Len2, ByteOrder), - {#reply_header{service_context=Context, request_id=Request_id, reply_status=ReplyStatus}, - Rest, Len3}. - -dec_reply_status(Version, Status, Len, ByteOrder) -> - {L, Rest, Len1}= dec_type('tk_ulong', Version, Status, Len, ByteOrder), - {dec_giop_reply_status_type(L), Rest, Len1}. - -dec_reply_body(_, {'tk_void', _, []}, <<>>, Len, _, _) -> - %% This case is mainly to be able to avoid removing non-existent alignment for - %% IIOP-1.2 messages if the body should be empty, i.e., void return value and - %% no out parameters. - {ok, [], Len}; -dec_reply_body(Version, {RetType, _InParameters, OutParameters}, Body, Len, - ByteOrder, Bytes) when Version == {1,2} -> - {Rest, Len1, Counter} = dec_align(Body, Len, 8, Len), - {Result, Rest2, Len2, C} = dec_type(RetType, Version, Rest, Len1, ByteOrder, Bytes, Counter), - {Par, Len3} = dec_parameters(Version, OutParameters, Rest2, Len2, ByteOrder, Bytes, C), - {Result, Par, Len3}; -dec_reply_body(Version, {RetType, _InParameters, OutParameters}, Body, Len, ByteOrder, Bytes) -> - {Result, Rest, Len1, C} = dec_type(RetType, Version, Body, Len, ByteOrder, Bytes, Len), - {Par, Len2} = dec_parameters(Version, OutParameters, Rest, Len1, ByteOrder, Bytes, C), - {Result, Par, Len2}. - - -%%----------------------------------------------------------------- -%% Func: dec_cancel_request/3 -%% Args: -%% Message - The message -%% Len - Number of bytes already read. -%% ByteOrder - little or big -%% Returns: -%% A cancel_request_header record. -%%----------------------------------------------------------------- -dec_cancel_request(Version, Message, Len, ByteOrder) -> - {Request_id, _, _} = dec_type('tk_ulong', Version, Message, Len, ByteOrder), - #cancel_request_header{request_id=Request_id}. - -%%----------------------------------------------------------------- -%% Func: dec_locate_request/3 -%% Args: -%% Message - The message -%% Len - Number of bytes already read. -%% ByteOrder - little or big -%% Returns: -%% A locate_request_header record. -%%----------------------------------------------------------------- -%% ## NEW IIOP 1.2 ## -dec_locate_request(Version, Message, Len, ByteOrder) when Version == {1,2} -> - {Request_id, Rest, Len1} = dec_type('tk_ulong', Version, Message, Len, ByteOrder), - {Object_key, _, _, _} = dec_target_addr(Version, Rest, Len1, ByteOrder, Request_id, - 'object_forward'), - {Version, #locate_request_header{request_id=Request_id, object_key=Object_key}}; -dec_locate_request(Version, Message, Len, ByteOrder) -> - {Request_id, Rest, Len1} = dec_type('tk_ulong', Version, Message, Len, ByteOrder), - {ObjKey, _, _} = dec_type({'tk_sequence', 'tk_octet', 0}, Version, Rest, - Len1, ByteOrder), - Object_key = dec_target_key(ObjKey, Request_id, Version, 'object_forward'), - {Version, #locate_request_header{request_id=Request_id, object_key=Object_key}}. - - -%%----------------------------------------------------------------- -%% Func: dec_locate_reply/3 -%% Args: -%% Message - The message -%% Len - Number of bytes already read. -%% ByteOrder - little or big -%% Returns: -%% A locate_reply_header record. -%%----------------------------------------------------------------- -dec_locate_reply(Version, Message, Len, ByteOrder) -> - {ReplyHeader, Rest1, Len1} = dec_locate_reply_header(Version, Message, Len, ByteOrder), - {ReplyHeader, dec_locate_reply_body(Version, ReplyHeader#locate_reply_header.locate_status, Rest1, - Len1, ByteOrder)}. - -dec_locate_reply_header(Version, Message, Len, ByteOrder) -> - {Request_id, Rest1, Len1} = dec_type('tk_ulong', Version, Message, Len, ByteOrder), - {Locate_status, Rest2, Len2} = dec_locate_status(Version, Rest1, Len1, ByteOrder), - {#locate_reply_header{request_id=Request_id, locate_status=Locate_status}, Rest2, Len2}. - -dec_locate_reply_body(Version, LocateStatus, Rest, Len, ByteOrder) when Version == {1,2} -> - %% In CORBA-2.3.1 the LocateReply body didn't align the body (8-octet - %% boundry) for IIOP-1.2. This have been changed in CORBA-2.4 and - %% changed back in CORBA-2.6. Hence, we should not change this. - case LocateStatus of - 'object_forward' -> - {ObjRef, _, _, _} = dec_objref(Version, Rest, Len, ByteOrder), - ObjRef; - 'object_forward_perm' -> - %% This is deprecated in later version than CORBA-2.3.1. We'll leave it for - %% now. - {ObjRef, _, _, _} = dec_objref(Version, Rest, Len, ByteOrder), - ObjRef; - 'loc_system_exception' -> - %% This should be updated but since 'dec_system_exception' removes - %% alignment, which the LocateReplyBody don't have, for 1.2 we - %% pretend it's 1.1 for now. - {SysExc, _} = dec_system_exception({1,1}, Rest, Len, ByteOrder), - corba:raise(SysExc); - 'loc_needs_addressing_mode' -> - %% Not supported. - []; - _ -> - [] - end; -dec_locate_reply_body(Version, LocateStatus, Rest, Len, ByteOrder) -> - case LocateStatus of - 'object_forward' -> - {ObjRef, _, _, _} = dec_objref(Version, Rest, Len, ByteOrder), - ObjRef; - _ -> - [] - end. - -dec_locate_status(Version, Bytes, Len, ByteOrder) -> - {L, Rest, Len1} = dec_type('tk_ulong', Version, Bytes, Len, ByteOrder), - {dec_giop_locate_status_type(L), Rest, Len1}. - - -%%----------------------------------------------------------------- -%% Func: dec_fragment_header/5 -%% Args: -%% Message - The message -%% Len0 - Number of bytes already read. -%% ByteOrder - little or big -%% Returns: -%%----------------------------------------------------------------- -dec_fragment_header(Version, Message, Len0, ByteOrder, _Buffer) when Version == {1,2} -> - {RequestId, Rest1, Len1, _} = dec_type('tk_ulong', Version, Message, Len0, - ByteOrder, [], 0), - {Version, #fragment_header{request_id=RequestId}, Rest1, Len1, ByteOrder}; -dec_fragment_header(Version, _Message, _Len0, _ByteOrder, _Buffer) -> - %% The FragmentHeader is IIOP-1.2 specific. Hence, do nothing here. - orber:dbg("[~p] cdr_decode:dec_fragment_header(~p)~n" - "Orber only supports fragmented messages for IIOP-1.2.", - [?LINE, Version], ?DEBUG_LEVEL), - exit(message_error). -% {Version, #fragment_header{}, Message, Len0, ByteOrder}. - -%%----------------------------------------------------------------- -%% Func: dec_giop_reply_status_type -%% Args: -%% An integer status code -%% Returns: -%% An atom which is the reply status -%%----------------------------------------------------------------- -dec_giop_reply_status_type(0) -> - 'no_exception'; -dec_giop_reply_status_type(1) -> - 'user_exception'; -dec_giop_reply_status_type(2) -> - 'system_exception'; -dec_giop_reply_status_type(3) -> - 'location_forward'; -%% ## IIOP-1.2 ## -dec_giop_reply_status_type(4) -> - 'location_forward_perm'; -dec_giop_reply_status_type(5) -> - 'needs_addressing_mode'. - -%%----------------------------------------------------------------- -%% Func: dec_giop_locate_status_type -%% Args: -%% An integer status code -%% Returns: -%% An atom which is the reply status -%%----------------------------------------------------------------- -dec_giop_locate_status_type(0) -> - 'unknown_object'; -dec_giop_locate_status_type(1) -> - 'object_here'; -dec_giop_locate_status_type(2) -> - 'object_forward'; -%% ## IIOP-1.2 ## -dec_giop_locate_status_type(3) -> - 'object_forward_perm'; -dec_giop_locate_status_type(4) -> - 'loc_system_exception'; -dec_giop_locate_status_type(5) -> - 'loc_needs_addressing_mode'. - - -%%----------------------------------------------------------------- -%% Func: dec_type/5 -%%----------------------------------------------------------------- -dec_type(Type, Version, Bytes, Len, ByteOrder) -> - {Val, Rest, Len2, _} = - dec_type(Type, Version, Bytes, Len, ByteOrder, [], 0), - {Val, Rest, Len2}. - -dec_type('tk_null', _Version, Bytes, Len, _, _, C) -> - {'null', Bytes, Len, C}; -dec_type('tk_void', _Version, Bytes, Len, _, _, C) -> - {'ok', Bytes, Len, C}; -dec_type('tk_short', _Version, Bytes, Len, ByteOrder, _, C) -> - {Rest, Len1, NewC} = dec_align(Bytes, Len, 2, C), - {Short, Rest1} = cdrlib:dec_short(ByteOrder, Rest), - {Short, Rest1, Len1 + 2, NewC+2}; -dec_type('tk_long', _Version, Bytes, Len, ByteOrder, _, C) -> - {Rest, Len1, NewC} = dec_align(Bytes, Len, 4, C), - {Long, Rest1} = cdrlib:dec_long(ByteOrder, Rest), - {Long, Rest1, Len1 + 4, NewC+4}; -dec_type('tk_longlong', _Version, Bytes, Len, ByteOrder, _, C) -> - {Rest, Len1, NewC} = dec_align(Bytes, Len, 8, C), - {Long, Rest1} = cdrlib:dec_longlong(ByteOrder, Rest), - {Long, Rest1, Len1 + 8, NewC+8}; -dec_type('tk_ushort', _Version, Bytes, Len, ByteOrder, _, C) -> - {Rest, Len1, NewC} = dec_align(Bytes, Len, 2, C), - {Short, Rest1} = cdrlib:dec_unsigned_short(ByteOrder, Rest), - {Short, Rest1, Len1 + 2, NewC+2}; -dec_type('tk_ulong', _Version, Bytes, Len, ByteOrder, _, C) -> - {Rest, Len1, NewC} = dec_align(Bytes, Len, 4, C), - {Long, Rest1} = cdrlib:dec_unsigned_long(ByteOrder, Rest), - {Long, Rest1, Len1 + 4, NewC+4}; -dec_type('tk_ulonglong', _Version, Bytes, Len, ByteOrder, _, C) -> - {Rest, Len1, NewC} = dec_align(Bytes, Len, 8, C), - {Long, Rest1} = cdrlib:dec_unsigned_longlong(ByteOrder, Rest), - {Long, Rest1, Len1 + 8, NewC+8}; -dec_type('tk_float', _Version, Bytes, Len, ByteOrder, _, C) -> - {Rest, Len1, NewC} = dec_align(Bytes, Len, 4, C), - {Float, Rest1} = cdrlib:dec_float(ByteOrder, Rest), - {Float, Rest1, Len1 + 4, NewC+4}; -dec_type('tk_double', _Version, Bytes, Len, ByteOrder, _, C) -> - {Rest, Len1, NewC} = dec_align(Bytes, Len, 8, C), - {Double, Rest1} = cdrlib:dec_double(ByteOrder, Rest), - {Double, Rest1, Len1 + 8, NewC+8}; -dec_type('tk_boolean', _Version, Bytes, Len, _, _, C) -> - {Bool, Rest} = cdrlib:dec_bool(Bytes), - {Bool, Rest, Len + 1, C+1}; -dec_type('tk_char', _Version, Bytes, Len, _, _, C) -> - {Char, Rest} = cdrlib:dec_char(Bytes), - {Char, Rest, Len + 1, C+1}; -dec_type('tk_wchar', {1,2}, Bytes, Len, _ByteOrder, _, C) -> - %% For IIOP-1.2 a wchar is almost encoded the same way as an octet-sequence. - %% The only difference is that the length-value is an octet as well. - case cdrlib:dec_octet(Bytes) of - {2, Rest1} -> - %% Currently we only allow 2-bytes wchar. - {WChar, Rest2} = cdrlib:dec_unsigned_short(big, Rest1), - {WChar, Rest2, Len+3, C+3}; - {What, _} -> - orber:dbg("[~p] cdr_decode:dec_type(~p); unsupported wchar", - [?LINE, What], ?DEBUG_LEVEL), - corba:raise(#'DATA_CONVERSION'{completion_status=?COMPLETED_NO}) - end; -%% For 1.1 the wchar is limited to the use of two-octet fixed-length encoding. -dec_type('tk_wchar', _Version, Bytes, Len, ByteOrder, _, C) -> - {Rest, Len1, NewC} = dec_align(Bytes, Len, 2, C), - {WChar, Rest2} = cdrlib:dec_unsigned_short(ByteOrder, Rest), - {WChar, Rest2, Len1 + 2, NewC+2}; -dec_type('tk_octet', _Version, Bytes, Len, _, _, C) -> - {Octet, Rest} = cdrlib:dec_octet(Bytes), - {Octet, Rest, Len + 1, C+1}; -dec_type('tk_any', Version, Bytes, Len, ByteOrder, Buff, C) -> - {TypeCode, Rest1, Len1, NewC} = dec_type('tk_TypeCode', Version, Bytes, Len, ByteOrder, Buff, C), - {Value, Rest2, Len2, NewC2} = dec_type(TypeCode, Version, Rest1, Len1, ByteOrder, Buff, NewC), - {#any{typecode=TypeCode, value=Value}, Rest2, Len2, NewC2}; -dec_type('tk_TypeCode', Version, Bytes, Len, ByteOrder, Buff, C) -> - dec_type_code(Version, Bytes, Len, ByteOrder, Buff, C); -dec_type('tk_Principal', Version, Bytes, Len, ByteOrder, Buff, C) -> - dec_sequence(Version, Bytes, 'tk_octet', Len, ByteOrder, Buff, C); -dec_type({'tk_objref', _IFRId, _Name}, Version, Bytes, Len, ByteOrder, Buff, C) -> - dec_objref(Version, Bytes, Len, ByteOrder, Buff, C); -dec_type({'tk_struct', IFRId, Name, ElementList}, Version, Bytes, Len, ByteOrder, Buff, C) -> - dec_struct(Version, IFRId, Name, ElementList, Bytes, Len, ByteOrder, Buff, C); -dec_type({'tk_union', IFRId, Name, DiscrTC, Default, ElementList}, - Version, Bytes, Len, ByteOrder, Buff, C) -> - dec_union(Version, IFRId, Name, DiscrTC, Default, ElementList, Bytes, Len, ByteOrder, Buff, C); -dec_type({'tk_enum', _IFRId, _Name, ElementList}, _Version, Bytes, Len, ByteOrder, _, C) -> - {Rest, Len1, NewC} = dec_align(Bytes, Len, 4, C), - {Enum, Rest1} = cdrlib:dec_enum(ByteOrder, ElementList, Rest), - {Enum, Rest1, Len1 + 4, NewC+4}; -dec_type({'tk_string', _MaxLength}, Version, Bytes, Len, ByteOrder, Buff, C) -> - dec_string(Version, Bytes, Len, ByteOrder, Buff, C); -dec_type({'tk_wstring', _MaxLength}, Version, Bytes, Len, ByteOrder, Buff, C) -> - dec_wstring(Version, Bytes, Len, ByteOrder, Buff, C); -dec_type({'tk_sequence', ElemTC, _MaxLength}, Version, Bytes, Len, ByteOrder, Buff, C) -> - dec_sequence(Version, Bytes, ElemTC, Len, ByteOrder, Buff, C); -dec_type({'tk_array', ElemTC, Size}, Version, Bytes, Len, ByteOrder, Buff, C) -> - dec_array(Version, Bytes, Size, ElemTC, Len, ByteOrder, Buff, C); -dec_type({'tk_alias', _IFRId, _Name, TC}, Version, Bytes, Len, ByteOrder, Buff, C) -> - dec_type(TC, Version, Bytes, Len, ByteOrder, Buff, C); -%dec_type({'tk_except', IFRId, Name, ElementList}, Version, Bytes, Len, ByteOrder) -> -dec_type({'tk_fixed', Digits, Scale}, _Version, Bytes, Len, _ByteOrder, _Buff, C) -> - dec_fixed(Digits, Scale, Bytes, Len, C); -dec_type(Type, _, _, _, _, _, _) -> - orber:dbg("[~p] cdr_decode:dec_type(~p)~n" - "Incorrect TypeCode or unsupported type.", - [?LINE, Type], ?DEBUG_LEVEL), - corba:raise(#'MARSHAL'{minor=(?ORBER_VMCID bor 13), completion_status=?COMPLETED_MAYBE}). - -stringify_enum({tk_enum,_,_,_}, Label) -> - atom_to_list(Label); -stringify_enum(_, Label) -> - Label. - -%%----------------------------------------------------------------- -%% Func: dec_fixed -%%----------------------------------------------------------------- -%% Digits eq. total number of digits. -%% Scale eq. position of the decimal point. -%% E.g. fixed<5,2> - "123.45" -%% E.g. fixed<4,2> - "12.34" -%% These are encoded as: -%% ## <5,2> ## ## <4,2> ## -%% 1,2 0,1 eq. 1 octet -%% 3,4 2,3 -%% 5,0xC 4,0xC -%% -%% Each number is encoded as a half-octet. Note, for <4,2> a zero is -%% added first to to be able to create "even" octets. -dec_fixed(0, 0, Bytes, Len, C) -> - {#fixed{digits = 0, scale = 0, value = ""}, Bytes, Len, C}; -dec_fixed(Digits, Scale, Bytes, Len, C) -> - case ?ODD(Digits) of - true -> - {Fixed, Bytes2, Len2, C2, Sign} = dec_fixed_2(Digits, Scale, Bytes, Len, C), - case Sign of - ?FIXED_POSITIVE -> - {#fixed{digits = Digits, scale = Scale, - value = list_to_integer(Fixed)}, Bytes2, Len2, C2}; - ?FIXED_NEGATIVE -> - {#fixed{digits = Digits, scale = Scale, - value = -list_to_integer(Fixed)}, Bytes2, Len2, C2} - end; - false -> - %% If the length (of fixed) is even a zero is added first. - %% Subtract that we've read 1 digit. - <<0:4,D2:4,T/binary>> = Bytes, - {Fixed, Bytes2, Len2, C2, Sign} = dec_fixed_2(Digits-1, Scale, T, Len+1, C+1), - case Sign of - ?FIXED_POSITIVE -> - {#fixed{digits = Digits, scale = Scale, - value = list_to_integer([D2+48|Fixed])}, Bytes2, Len2, C2}; - ?FIXED_NEGATIVE -> - {#fixed{digits = Digits, scale = Scale, - value = -list_to_integer([D2+48|Fixed])}, Bytes2, Len2, C2} - end - end. - -dec_fixed_2(1, _Scale, <<D1:4,?FIXED_POSITIVE:4,T/binary>>, Len, C) -> - {[D1+48], T, Len+1, C+1, ?FIXED_POSITIVE}; -dec_fixed_2(1, _Scale, <<D1:4,?FIXED_NEGATIVE:4,T/binary>>, Len, C) -> - {[D1+48], T, Len+1, C+1, ?FIXED_NEGATIVE}; -dec_fixed_2(Digits, Scale, _Bytes, _Len, _C) when Digits =< 0 -> - orber:dbg("[~p] cdr_decode:dec_fixed_2(~p, ~p)~n" - "Malformed fixed type.", [?LINE, Digits, Scale], ?DEBUG_LEVEL), - corba:raise(#'MARSHAL'{minor=(?ORBER_VMCID bor 14), completion_status=?COMPLETED_MAYBE}); -dec_fixed_2(Digits, Scale, <<>>, _Len, _C) -> - orber:dbg("[~p] cdr_decode:dec_fixed_2(~p, ~p)~n" - "The fixed type received was to short.", - [?LINE, Digits, Scale], ?DEBUG_LEVEL), - corba:raise(#'MARSHAL'{minor=(?ORBER_VMCID bor 14), completion_status=?COMPLETED_MAYBE}); -dec_fixed_2(Digits, Scale, <<D1:4,D2:4,T/binary>>, Len, C) -> - {Seq, Rest2, Len2, NewC2, Sign} = dec_fixed_2(Digits-2, Scale, T, Len+1, C+1), - {[D1+48, D2+48 | Seq], Rest2, Len2, NewC2, Sign}. - -%%----------------------------------------------------------------- -%% Func: dec_sequence/7 and dec_sequence/8 -%%----------------------------------------------------------------- -dec_sequence(_Version, Message, 'tk_octet', Len, ByteOrder, _Buff, C) -> - {Rest, Len1, NewC} = dec_align(Message, Len, 4, C), - {Size, Rest1} = cdrlib:dec_unsigned_long(ByteOrder, Rest), - <<OctetSeq:Size/binary, Rest2/binary>> = Rest1, - {binary_to_list(OctetSeq), Rest2, Len1+4+Size, NewC+4+Size}; -dec_sequence(_Version, Message, 'tk_char', Len, ByteOrder, _Buff, C) -> - {Rest, Len1, NewC} = dec_align(Message, Len, 4, C), - {Size, Rest1} = cdrlib:dec_unsigned_long(ByteOrder, Rest), - <<OctetSeq:Size/binary, Rest2/binary>> = Rest1, - {binary_to_list(OctetSeq), Rest2, Len1+4+Size, NewC+4+Size}; -%% We test if it's a sequence of struct's or unions. By doing this we only -%% have to look up the IFR-ID once instead of N times (N eq length of sequence). -dec_sequence(Version, Message, {'tk_struct', IFRId, ShortName, ElementList}, - Len, ByteOrder, Buff, C) when IFRId /= "", ShortName /= "" -> - {Rest, Len1, NewC} = dec_align(Message, Len, 4, C), - {Size, Rest1} = cdrlib:dec_unsigned_long(ByteOrder, Rest), - case IFRId of - ?SYSTEM_TYPE -> - dec_sequence_struct(Version, Rest1, Size, ElementList, Len1 + 4, - ByteOrder, Buff, NewC+4, ShortName); - _ -> - Name = ifrid_to_name(IFRId, ?IFR_StructDef), - dec_sequence_struct(Version, Rest1, Size, ElementList, Len1 + 4, - ByteOrder, Buff, NewC+4, Name) - end; -dec_sequence(Version, Message, - {'tk_union', ?SYSTEM_TYPE, TCName, DiscrTC, Default, ElementList}, - Len, ByteOrder, Buff, C) -> - {Rest, Len1, NewC} = dec_align(Message, Len, 4, C), - {Size, Rest1} = cdrlib:dec_unsigned_long(ByteOrder, Rest), - dec_sequence_union(Version, Rest1, Size, DiscrTC, Default, ElementList, Len1 + 4, - ByteOrder, Buff, NewC+4, TCName); -dec_sequence(Version, Message, - {'tk_union', IFRId, _TCName, DiscrTC, Default, ElementList}, - Len, ByteOrder, Buff, C) -> - {Rest, Len1, NewC} = dec_align(Message, Len, 4, C), - {Size, Rest1} = cdrlib:dec_unsigned_long(ByteOrder, Rest), - Name = ifrid_to_name(IFRId, ?IFR_UnionDef), - dec_sequence_union(Version, Rest1, Size, DiscrTC, Default, ElementList, Len1 + 4, - ByteOrder, Buff, NewC+4, Name); -dec_sequence(Version, Message, TypeCode, Len, ByteOrder, Buff, C) -> - {Rest, Len1, NewC} = dec_align(Message, Len, 4, C), - {Size, Rest1} = cdrlib:dec_unsigned_long(ByteOrder, Rest), - dec_sequence(Version, Rest1, Size, TypeCode, Len1 + 4, ByteOrder, Buff, NewC+4). - - -dec_sequence(_, Message, 0, _Type, Len, _ByteOrder, _Buff, C) -> - {[], Message, Len, C}; -dec_sequence(Version, Message, N, Type, Len, ByteOrder, Buff, C) -> - {Object, Rest1, Len1, NewC} = dec_type(Type, Version, Message, Len, ByteOrder, Buff, C), - {Seq, Rest2, Len2, NewC2} = dec_sequence(Version, Rest1, N - 1, Type, Len1, ByteOrder, Buff, NewC), - {[Object | Seq], Rest2, Len2, NewC2}. - -dec_sequence_struct(_, Message, 0, _Type, Len, _ByteOrder, _Buff, C, _Name) -> - {[], Message, Len, C}; -dec_sequence_struct(Version, Message, N, TypeCodeList, Len, ByteOrder, Buff, C, Name) -> - {Struct, Rest1, Len1, NewC} = dec_struct1(Version, TypeCodeList, Message, Len, ByteOrder, Buff, C), - {Seq, Rest2, Len2, NewC2} = dec_sequence_struct(Version, Rest1, N - 1, TypeCodeList, Len1, ByteOrder, - Buff, NewC, Name), - {[list_to_tuple([Name |Struct]) | Seq], Rest2, Len2, NewC2}. - - -dec_sequence_union(_, Message, 0, _DiscrTC, _Default, _ElementList, - Len, _ByteOrder, _Buff, C, _Name) -> - {[], Message, Len, C}; -dec_sequence_union(Version, Message, N, DiscrTC, Default, ElementList, - Len, ByteOrder, Buff, C, Name) when is_list(ElementList) -> - - {Label, Rest1, Len1, NewC} = dec_type(DiscrTC, Version, Message, Len, ByteOrder, Buff, C), - Result = dec_union(Version, stringify_enum(DiscrTC, Label), ElementList, Default, - Rest1, Len1, ByteOrder, Buff, NewC), - {Value, Rest2, Len2, NewC3} = case Result of - {default, R, L, NewC2} -> - dec_union(Version, default, ElementList, Default, - R, L, ByteOrder, Buff, NewC2); - X -> - X - end, - {Seq, Rest3, Len3, NewC4} = dec_sequence_union(Version, Rest2, N - 1, - DiscrTC, Default, ElementList, - Len2, ByteOrder, - Buff, NewC3, Name), - {[{Name, Label, Value} | Seq], Rest3, Len3, NewC4}; -dec_sequence_union(Version, Message, N, _DiscrTC, _Default, Module, - Len, ByteOrder, Buff, C, Name) when is_atom(Module) -> - case catch Module:tc() of - {tk_union, _, _, DiscrTC, Default, ElementList} -> - dec_sequence_union(Version, Message, N, DiscrTC, Default, ElementList, - Len, ByteOrder, Buff, C, Name); - What -> - orber:dbg("[~p] ~p:dec_sequence_union(~p). Union module doesn't exist or incorrect.", - [?LINE, ?MODULE, What], ?DEBUG_LEVEL), - corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE}) - end. - - - -%% A special case; when something is encapsulated (i.e. sent as octet-sequence) -%% we sometimes don not want the result to be converted to a list. -dec_octet_sequence_bin(_Version, Message, Len, ByteOrder, _Buff, C) -> - {Rest, Len1, NewC} = dec_align(Message, Len, 4, C), - {Size, Rest1} = cdrlib:dec_unsigned_long(ByteOrder, Rest), - <<OctetSeq:Size/binary, Rest2/binary>> = Rest1, - {OctetSeq, Rest2, Len1+4+Size, NewC+4+Size}. - -%%----------------------------------------------------------------- -%% Func: dec_array/5 -%%----------------------------------------------------------------- -dec_array(Version, Message, Size, TypeCode, Len, ByteOrder, Buff, C) -> - {Seq, Rest1, Len1, NewC} = dec_sequence(Version, Message, Size, TypeCode, Len, - ByteOrder, Buff, C), - {list_to_tuple(Seq), Rest1, Len1, NewC}. - - -%%----------------------------------------------------------------- -%% Func: dec_string/4 -%%----------------------------------------------------------------- -dec_string(_Version, Message, Len, ByteOrder, _Buff, C) -> - {Rest, Len1, NewC} = dec_align(Message, Len, 4, C), - {Size, Rest1} = cdrlib:dec_unsigned_long(ByteOrder, Rest), - if - Size > 0 -> - DataSize = Size-1, - <<String:DataSize/binary, _Null:1/binary, Rest2/binary>> = Rest1, - {binary_to_list(String), Rest2, Len1+4+Size, NewC+4+Size}; - true -> - {"", Rest1, Len1 + 4, NewC+4} - end. - -%%----------------------------------------------------------------- -%% Func: dec_string/4 -%%----------------------------------------------------------------- -dec_wstring({1,2}, Message, Len, ByteOrder, Buff, C) -> - {Rest, Len1, NewC} = dec_align(Message, Len, 4, C), - {Octets, Rest1} = cdrlib:dec_unsigned_long(ByteOrder, Rest), - if - Octets == 0 -> - {"", Rest1, Len1 + 4, NewC+4}; - Octets > 0 -> - Size = round(Octets/2), - {String, Rest2, Len2, NewC2} = - dec_sequence({1,2}, Rest1, Size, 'tk_ushort', - Len1 + 4, big, Buff, NewC+4), - {String, Rest2, Len2, NewC2}; - true -> - orber:dbg("[~p] cdr_decode:dec_wstring(~p);", - [?LINE, Rest1], ?DEBUG_LEVEL), - corba:raise(#'MARSHAL'{completion_status=?COMPLETED_NO}) - end; -dec_wstring(Version, Message, Len, ByteOrder, Buff, C) -> - {Rest, Len1, NewC} = dec_align(Message, Len, 4, C), - {Size, Rest1} = cdrlib:dec_unsigned_long(ByteOrder, Rest), - if - Size > 0 -> - {String, Rest2, Len2, NewC2} = dec_sequence(Version, Rest1, Size - 1, 'tk_wchar', - Len1 + 4, ByteOrder, Buff, NewC+4), - %% Remove the NULL character. - {_, Rest3} = cdrlib:dec_unsigned_short(ByteOrder, Rest2), - {String, Rest3, Len2 + 2, NewC2+2}; - Size == 0 -> - {"", Rest1, Len1 + 4, NewC+4}; - true -> - orber:dbg("[~p] cdr_decode:dec_wstring(~p);", - [?LINE, Rest1], ?DEBUG_LEVEL), - corba:raise(#'MARSHAL'{completion_status=?COMPLETED_NO}) - end. - - -%%----------------------------------------------------------------- -%% Func: dec_union/9 -%%----------------------------------------------------------------- -%% ## NEW IIOP 1.2 ## -dec_union(Version, ?SYSTEM_TYPE, Name, DiscrTC, Default, ElementList, Bytes, - Len, ByteOrder, Buff, C) -> - {Label, Rest1, Len1, NewC} = dec_type(DiscrTC, Version, Bytes, Len, ByteOrder, Buff, C), - {Value, Rest2, Len2, NewC3} = dec_union(Version, Label, ElementList, Default, - Rest1, Len1, ByteOrder, Buff, NewC), - {{Name, Label, Value}, Rest2, Len2, NewC3}; - - -dec_union(Version, IFRId, _, DiscrTC, Default, ElementList, Bytes, Len, - ByteOrder, Buff, C) when is_list(ElementList) -> - {Label, Rest1, Len1, NewC} = dec_type(DiscrTC, Version, Bytes, Len, ByteOrder, Buff, C), - Result = dec_union(Version, stringify_enum(DiscrTC, Label), ElementList, Default, - Rest1, Len1, ByteOrder, Buff, NewC), - {Value, Rest2, Len2, NewC3} = case Result of - {default, R, L, NewC2} -> - dec_union(Version, default, ElementList, Default, - R, L, ByteOrder, Buff, NewC2); - X -> - X - end, - Name = ifrid_to_name(IFRId, ?IFR_UnionDef), - {{Name, Label, Value}, Rest2, Len2, NewC3}; -dec_union(Version, IFRId, _, _DiscrTC, _Default, Module, Bytes, Len, - ByteOrder, Buff, C) when is_atom(Module) -> - case catch Module:tc() of - {tk_union, _, Name, DiscrTC, Default, ElementList} -> - dec_union(Version, IFRId, Name, DiscrTC, Default, ElementList, Bytes, Len, - ByteOrder, Buff, C); - What -> - orber:dbg("[~p] ~p:dec_union(~p). Union module doesn't exist or incorrect.", - [?LINE, ?MODULE, What], ?DEBUG_LEVEL), - corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE}) - end. - - - -dec_union(_, _, [], Default, Message, Len, _, _Buff, C) when Default < 0 -> - {undefined, Message, Len, C}; -dec_union(_, _, [], _Default, Message, Len, _, _Buff, C) -> - {default, Message, Len, C}; -dec_union(Version, Label, [{Label, _Name, Type}|_List], _Default, Message, Len, ByteOrder, Buff, C) -> - dec_type(Type, Version, Message, Len, ByteOrder, Buff, C); -dec_union(Version, Label, [_H|List], Default, Message, Len, ByteOrder, Buff, C) -> - dec_union(Version, Label, List, Default, Message, Len, ByteOrder, Buff, C). - -%%----------------------------------------------------------------- -%% Func: dec_struct/7 -%%----------------------------------------------------------------- -dec_struct(Version, "", "", TypeCodeList, Message, Len, ByteOrder, Buff, C) -> - {Struct, Rest, Len1, NewC} = dec_struct1(Version, TypeCodeList, Message, Len, ByteOrder, Buff, C), - {list_to_tuple(Struct), Rest, Len1, NewC}; -dec_struct(Version, [], Name, TypeCodeList, Message, Len, ByteOrder, Buff, C) -> - %% This case is used when communicating with ORB:s which don't supply the IFRId - %% field in struct type codes (used in any) - {Struct, Rest, Len1, NewC} = dec_struct1(Version, TypeCodeList, Message, Len, ByteOrder, Buff, C), - {list_to_tuple([list_to_atom(Name) |Struct]), Rest, Len1, NewC}; -dec_struct(Version, ?SYSTEM_TYPE, ShortName, TypeCodeList, Message, Len, ByteOrder, Buff, C) -> - {Struct, Rest, Len1, NewC} = dec_struct1(Version, TypeCodeList, Message, Len, ByteOrder, Buff, C), - {list_to_tuple([ShortName |Struct]), Rest, Len1, NewC}; -dec_struct(Version, IFRId, _ShortName, TypeCodeList, Message, Len, ByteOrder, Buff, C) -> - Name = ifrid_to_name(IFRId, ?IFR_StructDef), - {Struct, Rest, Len1, NewC} = dec_struct1(Version, TypeCodeList, Message, Len, ByteOrder, Buff, C), - {list_to_tuple([Name |Struct]), Rest, Len1, NewC}. - -dec_struct1(_, [], Message, Len, _ByteOrder, _, C) -> - {[], Message, Len, C}; -dec_struct1(Version, [{_ElemName, ElemType} | TypeCodeList], Message, Len, ByteOrder, Buff, C) -> - {Element, Rest, Len1, NewC} = dec_type(ElemType, Version, Message, Len, ByteOrder, Buff, C), - {Struct, Rest1, Len2, NewC2} = dec_struct1(Version, TypeCodeList, Rest, Len1, ByteOrder, Buff, NewC), - {[Element |Struct], Rest1, Len2, NewC2}; -dec_struct1(Version, Module, Message, Len, ByteOrder, Buff, C) -> - case catch Module:tc() of - {tk_struct, _, _, TypeCodeList} -> - dec_struct1(Version, TypeCodeList, Message, Len, ByteOrder, Buff, C); - What -> - orber:dbg("[~p] ~p:dec_struct1(~p). Struct module doesn't exist or incorrect.", - [?LINE, ?MODULE, What], ?DEBUG_LEVEL), - corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE}) - end. - -ifrid_to_name([], Type) -> - orber:dbg("[~p] ~p:ifrid_to_name([], ~p). No Id supplied.", - [?LINE, ?MODULE, Type], ?DEBUG_LEVEL), - corba:raise(#'MARSHAL'{minor=(?CORBA_OMGVMCID bor 11), - completion_status=?COMPLETED_MAYBE}); -ifrid_to_name(Id, Type) -> - case orber:light_ifr() of - true -> - orber_ifr:get_module(Id, Type); - false -> - case catch ifrid_to_name_helper(Id, Type) of - {'EXCEPTION', E} -> - corba:raise(E); - {'EXIT',{aborted,{no_exists,_}}} -> - case orber:get_lightweight_nodes() of - false -> - orber:dbg("[~p] cdr_decode:ifrid_to_name(~p, ~p). IFRid not found.", - [?LINE, Id, Type], ?DEBUG_LEVEL), - corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE}); - Nodes -> - L = length(Nodes), - IFR = get_ifr_node(Nodes, rand:uniform(L), L), - list_to_atom('OrberApp_IFR':get_absolute_name(IFR, Id)) - end; - {'EXIT', Other} -> - orber:dbg("[~p] cdr_decode:ifrid_to_name(~p). Unknown: ~p", - [?LINE, Id, Other], ?DEBUG_LEVEL), - corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE}); - Name -> - list_to_atom(Name) - end - end. - -ifrid_to_name_helper(Id, ?IFR_UnionDef) -> - case mnesia:dirty_index_read(ir_UnionDef, Id, #ir_UnionDef.id) of - [#ir_UnionDef{absolute_name = [$:,$:|N]}] -> - change_colons_to_underscore(N, []); - Other -> - orber:dbg("[~p] cdr_decode:ifrid_to_name(~p). IFR Id not found: ~p", - [?LINE, Id, Other], ?DEBUG_LEVEL), - corba:raise(#'MARSHAL'{minor=(?ORBER_VMCID bor 9), - completion_status=?COMPLETED_MAYBE}) - end; -ifrid_to_name_helper(Id, ?IFR_StructDef) -> - case mnesia:dirty_index_read(ir_StructDef, Id, #ir_StructDef.id) of - [#ir_StructDef{absolute_name = [$:,$:|N]}] -> - change_colons_to_underscore(N, []); - Other -> - orber:dbg("[~p] cdr_decode:ifrid_to_name(~p). IFR Id not found: ~p", - [?LINE, Id, Other], ?DEBUG_LEVEL), - corba:raise(#'MARSHAL'{minor=(?ORBER_VMCID bor 10), - completion_status=?COMPLETED_MAYBE}) - end; -ifrid_to_name_helper(Id, ?IFR_ExceptionDef) -> - case mnesia:dirty_index_read(ir_ExceptionDef, Id, #ir_ExceptionDef.id) of - [#ir_ExceptionDef{absolute_name = [$:,$:|N]}] -> - change_colons_to_underscore(N, []); - Other -> - orber:dbg("[~p] cdr_decode:ifrid_to_name(~p). IFR Id not found: ~p", - [?LINE, Id, Other], ?DEBUG_LEVEL), - corba:raise(#'UNKNOWN'{minor=(?CORBA_OMGVMCID bor 1), - completion_status=?COMPLETED_MAYBE}) - end. - -change_colons_to_underscore([$:, $: | T], Acc) -> - change_colons_to_underscore(T, [$_ |Acc]); -change_colons_to_underscore([H |T], Acc) -> - change_colons_to_underscore(T, [H |Acc]); -change_colons_to_underscore([], Acc) -> - lists:reverse(Acc). - -get_ifr_node([], _, _) -> - %% Were not able to contact any of the given nodes. - orber:dbg("[~p] cdr_decode:get_ifr_node([]). No Node available.", - [?LINE], ?DEBUG_LEVEL), - corba:raise(#'INTERNAL'{minor=(?ORBER_VMCID bor 1), completion_status=?COMPLETED_MAYBE}); -get_ifr_node(Nodes, N, L) -> - Node = lists:nth(N, Nodes), - case catch corba:resolve_initial_references_remote("OrberIFR", [Node]) of - IFR when is_record(IFR, 'IOP_IOR') -> - IFR; - _ -> - %% Not able to commincate with the node. Try next one. - NewL = L-1, - get_ifr_node(lists:delete(Node, Nodes), rand:uniform(NewL), NewL) - end. - - -%%----------------------------------------------------------------- -%% Func: dec_objref/4 -%%----------------------------------------------------------------- -dec_objref(Version, Message, Len, ByteOrder) -> - dec_objref(Version, Message, Len, ByteOrder, [], 0). -dec_objref(Version, Message, Len, ByteOrder, _Buff, C) -> - {IOR, Rest, Length} = iop_ior:decode(Version, Message, Len, ByteOrder), - {IOR, Rest, Length, C+Length-Len}. - -%%----------------------------------------------------------------- -%% Func: dec_system_exception/4 and dec_user_exception/4 -%%----------------------------------------------------------------- -dec_system_exception(Version, Message, Len, ByteOrder) when Version == {1,2} -> - {Rest0, Len0, _Counter} = dec_align(Message, Len, 8, Len), - {TypeId, Rest1, Len1} = dec_type({'tk_string', 0}, Version, Rest0, Len0, ByteOrder), - Name = orber_exceptions:get_name(TypeId, ?SYSTEM_EXCEPTION), - {Struct, _Rest2, Len2} = - dec_exception_1(Version, [{"minor",'tk_ulong'}, - {"completed", - {'tk_enum', "", "completion_status", - ["COMPLETED_YES", "COMPLETED_NO", - "COMPLETED_MAYBE"]}}], - Rest1, Len1, ByteOrder), - {list_to_tuple([Name, "" |Struct]), Len2}; -dec_system_exception(Version, Message, Len, ByteOrder) -> - {TypeId, Rest1, Len1} = dec_type({'tk_string', 0}, Version, Message, Len, ByteOrder), - Name = orber_exceptions:get_name(TypeId, ?SYSTEM_EXCEPTION), - {Struct, _Rest2, Len2} = - dec_exception_1(Version, [{"minor",'tk_ulong'}, - {"completed", - {'tk_enum', "", "completion_status", - ["COMPLETED_YES", "COMPLETED_NO", - "COMPLETED_MAYBE"]}}], - Rest1, Len1, ByteOrder), - {list_to_tuple([Name, "" |Struct]), Len2}. - -dec_user_exception(Version, Message, Len, ByteOrder) when Version == {1,2} -> - {Rest0, Len0, _Counter} = dec_align(Message, Len, 8, Len), - {TypeId, Rest1, Len1} = dec_type({'tk_string', 0}, Version, Rest0, Len0, ByteOrder), - Name = ifrid_to_name(TypeId, ?IFR_ExceptionDef), - {'tk_except', _, _, ElementList} = get_user_exception_type(TypeId), - {Struct, _Rest2, Len2} = dec_exception_1(Version, ElementList, Rest1, Len1, - ByteOrder), - {list_to_tuple([Name, TypeId |Struct]), Len2}; -dec_user_exception(Version, Message, Len, ByteOrder) -> - {TypeId, Rest1, Len1} = dec_type({'tk_string', 0}, Version, Message, Len, ByteOrder), - Name = ifrid_to_name(TypeId, ?IFR_ExceptionDef), - {'tk_except', _, _, ElementList} = get_user_exception_type(TypeId), - {Struct, _Rest2, Len2} = dec_exception_1(Version, ElementList, Rest1, Len1, - ByteOrder), - {list_to_tuple([Name, TypeId |Struct]), Len2}. - -dec_exception_1(_, [], Message, Len, _ByteOrder) -> - {[], Message, Len}; -dec_exception_1(Version, [{_ElemName, ElemType} | ElementList], Message, - Len, ByteOrder) -> - {Element, Rest, Len1} = dec_type(ElemType, Version, Message, Len, ByteOrder), - {Struct, Rest1, Len2} = dec_exception_1(Version, ElementList, Rest, Len1, - ByteOrder), - {[Element |Struct], Rest1, Len2}. - - -get_user_exception_type(TypeId) -> - case orber:light_ifr() of - true -> - orber_ifr:get_tc(TypeId, ?IFR_ExceptionDef); - false -> - case orber:get_lightweight_nodes() of - false -> - case mnesia:dirty_index_read(ir_ExceptionDef, TypeId, - #ir_ExceptionDef.id) of - [ExcDef] when is_record(ExcDef, ir_ExceptionDef) -> - ExcDef#ir_ExceptionDef.type; - Other -> - orber:dbg("[~p] cdr_decode:get_user_exception_type(~p). IFR Id not found: ~p", - [?LINE, TypeId, Other], ?DEBUG_LEVEL), - corba:raise(#'UNKNOWN'{minor=(?CORBA_OMGVMCID bor 1), - completion_status=?COMPLETED_MAYBE}) - end; - Nodes -> - L = length(Nodes), - IFR = get_ifr_node(Nodes, rand:uniform(L), L), - 'OrberApp_IFR':get_user_exception_type(IFR, TypeId) - end - end. - -%%----------------------------------------------------------------- -%% Func: dec_type_code/4 -%%----------------------------------------------------------------- -dec_type_code(Version, Message, Len, ByteOrder, Buff, C) -> - {TypeNo, Message1, Len1, NewC} = dec_type('tk_ulong', Version, Message, Len, ByteOrder, Buff, C), - TC = dec_type_code(TypeNo, Version, Message1, Len1, ByteOrder, Buff, NewC), - erase(orber_indirection), - TC. - -%%----------------------------------------------------------------- -%% Func: dec_type_code/5 -%%----------------------------------------------------------------- -dec_type_code(0, _, Message, Len, _, _, C) -> - {'tk_null', Message, Len, C}; -dec_type_code(1, _, Message, Len, _, _, C) -> - {'tk_void', Message, Len, C}; -dec_type_code(2, _, Message, Len, _, _, C) -> - {'tk_short', Message, Len, C}; -dec_type_code(3, _, Message, Len, _, _, C) -> - {'tk_long', Message, Len, C}; -dec_type_code(23, _, Message, Len, _, _, C) -> - {'tk_longlong', Message, Len, C}; -dec_type_code(25, _, Message, Len, _, _, C) -> - {'tk_longdouble', Message, Len, C}; -dec_type_code(4, _, Message, Len, _, _, C) -> - {'tk_ushort', Message, Len, C}; -dec_type_code(5, _, Message, Len, _, _, C) -> - {'tk_ulong', Message, Len, C}; -dec_type_code(24, _, Message, Len, _, _, C) -> - {'tk_ulonglong', Message, Len, C}; -dec_type_code(6, _, Message, Len, _, _, C) -> - {'tk_float', Message, Len, C}; -dec_type_code(7, _, Message, Len, _, _, C) -> - {'tk_double', Message, Len, C}; -dec_type_code(8, _, Message, Len, _, _, C) -> - {'tk_boolean', Message, Len, C}; -dec_type_code(9, _, Message, Len, _, _, C) -> - {'tk_char', Message, Len, C}; -dec_type_code(26, _, Message, Len, _, _, C) -> - {'tk_wchar', Message, Len, C}; -dec_type_code(10, _, Message, Len, _, _, C) -> - {'tk_octet', Message, Len, C}; -dec_type_code(11, _, Message, Len, _, _, C) -> - {'tk_any', Message, Len, C}; -dec_type_code(12, _, Message, Len, _, _, C) -> - {'tk_TypeCode', Message, Len, C}; -dec_type_code(13, _, Message, Len, _, _, C) -> - {'tk_Principal', Message, Len, C}; -dec_type_code(14, Version, Message, Len, ByteOrder, Buff, C) -> - {ComplexParams, Message1, Len1, Ex} = decode_complex_tc_parameters(Version, Message, Len, ByteOrder), - %% Decode marshalled parameters, eg get the byteorder first - {ByteOrder1, Rest1} = dec_byte_order(ComplexParams), - {{RepId, Name}, <<>>, _Len2, NewC} = - dec_type({'tk_struct', "", "", [{"repository ID", {'tk_string', 0}}, - {"name", {'tk_string', 0}}]}, - Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex), - {{'tk_objref', RepId, Name}, Message1, Len1, NewC}; -dec_type_code(15, Version, Message, Len, ByteOrder, Buff, C) -> - {ComplexParams, Message1, Len1, Ex} = decode_complex_tc_parameters(Version, Message, Len, ByteOrder), - %% Decode marshalled parameters, eg get the byteorder first - {ByteOrder1, Rest1} = dec_byte_order(ComplexParams), - {{RepId, Name, ElementList}, <<>>, _Len2, NewC} = - dec_type({'tk_struct', "", "", - [{"repository ID", {'tk_string', 0}}, - {"name", {'tk_string', 0}}, - {"element list", - {'tk_sequence', {'tk_struct', "","", - [{"member name", {'tk_string', 0}}, - {"member type", 'tk_TypeCode'}]}, - 0}}]}, - Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex), - {{'tk_struct', RepId, Name, ElementList}, Message1, Len1, NewC}; -dec_type_code(16, Version, Message, Len, ByteOrder, Buff, C) -> - {ComplexParams, Message1, Len1, Ex} = decode_complex_tc_parameters(Version, Message, Len, ByteOrder), - %% Decode marshalled parameters, eg get the byteorder first - {ByteOrder1, Rest1} = dec_byte_order(ComplexParams), - {{RepId, Name, DiscrTC, Default}, Rest2, RestLen2, NewC} = - dec_type({'tk_struct', "", "", - [{"repository ID", {'tk_string', 0}}, - {"name", {'tk_string', 0}}, - {"discriminant type", 'tk_TypeCode'}, - {"default used", 'tk_long'}]}, - Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex), - {ElementList, <<>>, _RestLen3, NewC2} = - dec_type({'tk_sequence', {'tk_struct', "","", - [{"label value", DiscrTC}, - {"member name", {'tk_string', 0}}, - {"member type", 'tk_TypeCode'}]}, 0}, - Version, Rest2, RestLen2, ByteOrder1, Buff, NewC), - NewElementList = - case check_enum(DiscrTC) of - true -> - lists:map(fun({L,N,T}) -> {atom_to_list(L),N,T} end, ElementList); - false -> - ElementList - end, - {{'tk_union', RepId, Name, DiscrTC, Default, NewElementList}, Message1, Len1, NewC2}; -dec_type_code(17, Version, Message, Len, ByteOrder, Buff, C) -> - {ComplexParams, Message1, Len1, Ex} = decode_complex_tc_parameters(Version, Message, Len, ByteOrder), - %% Decode marshalled parameters, eg get the byteorder first - {ByteOrder1, Rest1} = dec_byte_order(ComplexParams), - {{RepId, Name, ElementList}, <<>>, _Len2, NewC} = - dec_type({'tk_struct', "", "", - [{"repository ID", {'tk_string', 0}}, - {"name", {'tk_string', 0}}, - {"element list", - {'tk_sequence', {'tk_string', 0}, 0}}]}, - Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex), - {{'tk_enum', RepId, Name, ElementList}, Message1, Len1, NewC}; -dec_type_code(18, Version, Message, Len, ByteOrder, Buff, C) -> - {MaxLength, Message1, Len1, NewC} = - dec_type('tk_ulong', Version, Message, Len, ByteOrder, Buff, C), - {{'tk_string', MaxLength}, Message1, Len1, NewC}; -dec_type_code(19, Version, Message, Len, ByteOrder, Buff, C) -> - {ComplexParams, Message1, Len1, Ex} = decode_complex_tc_parameters(Version, Message, Len, ByteOrder), - %% Decode marshalled parameters, eg get the byteorder first - {ByteOrder1, Rest1} = dec_byte_order(ComplexParams), - {{ElemTC, MaxLength}, <<>>, _Len2, NewC} = - dec_type({'tk_struct', "", "", [{"element type", 'tk_TypeCode'}, - {"max length", 'tk_ulong'}]}, - Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex), - {{'tk_sequence', ElemTC, MaxLength}, Message1, Len1, NewC}; -dec_type_code(20, Version, Message, Len, ByteOrder, Buff, C) -> - {ComplexParams, Message1, Len1, Ex} = decode_complex_tc_parameters(Version, Message, Len, ByteOrder), - %% Decode marshalled parameters, eg get the byteorder first - {ByteOrder1, Rest1} = dec_byte_order(ComplexParams), - {{ElemTC, Length}, <<>>, _Len2, NewC} = - dec_type({'tk_struct', "", "", [{"element type", 'tk_TypeCode'}, - {"length", 'tk_ulong'}]}, - Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex), - {{'tk_array', ElemTC, Length}, Message1, Len1, NewC}; -dec_type_code(21, Version, Message, Len, ByteOrder, Buff, C) -> - {ComplexParams, Message1, Len1, Ex} = decode_complex_tc_parameters(Version, Message, Len, ByteOrder), - %% Decode marshalled parameters, eg ge a byteorder first - {ByteOrder1, Rest1} = dec_byte_order(ComplexParams), - {{RepId, Name, TC}, <<>>, _Len2, NewC} = - dec_type({'tk_struct', "", "", [{"repository ID", {'tk_string', 0}}, - {"name", {'tk_string', 0}}, - {"TypeCode", 'tk_TypeCode'}]}, - Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex), - {{'tk_alias', RepId, Name, TC}, Message1, Len1, NewC}; -dec_type_code(22, Version, Message, Len, ByteOrder, Buff, C) -> - {ComplexParams, Message1, Len1, Ex} = decode_complex_tc_parameters(Version, Message, Len, ByteOrder), - %% Decode marshalled parameters, eg get the byteorder first - {ByteOrder1, Rest1} = dec_byte_order(ComplexParams), - {{RepId, Name, ElementList}, <<>>, _Len2, NewC} = - dec_type({'tk_struct', "", "", - [{"repository ID", {'tk_string', 0}}, - {"name", {'tk_string', 0}}, - {"element list", - {'tk_sequence', {'tk_struct', "","", - [{"member name", {'tk_string', 0}}, - {"member type", 'tk_TypeCode'}]}, - 0}}]}, - Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex), - {{'tk_except', RepId, Name, ElementList}, Message1, Len1, NewC}; -dec_type_code(27, Version, Message, Len, ByteOrder, Buff, C) -> - {MaxLength, Message1, Len1, NewC} = - dec_type('tk_ulong', Version, Message, Len, ByteOrder, Buff, C), - {{'tk_wstring', MaxLength}, Message1, Len1, NewC}; -dec_type_code(28, Version, Message, Len, ByteOrder, Buff, C) -> - {Digits, Message1, Len1, C1} = - dec_type('tk_ushort', Version, Message, Len, ByteOrder, Buff, C), - {Scale, Message2, Len2, C2} = - dec_type('tk_short', Version, Message1, Len1, ByteOrder, Buff, C1), - {{'tk_fixed', Digits, Scale}, Message2, Len2, C2}; -dec_type_code(29, Version, Message, Len, ByteOrder, Buff, C) -> - {ComplexParams, Message1, Len1, Ex} = decode_complex_tc_parameters(Version, Message, Len, ByteOrder), - {ByteOrder1, Rest1} = dec_byte_order(ComplexParams), - {{RepId, Name, ValueModifier, TC, ElementList}, <<>>, _Len2, NewC} = - dec_type({'tk_struct', "", "", [{"repository ID", {'tk_string', 0}}, - {"name", {'tk_string', 0}}, - {"ValueModifier", 'tk_short'}, - {"TypeCode", 'tk_TypeCode'}, - {"element list", - {'tk_sequence', - {'tk_struct', "","", - [{"member name", {'tk_string', 0}}, - {"member type", 'tk_TypeCode'}, - {"Visibility", 'tk_short'}]}, - 0}}]}, - Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex), - {{'tk_value', RepId, Name, ValueModifier, TC, ElementList}, Message1, Len1, NewC}; -dec_type_code(30, Version, Message, Len, ByteOrder, Buff, C) -> - {ComplexParams, Message1, Len1, Ex} = decode_complex_tc_parameters(Version, Message, Len, ByteOrder), - {ByteOrder1, Rest1} = dec_byte_order(ComplexParams), - {{RepId, Name, TC}, <<>>, _Len2, NewC} = - dec_type({'tk_struct', "", "", [{"repository ID", {'tk_string', 0}}, - {"name", {'tk_string', 0}}, - {"TypeCode", 'tk_TypeCode'}]}, - Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex), - {{'tk_value_box', RepId, Name, TC}, Message1, Len1, NewC}; -dec_type_code(31, Version, Message, Len, ByteOrder, Buff, C) -> - {ComplexParams, Message1, Len1, Ex} = decode_complex_tc_parameters(Version, Message, Len, ByteOrder), - {ByteOrder1, Rest1} = dec_byte_order(ComplexParams), - {{RepId, Name}, <<>>, _Len2, NewC} = - dec_type({'tk_struct', "", "", [{"repository ID", {'tk_string', 0}}, - {"name", {'tk_string', 0}}]}, - Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex), - {{'tk_native', RepId, Name}, Message1, Len1, NewC}; -dec_type_code(32, Version, Message, Len, ByteOrder, Buff, C) -> - {ComplexParams, Message1, Len1, Ex} = decode_complex_tc_parameters(Version, Message, Len, ByteOrder), - {ByteOrder1, Rest1} = dec_byte_order(ComplexParams), - {{RepId, Name}, <<>>, _Len2, NewC} = - dec_type({'tk_struct', "", "", [{"RepositoryId", {'tk_string', 0}}, - {"name", {'tk_string', 0}}]}, - Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex), - {{'tk_abstract_interface', RepId, Name}, Message1, Len1, NewC}; -dec_type_code(33, Version, Message, Len, ByteOrder, Buff, C) -> - {ComplexParams, Message1, Len1, Ex} = decode_complex_tc_parameters(Version, Message, Len, ByteOrder), - {ByteOrder1, Rest1} = dec_byte_order(ComplexParams), - {{RepId, Name}, <<>>, _Len2, NewC} = - dec_type({'tk_struct', "", "", [{"RepositoryId", {'tk_string', 0}}, - {"name", {'tk_string', 0}}]}, - Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex), - {{'tk_local_interface', RepId, Name}, Message1, Len1, NewC}; -dec_type_code(16#ffffffff, Version, Message, Len, ByteOrder, Buff, C) -> - {Indirection, Message1, Len1, NewC} = - dec_type('tk_long', Version, Message, Len, ByteOrder, Buff, C), - Position = C+Indirection, - case put(orber_indirection, Position) of - Position -> -%% {{'none', Indirection}, Message1, Len1, NewC}; - %% Recursive TypeCode. Break the loop. - orber:dbg("[~p] cdr_decode:dec_type_code(~p); Recursive TC not supported.", - [?LINE,Position], ?DEBUG_LEVEL), - corba:raise(#'MARSHAL'{completion_status=?COMPLETED_NO}); - _ -> - <<_:Position/binary, SubBuff/binary>> = Buff, - {TC, _, _, _} = dec_type_code(Version, SubBuff, Position, ByteOrder, Buff, Position), - {TC, Message1, Len1, NewC} - end; -dec_type_code(Type, _, _, _, _, _, _) -> - orber:dbg("[~p] cdr_decode:dec_type_code(~p); No match.", - [?LINE, Type], ?DEBUG_LEVEL), - corba:raise(#'MARSHAL'{minor=(?ORBER_VMCID bor 8), completion_status=?COMPLETED_MAYBE}). - -check_enum({'tk_enum', _, _, _}) -> - true; -check_enum(_) -> - false. - - -decode_complex_tc_parameters(_Version, Message, Len, ByteOrder) -> - {Rest, Len1, NewC} = dec_align(Message, Len, 4, 0), - {Size, Rest1} = cdrlib:dec_unsigned_long(ByteOrder, Rest), - <<OctetSeq:Size/binary, Rest2/binary>> = Rest1, - {OctetSeq, Rest2, Len1+4+Size, NewC+4}. - -%%----------------------------------------------------------------- -%% Func: dec_align/3 -%% Args: -%% R - The byte sequence that shall be aligned. -%% Len - The number of bytes read so far. -%% Alignment - The alignment as an integer (for example: 2,4,8). -%% Returns: -%% An aligned byte sequence. -%%----------------------------------------------------------------- -dec_align(R, Len, Alignment, C) -> - Rem = Len rem Alignment, - if Rem == 0 -> - {R, Len, C}; - true -> - Diff = Alignment - Rem, - <<_:Diff/binary,Rest/binary>> = R, - {Rest, Len + Diff, C + Diff} - end. - -%%---------------- EOF MODULE ---------------------------------------- |