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_sequence_java). 23 24 25-include("icforms.hrl"). 26-include("ic.hrl"). 27-include("ic_debug.hrl"). 28%%----------------------------------------------------------------- 29%% External exports 30%%----------------------------------------------------------------- 31-export([gen/4]). 32 33%%----------------------------------------------------------------- 34%% Internal exports 35%%----------------------------------------------------------------- 36-export([]). 37 38%%----------------------------------------------------------------- 39%% External functions 40%%----------------------------------------------------------------- 41 42%%----------------------------------------------------------------- 43%% Func: gen/4 44%%----------------------------------------------------------------- 45gen(G, N, X, SequenceName) when is_record(X, sequence) -> 46 emit_holder_class(G, N, X, SequenceName), 47 emit_helper_class(G, N, X, SequenceName); 48gen(_G, _N, _X, _SequenceName) -> 49 ok. 50 51 52%%----------------------------------------------------------------- 53%% Internal functions 54%%----------------------------------------------------------------- 55 56 57%%----------------------------------------------------------------- 58%% Func: emit_holder_class/4 59%%----------------------------------------------------------------- 60emit_holder_class(G, N, X, SequenceName) -> 61 SName = string:concat(SequenceName, "Holder"), 62 {Fd, _}= ic_file:open_java_file(G, N, SName), 63 64 SequenceType = ic_java_type:getType(G, N, X), 65 66 ic_codegen:emit(Fd, ["final public class ",SequenceName,"Holder {\n" 67 " // instance variables\n" 68 " public ",SequenceType," value;\n\n" 69 " // constructors\n" 70 " public ",SequenceName,"Holder() {}\n" 71 " public ",SequenceName,"Holder(",SequenceType," initial) {\n" 72 " value = initial;\n" 73 " }\n\n" 74 75 " // methods\n" 76 77 " public void _marshal(",?ERLANGPACKAGE,"OtpOutputStream out) throws java.lang.Exception{\n" 78 " ",SequenceName,"Helper.marshal(out, value);\n" 79 " }\n\n" 80 81 " public void _unmarshal(",?ERLANGPACKAGE,"OtpInputStream in) throws java.lang.Exception {\n" 82 " value = ",SequenceName,"Helper.unmarshal(in);\n" 83 " }\n\n" 84 "}\n"]), 85 file:close(Fd). 86 87 88 89emit_helper_class(G, N, X, SequenceName) -> 90 SName = string:concat(SequenceName, "Helper"), 91 {Fd, _}= ic_file:open_java_file(G, N, SName), 92 93 SequenceType = ic_java_type:getType(G, N, X), 94 ElementType = ic_forms:get_type(X), 95 96 ic_codegen:emit(Fd, ["public class ",SequenceName,"Helper {\n" 97 98 " // constructors\n" 99 " private ",SequenceName,"Helper() {}\n\n" 100 101 " // methods\n" 102 " public static void marshal(",?ERLANGPACKAGE,"OtpOutputStream _out, ",SequenceType," _value) \n" 103 " throws java.lang.Exception {\n\n"]), 104 105 emit_sequence_marshal_function(G, N, X, Fd, SequenceName, ElementType), 106 107 ic_codegen:emit(Fd, [" }\n\n" 108 109 " public static ",SequenceType," unmarshal(",?ERLANGPACKAGE,"OtpInputStream _in) \n" 110 " throws java.lang.Exception {\n\n"]), 111 112 emit_sequence_unmarshal_function(G, N, X, Fd, SequenceName, ElementType), 113 114 ic_codegen:emit(Fd, [" }\n\n" 115 116 " public static String id() {\n" 117 " return \"",ic_pragma:scope2id(G, [SequenceName | N]),"\";\n" 118 " }\n\n" 119 120 " public static String name() {\n" 121 " return \"",SequenceName,"\";\n" 122 " }\n\n"]), 123 124 ic_jbe:emit_type_function(G, N, X, Fd), 125 126 ic_codegen:emit(Fd, [" public static void insert(",?ICPACKAGE,"Any _any, ",SequenceType," _this)\n" 127 " throws java.lang.Exception {\n\n" 128 129 " ",?ERLANGPACKAGE,"OtpOutputStream _os = \n" 130 " new ",?ERLANGPACKAGE,"OtpOutputStream();\n\n" 131 132 " _any.type(type());\n" 133 " marshal(_os, _this);\n" 134 " _any.insert_Streamable(_os);\n" 135 " }\n\n" 136 137 " public static ",SequenceType," extract(",?ICPACKAGE,"Any _any)\n" 138 " throws java.lang.Exception {\n\n" 139 140 " return unmarshal(_any.extract_Streamable());\n" 141 " }\n\n" 142 143 144 %% In corba mapping there is also a _type function here. 145 "}\n\n"]), 146 file:close(Fd). 147 148 149%%----------------------------------------------------------------- 150%% Func: emit_sequence_marshal_function/6 151%%----------------------------------------------------------------- 152emit_sequence_marshal_function(G, N, X, Fd, _SequenceName, ElementType) -> 153 ic_codegen:emit(Fd, [" int _length = _value.length;\n\n" 154 155 " _out.write_list_head(_length);\n\n" 156 157 " if (_length > 0) {\n" 158 " for(int _tmp = 0; _tmp < _length; _tmp++)\n"]), 159 160 case ic_java_type:isBasicType(G, N, ElementType) of 161 true -> 162 ic_codegen:emit(Fd, [" _out",ic_java_type:marshalFun(G, N, X, ElementType),"(_value[_tmp]);\n\n"]); 163 false -> 164 ic_codegen:emit(Fd, [" ",ic_java_type:marshalFun(G, N, X, ElementType),"(_out, _value[_tmp]);\n\n"]) 165 end, 166 167 ic_codegen:emit(Fd, [" _out.write_nil();\n" 168 " }\n\n"]). 169 170 171 172 173%%----------------------------------------------------------------- 174%% Func: emit_sequence_unmarshal_function/6 175%%----------------------------------------------------------------- 176emit_sequence_unmarshal_function(G, N, X, Fd, _SequenceName, ElementType) -> 177 178 SequenceElementType = ic_java_type:getType(G, N, ElementType), 179 180 ic_codegen:emit(Fd, [" int _tag,_length;\n" 181 " ",SequenceElementType," _sequence[];\n" 182 " _tag = _in.peek();\n\n"]), 183 184 case ic_java_type:isIntegerType(G, N, ElementType) of 185 true -> 186 ic_codegen:emit(Fd, [" switch(_tag) {\n" 187 " case ",?ERLANGPACKAGE,"OtpExternal.stringTag:\n" 188 " byte _compressed[] = (_in.read_string()).getBytes();\n" 189 " _length = _compressed.length;\n" 190 " _sequence = new ",ic_java_type:getFullType(G,N,X),";\n\n" 191 192 " for(int _tmp = 0; _tmp < _length; _tmp++)\n" 193 " _sequence[_tmp] = (",ic_java_type:getType(G, N, ElementType),")(_compressed[_tmp] & 0xff);\n\n" 194 195 " break;\n" 196 " default:\n" 197 " _length = _in.read_list_head();\n" 198 " _sequence = new ",ic_java_type:getFullType(G,N,X),";\n\n" 199 200 " if(_length > 0) {\n" 201 " for(int _tmp = 0; _tmp < _length; _tmp++)\n" 202 " _sequence[_tmp] = _in",ic_java_type:unMarshalFun(G, N, X, ElementType),";\n\n" 203 204 " _in.read_nil();\n" 205 " }\n" 206 " }\n"]); 207 false -> 208 ic_codegen:emit(Fd, [" _length = _in.read_list_head();\n" 209 " _sequence = new ",ic_java_type:getFullType(G,N,X),";\n\n" 210 211 " if(_length > 0) {\n" 212 " for(int _tmp = 0; _tmp < _length; _tmp++)\n"]), 213 case ic_java_type:isBasicType(G, N, ElementType) of 214 true -> 215 ic_codegen:emit(Fd, [" _sequence[_tmp] = _in",ic_java_type:unMarshalFun(G, N, X, ElementType),";\n\n"]); 216 _ -> 217 ic_codegen:emit(Fd, [" _sequence[_tmp] = ",ic_java_type:getUnmarshalType(G, N, X, ElementType),".unmarshal(_in);\n\n"]) 218 end, 219 220 ic_codegen:emit(Fd, [" _in.read_nil();\n" 221 " }\n\n"]) 222 end, 223 224 ic_codegen:emit(Fd, " return _sequence;\n"). 225 226 227 228 229%%--------------------------------------------------- 230%% Utilities 231%%--------------------------------------------------- 232 233 234 235 236 237 238 239 240 241