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