cdr_encode.erl

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

ERL
1,146
字号
    {cdrlib:enc_unsigned_longlong(Value, Rest), Len1 + 8};enc_type('tk_float', _Env, Value, Bytes, Len) ->    {Rest, Len1} = enc_align(Bytes, Len, 4),    {cdrlib:enc_float(Value, Rest), Len1 + 4};enc_type('tk_double', _Env, Value, Bytes, Len) ->    {Rest, Len1} = enc_align(Bytes, Len, 8),    {cdrlib:enc_double(Value, Rest), Len1 + 8};enc_type('tk_boolean', _Env, Value, Bytes, Len) ->    {cdrlib:enc_bool(Value, Bytes), Len + 1};enc_type('tk_char', _Env, Value, Bytes, Len) ->    {cdrlib:enc_char(Value, Bytes), Len + 1};%% The wchar decoding can be 1, 2 or 4 bytes but for now we only accept 2.enc_type('tk_wchar', #giop_env{version = {1,2}}, Value, Bytes, Len) ->    Bytes1 = cdrlib:enc_octet(2, Bytes),    {cdrlib:enc_unsigned_short(Value, Bytes1), Len + 3};enc_type('tk_wchar', _Env, Value, Bytes, Len) ->    {Rest, Len1} = enc_align(Bytes, Len, 2),    {cdrlib:enc_unsigned_short(Value, Rest), Len1 + 2};enc_type('tk_octet', _Env, Value, Bytes, Len) ->    {cdrlib:enc_octet(Value, Bytes), Len + 1};enc_type('tk_any', Env, Any, Bytes, Len) when record(Any, any) ->    {Rest, Len1} = enc_type('tk_TypeCode', Env, Any#any.typecode, Bytes, Len),    enc_type(Any#any.typecode, Env, Any#any.value, Rest, Len1);enc_type('tk_TypeCode', Env, Value, Bytes, Len) ->    enc_type_code(Value, Env, Bytes, Len);enc_type('tk_Principal', Env, Value, Bytes, Len) ->    %% Set MaxLength no 0 (i.e. unlimited).    enc_sequence(Env, Value, 0, 'tk_octet', Bytes, Len);enc_type({'tk_objref', _IFRId, Name}, Env, Value, Bytes, Len) ->    enc_objref(Env, Name,Value, Bytes, Len);enc_type({'tk_struct', _IFRId, _Name, ElementList}, Env, Value, Bytes, Len) ->     enc_struct(Env, Value, ElementList, Bytes, Len);enc_type({'tk_union', _IFRId, _Name, DiscrTC, Default, ElementList},	Env, Value, Bytes, Len) ->    enc_union(Env, Value, DiscrTC, Default, ElementList, Bytes, Len);enc_type({'tk_enum', _IFRId, _Name, ElementList}, _Env, Value, Bytes, Len) ->    {Rest, Len1} = enc_align(Bytes, Len, 4),    {cdrlib:enc_enum(atom_to_list(Value), ElementList, Rest), Len1 + 4};enc_type({'tk_string', MaxLength}, Env, Value, Bytes, Len) ->    enc_string(Env, Value, MaxLength, Bytes, Len);enc_type({'tk_wstring', MaxLength}, Env, Value, Bytes, Len) ->    enc_wstring(Env, Value, MaxLength, Bytes, Len);enc_type({'tk_sequence', ElemTC, MaxLength}, Env, Value, Bytes, Len) ->    enc_sequence(Env, Value, MaxLength, ElemTC, Bytes, Len);enc_type({'tk_array', ElemTC, Size}, Env, Value, Bytes, Len) ->     enc_array(Env, Value, Size, ElemTC, Bytes, Len);enc_type({'tk_alias', _IFRId, _Name, TC}, Env, Value, Bytes, Len) ->    enc_type(TC, Env, Value, Bytes, Len);enc_type({'tk_except', IFRId, Name, ElementList}, Env, Value, Bytes, Len) ->    enc_exception(Env, Name, IFRId, Value, ElementList, Bytes, Len);enc_type({'tk_fixed', Digits, Scale}, Env, Value, Bytes, Len) ->    enc_fixed(Env, Digits, Scale, Value, Bytes, Len);enc_type(Type, _, Value, _, _) ->    orber:dbg("[~p] cdr_encode:type(~p, ~p)~n"	      "Incorrect TypeCode or unsupported type.", 	      [?LINE, Type, Value], ?DEBUG_LEVEL),    corba:raise(#'MARSHAL'{minor=(?ORBER_VMCID bor 13), completion_status=?COMPLETED_MAYBE}).%%-----------------------------------------------------------------%% Func: enc_fixed%%-----------------------------------------------------------------%% Digits eq. total number of digits.%% Scale  eq. position of the decimal point.%% E.g. fixed<5,2> - "123.45" eq. #fixed{digits = 5, scale = 2, value = 12345}%% E.g. fixed<4,2> - "12.34"  eq. #fixed{digits = 4, scale = 2, value = 1234}%% 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.enc_fixed(Env, Digits, Scale, 	  #fixed{digits = Digits, scale = Scale, value = Value}, Bytes, Len)   when integer(Value), integer(Digits), integer(Scale), Digits < 32, Digits >= Scale ->    %% This isn't very efficient and we should improve it before supporting it    %% officially.    Odd = ?ODD(Digits),    case integer_to_list(Value) of	[$-|ValueList] when Odd == true ->	    Padded = lists:duplicate((Digits-length(ValueList)), 0) ++ ValueList,	    enc_fixed_2(Env, Digits, Scale, Padded, 			Bytes, Len, ?FIXED_NEGATIVE);	[$-|ValueList] ->	    Padded = lists:duplicate((Digits-length(ValueList)), 0) ++ ValueList,	    enc_fixed_2(Env, Digits, Scale, [0|Padded], 			Bytes, Len, ?FIXED_NEGATIVE);	ValueList when Odd == true ->	    Padded = lists:duplicate((Digits-length(ValueList)), 0) ++ ValueList,	    enc_fixed_2(Env, Digits, Scale, Padded, 			Bytes, Len, ?FIXED_POSITIVE);	ValueList ->	    Padded = lists:duplicate((Digits-length(ValueList)), 0) ++ ValueList,	    enc_fixed_2(Env, Digits, Scale, [0|Padded], 			Bytes, Len, ?FIXED_POSITIVE)    end;enc_fixed(_Env, Digits, Scale, Fixed, _Bytes, _Len) ->    orber:dbg("[~p] cdr_encode:enc_fixed(~p, ~p, ~p)~n"	      "The supplied fixed type incorrect. Check that the 'digits' and 'scale' field~n"	      "match the definition in the IDL-specification. The value field must be~n"	      "a list of Digits lenght.", 	      [?LINE, Digits, Scale, Fixed], ?DEBUG_LEVEL),    corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE}).enc_fixed_2(_Env, _Digits, _Scale, [D1], Bytes, Len, Sign) ->    {[<<D1:4,Sign:4>>|Bytes], Len+1};enc_fixed_2(Env, Digits, Scale, [D1, D2|Ds], Bytes, Len, Sign) ->    %% We could convert the ASCII-value to digit values but the bit-syntax will    %% truncate it correctly.    enc_fixed_2(Env, Digits, Scale, Ds, [<<D1:4,D2:4>> | Bytes], Len+1, Sign);enc_fixed_2(_Env, Digits, Scale, Value, _Bytes, _Len, Sign) ->    orber:dbg("[~p] cdr_encode:enc_fixed_2(~p, ~p, ~p, ~p)~n"	      "The supplied fixed type incorrect. Most likely the 'digits' field don't match the~n"	      "supplied value. Hence, check that the value is correct.", 	      [?LINE, Digits, Scale, Value, Sign], ?DEBUG_LEVEL),    corba:raise(#'MARSHAL'{completion_status=?COMPLETED_MAYBE}). %%-----------------------------------------------------------------%% Func: enc_sequence/5%%-----------------------------------------------------------------%% This is a special case used when encoding encapsualted data, i.e., contained%% in an octet-sequence.enc_sequence(_Env, Sequence, MaxLength, 'tk_octet', Bytes, Len)  when binary(Sequence) ->    {ByteSequence, Len1} = enc_align(Bytes, Len, 4),    Size = size(Sequence),    if	Size > MaxLength, MaxLength > 0 ->	    orber:dbg("[~p] cdr_encode:enc_sequnce(~p, ~p). Sequence exceeds max.", 		      [?LINE, Sequence, MaxLength], ?DEBUG_LEVEL),	    corba:raise(#'MARSHAL'{minor=(?ORBER_VMCID bor 19), 				   completion_status=?COMPLETED_MAYBE});	true ->	    ByteSequence1 = cdrlib:enc_unsigned_long(Size, ByteSequence),	    {[Sequence |ByteSequence1], Len1 + 4 + Size}    end;enc_sequence(Env, Sequence, MaxLength, TypeCode, Bytes, Len) ->    Length = length(Sequence),    if	Length > MaxLength, MaxLength > 0 ->	    orber:dbg("[~p] cdr_encode:enc_sequnce(~p, ~p). Sequence exceeds max.", 		      [?LINE, Sequence, MaxLength], ?DEBUG_LEVEL),	    corba:raise(#'MARSHAL'{minor=(?ORBER_VMCID bor 19), 				   completion_status=?COMPLETED_MAYBE});	true ->	    {ByteSequence, Len1} = enc_align(Bytes, Len, 4),	    ByteSequence1 = cdrlib:enc_unsigned_long(Length, ByteSequence),	    enc_sequence1(Env, Sequence, TypeCode, ByteSequence1, Len1 + 4)    end.%%-----------------------------------------------------------------%% Func: enc_sequence1/4%%-----------------------------------------------------------------enc_sequence1(_Env, [], _TypeCode, Bytes, Len) ->    {Bytes, Len};enc_sequence1(_Env, CharSeq, 'tk_char', Bytes, Len) ->     {[list_to_binary(CharSeq) |Bytes], Len + length(CharSeq)};enc_sequence1(_Env, OctetSeq, 'tk_octet', Bytes, Len) ->     {[list_to_binary(OctetSeq) |Bytes], Len + length(OctetSeq)};enc_sequence1(Env, [Object| Rest], TypeCode, Bytes, Len) ->     {ByteSequence, Len1} = enc_type(TypeCode, Env, Object, Bytes, Len),    enc_sequence1(Env, Rest, TypeCode, ByteSequence, Len1).%%-----------------------------------------------------------------%% Func: enc_array/4%%-----------------------------------------------------------------enc_array(Env, Array, Size, TypeCode, Bytes, Len) when size(Array) == Size ->    Sequence = tuple_to_list(Array),    enc_sequence1(Env, Sequence, TypeCode, Bytes, Len);enc_array(_,Array, Size, _, _, _) ->    orber:dbg("[~p] cdr_encode:enc_array(~p, ~p). Incorrect size.", 	      [?LINE, Array, Size], ?DEBUG_LEVEL),    corba:raise(#'MARSHAL'{minor=(?ORBER_VMCID bor 15), completion_status=?COMPLETED_MAYBE}).%%-----------------------------------------------------------------%% Func: enc_string/4%%-----------------------------------------------------------------enc_string(_Env, String, MaxLength, Bytes, Len) ->    StrLen = length(String),    if	StrLen > MaxLength, MaxLength > 0 ->	    orber:dbg("[~p] cdr_encode:enc_string(~p, ~p). String exceeds max.", 		      [?LINE, String, MaxLength], ?DEBUG_LEVEL),	    corba:raise(#'MARSHAL'{minor=(?ORBER_VMCID bor 16), 				   completion_status=?COMPLETED_MAYBE});	true ->	    {ByteSequence, Len1} = enc_align(Bytes, Len, 4),	    ByteSequence1 = cdrlib:enc_unsigned_long(StrLen + 1, ByteSequence),	    {cdrlib:enc_octet(0, [String | ByteSequence1]), Len1 + StrLen + 5}    end.   %%-----------------------------------------------------------------%% Func: enc_wstring/4%%-----------------------------------------------------------------enc_wstring(#giop_env{version = {1,2}} = Env, String, MaxLength, Bytes, Len) ->    %% Encode the length of the string (ulong).    {Bytes1, Len1} = enc_align(Bytes, Len, 4),    %% For IIOP-1.2 the length is the total number of octets. Hence, since the wchar's    %% we accepts is encoded as <<255, 255>> the total size is 2*length of the list.    ListLen = length(String),    if	ListLen > MaxLength, MaxLength > 0 ->	    corba:raise(#'MARSHAL'{minor=(?ORBER_VMCID bor 16), 				   completion_status=?COMPLETED_MAYBE});	true ->	    StrLen = ListLen * 2,	    Bytes2 = cdrlib:enc_unsigned_long(StrLen, Bytes1),	    %% For IIOP-1.2 no terminating null character is used.	    enc_sequence1(Env, String, 'tk_ushort', Bytes2, Len1+4)    end;enc_wstring(Env, String, MaxLength, Bytes, Len) ->    %% Encode the length of the string (ulong).    {Bytes1, Len1} = enc_align(Bytes, Len, 4),    ListLen = length(String),    if	ListLen > MaxLength, MaxLength > 0 ->	    corba:raise(#'MARSHAL'{minor=(?ORBER_VMCID bor 16), 				   completion_status=?COMPLETED_MAYBE});	true ->	    StrLen = ListLen + 1,	    Bytes2 = cdrlib:enc_unsigned_long(StrLen, Bytes1),	    {Bytes3, Len3} = enc_sequence1(Env, String, 'tk_wchar', Bytes2, Len1+4),	    %% The terminating null character is also a wchar.	    {cdrlib:enc_unsigned_short(0, Bytes3), Len3+2}    end.%%-----------------------------------------------------------------%% Func: enc_union/5%%-----------------------------------------------------------------enc_union(Env, {_, Label, Value}, DiscrTC, Default, TypeCodeList, Bytes, Len) ->    {ByteSequence, Len1} = enc_type(DiscrTC, Env, Label, Bytes, Len),    Label2 = stringify_enum(DiscrTC,Label),    enc_union2(Env, {Label2, Value},TypeCodeList, Default, 	      ByteSequence, Len1, undefined).enc_union2(_Env, _What, [], Default, Bytes, Len, _) when Default < 0 ->    {Bytes, Len};enc_union2(Env, {_, Value}, [], _Default, Bytes, Len, Type) ->     enc_type(Type, Env, Value, Bytes, Len);enc_union2(Env, {Label,Value} ,[{Label, _Name, Type} |_List], 	   _Default, Bytes, Len, _) ->    enc_type(Type, Env, Value, Bytes, Len);enc_union2(Env, Union ,[{default, _Name, Type} |List], Default, Bytes, Len, _) ->    enc_union2(Env, Union, List, Default, Bytes, Len, Type);enc_union2(Env, Union,[_ | List], Default, Bytes, Len, DefaultType) ->    enc_union2(Env, Union, List, Default, Bytes, Len, DefaultType).stringify_enum({tk_enum, _,_,_}, Label) ->    atom_to_list(Label);stringify_enum(_, Label) ->    Label.%%-----------------------------------------------------------------%% Func: enc_struct/4%%-----------------------------------------------------------------enc_struct(Env, Struct, TypeCodeList, Bytes, Len) ->    [_Name | StructList] = tuple_to_list(Struct),    enc_struct1(Env, StructList, TypeCodeList, Bytes, Len).enc_struct1(_Env, [], [], Bytes, Len) ->    {Bytes, Len};enc_struct1(Env, [Object | Rest], [{_ElemName, ElemType} | TypeCodeList], Bytes,	    Len) ->    {ByteSequence, Len1} = enc_type(ElemType, Env, Object, Bytes, Len),    enc_struct1(Env, Rest, TypeCodeList, ByteSequence, Len1).%%-----------------------------------------------------------------%% Func: enc_objref/4%%-----------------------------------------------------------------enc_objref(Env, _Name, Value, Bytes, Len) ->     iop_ior:code(Env, Value, Bytes, Len).      %%-----------------------------------------------------------------%% Func: enc_exception/5%%-----------------------------------------------------------------enc_exception(Env, _Name, IFRId, Value, ElementList, Bytes, Len) ->    [_Name1, _TypeId | Args] = tuple_to_list(Value),    {Bytes1, Len1} = enc_type({'tk_string', 0}, Env, IFRId , Bytes, Len),    enc_exception_1(Env, Args, ElementList, Bytes1, Len1).

⌨️ 快捷键说明

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