Utilities/binplistlib.py

changeset 1965
96f5a76e1845
parent 1720
201622cf8a01
child 2302
f29e9405c851
--- a/Utilities/binplistlib.py	Sun Jul 29 17:26:28 2012 +0200
+++ b/Utilities/binplistlib.py	Sun Jul 29 18:05:03 2012 +0200
@@ -21,7 +21,7 @@
 
 Date values can only be datetime.datetime objects.
 
-The exceptions InvalidPlistException and NotBinaryPlistException may be 
+The exceptions InvalidPlistException and NotBinaryPlistException may be
 thrown to indicate that the data cannot be serialized or deserialized as
 a binary plist.
 
@@ -68,7 +68,7 @@
 #      notice, this list of conditions and the following disclaimer in the
 #      documentation and/or other materials provided with the distribution.
 #    * Neither the name of biplist nor the names of its contributors may be
-#      used to endorse or promote products derived from this software without 
+#      used to endorse or promote products derived from this software without
 #      specific prior written permission.
 #
 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
@@ -156,6 +156,7 @@
         pathOrFile.close()
     return result
 
+
 def writePlist(rootObject, pathOrFile, binary=True):
     """
     Module function to write a plist file.
@@ -178,6 +179,7 @@
             pathOrFile.close()
         return
 
+
 def readPlistFromBytes(data):
     """
     Module function to read from a plist bytes object.
@@ -188,6 +190,7 @@
     """
     return readPlist(BytesIO(data))
 
+
 def writePlistToBytes(rootObject, binary=True):
     """
     Module function to write a plist bytes object.
@@ -203,6 +206,7 @@
         writer.writeRoot(rootObject)
         return io.getvalue()
 
+
 def is_stream_binary_plist(stream):
     """
     Module function to check, if the stream is a binary plist.
@@ -223,6 +227,7 @@
     'nullBytes, boolBytes, intBytes, realBytes, dateBytes, dataBytes, stringBytes, '
     'uidBytes, arrayBytes, setBytes, dictBytes')
 
+
 class PlistReader(object):
     """
     Class implementing the plist reader.
@@ -279,11 +284,11 @@
             self.trailer = PlistTrailer._make(unpack("!xxxxxxBBQQQ", trailerContents))
             offset_size = self.trailer.offsetSize * self.trailer.offsetCount
             offset = self.trailer.offsetTableOffset
-            offset_contents = self.contents[offset:offset+offset_size]
+            offset_contents = self.contents[offset:offset + offset_size]
             offset_i = 0
             while offset_i < self.trailer.offsetCount:
-                begin = self.trailer.offsetSize*offset_i
-                tmp_contents = offset_contents[begin:begin+self.trailer.offsetSize]
+                begin = self.trailer.offsetSize * offset_i
+                tmp_contents = offset_contents[begin:begin + self.trailer.offsetSize]
                 tmp_sized = self.getSizedInteger(tmp_contents, self.trailer.offsetSize)
                 self.offsets.append(tmp_sized)
                 offset_i += 1
@@ -308,7 +313,7 @@
         @return unpickled object
         """
         result = None
-        tmp_byte = self.contents[self.currentOffset:self.currentOffset+1]
+        tmp_byte = self.contents[self.currentOffset:self.currentOffset + 1]
         marker_byte = unpack("!B", tmp_byte)[0]
         format = (marker_byte >> 4) & 0x0f
         extra = marker_byte & 0x0f
@@ -329,7 +334,7 @@
             elif extra == 0b1001:
                 result = True
             elif extra == 0b1111:
-                pass # fill byte
+                pass  # fill byte
             else:
                 raise InvalidPlistException(
                     "Invalid object found at offset: {0}".format(self.currentOffset - 1))
@@ -371,7 +376,7 @@
         elif format == 0b1101:
             extra = proc_extra(extra)
             result = self.readDict(extra)
-        else:    
+        else:
             raise InvalidPlistException(
                 "Invalid object found: {{format: {0}, extra: {1}}}".format(
                     bin(format), bin(extra)))
@@ -386,7 +391,7 @@
         """
         result = 0
         original_offset = self.currentOffset
-        data = self.contents[self.currentOffset:self.currentOffset+bytes]
+        data = self.contents[self.currentOffset:self.currentOffset + bytes]
         result = self.getSizedInteger(data, bytes)
         self.currentOffset = original_offset + bytes
         return result
@@ -400,17 +405,17 @@
         """
         result = 0.0
         to_read = pow(2, length)
-        data = self.contents[self.currentOffset:self.currentOffset+to_read]
-        if length == 2: # 4 bytes
+        data = self.contents[self.currentOffset:self.currentOffset + to_read]
+        if length == 2:  # 4 bytes
             result = unpack('>f', data)[0]
-        elif length == 3: # 8 bytes
+        elif length == 3:  # 8 bytes
             result = unpack('>d', data)[0]
         else:
             raise InvalidPlistException(
                 "Unknown real of length {0} bytes".format(to_read))
         return result
     
-    def readRefs(self, count):    
+    def readRefs(self, count):
         """
         Private method to read References.
         
@@ -421,7 +426,7 @@
         i = 0
         while i < count:
             fragment = self.contents[
-                self.currentOffset:self.currentOffset+self.trailer.objectRefSize]
+                self.currentOffset:self.currentOffset + self.trailer.objectRefSize]
             ref = self.getSizedInteger(fragment, len(fragment))
             refs.append(ref)
             self.currentOffset += self.trailer.objectRefSize
@@ -473,7 +478,7 @@
         @return ASCII encoded string
         """
         result = str(unpack("!{0}s".format(length),
-            self.contents[self.currentOffset:self.currentOffset+length])[0],
+            self.contents[self.currentOffset:self.currentOffset + length])[0],
             encoding="ascii")
         self.currentOffset += length
         return result
@@ -485,8 +490,8 @@
         @param length length of the string (integer)
         @return unicode encoded string
         """
-        actual_length = length*2
-        data = self.contents[self.currentOffset:self.currentOffset+actual_length]
+        actual_length = length * 2
+        data = self.contents[self.currentOffset:self.currentOffset + actual_length]
         # unpack not needed?!! data = unpack(">%ds" % (actual_length), data)[0]
         self.currentOffset += actual_length
         return data.decode('utf_16_be')
@@ -498,7 +503,7 @@
         @return date object (datetime.datetime)
         """
         global apple_reference_date_offset
-        result = unpack(">d", self.contents[self.currentOffset:self.currentOffset+8])[0]
+        result = unpack(">d", self.contents[self.currentOffset:self.currentOffset + 8])[0]
         result = datetime.datetime.utcfromtimestamp(result + apple_reference_date_offset)
         self.currentOffset += 8
         return result
@@ -510,7 +515,7 @@
         @param length number of bytes to read (integer)
         @return Data object
         """
-        result = self.contents[self.currentOffset:self.currentOffset+length]
+        result = self.contents[self.currentOffset:self.currentOffset + length]
         self.currentOffset += length
         return Data(result)
     
@@ -521,7 +526,7 @@
         @param length length of the UID (integer)
         @return Uid object
         """
-        return Uid(self.readInteger(length+1))
+        return Uid(self.readInteger(length + 1))
     
     def getSizedInteger(self, data, bytes):
         """
@@ -544,24 +549,29 @@
             raise InvalidPlistException("Encountered integer longer than 8 bytes.")
         return result
 
+
 class HashableWrapper(object):
     """
     Class wrapping a hashable value.
     """
     def __init__(self, value):
         self.value = value
+
     def __repr__(self):
         return "<HashableWrapper: %s>" % [self.value]
 
+
 class BoolWrapper(object):
     """
     Class wrapping a boolean value.
     """
     def __init__(self, value):
         self.value = value
+
     def __repr__(self):
         return "<BoolWrapper: %s>" % self.value
 
+
 class PlistWriter(object):
     """
     Class implementing the plist writer.
@@ -640,20 +650,20 @@
         """
         output = self.header
         wrapped_root = self.wrapRoot(root)
-        should_reference_root = True#not isinstance(wrapped_root, HashableWrapper)
+        should_reference_root = True  # not isinstance(wrapped_root, HashableWrapper)
         self.computeOffsets(wrapped_root, asReference=should_reference_root, isRoot=True)
         self.trailer = self.trailer._replace(
-            **{'objectRefSize':self.intSize(len(self.computedUniques))})
+            **{'objectRefSize': self.intSize(len(self.computedUniques))})
         (_, output) = self.writeObjectReference(wrapped_root, output)
         output = self.writeObject(wrapped_root, output, setReferencePosition=True)
         
         # output size at this point is an upper bound on how big the
         # object reference offsets need to be.
         self.trailer = self.trailer._replace(**{
-            'offsetSize':self.intSize(len(output)),
-            'offsetCount':len(self.computedUniques),
-            'offsetTableOffset':len(output),
-            'topLevelObjectNumber':0
+            'offsetSize': self.intSize(len(output)),
+            'offsetCount': len(self.computedUniques),
+            'offsetTableOffset': len(output),
+            'topLevelObjectNumber': 0
             })
         
         output = self.writeOffsetTable(output)
@@ -695,7 +705,7 @@
 
     def incrementByteCount(self, field, incr=1):
         self.byteCounts = self.byteCounts._replace(
-            **{field:self.byteCounts.__getattribute__(field) + incr})
+            **{field: self.byteCounts.__getattribute__(field) + incr})
 
     def computeOffsets(self, obj, asReference=False, isRoot=False):
         def check_key(key):
@@ -724,36 +734,36 @@
             self.incrementByteCount('boolBytes')
         elif isinstance(obj, Uid):
             size = self.intSize(obj)
-            self.incrementByteCount('uidBytes', incr=1+size)
+            self.incrementByteCount('uidBytes', incr=1 + size)
         elif isinstance(obj, int):
             size = self.intSize(obj)
-            self.incrementByteCount('intBytes', incr=1+size)
+            self.incrementByteCount('intBytes', incr=1 + size)
         elif isinstance(obj, (float)):
             size = self.realSize(obj)
-            self.incrementByteCount('realBytes', incr=1+size)
-        elif isinstance(obj, datetime.datetime):    
+            self.incrementByteCount('realBytes', incr=1 + size)
+        elif isinstance(obj, datetime.datetime):
             self.incrementByteCount('dateBytes', incr=2)
         elif isinstance(obj, Data):
             size = proc_size(len(obj))
-            self.incrementByteCount('dataBytes', incr=1+size)
+            self.incrementByteCount('dataBytes', incr=1 + size)
         elif isinstance(obj, str):
             size = proc_size(len(obj))
-            self.incrementByteCount('stringBytes', incr=1+size)
+            self.incrementByteCount('stringBytes', incr=1 + size)
         elif isinstance(obj, HashableWrapper):
             obj = obj.value
             if isinstance(obj, set):
                 size = proc_size(len(obj))
-                self.incrementByteCount('setBytes', incr=1+size)
+                self.incrementByteCount('setBytes', incr=1 + size)
                 for value in obj:
                     self.computeOffsets(value, asReference=True)
             elif isinstance(obj, (list, tuple)):
                 size = proc_size(len(obj))
-                self.incrementByteCount('arrayBytes', incr=1+size)
+                self.incrementByteCount('arrayBytes', incr=1 + size)
                 for value in obj:
                     self.computeOffsets(value, asReference=True)
             elif isinstance(obj, dict):
                 size = proc_size(len(obj))
-                self.incrementByteCount('dictBytes', incr=1+size)
+                self.incrementByteCount('dictBytes', incr=1 + size)
                 for key, value in obj.items():
                     check_key(key)
                     self.computeOffsets(key, asReference=True)
@@ -838,7 +848,7 @@
         elif isinstance(obj, str):
             # Python 3 uses unicode strings only
             bytes = obj.encode('utf_16_be')
-            output += proc_variable_length(0b0110, len(bytes)/2)
+            output += proc_variable_length(0b0110, len(bytes) / 2)
             output += bytes
         elif isinstance(obj, HashableWrapper):
             obj = obj.value
@@ -885,7 +895,7 @@
         all_positions = []
         writtenReferences = list(self.writtenReferences.items())
         writtenReferences.sort(key=lambda x: x[1])
-        for obj,order in writtenReferences:
+        for obj, order in writtenReferences:
             position = self.referencePositions.get(obj)
             if position is None:
                 raise InvalidPlistException(
@@ -939,18 +949,18 @@
         @return number of bytes required (integer)
         """
         # SIGNED
-        if obj < 0: # Signed integer, always 8 bytes
+        if obj < 0:  # Signed integer, always 8 bytes
             return 8
         # UNSIGNED
-        elif obj <= 0xFF: # 1 byte
+        elif obj <= 0xFF:  # 1 byte
             return 1
-        elif obj <= 0xFFFF: # 2 bytes
+        elif obj <= 0xFFFF:  # 2 bytes
             return 2
-        elif obj <= 0xFFFFFFFF: # 4 bytes
+        elif obj <= 0xFFFFFFFF:  # 4 bytes
             return 4
         # SIGNED
         # 0x7FFFFFFFFFFFFFFF is the max.
-        elif obj <= 0x7FFFFFFFFFFFFFFF: # 8 bytes
+        elif obj <= 0x7FFFFFFFFFFFFFFF:  # 8 bytes
             return 8
         else:
             raise InvalidPlistException(

eric ide

mercurial