|
34 | 34 | """ |
35 | 35 |
|
36 | 36 | # Standard library |
| 37 | +import collections |
37 | 38 | import logging |
38 | 39 | import os |
39 | 40 | import struct |
@@ -1199,8 +1200,22 @@ def write_string(self, obj, use_reference=True): |
1199 | 1200 | :param obj: The string to print |
1200 | 1201 | :param use_reference: If True, allow writing a reference |
1201 | 1202 | """ |
1202 | | - self._writeStruct(">B", 1, (self.TC_STRING,)) |
1203 | | - self._writeString(obj, use_reference) |
| 1203 | + if use_reference and isinstance(obj, JavaString): |
| 1204 | + try: |
| 1205 | + idx = self.references.index(obj) |
| 1206 | + except ValueError: |
| 1207 | + # String is not referenced: let _writeString store it |
| 1208 | + self._writeStruct(">B", 1, (self.TC_STRING,)) |
| 1209 | + self._writeString(obj, use_reference) |
| 1210 | + else: |
| 1211 | + # Reuse the referenced string |
| 1212 | + logging.debug("*** Reusing ref 0x%X for String: %s", |
| 1213 | + idx + self.BASE_REFERENCE_IDX, obj) |
| 1214 | + self.write_reference(idx) |
| 1215 | + else: |
| 1216 | + # Don't use references |
| 1217 | + self._writeStruct(">B", 1, (self.TC_STRING,)) |
| 1218 | + self._writeString(obj, use_reference) |
1204 | 1219 |
|
1205 | 1220 | def write_enum(self, obj): |
1206 | 1221 | """ |
@@ -1266,12 +1281,12 @@ def write_object(self, obj, parent=None): |
1266 | 1281 | "*** Adding ref 0x%X for object %s", |
1267 | 1282 | len(self.references) - 1 + self.BASE_REFERENCE_IDX, obj) |
1268 | 1283 |
|
1269 | | - all_names = [] |
1270 | | - all_types = [] |
| 1284 | + all_names = collections.deque() |
| 1285 | + all_types = collections.deque() |
1271 | 1286 | tmpcls = cls |
1272 | 1287 | while tmpcls: |
1273 | | - all_names.extend(tmpcls.fields_names) |
1274 | | - all_types.extend(tmpcls.fields_types) |
| 1288 | + all_names.extendleft(reversed(tmpcls.fields_names)) |
| 1289 | + all_types.extendleft(reversed(tmpcls.fields_types)) |
1275 | 1290 | tmpcls = tmpcls.superclass |
1276 | 1291 | del tmpcls |
1277 | 1292 |
|
@@ -1326,39 +1341,43 @@ def write_classdesc(self, obj, parent=None): |
1326 | 1341 | "*** Adding ref 0x%X for classdesc %s", |
1327 | 1342 | len(self.references) - 1 + self.BASE_REFERENCE_IDX, obj.name) |
1328 | 1343 |
|
1329 | | - self._writeStruct(">B", 1, (self.TC_CLASSDESC,)) |
1330 | | - self._writeString(obj.name) |
1331 | | - self._writeStruct(">qB", 1, (obj.serialVersionUID, obj.flags)) |
1332 | | - self._writeStruct(">H", 1, (len(obj.fields_names),)) |
1333 | | - |
1334 | | - for field_name, field_type in zip(obj.fields_names, obj.fields_types): |
1335 | | - self._writeStruct( |
1336 | | - ">B", 1, (self._convert_type_to_char(field_type),)) |
1337 | | - self._writeString(field_name) |
1338 | | - if field_type[0] in (self.TYPE_OBJECT, self.TYPE_ARRAY): |
1339 | | - try: |
1340 | | - idx = self.references.index(field_type) |
1341 | | - except ValueError: |
1342 | | - # First appearance of the type |
1343 | | - 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) |
1350 | | - else: |
1351 | | - # 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) |
1355 | | - self.write_reference(idx) |
1356 | | - |
1357 | | - self._writeStruct(">B", 1, (self.TC_ENDBLOCKDATA,)) |
1358 | | - if obj.superclass: |
1359 | | - self.write_classdesc(obj.superclass) |
| 1344 | + self._writeStruct(">B", 1, (self.TC_CLASSDESC,)) |
| 1345 | + self._writeString(obj.name) |
| 1346 | + self._writeStruct(">qB", 1, (obj.serialVersionUID, obj.flags)) |
| 1347 | + self._writeStruct(">H", 1, (len(obj.fields_names),)) |
| 1348 | + |
| 1349 | + for field_name, field_type \ |
| 1350 | + in zip(obj.fields_names, obj.fields_types): |
| 1351 | + self._writeStruct( |
| 1352 | + ">B", 1, (self._convert_type_to_char(field_type),)) |
| 1353 | + self._writeString(field_name) |
| 1354 | + if field_type[0] in (self.TYPE_OBJECT, self.TYPE_ARRAY): |
| 1355 | + try: |
| 1356 | + idx = self.references.index(field_type) |
| 1357 | + except ValueError: |
| 1358 | + # First appearance of the type |
| 1359 | + self.references.append(field_type) |
| 1360 | + logging.debug( |
| 1361 | + "*** Adding ref 0x%X for field type %s", |
| 1362 | + len(self.references) - 1 + self.BASE_REFERENCE_IDX, |
| 1363 | + field_type) |
| 1364 | + |
| 1365 | + self.write_string(field_type, False) |
| 1366 | + else: |
| 1367 | + # Write a reference to the previous type |
| 1368 | + logging.debug("*** Reusing ref 0x%X for %s (%s)", |
| 1369 | + idx + self.BASE_REFERENCE_IDX, |
| 1370 | + field_type, field_name) |
| 1371 | + self.write_reference(idx) |
| 1372 | + |
| 1373 | + self._writeStruct(">B", 1, (self.TC_ENDBLOCKDATA,)) |
| 1374 | + if obj.superclass: |
| 1375 | + self.write_classdesc(obj.superclass) |
| 1376 | + else: |
| 1377 | + self.write_null() |
1360 | 1378 | else: |
1361 | | - self.write_null() |
| 1379 | + # Use reference |
| 1380 | + self.write_reference(self.references.index(obj)) |
1362 | 1381 |
|
1363 | 1382 | def write_reference(self, ref_index): |
1364 | 1383 | """ |
|
0 commit comments