@@ -651,6 +651,10 @@ def do_classdesc(self, parent=None, ident=0):
651651 ident = ident + 1 ,
652652 expect = (self .TC_STRING , self .TC_REFERENCE ))
653653
654+ if type (field_type ) is JavaClass :
655+ # FIXME: ugly trick
656+ field_type = JavaString (field_type .name )
657+
654658 if type (field_type ) is not JavaString :
655659 raise AssertionError ("Field type must be a JavaString, "
656660 "not {0}" .format (type (field_type )))
@@ -1156,27 +1160,47 @@ def _writeStruct(self, unpack, length, args):
11561160 ba = struct .pack (unpack , * args )
11571161 self .object_stream .write (ba )
11581162
1159- def _writeString (self , string ):
1163+ def _writeString (self , obj , use_reference = True ):
11601164 """
11611165 Appends a string to the serialization stream
11621166
1163- :param string: String to serialize
1167+ :param obj: String to serialize
1168+ :param use_reference: If True, allow writing a reference
11641169 """
11651170 # TODO: Convert to "modified UTF-8"
11661171 # http://docs.oracle.com/javase/7/docs/api/java/io/DataInput.html#modified-utf-8
1167- string = to_bytes (string , "utf-8" )
1172+ string = to_bytes (obj , "utf-8" )
11681173
1169- self ._writeStruct (">H" , 2 , (len (string ),))
1170- self .object_stream .write (string )
1174+ if use_reference and isinstance (obj , JavaString ):
1175+ try :
1176+ idx = self .references .index (obj )
1177+ except ValueError :
1178+ # First appearance of the string
1179+ self .references .append (obj )
1180+ logging .debug (
1181+ "*** Adding ref 0x%X for string: %s" ,
1182+ len (self .references ) - 1 + self .BASE_REFERENCE_IDX , obj )
1183+
1184+ self ._writeStruct (">H" , 2 , (len (string ),))
1185+ self .object_stream .write (string )
1186+ else :
1187+ # Write a reference to the previous type
1188+ logging .debug ("*** Reusing ref 0x%X for string: %s" ,
1189+ idx + self .BASE_REFERENCE_IDX , obj )
1190+ self .write_reference (idx )
1191+ else :
1192+ self ._writeStruct (">H" , 2 , (len (string ),))
1193+ self .object_stream .write (string )
11711194
1172- def write_string (self , obj ):
1195+ def write_string (self , obj , use_reference = True ):
11731196 """
11741197 Writes a Java string with the TC_STRING type marker
11751198
11761199 :param obj: The string to print
1200+ :param use_reference: If True, allow writing a reference
11771201 """
11781202 self ._writeStruct (">B" , 1 , (self .TC_STRING ,))
1179- self ._writeString (obj )
1203+ self ._writeString (obj , use_reference )
11801204
11811205 def write_enum (self , obj ):
11821206 """
@@ -1236,6 +1260,12 @@ def write_object(self, obj, parent=None):
12361260 cls = obj .get_class ()
12371261 self .write_classdesc (cls )
12381262
1263+ # Add reference
1264+ self .references .append ([])
1265+ logging .debug (
1266+ "*** Adding ref 0x%X for object %s" ,
1267+ len (self .references ) - 1 + self .BASE_REFERENCE_IDX , obj )
1268+
12391269 all_names = []
12401270 all_types = []
12411271 tmpcls = cls
@@ -1245,8 +1275,13 @@ def write_object(self, obj, parent=None):
12451275 tmpcls = tmpcls .superclass
12461276 del tmpcls
12471277
1278+ logging .debug ("<=> Field names: %s" , all_names )
1279+ logging .debug ("<=> Field types: %s" , all_types )
1280+
12481281 for field_name , field_type in zip (all_names , all_types ):
12491282 try :
1283+ logging .debug ("Writing field %s (%s): %s" ,
1284+ field_name , field_type , getattr (obj , field_name ))
12501285 self ._write_value (field_type , getattr (obj , field_name ))
12511286 except AttributeError as ex :
12521287 log_error ("No attribute {0} for object {1}\n Dir: {2}"
@@ -1284,8 +1319,12 @@ def write_classdesc(self, obj, parent=None):
12841319 :param obj: Class description to write
12851320 :param parent:
12861321 """
1287- # Add reference
1288- self .references .append (obj .name )
1322+ if obj not in self .references :
1323+ # Add reference
1324+ self .references .append (obj )
1325+ logging .debug (
1326+ "*** Adding ref 0x%X for classdesc %s" ,
1327+ len (self .references ) - 1 + self .BASE_REFERENCE_IDX , obj .name )
12891328
12901329 self ._writeStruct (">B" , 1 , (self .TC_CLASSDESC ,))
12911330 self ._writeString (obj .name )
@@ -1301,10 +1340,18 @@ def write_classdesc(self, obj, parent=None):
13011340 idx = self .references .index (field_type )
13021341 except ValueError :
13031342 # First appearance of the type
1304- self .write_string (field_type )
13051343 self .references .append (field_type )
1344+ logging .debug (
1345+ "*** Adding ref 0x%X for field type %s" ,
1346+ len (self .references ) - 1 + self .BASE_REFERENCE_IDX ,
1347+ field_type )
1348+
1349+ self .write_string (field_type , False )
13061350 else :
13071351 # Write a reference to the previous type
1352+ logging .debug ("*** Reusing ref 0x%X for %s (%s)" ,
1353+ idx + self .BASE_REFERENCE_IDX ,
1354+ field_type , field_name )
13081355 self .write_reference (idx )
13091356
13101357 self ._writeStruct (">B" , 1 , (self .TC_ENDBLOCKDATA ,))
@@ -1327,19 +1374,24 @@ def write_array(self, obj):
13271374
13281375 :param obj: A JavaArray object
13291376 """
1377+ classdesc = obj .get_class ()
13301378 self ._writeStruct (">B" , 1 , (self .TC_ARRAY ,))
1331- self .write_classdesc (obj . get_class () )
1379+ self .write_classdesc (classdesc )
13321380 self ._writeStruct (">i" , 1 , (len (obj ),))
13331381
1334- classdesc = obj .get_class ()
1382+ # Add reference
1383+ self .references .append (obj )
1384+ logging .debug (
1385+ "*** Adding ref 0x%X for array []" ,
1386+ len (self .references ) - 1 + self .BASE_REFERENCE_IDX )
13351387
13361388 type_char = classdesc .name [0 ]
13371389 assert type_char == self .TYPE_ARRAY
13381390 type_char = classdesc .name [1 ]
13391391
13401392 if type_char == self .TYPE_OBJECT :
13411393 for o in obj :
1342- self .write_object ( o )
1394+ self ._write_value ( classdesc . name [ 1 :], o )
13431395 elif type_char == self .TYPE_ARRAY :
13441396 for a in obj :
13451397 self .write_array (a )
0 commit comments