*** plistlib.py 2012-03-30 23:43:43.000000000 +0200 --- /Users/flanker/Downloads/plistlib.py 2012-03-30 23:51:56.000000000 +0200 *************** *** 54,71 **** __all__ = [ "readPlist", "writePlist", "readPlistFromString", "writePlistToString", "readPlistFromResource", "writePlistToResource", ! "Plist", "Data", "Dict", ! "InvalidFileException", ] # Note: the Plist and Dict classes have been deprecated. import binascii import datetime - import json from cStringIO import StringIO - import os import re - import struct import warnings --- 54,67 ---- __all__ = [ "readPlist", "writePlist", "readPlistFromString", "writePlistToString", "readPlistFromResource", "writePlistToResource", ! "Plist", "Data", "Dict" ] # Note: the Plist and Dict classes have been deprecated. import binascii import datetime from cStringIO import StringIO import re import warnings *************** *** 78,92 **** if isinstance(pathOrFile, (str, unicode)): pathOrFile = open(pathOrFile) didOpen = 1 ! header = pathOrFile.read(8) ! pathOrFile.seek(0) ! if header == '6xBB4xL4xL4xL', trailer) - in_file.seek(offset_table_offset) - object_offsets = [] - offset_format = '>' + {1: 'B', 2: 'H', 4: 'L', 8: 'Q', }[offset_size] * num_objects - ref_format = {1: 'B', 2: 'H', 4: 'L', 8: 'Q', }[ref_size] - int_format = {0: (1, '>B'), 1: (2, '>H'), 2: (4, '>L'), 3: (8, '>Q'), } - object_offsets = struct.unpack(offset_format, in_file.read(offset_size * num_objects)) - def getSize(token_l): - """ return the size of the next object.""" - if token_l == 0xF: - m = ord(in_file.read(1)) & 0x3 - s, f = int_format[m] - return struct.unpack(f, in_file.read(s))[0] - return token_l - def readNextObject(offset): - """ read the object at offset. May recursively read sub-objects (content of an array/dict/set) """ - in_file.seek(offset) - token = in_file.read(1) - token_h, token_l = ord(token) & 0xF0, ord(token) & 0x0F #high and low parts - if token == '\x00': - return None - elif token == '\x08': - return False - elif token == '\x09': - return True - elif token == '\x0f': - return '' - elif token_h == 0x10: #int - result = 0 - for k in xrange((2 << token_l) - 1): - result = (result << 8) + ord(in_file.read(1)) - return result - elif token_h == 0x20: #real - if token_l == 2: - return struct.unpack('>f', in_file.read(4))[0] - elif token_l == 3: - return struct.unpack('>d', in_file.read(8))[0] - elif token_h == 0x30: #date - f = struct.unpack('>d', in_file.read(8))[0] - return datetime.datetime.utcfromtimestamp(f + MAC_OS_X_TIME_OFFSET) - elif token_h == 0x80: #data - s = getSize(token_l) - return in_file.read(s) - elif token_h == 0x50: #ascii string - s = getSize(token_l) - return in_file.read(s) - elif token_h == 0x60: #unicode string - s = getSize(token_l) - return in_file.read(s * 2).decode('utf-16be') - elif token_h == 0x80: #uid - return in_file.read(token_l + 1) - elif token_h == 0xA0: #array - s = getSize(token_l) - obj_refs = struct.unpack('>' + ref_format * s, in_file.read(s * ref_size)) - return map(lambda x: readNextObject(object_offsets[x]), obj_refs) - elif token_h == 0xC0: #set - s = getSize(token_l) - obj_refs = struct.unpack('>' + ref_format * s, in_file.read(s * ref_size)) - return set(map(lambda x: readNextObject(object_offsets[x]), obj_refs)) - elif token_h == 0xD0: #dict - result = {} - s = getSize(token_l) - key_refs = struct.unpack('>' + ref_format * s, in_file.read(s * ref_size)) - obj_refs = struct.unpack('>' + ref_format * s, in_file.read(s * ref_size)) - for k, o in zip(key_refs, obj_refs): - key = readNextObject(object_offsets[k]) - obj = readNextObject(object_offsets[o]) - result[key] = obj - return result - raise InvalidFileException() - return readNextObject(object_offsets[top_object]) - # Contents should conform to a subset of ISO 8601 # (in particular, YYYY '-' MM '-' DD 'T' HH ':' MM ':' SS 'Z'. Smaller units may be omitted with # a loss of precision) --- 181,186 ----