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