Commit | Line | Data |
---|---|---|
0235b0db | 1 | # SPDX-License-Identifier: MIT |
81447b5b | 2 | # |
811644b8 | 3 | # Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com> |
81447b5b | 4 | |
c345b078 | 5 | |
3fb99a22 | 6 | from bt2 import logging as bt2_logging |
d24d5663 | 7 | from bt2 import native_bt |
0feb43aa SM |
8 | from bt2 import error as bt2_error |
9 | ||
10 | ||
11 | class UnknownObject(Exception): | |
12 | """ | |
13 | Raised when a component class handles a query for an object it doesn't | |
14 | know about. | |
15 | """ | |
16 | ||
17 | pass | |
18 | ||
19 | ||
20 | class _OverflowError(bt2_error._Error, OverflowError): | |
21 | pass | |
22 | ||
23 | ||
24 | class TryAgain(Exception): | |
25 | pass | |
26 | ||
27 | ||
28 | class Stop(StopIteration): | |
29 | pass | |
81447b5b PP |
30 | |
31 | ||
32 | def _check_bool(o): | |
33 | if not isinstance(o, bool): | |
34 | raise TypeError("'{}' is not a 'bool' object".format(o.__class__.__name__)) | |
35 | ||
36 | ||
37 | def _check_int(o): | |
38 | if not isinstance(o, int): | |
39 | raise TypeError("'{}' is not an 'int' object".format(o.__class__.__name__)) | |
40 | ||
41 | ||
42 | def _check_float(o): | |
43 | if not isinstance(o, float): | |
44 | raise TypeError("'{}' is not a 'float' object".format(o.__class__.__name__)) | |
45 | ||
46 | ||
47 | def _check_str(o): | |
48 | if not isinstance(o, str): | |
49 | raise TypeError("'{}' is not a 'str' object".format(o.__class__.__name__)) | |
50 | ||
51 | ||
52 | def _check_type(o, expected_type): | |
53 | if not isinstance(o, expected_type): | |
cfbd7cf3 FD |
54 | raise TypeError( |
55 | "'{}' is not a '{}' object".format(o.__class__.__name__, expected_type) | |
56 | ) | |
81447b5b PP |
57 | |
58 | ||
c6af194f | 59 | def _is_in_int64_range(v): |
cfbd7cf3 | 60 | assert isinstance(v, int) |
768f9bcb | 61 | return v >= -(2**63) and v <= (2**63 - 1) |
81447b5b PP |
62 | |
63 | ||
c6af194f PP |
64 | def _is_int64(v): |
65 | if not isinstance(v, int): | |
66 | return False | |
67 | ||
68 | return _is_in_int64_range(v) | |
69 | ||
70 | ||
71 | def _is_in_uint64_range(v): | |
cfbd7cf3 | 72 | assert isinstance(v, int) |
768f9bcb | 73 | return v >= 0 and v <= (2**64 - 1) |
81447b5b PP |
74 | |
75 | ||
c6af194f PP |
76 | def _is_uint64(v): |
77 | if not isinstance(v, int): | |
78 | return False | |
79 | ||
80 | return _is_in_uint64_range(v) | |
81 | ||
82 | ||
81447b5b | 83 | def _check_int64(v, msg=None): |
c6af194f PP |
84 | _check_int(v) |
85 | ||
86 | if not _is_in_int64_range(v): | |
81447b5b | 87 | if msg is None: |
f5567ea8 | 88 | msg = "expecting a signed 64-bit integral value" |
81447b5b | 89 | |
f5567ea8 | 90 | msg += " (got {})".format(v) |
81447b5b PP |
91 | raise ValueError(msg) |
92 | ||
93 | ||
94 | def _check_uint64(v, msg=None): | |
c6af194f PP |
95 | _check_int(v) |
96 | ||
97 | if not _is_in_uint64_range(v): | |
81447b5b | 98 | if msg is None: |
f5567ea8 | 99 | msg = "expecting an unsigned 64-bit integral value" |
81447b5b | 100 | |
f5567ea8 | 101 | msg += " (got {})".format(v) |
81447b5b PP |
102 | raise ValueError(msg) |
103 | ||
104 | ||
105 | def _is_m1ull(v): | |
106 | return v == 18446744073709551615 | |
107 | ||
108 | ||
109 | def _is_pow2(v): | |
110 | return v != 0 and ((v & (v - 1)) == 0) | |
111 | ||
112 | ||
113 | def _check_alignment(a): | |
114 | _check_uint64(a) | |
115 | ||
81447b5b | 116 | if not _is_pow2(a): |
f5567ea8 | 117 | raise ValueError("{} is not a power of two".format(a)) |
81447b5b PP |
118 | |
119 | ||
e874da19 PP |
120 | def _check_log_level(log_level): |
121 | _check_int(log_level) | |
122 | ||
123 | log_levels = ( | |
3fb99a22 PP |
124 | bt2_logging.LoggingLevel.TRACE, |
125 | bt2_logging.LoggingLevel.DEBUG, | |
126 | bt2_logging.LoggingLevel.INFO, | |
127 | bt2_logging.LoggingLevel.WARNING, | |
128 | bt2_logging.LoggingLevel.ERROR, | |
129 | bt2_logging.LoggingLevel.FATAL, | |
130 | bt2_logging.LoggingLevel.NONE, | |
e874da19 PP |
131 | ) |
132 | ||
133 | if log_level not in log_levels: | |
134 | raise ValueError("'{}' is not a valid logging level".format(log_level)) | |
d24d5663 PP |
135 | |
136 | ||
137 | def _handle_func_status(status, msg=None): | |
138 | if status == native_bt.__BT_FUNC_STATUS_OK: | |
139 | # no error | |
140 | return | |
141 | ||
4acc866e | 142 | if status == native_bt.__BT_FUNC_STATUS_ERROR: |
ce4923b0 | 143 | assert msg is not None |
c345b078 | 144 | raise bt2_error._Error(msg) |
4acc866e SM |
145 | elif status == native_bt.__BT_FUNC_STATUS_MEMORY_ERROR: |
146 | assert msg is not None | |
c345b078 | 147 | raise bt2_error._MemoryError(msg) |
d24d5663 PP |
148 | elif status == native_bt.__BT_FUNC_STATUS_END: |
149 | if msg is None: | |
c345b078 | 150 | raise Stop |
d24d5663 | 151 | else: |
c345b078 | 152 | raise Stop(msg) |
d24d5663 PP |
153 | elif status == native_bt.__BT_FUNC_STATUS_AGAIN: |
154 | if msg is None: | |
c345b078 | 155 | raise TryAgain |
d24d5663 | 156 | else: |
c345b078 | 157 | raise TryAgain(msg) |
520cdc82 | 158 | elif status == native_bt.__BT_FUNC_STATUS_OVERFLOW_ERROR: |
d24d5663 | 159 | if msg is None: |
c345b078 | 160 | raise _OverflowError |
d24d5663 | 161 | else: |
c345b078 | 162 | raise _OverflowError(msg) |
76b6c2f7 | 163 | elif status == native_bt.__BT_FUNC_STATUS_UNKNOWN_OBJECT: |
d24d5663 | 164 | if msg is None: |
c345b078 | 165 | raise UnknownObject |
d24d5663 | 166 | else: |
c345b078 | 167 | raise UnknownObject(msg) |
d24d5663 PP |
168 | else: |
169 | assert False | |
2a52034a PP |
170 | |
171 | ||
172 | class _ListenerHandle: | |
67de22ba SM |
173 | def __init__(self, addr): |
174 | self._addr = addr | |
175 | self._listener_id = None | |
176 | ||
177 | def _set_listener_id(self, listener_id): | |
2a52034a | 178 | self._listener_id = listener_id |
67de22ba SM |
179 | |
180 | def _invalidate(self): | |
181 | self._listener_id = None |