Skip to content

Commit 4caba91

Browse files
committed
Added basic support for references while marshalling
This allows to be closer to what the Java ObjectOutputStream does and reduces the size of the output files.
1 parent 26c67aa commit 4caba91

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

javaobj.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1084,6 +1084,7 @@ def __init__(self, stream=None):
10841084
self.object_stream = stream
10851085
self.object_obj = None
10861086
self.object_transformers = []
1087+
self.references = []
10871088

10881089
def add_transformer(self, transformer):
10891090
"""
@@ -1097,6 +1098,7 @@ def dump(self, obj):
10971098
"""
10981099
Dumps the given object in the Java serialization format
10991100
"""
1101+
self.references = []
11001102
self.object_obj = obj
11011103
self.object_stream = BytesIO()
11021104
self._writeStreamHeader()
@@ -1282,6 +1284,9 @@ def write_classdesc(self, obj, parent=None):
12821284
:param obj: Class description to write
12831285
:param parent:
12841286
"""
1287+
# Add reference
1288+
self.references.append(obj.name)
1289+
12851290
self._writeStruct(">B", 1, (self.TC_CLASSDESC,))
12861291
self._writeString(obj.name)
12871292
self._writeStruct(">qB", 1, (obj.serialVersionUID, obj.flags))
@@ -1292,14 +1297,30 @@ def write_classdesc(self, obj, parent=None):
12921297
">B", 1, (self._convert_type_to_char(field_type),))
12931298
self._writeString(field_name)
12941299
if field_type[0] in (self.TYPE_OBJECT, self.TYPE_ARRAY):
1295-
self.write_string(field_type)
1300+
try:
1301+
idx = self.references.index(field_type)
1302+
except ValueError:
1303+
# First appearance of the type
1304+
self.write_string(field_type)
1305+
self.references.append(field_type)
1306+
else:
1307+
# Write a reference to the previous type
1308+
self.write_reference(idx)
12961309

12971310
self._writeStruct(">B", 1, (self.TC_ENDBLOCKDATA,))
12981311
if obj.superclass:
12991312
self.write_classdesc(obj.superclass)
13001313
else:
13011314
self.write_null()
13021315

1316+
def write_reference(self, ref_index):
1317+
"""
1318+
Writes a reference
1319+
:param ref_index: Local index (0-based) to the reference
1320+
"""
1321+
self._writeStruct(
1322+
">BL", 1, (self.TC_REFERENCE, ref_index + self.BASE_REFERENCE_IDX))
1323+
13031324
def write_array(self, obj):
13041325
"""
13051326
Writes a JavaArray

tests/tests.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,10 @@ def test_fields(self):
190190

191191
self.assertEqual(len(classdesc.fields_names), 3)
192192

193-
# jobj_ = javaobj.dumps(pobj)
194-
# self.assertEqual(jobj, jobj_)
193+
jobj_ = javaobj.dumps(pobj)
194+
# Reloading the new dump allows to compare the decoding sequence
195+
javaobj.loads(jobj_)
196+
self.assertEqual(jobj, jobj_)
195197

196198
def test_class(self):
197199
"""

0 commit comments

Comments
 (0)