OLD | NEW |
1 # -*- coding: utf-8 -*- | 1 # -*- coding: utf-8 -*- |
2 """The plist file object.""" | 2 """The plist file object.""" |
3 | 3 |
4 from __future__ import unicode_literals | 4 from __future__ import unicode_literals |
5 | 5 |
6 import binascii | 6 import biplist |
7 import os | |
8 import plistlib | |
9 | |
10 from binplist import binplist | |
11 | 7 |
12 | 8 |
13 class PlistFile(object): | 9 class PlistFile(object): |
14 """Class that defines a plist file. | 10 """Class that defines a plist file. |
15 | 11 |
16 Attributes: | 12 Attributes: |
17 root_key: the plist root key (instance of plistlib._InternalDict). | 13 root_key (dict): the plist root key. |
18 """ | 14 """ |
19 | 15 |
20 def __init__(self): | 16 def __init__(self): |
21 """Initializes the plist file object.""" | 17 """Initializes the plist file object.""" |
22 super(PlistFile, self).__init__() | 18 super(PlistFile, self).__init__() |
23 self.root_key = None | 19 self.root_key = None |
24 | 20 |
25 def GetValueByPath(self, path_segments): | 21 def GetValueByPath(self, path_segments): |
26 """Retrieves a plist value by path. | 22 """Retrieves a plist value by path. |
27 | 23 |
28 Args: | 24 Args: |
29 path_segments: a list of path segments strings relative from the root | 25 path_segments (list[str]): path segment strings relative to the root |
30 of the plist. | 26 of the plist. |
31 | 27 |
32 Returns: | 28 Returns: |
33 The value of the key specified by the path or None. | 29 object: The value of the key specified by the path or None. |
34 """ | 30 """ |
35 key = self.root_key | 31 key = self.root_key |
36 for path_segment in path_segments: | 32 for path_segment in path_segments: |
37 # pylint: disable=protected-access | 33 if isinstance(key, dict): |
38 if isinstance(key, (dict, plistlib._InternalDict)): | 34 try: |
39 key = key.get(path_segment) | 35 key = key[path_segment] |
| 36 except KeyError: |
| 37 return None |
40 | 38 |
41 elif isinstance(key, list): | 39 elif isinstance(key, list): |
42 try: | 40 try: |
43 list_index = int(path_segment, 10) | 41 list_index = int(path_segment, 10) |
44 except ValueError: | 42 except ValueError: |
45 return None | 43 return None |
46 | 44 |
47 key = key[list_index] | 45 key = key[list_index] |
48 | 46 |
49 else: | 47 else: |
50 return None | 48 return None |
51 | 49 |
52 if not key: | 50 if not key: |
53 return None | 51 return None |
54 | 52 |
55 return key | 53 return key |
56 | 54 |
57 def Read(self, file_object): | 55 def Read(self, file_object): |
58 """Reads a plist from a file-like object. | 56 """Reads a plist from a file-like object. |
59 | 57 |
60 Args: | 58 Args: |
61 file_object: the file-like object. | 59 file_object (dfvfs.FileIO): a file-like object containing plist data. |
62 | 60 |
63 Raises: | 61 Raises: |
64 IOError: if the plist file-like object cannot be read. | 62 IOError: if the plist file-like object cannot be read. |
65 """ | 63 """ |
66 try: | 64 try: |
67 file_object.seek(0, os.SEEK_SET) | 65 self.root_key = biplist.readPlist(file_object) |
68 # Note that binplist.readPlist does not seek to offset 0. | |
69 self.root_key = binplist.readPlist(file_object) | |
70 | 66 |
71 except ( | 67 except ( |
72 AttributeError, binascii.Error, binplist.FormatError, LookupError, | 68 biplist.NotBinaryPlistException, |
73 OverflowError, ValueError) as exception: | 69 biplist.InvalidPlistException) as exception: |
74 raise IOError(exception) | 70 raise IOError(exception) |
OLD | NEW |