276 """ |
276 """ |
277 return self.readRoot() |
277 return self.readRoot() |
278 |
278 |
279 def reset(self): |
279 def reset(self): |
280 """ |
280 """ |
281 Private method to reset the instance object. |
281 Public method to reset the instance object. |
282 """ |
282 """ |
283 self.trailer = None |
283 self.trailer = None |
284 self.contents = b'' |
284 self.contents = b'' |
285 self.offsets = [] |
285 self.offsets = [] |
286 self.currentOffset = 0 |
286 self.currentOffset = 0 |
287 |
287 |
288 def readRoot(self): |
288 def readRoot(self): |
289 """ |
289 """ |
290 Private method to read the root object. |
290 Public method to read the root object. |
291 |
291 |
292 @return unpickled object |
292 @return unpickled object |
293 @exception InvalidPlistException raised to indicate an invalid |
293 @exception InvalidPlistException raised to indicate an invalid |
294 plist file |
294 plist file |
295 """ |
295 """ |
325 raise InvalidPlistException(e) |
325 raise InvalidPlistException(e) |
326 return result |
326 return result |
327 |
327 |
328 def setCurrentOffsetToObjectNumber(self, objectNumber): |
328 def setCurrentOffsetToObjectNumber(self, objectNumber): |
329 """ |
329 """ |
330 Private method to set the current offset. |
330 Public method to set the current offset. |
331 |
331 |
332 @param objectNumber number of the object (integer) |
332 @param objectNumber number of the object (integer) |
333 """ |
333 """ |
334 self.currentOffset = self.offsets[objectNumber] |
334 self.currentOffset = self.offsets[objectNumber] |
335 |
335 |
336 def readObject(self): |
336 def readObject(self): |
337 """ |
337 """ |
338 Private method to read the object data. |
338 Public method to read the object data. |
339 |
339 |
340 @return unpickled object |
340 @return unpickled object |
341 @exception InvalidPlistException raised to indicate an invalid |
341 @exception InvalidPlistException raised to indicate an invalid |
342 plist file |
342 plist file |
343 """ |
343 """ |
412 bin(format), bin(extra))) |
412 bin(format), bin(extra))) |
413 return result |
413 return result |
414 |
414 |
415 def readInteger(self, bytes): |
415 def readInteger(self, bytes): |
416 """ |
416 """ |
417 Private method to read an Integer object. |
417 Public method to read an Integer object. |
418 |
418 |
419 @param bytes length of the object (integer) |
419 @param bytes length of the object (integer) |
420 @return integer object |
420 @return integer object |
421 """ |
421 """ |
422 result = 0 |
422 result = 0 |
426 self.currentOffset = original_offset + bytes |
426 self.currentOffset = original_offset + bytes |
427 return result |
427 return result |
428 |
428 |
429 def readReal(self, length): |
429 def readReal(self, length): |
430 """ |
430 """ |
431 Private method to read a Real object. |
431 Public method to read a Real object. |
432 |
432 |
433 @param length length of the object (integer) |
433 @param length length of the object (integer) |
434 @return float object |
434 @return float object |
435 @exception InvalidPlistException raised to indicate an invalid |
435 @exception InvalidPlistException raised to indicate an invalid |
436 plist file |
436 plist file |
447 "Unknown real of length {0} bytes".format(to_read)) |
447 "Unknown real of length {0} bytes".format(to_read)) |
448 return result |
448 return result |
449 |
449 |
450 def readRefs(self, count): |
450 def readRefs(self, count): |
451 """ |
451 """ |
452 Private method to read References. |
452 Public method to read References. |
453 |
453 |
454 @param count amount of the references (integer) |
454 @param count amount of the references (integer) |
455 @return list of references (list of integers) |
455 @return list of references (list of integers) |
456 """ |
456 """ |
457 refs = [] |
457 refs = [] |
517 self.currentOffset += length |
517 self.currentOffset += length |
518 return result |
518 return result |
519 |
519 |
520 def readUnicode(self, length): |
520 def readUnicode(self, length): |
521 """ |
521 """ |
522 Private method to read an Unicode encoded string. |
522 Public method to read an Unicode encoded string. |
523 |
523 |
524 @param length length of the string (integer) |
524 @param length length of the string (integer) |
525 @return unicode encoded string |
525 @return unicode encoded string |
526 """ |
526 """ |
527 actual_length = length * 2 |
527 actual_length = length * 2 |
531 self.currentOffset += actual_length |
531 self.currentOffset += actual_length |
532 return data.decode('utf_16_be') |
532 return data.decode('utf_16_be') |
533 |
533 |
534 def readDate(self): |
534 def readDate(self): |
535 """ |
535 """ |
536 Private method to read a date. |
536 Public method to read a date. |
537 |
537 |
538 @return date object (datetime.datetime) |
538 @return date object (datetime.datetime) |
539 """ |
539 """ |
540 global apple_reference_date_offset |
540 global apple_reference_date_offset |
541 result = unpack( |
541 result = unpack( |
546 self.currentOffset += 8 |
546 self.currentOffset += 8 |
547 return result |
547 return result |
548 |
548 |
549 def readData(self, length): |
549 def readData(self, length): |
550 """ |
550 """ |
551 Private method to read some bytes. |
551 Public method to read some bytes. |
552 |
552 |
553 @param length number of bytes to read (integer) |
553 @param length number of bytes to read (integer) |
554 @return Data object |
554 @return Data object |
555 """ |
555 """ |
556 result = self.contents[self.currentOffset:self.currentOffset + length] |
556 result = self.contents[self.currentOffset:self.currentOffset + length] |
557 self.currentOffset += length |
557 self.currentOffset += length |
558 return Data(result) |
558 return Data(result) |
559 |
559 |
560 def readUid(self, length): |
560 def readUid(self, length): |
561 """ |
561 """ |
562 Private method to read a UID. |
562 Public method to read a UID. |
563 |
563 |
564 @param length length of the UID (integer) |
564 @param length length of the UID (integer) |
565 @return Uid object |
565 @return Uid object |
566 """ |
566 """ |
567 return Uid(self.readInteger(length + 1)) |
567 return Uid(self.readInteger(length + 1)) |
568 |
568 |
569 def getSizedInteger(self, data, bytes): |
569 def getSizedInteger(self, data, bytes): |
570 """ |
570 """ |
571 Private method to read an integer of a specific size. |
571 Public method to read an integer of a specific size. |
572 |
572 |
573 @param data data to extract the integer from (bytes) |
573 @param data data to extract the integer from (bytes) |
574 @param bytes length of the integer (integer) |
574 @param bytes length of the integer (integer) |
575 @return read integer (integer) |
575 @return read integer (integer) |
576 @exception InvalidPlistException raised to indicate an invalid |
576 @exception InvalidPlistException raised to indicate an invalid |
659 self.wrappedTrue = BoolWrapper(True) |
659 self.wrappedTrue = BoolWrapper(True) |
660 self.wrappedFalse = BoolWrapper(False) |
660 self.wrappedFalse = BoolWrapper(False) |
661 |
661 |
662 def reset(self): |
662 def reset(self): |
663 """ |
663 """ |
664 Private method to reset the instance object. |
664 Public method to reset the instance object. |
665 """ |
665 """ |
666 self.byteCounts = PlistByteCounts(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) |
666 self.byteCounts = PlistByteCounts(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) |
667 self.trailer = PlistTrailer(0, 0, 0, 0, 0) |
667 self.trailer = PlistTrailer(0, 0, 0, 0, 0) |
668 |
668 |
669 # A set of all the uniques which have been computed. |
669 # A set of all the uniques which have been computed. |
673 # A dict of the positions of the written uniques. |
673 # A dict of the positions of the written uniques. |
674 self.referencePositions = {} |
674 self.referencePositions = {} |
675 |
675 |
676 def positionOfObjectReference(self, obj): |
676 def positionOfObjectReference(self, obj): |
677 """ |
677 """ |
678 Private method to get the position of an object. |
678 Public method to get the position of an object. |
679 |
679 |
680 If the given object has been written already, return its |
680 If the given object has been written already, return its |
681 position in the offset table. Otherwise, return None. |
681 position in the offset table. Otherwise, return None. |
682 |
682 |
683 @param obj object |
683 @param obj object |
735 output += pack('!xxxxxxBBQQQ', *self.trailer) |
735 output += pack('!xxxxxxBBQQQ', *self.trailer) |
736 self.file.write(output) |
736 self.file.write(output) |
737 |
737 |
738 def wrapRoot(self, root): |
738 def wrapRoot(self, root): |
739 """ |
739 """ |
740 Private method to generate object wrappers. |
740 Public method to generate object wrappers. |
741 |
741 |
742 @param root object to be wrapped |
742 @param root object to be wrapped |
743 @return wrapped object |
743 @return wrapped object |
744 """ |
744 """ |
745 if isinstance(root, bool): |
745 if isinstance(root, bool): |
854 else: |
854 else: |
855 raise InvalidPlistException("Unknown object type.") |
855 raise InvalidPlistException("Unknown object type.") |
856 |
856 |
857 def writeObjectReference(self, obj, output): |
857 def writeObjectReference(self, obj, output): |
858 """ |
858 """ |
859 Private method to write an object reference. |
859 Public method to write an object reference. |
860 |
860 |
861 Tries to write an object reference, adding it to the references |
861 Tries to write an object reference, adding it to the references |
862 table. Does not write the actual object bytes or set the reference |
862 table. Does not write the actual object bytes or set the reference |
863 position. Returns a tuple of whether the object was a new reference |
863 position. Returns a tuple of whether the object was a new reference |
864 (True if it was, False if it already was in the reference table) |
864 (True if it was, False if it already was in the reference table) |
879 position, bytes=self.trailer.objectRefSize) |
879 position, bytes=self.trailer.objectRefSize) |
880 return (False, output) |
880 return (False, output) |
881 |
881 |
882 def writeObject(self, obj, output, setReferencePosition=False): |
882 def writeObject(self, obj, output, setReferencePosition=False): |
883 """ |
883 """ |
884 Private method to serialize the given object to the output. |
884 Public method to serialize the given object to the output. |
885 |
885 |
886 @param obj object to be serialized |
886 @param obj object to be serialized |
887 @param output output to be serialized to (bytes) |
887 @param output output to be serialized to (bytes) |
888 @param setReferencePosition flag indicating, that the reference |
888 @param setReferencePosition flag indicating, that the reference |
889 position the object was written to shall be recorded (boolean) |
889 position the object was written to shall be recorded (boolean) |
971 objRef, output, setReferencePosition=True) |
971 objRef, output, setReferencePosition=True) |
972 return output |
972 return output |
973 |
973 |
974 def writeOffsetTable(self, output): |
974 def writeOffsetTable(self, output): |
975 """ |
975 """ |
976 Private method to write all of the object reference offsets. |
976 Public method to write all of the object reference offsets. |
977 |
977 |
978 @param output current output (bytes) |
978 @param output current output (bytes) |
979 @return new output (bytes) |
979 @return new output (bytes) |
980 @exception InvalidPlistException raised to indicate an invalid |
980 @exception InvalidPlistException raised to indicate an invalid |
981 plist file |
981 plist file |
993 all_positions.append(position) |
993 all_positions.append(position) |
994 return output |
994 return output |
995 |
995 |
996 def binaryReal(self, obj): |
996 def binaryReal(self, obj): |
997 """ |
997 """ |
998 Private method to pack a real object. |
998 Public method to pack a real object. |
999 |
999 |
1000 @param obj real to be packed |
1000 @param obj real to be packed |
1001 @return serialized object (bytes) |
1001 @return serialized object (bytes) |
1002 """ |
1002 """ |
1003 # just use doubles |
1003 # just use doubles |
1004 result = pack('>d', obj) |
1004 result = pack('>d', obj) |
1005 return result |
1005 return result |
1006 |
1006 |
1007 def binaryInt(self, obj, bytes=None): |
1007 def binaryInt(self, obj, bytes=None): |
1008 """ |
1008 """ |
1009 Private method to pack an integer object. |
1009 Public method to pack an integer object. |
1010 |
1010 |
1011 @param obj integer to be packed |
1011 @param obj integer to be packed |
1012 @param bytes length the integer should be packed into (integer) |
1012 @param bytes length the integer should be packed into (integer) |
1013 @return serialized object (bytes) |
1013 @return serialized object (bytes) |
1014 @exception InvalidPlistException raised to indicate an invalid |
1014 @exception InvalidPlistException raised to indicate an invalid |
1031 " than 8 bytes.") |
1031 " than 8 bytes.") |
1032 return result |
1032 return result |
1033 |
1033 |
1034 def intSize(self, obj): |
1034 def intSize(self, obj): |
1035 """ |
1035 """ |
1036 Private method to determine the number of bytes necessary to store the |
1036 Public method to determine the number of bytes necessary to store the |
1037 given integer. |
1037 given integer. |
1038 |
1038 |
1039 @param obj integer object |
1039 @param obj integer object |
1040 @return number of bytes required (integer) |
1040 @return number of bytes required (integer) |
1041 @exception InvalidPlistException raised to indicate an invalid |
1041 @exception InvalidPlistException raised to indicate an invalid |
1060 "Core Foundation can't handle integers with size greater" |
1060 "Core Foundation can't handle integers with size greater" |
1061 " than 8 bytes.") |
1061 " than 8 bytes.") |
1062 |
1062 |
1063 def realSize(self, obj): |
1063 def realSize(self, obj): |
1064 """ |
1064 """ |
1065 Private method to determine the number of bytes necessary to store the |
1065 Public method to determine the number of bytes necessary to store the |
1066 given real. |
1066 given real. |
1067 |
1067 |
1068 @param obj real object |
1068 @param obj real object |
1069 @return number of bytes required (integer) |
1069 @return number of bytes required (integer) |
1070 """ |
1070 """ |