1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 1999-2016. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20%% 21 22-module(ic_java_type). 23 24 25-include("icforms.hrl"). 26-include("ic.hrl"). 27-include("ic_debug.hrl"). 28%%----------------------------------------------------------------- 29%% External exports 30%%----------------------------------------------------------------- 31-export([getType/3, getHolderType/3, 32 getParamType/4, inlinedTypes/2, 33 marshalFun/4, unMarshalFun/4, getFullType/4, 34 getFullType/3, getMarshalType/4, getUnmarshalType/4, 35 getdim/1]). 36-export([isBasicType/3, isBasicType/1]). 37-export([isIntegerType/3, isIntegerType/1]). 38-export([isTermType/3]). 39 40%%----------------------------------------------------------------- 41%% Internal exports 42%%----------------------------------------------------------------- 43-export([]). 44 45%%----------------------------------------------------------------- 46%% External functions 47%%----------------------------------------------------------------- 48%%----------------------------------------------------------------- 49%% Func: getType/3 50%%----------------------------------------------------------------- 51getType(G, N, T) when is_record(T, scoped_id) -> 52 {FullScopedName, _, TK, _} = ic_symtab:get_full_scoped_name(G, N, T), 53 BT = ic_code:get_basetype(G, ic_util:to_dot(G,FullScopedName)), 54 case BT of 55 "erlang.pid" -> 56 ?ICPACKAGE ++ "Pid"; 57 "erlang.port" -> 58 ?ICPACKAGE ++ "Port"; 59 "erlang.ref" -> 60 ?ICPACKAGE ++ "Ref"; 61 "erlang.term" -> 62 ?ICPACKAGE ++ "Term"; 63 {enum, Type} -> 64 getType(G, N, Type); 65 Type -> 66 case TK of 67 {tk_array,_,_} -> 68 tk2type(G,N,T,TK); 69 {tk_sequence,_,_} -> 70 tk2type(G,N,T,TK); 71 tk_any -> 72 ?ICPACKAGE ++ "Any"; 73 _ -> 74 case isBasicType(G,N,TK) of 75 true -> 76 tk2type(G,N,T,TK); 77 false -> 78 Type %% Other types 79 end 80 end 81 end; 82 83getType(_G, _N, S) when is_list(S) -> 84 S; 85 86getType(_G, _N, T) when is_record(T, string) -> 87 "java.lang.String"; 88 89getType(_G, _N, T) when is_record(T, wstring) -> %% WSTRING 90 "java.lang.String"; 91 92getType(G, N, T) when is_record(T, struct) -> 93 ic_util:to_dot(G,[ic_forms:get_id2(T)|N]); 94 95getType(G, N, T) when is_record(T, union) -> 96 ic_util:to_dot(G,[ic_forms:get_id2(T)|N]); 97 98getType(G, N, T) when is_record(T, sequence) -> 99 getType(G, N, ic_forms:get_type(T)) ++ "[]"; 100 101getType(G, N, T) when is_record(T, enum) -> 102 ic_util:to_dot(G,[ic_forms:get_id2(T)|N]); 103 104%% NOTE i am using the new isJavaElementaryType 105%% to avoid members declared as keywords (except 106%% all java elementary types) to be used as a 107%% class 108getType(G, N, T) when is_record(T, member) -> 109 Type = tk2type(G,N,T,ic_forms:get_type_code(G, N, T)), 110 case isJavaElementaryType(list_to_atom(Type)) of 111 true -> 112 Type; 113 false -> 114 Prefix = list_to_atom(lists:flatten(string:tokens(Type,"[]"))), 115 case isJavaElementaryType(Prefix) of %% Checks if Type is an array 116 %% of elementary java types 117 true -> 118 Type; 119 false -> 120 ic_forms:get_java_id(getType(G,N,ic_forms:get_type(T))) ++ 121 if is_record(hd(T#member.id),array) -> 122 arrayEmptyDim(hd(T#member.id)); 123 true -> 124 "" 125 end 126 end 127 end; 128 129getType(_G, _N, {boolean, _}) -> 130 "boolean"; 131 132getType(_G, _N, {octet, _}) -> 133 "byte"; 134 135getType(_G, _N, {void, _}) -> 136 "void"; 137 138getType(_G, _N, {unsigned, U}) -> 139 case U of 140 {short,_} -> 141 "short"; 142 {long,_} -> 143 "int"; 144 {'long long',_} -> 145 "long" 146 end; 147 148getType(_G, _N, {char, _}) -> 149 "char"; 150 151getType(_G, _N, {wchar, _}) -> %% WCHAR 152 "char"; 153 154getType(_G, _N, {short, _}) -> 155 "short"; 156 157getType(_G, _N, {long, _}) -> 158 "int"; 159 160getType(_G, _N, {'long long', _}) -> 161 "long"; 162 163getType(_G, _N, {float, _}) -> 164 "float"; 165 166getType(_G, _N, {double, _}) -> 167 "double"; 168 169getType(_G, _N, {any, _}) -> 170 ?ICPACKAGE ++ "Any". 171 172 173 174 175 176 177%%----------------------------------------------------------------- 178%% Func: getHolderType/3 179%%----------------------------------------------------------------- 180getHolderType(G, N, T) when element(1, T) == scoped_id -> 181 {FullScopedName, _, TK, _} = ic_symtab:get_full_scoped_name(G, N, T), 182 BT = ic_code:get_basetype(G, ic_util:to_dot(G,FullScopedName)), 183 case BT of 184 "erlang.pid" -> 185 ?ICPACKAGE ++ "PidHolder"; 186 "erlang.port" -> 187 ?ICPACKAGE ++ "PortHolder"; 188 "erlang.ref" -> 189 ?ICPACKAGE ++ "RefHolder"; 190 "erlang.term" -> 191 ?ICPACKAGE ++ "TermHolder"; 192 {enum, Type} -> 193 getHolderType(G, N, Type); 194 195 Type -> 196 case TK of 197 {'tk_struct', _, _, _} -> 198 Type ++ "Holder"; 199 200 {'tk_union', _, _, _, _, _} -> 201 Type ++ "Holder"; 202 203 {'tk_array', _ , _} -> 204 Type ++ "Holder"; 205 206 {'tk_sequence', _ , _} -> 207 Type ++ "Holder"; 208 209 {'tk_string', _} -> 210 ?ICPACKAGE ++ "StringHolder"; 211 212 {'tk_wstring', _} -> %% WSTRING 213 ?ICPACKAGE ++ "StringHolder"; 214 215 {'tk_enum', _, _, _} -> 216 Type ++ "Holder"; 217 218 'tk_boolean' -> 219 ?ICPACKAGE ++ "BooleanHolder"; 220 221 'tk_octet' -> 222 ?ICPACKAGE ++ "ByteHolder"; 223 224 'tk_ushort' -> 225 ?ICPACKAGE ++ "ShortHolder"; 226 227 'tk_ulong' -> 228 ?ICPACKAGE ++ "IntHolder"; 229 230 'tk_ulonglong' -> %% ULLONG 231 ?ICPACKAGE ++ "LongHolder"; 232 233 'tk_short' -> 234 ?ICPACKAGE ++ "ShortHolder"; 235 236 'tk_long' -> 237 ?ICPACKAGE ++ "IntHolder"; 238 239 'tk_longlong' -> 240 ?ICPACKAGE ++ "LongHolder"; %% LLONG 241 242 'tk_float' -> 243 ?ICPACKAGE ++ "FloatHolder"; 244 245 'tk_double' -> 246 ?ICPACKAGE ++ "DoubleHolder"; 247 248 'tk_char' -> 249 ?ICPACKAGE ++ "CharHolder"; 250 251 'tk_wchar' -> %% WCHAR 252 ?ICPACKAGE ++ "CharHolder"; 253 254 'tk_any' -> 255 ?ICPACKAGE ++ "AnyHolder"; 256 257 _ -> 258 case isBasicType(G,N,TK) of 259 true -> 260 %% Faked the type ! 261 getHolderType(G, N, {list_to_atom(tk2type(G,N,T,TK)), -1}); 262 false -> 263 %%io:format("TK = ~p, Type = ~p\n",[TK,Type]), 264 ic_util:to_dot(G,FullScopedName) ++ "Holder" 265 end 266 end 267 end; 268 269getHolderType(G, N, S) when is_list(S) -> 270 ic_util:to_dot(G,[S|N]) ++ "Holder"; 271 272getHolderType(_G, _N, T) when is_record(T, string) -> 273 ?ICPACKAGE ++"StringHolder"; 274 275getHolderType(_G, _N, T) when is_record(T, wstring) -> %% WSTRING 276 ?ICPACKAGE ++"StringHolder"; 277 278getHolderType(G, N, T) when is_record(T, struct) -> 279 ic_util:to_dot(G,[ic_forms:get_id2(T)|N]) ++ "Holder"; 280 281getHolderType(G, N, T) when is_record(T, union) -> 282 ic_util:to_dot(G,[ic_forms:get_id2(T)|N]) ++ "Holder"; 283 284getHolderType(G, N, T) when is_record(T, array) -> 285 ic_util:to_dot(G,[ic_forms:get_id2(T)|N]) ++ "Holder"; 286 287getHolderType(G, N, T) when is_record(T, sequence) -> 288 getType(G, N, ic_forms:get_type(T)) ++ "Holder[]"; 289 290getHolderType(G, N, T) when is_record(T, enum) -> 291 ic_util:to_dot(G,[ic_forms:get_id2(T)|N]) ++ "Holder"; 292 293getHolderType(_G, _N, {boolean, _}) -> 294 ?ICPACKAGE ++"BooleanHolder"; 295 296getHolderType(_G, _N, {octet, _}) -> 297 ?ICPACKAGE ++"ByteHolder"; 298 299getHolderType(_G, _N, {void, _}) -> 300 "void"; 301 302getHolderType(_G, _N, {unsigned, U}) -> 303 case U of 304 {short,_} -> 305 ?ICPACKAGE ++"ShortHolder"; 306 {long,_} -> 307 ?ICPACKAGE ++"IntHolder"; 308 {'long long',_} -> 309 ?ICPACKAGE ++"LongHolder" 310 end; 311 312getHolderType(_G, _N, {char, _}) -> 313 ?ICPACKAGE ++"CharHolder"; 314 315getHolderType(_G, _N, {wchar, _}) -> %% WCHAR 316 ?ICPACKAGE ++"CharHolder"; 317 318getHolderType(_G, _N, {short, _}) -> 319 ?ICPACKAGE ++"ShortHolder"; 320 321getHolderType(_G, _N, {long, _}) -> 322 ?ICPACKAGE ++"IntHolder"; 323 324getHolderType(_G, _N, {'long long', _}) -> 325 ?ICPACKAGE ++"LongHolder"; 326 327getHolderType(_G, _N, {float, _}) -> 328 ?ICPACKAGE ++"FloatHolder"; 329 330getHolderType(_G, _N, {double, _}) -> 331 ?ICPACKAGE ++"DoubleHolder"; 332 333getHolderType(_G, _N, {any,_}) -> 334 ?ICPACKAGE ++ "AnyHolder". 335 336 337%%----------------------------------------------------------------- 338%% Func: getParamType/4 339%%----------------------------------------------------------------- 340getParamType(G, N, S, in) -> 341 getType(G, N, S); 342getParamType(G, N, S, ret) -> 343 getType(G, N, S); 344getParamType(G, N, S, out) -> 345 getHolderType(G, N, S); 346getParamType(G, N, S, inout) -> 347 getHolderType(G, N, S). 348 349 350%%----------------------------------------------------------------- 351%% Func: getUnmarshalType/4 352%%----------------------------------------------------------------- 353getUnmarshalType(G, N, X, T) when element(1, T) == scoped_id -> 354 {FullScopedName, _, TK, _} = ic_symtab:get_full_scoped_name(G, N, T), 355 BT = ic_code:get_basetype(G, ic_util:to_dot(G,FullScopedName)), 356 case BT of 357 "erlang.pid" -> 358 ?ICPACKAGE ++ "PidHelper"; 359 "erlang.port" -> 360 ?ICPACKAGE ++ "PortHelper"; 361 "erlang.ref" -> 362 ?ICPACKAGE ++ "RefHelper"; 363 "erlang.term" -> 364 ?ICPACKAGE ++ "TermHelper"; 365 {enum, Type} -> 366 getUnmarshalType(G, N, X, Type); 367 Type -> 368 case TK of 369 {'tk_struct', _, _, _} -> 370 Type ++ "Helper"; 371 372 {'tk_union', _, _, _, _, _} -> 373 Type ++ "Helper"; 374 375 {'tk_sequence', _ , _} -> 376 Type ++ "Helper"; 377 378 {'tk_array', _ , _} -> 379 Type ++ "Helper"; 380 381 {'tk_enum', _, _, _} -> 382 Type ++ "Helper"; 383 384 {'tk_string',_} -> 385 ?ERLANGPACKAGE ++ "OtpErlangString"; 386 387 {'tk_wstring',_} -> %% WSTRING 388 ?ERLANGPACKAGE ++ "OtpErlangString"; 389 390 'tk_char' -> 391 ?ERLANGPACKAGE ++ "OtpErlangLong"; 392 393 'tk_wchar' -> %% WCHAR 394 ?ERLANGPACKAGE ++ "OtpErlangLong"; 395 396 'tk_octet' -> 397 ?ERLANGPACKAGE ++ "OtpErlangLong"; 398 399 'tk_ushort' -> 400 ?ERLANGPACKAGE ++ "OtpErlangLong"; 401 402 'tk_ulong' -> 403 ?ERLANGPACKAGE ++ "OtpErlangLong"; 404 405 'tk_ulonglong' -> %% ULLONG 406 ?ERLANGPACKAGE ++ "OtpErlangLong"; 407 408 'tk_short' -> 409 ?ERLANGPACKAGE ++ "OtpErlangLong"; 410 411 'tk_long' -> 412 ?ERLANGPACKAGE ++ "OtpErlangLong"; 413 414 'tk_longlong' -> %% LLONG 415 ?ERLANGPACKAGE ++ "OtpErlangLong"; 416 417 'tk_float' -> 418 ?ERLANGPACKAGE ++ "OtpErlangDouble"; 419 420 'tk_double' -> 421 ?ERLANGPACKAGE ++ "OtpErlangDouble"; 422 423 'tk_boolean' -> 424 ?ERLANGPACKAGE ++ "OtpErlangAtom"; 425 426 'tk_void' -> 427 ?ERLANGPACKAGE ++ "OtpErlangAtom"; 428 429 'tk_any' -> 430 ?ICPACKAGE ++ "AnyHelper"; 431 432 _ -> 433 case isBasicType(G,N,TK) of 434 true -> 435 %% Faked the type ! 436 getUnmarshalType(G, N, X, {list_to_atom(tk2type(G,N,T,TK)), -1}); 437 false -> 438 ic_util:to_dot(G,FullScopedName) ++ "Helper" 439 end 440 end 441 end; 442 443getUnmarshalType(_G, _N, _X, S) when is_list(S) -> 444 S ++ "Helper"; 445 446getUnmarshalType(_G, _N, _X, T) when is_record(T, string) -> 447 ?ERLANGPACKAGE ++ "OtpErlangString"; 448 449getUnmarshalType(_G, _N, _X, T) when is_record(T, wstring) -> %% WSTRING 450 ?ERLANGPACKAGE ++ "OtpErlangString"; 451 452getUnmarshalType(G, N, _X, T) when is_record(T, struct) -> 453 ic_util:to_dot(G,[ic_forms:get_id2(T)|N]) ++ "Helper"; 454 455getUnmarshalType(G, N, _X, T) when is_record(T, union) -> 456 ic_util:to_dot(G,[ic_forms:get_id2(T)|N]) ++ "Helper"; 457 458getUnmarshalType(G, N, X, T) when is_record(T, sequence) andalso 459 is_record(X, member) -> 460 ic_util:to_dot(G,[ic_forms:get_id2(X)|N]) ++ "Helper"; 461 462getUnmarshalType(G, N, X, T) when is_record(T, sequence) andalso 463 is_record(X, case_dcl) -> 464 ic_util:to_dot(G,[ic_forms:get_id2(X)|N]) ++ "Helper"; 465 466getUnmarshalType(G, N, X, T) when is_record(T, sequence) -> 467 getUnmarshalType(G, N, X, ic_forms:get_type(T)) ++ "Helper"; 468 469getUnmarshalType(G, N, X, T) when is_record(T, array) andalso 470 is_record(X, case_dcl) -> 471 ic_util:to_dot(G,[ic_forms:get_id2(T)|N]) ++ "Helper"; 472 473getUnmarshalType(G, N, _X, T) when is_record(T, enum) -> 474 ic_util:to_dot(G,[ic_forms:get_id2(T)|N]) ++ 475 "Helper"; 476 477getUnmarshalType(_G, _N, _X, {boolean, _}) -> 478 ?ERLANGPACKAGE ++ "OtpErlangAtom"; 479 480getUnmarshalType(_G, _N, _X, {octet, _}) -> 481 ?ERLANGPACKAGE ++ "OtpErlangLong"; 482 483getUnmarshalType(_G, _N, _X, {void, _}) -> 484 ?ERLANGPACKAGE ++ "OtpErlangAtom"; 485 486getUnmarshalType(_G, _N, _X, {unsigned, U}) -> 487 case U of 488 {short,_} -> 489 ?ERLANGPACKAGE ++ "OtpErlangLong"; 490 {long,_} -> 491 ?ERLANGPACKAGE ++ "OtpErlangLong"; 492 {'long long',_} -> 493 ?ERLANGPACKAGE ++ "OtpErlangLong" 494 end; 495 496getUnmarshalType(_G, _N, _X, {char, _}) -> 497 ?ERLANGPACKAGE ++ "OtpErlangLong"; 498 499getUnmarshalType(_G, _N, _X, {wchar, _}) -> %% WCHAR 500 ?ERLANGPACKAGE ++ "OtpErlangLong"; 501 502getUnmarshalType(_G, _N, _X, {short, _}) -> 503 ?ERLANGPACKAGE ++ "OtpErlangLong"; 504 505getUnmarshalType(_G, _N, _X, {long, _}) -> 506 ?ERLANGPACKAGE ++ "OtpErlangLong"; 507 508getUnmarshalType(_G, _N, _X, {'long long', _}) -> 509 ?ERLANGPACKAGE ++ "OtpErlangLong"; 510 511getUnmarshalType(_G, _N, _X, {float, _}) -> 512 ?ERLANGPACKAGE ++ "OtpErlangDouble"; 513 514getUnmarshalType(_G, _N, _X, {double, _}) -> 515 ?ERLANGPACKAGE ++ "OtpErlangDouble"; 516 517getUnmarshalType(_G, _N, _X, {any, _}) -> 518 ?ICPACKAGE ++ "AnyHelper". 519 520%%----------------------------------------------------------------- 521%% Func: getMarshalType/4 522%%----------------------------------------------------------------- 523getMarshalType(G, N, X, T) when element(1, T) == scoped_id -> 524 {FullScopedName, _, TK, _} = ic_symtab:get_full_scoped_name(G, N, T), 525 BT = ic_code:get_basetype(G, ic_util:to_dot(G,FullScopedName)), 526 case BT of 527 "erlang.pid" -> 528 ?ICPACKAGE ++ "PidHelper"; 529 "erlang.port" -> 530 ?ICPACKAGE ++ "PortHelper"; 531 "erlang.ref" -> 532 ?ICPACKAGE ++ "RefHelper"; 533 "erlang.term" -> 534 ?ICPACKAGE ++ "TermHelper"; 535 {enum, Type} -> 536 getMarshalType(G, N, X, Type); 537 Type -> 538 case TK of 539 {'tk_struct', _, _, _} -> 540 Type ++ "Helper"; 541 542 {'tk_union', _, _, _, _, _} -> 543 Type ++ "Helper"; 544 545 {'tk_array', _ , _} -> 546 Type ++ "Helper"; 547 548 {'tk_sequence', _ , _} -> 549 Type ++ "Helper"; 550 551 {'tk_enum', _, _, _} -> 552 Type ++ "Helper"; 553 554 {'tk_string',_} -> 555 "string"; 556 557 {'tk_wstring',_} -> %% WSTRING 558 "string"; 559 560 'tk_char' -> 561 "char"; 562 563 'tk_wchar' -> %% WCHAR 564 "char"; 565 566 'tk_octet' -> 567 "byte"; 568 569 'tk_ushort' -> 570 "ushort"; 571 572 'tk_ulong' -> 573 "uint"; 574 575 'tk_ulonglong' -> %% ULLONG 576 "ulong"; 577 578 'tk_short' -> 579 "short"; 580 581 'tk_long' -> 582 "int"; 583 584 'tk_longlong' -> %% LLONG 585 "long"; 586 587 'tk_float' -> 588 "float"; 589 590 'tk_double' -> 591 "double"; 592 593 'tk_boolean' -> 594 "boolean"; 595 596 'tk_void' -> 597 "atom"; 598 599 'tk_any' -> 600 ?ICPACKAGE ++ "AnyHelper"; 601 602 _ -> 603 case isBasicType(G,N,TK) of 604 true -> 605 %% Faked the type ! 606 getMarshalType(G, N, X, {list_to_atom(tk2type(G,N,T,TK)), -1}); 607 false -> 608 ic_util:to_dot(G,FullScopedName) ++ "Helper" 609 end 610 end 611 end; 612 613getMarshalType(_G, _N, _X, S) when is_list(S) -> 614 S ++ "Helper"; 615 616getMarshalType(_G, _N, _X, T) when is_record(T, string) -> 617 "string"; 618 619getMarshalType(_G, _N, _X, T) when is_record(T, wstring) -> %% WSTRING 620 "string"; 621 622getMarshalType(G, N, _X, T) when is_record(T, struct) -> 623 ic_util:to_dot(G,[ic_forms:get_id2(T)|N]) ++ 624 "Helper"; 625 626getMarshalType(G, N, _X, T) when is_record(T, union) -> 627 ic_util:to_dot(G,[ic_forms:get_id2(T)|N]) ++ 628 "Helper"; 629 630getMarshalType(G, N, X, T) when is_record(T, array) andalso 631 is_record(X, case_dcl) -> 632 ic_util:to_dot(G,[ic_forms:get_id2(T)|N]) ++ 633 "Helper"; 634 635getMarshalType(G, N, X, T) when is_record(T, sequence) andalso 636 is_record(X, member) -> 637 ic_util:to_dot(G,[ic_forms:get_id2(X)|N]) ++ 638 "Helper"; 639 640getMarshalType(G, N, _X, T) when is_record(T, sequence) -> 641 getType(G, N, ic_forms:get_type(T)) ++ 642 "Helper"; 643 644getMarshalType(G, N, _X, T) when is_record(T, enum) -> 645 ic_util:to_dot(G,[ic_forms:get_id2(T)|N]) ++ 646 "Helper"; 647 648getMarshalType(_G, _N, _X, {boolean, _}) -> 649 "boolean"; 650 651getMarshalType(_G, _N, _X, {octet, _}) -> 652 "byte"; 653 654getMarshalType(_G, _N, _X, {void, _}) -> 655 ""; % <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 656 657getMarshalType(_G, _N, _X, {unsigned, U}) -> 658 case U of 659 {short,_} -> 660 "ushort"; 661 {long,_} -> 662 "uint"; 663 {'long long',_} -> 664 "ulong" 665 end; 666 667getMarshalType(_G, _N, _X, {short, _}) -> 668 "short"; 669getMarshalType(_G, _N, _X, {long, _}) -> 670 "int"; 671getMarshalType(_G, _N, _X, {'long long', _}) -> 672 "long"; 673getMarshalType(_G, _N, _X, {float, _}) -> 674 "float"; 675getMarshalType(_G, _N, _X, {double, _}) -> 676 "double"; 677getMarshalType(_G, _N, _X, {char, _}) -> 678 "char"; 679getMarshalType(_G, _N, _X, {wchar, _}) -> %% WCHAR 680 "char"; 681getMarshalType(_G, _N, _X, {any, _}) -> 682 ?ICPACKAGE ++ "AnyHelper". 683 684 685 686 687%%----------------------------------------------------------------- 688%% Func: unMarshalFun/4 689%%----------------------------------------------------------------- 690unMarshalFun(G, N, X, T) when element(1, T) == scoped_id -> 691 {FullScopedName, _, TK, _} = ic_symtab:get_full_scoped_name(G, N, T), 692 BT = ic_code:get_basetype(G, ic_util:to_dot(G,FullScopedName)), 693 case BT of 694 "erlang.pid" -> 695 ".read_pid()"; 696 "erlang.port" -> 697 ".read_port()"; 698 "erlang.ref" -> 699 ".read_ref()"; 700 "erlang.term" -> 701 ".read_term()"; 702 {enum, Type} -> 703 unMarshalFun(G, N, X, Type); 704 _Type -> 705 case isBasicType(G,N,TK) of 706 true -> 707 case TK of 708 {'tk_string',_} -> 709 ".read_string()"; 710 711 {'tk_wstring',_} -> %% WSTRING 712 ".read_string()"; 713 714 'tk_boolean' -> 715 ".read_boolean()"; 716 717 'tk_octet' -> 718 ".read_byte()"; 719 720 'tk_ushort' -> 721 ".read_ushort()"; 722 723 'tk_ulong' -> 724 ".read_uint()"; 725 726 'tk_ulonglong' -> %% ULLONG 727 ".read_ulong()"; 728 729 'tk_short' -> 730 ".read_short()"; 731 732 'tk_long' -> 733 ".read_int()"; 734 735 'tk_longlong' -> %% LLONG 736 ".read_long()"; 737 738 'tk_float' -> 739 ".read_float()"; 740 741 'tk_double' -> 742 ".read_double()"; 743 744 'tk_char' -> 745 ".read_char()"; 746 747 'tk_wchar' -> %% WCHAR 748 ".read_char()"; 749 750 _ -> 751 %% Faked the type ! 752 unMarshalFun(G, N, X, {list_to_atom(tk2type(G,N,X,TK)), -1}) 753 end; 754 false -> 755 ".unmarshal()" 756 end 757 end; 758 759unMarshalFun(_G, _N, _X, S) when is_list(S) -> 760 ".unmarshal()"; 761 762unMarshalFun(_G, _N, _X, T) when is_record(T, string) -> 763 ".read_string()"; 764 765unMarshalFun(_G, _N, _X, T) when is_record(T, wstring) -> %% WSTRING 766 ".read_string()"; 767 768unMarshalFun(_G, _N, _X, T) when is_record(T, struct) -> 769 ".unmarshal((" ++ ?ERLANGPACKAGE ++ "OtpErlangTuple)"; 770 771unMarshalFun(_G, _N, _X, T) when is_record(T, union) -> 772 ".unmarshal((" ++ ?ERLANGPACKAGE ++ "OtpErlangTuple)"; 773 774unMarshalFun(_G, _N, _X, T) when is_record(T, sequence) -> 775 ".unmarshal((" ++ ?ERLANGPACKAGE ++ "OtpErlanglist)"; 776 777unMarshalFun(_G, _N, _X, T) when is_record(T, enum) -> 778 ".unmarshal((" ++ ?ERLANGPACKAGE ++ "OtpErlangAtom)"; 779 780unMarshalFun(_G, _N, _X, {boolean, _}) -> 781 ".read_boolean()"; 782 783unMarshalFun(_G, _N, _X, {octet, _}) -> 784 ".read_byte()"; 785 786unMarshalFun(_G, _N, _X, {void, _}) -> 787 ""; 788 789unMarshalFun(_G, _N, _X, {unsigned, U}) -> 790 case U of 791 {short,_} -> 792 ".read_ushort()"; 793 {long,_} -> 794 ".read_uint()"; 795 {'long long',_} -> 796 ".read_ulong()" 797 end; 798 799unMarshalFun(_G, _N, _X, {short, _}) -> 800 ".read_short()"; 801unMarshalFun(_G, _N, _X, {long, _}) -> 802 ".read_int()"; 803unMarshalFun(_G, _N, _X, {'long long', _}) -> 804 ".read_long()"; 805unMarshalFun(_G, _N, _X, {float, _}) -> 806 ".read_float()"; 807unMarshalFun(_G, _N, _X, {double, _}) -> 808 ".read_double()"; 809unMarshalFun(_G, _N, _X, {char, _}) -> 810 ".read_char()"; 811unMarshalFun(_G, _N, _X, {wchar, _}) -> %% WCHAR 812 ".read_char()". 813 814 815 816 817 818%%----------------------------------------------------------------- 819%% Func: getFullType/4 - /3 820%% 821%% Note : Similar to the getType/3 with the major difference 822%% thet on arrays and sequences it will also declare 823%% their sizes. Used for "new" declarations 824%% 825%%----------------------------------------------------------------- 826 827 828getFullType(G, N, X, T) when is_record(X, typedef) andalso is_record(T, array) -> 829 FullDim = 830 tk2FullType(G,N,X,ic_forms:get_tk(X)) ++ 831 getFullDim(G,N,T#array.size), 832 fixArrayDims(FullDim); 833 834getFullType(G, N, X, T) when is_record(X, member) andalso is_record(T, array) -> 835 FullDim = 836 getFullType(G, N, ic_forms:get_type(X)) ++ 837 getFullDim(G,N,T#array.size), 838 fixArrayDims(FullDim); 839 840getFullType(G, N, X, T) when is_record(X, case_dcl) andalso is_record(T, array) -> 841 FullDim = 842 getFullType(G, N, ic_forms:get_type(X)) ++ 843 getFullDim(G,N,T#array.size), 844 fixArrayDims(FullDim); 845 846getFullType(G, N, _X, T) -> 847 getFullType(G, N, T). 848 849 850 851getFullType(G, N, T) when is_record(T, scoped_id) -> 852 {FullScopedName, _, TK, _} = ic_symtab:get_full_scoped_name(G, N, T), 853 case TK of 854 {tk_array,_,_} -> 855 tk2FullType(G,N,T,TK); 856 {tk_sequence,_,_} -> 857 tk2FullType(G,N,T,TK); 858 _ -> 859 case isBasicType(G,N,TK) of 860 true -> 861 tk2FullType(G,N,T,TK); 862 false -> 863 %% Other types 864 ic_code:get_basetype(G, ic_util:to_dot(G,FullScopedName)) 865 end 866 end; 867 868getFullType(G, N, T) when is_record(T, sequence) -> 869 fixSeqDims(getType(G,N,T),"_length"); 870 871getFullType(G, N, T) -> 872 getType(G, N, T). 873 874 875 876%% In order to make a legal declaration 877%% of an assignable array, the dimensions 878%% of empty array sequences are swifted to 879%% the end of the type 880fixArrayDims(Cs) -> 881 fixArrayDims(Cs,[],[]). 882 883fixArrayDims([],Fulls,Emptys) -> 884 lists:reverse(Fulls) ++ Emptys; 885fixArrayDims([91,93|Rest],Fulls,Emptys) -> 886 fixArrayDims(Rest,Fulls,[91,93|Emptys]); 887fixArrayDims([C|Rest],Fulls,Emptys) -> 888 fixArrayDims(Rest,[C|Fulls],Emptys). 889 890 891%% In order to make a legal declaration 892%% of an assignable array, the dimensions 893%% of empty array of sequences are swifted 894%% to the end of the type 895fixSeqDims(Cs,Length) -> 896 fixSeqDims(Cs,Length,[]). 897 898fixSeqDims([],_Length,Found) -> 899 lists:reverse(Found); 900fixSeqDims([91,93|Rest],Length,Found) when is_list(Length) -> 901 lists:reverse([93|lists:reverse(Length)] ++ 902 [91|Found]) ++ Rest; 903fixSeqDims([C|Rest],Length,Found) -> 904 fixSeqDims(Rest,Length,[C|Found]). 905 906 907 908%%----------------------------------------------------------------- 909%% Func: inlinedTypes/2 910%%----------------------------------------------------------------- 911inlinedTypes(PkgName, Type) when is_record(Type, struct) -> 912 "_" ++ PkgName ++ "."; 913inlinedTypes(PkgName, Type) when is_record(Type, union) -> 914 "_" ++ PkgName ++ "."; 915inlinedTypes(PkgName, Type) when is_record(Type, enum) -> 916 "_" ++ PkgName ++ "."; 917inlinedTypes(_, _) -> 918 "". 919 920%%----------------------------------------------------------------- 921%% Func: marshalFun/4 922%%----------------------------------------------------------------- 923marshalFun(G, N, X, Type) -> 924 case isBasicType(G, N, Type) of 925 true -> 926 ".write_" ++ getMarshalType(G, N, X, Type); 927 _ -> 928 getMarshalType(G, N, X, Type) ++ ".marshal" 929 end. 930 931 932%%----------------------------------------------------------------- 933%% Func: isBasicType/3 934%%----------------------------------------------------------------- 935isBasicType(G, N, S) when element(1, S) == scoped_id -> 936 {_, _, TK, _} = ic_symtab:get_full_scoped_name(G, N, S), 937 isBasicType(ictype:fetchType(TK)); 938 939isBasicType(G, N, X) when is_record(X, member) -> 940 if is_record(hd(element(3,X)), array) -> 941 false; 942 true -> 943 isBasicType(G, N, element(2,X)) 944 end; 945 946isBasicType(_G, _N, {unsigned, {long, _}} ) -> 947 true; 948 949isBasicType(_G, _N, {unsigned, {short, _}} ) -> 950 true; 951 952isBasicType(_G, _N, {unsigned, {'long long', _}} ) -> 953 true; 954 955isBasicType(_G, _N, {'long long', _} ) -> 956 true; 957 958isBasicType(_G, _N, {Type, _} ) -> 959 isBasicType(Type); 960 961isBasicType(_G, _N, Type) -> 962 isBasicType(Type). 963 964 965%%----------------------------------------------------------------- 966%% Func: isBasicType/1 967%%----------------------------------------------------------------- 968 969isBasicType( Type ) -> 970 lists:member(Type, 971 [tk_short,short, 972 tk_long,long, 973 tk_longlong,longlong, %% LLONG 974 tk_ushort,ushort, 975 tk_ulong,ulong, 976 tk_ulonglong,ulonglong, %% ULLONG 977 tk_float,float, 978 tk_double,double, 979 tk_boolean,boolean, 980 tk_char,char, 981 tk_wchar,wchar, %% WCHAR 982 tk_octet,octet, 983 tk_wstring,wstring, %% WSTRING 984 tk_string,string]). 985 986%% returns true if the Type is a java elementary type 987isJavaElementaryType( Type ) -> 988 lists:member(Type, 989 [byte, char, wchar, boolean, 990 int, short, long, 'long long', float, double]). 991 992%%----------------------------------------------------------------- 993%% Func: isIntegerType/3 994%%----------------------------------------------------------------- 995isIntegerType(G, N, S) when element(1, S) == scoped_id -> 996 {_, _, TK, _} = ic_symtab:get_full_scoped_name(G, N, S), 997 isIntegerType(ictype:fetchType(TK)); 998isIntegerType(_G, _N, {unsigned, {long, _}} ) -> 999 true; 1000isIntegerType(_G, _N, {unsigned, {short, _}} ) -> 1001 true; 1002isIntegerType(_G, _N, {unsigned, {'long long', _}} ) -> 1003 true; 1004isIntegerType(_G, _N, {'long long', _} ) -> 1005 true; 1006isIntegerType(_G, _N, {Type, _} ) -> 1007 isIntegerType(Type); 1008isIntegerType(_G, _N, Type) -> 1009 isIntegerType(Type). 1010 1011%%----------------------------------------------------------------- 1012%% Func: isIntegerType/1 1013%%----------------------------------------------------------------- 1014 1015isIntegerType( Type ) -> 1016 lists:member(Type, 1017 [tk_short,short, 1018 tk_long,long, 1019 tk_longlong,longlong, %% LLONG 1020 tk_ushort,ushort, 1021 tk_ulong,ulong, 1022 tk_ulonglong,ulonglong, %% ULLONG 1023 tk_char,char, 1024 tk_wchar,wchar, %% WCHAR 1025 tk_octet,octet]). 1026 1027 1028 1029%%----------------------------------------------------------------- 1030%% Func: isTerm/3 1031%%----------------------------------------------------------------- 1032isTermType(G, N, T) -> 1033 case getType(G,N,T) of 1034 "com.ericsson.otp.ic.Term" -> 1035 true; 1036 _ -> 1037 false 1038 end. 1039 1040 1041 1042 1043%%----------------------------------------------------------------- 1044%% Internal functions 1045%%----------------------------------------------------------------- 1046 1047 1048%% Changes the typecode to the 1049%% corresponding "basic" type 1050tk2type(_G,_N,_X,{'tk_struct', _IFRId, "port", _ElementList}) -> 1051 ?ICPACKAGE ++ "Port"; 1052tk2type(_G,_N,_X,{'tk_struct', _IFRId, "pid", _ElementList}) -> 1053 ?ICPACKAGE ++ "Pid"; 1054tk2type(_G,_N,_X,{'tk_struct', _IFRId, "ref", _ElementList}) -> 1055 ?ICPACKAGE ++ "Ref"; 1056tk2type(_G,_N,_X,{'tk_struct', _IFRId, "term", _ElementList}) -> 1057 ?ICPACKAGE ++ "Term"; 1058tk2type(_G,_N,_X,{'tk_string', _}) -> 1059 "java.lang.String"; 1060tk2type(_G,_N,_X,{'tk_wstring', _}) -> %% WSTRING 1061 "java.lang.String"; 1062tk2type(G,N,X,{'tk_array', ElemTC, Dim}) -> 1063 tkarr2decl(G,N,X,{'tk_array', ElemTC, Dim}); 1064tk2type(G,N,X,{'tk_sequence', ElemTC, MaxLsextractength}) -> 1065 tkseq2decl(G,N,X,{'tk_sequence', ElemTC, MaxLsextractength}); 1066tk2type(G,N,_X,{'tk_struct', IFRId, Name, _ElementList}) -> 1067 ScopedId= 1068 lists:reverse(string:tokens(lists:nth(2,string:tokens(IFRId,":")),"/")), 1069 1070 case ic_forms:clean_up_scope([Name|N]) of 1071 ScopedId -> 1072 %% Right path, use N instead 1073 ic_util:to_dot(G,[Name|N]); 1074 _ -> 1075 %% Ugly work arround 1076 ic_util:to_dot(G,ScopedId) 1077 end; 1078tk2type(G,N,_X,{'tk_union', IFRId, Name, _, _, _ElementList}) -> 1079 ScopedId= 1080 lists:reverse(string:tokens(lists:nth(2,string:tokens(IFRId,":")),"/")), 1081 1082 case ic_forms:clean_up_scope([Name|N]) of 1083 ScopedId -> 1084 %% Right path, use N instead 1085 ic_util:to_dot(G,[Name|N]); 1086 _ -> 1087 %% Ugly work arround 1088 ic_util:to_dot(G,ScopedId) 1089 end; 1090tk2type(_G,_N,_X,{'tk_enum', _Id, Name, _ElementList}) -> 1091 Name; 1092tk2type(_G,_N,_X,tk_void) -> 1093 "void"; 1094tk2type(_G,_N,_X,tk_long) -> 1095 "int"; 1096tk2type(_G,_N,_X,tk_longlong) -> %% LLONG 1097 "long"; 1098tk2type(_G,_N,_X,tk_short) -> 1099 "short"; 1100tk2type(_G,_N,_X,tk_ulong) -> 1101 "int"; 1102tk2type(_G,_N,_X,tk_ulonglong) -> %% ULLONG 1103 "long"; 1104tk2type(_G,_N,_X,tk_ushort) -> 1105 "short"; 1106tk2type(_G,_N,_X,tk_float) -> 1107 "float"; 1108tk2type(_G,_N,_X,tk_double) -> 1109 "double"; 1110tk2type(_G,_N,_X,tk_boolean) -> 1111 "boolean"; 1112tk2type(_G,_N,_X,tk_char) -> 1113 "char"; 1114tk2type(_G,_N,_X,tk_wchar) -> %% WCHAR 1115 "char"; 1116tk2type(_G,_N,_X,tk_octet) -> 1117 "byte"; 1118tk2type(_G,_N,_X,tk_string) -> 1119 "java.lang.String"; 1120tk2type(_G,_N,_X,tk_wstring) -> %% WSTRING 1121 "java.lang.String"; 1122tk2type(_G,_N,_X,tk_any) -> 1123 ?ICPACKAGE ++ "Any"; 1124tk2type(_G,_N,_X,tk_term) -> %% Term 1125 ?ICPACKAGE ++ "Term". 1126 1127%% Changes the sequence typecode to the 1128%% corresponding "basic" structure 1129tkseq2decl(G,N,X,TKSeq) -> 1130 tkseq2decl2(G,N,X,TKSeq,[],[]). 1131 1132tkseq2decl2(G,N,X,{tk_sequence,E,D},[],Ds) -> 1133 tkseq2decl2(G,N,X,E,[],[D|Ds]); 1134tkseq2decl2(G,N,X,TkEl,[],Ds) -> 1135 ElName = tk2type(G,N,X,TkEl), 1136 ElName ++ getdim(Ds). 1137 1138%% Changes the array typecode to the 1139%% corresponding "basic" structure 1140tkarr2decl(G,N,X,TKArr) -> 1141 tkarr2decl2(G,N,X,TKArr,[],[]). 1142 1143tkarr2decl2(G,N,X,{tk_array,E,D},[],Ds) -> 1144 tkarr2decl2(G,N,X,E,[],[D|Ds]); 1145tkarr2decl2(G,N,X,TkEl,[],Ds) -> 1146 ElName = tk2type(G,N,X,TkEl), 1147 ElName ++ getdim(Ds). 1148 1149getdim([]) -> 1150 ""; 1151getdim([_D|Ds]) -> 1152 getdim(Ds) ++ "[]". 1153 1154 1155 1156%% Changes the typecode to the corresponding "basic" type 1157%% used for variable declarations where arrays and sequences 1158%% are declared with there full dimensions 1159tk2FullType(G,N,X,{'tk_array', ElemTC, Dim}) -> 1160 tkarr2FullDecl(G,N,X,{'tk_array', ElemTC, Dim}); 1161tk2FullType(G,N,X,{'tk_sequence', ElemTC, MaxLsextractength}) -> 1162 tkseq2FullDecl(G,N,X,{'tk_sequence', ElemTC, MaxLsextractength}); 1163tk2FullType(G,N,X,TK) -> 1164 tk2type(G,N,X,TK). 1165 1166 1167%% Changes the sequence typecode to the 1168%% corresponding "basic" structure here 1169%% arrays and sequences are declared with 1170%% their full dimensions 1171tkseq2FullDecl(G,N,X,TKSeq) -> 1172 tkseq2FullDecl2(G,N,X,TKSeq,[],[]). 1173 1174tkseq2FullDecl2(G,N,X,{tk_sequence,E,D},[],Ds) -> 1175 tkseq2FullDecl2(G,N,X,E,[],[D|Ds]); 1176tkseq2FullDecl2(G,N,X,TkEl,[],Ds) -> 1177 ElName = tk2FullType(G,N,X,TkEl), 1178 ElName ++ getdim(Ds). 1179 1180%% Changes the array typecode to the 1181%% corresponding "basic" structure 1182tkarr2FullDecl(G,N,X,TKArr) -> 1183 tkarr2FullDecl2(G,N,X,TKArr,[],[]). 1184 1185tkarr2FullDecl2(G,N,X,{tk_array,E,D},[],Ds) -> 1186 tkarr2FullDecl2(G,N,X,E,[],[D|Ds]); 1187tkarr2FullDecl2(G,N,X,TkEl,[],Ds) -> 1188 ElName = tk2FullType(G,N,X,TkEl), 1189 ElName ++ getFullDim(G,N,Ds). 1190 1191getFullDim(_G,_N,[]) -> 1192 ""; 1193getFullDim(G,N,[D|Ds]) when is_record(D,scoped_id) -> 1194 {FSN, _, _, _} = ic_symtab:get_full_scoped_name(G, N, D), 1195 "[" ++ ic_util:to_dot(G,FSN) ++ "]" ++ getFullDim(G,N,Ds); 1196getFullDim(G,N,[D|Ds]) when is_integer(D) -> 1197 "[" ++ integer_to_list(D) ++ "]" ++ getFullDim(G,N,Ds); 1198getFullDim(G,N,[D|Ds]) when is_tuple(D) -> 1199 "[" ++ ic_util:eval_java(G,N,D) ++ "]" ++ getFullDim(G,N,Ds). 1200 1201 1202 1203%% Constructs an array empty dimension string 1204%% used for array variable declaration 1205arrayEmptyDim(X) -> 1206 arrayEmptyDim2(X#array.size). 1207 1208arrayEmptyDim2([_D]) -> 1209 "[]"; 1210arrayEmptyDim2([_D |Ds]) -> 1211 "[]" ++ arrayEmptyDim2(Ds). 1212 1213 1214 1215