Skip to content

Commit 9e355cf

Browse files
committed
Add a debug flag for structure parsing.
There are still bugs in the structure parsing. This flag can help locate the breaking points and will show where in the structure we died. Should make orienting yourself in the hex dump easier.
1 parent 9906968 commit 9e355cf

File tree

1 file changed

+41
-30
lines changed

1 file changed

+41
-30
lines changed

sc2reader/utils.py

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -266,81 +266,92 @@ def read_data_struct(self, indent=0, key=None):
266266
Read a Blizzard data-structure. Structure can contain strings, lists,
267267
dictionaries and custom integer types.
268268
"""
269+
debug = False
270+
269271
#The first byte serves as a flag for the type of data to follow
270272
datatype = self.read_byte()
271273
prefix = hex(self.tell())+"\t"*indent
272274
if key != None:
273-
prefix+="{0}: {1}".format(key, datatype)
274-
275-
#print prefix
275+
prefix+="{0}:".format(key)
276+
prefix+=" {0}".format(datatype)
276277

277278
if datatype == 0x00:
278279
#0x00 is an array where the first X bytes mark the number of entries in
279280
#the array. See variable int documentation for details.
280281
entries = self.read_variable_int()
281-
#print "Entries, ",entries
282-
#print self.peek(10)
283-
return [self.read_data_struct(indent+1,i) for i in range(entries)]
282+
prefix+=" ({0})".format(entries)
283+
if debug: print prefix
284+
data = [self.read_data_struct(indent+1,i) for i in range(entries)]
284285

285-
if datatype == 0x01:# or datatype == 0x0A:
286+
elif datatype == 0x01:
286287
#0x01 is an array where the first X bytes mark the number of entries in
287288
#the array. See variable int documentation for details.
288289
#print self.peek(10)
289290
self.read_chars(2).encode("hex")
290-
#print self.peek(10)
291291
entries = self.read_variable_int()
292-
#print "Entries, ",entries
293-
return [self.read_data_struct(indent+1,i) for i in range(entries)]
292+
prefix+=" ({0})".format(entries)
293+
if debug: print prefix
294+
data = [self.read_data_struct(indent+1,i) for i in range(entries)]
294295

295-
if datatype == 0x02:
296+
elif datatype == 0x02:
296297
#0x02 is a byte string with the first byte indicating
297298
#the length of the byte string to follow
298-
return self.read_string(self.read_count())
299+
entries = self.read_count()
300+
data = self.read_string(entries)
301+
prefix+=" ({0}) - {1}".format(entries,data)
302+
if debug: print prefix
299303

300304
elif datatype == 0x03:
301305
#0x03 is an unknown data type where the first byte appears
302306
#to have no effect and kicks back the next instruction
303307
flag = self.read_byte()
304-
return self.read_data_struct(indent,key)
308+
if debug: print prefix
309+
data = self.read_data_struct(indent,key)
305310

306311
elif datatype == 0x04:
307312
#0x04 is an unknown data type where the first byte of information
308313
#is a switch (1 or 0) that can trigger another structure to be
309314
#read.
310315
flag = self.read_byte()
311-
#if flag == 0x04:
312-
# flag = self.read_byte()
313316
if flag:
314-
return self.read_data_struct(indent,key)
317+
if debug: print prefix
318+
data = self.read_data_struct(indent,key)
315319
else:
316-
return 0
320+
data = 0
321+
prefix+=" - {0}".format(data)
322+
if debug: print prefix
317323

318324
elif datatype == 0x05:
319325
#0x05 is a serialized key,value structure with the first byte
320326
#indicating the number of key,value pairs to follow
321327
#When looping through the pairs, the first byte is the key,
322328
#followed by the serialized data object value
323329
data = dict()
324-
#print self.peek(10)
325330
entries = self.read_count()
326-
#print "Key Entries, ",entries
331+
prefix+=" ({0})".format(entries)
332+
if debug: print prefix
327333
for i in range(entries):
328334
key = self.read_count()
329335
data[key] = self.read_data_struct(indent+1,key) #Done like this to keep correct parse order
330-
return data
331336

332337
elif datatype == 0x06:
333-
return self.read_byte()
338+
data = self.read_byte()
339+
prefix+=" - {0}".format(data)
340+
if debug: print prefix
334341
elif datatype == 0x07:
335-
return self.read_chars(4)
342+
data = self.read_chars(4)
343+
prefix+=" - {0}".format(data)
344+
if debug: print prefix
336345
elif datatype == 0x09:
337-
#print self.peek(10)
338-
return self.read_variable_int()
339-
"""
340-
elif datatype == 0x0A:
341-
return self.read_byte()
342-
"""
343-
raise TypeError("Unknown Data Structure: '%s'" % datatype)
346+
data = self.read_variable_int()
347+
prefix+=" - {0}".format(data)
348+
if debug: print prefix
349+
else:
350+
if debug: print prefix
351+
raise TypeError("Unknown Data Structure: '%s'" % datatype)
352+
353+
return data
354+
344355

345356
def read_object_type(self, read_modifier=False):
346357
""" Object type is big-endian short16 """
@@ -693,7 +704,7 @@ def get_files(path, extensions=['.sc2replay'], exclude=[], depth=-1, followlinks
693704

694705
# os.walk can't handle file paths, only directories
695706
if os.path.isfile(path):
696-
return [path] if filtr_func(path,extensions) else []
707+
return [path] if filtr_func(path) else []
697708

698709
files = list()
699710
for root, directories, filenames in os.walk(path, followlinks=followlinks):

0 commit comments

Comments
 (0)