00001
00002 from snippets.generators.elements.structure import Structure
00003 from snippets.generators.elements.variable import Variable
00004 from snippets.generators.elements.function import Function
00005 import xml.etree.ElementTree as ET
00006
00007 class JavaGen():
00008 def __init__(self):
00009
00010 self.storage_equiv = {
00011 'bool': 'byte',
00012 'int8_t': 'byte',
00013 'uint8_t': 'int',
00014 'int16_t': 'short',
00015 'uint16_t': 'int',
00016 'int32_t': 'int',
00017 'uint32_t': 'long',
00018 'int64_t': 'long',
00019 'uint64_t': 'float'
00020 }
00021
00022 self.type_unsigned_corr = {
00023 'uint8_t': ' & 0xFF',
00024 'uint16_t': ' & 0xFFFF',
00025 'uint32_t': ' & 0xFFFFFFFFL'
00026 }
00027
00028 self.type_equiv = {
00029 'bool': 'byte',
00030 'int8_t': 'byte',
00031 'uint8_t': 'byte',
00032 'int16_t': 'short',
00033 'uint16_t': 'short',
00034 'int32_t': 'int',
00035 'uint32_t': 'int',
00036 'int64_t': 'long',
00037 'uint64_t': 'long'
00038 }
00039
00040 self.type_size = {
00041 'byte':1,
00042 'short':2,
00043 'int':4,
00044 'long':8,
00045 'float':4,
00046 'double':8}
00047
00048 self.primitive_types = self.type_equiv.keys()
00049 self.packable_types = []
00050 self.special_types = {}
00051 self.array_len_type = 'int'
00052
00053 def gen_variable(self, var, indent = ''):
00054 '''All variables default to a public specifier'''
00055 etype = self.type_equiv.get(var.type,var.type)
00056 type = self.storage_equiv.get(var.type,etype)
00057 cinit = var.default
00058 if cinit == None:
00059 if self.is_array_type(var.type):
00060 len = self.get_array_len(var.type)
00061 etype = self.type_equiv.get(var.type,var.type)
00062 if len == '':
00063 cinit = 'new ' + etype + '[0]'
00064 else:
00065 cinit = 'new ' + etype + '[' + len + ']'
00066 type = etype + '[]'
00067 elif var.type not in self.primitive_types:
00068 cinit = 'new ' + type + '()'
00069
00070 cvar = indent + 'public ' + type + ' ' + var.name
00071
00072 if cinit != None:
00073 cvar = cvar + ' = ' + cinit
00074
00075 return cvar + ';'
00076
00077 def gen_enum(self, enum, indent = ''):
00078 return indent + 'public final static int ' + enum.name + ' = ' + enum.value + ';'
00079
00080 def gen_method(self, method, indent):
00081 rtype = self.storage_equiv.get(method.ret,method.ret)
00082 code = indent;
00083 if method.static:
00084 code = code + 'static '
00085 code = code + 'public ' + rtype + ' '
00086 code = code + method.name + '('
00087
00088 for arg in method.args:
00089 type = self.type_equiv.get(arg.type,arg.type)
00090 code = code + type + ' ' + arg.name + ','
00091
00092 if len(method.args): code = code[:-1]
00093
00094 code = code + ')'
00095 if method.qual != None:
00096 code = code + ' ' + method.qual + ' '
00097
00098 code = code + '{\n'
00099 code = code + indent + ' ' + method.body + '\n'
00100 code = code + indent + '}'
00101
00102 return code
00103
00104 def gen_class(self, struct, package, imports = [], serialization = True):
00105 code = 'package ' + package + ';\n'
00106 code = code + "\n"
00107
00108
00109 if serialization:
00110 imports_ser = [
00111 'com.google.common.io.LittleEndianDataInputStream',
00112 'com.google.common.io.LittleEndianDataOutputStream',
00113 'java.io.IOException']
00114
00115 for im in imports_ser:
00116 code = code + 'import ' + im + ';\n'
00117
00118 for im in imports:
00119 code = code + 'import ' + im + ';\n'
00120
00121 code = code + '\n'
00122
00123
00124 code = code + 'public class ' + struct.name
00125
00126 if struct.inherit != None:
00127 code = code + ' implements ' + struct.inherit
00128 code = code + ' {\n'
00129
00130
00131
00132
00133 for enum in struct.enums:
00134 code = code + self.gen_enum(enum, ' ') + '\n'
00135 code = code + "\n"
00136
00137 for var in struct.variables:
00138 code = code + self.gen_variable(var, ' ') + '\n'
00139
00140 code = code + "\n"
00141
00142
00143 if serialization: self.add_serializers(struct, ' ')
00144 for method in struct.methods:
00145 code = code + self.gen_method(method, ' ') + '\n\n'
00146
00147
00148 code = code + '}\n'
00149
00150 return code
00151
00152 def add_serializers(self, struct, indent):
00153
00154 fn = Function()
00155 fn.name = 'pack'
00156 fn.ret = 'void'
00157 fn.qual = 'throws IOException'
00158 arg = Variable()
00159 arg.name = 'out'
00160 arg.type = 'LittleEndianDataOutputStream'
00161 fn.args.append(arg)
00162 fn.body = self.gen_serializer_body(struct, indent)
00163 struct.methods.append(fn)
00164
00165 fn = Function()
00166 fn.name = 'unpack'
00167 fn.ret = 'void'
00168 fn.qual = 'throws IOException'
00169 arg = Variable()
00170 arg.name = 'in'
00171 arg.type = 'LittleEndianDataInputStream'
00172 fn.args.append(arg)
00173 fn.body = self.gen_deserializer_body(struct, indent)
00174 struct.methods.append(fn)
00175
00176
00177 def gen_bitfield_serializer(self, struct, indent):
00178 store_type = ''
00179 sz = int(struct.assert_size)
00180 if sz == 1:
00181 store_type = 'byte'
00182 if sz == 2:
00183 store_type = 'short'
00184 elif (sz > 2) and (sz <= 4):
00185 store_type = 'int'
00186 elif (sz > 4) and (sz <= 8):
00187 store_type = 'long'
00188 elif sz != 1:
00189 print('Cannot create a serializer for size '+ str(sz))
00190 return ''
00191
00192 code = indent + store_type + ' storage = 0;\n'
00193 shift = 0
00194 for var in struct.variables:
00195 if var.bits == None:
00196 print('All variables need a bit size in a bitfield.')
00197 return ''
00198 code = code + indent + 'storage |= ( ('
00199 code = code + store_type + ')(' + var.name
00200 code = code + ' & ((1<<' + var.bits + ')-1))'
00201 code = code + ' << ' + str(shift) + ');\n'
00202 shift += int(var.bits)
00203
00204
00205 code = code + indent + 'ByteArrayOutputStream baos = new ByteArrayOutputStream(); \n'
00206 code = code + indent + 'LittleEndianDataOutputStream dos = new LittleEndianDataOutputStream(baos);\n'
00207 code = code + indent + 'dos.write' + store_type.title() + '(storage);\n'
00208 code = code + 'dos.close();\n'
00209 code = code + 'byte[] bb = baos.toByteArray();\n'
00210 code = code + 'for(int i=0; i<' + str(sz) + ';++i) out.writeByte(bb[i]);\n'
00211
00212 return code
00213
00214 def gen_bitfield_deserializer(self, struct, indent):
00215 store_type = ''
00216 sz = int(struct.assert_size)
00217 ssz = 1
00218 if sz == 1:
00219 store_type = 'byte'
00220 if sz == 2:
00221 ssz = 2
00222 store_type = 'short'
00223 elif (sz > 2) and (sz <= 4):
00224 ssz = 4
00225 store_type = 'int'
00226 elif (sz > 4) and (sz <= 8):
00227 ssz = 8
00228 store_type = 'long'
00229 elif sz != 1:
00230 print('Cannot create a serializer for size '+ str(sz))
00231 return ''
00232
00233 code = indent + 'byte[] buffer = new byte[' + str(ssz) + '];\n'
00234 code = code + indent + 'for(int i=0; i<' + str(sz) + ';++i) buffer[i] = in.readByte();\n'
00235 code = code + indent + 'ByteArrayInputStream bais = new ByteArrayInputStream(buffer); \n'
00236 code = code + indent + 'LittleEndianDataInputStream dis = new LittleEndianDataInputStream(bais);\n'
00237 code = code + indent + store_type + ' storage ='
00238 code = code + indent + 'dis.read' + store_type.title() + '();\n'
00239 code = code + 'dis.close();\n'
00240
00241 for var in struct.variables:
00242 if var.bits == None:
00243 print('All variables need a bit size in a bitfield.')
00244 return ''
00245 code = code + indent + var.name + ' = ('
00246 code = code + self.type_equiv.get(var.type, var.type) + ') '
00247 code = code + '(storage & ((1<<' + var.bits + ')-1));\n'
00248 code = code + indent + 'storage >>>= ' + str(var.bits) + ';\n'
00249
00250 return code
00251
00252 def is_array_type(self, type):
00253 return ((type.find('[') != -1) and
00254 (type.find(']') != -1))
00255
00256 def get_array_len(self, type):
00257 sidx = type.find('[')
00258 eidx = type.find(']')
00259 return type[sidx+1:eidx]
00260
00261 def get_array_type(self, type):
00262 sidx = type.find('[')
00263 return type[:sidx]
00264
00265 def gen_array_serializer(self, var, indent):
00266 code = indent
00267 type = self.get_array_type(var.type)
00268 type = self.type_equiv.get(type,type)
00269 len = self.get_array_len(var.type)
00270
00271 if len == '':
00272 code = code + indent + 'out.write' + self.array_len_type.title()
00273 code = code + '(' + var.name +'.length);\n'
00274
00275 if type == 'byte':
00276 code = code + indent + 'out.write(' + var.name + ');'
00277 else:
00278 code = code + indent + 'for(int i=0; i<' + var.name + '.length; ++i) '
00279 code = code + 'out.write' + type.title() + '('
00280 code = code + var.name + '[i]);\n'
00281
00282 return code
00283
00284 def gen_array_deserializer(self, var, indent):
00285 code = indent
00286 type = self.get_array_type(var.type)
00287 type = self.type_equiv.get(type,type)
00288 len = self.get_array_len(var.type)
00289
00290 if len == '':
00291 code = code + indent + var.name + ' = new ' + type
00292 code = code + '[' + 'in.read' + self.array_len_type.title() + '()];\n'
00293
00294 if type == 'byte':
00295 code = code + indent + 'in.read(' + var.name + ');'
00296 else:
00297 code = code + indent + 'for(int i=0; i<' + var.name + '.length; ++i) '
00298 code = code + var.name + '[i] = ' + 'in.read' + type.title() + '();\n'
00299
00300 return code
00301
00302 def gen_serializer_body(self, struct, indent):
00303
00304 if struct.bitfield: return self.gen_bitfield_serializer(struct, indent)
00305
00306
00307 code = ''
00308 for var in struct.variables:
00309 if var.cond != None:
00310 code = code + indent + 'if (' + var.cond + ' == 1){\n'
00311
00312 if self.is_array_type(var.type):
00313 code = code + indent + self.gen_array_serializer(var, indent)
00314 elif var.type in self.primitive_types:
00315 type = self.type_equiv.get(var.type,var.type)
00316 code = code + indent + 'out.write'
00317 code = code + type.title() + '( (' + type + ')'
00318 code = code + var.name + ');\n'
00319 elif var.type in self.packable_types:
00320 code = code + indent + var.name + '.pack(out);\n'
00321 elif var.type in self.special_types.keys():
00322 code = code + indent + self.special_types[var.type](var, "serializer")
00323 else:
00324 print('Cannot create a serializer for type: ' + var.type)
00325
00326 if var.cond != None:
00327 code = code + indent + '}\n'
00328
00329
00330 return code
00331
00332 def gen_deserializer_body(self, struct, indent):
00333
00334 if struct.bitfield: return self.gen_bitfield_deserializer(struct, indent)
00335
00336
00337 code = ''
00338 for var in struct.variables:
00339 if var.cond != None:
00340 code = code + indent + 'if (' + var.cond + ' == 1){\n'
00341
00342 if self.is_array_type(var.type):
00343 code = code + indent + self.gen_array_deserializer(var, indent)
00344 elif var.type in self.primitive_types:
00345 code = code + indent + var.name + ' = ('
00346 code = code + self.storage_equiv.get(var.type, var.type) + ') in.read'
00347 code = code + self.type_equiv.get(var.type,var.type).title()
00348 code = code + '()' + self.type_unsigned_corr.get(var.type, '') + ';\n'
00349 elif var.type in self.packable_types:
00350 code = code + indent + var.name + '.unpack(in);\n'
00351 elif var.type in self.special_types.keys():
00352 code = code + indent + self.special_types[var.type](var, "deserializer")
00353 else:
00354 print('Cannot create a serializer for type: ' + var.type)
00355
00356 if var.cond != None:
00357 code = code + indent + '}\n'
00358 return code