Skip to content

Commit 9e95288

Browse files
committed
Better handling of references (but still not working)
1 parent 4caba91 commit 9e95288

File tree

1 file changed

+65
-13
lines changed

1 file changed

+65
-13
lines changed

javaobj.py

Lines changed: 65 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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}\nDir: {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

Comments
 (0)