1%%-------------------------------------------------------------------- 2%% 3%% %CopyrightBegin% 4%% 5%% Copyright Ericsson AB 1997-2015. All Rights Reserved. 6%% 7%% Licensed under the Apache License, Version 2.0 (the "License"); 8%% you may not use this file except in compliance with the License. 9%% You may obtain a copy of the License at 10%% 11%% http://www.apache.org/licenses/LICENSE-2.0 12%% 13%% Unless required by applicable law or agreed to in writing, software 14%% distributed under the License is distributed on an "AS IS" BASIS, 15%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16%% See the License for the specific language governing permissions and 17%% limitations under the License. 18%% 19%% %CopyrightEnd% 20%% 21%% 22%%----------------------------------------------------------------- 23%% File: cdr_decode.erl 24%% 25%% Description: 26%% This file contains all decoding functions for the CDR 27%% format. 28%% 29%%----------------------------------------------------------------- 30-module(cdr_decode). 31 32-include_lib("orber/src/orber_iiop.hrl"). 33-include_lib("orber/include/ifr_types.hrl"). 34-include_lib("orber/include/corba.hrl"). 35 36-include_lib("orber/src/ifr_objects.hrl"). 37 38%%----------------------------------------------------------------- 39%% External exports 40%%----------------------------------------------------------------- 41-export([dec_giop_message_header/1, dec_reply_header/4, 42 dec_reply_body/6, dec_locate_reply_header/4, 43 dec_locate_reply_body/5, dec_message_header/3, dec_request_body/6, 44 dec_octet_sequence_bin/6, dec_message/2, peek_request_id/2]). 45 46%%----------------------------------------------------------------- 47%% Functions which only are exported for the testcases. 48%%----------------------------------------------------------------- 49-export([dec_type/5, dec_byte_order/1, dec_system_exception/4, dec_user_exception/4, 50 dec_byte_order_list/1]). 51 52%%----------------------------------------------------------------- 53%% Internal exports 54%%----------------------------------------------------------------- 55 56%%----------------------------------------------------------------- 57%% Macros 58%%----------------------------------------------------------------- 59-define(DEBUG_LEVEL, 9). 60 61-define(ODD(N), (N rem 2) == 1). 62 63%%----------------------------------------------------------------- 64%% Func: dec_message/3 65%% Args: 66%% TypeCodes - is the type_codes of the return value and out parameters 67%% when one decodes a reply. 68%% Bytes - is the the message as a byte sequence. 69%% Returns: 70%% A tupple which contains the decoded message, 71%% {ok, Header, Parameters, TypeCodes}. 72%%----------------------------------------------------------------- 73dec_message(TypeCodes, Bytes) -> 74 Message = dec_giop_message_header(Bytes), 75 case Message#giop_message.message_type of 76 ?GIOP_MSG_REQUEST -> 77 {Version, ReqHdr, Rest, Len, ByteOrder} = 78 dec_request_header(Message#giop_message.giop_version, 79 Message#giop_message.message, ?GIOP_HEADER_SIZE, 80 Message#giop_message.byte_order, Bytes), 81 dec_request_body(Version, ReqHdr, Rest, Len, ByteOrder, Bytes); 82 ?GIOP_MSG_REPLY -> 83 dec_reply(Message#giop_message.giop_version, 84 TypeCodes, Message#giop_message.message, ?GIOP_HEADER_SIZE, 85 Message#giop_message.byte_order); 86 ?GIOP_MSG_CANCEL_REQUEST -> 87 dec_cancel_request(Message#giop_message.giop_version, 88 Message#giop_message.message, ?GIOP_HEADER_SIZE, 89 Message#giop_message.byte_order); 90 ?GIOP_MSG_LOCATE_REQUEST -> 91 dec_locate_request(Message#giop_message.giop_version, 92 Message#giop_message.message, ?GIOP_HEADER_SIZE, 93 Message#giop_message.byte_order); 94 ?GIOP_MSG_LOCATE_REPLY -> 95 dec_locate_reply(Message#giop_message.giop_version, 96 Message#giop_message.message, ?GIOP_HEADER_SIZE, 97 Message#giop_message.byte_order); 98 ?GIOP_MSG_CLOSE_CONNECTION -> 99 'close_connection'; 100 ?GIOP_MSG_MESSAGE_ERROR -> 101 'message_error'; 102 ?GIOP_MSG_FRAGMENT -> 103 dec_fragment_header(Message#giop_message.giop_version, 104 Message#giop_message.message, ?GIOP_HEADER_SIZE, 105 Message#giop_message.byte_order, Bytes) 106 end. 107 108%%----------------------------------------------------------------- 109%% Func: dec_giop_message_header/1 110%% Args: 111%% Bytes - is the the message as a byte sequence. 112%% Returns: 113%% A giop_message record. 114%%----------------------------------------------------------------- 115%% Magic|Version|BO| Type | Size | Body 116dec_giop_message_header(<<"GIOP",1:8,0:8,1:8,MessType:8, 117 MessSize:32/little-unsigned-integer,Message/binary>>) -> 118 #giop_message{magic = "GIOP", giop_version = {1,0}, 119 byte_order = little, message_type = MessType, 120 message_size = MessSize, message = Message}; 121dec_giop_message_header(<<"GIOP",1:8,0:8,0:8,MessType:8, 122 MessSize:32/big-unsigned-integer,Message/binary>>) -> 123 #giop_message{magic = "GIOP", giop_version = {1,0}, 124 byte_order = big, message_type = MessType, 125 message_size = MessSize, message = Message}; 126dec_giop_message_header(<<"GIOP",1:8,Minor:8,Flags:8,MessType:8, 127 MessSize:32/little-unsigned-integer,Message/binary>>) when 128 ((Flags band 16#01) == 16#01) -> 129 #giop_message{magic = "GIOP", giop_version = {1,Minor}, 130 byte_order = little, fragments = ((Flags band 16#02) == 16#02), 131 message_type = MessType, message_size = MessSize, message = Message}; 132dec_giop_message_header(<<"GIOP",1:8,Minor:8,Flags:8,MessType:8, 133 MessSize:32/big-unsigned-integer,Message/binary>>) -> 134 #giop_message{magic = "GIOP", giop_version = {1,Minor}, 135 byte_order = big, fragments = ((Flags band 16#02) == 16#02), 136 message_type = MessType, message_size = MessSize, message = Message}; 137dec_giop_message_header(<<Hdr:?GIOP_HEADER_SIZE/binary, _Body/binary>>) -> 138 orber:dbg("[~p] cdr_decode:dec_giop_message_header(~p);~n" 139 "Orber cannot decode the GIOP-header.", [?LINE, Hdr], ?DEBUG_LEVEL), 140 exit(message_error); 141dec_giop_message_header(Other) -> 142 orber:dbg("[~p] cdr_decode:dec_giop_message_header(~p);~n" 143 "Orber cannot decode the GIOP-header.", [?LINE, Other], ?DEBUG_LEVEL), 144 exit(message_error). 145 146 147peek_request_id(big, <<ReqId:32/big-unsigned-integer,_/binary>>) -> 148 ReqId; 149peek_request_id(little, <<ReqId:32/little-unsigned-integer,_/binary>>) -> 150 ReqId. 151 152%%----------------------------------------------------------------- 153%% Func: dec_message_header/2 154%% Args: 155%% Header - #giop_message{} 156%% Bytes - is the the message body as a byte sequence. 157%% Returns: 158%%----------------------------------------------------------------- 159dec_message_header(TypeCodes, Message, Bytes) -> 160 case Message#giop_message.message_type of 161 ?GIOP_MSG_REQUEST -> 162 dec_request_header(Message#giop_message.giop_version, 163 Message#giop_message.message, ?GIOP_HEADER_SIZE, 164 Message#giop_message.byte_order, Bytes); 165 ?GIOP_MSG_REPLY -> 166 dec_reply(Message#giop_message.giop_version, 167 TypeCodes, Message#giop_message.message, ?GIOP_HEADER_SIZE, 168 Message#giop_message.byte_order); 169 ?GIOP_MSG_CANCEL_REQUEST -> 170 dec_cancel_request(Message#giop_message.giop_version, 171 Message#giop_message.message, ?GIOP_HEADER_SIZE, 172 Message#giop_message.byte_order); 173 ?GIOP_MSG_LOCATE_REQUEST -> 174 dec_locate_request(Message#giop_message.giop_version, 175 Message#giop_message.message, ?GIOP_HEADER_SIZE, 176 Message#giop_message.byte_order); 177 ?GIOP_MSG_LOCATE_REPLY -> 178 dec_locate_reply(Message#giop_message.giop_version, 179 Message#giop_message.message, ?GIOP_HEADER_SIZE, 180 Message#giop_message.byte_order); 181 ?GIOP_MSG_CLOSE_CONNECTION -> 182 'close_connection'; 183 ?GIOP_MSG_MESSAGE_ERROR -> 184 'message_error'; 185 ?GIOP_MSG_FRAGMENT -> 186 dec_fragment_header(Message#giop_message.giop_version, 187 Message#giop_message.message, ?GIOP_HEADER_SIZE, 188 Message#giop_message.byte_order, Bytes) 189 end. 190 191 192%%----------------------------------------------------------------- 193%% Func: dec_byte_order/1 194%% Args: 195%% The message as a byte sequence. 196%% Returns: 197%% A tuple {Endianness, Rest} where Endianness is big or little. 198%% Rest is the remaining message byte sequence. 199%%----------------------------------------------------------------- 200dec_byte_order(<<0:8,T/binary>>) -> 201 {big, T}; 202dec_byte_order(<<1:8,T/binary>>) -> 203 {little, T}. 204 205%%----------------------------------------------------------------- 206%% Func: dec_byte_order_list/1 207%% Args: 208%% The message as a byte sequence. 209%% Returns: 210%% A tuple {Endianness, Rest} where Endianness is big or little. 211%% Rest is the remaining message byte sequence. 212%%----------------------------------------------------------------- 213dec_byte_order_list([0|T]) -> 214 {big, T}; 215dec_byte_order_list([1|T]) -> 216 {little, T}. 217 218%%----------------------------------------------------------------- 219%% Func : dec_response_flags 220%% Args : 221%% Returns : boolean 222%%----------------------------------------------------------------- 223%% FIX ME!! Not correct flag handling. 224dec_response_flags(_Version, <<0:8, Rest/binary>>, Len) -> 225 {false, Rest, Len+1}; 226dec_response_flags(_Version, <<1:8, Rest/binary>>, Len) -> 227 {true_oneway, Rest, Len+1}; 228dec_response_flags(_Version, <<3:8, Rest/binary>>, Len) -> 229 {true, Rest, Len+1}; 230dec_response_flags(_Version, <<X:8, Rest/binary>>, Len) -> 231 %% Not only the Response flag is set, test which. 232 if 233 %% Since the 6 most significant bits are unused we'll accept this for now. 234 ((X band 16#03) == 16#03) -> 235 {true, Rest, Len+1}; 236 ((X band 16#01) == 16#01) -> 237 {true_oneway, Rest, Len+1}; 238 true -> 239 {false, Rest, Len+1} 240 end. 241 242%%----------------------------------------------------------------- 243%% Func : dec_target_addr 244%% Args : Octet 245%% Returns : boolean 246%%----------------------------------------------------------------- 247dec_target_addr(Version, Message, Len, ByteOrder, RequestId, Type) -> 248 case dec_type(?TARGETADDRESS, Version, Message, Len, ByteOrder, [], 0) of 249 {#'GIOP_TargetAddress'{label = ?GIOP_KeyAddr, value = KeyAddr}, Rest3, Len3, C} -> 250 {dec_target_key(KeyAddr, RequestId, Version, Type), Rest3, Len3, C}; 251 {#'GIOP_TargetAddress'{label = ?GIOP_ProfileAddr, 252 value = #'IOP_TaggedProfile'{tag=?TAG_INTERNET_IOP, 253 profile_data=PA}}, 254 Rest3, Len3, C} -> 255 {dec_target_key(PA, RequestId, Version, Type), Rest3, Len3, C}; 256 {#'GIOP_TargetAddress'{label = ?GIOP_ReferenceAddr, 257 value = #'GIOP_IORAddressingInfo'{ 258 selected_profile_index = _PI, 259 ior = IOR}}, Rest3, Len3, C} -> 260 {dec_target_key(iop_ior:get_objkey(IOR), RequestId, Version, Type), 261 Rest3, Len3, C}; 262 Other -> 263 orber:dbg("[~p] cdr_decode:dec_target_addr(~p);~n" 264 "Unsupported TargetAddress.", [?LINE, Other], ?DEBUG_LEVEL), 265 corba:raise(#'MARSHAL'{minor=(?ORBER_VMCID bor 12), completion_status=?COMPLETED_MAYBE}) 266 end. 267 268%%----------------------------------------------------------------- 269%% Func : dec_target_key 270%% Args : Octet 271%% Returns : boolean 272%%----------------------------------------------------------------- 273dec_target_key(Key, RequestId, Version, Type) -> 274 %% The Type argument is used as an identifier of which operation it is. 275 %% We need it to be able to tell the difference if it's, for example, 276 %% a request or locate-request. 277 case corba:string_to_objkey_local(Key) of 278 {location_forward, Object} -> 279 throw({Type, Object, RequestId, Version, Key}); 280 ObjRef -> 281 ObjRef 282 end. 283 284%%----------------------------------------------------------------- 285%% Func: dec_request_header/3 286%% Args: 287%% Message - The message 288%% Len0 - Number of bytes already read. 289%% ByteOrder - little or big 290%% Returns: 291%%----------------------------------------------------------------- 292dec_request_header(Version, Message, Len0, ByteOrder, _Buffer) when Version == {1,2} -> 293 {Request_id, Rest1, Len1, _} = dec_type('tk_ulong', Version, Message, Len0, 294 ByteOrder, [], 0), 295 {ResponseFlags, Rest2, Len2} = dec_response_flags(Version, Rest1, Len1), 296 {_, Rest2b, Len2b, _} = dec_type({'tk_array', 'tk_octet', 3}, Version, Rest2, Len2, ByteOrder, [], 0), 297 {Object_key, Rest3, Len3, _} = dec_target_addr(Version, Rest2b, Len2b, ByteOrder, Request_id, 298 'location_forward'), 299 {Operation, Rest4, Len4, _} = dec_type({'tk_string', 0}, Version, Rest3, Len3, ByteOrder, [], 0), 300 {Context, Rest5, Len5} = dec_service_context(Version, Rest4, Len4, ByteOrder), 301 {Version, #request_header{service_context=Context, 302 request_id=Request_id, 303 response_expected=ResponseFlags, 304 object_key=Object_key, 305 operation=list_to_atom(Operation), 306 requesting_principal=""}, Rest5, Len5, ByteOrder}; 307dec_request_header(Version, Message, Len0, ByteOrder, _Buffer) -> 308 {Context, Rest1, Len1} = dec_service_context(Version, Message, Len0, ByteOrder), 309 {Request_id, Rest2, Len2, _} = dec_type('tk_ulong', Version, Rest1, Len1, ByteOrder, [], 0), 310 {Response_expected, Rest3, Len3, _} = dec_type('tk_boolean', Version, Rest2, Len2, 311 ByteOrder, [], 0), 312 {ObjKey, Rest4, Len4, _} = dec_type({'tk_sequence', 'tk_octet', 0}, Version, Rest3, 313 Len3, ByteOrder, [], 0), 314 Object_key = dec_target_key(ObjKey, Request_id, Version, 'location_forward'), 315 {Operation, Rest5, Len5, _} = dec_type({'tk_string', 0}, Version, Rest4, Len4, ByteOrder, [], 0), 316 {Principal, Rest, Len, _} = dec_type({'tk_string', 0}, Version, Rest5,Len5, ByteOrder, [], 0), 317 {Version, #request_header{service_context=Context, 318 request_id=Request_id, 319 response_expected=Response_expected, 320 object_key=Object_key, 321 operation=list_to_atom(Operation), 322 requesting_principal=Principal}, Rest, Len, ByteOrder}. 323 324 325%%----------------------------------------------------------------- 326%% Func: dec_service_context/4 327%% Args: Version - e.g. 1.2 328%% Message - The message 329%% Len - Number of bytes already read. 330%% ByteOrder - little or big 331%% Returns: 332%%----------------------------------------------------------------- 333dec_service_context(Version, Message, Len, ByteOrder) -> 334 {Context, Rest, Len1} = dec_type(?IOP_SERVICECONTEXT, Version, Message, 335 Len, ByteOrder), 336 {dec_used_contexts(Version, Context, []), Rest, Len1}. 337 338dec_used_contexts(_Version, [], Ctxs) -> 339 Ctxs; 340dec_used_contexts({1,0}, [#'IOP_ServiceContext'{context_id=?IOP_CodeSets}|T], Ctxs) -> 341 %% Not supported by 1.0, drop it. 342 dec_used_contexts({1,0}, T, Ctxs); 343dec_used_contexts(Version, [#'IOP_ServiceContext'{context_id=?IOP_CodeSets, 344 context_data = Bytes}|T], Ctxs) -> 345 {ByteOrder, Rest} = dec_byte_order(list_to_binary(Bytes)), 346 {CodeCtx, _, _} = dec_type(?CONV_FRAME_CODESETCONTEXT, Version, 347 Rest, 1, ByteOrder), 348 dec_used_contexts(Version, T, 349 [#'IOP_ServiceContext'{context_id=?IOP_CodeSets, 350 context_data = CodeCtx}|Ctxs]); 351dec_used_contexts(Version, [#'IOP_ServiceContext'{context_id=?IOP_BI_DIR_IIOP, 352 context_data = Bytes}|T], Ctxs) -> 353 {ByteOrder, Rest} = dec_byte_order(list_to_binary(Bytes)), 354 {BiDirCtx, _, _} = dec_type(?IIOP_BIDIRIIOPSERVICECONTEXT, Version, 355 Rest, 1, ByteOrder), 356 dec_used_contexts(Version, T, 357 [#'IOP_ServiceContext'{context_id=?IOP_BI_DIR_IIOP, 358 context_data = BiDirCtx}|Ctxs]); 359dec_used_contexts(Version, [#'IOP_ServiceContext'{context_id=?IOP_FT_REQUEST, 360 context_data = Bytes}|T], Ctxs) -> 361 {ByteOrder, Rest} = dec_byte_order(list_to_binary(Bytes)), 362 {Ctx, _, _} = dec_type(?FT_FTRequestServiceContext, Version, 363 Rest, 1, ByteOrder), 364 dec_used_contexts(Version, T, 365 [#'IOP_ServiceContext'{context_id=?IOP_FT_REQUEST, 366 context_data = Ctx}|Ctxs]); 367dec_used_contexts(Version, [#'IOP_ServiceContext'{context_id=?IOP_FT_GROUP_VERSION, 368 context_data = Bytes}|T], Ctxs) -> 369 {ByteOrder, Rest} = dec_byte_order(list_to_binary(Bytes)), 370 {Ctx, _, _} = dec_type(?FT_FTGroupVersionServiceContext, Version, 371 Rest, 1, ByteOrder), 372 dec_used_contexts(Version, T, 373 [#'IOP_ServiceContext'{context_id=?IOP_FT_GROUP_VERSION, 374 context_data = Ctx}|Ctxs]); 375dec_used_contexts(Version, [#'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, 376 context_data = Bytes}|T], Ctxs) -> 377 {ByteOrder, Rest} = dec_byte_order(list_to_binary(Bytes)), 378 {Ctx, _, _} = dec_type(?CSI_SASContextBody, Version, 379 Rest, 1, ByteOrder), 380 dec_used_contexts(Version, T, 381 [#'IOP_ServiceContext'{context_id=?IOP_SecurityAttributeService, 382 context_data = Ctx}|Ctxs]); 383dec_used_contexts(Version, [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, 384 context_data = Bytes}|T], Ctxs) -> 385 {ByteOrder, Rest} = dec_byte_order(list_to_binary(Bytes)), 386 {Ctx, _, _} = dec_type(?ORBER_GENERIC_CTX, Version, 387 Rest, 1, ByteOrder), 388 dec_used_contexts(Version, T, 389 [#'IOP_ServiceContext'{context_id=?ORBER_GENERIC_CTX_ID, 390 context_data = binary_to_term(list_to_binary(Ctx))}|Ctxs]); 391dec_used_contexts(Version, [H|T], Ctxs) -> 392 dec_used_contexts(Version, T, [H|Ctxs]). 393 394%%----------------------------------------------------------------- 395%% Func: dec_request_body 396%% Args: Version - e.g. 1.2 397%% Returns: 398%%----------------------------------------------------------------- 399dec_request_body(Version, ReqHdr, Rest, Len, ByteOrder, Buffer) -> 400 {Parameters, TypeCodes, _} = 401 dec_request_body(Version, ReqHdr#request_header.object_key, 402 ReqHdr#request_header.operation, 403 Rest, Len, ByteOrder, Buffer, Len), 404 {Version, ReqHdr, Parameters, TypeCodes}. 405 406dec_request_body(Version, Object_key, Operation, Body, Len, ByteOrder, Buffer, Counter) 407 when Version == {1,2} -> 408 case orber_typedefs:get_op_def(Object_key, Operation) of 409 {RetType, [], OutParameters} -> 410 {[], {RetType, [], OutParameters}, Len}; 411 {RetType, InParameters, OutParameters} -> 412 {Rest, Len1, NewC} = dec_align(Body, Len, 8, Counter), 413 {Parameters, Len2} = dec_parameters(Version, InParameters, Rest, Len1, 414 ByteOrder, Buffer, NewC), 415 {Parameters, {RetType, InParameters, OutParameters}, Len2} 416 end; 417dec_request_body(Version, Object_key, Operation, Body, Len, ByteOrder, Buffer, Counter) -> 418 {RetType, InParameters, OutParameters} = 419 orber_typedefs:get_op_def(Object_key, Operation), 420 {Parameters, Len1} = dec_parameters(Version, InParameters, Body, Len, ByteOrder, Buffer, Counter), 421 {Parameters, {RetType, InParameters, OutParameters}, Len1}. 422 423dec_parameters(_, [], _, Len, _, _, _) -> 424 {[], Len}; 425dec_parameters(Version, [P1 |InParList], Body, Len, ByteOrder, Buffer, Counter) -> 426 {Object, Rest, Len1, NewCounter} = dec_type(P1, Version, Body, Len, ByteOrder, Buffer, Counter), 427 {List, Len2} = dec_parameters(Version, InParList, Rest, Len1, ByteOrder, Buffer, NewCounter), 428 {[Object | List], Len2}. 429 430%%----------------------------------------------------------------- 431%% Func: dec_reply/5 432%% Args: 433%% Message - The message 434%% Len0 - Number of bytes already read. 435%% ByteOrder - little or big 436%% Returns: 437%% A tuple {ReplyHeader, Result} where ReplyHeader is a 438%% reply_header record and Result the decode result. 439%%----------------------------------------------------------------- 440dec_reply(Version, TypeCodes, Message, Len0, ByteOrder) -> 441 {ReplyHeader, Rest, Len} = dec_reply_header(Version, Message, Len0, ByteOrder), 442 {Result, Par} = 443 case ReplyHeader#reply_header.reply_status of 444 'no_exception' -> 445 {R, P, _} = dec_reply_body(Version, TypeCodes, Rest, Len, ByteOrder, Message), 446 {R, P}; 447 'system_exception' -> 448 {R, _} = dec_system_exception(Version, Rest, Len, ByteOrder), 449 {R, []}; 450 'user_exception' -> 451 {R, _} = dec_user_exception(Version, Rest, Len, ByteOrder), 452 {R, []}; 453 'location_forward' -> 454 {R, _, _} = dec_reply_body(Version, {{'tk_objref', "", ""}, [],[]}, 455 Rest, Len, ByteOrder, Message), 456 {R, []}; 457 %% This is deprecated in later version than CORBA-2.3.1. We'll leave it for 458 %% now. 459 'location_forward_perm' -> 460 {R, _, _} = dec_reply_body(Version, {{'tk_objref', "", ""}, [],[]}, 461 Rest, Len, ByteOrder, Message), 462 {R, []}; 463 'needs_addressing_mode' -> 464 {R, _, _} = dec_reply_body(Version, {'tk_short', [],[]}, 465 Rest, Len, ByteOrder, Message), 466 {R, []} 467 end, 468 {ReplyHeader, Result, Par}. 469 470 471%% ## NEW IIOP 1.2 ## 472dec_reply_header(Version, Message, Len0, ByteOrder) when Version == {1,2} -> 473 {Request_id, Rest1, Len1} = dec_type('tk_ulong', Version, Message, Len0, ByteOrder), 474 {ReplyStatus, Rest2, Len2} = dec_reply_status(Version, Rest1, Len1, ByteOrder), 475 {Context, Rest, Len3} = dec_service_context(Version, Rest2, Len2, ByteOrder), 476 {#reply_header{service_context=Context, request_id=Request_id, reply_status=ReplyStatus}, 477 Rest, Len3}; 478 479dec_reply_header(Version, Message, Len0, ByteOrder) -> 480 {Context, Rest1, Len1} = dec_service_context(Version, Message, Len0, ByteOrder), 481 {Request_id, Rest2, Len2} = dec_type('tk_ulong', Version, Rest1, Len1, ByteOrder), 482 {ReplyStatus, Rest, Len3} = dec_reply_status(Version, Rest2, Len2, ByteOrder), 483 {#reply_header{service_context=Context, request_id=Request_id, reply_status=ReplyStatus}, 484 Rest, Len3}. 485 486dec_reply_status(Version, Status, Len, ByteOrder) -> 487 {L, Rest, Len1}= dec_type('tk_ulong', Version, Status, Len, ByteOrder), 488 {dec_giop_reply_status_type(L), Rest, Len1}. 489 490dec_reply_body(_, {'tk_void', _, []}, <<>>, Len, _, _) -> 491 %% This case is mainly to be able to avoid removing non-existent alignment for 492 %% IIOP-1.2 messages if the body should be empty, i.e., void return value and 493 %% no out parameters. 494 {ok, [], Len}; 495dec_reply_body(Version, {RetType, _InParameters, OutParameters}, Body, Len, 496 ByteOrder, Bytes) when Version == {1,2} -> 497 {Rest, Len1, Counter} = dec_align(Body, Len, 8, Len), 498 {Result, Rest2, Len2, C} = dec_type(RetType, Version, Rest, Len1, ByteOrder, Bytes, Counter), 499 {Par, Len3} = dec_parameters(Version, OutParameters, Rest2, Len2, ByteOrder, Bytes, C), 500 {Result, Par, Len3}; 501dec_reply_body(Version, {RetType, _InParameters, OutParameters}, Body, Len, ByteOrder, Bytes) -> 502 {Result, Rest, Len1, C} = dec_type(RetType, Version, Body, Len, ByteOrder, Bytes, Len), 503 {Par, Len2} = dec_parameters(Version, OutParameters, Rest, Len1, ByteOrder, Bytes, C), 504 {Result, Par, Len2}. 505 506 507%%----------------------------------------------------------------- 508%% Func: dec_cancel_request/3 509%% Args: 510%% Message - The message 511%% Len - Number of bytes already read. 512%% ByteOrder - little or big 513%% Returns: 514%% A cancel_request_header record. 515%%----------------------------------------------------------------- 516dec_cancel_request(Version, Message, Len, ByteOrder) -> 517 {Request_id, _, _} = dec_type('tk_ulong', Version, Message, Len, ByteOrder), 518 #cancel_request_header{request_id=Request_id}. 519 520%%----------------------------------------------------------------- 521%% Func: dec_locate_request/3 522%% Args: 523%% Message - The message 524%% Len - Number of bytes already read. 525%% ByteOrder - little or big 526%% Returns: 527%% A locate_request_header record. 528%%----------------------------------------------------------------- 529%% ## NEW IIOP 1.2 ## 530dec_locate_request(Version, Message, Len, ByteOrder) when Version == {1,2} -> 531 {Request_id, Rest, Len1} = dec_type('tk_ulong', Version, Message, Len, ByteOrder), 532 {Object_key, _, _, _} = dec_target_addr(Version, Rest, Len1, ByteOrder, Request_id, 533 'object_forward'), 534 {Version, #locate_request_header{request_id=Request_id, object_key=Object_key}}; 535dec_locate_request(Version, Message, Len, ByteOrder) -> 536 {Request_id, Rest, Len1} = dec_type('tk_ulong', Version, Message, Len, ByteOrder), 537 {ObjKey, _, _} = dec_type({'tk_sequence', 'tk_octet', 0}, Version, Rest, 538 Len1, ByteOrder), 539 Object_key = dec_target_key(ObjKey, Request_id, Version, 'object_forward'), 540 {Version, #locate_request_header{request_id=Request_id, object_key=Object_key}}. 541 542 543%%----------------------------------------------------------------- 544%% Func: dec_locate_reply/3 545%% Args: 546%% Message - The message 547%% Len - Number of bytes already read. 548%% ByteOrder - little or big 549%% Returns: 550%% A locate_reply_header record. 551%%----------------------------------------------------------------- 552dec_locate_reply(Version, Message, Len, ByteOrder) -> 553 {ReplyHeader, Rest1, Len1} = dec_locate_reply_header(Version, Message, Len, ByteOrder), 554 {ReplyHeader, dec_locate_reply_body(Version, ReplyHeader#locate_reply_header.locate_status, Rest1, 555 Len1, ByteOrder)}. 556 557dec_locate_reply_header(Version, Message, Len, ByteOrder) -> 558 {Request_id, Rest1, Len1} = dec_type('tk_ulong', Version, Message, Len, ByteOrder), 559 {Locate_status, Rest2, Len2} = dec_locate_status(Version, Rest1, Len1, ByteOrder), 560 {#locate_reply_header{request_id=Request_id, locate_status=Locate_status}, Rest2, Len2}. 561 562dec_locate_reply_body(Version, LocateStatus, Rest, Len, ByteOrder) when Version == {1,2} -> 563 %% In CORBA-2.3.1 the LocateReply body didn't align the body (8-octet 564 %% boundry) for IIOP-1.2. This have been changed in CORBA-2.4 and 565 %% changed back in CORBA-2.6. Hence, we should not change this. 566 case LocateStatus of 567 'object_forward' -> 568 {ObjRef, _, _, _} = dec_objref(Version, Rest, Len, ByteOrder), 569 ObjRef; 570 'object_forward_perm' -> 571 %% This is deprecated in later version than CORBA-2.3.1. We'll leave it for 572 %% now. 573 {ObjRef, _, _, _} = dec_objref(Version, Rest, Len, ByteOrder), 574 ObjRef; 575 'loc_system_exception' -> 576 %% This should be updated but since 'dec_system_exception' removes 577 %% alignment, which the LocateReplyBody don't have, for 1.2 we 578 %% pretend it's 1.1 for now. 579 {SysExc, _} = dec_system_exception({1,1}, Rest, Len, ByteOrder), 580 corba:raise(SysExc); 581 'loc_needs_addressing_mode' -> 582 %% Not supported. 583 []; 584 _ -> 585 [] 586 end; 587dec_locate_reply_body(Version, LocateStatus, Rest, Len, ByteOrder) -> 588 case LocateStatus of 589 'object_forward' -> 590 {ObjRef, _, _, _} = dec_objref(Version, Rest, Len, ByteOrder), 591 ObjRef; 592 _ -> 593 [] 594 end. 595 596dec_locate_status(Version, Bytes, Len, ByteOrder) -> 597 {L, Rest, Len1} = dec_type('tk_ulong', Version, Bytes, Len, ByteOrder), 598 {dec_giop_locate_status_type(L), Rest, Len1}. 599 600 601%%----------------------------------------------------------------- 602%% Func: dec_fragment_header/5 603%% Args: 604%% Message - The message 605%% Len0 - Number of bytes already read. 606%% ByteOrder - little or big 607%% Returns: 608%%----------------------------------------------------------------- 609dec_fragment_header(Version, Message, Len0, ByteOrder, _Buffer) when Version == {1,2} -> 610 {RequestId, Rest1, Len1, _} = dec_type('tk_ulong', Version, Message, Len0, 611 ByteOrder, [], 0), 612 {Version, #fragment_header{request_id=RequestId}, Rest1, Len1, ByteOrder}; 613dec_fragment_header(Version, _Message, _Len0, _ByteOrder, _Buffer) -> 614 %% The FragmentHeader is IIOP-1.2 specific. Hence, do nothing here. 615 orber:dbg("[~p] cdr_decode:dec_fragment_header(~p)~n" 616 "Orber only supports fragmented messages for IIOP-1.2.", 617 [?LINE, Version], ?DEBUG_LEVEL), 618 exit(message_error). 619% {Version, #fragment_header{}, Message, Len0, ByteOrder}. 620 621%%----------------------------------------------------------------- 622%% Func: dec_giop_reply_status_type 623%% Args: 624%% An integer status code 625%% Returns: 626%% An atom which is the reply status 627%%----------------------------------------------------------------- 628dec_giop_reply_status_type(0) -> 629 'no_exception'; 630dec_giop_reply_status_type(1) -> 631 'user_exception'; 632dec_giop_reply_status_type(2) -> 633 'system_exception'; 634dec_giop_reply_status_type(3) -> 635 'location_forward'; 636%% ## IIOP-1.2 ## 637dec_giop_reply_status_type(4) -> 638 'location_forward_perm'; 639dec_giop_reply_status_type(5) -> 640 'needs_addressing_mode'. 641 642%%----------------------------------------------------------------- 643%% Func: dec_giop_locate_status_type 644%% Args: 645%% An integer status code 646%% Returns: 647%% An atom which is the reply status 648%%----------------------------------------------------------------- 649dec_giop_locate_status_type(0) -> 650 'unknown_object'; 651dec_giop_locate_status_type(1) -> 652 'object_here'; 653dec_giop_locate_status_type(2) -> 654 'object_forward'; 655%% ## IIOP-1.2 ## 656dec_giop_locate_status_type(3) -> 657 'object_forward_perm'; 658dec_giop_locate_status_type(4) -> 659 'loc_system_exception'; 660dec_giop_locate_status_type(5) -> 661 'loc_needs_addressing_mode'. 662 663 664%%----------------------------------------------------------------- 665%% Func: dec_type/5 666%%----------------------------------------------------------------- 667dec_type(Type, Version, Bytes, Len, ByteOrder) -> 668 {Val, Rest, Len2, _} = 669 dec_type(Type, Version, Bytes, Len, ByteOrder, [], 0), 670 {Val, Rest, Len2}. 671 672dec_type('tk_null', _Version, Bytes, Len, _, _, C) -> 673 {'null', Bytes, Len, C}; 674dec_type('tk_void', _Version, Bytes, Len, _, _, C) -> 675 {'ok', Bytes, Len, C}; 676dec_type('tk_short', _Version, Bytes, Len, ByteOrder, _, C) -> 677 {Rest, Len1, NewC} = dec_align(Bytes, Len, 2, C), 678 {Short, Rest1} = cdrlib:dec_short(ByteOrder, Rest), 679 {Short, Rest1, Len1 + 2, NewC+2}; 680dec_type('tk_long', _Version, Bytes, Len, ByteOrder, _, C) -> 681 {Rest, Len1, NewC} = dec_align(Bytes, Len, 4, C), 682 {Long, Rest1} = cdrlib:dec_long(ByteOrder, Rest), 683 {Long, Rest1, Len1 + 4, NewC+4}; 684dec_type('tk_longlong', _Version, Bytes, Len, ByteOrder, _, C) -> 685 {Rest, Len1, NewC} = dec_align(Bytes, Len, 8, C), 686 {Long, Rest1} = cdrlib:dec_longlong(ByteOrder, Rest), 687 {Long, Rest1, Len1 + 8, NewC+8}; 688dec_type('tk_ushort', _Version, Bytes, Len, ByteOrder, _, C) -> 689 {Rest, Len1, NewC} = dec_align(Bytes, Len, 2, C), 690 {Short, Rest1} = cdrlib:dec_unsigned_short(ByteOrder, Rest), 691 {Short, Rest1, Len1 + 2, NewC+2}; 692dec_type('tk_ulong', _Version, Bytes, Len, ByteOrder, _, C) -> 693 {Rest, Len1, NewC} = dec_align(Bytes, Len, 4, C), 694 {Long, Rest1} = cdrlib:dec_unsigned_long(ByteOrder, Rest), 695 {Long, Rest1, Len1 + 4, NewC+4}; 696dec_type('tk_ulonglong', _Version, Bytes, Len, ByteOrder, _, C) -> 697 {Rest, Len1, NewC} = dec_align(Bytes, Len, 8, C), 698 {Long, Rest1} = cdrlib:dec_unsigned_longlong(ByteOrder, Rest), 699 {Long, Rest1, Len1 + 8, NewC+8}; 700dec_type('tk_float', _Version, Bytes, Len, ByteOrder, _, C) -> 701 {Rest, Len1, NewC} = dec_align(Bytes, Len, 4, C), 702 {Float, Rest1} = cdrlib:dec_float(ByteOrder, Rest), 703 {Float, Rest1, Len1 + 4, NewC+4}; 704dec_type('tk_double', _Version, Bytes, Len, ByteOrder, _, C) -> 705 {Rest, Len1, NewC} = dec_align(Bytes, Len, 8, C), 706 {Double, Rest1} = cdrlib:dec_double(ByteOrder, Rest), 707 {Double, Rest1, Len1 + 8, NewC+8}; 708dec_type('tk_boolean', _Version, Bytes, Len, _, _, C) -> 709 {Bool, Rest} = cdrlib:dec_bool(Bytes), 710 {Bool, Rest, Len + 1, C+1}; 711dec_type('tk_char', _Version, Bytes, Len, _, _, C) -> 712 {Char, Rest} = cdrlib:dec_char(Bytes), 713 {Char, Rest, Len + 1, C+1}; 714dec_type('tk_wchar', {1,2}, Bytes, Len, _ByteOrder, _, C) -> 715 %% For IIOP-1.2 a wchar is almost encoded the same way as an octet-sequence. 716 %% The only difference is that the length-value is an octet as well. 717 case cdrlib:dec_octet(Bytes) of 718 {2, Rest1} -> 719 %% Currently we only allow 2-bytes wchar. 720 {WChar, Rest2} = cdrlib:dec_unsigned_short(big, Rest1), 721 {WChar, Rest2, Len+3, C+3}; 722 {What, _} -> 723 orber:dbg("[~p] cdr_decode:dec_type(~p); unsupported wchar", 724 [?LINE, What], ?DEBUG_LEVEL), 725 corba:raise(#'DATA_CONVERSION'{completion_status=?COMPLETED_NO}) 726 end; 727%% For 1.1 the wchar is limited to the use of two-octet fixed-length encoding. 728dec_type('tk_wchar', _Version, Bytes, Len, ByteOrder, _, C) -> 729 {Rest, Len1, NewC} = dec_align(Bytes, Len, 2, C), 730 {WChar, Rest2} = cdrlib:dec_unsigned_short(ByteOrder, Rest), 731 {WChar, Rest2, Len1 + 2, NewC+2}; 732dec_type('tk_octet', _Version, Bytes, Len, _, _, C) -> 733 {Octet, Rest} = cdrlib:dec_octet(Bytes), 734 {Octet, Rest, Len + 1, C+1}; 735dec_type('tk_any', Version, Bytes, Len, ByteOrder, Buff, C) -> 736 {TypeCode, Rest1, Len1, NewC} = dec_type('tk_TypeCode', Version, Bytes, Len, ByteOrder, Buff, C), 737 {Value, Rest2, Len2, NewC2} = dec_type(TypeCode, Version, Rest1, Len1, ByteOrder, Buff, NewC), 738 {#any{typecode=TypeCode, value=Value}, Rest2, Len2, NewC2}; 739dec_type('tk_TypeCode', Version, Bytes, Len, ByteOrder, Buff, C) -> 740 dec_type_code(Version, Bytes, Len, ByteOrder, Buff, C); 741dec_type('tk_Principal', Version, Bytes, Len, ByteOrder, Buff, C) -> 742 dec_sequence(Version, Bytes, 'tk_octet', Len, ByteOrder, Buff, C); 743dec_type({'tk_objref', _IFRId, _Name}, Version, Bytes, Len, ByteOrder, Buff, C) -> 744 dec_objref(Version, Bytes, Len, ByteOrder, Buff, C); 745dec_type({'tk_struct', IFRId, Name, ElementList}, Version, Bytes, Len, ByteOrder, Buff, C) -> 746 dec_struct(Version, IFRId, Name, ElementList, Bytes, Len, ByteOrder, Buff, C); 747dec_type({'tk_union', IFRId, Name, DiscrTC, Default, ElementList}, 748 Version, Bytes, Len, ByteOrder, Buff, C) -> 749 dec_union(Version, IFRId, Name, DiscrTC, Default, ElementList, Bytes, Len, ByteOrder, Buff, C); 750dec_type({'tk_enum', _IFRId, _Name, ElementList}, _Version, Bytes, Len, ByteOrder, _, C) -> 751 {Rest, Len1, NewC} = dec_align(Bytes, Len, 4, C), 752 {Enum, Rest1} = cdrlib:dec_enum(ByteOrder, ElementList, Rest), 753 {Enum, Rest1, Len1 + 4, NewC+4}; 754dec_type({'tk_string', _MaxLength}, Version, Bytes, Len, ByteOrder, Buff, C) -> 755 dec_string(Version, Bytes, Len, ByteOrder, Buff, C); 756dec_type({'tk_wstring', _MaxLength}, Version, Bytes, Len, ByteOrder, Buff, C) -> 757 dec_wstring(Version, Bytes, Len, ByteOrder, Buff, C); 758dec_type({'tk_sequence', ElemTC, _MaxLength}, Version, Bytes, Len, ByteOrder, Buff, C) -> 759 dec_sequence(Version, Bytes, ElemTC, Len, ByteOrder, Buff, C); 760dec_type({'tk_array', ElemTC, Size}, Version, Bytes, Len, ByteOrder, Buff, C) -> 761 dec_array(Version, Bytes, Size, ElemTC, Len, ByteOrder, Buff, C); 762dec_type({'tk_alias', _IFRId, _Name, TC}, Version, Bytes, Len, ByteOrder, Buff, C) -> 763 dec_type(TC, Version, Bytes, Len, ByteOrder, Buff, C); 764%dec_type({'tk_except', IFRId, Name, ElementList}, Version, Bytes, Len, ByteOrder) -> 765dec_type({'tk_fixed', Digits, Scale}, _Version, Bytes, Len, _ByteOrder, _Buff, C) -> 766 dec_fixed(Digits, Scale, Bytes, Len, C); 767dec_type(Type, _, _, _, _, _, _) -> 768 orber:dbg("[~p] cdr_decode:dec_type(~p)~n" 769 "Incorrect TypeCode or unsupported type.", 770 [?LINE, Type], ?DEBUG_LEVEL), 771 corba:raise(#'MARSHAL'{minor=(?ORBER_VMCID bor 13), completion_status=?COMPLETED_MAYBE}). 772 773stringify_enum({tk_enum,_,_,_}, Label) -> 774 atom_to_list(Label); 775stringify_enum(_, Label) -> 776 Label. 777 778%%----------------------------------------------------------------- 779%% Func: dec_fixed 780%%----------------------------------------------------------------- 781%% Digits eq. total number of digits. 782%% Scale eq. position of the decimal point. 783%% E.g. fixed<5,2> - "123.45" 784%% E.g. fixed<4,2> - "12.34" 785%% These are encoded as: 786%% ## <5,2> ## ## <4,2> ## 787%% 1,2 0,1 eq. 1 octet 788%% 3,4 2,3 789%% 5,0xC 4,0xC 790%% 791%% Each number is encoded as a half-octet. Note, for <4,2> a zero is 792%% added first to to be able to create "even" octets. 793dec_fixed(0, 0, Bytes, Len, C) -> 794 {#fixed{digits = 0, scale = 0, value = ""}, Bytes, Len, C}; 795dec_fixed(Digits, Scale, Bytes, Len, C) -> 796 case ?ODD(Digits) of 797 true -> 798 {Fixed, Bytes2, Len2, C2, Sign} = dec_fixed_2(Digits, Scale, Bytes, Len, C), 799 case Sign of 800 ?FIXED_POSITIVE -> 801 {#fixed{digits = Digits, scale = Scale, 802 value = list_to_integer(Fixed)}, Bytes2, Len2, C2}; 803 ?FIXED_NEGATIVE -> 804 {#fixed{digits = Digits, scale = Scale, 805 value = -list_to_integer(Fixed)}, Bytes2, Len2, C2} 806 end; 807 false -> 808 %% If the length (of fixed) is even a zero is added first. 809 %% Subtract that we've read 1 digit. 810 <<0:4,D2:4,T/binary>> = Bytes, 811 {Fixed, Bytes2, Len2, C2, Sign} = dec_fixed_2(Digits-1, Scale, T, Len+1, C+1), 812 case Sign of 813 ?FIXED_POSITIVE -> 814 {#fixed{digits = Digits, scale = Scale, 815 value = list_to_integer([D2+48|Fixed])}, Bytes2, Len2, C2}; 816 ?FIXED_NEGATIVE -> 817 {#fixed{digits = Digits, scale = Scale, 818 value = -list_to_integer([D2+48|Fixed])}, Bytes2, Len2, C2} 819 end 820 end. 821 822dec_fixed_2(1, _Scale, <<D1:4,?FIXED_POSITIVE:4,T/binary>>, Len, C) -> 823 {[D1+48], T, Len+1, C+1, ?FIXED_POSITIVE}; 824dec_fixed_2(1, _Scale, <<D1:4,?FIXED_NEGATIVE:4,T/binary>>, Len, C) -> 825 {[D1+48], T, Len+1, C+1, ?FIXED_NEGATIVE}; 826dec_fixed_2(Digits, Scale, _Bytes, _Len, _C) when Digits =< 0 -> 827 orber:dbg("[~p] cdr_decode:dec_fixed_2(~p, ~p)~n" 828 "Malformed fixed type.", [?LINE, Digits, Scale], ?DEBUG_LEVEL), 829 corba:raise(#'MARSHAL'{minor=(?ORBER_VMCID bor 14), completion_status=?COMPLETED_MAYBE}); 830dec_fixed_2(Digits, Scale, <<>>, _Len, _C) -> 831 orber:dbg("[~p] cdr_decode:dec_fixed_2(~p, ~p)~n" 832 "The fixed type received was to short.", 833 [?LINE, Digits, Scale], ?DEBUG_LEVEL), 834 corba:raise(#'MARSHAL'{minor=(?ORBER_VMCID bor 14), completion_status=?COMPLETED_MAYBE}); 835dec_fixed_2(Digits, Scale, <<D1:4,D2:4,T/binary>>, Len, C) -> 836 {Seq, Rest2, Len2, NewC2, Sign} = dec_fixed_2(Digits-2, Scale, T, Len+1, C+1), 837 {[D1+48, D2+48 | Seq], Rest2, Len2, NewC2, Sign}. 838 839%%----------------------------------------------------------------- 840%% Func: dec_sequence/7 and dec_sequence/8 841%%----------------------------------------------------------------- 842dec_sequence(_Version, Message, 'tk_octet', Len, ByteOrder, _Buff, C) -> 843 {Rest, Len1, NewC} = dec_align(Message, Len, 4, C), 844 {Size, Rest1} = cdrlib:dec_unsigned_long(ByteOrder, Rest), 845 <<OctetSeq:Size/binary, Rest2/binary>> = Rest1, 846 {binary_to_list(OctetSeq), Rest2, Len1+4+Size, NewC+4+Size}; 847dec_sequence(_Version, Message, 'tk_char', Len, ByteOrder, _Buff, C) -> 848 {Rest, Len1, NewC} = dec_align(Message, Len, 4, C), 849 {Size, Rest1} = cdrlib:dec_unsigned_long(ByteOrder, Rest), 850 <<OctetSeq:Size/binary, Rest2/binary>> = Rest1, 851 {binary_to_list(OctetSeq), Rest2, Len1+4+Size, NewC+4+Size}; 852%% We test if it's a sequence of struct's or unions. By doing this we only 853%% have to look up the IFR-ID once instead of N times (N eq length of sequence). 854dec_sequence(Version, Message, {'tk_struct', IFRId, ShortName, ElementList}, 855 Len, ByteOrder, Buff, C) when IFRId /= "", ShortName /= "" -> 856 {Rest, Len1, NewC} = dec_align(Message, Len, 4, C), 857 {Size, Rest1} = cdrlib:dec_unsigned_long(ByteOrder, Rest), 858 case IFRId of 859 ?SYSTEM_TYPE -> 860 dec_sequence_struct(Version, Rest1, Size, ElementList, Len1 + 4, 861 ByteOrder, Buff, NewC+4, ShortName); 862 _ -> 863 Name = ifrid_to_name(IFRId, ?IFR_StructDef), 864 dec_sequence_struct(Version, Rest1, Size, ElementList, Len1 + 4, 865 ByteOrder, Buff, NewC+4, Name) 866 end; 867dec_sequence(Version, Message, 868 {'tk_union', ?SYSTEM_TYPE, TCName, DiscrTC, Default, ElementList}, 869 Len, ByteOrder, Buff, C) -> 870 {Rest, Len1, NewC} = dec_align(Message, Len, 4, C), 871 {Size, Rest1} = cdrlib:dec_unsigned_long(ByteOrder, Rest), 872 dec_sequence_union(Version, Rest1, Size, DiscrTC, Default, ElementList, Len1 + 4, 873 ByteOrder, Buff, NewC+4, TCName); 874dec_sequence(Version, Message, 875 {'tk_union', IFRId, _TCName, DiscrTC, Default, ElementList}, 876 Len, ByteOrder, Buff, C) -> 877 {Rest, Len1, NewC} = dec_align(Message, Len, 4, C), 878 {Size, Rest1} = cdrlib:dec_unsigned_long(ByteOrder, Rest), 879 Name = ifrid_to_name(IFRId, ?IFR_UnionDef), 880 dec_sequence_union(Version, Rest1, Size, DiscrTC, Default, ElementList, Len1 + 4, 881 ByteOrder, Buff, NewC+4, Name); 882dec_sequence(Version, Message, TypeCode, Len, ByteOrder, Buff, C) -> 883 {Rest, Len1, NewC} = dec_align(Message, Len, 4, C), 884 {Size, Rest1} = cdrlib:dec_unsigned_long(ByteOrder, Rest), 885 dec_sequence(Version, Rest1, Size, TypeCode, Len1 + 4, ByteOrder, Buff, NewC+4). 886 887 888dec_sequence(_, Message, 0, _Type, Len, _ByteOrder, _Buff, C) -> 889 {[], Message, Len, C}; 890dec_sequence(Version, Message, N, Type, Len, ByteOrder, Buff, C) -> 891 {Object, Rest1, Len1, NewC} = dec_type(Type, Version, Message, Len, ByteOrder, Buff, C), 892 {Seq, Rest2, Len2, NewC2} = dec_sequence(Version, Rest1, N - 1, Type, Len1, ByteOrder, Buff, NewC), 893 {[Object | Seq], Rest2, Len2, NewC2}. 894 895dec_sequence_struct(_, Message, 0, _Type, Len, _ByteOrder, _Buff, C, _Name) -> 896 {[], Message, Len, C}; 897dec_sequence_struct(Version, Message, N, TypeCodeList, Len, ByteOrder, Buff, C, Name) -> 898 {Struct, Rest1, Len1, NewC} = dec_struct1(Version, TypeCodeList, Message, Len, ByteOrder, Buff, C), 899 {Seq, Rest2, Len2, NewC2} = dec_sequence_struct(Version, Rest1, N - 1, TypeCodeList, Len1, ByteOrder, 900 Buff, NewC, Name), 901 {[list_to_tuple([Name |Struct]) | Seq], Rest2, Len2, NewC2}. 902 903 904dec_sequence_union(_, Message, 0, _DiscrTC, _Default, _ElementList, 905 Len, _ByteOrder, _Buff, C, _Name) -> 906 {[], Message, Len, C}; 907dec_sequence_union(Version, Message, N, DiscrTC, Default, ElementList, 908 Len, ByteOrder, Buff, C, Name) when is_list(ElementList) -> 909 910 {Label, Rest1, Len1, NewC} = dec_type(DiscrTC, Version, Message, Len, ByteOrder, Buff, C), 911 Result = dec_union(Version, stringify_enum(DiscrTC, Label), ElementList, Default, 912 Rest1, Len1, ByteOrder, Buff, NewC), 913 {Value, Rest2, Len2, NewC3} = case Result of 914 {default, R, L, NewC2} -> 915 dec_union(Version, default, ElementList, Default, 916 R, L, ByteOrder, Buff, NewC2); 917 X -> 918 X 919 end, 920 {Seq, Rest3, Len3, NewC4} = dec_sequence_union(Version, Rest2, N - 1, 921 DiscrTC, Default, ElementList, 922 Len2, ByteOrder, 923 Buff, NewC3, Name), 924 {[{Name, Label, Value} | Seq], Rest3, Len3, NewC4}; 925dec_sequence_union(Version, Message, N, _DiscrTC, _Default, Module, 926 Len, ByteOrder, Buff, C, Name) when is_atom(Module) -> 927 case catch Module:tc() of 928 {tk_union, _, _, DiscrTC, Default, ElementList} -> 929 dec_sequence_union(Version, Message, N, DiscrTC, Default, ElementList, 930 Len, ByteOrder, Buff, C, Name); 931 What -> 932 orber:dbg("[~p] ~p:dec_sequence_union(~p). Union module doesn't exist or incorrect.", 933 [?LINE, ?MODULE, What], ?DEBUG_LEVEL), 934 corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE}) 935 end. 936 937 938 939%% A special case; when something is encapsulated (i.e. sent as octet-sequence) 940%% we sometimes don not want the result to be converted to a list. 941dec_octet_sequence_bin(_Version, Message, Len, ByteOrder, _Buff, C) -> 942 {Rest, Len1, NewC} = dec_align(Message, Len, 4, C), 943 {Size, Rest1} = cdrlib:dec_unsigned_long(ByteOrder, Rest), 944 <<OctetSeq:Size/binary, Rest2/binary>> = Rest1, 945 {OctetSeq, Rest2, Len1+4+Size, NewC+4+Size}. 946 947%%----------------------------------------------------------------- 948%% Func: dec_array/5 949%%----------------------------------------------------------------- 950dec_array(Version, Message, Size, TypeCode, Len, ByteOrder, Buff, C) -> 951 {Seq, Rest1, Len1, NewC} = dec_sequence(Version, Message, Size, TypeCode, Len, 952 ByteOrder, Buff, C), 953 {list_to_tuple(Seq), Rest1, Len1, NewC}. 954 955 956%%----------------------------------------------------------------- 957%% Func: dec_string/4 958%%----------------------------------------------------------------- 959dec_string(_Version, Message, Len, ByteOrder, _Buff, C) -> 960 {Rest, Len1, NewC} = dec_align(Message, Len, 4, C), 961 {Size, Rest1} = cdrlib:dec_unsigned_long(ByteOrder, Rest), 962 if 963 Size > 0 -> 964 DataSize = Size-1, 965 <<String:DataSize/binary, _Null:1/binary, Rest2/binary>> = Rest1, 966 {binary_to_list(String), Rest2, Len1+4+Size, NewC+4+Size}; 967 true -> 968 {"", Rest1, Len1 + 4, NewC+4} 969 end. 970 971%%----------------------------------------------------------------- 972%% Func: dec_string/4 973%%----------------------------------------------------------------- 974dec_wstring({1,2}, Message, Len, ByteOrder, Buff, C) -> 975 {Rest, Len1, NewC} = dec_align(Message, Len, 4, C), 976 {Octets, Rest1} = cdrlib:dec_unsigned_long(ByteOrder, Rest), 977 if 978 Octets == 0 -> 979 {"", Rest1, Len1 + 4, NewC+4}; 980 Octets > 0 -> 981 Size = round(Octets/2), 982 {String, Rest2, Len2, NewC2} = 983 dec_sequence({1,2}, Rest1, Size, 'tk_ushort', 984 Len1 + 4, big, Buff, NewC+4), 985 {String, Rest2, Len2, NewC2}; 986 true -> 987 orber:dbg("[~p] cdr_decode:dec_wstring(~p);", 988 [?LINE, Rest1], ?DEBUG_LEVEL), 989 corba:raise(#'MARSHAL'{completion_status=?COMPLETED_NO}) 990 end; 991dec_wstring(Version, Message, Len, ByteOrder, Buff, C) -> 992 {Rest, Len1, NewC} = dec_align(Message, Len, 4, C), 993 {Size, Rest1} = cdrlib:dec_unsigned_long(ByteOrder, Rest), 994 if 995 Size > 0 -> 996 {String, Rest2, Len2, NewC2} = dec_sequence(Version, Rest1, Size - 1, 'tk_wchar', 997 Len1 + 4, ByteOrder, Buff, NewC+4), 998 %% Remove the NULL character. 999 {_, Rest3} = cdrlib:dec_unsigned_short(ByteOrder, Rest2), 1000 {String, Rest3, Len2 + 2, NewC2+2}; 1001 Size == 0 -> 1002 {"", Rest1, Len1 + 4, NewC+4}; 1003 true -> 1004 orber:dbg("[~p] cdr_decode:dec_wstring(~p);", 1005 [?LINE, Rest1], ?DEBUG_LEVEL), 1006 corba:raise(#'MARSHAL'{completion_status=?COMPLETED_NO}) 1007 end. 1008 1009 1010%%----------------------------------------------------------------- 1011%% Func: dec_union/9 1012%%----------------------------------------------------------------- 1013%% ## NEW IIOP 1.2 ## 1014dec_union(Version, ?SYSTEM_TYPE, Name, DiscrTC, Default, ElementList, Bytes, 1015 Len, ByteOrder, Buff, C) -> 1016 {Label, Rest1, Len1, NewC} = dec_type(DiscrTC, Version, Bytes, Len, ByteOrder, Buff, C), 1017 {Value, Rest2, Len2, NewC3} = dec_union(Version, Label, ElementList, Default, 1018 Rest1, Len1, ByteOrder, Buff, NewC), 1019 {{Name, Label, Value}, Rest2, Len2, NewC3}; 1020 1021 1022dec_union(Version, IFRId, _, DiscrTC, Default, ElementList, Bytes, Len, 1023 ByteOrder, Buff, C) when is_list(ElementList) -> 1024 {Label, Rest1, Len1, NewC} = dec_type(DiscrTC, Version, Bytes, Len, ByteOrder, Buff, C), 1025 Result = dec_union(Version, stringify_enum(DiscrTC, Label), ElementList, Default, 1026 Rest1, Len1, ByteOrder, Buff, NewC), 1027 {Value, Rest2, Len2, NewC3} = case Result of 1028 {default, R, L, NewC2} -> 1029 dec_union(Version, default, ElementList, Default, 1030 R, L, ByteOrder, Buff, NewC2); 1031 X -> 1032 X 1033 end, 1034 Name = ifrid_to_name(IFRId, ?IFR_UnionDef), 1035 {{Name, Label, Value}, Rest2, Len2, NewC3}; 1036dec_union(Version, IFRId, _, _DiscrTC, _Default, Module, Bytes, Len, 1037 ByteOrder, Buff, C) when is_atom(Module) -> 1038 case catch Module:tc() of 1039 {tk_union, _, Name, DiscrTC, Default, ElementList} -> 1040 dec_union(Version, IFRId, Name, DiscrTC, Default, ElementList, Bytes, Len, 1041 ByteOrder, Buff, C); 1042 What -> 1043 orber:dbg("[~p] ~p:dec_union(~p). Union module doesn't exist or incorrect.", 1044 [?LINE, ?MODULE, What], ?DEBUG_LEVEL), 1045 corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE}) 1046 end. 1047 1048 1049 1050dec_union(_, _, [], Default, Message, Len, _, _Buff, C) when Default < 0 -> 1051 {undefined, Message, Len, C}; 1052dec_union(_, _, [], _Default, Message, Len, _, _Buff, C) -> 1053 {default, Message, Len, C}; 1054dec_union(Version, Label, [{Label, _Name, Type}|_List], _Default, Message, Len, ByteOrder, Buff, C) -> 1055 dec_type(Type, Version, Message, Len, ByteOrder, Buff, C); 1056dec_union(Version, Label, [_H|List], Default, Message, Len, ByteOrder, Buff, C) -> 1057 dec_union(Version, Label, List, Default, Message, Len, ByteOrder, Buff, C). 1058 1059%%----------------------------------------------------------------- 1060%% Func: dec_struct/7 1061%%----------------------------------------------------------------- 1062dec_struct(Version, "", "", TypeCodeList, Message, Len, ByteOrder, Buff, C) -> 1063 {Struct, Rest, Len1, NewC} = dec_struct1(Version, TypeCodeList, Message, Len, ByteOrder, Buff, C), 1064 {list_to_tuple(Struct), Rest, Len1, NewC}; 1065dec_struct(Version, [], Name, TypeCodeList, Message, Len, ByteOrder, Buff, C) -> 1066 %% This case is used when communicating with ORB:s which don't supply the IFRId 1067 %% field in struct type codes (used in any) 1068 {Struct, Rest, Len1, NewC} = dec_struct1(Version, TypeCodeList, Message, Len, ByteOrder, Buff, C), 1069 {list_to_tuple([list_to_atom(Name) |Struct]), Rest, Len1, NewC}; 1070dec_struct(Version, ?SYSTEM_TYPE, ShortName, TypeCodeList, Message, Len, ByteOrder, Buff, C) -> 1071 {Struct, Rest, Len1, NewC} = dec_struct1(Version, TypeCodeList, Message, Len, ByteOrder, Buff, C), 1072 {list_to_tuple([ShortName |Struct]), Rest, Len1, NewC}; 1073dec_struct(Version, IFRId, _ShortName, TypeCodeList, Message, Len, ByteOrder, Buff, C) -> 1074 Name = ifrid_to_name(IFRId, ?IFR_StructDef), 1075 {Struct, Rest, Len1, NewC} = dec_struct1(Version, TypeCodeList, Message, Len, ByteOrder, Buff, C), 1076 {list_to_tuple([Name |Struct]), Rest, Len1, NewC}. 1077 1078dec_struct1(_, [], Message, Len, _ByteOrder, _, C) -> 1079 {[], Message, Len, C}; 1080dec_struct1(Version, [{_ElemName, ElemType} | TypeCodeList], Message, Len, ByteOrder, Buff, C) -> 1081 {Element, Rest, Len1, NewC} = dec_type(ElemType, Version, Message, Len, ByteOrder, Buff, C), 1082 {Struct, Rest1, Len2, NewC2} = dec_struct1(Version, TypeCodeList, Rest, Len1, ByteOrder, Buff, NewC), 1083 {[Element |Struct], Rest1, Len2, NewC2}; 1084dec_struct1(Version, Module, Message, Len, ByteOrder, Buff, C) -> 1085 case catch Module:tc() of 1086 {tk_struct, _, _, TypeCodeList} -> 1087 dec_struct1(Version, TypeCodeList, Message, Len, ByteOrder, Buff, C); 1088 What -> 1089 orber:dbg("[~p] ~p:dec_struct1(~p). Struct module doesn't exist or incorrect.", 1090 [?LINE, ?MODULE, What], ?DEBUG_LEVEL), 1091 corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE}) 1092 end. 1093 1094ifrid_to_name([], Type) -> 1095 orber:dbg("[~p] ~p:ifrid_to_name([], ~p). No Id supplied.", 1096 [?LINE, ?MODULE, Type], ?DEBUG_LEVEL), 1097 corba:raise(#'MARSHAL'{minor=(?CORBA_OMGVMCID bor 11), 1098 completion_status=?COMPLETED_MAYBE}); 1099ifrid_to_name(Id, Type) -> 1100 case orber:light_ifr() of 1101 true -> 1102 orber_ifr:get_module(Id, Type); 1103 false -> 1104 case catch ifrid_to_name_helper(Id, Type) of 1105 {'EXCEPTION', E} -> 1106 corba:raise(E); 1107 {'EXIT',{aborted,{no_exists,_}}} -> 1108 case orber:get_lightweight_nodes() of 1109 false -> 1110 orber:dbg("[~p] cdr_decode:ifrid_to_name(~p, ~p). IFRid not found.", 1111 [?LINE, Id, Type], ?DEBUG_LEVEL), 1112 corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE}); 1113 Nodes -> 1114 L = length(Nodes), 1115 IFR = get_ifr_node(Nodes, rand:uniform(L), L), 1116 list_to_atom('OrberApp_IFR':get_absolute_name(IFR, Id)) 1117 end; 1118 {'EXIT', Other} -> 1119 orber:dbg("[~p] cdr_decode:ifrid_to_name(~p). Unknown: ~p", 1120 [?LINE, Id, Other], ?DEBUG_LEVEL), 1121 corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE}); 1122 Name -> 1123 list_to_atom(Name) 1124 end 1125 end. 1126 1127ifrid_to_name_helper(Id, ?IFR_UnionDef) -> 1128 case mnesia:dirty_index_read(ir_UnionDef, Id, #ir_UnionDef.id) of 1129 [#ir_UnionDef{absolute_name = [$:,$:|N]}] -> 1130 change_colons_to_underscore(N, []); 1131 Other -> 1132 orber:dbg("[~p] cdr_decode:ifrid_to_name(~p). IFR Id not found: ~p", 1133 [?LINE, Id, Other], ?DEBUG_LEVEL), 1134 corba:raise(#'MARSHAL'{minor=(?ORBER_VMCID bor 9), 1135 completion_status=?COMPLETED_MAYBE}) 1136 end; 1137ifrid_to_name_helper(Id, ?IFR_StructDef) -> 1138 case mnesia:dirty_index_read(ir_StructDef, Id, #ir_StructDef.id) of 1139 [#ir_StructDef{absolute_name = [$:,$:|N]}] -> 1140 change_colons_to_underscore(N, []); 1141 Other -> 1142 orber:dbg("[~p] cdr_decode:ifrid_to_name(~p). IFR Id not found: ~p", 1143 [?LINE, Id, Other], ?DEBUG_LEVEL), 1144 corba:raise(#'MARSHAL'{minor=(?ORBER_VMCID bor 10), 1145 completion_status=?COMPLETED_MAYBE}) 1146 end; 1147ifrid_to_name_helper(Id, ?IFR_ExceptionDef) -> 1148 case mnesia:dirty_index_read(ir_ExceptionDef, Id, #ir_ExceptionDef.id) of 1149 [#ir_ExceptionDef{absolute_name = [$:,$:|N]}] -> 1150 change_colons_to_underscore(N, []); 1151 Other -> 1152 orber:dbg("[~p] cdr_decode:ifrid_to_name(~p). IFR Id not found: ~p", 1153 [?LINE, Id, Other], ?DEBUG_LEVEL), 1154 corba:raise(#'UNKNOWN'{minor=(?CORBA_OMGVMCID bor 1), 1155 completion_status=?COMPLETED_MAYBE}) 1156 end. 1157 1158change_colons_to_underscore([$:, $: | T], Acc) -> 1159 change_colons_to_underscore(T, [$_ |Acc]); 1160change_colons_to_underscore([H |T], Acc) -> 1161 change_colons_to_underscore(T, [H |Acc]); 1162change_colons_to_underscore([], Acc) -> 1163 lists:reverse(Acc). 1164 1165get_ifr_node([], _, _) -> 1166 %% Were not able to contact any of the given nodes. 1167 orber:dbg("[~p] cdr_decode:get_ifr_node([]). No Node available.", 1168 [?LINE], ?DEBUG_LEVEL), 1169 corba:raise(#'INTERNAL'{minor=(?ORBER_VMCID bor 1), completion_status=?COMPLETED_MAYBE}); 1170get_ifr_node(Nodes, N, L) -> 1171 Node = lists:nth(N, Nodes), 1172 case catch corba:resolve_initial_references_remote("OrberIFR", [Node]) of 1173 IFR when is_record(IFR, 'IOP_IOR') -> 1174 IFR; 1175 _ -> 1176 %% Not able to commincate with the node. Try next one. 1177 NewL = L-1, 1178 get_ifr_node(lists:delete(Node, Nodes), rand:uniform(NewL), NewL) 1179 end. 1180 1181 1182%%----------------------------------------------------------------- 1183%% Func: dec_objref/4 1184%%----------------------------------------------------------------- 1185dec_objref(Version, Message, Len, ByteOrder) -> 1186 dec_objref(Version, Message, Len, ByteOrder, [], 0). 1187dec_objref(Version, Message, Len, ByteOrder, _Buff, C) -> 1188 {IOR, Rest, Length} = iop_ior:decode(Version, Message, Len, ByteOrder), 1189 {IOR, Rest, Length, C+Length-Len}. 1190 1191%%----------------------------------------------------------------- 1192%% Func: dec_system_exception/4 and dec_user_exception/4 1193%%----------------------------------------------------------------- 1194dec_system_exception(Version, Message, Len, ByteOrder) when Version == {1,2} -> 1195 {Rest0, Len0, _Counter} = dec_align(Message, Len, 8, Len), 1196 {TypeId, Rest1, Len1} = dec_type({'tk_string', 0}, Version, Rest0, Len0, ByteOrder), 1197 Name = orber_exceptions:get_name(TypeId, ?SYSTEM_EXCEPTION), 1198 {Struct, _Rest2, Len2} = 1199 dec_exception_1(Version, [{"minor",'tk_ulong'}, 1200 {"completed", 1201 {'tk_enum', "", "completion_status", 1202 ["COMPLETED_YES", "COMPLETED_NO", 1203 "COMPLETED_MAYBE"]}}], 1204 Rest1, Len1, ByteOrder), 1205 {list_to_tuple([Name, "" |Struct]), Len2}; 1206dec_system_exception(Version, Message, Len, ByteOrder) -> 1207 {TypeId, Rest1, Len1} = dec_type({'tk_string', 0}, Version, Message, Len, ByteOrder), 1208 Name = orber_exceptions:get_name(TypeId, ?SYSTEM_EXCEPTION), 1209 {Struct, _Rest2, Len2} = 1210 dec_exception_1(Version, [{"minor",'tk_ulong'}, 1211 {"completed", 1212 {'tk_enum', "", "completion_status", 1213 ["COMPLETED_YES", "COMPLETED_NO", 1214 "COMPLETED_MAYBE"]}}], 1215 Rest1, Len1, ByteOrder), 1216 {list_to_tuple([Name, "" |Struct]), Len2}. 1217 1218dec_user_exception(Version, Message, Len, ByteOrder) when Version == {1,2} -> 1219 {Rest0, Len0, _Counter} = dec_align(Message, Len, 8, Len), 1220 {TypeId, Rest1, Len1} = dec_type({'tk_string', 0}, Version, Rest0, Len0, ByteOrder), 1221 Name = ifrid_to_name(TypeId, ?IFR_ExceptionDef), 1222 {'tk_except', _, _, ElementList} = get_user_exception_type(TypeId), 1223 {Struct, _Rest2, Len2} = dec_exception_1(Version, ElementList, Rest1, Len1, 1224 ByteOrder), 1225 {list_to_tuple([Name, TypeId |Struct]), Len2}; 1226dec_user_exception(Version, Message, Len, ByteOrder) -> 1227 {TypeId, Rest1, Len1} = dec_type({'tk_string', 0}, Version, Message, Len, ByteOrder), 1228 Name = ifrid_to_name(TypeId, ?IFR_ExceptionDef), 1229 {'tk_except', _, _, ElementList} = get_user_exception_type(TypeId), 1230 {Struct, _Rest2, Len2} = dec_exception_1(Version, ElementList, Rest1, Len1, 1231 ByteOrder), 1232 {list_to_tuple([Name, TypeId |Struct]), Len2}. 1233 1234dec_exception_1(_, [], Message, Len, _ByteOrder) -> 1235 {[], Message, Len}; 1236dec_exception_1(Version, [{_ElemName, ElemType} | ElementList], Message, 1237 Len, ByteOrder) -> 1238 {Element, Rest, Len1} = dec_type(ElemType, Version, Message, Len, ByteOrder), 1239 {Struct, Rest1, Len2} = dec_exception_1(Version, ElementList, Rest, Len1, 1240 ByteOrder), 1241 {[Element |Struct], Rest1, Len2}. 1242 1243 1244get_user_exception_type(TypeId) -> 1245 case orber:light_ifr() of 1246 true -> 1247 orber_ifr:get_tc(TypeId, ?IFR_ExceptionDef); 1248 false -> 1249 case orber:get_lightweight_nodes() of 1250 false -> 1251 case mnesia:dirty_index_read(ir_ExceptionDef, TypeId, 1252 #ir_ExceptionDef.id) of 1253 [ExcDef] when is_record(ExcDef, ir_ExceptionDef) -> 1254 ExcDef#ir_ExceptionDef.type; 1255 Other -> 1256 orber:dbg("[~p] cdr_decode:get_user_exception_type(~p). IFR Id not found: ~p", 1257 [?LINE, TypeId, Other], ?DEBUG_LEVEL), 1258 corba:raise(#'UNKNOWN'{minor=(?CORBA_OMGVMCID bor 1), 1259 completion_status=?COMPLETED_MAYBE}) 1260 end; 1261 Nodes -> 1262 L = length(Nodes), 1263 IFR = get_ifr_node(Nodes, rand:uniform(L), L), 1264 'OrberApp_IFR':get_user_exception_type(IFR, TypeId) 1265 end 1266 end. 1267 1268%%----------------------------------------------------------------- 1269%% Func: dec_type_code/4 1270%%----------------------------------------------------------------- 1271dec_type_code(Version, Message, Len, ByteOrder, Buff, C) -> 1272 {TypeNo, Message1, Len1, NewC} = dec_type('tk_ulong', Version, Message, Len, ByteOrder, Buff, C), 1273 TC = dec_type_code(TypeNo, Version, Message1, Len1, ByteOrder, Buff, NewC), 1274 erase(orber_indirection), 1275 TC. 1276 1277%%----------------------------------------------------------------- 1278%% Func: dec_type_code/5 1279%%----------------------------------------------------------------- 1280dec_type_code(0, _, Message, Len, _, _, C) -> 1281 {'tk_null', Message, Len, C}; 1282dec_type_code(1, _, Message, Len, _, _, C) -> 1283 {'tk_void', Message, Len, C}; 1284dec_type_code(2, _, Message, Len, _, _, C) -> 1285 {'tk_short', Message, Len, C}; 1286dec_type_code(3, _, Message, Len, _, _, C) -> 1287 {'tk_long', Message, Len, C}; 1288dec_type_code(23, _, Message, Len, _, _, C) -> 1289 {'tk_longlong', Message, Len, C}; 1290dec_type_code(25, _, Message, Len, _, _, C) -> 1291 {'tk_longdouble', Message, Len, C}; 1292dec_type_code(4, _, Message, Len, _, _, C) -> 1293 {'tk_ushort', Message, Len, C}; 1294dec_type_code(5, _, Message, Len, _, _, C) -> 1295 {'tk_ulong', Message, Len, C}; 1296dec_type_code(24, _, Message, Len, _, _, C) -> 1297 {'tk_ulonglong', Message, Len, C}; 1298dec_type_code(6, _, Message, Len, _, _, C) -> 1299 {'tk_float', Message, Len, C}; 1300dec_type_code(7, _, Message, Len, _, _, C) -> 1301 {'tk_double', Message, Len, C}; 1302dec_type_code(8, _, Message, Len, _, _, C) -> 1303 {'tk_boolean', Message, Len, C}; 1304dec_type_code(9, _, Message, Len, _, _, C) -> 1305 {'tk_char', Message, Len, C}; 1306dec_type_code(26, _, Message, Len, _, _, C) -> 1307 {'tk_wchar', Message, Len, C}; 1308dec_type_code(10, _, Message, Len, _, _, C) -> 1309 {'tk_octet', Message, Len, C}; 1310dec_type_code(11, _, Message, Len, _, _, C) -> 1311 {'tk_any', Message, Len, C}; 1312dec_type_code(12, _, Message, Len, _, _, C) -> 1313 {'tk_TypeCode', Message, Len, C}; 1314dec_type_code(13, _, Message, Len, _, _, C) -> 1315 {'tk_Principal', Message, Len, C}; 1316dec_type_code(14, Version, Message, Len, ByteOrder, Buff, C) -> 1317 {ComplexParams, Message1, Len1, Ex} = decode_complex_tc_parameters(Version, Message, Len, ByteOrder), 1318 %% Decode marshalled parameters, eg get the byteorder first 1319 {ByteOrder1, Rest1} = dec_byte_order(ComplexParams), 1320 {{RepId, Name}, <<>>, _Len2, NewC} = 1321 dec_type({'tk_struct', "", "", [{"repository ID", {'tk_string', 0}}, 1322 {"name", {'tk_string', 0}}]}, 1323 Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex), 1324 {{'tk_objref', RepId, Name}, Message1, Len1, NewC}; 1325dec_type_code(15, Version, Message, Len, ByteOrder, Buff, C) -> 1326 {ComplexParams, Message1, Len1, Ex} = decode_complex_tc_parameters(Version, Message, Len, ByteOrder), 1327 %% Decode marshalled parameters, eg get the byteorder first 1328 {ByteOrder1, Rest1} = dec_byte_order(ComplexParams), 1329 {{RepId, Name, ElementList}, <<>>, _Len2, NewC} = 1330 dec_type({'tk_struct', "", "", 1331 [{"repository ID", {'tk_string', 0}}, 1332 {"name", {'tk_string', 0}}, 1333 {"element list", 1334 {'tk_sequence', {'tk_struct', "","", 1335 [{"member name", {'tk_string', 0}}, 1336 {"member type", 'tk_TypeCode'}]}, 1337 0}}]}, 1338 Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex), 1339 {{'tk_struct', RepId, Name, ElementList}, Message1, Len1, NewC}; 1340dec_type_code(16, Version, Message, Len, ByteOrder, Buff, C) -> 1341 {ComplexParams, Message1, Len1, Ex} = decode_complex_tc_parameters(Version, Message, Len, ByteOrder), 1342 %% Decode marshalled parameters, eg get the byteorder first 1343 {ByteOrder1, Rest1} = dec_byte_order(ComplexParams), 1344 {{RepId, Name, DiscrTC, Default}, Rest2, RestLen2, NewC} = 1345 dec_type({'tk_struct', "", "", 1346 [{"repository ID", {'tk_string', 0}}, 1347 {"name", {'tk_string', 0}}, 1348 {"discriminant type", 'tk_TypeCode'}, 1349 {"default used", 'tk_long'}]}, 1350 Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex), 1351 {ElementList, <<>>, _RestLen3, NewC2} = 1352 dec_type({'tk_sequence', {'tk_struct', "","", 1353 [{"label value", DiscrTC}, 1354 {"member name", {'tk_string', 0}}, 1355 {"member type", 'tk_TypeCode'}]}, 0}, 1356 Version, Rest2, RestLen2, ByteOrder1, Buff, NewC), 1357 NewElementList = 1358 case check_enum(DiscrTC) of 1359 true -> 1360 lists:map(fun({L,N,T}) -> {atom_to_list(L),N,T} end, ElementList); 1361 false -> 1362 ElementList 1363 end, 1364 {{'tk_union', RepId, Name, DiscrTC, Default, NewElementList}, Message1, Len1, NewC2}; 1365dec_type_code(17, Version, Message, Len, ByteOrder, Buff, C) -> 1366 {ComplexParams, Message1, Len1, Ex} = decode_complex_tc_parameters(Version, Message, Len, ByteOrder), 1367 %% Decode marshalled parameters, eg get the byteorder first 1368 {ByteOrder1, Rest1} = dec_byte_order(ComplexParams), 1369 {{RepId, Name, ElementList}, <<>>, _Len2, NewC} = 1370 dec_type({'tk_struct', "", "", 1371 [{"repository ID", {'tk_string', 0}}, 1372 {"name", {'tk_string', 0}}, 1373 {"element list", 1374 {'tk_sequence', {'tk_string', 0}, 0}}]}, 1375 Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex), 1376 {{'tk_enum', RepId, Name, ElementList}, Message1, Len1, NewC}; 1377dec_type_code(18, Version, Message, Len, ByteOrder, Buff, C) -> 1378 {MaxLength, Message1, Len1, NewC} = 1379 dec_type('tk_ulong', Version, Message, Len, ByteOrder, Buff, C), 1380 {{'tk_string', MaxLength}, Message1, Len1, NewC}; 1381dec_type_code(19, Version, Message, Len, ByteOrder, Buff, C) -> 1382 {ComplexParams, Message1, Len1, Ex} = decode_complex_tc_parameters(Version, Message, Len, ByteOrder), 1383 %% Decode marshalled parameters, eg get the byteorder first 1384 {ByteOrder1, Rest1} = dec_byte_order(ComplexParams), 1385 {{ElemTC, MaxLength}, <<>>, _Len2, NewC} = 1386 dec_type({'tk_struct', "", "", [{"element type", 'tk_TypeCode'}, 1387 {"max length", 'tk_ulong'}]}, 1388 Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex), 1389 {{'tk_sequence', ElemTC, MaxLength}, Message1, Len1, NewC}; 1390dec_type_code(20, Version, Message, Len, ByteOrder, Buff, C) -> 1391 {ComplexParams, Message1, Len1, Ex} = decode_complex_tc_parameters(Version, Message, Len, ByteOrder), 1392 %% Decode marshalled parameters, eg get the byteorder first 1393 {ByteOrder1, Rest1} = dec_byte_order(ComplexParams), 1394 {{ElemTC, Length}, <<>>, _Len2, NewC} = 1395 dec_type({'tk_struct', "", "", [{"element type", 'tk_TypeCode'}, 1396 {"length", 'tk_ulong'}]}, 1397 Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex), 1398 {{'tk_array', ElemTC, Length}, Message1, Len1, NewC}; 1399dec_type_code(21, Version, Message, Len, ByteOrder, Buff, C) -> 1400 {ComplexParams, Message1, Len1, Ex} = decode_complex_tc_parameters(Version, Message, Len, ByteOrder), 1401 %% Decode marshalled parameters, eg ge a byteorder first 1402 {ByteOrder1, Rest1} = dec_byte_order(ComplexParams), 1403 {{RepId, Name, TC}, <<>>, _Len2, NewC} = 1404 dec_type({'tk_struct', "", "", [{"repository ID", {'tk_string', 0}}, 1405 {"name", {'tk_string', 0}}, 1406 {"TypeCode", 'tk_TypeCode'}]}, 1407 Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex), 1408 {{'tk_alias', RepId, Name, TC}, Message1, Len1, NewC}; 1409dec_type_code(22, Version, Message, Len, ByteOrder, Buff, C) -> 1410 {ComplexParams, Message1, Len1, Ex} = decode_complex_tc_parameters(Version, Message, Len, ByteOrder), 1411 %% Decode marshalled parameters, eg get the byteorder first 1412 {ByteOrder1, Rest1} = dec_byte_order(ComplexParams), 1413 {{RepId, Name, ElementList}, <<>>, _Len2, NewC} = 1414 dec_type({'tk_struct', "", "", 1415 [{"repository ID", {'tk_string', 0}}, 1416 {"name", {'tk_string', 0}}, 1417 {"element list", 1418 {'tk_sequence', {'tk_struct', "","", 1419 [{"member name", {'tk_string', 0}}, 1420 {"member type", 'tk_TypeCode'}]}, 1421 0}}]}, 1422 Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex), 1423 {{'tk_except', RepId, Name, ElementList}, Message1, Len1, NewC}; 1424dec_type_code(27, Version, Message, Len, ByteOrder, Buff, C) -> 1425 {MaxLength, Message1, Len1, NewC} = 1426 dec_type('tk_ulong', Version, Message, Len, ByteOrder, Buff, C), 1427 {{'tk_wstring', MaxLength}, Message1, Len1, NewC}; 1428dec_type_code(28, Version, Message, Len, ByteOrder, Buff, C) -> 1429 {Digits, Message1, Len1, C1} = 1430 dec_type('tk_ushort', Version, Message, Len, ByteOrder, Buff, C), 1431 {Scale, Message2, Len2, C2} = 1432 dec_type('tk_short', Version, Message1, Len1, ByteOrder, Buff, C1), 1433 {{'tk_fixed', Digits, Scale}, Message2, Len2, C2}; 1434dec_type_code(29, Version, Message, Len, ByteOrder, Buff, C) -> 1435 {ComplexParams, Message1, Len1, Ex} = decode_complex_tc_parameters(Version, Message, Len, ByteOrder), 1436 {ByteOrder1, Rest1} = dec_byte_order(ComplexParams), 1437 {{RepId, Name, ValueModifier, TC, ElementList}, <<>>, _Len2, NewC} = 1438 dec_type({'tk_struct', "", "", [{"repository ID", {'tk_string', 0}}, 1439 {"name", {'tk_string', 0}}, 1440 {"ValueModifier", 'tk_short'}, 1441 {"TypeCode", 'tk_TypeCode'}, 1442 {"element list", 1443 {'tk_sequence', 1444 {'tk_struct', "","", 1445 [{"member name", {'tk_string', 0}}, 1446 {"member type", 'tk_TypeCode'}, 1447 {"Visibility", 'tk_short'}]}, 1448 0}}]}, 1449 Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex), 1450 {{'tk_value', RepId, Name, ValueModifier, TC, ElementList}, Message1, Len1, NewC}; 1451dec_type_code(30, Version, Message, Len, ByteOrder, Buff, C) -> 1452 {ComplexParams, Message1, Len1, Ex} = decode_complex_tc_parameters(Version, Message, Len, ByteOrder), 1453 {ByteOrder1, Rest1} = dec_byte_order(ComplexParams), 1454 {{RepId, Name, TC}, <<>>, _Len2, NewC} = 1455 dec_type({'tk_struct', "", "", [{"repository ID", {'tk_string', 0}}, 1456 {"name", {'tk_string', 0}}, 1457 {"TypeCode", 'tk_TypeCode'}]}, 1458 Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex), 1459 {{'tk_value_box', RepId, Name, TC}, Message1, Len1, NewC}; 1460dec_type_code(31, Version, Message, Len, ByteOrder, Buff, C) -> 1461 {ComplexParams, Message1, Len1, Ex} = decode_complex_tc_parameters(Version, Message, Len, ByteOrder), 1462 {ByteOrder1, Rest1} = dec_byte_order(ComplexParams), 1463 {{RepId, Name}, <<>>, _Len2, NewC} = 1464 dec_type({'tk_struct', "", "", [{"repository ID", {'tk_string', 0}}, 1465 {"name", {'tk_string', 0}}]}, 1466 Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex), 1467 {{'tk_native', RepId, Name}, Message1, Len1, NewC}; 1468dec_type_code(32, Version, Message, Len, ByteOrder, Buff, C) -> 1469 {ComplexParams, Message1, Len1, Ex} = decode_complex_tc_parameters(Version, Message, Len, ByteOrder), 1470 {ByteOrder1, Rest1} = dec_byte_order(ComplexParams), 1471 {{RepId, Name}, <<>>, _Len2, NewC} = 1472 dec_type({'tk_struct', "", "", [{"RepositoryId", {'tk_string', 0}}, 1473 {"name", {'tk_string', 0}}]}, 1474 Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex), 1475 {{'tk_abstract_interface', RepId, Name}, Message1, Len1, NewC}; 1476dec_type_code(33, Version, Message, Len, ByteOrder, Buff, C) -> 1477 {ComplexParams, Message1, Len1, Ex} = decode_complex_tc_parameters(Version, Message, Len, ByteOrder), 1478 {ByteOrder1, Rest1} = dec_byte_order(ComplexParams), 1479 {{RepId, Name}, <<>>, _Len2, NewC} = 1480 dec_type({'tk_struct', "", "", [{"RepositoryId", {'tk_string', 0}}, 1481 {"name", {'tk_string', 0}}]}, 1482 Version, Rest1, 1, ByteOrder1, Buff, C+1+Ex), 1483 {{'tk_local_interface', RepId, Name}, Message1, Len1, NewC}; 1484dec_type_code(16#ffffffff, Version, Message, Len, ByteOrder, Buff, C) -> 1485 {Indirection, Message1, Len1, NewC} = 1486 dec_type('tk_long', Version, Message, Len, ByteOrder, Buff, C), 1487 Position = C+Indirection, 1488 case put(orber_indirection, Position) of 1489 Position -> 1490%% {{'none', Indirection}, Message1, Len1, NewC}; 1491 %% Recursive TypeCode. Break the loop. 1492 orber:dbg("[~p] cdr_decode:dec_type_code(~p); Recursive TC not supported.", 1493 [?LINE,Position], ?DEBUG_LEVEL), 1494 corba:raise(#'MARSHAL'{completion_status=?COMPLETED_NO}); 1495 _ -> 1496 <<_:Position/binary, SubBuff/binary>> = Buff, 1497 {TC, _, _, _} = dec_type_code(Version, SubBuff, Position, ByteOrder, Buff, Position), 1498 {TC, Message1, Len1, NewC} 1499 end; 1500dec_type_code(Type, _, _, _, _, _, _) -> 1501 orber:dbg("[~p] cdr_decode:dec_type_code(~p); No match.", 1502 [?LINE, Type], ?DEBUG_LEVEL), 1503 corba:raise(#'MARSHAL'{minor=(?ORBER_VMCID bor 8), completion_status=?COMPLETED_MAYBE}). 1504 1505check_enum({'tk_enum', _, _, _}) -> 1506 true; 1507check_enum(_) -> 1508 false. 1509 1510 1511decode_complex_tc_parameters(_Version, Message, Len, ByteOrder) -> 1512 {Rest, Len1, NewC} = dec_align(Message, Len, 4, 0), 1513 {Size, Rest1} = cdrlib:dec_unsigned_long(ByteOrder, Rest), 1514 <<OctetSeq:Size/binary, Rest2/binary>> = Rest1, 1515 {OctetSeq, Rest2, Len1+4+Size, NewC+4}. 1516 1517%%----------------------------------------------------------------- 1518%% Func: dec_align/3 1519%% Args: 1520%% R - The byte sequence that shall be aligned. 1521%% Len - The number of bytes read so far. 1522%% Alignment - The alignment as an integer (for example: 2,4,8). 1523%% Returns: 1524%% An aligned byte sequence. 1525%%----------------------------------------------------------------- 1526dec_align(R, Len, Alignment, C) -> 1527 Rem = Len rem Alignment, 1528 if Rem == 0 -> 1529 {R, Len, C}; 1530 true -> 1531 Diff = Alignment - Rem, 1532 <<_:Diff/binary,Rest/binary>> = R, 1533 {Rest, Len + Diff, C + Diff} 1534 end. 1535 1536%%---------------- EOF MODULE ---------------------------------------- 1537