Commit | Line | Data |
---|---|---|
0235b0db | 1 | # SPDX-License-Identifier: MIT |
19bb8b5a PP |
2 | # |
3 | # Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com> | |
19bb8b5a | 4 | |
e5914347 SM |
5 | from bt2 import native_bt |
6 | from bt2 import object as bt2_object | |
7 | from bt2 import utils as bt2_utils | |
c345b078 | 8 | from bt2 import error as bt2_error |
19bb8b5a | 9 | import collections.abc |
19bb8b5a PP |
10 | |
11 | ||
fc866000 | 12 | class _IntegerRangeConst: |
7a2a2328 | 13 | def __init__(self, lower, upper=None): |
19bb8b5a | 14 | self._check_type(lower) |
7a2a2328 PP |
15 | |
16 | if upper is None: | |
17 | upper = lower | |
18 | ||
19bb8b5a PP |
19 | self._check_type(upper) |
20 | ||
21 | if lower > upper: | |
cfbd7cf3 FD |
22 | raise ValueError( |
23 | "range's lower bound ({}) is greater than its upper bound ({})".format( | |
24 | lower, upper | |
25 | ) | |
26 | ) | |
19bb8b5a PP |
27 | |
28 | self._lower = lower | |
29 | self._upper = upper | |
30 | ||
31 | @property | |
32 | def lower(self): | |
33 | return self._lower | |
34 | ||
35 | @property | |
36 | def upper(self): | |
37 | return self._upper | |
38 | ||
39 | def contains(self, value): | |
40 | self._check_type(value) | |
41 | return value >= self._lower and value <= self._upper | |
42 | ||
43 | def __eq__(self, other): | |
fc866000 | 44 | if not isinstance(other, _IntegerRangeConst): |
19bb8b5a PP |
45 | return False |
46 | ||
47 | return self.lower == other.lower and self.upper == other.upper | |
48 | ||
49 | ||
fc866000 FD |
50 | class _IntegerRange(_IntegerRangeConst): |
51 | def __init__(self, lower, upper=None): | |
52 | super().__init__(lower, upper) | |
53 | ||
54 | ||
55 | class _SignedIntegerRangeConst(_IntegerRangeConst): | |
e5914347 SM |
56 | _is_type = staticmethod(bt2_utils._is_int64) |
57 | _check_type = staticmethod(bt2_utils._check_int64) | |
19bb8b5a PP |
58 | |
59 | ||
fc866000 FD |
60 | class SignedIntegerRange(_SignedIntegerRangeConst, _IntegerRange): |
61 | pass | |
19bb8b5a PP |
62 | |
63 | ||
fc866000 | 64 | class _UnsignedIntegerRangeConst(_IntegerRangeConst): |
e5914347 SM |
65 | _is_type = staticmethod(bt2_utils._is_uint64) |
66 | _check_type = staticmethod(bt2_utils._check_uint64) | |
19bb8b5a | 67 | |
19bb8b5a | 68 | |
fc866000 FD |
69 | class UnsignedIntegerRange(_UnsignedIntegerRangeConst, _IntegerRange): |
70 | pass | |
19bb8b5a | 71 | |
19bb8b5a | 72 | |
e5914347 | 73 | class _IntegerRangeSetConst(bt2_object._SharedObject, collections.abc.Set): |
19bb8b5a PP |
74 | def __len__(self): |
75 | range_set_ptr = self._as_range_set_ptr(self._ptr) | |
76 | count = native_bt.integer_range_set_get_range_count(range_set_ptr) | |
77 | assert count >= 0 | |
78 | return count | |
79 | ||
80 | def __contains__(self, other_range): | |
81 | for rg in self: | |
82 | if rg == other_range: | |
83 | return True | |
84 | ||
85 | return False | |
86 | ||
87 | def __iter__(self): | |
88 | for idx in range(len(self)): | |
fc866000 | 89 | rg_ptr = self._borrow_range_ptr_by_index(self._ptr, idx) |
19bb8b5a PP |
90 | assert rg_ptr is not None |
91 | lower = self._range_get_lower(rg_ptr) | |
92 | upper = self._range_get_upper(rg_ptr) | |
fc866000 | 93 | yield self._range_pycls(lower, upper) |
19bb8b5a PP |
94 | |
95 | def __eq__(self, other): | |
fc866000 | 96 | if not isinstance(other, _IntegerRangeSetConst): |
19bb8b5a PP |
97 | return False |
98 | ||
cd933d89 | 99 | return self._is_equal(self._ptr, other._ptr) |
19bb8b5a PP |
100 | |
101 | def contains_value(self, value): | |
102 | for rg in self: | |
103 | if rg.contains(value): | |
104 | return True | |
105 | ||
106 | return False | |
107 | ||
fc866000 FD |
108 | |
109 | class _IntegerRangeSet(_IntegerRangeSetConst, collections.abc.MutableSet): | |
110 | def __init__(self, ranges=None): | |
111 | ptr = self._create_range_set() | |
112 | ||
113 | if ptr is None: | |
c345b078 | 114 | raise bt2_error._MemoryError("cannot create range set object") |
fc866000 FD |
115 | |
116 | super().__init__(ptr) | |
117 | ||
118 | if ranges is not None: | |
119 | # will raise if not iterable | |
120 | for rg in ranges: | |
121 | self.add(rg) | |
122 | ||
19bb8b5a | 123 | def add(self, rg): |
fc866000 FD |
124 | if type(rg) is not self._range_pycls: |
125 | if self._range_pycls._is_type(rg): | |
126 | rg = self._range_pycls(rg) | |
7a2a2328 PP |
127 | else: |
128 | # assume it's a simple pair (will raise if it's not) | |
fc866000 | 129 | rg = self._range_pycls(rg[0], rg[1]) |
19bb8b5a PP |
130 | |
131 | status = self._add_range(self._ptr, rg.lower, rg.upper) | |
e5914347 | 132 | bt2_utils._handle_func_status(status, "cannot add range to range set object") |
19bb8b5a PP |
133 | |
134 | def discard(self, rg): | |
135 | raise NotImplementedError | |
136 | ||
137 | ||
fc866000 | 138 | class _SignedIntegerRangeSetConst(_IntegerRangeSetConst): |
9dee90bd SM |
139 | @staticmethod |
140 | def _get_ref(ptr): | |
141 | native_bt.integer_range_set_signed_get_ref(ptr) | |
142 | ||
143 | @staticmethod | |
144 | def _put_ref(ptr): | |
145 | native_bt.integer_range_set_signed_put_ref(ptr) | |
146 | ||
cfbd7cf3 FD |
147 | _as_range_set_ptr = staticmethod( |
148 | native_bt.integer_range_set_signed_as_range_set_const | |
149 | ) | |
fc866000 | 150 | _borrow_range_ptr_by_index = staticmethod( |
cfbd7cf3 FD |
151 | native_bt.integer_range_set_signed_borrow_range_by_index_const |
152 | ) | |
19bb8b5a PP |
153 | _range_get_lower = staticmethod(native_bt.integer_range_signed_get_lower) |
154 | _range_get_upper = staticmethod(native_bt.integer_range_signed_get_upper) | |
cd933d89 | 155 | _is_equal = staticmethod(native_bt.integer_range_set_signed_is_equal) |
fc866000 | 156 | _range_pycls = _SignedIntegerRangeConst |
19bb8b5a PP |
157 | |
158 | ||
fc866000 FD |
159 | class SignedIntegerRangeSet(_SignedIntegerRangeSetConst, _IntegerRangeSet): |
160 | _create_range_set = staticmethod(native_bt.integer_range_set_signed_create) | |
161 | _add_range = staticmethod(native_bt.integer_range_set_signed_add_range) | |
162 | _range_pycls = SignedIntegerRange | |
163 | ||
164 | ||
165 | class _UnsignedIntegerRangeSetConst(_IntegerRangeSetConst): | |
9dee90bd SM |
166 | @staticmethod |
167 | def _get_ref(ptr): | |
168 | native_bt.integer_range_set_unsigned_get_ref(ptr) | |
169 | ||
170 | @staticmethod | |
171 | def _put_ref(ptr): | |
172 | native_bt.integer_range_set_unsigned_put_ref(ptr) | |
173 | ||
cfbd7cf3 FD |
174 | _as_range_set_ptr = staticmethod( |
175 | native_bt.integer_range_set_unsigned_as_range_set_const | |
176 | ) | |
fc866000 | 177 | _borrow_range_ptr_by_index = staticmethod( |
cfbd7cf3 FD |
178 | native_bt.integer_range_set_unsigned_borrow_range_by_index_const |
179 | ) | |
19bb8b5a PP |
180 | _range_get_lower = staticmethod(native_bt.integer_range_unsigned_get_lower) |
181 | _range_get_upper = staticmethod(native_bt.integer_range_unsigned_get_upper) | |
cd933d89 | 182 | _is_equal = staticmethod(native_bt.integer_range_set_unsigned_is_equal) |
fc866000 FD |
183 | _range_pycls = _UnsignedIntegerRangeConst |
184 | ||
185 | ||
186 | class UnsignedIntegerRangeSet(_UnsignedIntegerRangeSetConst, _IntegerRangeSet): | |
187 | _create_range_set = staticmethod(native_bt.integer_range_set_unsigned_create) | |
188 | _add_range = staticmethod(native_bt.integer_range_set_unsigned_add_range) | |
189 | _range_pycls = UnsignedIntegerRange |