776 @param incr byte count increment (integer) |
776 @param incr byte count increment (integer) |
777 """ |
777 """ |
778 self.byteCounts = self.byteCounts._replace( |
778 self.byteCounts = self.byteCounts._replace( |
779 **{field: self.byteCounts.__getattribute__(field) + incr}) |
779 **{field: self.byteCounts.__getattribute__(field) + incr}) |
780 |
780 |
|
781 def __checkKey(self, key): |
|
782 """ |
|
783 Private method to check the validity of a key. |
|
784 |
|
785 @param key key to be checked |
|
786 @exception InvalidPlistException raised to indicate an invalid |
|
787 plist file |
|
788 """ |
|
789 if key is None: |
|
790 raise InvalidPlistException( |
|
791 'Dictionary keys cannot be null in plists.') |
|
792 elif isinstance(key, Data): |
|
793 raise InvalidPlistException( |
|
794 'Data cannot be dictionary keys in plists.') |
|
795 elif not isinstance(key, str): |
|
796 raise InvalidPlistException('Keys must be strings.') |
|
797 |
|
798 def __processSize(self, size): |
|
799 """ |
|
800 Private method to process a size. |
|
801 |
|
802 @param size size value to be processed (int) |
|
803 @return processed size (int) |
|
804 """ |
|
805 if size > 0b1110: |
|
806 size += self.intSize(size) |
|
807 return size |
|
808 |
781 def computeOffsets(self, obj, asReference=False, isRoot=False): |
809 def computeOffsets(self, obj, asReference=False, isRoot=False): |
782 """ |
810 """ |
783 Public method to compute offsets of an object. |
811 Public method to compute offsets of an object. |
784 |
812 |
785 @param obj plist object |
813 @param obj plist object |
786 @param asReference flag indicating offsets as references (boolean) |
814 @param asReference flag indicating offsets as references (boolean) |
787 @param isRoot flag indicating a root object (boolean) |
815 @param isRoot flag indicating a root object (boolean) |
788 @exception InvalidPlistException raised to indicate an invalid |
816 @exception InvalidPlistException raised to indicate an invalid |
789 plist file |
817 plist file |
790 """ # __IGNORE_WARNING__ |
818 """ |
791 def check_key(key): |
|
792 if key is None: |
|
793 raise InvalidPlistException( |
|
794 'Dictionary keys cannot be null in plists.') |
|
795 elif isinstance(key, Data): |
|
796 raise InvalidPlistException( |
|
797 'Data cannot be dictionary keys in plists.') |
|
798 elif not isinstance(key, str): |
|
799 raise InvalidPlistException('Keys must be strings.') |
|
800 |
|
801 def proc_size(size): |
|
802 if size > 0b1110: |
|
803 size += self.intSize(size) |
|
804 return size |
|
805 |
|
806 # If this should be a reference, then we keep a record of it in the |
819 # If this should be a reference, then we keep a record of it in the |
807 # uniques table. |
820 # uniques table. |
808 if asReference: |
821 if asReference: |
809 if obj in self.computedUniques: |
822 if obj in self.computedUniques: |
810 return |
823 return |
825 size = self.realSize(obj) |
838 size = self.realSize(obj) |
826 self.incrementByteCount('realBytes', incr=1 + size) |
839 self.incrementByteCount('realBytes', incr=1 + size) |
827 elif isinstance(obj, datetime.datetime): |
840 elif isinstance(obj, datetime.datetime): |
828 self.incrementByteCount('dateBytes', incr=2) |
841 self.incrementByteCount('dateBytes', incr=2) |
829 elif isinstance(obj, Data): |
842 elif isinstance(obj, Data): |
830 size = proc_size(len(obj)) |
843 size = self.__processSize(len(obj)) |
831 self.incrementByteCount('dataBytes', incr=1 + size) |
844 self.incrementByteCount('dataBytes', incr=1 + size) |
832 elif isinstance(obj, str): |
845 elif isinstance(obj, str): |
833 size = proc_size(len(obj)) |
846 size = self.__processSize(len(obj)) |
834 self.incrementByteCount('stringBytes', incr=1 + size) |
847 self.incrementByteCount('stringBytes', incr=1 + size) |
835 elif isinstance(obj, HashableWrapper): |
848 elif isinstance(obj, HashableWrapper): |
836 obj = obj.value |
849 obj = obj.value |
837 if isinstance(obj, set): |
850 if isinstance(obj, set): |
838 size = proc_size(len(obj)) |
851 size = self.__processSize(len(obj)) |
839 self.incrementByteCount('setBytes', incr=1 + size) |
852 self.incrementByteCount('setBytes', incr=1 + size) |
840 for value in obj: |
853 for value in obj: |
841 self.computeOffsets(value, asReference=True) |
854 self.computeOffsets(value, asReference=True) |
842 elif isinstance(obj, (list, tuple)): |
855 elif isinstance(obj, (list, tuple)): |
843 size = proc_size(len(obj)) |
856 size = self.__processSize(len(obj)) |
844 self.incrementByteCount('arrayBytes', incr=1 + size) |
857 self.incrementByteCount('arrayBytes', incr=1 + size) |
845 for value in obj: |
858 for value in obj: |
846 self.computeOffsets(value, asReference=True) |
859 self.computeOffsets(value, asReference=True) |
847 elif isinstance(obj, dict): |
860 elif isinstance(obj, dict): |
848 size = proc_size(len(obj)) |
861 size = self.__processSize(len(obj)) |
849 self.incrementByteCount('dictBytes', incr=1 + size) |
862 self.incrementByteCount('dictBytes', incr=1 + size) |
850 for key, value in obj.items(): |
863 for key, value in obj.items(): |
851 check_key(key) |
864 self.__checkKey(key) |
852 self.computeOffsets(key, asReference=True) |
865 self.computeOffsets(key, asReference=True) |
853 self.computeOffsets(value, asReference=True) |
866 self.computeOffsets(value, asReference=True) |
854 else: |
867 else: |
855 raise InvalidPlistException("Unknown object type.") |
868 raise InvalidPlistException("Unknown object type.") |
856 |
869 |