Python: writer.IntegerBase: remove redundant prefixes
[babeltrace.git] / bindings / python / writer.py
CommitLineData
be5a4e67
PP
1# writer.py
2#
3# Babeltrace writer interface Python module
4#
5# Copyright 2012-2015 EfficiOS Inc.
6#
7# Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
8#
9# Permission is hereby granted, free of charge, to any person obtaining a copy
10# of this software and associated documentation files (the "Software"), to deal
11# in the Software without restriction, including without limitation the rights
12# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13# copies of the Software, and to permit persons to whom the Software is
14# furnished to do so, subject to the following conditions:
15#
16# The above copyright notice and this permission notice shall be included in
17# all copies or substantial portions of the Software.
18#
19# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25# SOFTWARE.
26
27import babeltrace.nativebt as nbt
28import babeltrace.common as common
29from uuid import UUID
30
31
32# Used to compare to -1ULL in error checks
33_MAX_UINT64 = 0xFFFFFFFFFFFFFFFF
34
35
36class EnumerationMapping:
37 """
1759e132 38 Mapping from an enumeration label to a range of integers.
be5a4e67
PP
39 """
40
41 def __init__(self, name, start, end):
1759e132
PP
42 """
43 Creates an enumeration mapping, where label *name* is mapped to
44 the [*start*, *end*] range of integers (*end* is included).
45
46 Set *start* and *end* to the same value to create an enumeration
47 mapping to a single value.
48 """
49
be5a4e67
PP
50 self.name = name
51 self.start = start
52 self.end = end
53
54
55class Clock:
4d7ac86a
PP
56 """
57 A CTF clock allows the description of the system's clock topology, as
58 well as the definition of each clock's parameters.
59
60 :class:`Clock` objects must be registered to a :class:`Writer`
61 object (see :meth:`Writer.add_clock`), as well as be registered to
62 a :class:`StreamClass` object (see :attr:`StreamClass.clock`).
63 """
64
be5a4e67 65 def __init__(self, name):
4d7ac86a
PP
66 """
67 Creates a default CTF clock named *name*.
68
69 :exc:`ValueError` is raised on error.
70 """
71
be5a4e67
PP
72 self._c = nbt._bt_ctf_clock_create(name)
73
74 if self._c is None:
75 raise ValueError("Invalid clock name.")
76
77 def __del__(self):
78 nbt._bt_ctf_clock_put(self._c)
79
80 @property
81 def name(self):
82 """
4d7ac86a
PP
83 Clock name.
84
85 Set this attribute to change the clock's name.
86
87 :exc:`ValueError` is raised on error.
be5a4e67
PP
88 """
89
90 name = nbt._bt_ctf_clock_get_name(self._c)
91
92 if name is None:
93 raise ValueError("Invalid clock instance.")
94
95 return name
96
97 @property
98 def description(self):
99 """
4d7ac86a
PP
100 Clock description (string).
101
102 Set this attribute to change the clock's description.
103
104 :exc:`ValueError` is raised on error.
be5a4e67
PP
105 """
106
107 return nbt._bt_ctf_clock_get_description(self._c)
108
109 @description.setter
110 def description(self, desc):
be5a4e67
PP
111 ret = nbt._bt_ctf_clock_set_description(self._c, str(desc))
112
113 if ret < 0:
114 raise ValueError("Invalid clock description.")
115
116 @property
117 def frequency(self):
118 """
4d7ac86a
PP
119 Clock frequency in Hz (integer).
120
121 Set this attribute to change the clock's frequency.
122
123 :exc:`ValueError` is raised on error.
be5a4e67
PP
124 """
125
126 freq = nbt._bt_ctf_clock_get_frequency(self._c)
127
128 if freq == _MAX_UINT64:
129 raise ValueError("Invalid clock instance")
130
131 return freq
132
133 @frequency.setter
134 def frequency(self, freq):
be5a4e67
PP
135 ret = nbt._bt_ctf_clock_set_frequency(self._c, freq)
136
137 if ret < 0:
138 raise ValueError("Invalid frequency value.")
139
140 @property
141 def precision(self):
142 """
4d7ac86a
PP
143 Clock precision in clock ticks (integer).
144
145 Set this attribute to change the clock's precision.
146
147 :exc:`ValueError` is raised on error.
be5a4e67
PP
148 """
149
150 precision = nbt._bt_ctf_clock_get_precision(self._c)
151
152 if precision == _MAX_UINT64:
153 raise ValueError("Invalid clock instance")
154
155 return precision
156
157 @precision.setter
158 def precision(self, precision):
be5a4e67
PP
159 ret = nbt._bt_ctf_clock_set_precision(self._c, precision)
160
161 @property
162 def offset_seconds(self):
163 """
4d7ac86a
PP
164 Clock offset in seconds since POSIX.1 Epoch (integer).
165
166 Set this attribute to change the clock's offset in seconds.
167
168 :exc:`ValueError` is raised on error.
be5a4e67
PP
169 """
170
171 offset_s = nbt._bt_ctf_clock_get_offset_s(self._c)
172
173 if offset_s == _MAX_UINT64:
174 raise ValueError("Invalid clock instance")
175
176 return offset_s
177
178 @offset_seconds.setter
179 def offset_seconds(self, offset_s):
be5a4e67
PP
180 ret = nbt._bt_ctf_clock_set_offset_s(self._c, offset_s)
181
182 if ret < 0:
183 raise ValueError("Invalid offset value.")
184
185 @property
186 def offset(self):
187 """
4d7ac86a
PP
188 Clock offset in ticks since (POSIX.1 Epoch +
189 :attr:`offset_seconds`).
190
191 Set this attribute to change the clock's offset.
192
193 :exc:`ValueError` is raised on error.
be5a4e67
PP
194 """
195
196 offset = nbt._bt_ctf_clock_get_offset(self._c)
197
198 if offset == _MAX_UINT64:
199 raise ValueError("Invalid clock instance")
200
201 return offset
202
203 @offset.setter
204 def offset(self, offset):
be5a4e67
PP
205 ret = nbt._bt_ctf_clock_set_offset(self._c, offset)
206
207 if ret < 0:
208 raise ValueError("Invalid offset value.")
209
210 @property
211 def absolute(self):
212 """
4d7ac86a
PP
213 ``True`` if this clock is absolute, i.e. if the clock is a
214 global reference across the other clocks of the trace.
215
216 Set this attribute to change the clock's absolute state
217 (boolean).
218
219 :exc:`ValueError` is raised on error.
be5a4e67
PP
220 """
221
222 is_absolute = nbt._bt_ctf_clock_get_is_absolute(self._c)
223
224 if is_absolute == -1:
225 raise ValueError("Invalid clock instance")
226
227 return False if is_absolute == 0 else True
228
229 @absolute.setter
230 def absolute(self, is_absolute):
be5a4e67
PP
231 ret = nbt._bt_ctf_clock_set_is_absolute(self._c, int(is_absolute))
232
233 if ret < 0:
4d7ac86a 234 raise ValueError("Could not set the clock absolute attribute.")
be5a4e67
PP
235
236 @property
237 def uuid(self):
238 """
4d7ac86a
PP
239 Clock UUID (an :class:`uuid.UUID` object).
240
241 Set this attribute to change the clock's UUID.
242
243 :exc:`ValueError` is raised on error.
be5a4e67
PP
244 """
245
246 uuid_list = []
247
248 for i in range(16):
249 ret, value = nbt._bt_python_ctf_clock_get_uuid_index(self._c, i)
250
251 if ret < 0:
252 raise ValueError("Invalid clock instance")
253
254 uuid_list.append(value)
255
256 return UUID(bytes=bytes(uuid_list))
257
258 @uuid.setter
259 def uuid(self, uuid):
be5a4e67
PP
260 uuid_bytes = uuid.bytes
261
262 if len(uuid_bytes) != 16:
263 raise ValueError("Invalid UUID provided. UUID length must be 16 bytes")
264
265 for i in range(len(uuid_bytes)):
266 ret = nbt._bt_python_ctf_clock_set_uuid_index(self._c, i,
267 uuid_bytes[i])
268
269 if ret < 0:
270 raise ValueError("Invalid clock instance")
271
272 @property
273 def time(self):
274 """
4d7ac86a
PP
275 Clock current time; nanoseconds (integer) since clock origin
276 (POSIX.1 Epoch + :attr:`offset_seconds` + :attr:`offset`).
277
278 Set this attribute to change the clock's current time.
279
280 :exc:`ValueError` is raised on error.
be5a4e67
PP
281 """
282
283 time = nbt._bt_ctf_clock_get_time(self._c)
284
285 if time == _MAX_UINT64:
286 raise ValueError("Invalid clock instance")
287
288 return time
289
290 @time.setter
291 def time(self, time):
be5a4e67
PP
292 ret = nbt._bt_ctf_clock_set_time(self._c, time)
293
294 if ret < 0:
295 raise ValueError("Invalid time value.")
296
297
fe9f5df1
PP
298class IntegerBase:
299 """
300 Display base of an integer.
301 """
302
303 #: Unknown
b3df7a8f 304 UNKNOWN = -1
fe9f5df1
PP
305
306 #: Binary
b3df7a8f 307 BIN = 2
fe9f5df1
PP
308
309 #: Octal
b3df7a8f 310 OCT = 8
fe9f5df1
PP
311
312 #: Decimal
b3df7a8f 313 DEC = 10
fe9f5df1
PP
314
315 #: Hexadecimal
b3df7a8f
PP
316 HEX = 16
317
318 # keep this for backward compatibility
319 INTEGER_BASE_UNKNOWN = -1
320 INTEGER_BASE_BINARY = 2
321 INTEGER_BASE_OCTAL = 8
322 INTEGER_BASE_DECIMAL = 10
fe9f5df1
PP
323 INTEGER_BASE_HEXADECIMAL = 16
324
325
be5a4e67
PP
326class FieldDeclaration:
327 """
a20c2934
PP
328 Base class of all field declarations. This class is not meant to
329 be instantiated by the user; use one of the concrete field
330 declaration subclasses instead.
be5a4e67
PP
331 """
332
fe9f5df1
PP
333 class IntegerBase(IntegerBase):
334 pass
be5a4e67
PP
335
336 def __init__(self):
337 if self._ft is None:
338 raise ValueError("FieldDeclaration creation failed.")
339
340 def __del__(self):
341 nbt._bt_ctf_field_type_put(self._ft)
342
343 @staticmethod
344 def _create_field_declaration_from_native_instance(
345 native_field_declaration):
346 type_dict = {
347 common.CTFTypeId.INTEGER: IntegerFieldDeclaration,
348 common.CTFTypeId.FLOAT: FloatFieldDeclaration,
349 common.CTFTypeId.ENUM: EnumerationFieldDeclaration,
350 common.CTFTypeId.STRING: StringFieldDeclaration,
351 common.CTFTypeId.STRUCT: StructureFieldDeclaration,
352 common.CTFTypeId.VARIANT: VariantFieldDeclaration,
353 common.CTFTypeId.ARRAY: ArrayFieldDeclaration,
354 common.CTFTypeId.SEQUENCE: SequenceFieldDeclaration
355 }
356
357 field_type_id = nbt._bt_ctf_field_type_get_type_id(native_field_declaration)
358
359 if field_type_id == common.CTFTypeId.UNKNOWN:
360 raise TypeError("Invalid field instance")
361
362 declaration = Field.__new__(Field)
363 declaration._ft = native_field_declaration
364 declaration.__class__ = type_dict[field_type_id]
365
366 return declaration
367
368 @property
369 def alignment(self):
370 """
a20c2934
PP
371 Field alignment in bits (integer).
372
373 Set this attribute to change this field's alignment.
374
375 :exc:`ValueError` is raised on error.
be5a4e67
PP
376 """
377
378 return nbt._bt_ctf_field_type_get_alignment(self._ft)
379
380 @alignment.setter
381 def alignment(self, alignment):
be5a4e67
PP
382 ret = nbt._bt_ctf_field_type_set_alignment(self._ft, alignment)
383
384 if ret < 0:
385 raise ValueError("Invalid alignment value.")
386
387 @property
388 def byte_order(self):
389 """
a20c2934
PP
390 Field byte order (one of :class:`babeltrace.common.ByteOrder`
391 constants).
392
393 Set this attribute to change this field's byte order.
394
395 :exc:`ValueError` is raised on error.
be5a4e67
PP
396 """
397
398 return nbt._bt_ctf_field_type_get_byte_order(self._ft)
399
400 @byte_order.setter
401 def byte_order(self, byte_order):
be5a4e67
PP
402 ret = nbt._bt_ctf_field_type_set_byte_order(self._ft, byte_order)
403
404 if ret < 0:
405 raise ValueError("Could not set byte order value.")
406
407
408class IntegerFieldDeclaration(FieldDeclaration):
7d06a31a
PP
409 """
410 Integer field declaration.
411 """
412
be5a4e67
PP
413 def __init__(self, size):
414 """
7d06a31a
PP
415 Creates an integer field declaration of size *size* bits.
416
417 :exc:`ValueError` is raised on error.
be5a4e67 418 """
7d06a31a 419
be5a4e67
PP
420 self._ft = nbt._bt_ctf_field_type_integer_create(size)
421 super().__init__()
422
423 @property
424 def size(self):
425 """
7d06a31a
PP
426 Integer size in bits (integer).
427
428 Set this attribute to change this integer's size.
429
430 :exc:`ValueError` is raised on error.
be5a4e67
PP
431 """
432
433 ret = nbt._bt_ctf_field_type_integer_get_size(self._ft)
434
435 if ret < 0:
7d06a31a 436 raise ValueError("Could not get Integer size attribute.")
be5a4e67
PP
437 else:
438 return ret
439
440 @property
441 def signed(self):
442 """
7d06a31a
PP
443 ``True`` if this integer is signed.
444
445 Set this attribute to change this integer's signedness
446 (boolean).
447
448 :exc:`ValueError` is raised on error.
be5a4e67
PP
449 """
450
451 ret = nbt._bt_ctf_field_type_integer_get_signed(self._ft)
452
453 if ret < 0:
7d06a31a 454 raise ValueError("Could not get Integer signed attribute.")
be5a4e67
PP
455 elif ret > 0:
456 return True
457 else:
458 return False
459
460 @signed.setter
461 def signed(self, signed):
be5a4e67
PP
462 ret = nbt._bt_ctf_field_type_integer_set_signed(self._ft, signed)
463
464 if ret < 0:
7d06a31a 465 raise ValueError("Could not set Integer signed attribute.")
be5a4e67
PP
466
467 @property
468 def base(self):
469 """
7d06a31a
PP
470 Integer display base (one of :class:`IntegerBase` constants).
471
472 Set this attribute to change this integer's display base.
473
474 :exc:`ValueError` is raised on error.
be5a4e67
PP
475 """
476
477 return nbt._bt_ctf_field_type_integer_get_base(self._ft)
478
479 @base.setter
480 def base(self, base):
be5a4e67
PP
481 ret = nbt._bt_ctf_field_type_integer_set_base(self._ft, base)
482
483 if ret < 0:
7d06a31a 484 raise ValueError("Could not set Integer base.")
be5a4e67
PP
485
486 @property
487 def encoding(self):
488 """
7d06a31a
PP
489 Integer encoding (one of
490 :class:`babeltrace.common.CTFStringEncoding` constants).
491
492 Set this attribute to change this integer's encoding.
493
494 :exc:`ValueError` is raised on error.
be5a4e67
PP
495 """
496
497 return nbt._bt_ctf_field_type_integer_get_encoding(self._ft)
498
499 @encoding.setter
500 def encoding(self, encoding):
be5a4e67
PP
501 ret = nbt._bt_ctf_field_type_integer_set_encoding(self._ft, encoding)
502
503 if ret < 0:
7d06a31a 504 raise ValueError("Could not set Integer encoding.")
be5a4e67
PP
505
506
507class EnumerationFieldDeclaration(FieldDeclaration):
6d4014ed
PP
508 """
509 Enumeration field declaration. A CTF enumeration maps labels to
510 ranges of integers.
511 """
512
be5a4e67
PP
513 def __init__(self, integer_type):
514 """
6d4014ed
PP
515 Creates an enumeration field declaration, with *integer_type*
516 being the underlying :class:`IntegerFieldDeclaration` for storing
517 the integer.
518
519 :exc:`ValueError` is raised on error.
be5a4e67 520 """
6d4014ed 521
be5a4e67
PP
522 isinst = isinstance(integer_type, IntegerFieldDeclaration)
523
524 if integer_type is None or not isinst:
525 raise TypeError("Invalid integer container.")
526
527 self._ft = nbt._bt_ctf_field_type_enumeration_create(integer_type._ft)
528 super().__init__()
529
530 @property
531 def container(self):
532 """
6d4014ed
PP
533 Underlying container (:class:`IntegerFieldDeclaration`).
534
535 :exc:`TypeError` is raised on error.
be5a4e67
PP
536 """
537
538 ret = nbt._bt_ctf_field_type_enumeration_get_container_type(self._ft)
539
540 if ret is None:
541 raise TypeError("Invalid enumeration declaration")
542
543 return FieldDeclaration._create_field_declaration_from_native_instance(ret)
544
545 def add_mapping(self, name, range_start, range_end):
546 """
6d4014ed
PP
547 Adds a mapping to the enumeration field declaration, from the
548 label named *name* to range [*range_start*, *range_end*], where
549 *range_start* and *range_end* are integers included in the
550 range.
551
552 :exc:`ValueError` is raised on error.
be5a4e67
PP
553 """
554
555 if range_start < 0 or range_end < 0:
556 ret = nbt._bt_ctf_field_type_enumeration_add_mapping(self._ft,
557 str(name),
558 range_start,
559 range_end)
560 else:
561 ret = nbt._bt_ctf_field_type_enumeration_add_mapping_unsigned(self._ft,
562 str(name),
563 range_start,
564 range_end)
565
566 if ret < 0:
567 raise ValueError("Could not add mapping to enumeration declaration.")
568
569 @property
570 def mappings(self):
571 """
6d4014ed
PP
572 Generates the mappings of this enumeration field declaration
573 (:class:`EnumerationMapping` objects).
574
575 :exc:`TypeError` is raised on error.
be5a4e67
PP
576 """
577
578 signed = self.container.signed
579
580 count = nbt._bt_ctf_field_type_enumeration_get_mapping_count(self._ft)
581
582 for i in range(count):
583 if signed:
584 ret = nbt._bt_python_ctf_field_type_enumeration_get_mapping(self._ft, i)
585 else:
586 ret = nbt._bt_python_ctf_field_type_enumeration_get_mapping_unsigned(self._ft, i)
587
588 if len(ret) != 3:
589 msg = "Could not get Enumeration mapping at index {}".format(i)
590 raise TypeError(msg)
591
592 name, range_start, range_end = ret
593 yield EnumerationMapping(name, range_start, range_end)
594
595 def get_mapping_by_name(self, name):
596 """
6d4014ed
PP
597 Returns the :class:`EnumerationMapping` object for the label
598 named *name*.
599
600 :exc:`TypeError` is raised on error.
be5a4e67
PP
601 """
602
603 index = nbt._bt_ctf_field_type_enumeration_get_mapping_index_by_name(self._ft, name)
604
605 if index < 0:
606 return None
607
608 if self.container.signed:
609 ret = nbt._bt_python_ctf_field_type_enumeration_get_mapping(self._ft, index)
610 else:
611 ret = nbt._bt_python_ctf_field_type_enumeration_get_mapping_unsigned(self._ft, index)
612
613 if len(ret) != 3:
614 msg = "Could not get Enumeration mapping at index {}".format(i)
615 raise TypeError(msg)
616
617 name, range_start, range_end = ret
618
619 return EnumerationMapping(name, range_start, range_end)
620
621 def get_mapping_by_value(self, value):
622 """
6d4014ed
PP
623 Returns the :class:`EnumerationMapping` object for the value
624 *value* (integer).
625
626 :exc:`TypeError` is raised on error.
be5a4e67
PP
627 """
628
629 if value < 0:
630 index = nbt._bt_ctf_field_type_enumeration_get_mapping_index_by_value(self._ft, value)
631 else:
632 index = nbt._bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value(self._ft, value)
633
634 if index < 0:
635 return None
636
637 if self.container.signed:
638 ret = nbt._bt_python_ctf_field_type_enumeration_get_mapping(self._ft, index)
639 else:
640 ret = nbt._bt_python_ctf_field_type_enumeration_get_mapping_unsigned(self._ft, index)
641
642 if len(ret) != 3:
643 msg = "Could not get Enumeration mapping at index {}".format(i)
644 raise TypeError(msg)
645
646 name, range_start, range_end = ret
647
648 return EnumerationMapping(name, range_start, range_end)
649
650
a777c99f
PP
651class FloatingPointFieldDeclaration(FieldDeclaration):
652 """
653 Floating point number field declaration.
654
655 A CTF floating point number is a made of three sections: the sign
656 bit, the exponent bits, and the mantissa bits. The most significant
657 bit of the resulting binary word is the sign bit, and is included
658 in the number of mantissa bits.
659
660 For example, the
661 `IEEE 754 <http://en.wikipedia.org/wiki/IEEE_floating_point>`_
662 single precision floating point number is represented on a 32-bit
663 word using an 8-bit exponent (``e``) and a 24-bit mantissa (``m``),
664 the latter count including the sign bit (``s``)::
665
666 s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm
667
668 The IEEE 754 double precision floating point number uses an
669 11-bit exponent and a 53-bit mantissa.
670 """
671
672 #: IEEE 754 single precision floating point number exponent size
be5a4e67 673 FLT_EXP_DIG = 8
a777c99f
PP
674
675 #: IEEE 754 double precision floating point number exponent size
be5a4e67 676 DBL_EXP_DIG = 11
a777c99f
PP
677
678 #: IEEE 754 single precision floating point number mantissa size
be5a4e67 679 FLT_MANT_DIG = 24
a777c99f
PP
680
681 #: IEEE 754 double precision floating point number mantissa size
be5a4e67
PP
682 DBL_MANT_DIG = 53
683
684 def __init__(self):
685 """
a777c99f
PP
686 Creates a floating point number field declaration.
687
688 :exc:`ValueError` is raised on error.
be5a4e67
PP
689 """
690
691 self._ft = nbt._bt_ctf_field_type_floating_point_create()
692 super().__init__()
693
694 @property
695 def exponent_digits(self):
696 """
a777c99f
PP
697 Floating point number exponent section size in bits (integer).
698
699 Set this attribute to change the floating point number's
700 exponent section's size. You may use :attr:`FLT_EXP_DIG` or
701 :attr:`DBL_EXP_DIG` for IEEE 754 floating point numbers.
702
703 :exc:`ValueError` is raised on error.
be5a4e67
PP
704 """
705
706 ret = nbt._bt_ctf_field_type_floating_point_get_exponent_digits(self._ft)
707
708 if ret < 0:
709 raise TypeError(
710 "Could not get Floating point exponent digit count")
711
712 return ret
713
714 @exponent_digits.setter
715 def exponent_digits(self, exponent_digits):
be5a4e67
PP
716 ret = nbt._bt_ctf_field_type_floating_point_set_exponent_digits(self._ft,
717 exponent_digits)
718
719 if ret < 0:
720 raise ValueError("Could not set exponent digit count.")
721
722 @property
723 def mantissa_digits(self):
724 """
a777c99f
PP
725 Floating point number mantissa section size in bits (integer).
726
727 Set this attribute to change the floating point number's
728 mantissa section's size. You may use :attr:`FLT_MANT_DIG` or
729 :attr:`DBL_MANT_DIG` for IEEE 754 floating point numbers.
730
731 :exc:`ValueError` is raised on error.
be5a4e67
PP
732 """
733
734 ret = nbt._bt_ctf_field_type_floating_point_get_mantissa_digits(self._ft)
735
736 if ret < 0:
737 raise TypeError("Could not get Floating point mantissa digit count")
738
739 return ret
740
741 @mantissa_digits.setter
742 def mantissa_digits(self, mantissa_digits):
be5a4e67
PP
743 ret = nbt._bt_ctf_field_type_floating_point_set_mantissa_digits(self._ft,
744 mantissa_digits)
745
746 if ret < 0:
747 raise ValueError("Could not set mantissa digit count.")
748
749
a777c99f 750class FloatFieldDeclaration(FloatingPointFieldDeclaration):
be5a4e67
PP
751 pass
752
753
754class StructureFieldDeclaration(FieldDeclaration):
18449dbf
PP
755 """
756 Structure field declaration, i.e. an ordered mapping from field
757 names to field declarations.
758 """
759
be5a4e67
PP
760 def __init__(self):
761 """
18449dbf
PP
762 Creates an empty structure field declaration.
763
764 :exc:`ValueError` is raised on error.
be5a4e67
PP
765 """
766
767 self._ft = nbt._bt_ctf_field_type_structure_create()
768 super().__init__()
769
770 def add_field(self, field_type, field_name):
771 """
18449dbf
PP
772 Appends one :class:`FieldDeclaration` *field_type* named
773 *field_name* to the structure's ordered map.
774
775 :exc:`ValueError` is raised on error.
be5a4e67
PP
776 """
777
778 ret = nbt._bt_ctf_field_type_structure_add_field(self._ft,
779 field_type._ft,
780 str(field_name))
781
782 if ret < 0:
783 raise ValueError("Could not add field to structure.")
784
785 @property
786 def fields(self):
787 """
18449dbf
PP
788 Generates the (field name, :class:`FieldDeclaration`) pairs
789 of this structure.
790
791 :exc:`TypeError` is raised on error.
be5a4e67
PP
792 """
793
794 count = nbt._bt_ctf_field_type_structure_get_field_count(self._ft)
795
796 if count < 0:
797 raise TypeError("Could not get Structure field count")
798
799 for i in range(count):
800 field_name = nbt._bt_python_ctf_field_type_structure_get_field_name(self._ft, i)
801
802 if field_name is None:
803 msg = "Could not get Structure field name at index {}".format(i)
804 raise TypeError(msg)
805
806 field_type_native = nbt._bt_python_ctf_field_type_structure_get_field_type(self._ft, i)
807
808 if field_type_native is None:
809 msg = "Could not get Structure field type at index {}".format(i)
810 raise TypeError(msg)
811
812 field_type = FieldDeclaration._create_field_declaration_from_native_instance(field_type_native)
813 yield (field_name, field_type)
814
815 def get_field_by_name(self, name):
816 """
18449dbf
PP
817 Returns the :class:`FieldDeclaration` mapped to the field name
818 *name* in this structure.
819
820 :exc:`TypeError` is raised on error.
be5a4e67
PP
821 """
822
823 field_type_native = nbt._bt_ctf_field_type_structure_get_field_type_by_name(self._ft, name)
824
825 if field_type_native is None:
826 msg = "Could not find Structure field with name {}".format(name)
827 raise TypeError(msg)
828
829 return FieldDeclaration._create_field_declaration_from_native_instance(field_type_native)
830
831
832class VariantFieldDeclaration(FieldDeclaration):
62d7eb34
PP
833 """
834 Variant field declaration.
835
836 A CTF variant is a dynamic selection between different fields.
837 The value of a *tag* (a CTF enumeration) determines what is the
838 current selected field. All the possible fields must be added to
839 its field declaration before using an actual variant field.
840 """
841
be5a4e67
PP
842 def __init__(self, enum_tag, tag_name):
843 """
62d7eb34
PP
844 Creates an empty variant field declaration with tag field
845 declaration *enum_tag* (instance of
846 :class:`EnumerationFieldDeclaration`) named *tag_name*
847 (string).
848
849 :exc:`ValueError` is raised on error.
be5a4e67
PP
850 """
851
852 isinst = isinstance(enum_tag, EnumerationFieldDeclaration)
853 if enum_tag is None or not isinst:
854 raise TypeError("Invalid tag type; must be of type EnumerationFieldDeclaration.")
855
856 self._ft = nbt._bt_ctf_field_type_variant_create(enum_tag._ft,
857 str(tag_name))
858 super().__init__()
859
860 @property
861 def tag_name(self):
862 """
62d7eb34
PP
863 Variant field declaration tag name.
864
865 :exc:`TypeError` is raised on error.
be5a4e67
PP
866 """
867
868 ret = nbt._bt_ctf_field_type_variant_get_tag_name(self._ft)
869
870 if ret is None:
871 raise TypeError("Could not get Variant tag name")
872
873 return ret
874
875 @property
876 def tag_type(self):
877 """
62d7eb34
PP
878 Variant field declaration tag field declaration
879 (:class:`EnumerationFieldDeclaration` object).
880
881 :exc:`TypeError` is raised on error.
be5a4e67
PP
882 """
883
884 ret = nbt._bt_ctf_field_type_variant_get_tag_type(self._ft)
885
886 if ret is None:
887 raise TypeError("Could not get Variant tag type")
888
889 return FieldDeclaration._create_field_declaration_from_native_instance(ret)
890
891 def add_field(self, field_type, field_name):
892 """
62d7eb34
PP
893 Registers the :class:`FieldDeclaration` object *field_type*
894 as the variant's selected type when the variant's tag's current
895 label is *field_name*.
896
897 :exc:`ValueError` is raised on error.
be5a4e67
PP
898 """
899
900 ret = nbt._bt_ctf_field_type_variant_add_field(self._ft,
901 field_type._ft,
902 str(field_name))
903
904 if ret < 0:
905 raise ValueError("Could not add field to variant.")
906
907 @property
908 def fields(self):
909 """
62d7eb34
PP
910 Generates the (field name, :class:`FieldDeclaration`) pairs
911 of this variant field declaration.
912
913 :exc:`TypeError` is raised on error.
be5a4e67
PP
914 """
915
916 count = nbt._bt_ctf_field_type_variant_get_field_count(self._ft)
917
918 if count < 0:
919 raise TypeError("Could not get Variant field count")
920
921 for i in range(count):
922 field_name = nbt._bt_python_ctf_field_type_variant_get_field_name(self._ft, i)
923
924 if field_name is None:
925 msg = "Could not get Variant field name at index {}".format(i)
926 raise TypeError(msg)
927
928 field_type_native = nbt._bt_python_ctf_field_type_variant_get_field_type(self._ft, i)
929
930 if field_type_native is None:
931 msg = "Could not get Variant field type at index {}".format(i)
932 raise TypeError(msg)
933
934 field_type = FieldDeclaration._create_field_declaration_from_native_instance(field_type_native)
935 yield (field_name, field_type)
936
937 def get_field_by_name(self, name):
938 """
62d7eb34
PP
939 Returns the :class:`FieldDeclaration` selected when the
940 variant's tag's current label is *name*.
941
942 :exc:`TypeError` is raised on error.
be5a4e67
PP
943 """
944
945 field_type_native = nbt._bt_ctf_field_type_variant_get_field_type_by_name(self._ft,
946 name)
947
948 if field_type_native is None:
949 msg = "Could not find Variant field with name {}".format(name)
950 raise TypeError(msg)
951
952 return FieldDeclaration._create_field_declaration_from_native_instance(field_type_native)
953
954 def get_field_from_tag(self, tag):
955 """
62d7eb34
PP
956 Returns the :class:`FieldDeclaration` selected by the current
957 label of the :class:`EnumerationField` *tag*.
958
959 :exc:`TypeError` is raised on error.
be5a4e67
PP
960 """
961
962 field_type_native = nbt._bt_ctf_field_type_variant_get_field_type_from_tag(self._ft, tag._f)
963
964 if field_type_native is None:
965 msg = "Could not find Variant field with tag value {}".format(tag.value)
966 raise TypeError(msg)
967
968 return FieldDeclaration._create_field_declaration_from_native_instance(field_type_native)
969
970
971class ArrayFieldDeclaration(FieldDeclaration):
ee77cc15
PP
972 """
973 Static array field declaration.
974 """
975
be5a4e67
PP
976 def __init__(self, element_type, length):
977 """
ee77cc15
PP
978 Creates a static array field declaration of *length*
979 elements of type *element_type* (:class:`FieldDeclaration`).
980
981 :exc:`ValueError` is raised on error.
be5a4e67
PP
982 """
983
984 self._ft = nbt._bt_ctf_field_type_array_create(element_type._ft,
985 length)
986 super().__init__()
987
988 @property
989 def element_type(self):
990 """
ee77cc15
PP
991 Type of the elements of this this static array (subclass of
992 :class:`FieldDeclaration`).
993
994 :exc:`TypeError` is raised on error.
be5a4e67
PP
995 """
996
997 ret = nbt._bt_ctf_field_type_array_get_element_type(self._ft)
998
999 if ret is None:
1000 raise TypeError("Could not get Array element type")
1001
1002 return FieldDeclaration._create_field_declaration_from_native_instance(ret)
1003
1004 @property
1005 def length(self):
1006 """
ee77cc15
PP
1007 Length of this static array (integer).
1008
1009 :exc:`TypeError` is raised on error.
be5a4e67
PP
1010 """
1011
1012 ret = nbt._bt_ctf_field_type_array_get_length(self._ft)
1013
1014 if ret < 0:
1015 raise TypeError("Could not get Array length")
1016
1017 return ret
1018
1019
1020class SequenceFieldDeclaration(FieldDeclaration):
28ada968
PP
1021 """
1022 Sequence (dynamic array) field declaration.
1023 """
1024
be5a4e67
PP
1025 def __init__(self, element_type, length_field_name):
1026 """
28ada968
PP
1027 Creates a sequence field declaration of
1028 elements of type *element_type* (:class:`FieldDeclaration`).
1029 The length of a sequence field based on this sequence field
1030 declaration is obtained by retrieving the dynamic integer
1031 value of the field named *length_field_name*.
1032
1033 :exc:`ValueError` is raised on error.
be5a4e67
PP
1034 """
1035
1036 self._ft = nbt._bt_ctf_field_type_sequence_create(element_type._ft,
1037 str(length_field_name))
1038 super().__init__()
1039
1040 @property
1041 def element_type(self):
1042 """
28ada968
PP
1043 Type of the elements of this sequence (subclass of
1044 :class:`FieldDeclaration`).
1045
1046 :exc:`TypeError` is raised on error.
be5a4e67
PP
1047 """
1048
1049 ret = nbt._bt_ctf_field_type_sequence_get_element_type(self._ft)
1050
1051 if ret is None:
1052 raise TypeError("Could not get Sequence element type")
1053
1054 return FieldDeclaration._create_field_declaration_from_native_instance(ret)
1055
1056 @property
1057 def length_field_name(self):
1058 """
28ada968
PP
1059 Name of the integer field defining the dynamic length of
1060 sequence fields based on this sequence field declaration.
1061
1062 :exc:`TypeError` is raised on error.
be5a4e67
PP
1063 """
1064
1065 ret = nbt._bt_ctf_field_type_sequence_get_length_field_name(self._ft)
1066
1067 if ret is None:
1068 raise TypeError("Could not get Sequence length field name")
1069
1070 return ret
1071
1072
1073class StringFieldDeclaration(FieldDeclaration):
0a1148a9
PP
1074 """
1075 String (NULL-terminated array of bytes) field declaration.
1076 """
1077
be5a4e67
PP
1078 def __init__(self):
1079 """
0a1148a9
PP
1080 Creates a string field declaration.
1081
1082 :exc:`ValueError` is raised on error.
be5a4e67
PP
1083 """
1084
1085 self._ft = nbt._bt_ctf_field_type_string_create()
1086 super().__init__()
1087
1088 @property
1089 def encoding(self):
1090 """
0a1148a9
PP
1091 String encoding (one of
1092 :class:`babeltrace.common.CTFStringEncoding` constants).
1093
1094 Set this attribute to change this string's encoding.
1095
1096 :exc:`ValueError` is raised on error.
be5a4e67
PP
1097 """
1098
1099 return nbt._bt_ctf_field_type_string_get_encoding(self._ft)
1100
1101 @encoding.setter
1102 def encoding(self, encoding):
be5a4e67
PP
1103 ret = nbt._bt_ctf_field_type_string_set_encoding(self._ft, encoding)
1104 if ret < 0:
1105 raise ValueError("Could not set string encoding.")
1106
1107
1108@staticmethod
1109def create_field(field_type):
1110 """
1111 Create an instance of a field.
1112 """
1113 isinst = isinstance(field_type, FieldDeclaration)
1114
1115 if field_type is None or not isinst:
1116 raise TypeError("Invalid field_type. Type must be a FieldDeclaration-derived class.")
1117
1118 if isinstance(field_type, IntegerFieldDeclaration):
1119 return IntegerField(field_type)
1120 elif isinstance(field_type, EnumerationFieldDeclaration):
1121 return EnumerationField(field_type)
1122 elif isinstance(field_type, FloatFieldDeclaration):
1123 return FloatingPointField(field_type)
1124 elif isinstance(field_type, StructureFieldDeclaration):
1125 return StructureField(field_type)
1126 elif isinstance(field_type, VariantFieldDeclaration):
1127 return VariantField(field_type)
1128 elif isinstance(field_type, ArrayFieldDeclaration):
1129 return ArrayField(field_type)
1130 elif isinstance(field_type, SequenceFieldDeclaration):
1131 return SequenceField(field_type)
1132 elif isinstance(field_type, StringFieldDeclaration):
1133 return StringField(field_type)
1134
1135
1136class Field:
1137 """
d4ba140f
PP
1138 Base class of all fields. This class is not meant to be
1139 instantiated by the user, and neither are its subclasses. Use
1140 :meth:`Event.payload` to access specific, concrete fields of
1141 an event.
be5a4e67
PP
1142 """
1143
1144 def __init__(self, field_type):
1145 if not isinstance(field_type, FieldDeclaration):
1146 raise TypeError("Invalid field_type argument.")
1147
1148 self._f = nbt._bt_ctf_field_create(field_type._ft)
1149
1150 if self._f is None:
1151 raise ValueError("Field creation failed.")
1152
1153 def __del__(self):
1154 nbt._bt_ctf_field_put(self._f)
1155
1156 @staticmethod
1157 def _create_field_from_native_instance(native_field_instance):
1158 type_dict = {
1159 common.CTFTypeId.INTEGER: IntegerField,
1160 common.CTFTypeId.FLOAT: FloatingPointField,
1161 common.CTFTypeId.ENUM: EnumerationField,
1162 common.CTFTypeId.STRING: StringField,
1163 common.CTFTypeId.STRUCT: StructureField,
1164 common.CTFTypeId.VARIANT: VariantField,
1165 common.CTFTypeId.ARRAY: ArrayField,
1166 common.CTFTypeId.SEQUENCE: SequenceField
1167 }
1168
1169 field_type = nbt._bt_python_get_field_type(native_field_instance)
1170
1171 if field_type == common.CTFTypeId.UNKNOWN:
1172 raise TypeError("Invalid field instance")
1173
1174 field = Field.__new__(Field)
1175 field._f = native_field_instance
1176 field.__class__ = type_dict[field_type]
1177
1178 return field
1179
1180 @property
1181 def declaration(self):
d4ba140f
PP
1182 """
1183 Field declaration (subclass of :class:`FieldDeclaration`).
1184
1185 :exc:`TypeError` is raised on error.
1186 """
1187
be5a4e67
PP
1188 native_field_type = nbt._bt_ctf_field_get_type(self._f)
1189
1190 if native_field_type is None:
1191 raise TypeError("Invalid field instance")
1192 return FieldDeclaration._create_field_declaration_from_native_instance(
1193 native_field_type)
1194
1195
1196class IntegerField(Field):
26912ff5
PP
1197 """
1198 Integer field, based on an :class:`IntegerFieldDeclaration` object.
1199 """
1200
be5a4e67
PP
1201 @property
1202 def value(self):
1203 """
26912ff5
PP
1204 Integer value (:class:`int`).
1205
1206 Set this attribute to change the integer field's value.
1207
1208 :exc:`ValueError` or :exc:`TypeError` are raised on error.
be5a4e67
PP
1209 """
1210
1211 signedness = nbt._bt_python_field_integer_get_signedness(self._f)
1212
1213 if signedness < 0:
1214 raise TypeError("Invalid integer instance.")
1215
1216 if signedness == 0:
1217 ret, value = nbt._bt_ctf_field_unsigned_integer_get_value(self._f)
1218 else:
1219 ret, value = nbt._bt_ctf_field_signed_integer_get_value(self._f)
1220
1221 if ret < 0:
1222 raise ValueError("Could not get integer field value.")
1223
1224 return value
1225
1226 @value.setter
1227 def value(self, value):
be5a4e67
PP
1228 if not isinstance(value, int):
1229 raise TypeError("IntegerField's value must be an int")
1230
1231 signedness = nbt._bt_python_field_integer_get_signedness(self._f)
1232 if signedness < 0:
1233 raise TypeError("Invalid integer instance.")
1234
1235 if signedness == 0:
1236 ret = nbt._bt_ctf_field_unsigned_integer_set_value(self._f, value)
1237 else:
1238 ret = nbt._bt_ctf_field_signed_integer_set_value(self._f, value)
1239
1240 if ret < 0:
1241 raise ValueError("Could not set integer field value.")
1242
1243
1244class EnumerationField(Field):
fbfe2f0e
PP
1245 """
1246 Enumeration field, based on an
1247 :class:`EnumerationFieldDeclaration` object.
1248 """
1249
be5a4e67
PP
1250 @property
1251 def container(self):
1252 """
fbfe2f0e
PP
1253 Underlying container (:class:`IntegerField`).
1254
1255 :exc:`TypeError` is raised on error.
be5a4e67
PP
1256 """
1257
1258 container = IntegerField.__new__(IntegerField)
1259 container._f = nbt._bt_ctf_field_enumeration_get_container(self._f)
1260
1261 if container._f is None:
1262 raise TypeError("Invalid enumeration field type.")
1263
1264 return container
1265
1266 @property
1267 def value(self):
1268 """
fbfe2f0e
PP
1269 Current label of this enumeration field (:class:`str`).
1270
1271 Set this attribute to an integer (:class:`int`) to change the
1272 enumeration field's value.
1273
1274 :exc:`ValueError` is raised on error.
be5a4e67
PP
1275 """
1276
1277 value = nbt._bt_ctf_field_enumeration_get_mapping_name(self._f)
1278
1279 if value is None:
fbfe2f0e 1280 raise ValueError("Could not get enumeration mapping name.")
be5a4e67
PP
1281
1282 return value
1283
1284 @value.setter
1285 def value(self, value):
be5a4e67
PP
1286 if not isinstance(value, int):
1287 raise TypeError("EnumerationField value must be an int")
1288
1289 self.container.value = value
1290
1291
1292class FloatingPointField(Field):
cf3687b5
PP
1293 """
1294 Floating point number field, based on a
1295 :class:`FloatingPointFieldDeclaration` object.
1296 """
1297
be5a4e67
PP
1298 @property
1299 def value(self):
1300 """
cf3687b5
PP
1301 Floating point number value (:class:`float`).
1302
1303 Set this attribute to change the floating point number field's
1304 value.
1305
1306 :exc:`ValueError` or :exc:`TypeError` are raised on error.
be5a4e67
PP
1307 """
1308
1309 ret, value = nbt._bt_ctf_field_floating_point_get_value(self._f)
1310
1311 if ret < 0:
1312 raise ValueError("Could not get floating point field value.")
1313
1314 return value
1315
1316 @value.setter
1317 def value(self, value):
be5a4e67
PP
1318 if not isinstance(value, int) and not isinstance(value, float):
1319 raise TypeError("Value must be either a float or an int")
1320
1321 ret = nbt._bt_ctf_field_floating_point_set_value(self._f, float(value))
1322
1323 if ret < 0:
1324 raise ValueError("Could not set floating point field value.")
1325
1326
1327# oops!! This class is provided to ensure backward-compatibility since
1328# a stable release publicly exposed this abomination.
1329class FloatFieldingPoint(FloatingPointField):
1330 pass
1331
1332
1333class StructureField(Field):
773edf13
PP
1334 """
1335 Structure field, based on a
1336 :class:`StructureFieldDeclaration` object.
1337 """
1338
be5a4e67
PP
1339 def field(self, field_name):
1340 """
773edf13
PP
1341 Returns the structure :class:`Field` named *field_name*.
1342
1343 :exc:`ValueError` is raised on error.
be5a4e67
PP
1344 """
1345
1346 native_instance = nbt._bt_ctf_field_structure_get_field(self._f,
1347 str(field_name))
1348
1349 if native_instance is None:
1350 raise ValueError("Invalid field_name provided.")
1351
1352 return Field._create_field_from_native_instance(native_instance)
1353
1354
1355class VariantField(Field):
5f6ba8b2
PP
1356 """
1357 Variant field, based on a
1358 :class:`VariantFieldDeclaration` object.
1359 """
1360
be5a4e67
PP
1361 def field(self, tag):
1362 """
5f6ba8b2
PP
1363 Returns the :class:`Field` selected by the current label of
1364 *tag* (:class:`EnumerationField`).
1365
1366 :exc:`ValueError` is raised on error.
be5a4e67
PP
1367 """
1368
1369 native_instance = nbt._bt_ctf_field_variant_get_field(self._f, tag._f)
1370
1371 if native_instance is None:
1372 raise ValueError("Invalid tag provided.")
1373
1374 return Field._create_field_from_native_instance(native_instance)
1375
1376
1377class ArrayField(Field):
a1bdc25c
PP
1378 """
1379 Static array field, based on an
1380 :class:`ArrayFieldDeclaration` object.
1381 """
1382
be5a4e67
PP
1383 def field(self, index):
1384 """
a1bdc25c
PP
1385 Returns the :class:`Field` at index *index* in this static
1386 array.
1387
1388 :exc:`IndexError` is raised on error.
be5a4e67
PP
1389 """
1390
1391 native_instance = nbt._bt_ctf_field_array_get_field(self._f, index)
1392
1393 if native_instance is None:
1394 raise IndexError("Invalid index provided.")
1395
1396 return Field._create_field_from_native_instance(native_instance)
1397
1398
1399class SequenceField(Field):
4ac159aa
PP
1400 """
1401 Sequence (dynamic array) field, based on a
1402 :class:`SequenceFieldDeclaration` object.
1403 """
1404
be5a4e67
PP
1405 @property
1406 def length(self):
1407 """
4ac159aa
PP
1408 Sequence length (:class:`IntegerField`).
1409
1410 Set this attribute to change the sequence length's integer
1411 field (integer must be unsigned).
1412
1413 :exc:`ValueError` or :exc:`TypeError` are raised on error.
be5a4e67
PP
1414 """
1415
1416 native_instance = nbt._bt_ctf_field_sequence_get_length(self._f)
1417
1418 if native_instance is None:
1419 length = -1
1420
1421 return Field._create_field_from_native_instance(native_instance)
1422
1423 @length.setter
1424 def length(self, length_field):
be5a4e67
PP
1425 if not isinstance(length_field, IntegerField):
1426 raise TypeError("Invalid length field.")
1427
1428 if length_field.declaration.signed:
1429 raise TypeError("Sequence field length must be unsigned")
1430
1431 ret = nbt._bt_ctf_field_sequence_set_length(self._f, length_field._f)
1432
1433 if ret < 0:
1434 raise ValueError("Could not set sequence length.")
1435
1436 def field(self, index):
1437 """
4ac159aa
PP
1438 Returns the :class:`Field` at index *index* in this sequence.
1439
1440 :exc:`ValueError` is raised on error.
be5a4e67
PP
1441 """
1442
1443 native_instance = nbt._bt_ctf_field_sequence_get_field(self._f, index)
1444
1445 if native_instance is None:
1446 raise ValueError("Could not get sequence element at index.")
1447
1448 return Field._create_field_from_native_instance(native_instance)
1449
1450
1451class StringField(Field):
4027ea9d
PP
1452 """
1453 String (NULL-terminated array of bytes) field.
1454 """
1455
be5a4e67
PP
1456 @property
1457 def value(self):
1458 """
4027ea9d
PP
1459 String value (:class:`str`).
1460
1461 Set this attribute to change the string's value.
1462
1463 :exc:`ValueError` or :exc:`TypeError` are raised on error.
be5a4e67
PP
1464 """
1465
1466 return nbt._bt_ctf_field_string_get_value(self._f)
1467
1468 @value.setter
1469 def value(self, value):
be5a4e67
PP
1470 ret = nbt._bt_ctf_field_string_set_value(self._f, str(value))
1471
1472 if ret < 0:
1473 raise ValueError("Could not set string field value.")
1474
1475
1476class EventClass:
ad9c62de
PP
1477 """
1478 An event class contains the properties of specific
1479 events (:class:`Event`). Any concrete event must be linked with an
1480 :class:`EventClass`.
1481
1482 Some attributes are automatically set when creating an event class.
1483 For example, if no numeric ID is explicitly set using the
1484 :attr:`id` attribute, a default, unique ID within the stream class
1485 containing this event class will be created when needed.
1486 """
1487
be5a4e67
PP
1488 def __init__(self, name):
1489 """
ad9c62de
PP
1490 Creates an event class named *name*.
1491
1492 :exc:`ValueError` is raised on error.
be5a4e67
PP
1493 """
1494
1495 self._ec = nbt._bt_ctf_event_class_create(name)
1496
1497 if self._ec is None:
1498 raise ValueError("Event class creation failed.")
1499
1500 def __del__(self):
1501 nbt._bt_ctf_event_class_put(self._ec)
1502
1503 def add_field(self, field_type, field_name):
1504 """
ad9c62de
PP
1505 Adds a field declaration *field_type* named *field_name* to
1506 this event class.
1507
1508 *field_type* must be one of:
1509
1510 * :class:`IntegerFieldDeclaration`
1511 * :class:`FloatingPointFieldDeclaration`
1512 * :class:`EnumerationFieldDeclaration`
1513 * :class:`StringFieldDeclaration`
1514 * :class:`ArrayFieldDeclaration`
1515 * :class:`SequenceFieldDeclaration`
1516 * :class:`StructureFieldDeclaration`
1517 * :class:`VariantFieldDeclaration`
1518
1519 :exc:`ValueError` is raised on error.
be5a4e67
PP
1520 """
1521
1522 ret = nbt._bt_ctf_event_class_add_field(self._ec, field_type._ft,
1523 str(field_name))
1524
1525 if ret < 0:
1526 raise ValueError("Could not add field to event class.")
1527
1528 @property
1529 def name(self):
1530 """
ad9c62de 1531 Event class' name.
be5a4e67
PP
1532 """
1533
1534 name = nbt._bt_ctf_event_class_get_name(self._ec)
1535
1536 if name is None:
1537 raise TypeError("Could not get EventClass name")
1538
1539 return name
1540
1541 @property
1542 def id(self):
1543 """
ad9c62de
PP
1544 Event class' numeric ID.
1545
1546 Set this attribute to assign a numeric ID to this event class.
1547 This ID must be unique amongst all the event class IDs of a
1548 given stream class.
1549
1550 :exc:`TypeError` is raised on error.
be5a4e67
PP
1551 """
1552
1553 id = nbt._bt_ctf_event_class_get_id(self._ec)
1554
1555 if id < 0:
1556 raise TypeError("Could not get EventClass id")
1557
1558 return id
1559
1560 @id.setter
1561 def id(self, id):
be5a4e67
PP
1562 ret = nbt._bt_ctf_event_class_set_id(self._ec, id)
1563
1564 if ret < 0:
ad9c62de 1565 raise TypeError("Can't change an Event Class id after it has been assigned to a stream class")
be5a4e67
PP
1566
1567 @property
1568 def stream_class(self):
1569 """
ad9c62de
PP
1570 :class:`StreamClass` object containing this event class,
1571 or ``None`` if not set.
be5a4e67 1572 """
ad9c62de 1573
be5a4e67
PP
1574 stream_class_native = nbt._bt_ctf_event_class_get_stream_class(self._ec)
1575
1576 if stream_class_native is None:
1577 return None
1578
1579 stream_class = StreamClass.__new__(StreamClass)
1580 stream_class._sc = stream_class_native
1581
1582 return stream_class
1583
1584 @property
1585 def fields(self):
1586 """
ad9c62de
PP
1587 Generates the (field name, :class:`FieldDeclaration`) pairs of
1588 this event class.
1589
1590 :exc:`TypeError` is raised on error.
be5a4e67
PP
1591 """
1592
1593 count = nbt._bt_ctf_event_class_get_field_count(self._ec)
1594
1595 if count < 0:
1596 raise TypeError("Could not get EventClass' field count")
1597
1598 for i in range(count):
1599 field_name = nbt._bt_python_ctf_event_class_get_field_name(self._ec, i)
1600
1601 if field_name is None:
1602 msg = "Could not get EventClass' field name at index {}".format(i)
1603 raise TypeError(msg)
1604
1605 field_type_native = nbt._bt_python_ctf_event_class_get_field_type(self._ec, i)
1606
1607 if field_type_native is None:
1608 msg = "Could not get EventClass' field type at index {}".format(i)
1609 raise TypeError(msg)
1610
1611 field_type = FieldDeclaration._create_field_declaration_from_native_instance(field_type_native)
1612 yield (field_name, field_type)
1613
1614 def get_field_by_name(self, name):
1615 """
ad9c62de
PP
1616 Returns the :class:`FieldDeclaration` object named *name* in
1617 this event class.
1618
1619 :exc:`TypeError` is raised on error.
be5a4e67
PP
1620 """
1621
1622 field_type_native = nbt._bt_ctf_event_class_get_field_by_name(self._ec, name)
1623
1624 if field_type_native is None:
1625 msg = "Could not find EventClass field with name {}".format(name)
1626 raise TypeError(msg)
1627
1628 return FieldDeclaration._create_field_declaration_from_native_instance(field_type_native)
1629
1630
1631class Event:
59b50df8
PP
1632 """
1633 Events are specific instances of event classes
1634 (:class:`EventClass`), which means they may contain actual,
1635 concrete field values.
1636 """
1637
be5a4e67
PP
1638 def __init__(self, event_class):
1639 """
59b50df8
PP
1640 Creates an event linked with the :class:`EventClass`
1641 *event_class*.
1642
1643 :exc:`ValueError` is raised on error.
be5a4e67
PP
1644 """
1645
1646 if not isinstance(event_class, EventClass):
1647 raise TypeError("Invalid event_class argument.")
1648
1649 self._e = nbt._bt_ctf_event_create(event_class._ec)
1650
1651 if self._e is None:
1652 raise ValueError("Event creation failed.")
1653
1654 def __del__(self):
1655 nbt._bt_ctf_event_put(self._e)
1656
1657 @property
1658 def event_class(self):
1659 """
59b50df8 1660 :class:`EventClass` object to which this event is linked.
be5a4e67
PP
1661 """
1662
1663 event_class_native = nbt._bt_ctf_event_get_class(self._e)
1664
1665 if event_class_native is None:
1666 return None
1667
1668 event_class = EventClass.__new__(EventClass)
1669 event_class._ec = event_class_native
1670
1671 return event_class
1672
1673 def clock(self):
1674 """
59b50df8
PP
1675 :class:`Clock` object used by this object, or ``None`` if
1676 the event class is not registered to a stream class.
be5a4e67
PP
1677 """
1678
1679 clock_instance = nbt._bt_ctf_event_get_clock(self._e)
1680
1681 if clock_instance is None:
1682 return None
1683
1684 clock = Clock.__new__(Clock)
1685 clock._c = clock_instance
1686
1687 return clock
1688
1689 def payload(self, field_name):
1690 """
59b50df8
PP
1691 Returns the :class:`Field` object named *field_name* in this
1692 event.
1693
1694 The returned field object is created using the event class'
1695 field declaration named *field_name*.
1696
1697 The return type is one of:
1698
1699 * :class:`IntegerField`
1700 * :class:`FloatingPointField`
1701 * :class:`EnumerationField`
1702 * :class:`StringField`
1703 * :class:`ArrayField`
1704 * :class:`SequenceField`
1705 * :class:`StructureField`
1706 * :class:`VariantField`
1707
1708 :exc:`TypeError` is raised on error.
be5a4e67
PP
1709 """
1710
1711 native_instance = nbt._bt_ctf_event_get_payload(self._e,
1712 str(field_name))
1713
1714 if native_instance is None:
1715 raise ValueError("Could not get event payload.")
1716
1717 return Field._create_field_from_native_instance(native_instance)
1718
1719 def set_payload(self, field_name, value_field):
1720 """
59b50df8
PP
1721 Set the event's field named *field_name* to the manually
1722 created :class:`Field` object *value_field*.
1723
1724 *value_field*'s type must be one of:
1725
1726 * :class:`IntegerField`
1727 * :class:`FloatingPointField`
1728 * :class:`EnumerationField`
1729 * :class:`StringField`
1730 * :class:`ArrayField`
1731 * :class:`SequenceField`
1732 * :class:`StructureField`
1733 * :class:`VariantField`
1734
1735 :exc:`ValueError` is raised on error.
be5a4e67
PP
1736 """
1737
1738 if not isinstance(value, Field):
1739 raise TypeError("Invalid value type.")
1740
1741 ret = nbt._bt_ctf_event_set_payload(self._e, str(field_name),
1742 value_field._f)
1743
1744 if ret < 0:
1745 raise ValueError("Could not set event field payload.")
1746
1747
1748class StreamClass:
5fd17f73
PP
1749 """
1750 A stream class contains the properties of specific
1751 streams (:class:`Stream`). Any concrete stream must be linked with
1752 a :class:`StreamClass`, usually by calling
1753 :meth:`Writer.create_stream`.
1754
1755 Some attributes are automatically set when creating a stream class.
1756 For example, if no clock is explicitly set using the
1757 :attr:`clock` attribute, a default clock will be created
1758 when needed.
1759 """
1760
be5a4e67
PP
1761 def __init__(self, name):
1762 """
5fd17f73
PP
1763 Creates a stream class named *name*.
1764
1765 :exc:`ValueError` is raised on error.
be5a4e67
PP
1766 """
1767
1768 self._sc = nbt._bt_ctf_stream_class_create(name)
1769
1770 if self._sc is None:
1771 raise ValueError("Stream class creation failed.")
1772
1773 def __del__(self):
1774 nbt._bt_ctf_stream_class_put(self._sc)
1775
1776 @property
1777 def name(self):
1778 """
5fd17f73
PP
1779 Stream class' name.
1780
1781 :exc:`TypeError` is raised on error.
be5a4e67
PP
1782 """
1783
1784 name = nbt._bt_ctf_stream_class_get_name(self._sc)
1785
1786 if name is None:
1787 raise TypeError("Could not get StreamClass name")
1788
1789 return name
1790
1791 @property
1792 def clock(self):
1793 """
5fd17f73
PP
1794 Stream class' clock (:class:`Clock` object).
1795
1796 Set this attribute to change the clock of this stream class.
1797
1798 :exc:`ValueError` is raised on error.
be5a4e67
PP
1799 """
1800
1801 clock_instance = nbt._bt_ctf_stream_class_get_clock(self._sc)
1802
1803 if clock_instance is None:
1804 return None
1805
1806 clock = Clock.__new__(Clock)
1807 clock._c = clock_instance
1808
1809 return clock
1810
1811 @clock.setter
1812 def clock(self, clock):
be5a4e67
PP
1813 if not isinstance(clock, Clock):
1814 raise TypeError("Invalid clock type.")
1815
1816 ret = nbt._bt_ctf_stream_class_set_clock(self._sc, clock._c)
1817
1818 if ret < 0:
1819 raise ValueError("Could not set stream class clock.")
1820
1821 @property
1822 def id(self):
1823 """
5fd17f73
PP
1824 Stream class' numeric ID.
1825
1826 Set this attribute to change the ID of this stream class.
1827
1828 :exc:`ValueError` is raised on error.
be5a4e67
PP
1829 """
1830
1831 ret = nbt._bt_ctf_stream_class_get_id(self._sc)
1832
1833 if ret < 0:
1834 raise TypeError("Could not get StreamClass id")
1835
1836 return ret
1837
1838 @id.setter
1839 def id(self, id):
be5a4e67
PP
1840 ret = nbt._bt_ctf_stream_class_set_id(self._sc, id)
1841
1842 if ret < 0:
1843 raise TypeError("Could not set stream class id.")
1844
1845 @property
1846 def event_classes(self):
1847 """
5fd17f73
PP
1848 Generates the event classes (:class:`EventClass` objects) of
1849 this stream class.
1850
1851 :exc:`TypeError` is raised on error.
be5a4e67
PP
1852 """
1853
1854 count = nbt._bt_ctf_stream_class_get_event_class_count(self._sc)
1855
1856 if count < 0:
1857 raise TypeError("Could not get StreamClass' event class count")
1858
1859 for i in range(count):
1860 event_class_native = nbt._bt_ctf_stream_class_get_event_class(self._sc, i)
1861
1862 if event_class_native is None:
1863 msg = "Could not get StreamClass' event class at index {}".format(i)
1864 raise TypeError(msg)
1865
1866 event_class = EventClass.__new__(EventClass)
1867 event_class._ec = event_class_native
1868 yield event_class
1869
1870 def add_event_class(self, event_class):
1871 """
5fd17f73
PP
1872 Registers the :class:`EventClass` *event_class* to this stream
1873 class.
1874
1875 Once the event class is registered, it will be generated as one
1876 of the event classes generated by :attr:`event_classes`.
1877
1878 :exc:`ValueError` is raised on error.
be5a4e67
PP
1879 """
1880
1881 if not isinstance(event_class, EventClass):
1882 raise TypeError("Invalid event_class type.")
1883
1884 ret = nbt._bt_ctf_stream_class_add_event_class(self._sc,
1885 event_class._ec)
1886
1887 if ret < 0:
1888 raise ValueError("Could not add event class.")
1889
1890 @property
1891 def packet_context_type(self):
1892 """
5fd17f73
PP
1893 Stream packet context declaration.
1894
1895 Set this attribute to change the stream packet context
1896 declaration (must be an instance of
1897 :class:`StructureFieldDeclaration`).
1898
1899 :exc:`ValueError` is raised on error.
1900
be5a4e67
PP
1901 """
1902
1903 field_type_native = nbt._bt_ctf_stream_class_get_packet_context_type(self._sc)
1904
1905 if field_type_native is None:
1906 raise ValueError("Invalid StreamClass")
1907
1908 field_type = FieldDeclaration._create_field_declaration_from_native_instance(field_type_native)
1909
1910 return field_type
1911
1912 @packet_context_type.setter
1913 def packet_context_type(self, field_type):
be5a4e67
PP
1914 if not isinstance(field_type, StructureFieldDeclaration):
1915 raise TypeError("field_type argument must be of type StructureFieldDeclaration.")
1916
1917 ret = nbt._bt_ctf_stream_class_set_packet_context_type(self._sc,
1918 field_type._ft)
1919
1920 if ret < 0:
1921 raise ValueError("Failed to set packet context type.")
1922
1923
1924class Stream:
898a14a5
PP
1925 """
1926 Streams are specific instances of stream classes, which means they
1927 may contain actual, concrete events.
1928
1929 :class:`Stream` objects are returned by
1930 :meth:`Writer.create_stream`; they are not meant to be
1931 instantiated by the user.
1932
1933 Concrete :class:`Event` objects are appended to
1934 :class:`Stream` objects using :meth:`append_event`.
1935
1936 When :meth:`flush` is called, a CTF packet is created, containing
1937 all the appended events since the last flush. Although the stream
1938 is flushed on object destruction, it is **strongly recommended**
1939 that the user call :meth:`flush` manually before exiting the
1940 script, as :meth:`__del__` is not always reliable.
1941 """
1942
be5a4e67
PP
1943 def __init__(self):
1944 raise NotImplementedError("Stream cannot be instantiated; use Writer.create_stream()")
1945
1946 def __del__(self):
1947 nbt._bt_ctf_stream_put(self._s)
1948
1949 @property
1950 def discarded_events(self):
1951 """
898a14a5
PP
1952 Number of discarded (lost) events in this stream so far.
1953
1954 :exc:`ValueError` is raised on error.
be5a4e67
PP
1955 """
1956
1957 ret, count = nbt._bt_ctf_stream_get_discarded_events_count(self._s)
1958
1959 if ret < 0:
898a14a5 1960 raise ValueError("Could not get the stream discarded events count")
be5a4e67
PP
1961
1962 return count
1963
1964 def append_discarded_events(self, event_count):
1965 """
898a14a5 1966 Appends *event_count* discarded events to this stream.
be5a4e67
PP
1967 """
1968
1969 nbt._bt_ctf_stream_append_discarded_events(self._s, event_count)
1970
1971 def append_event(self, event):
1972 """
898a14a5
PP
1973 Appends event *event* (:class:`Event` object) to this stream.
1974
1975 The stream's associated clock will be sampled during this call.
1976 *event* **shall not** be modified after being appended to this
1977 stream.
1978
1979 :exc:`ValueError` is raised on error.
be5a4e67
PP
1980 """
1981
1982 ret = nbt._bt_ctf_stream_append_event(self._s, event._e)
1983
1984 if ret < 0:
1985 raise ValueError("Could not append event to stream.")
1986
1987 @property
1988 def packet_context(self):
1989 """
898a14a5
PP
1990 Stream packet context field (instance of
1991 :class:`StructureField`).
1992
1993 Set this attribute to assign a stream packet context field
1994 to this stream.
1995
1996 :exc:`ValueError` is raised on error.
be5a4e67
PP
1997 """
1998
1999 native_field = nbt._bt_ctf_stream_get_packet_context(self._s)
2000
2001 if native_field is None:
2002 raise ValueError("Invalid Stream.")
2003
2004 return Field._create_field_from_native_instance(native_field)
2005
2006 @packet_context.setter
2007 def packet_context(self, field):
be5a4e67
PP
2008 if not isinstance(field, StructureField):
2009 raise TypeError("Argument field must be of type StructureField")
2010
2011 ret = nbt._bt_ctf_stream_set_packet_context(self._s, field._f)
2012
2013 if ret < 0:
2014 raise ValueError("Invalid packet context field.")
2015
2016 def flush(self):
2017 """
898a14a5
PP
2018 Flushes the current packet of this stream to disk. Events
2019 subsequently appended to the stream will be added to a new
2020 packet.
2021
2022 :exc:`ValueError` is raised on error.
be5a4e67
PP
2023 """
2024
2025 ret = nbt._bt_ctf_stream_flush(self._s)
2026
2027 if ret < 0:
2028 raise ValueError("Could not flush stream.")
2029
2030
2031class Writer:
40529d6d
PP
2032 """
2033 This object is the CTF writer API context. It oversees its streams
2034 and clocks, and is responsible for writing one CTF trace.
2035 """
2036
be5a4e67
PP
2037 def __init__(self, path):
2038 """
40529d6d
PP
2039 Creates a CTF writer, initializing a new CTF trace at path
2040 *path*.
2041
2042 *path* must be an existing directory, since a CTF trace is
2043 made of multiple files.
2044
2045 :exc:`ValueError` is raised if the creation fails.
be5a4e67
PP
2046 """
2047
2048 self._w = nbt._bt_ctf_writer_create(path)
2049
2050 if self._w is None:
2051 raise ValueError("Writer creation failed.")
2052
2053 def __del__(self):
2054 nbt._bt_ctf_writer_put(self._w)
2055
2056 def create_stream(self, stream_class):
2057 """
40529d6d
PP
2058 Creates and registers a new stream based on stream class
2059 *stream_class*.
2060
2061 This is the standard way of creating a :class:`Stream` object:
2062 the user is not allowed to instantiate this class.
2063
2064 Returns a new :class:`Stream` object.
be5a4e67
PP
2065 """
2066
2067 if not isinstance(stream_class, StreamClass):
2068 raise TypeError("Invalid stream_class type.")
2069
2070 stream = Stream.__new__(Stream)
2071 stream._s = nbt._bt_ctf_writer_create_stream(self._w, stream_class._sc)
2072
2073 return stream
2074
2075 def add_environment_field(self, name, value):
2076 """
40529d6d
PP
2077 Sets the CTF environment variable named *name* to value *value*
2078 (converted to a string).
2079
2080 :exc:`ValueError` is raised on error.
be5a4e67
PP
2081 """
2082
2083 ret = nbt._bt_ctf_writer_add_environment_field(self._w, str(name),
2084 str(value))
2085
2086 if ret < 0:
2087 raise ValueError("Could not add environment field to trace.")
2088
2089 def add_clock(self, clock):
2090 """
40529d6d
PP
2091 Registers :class:`Clock` object *clock* to the writer.
2092
2093 You *must* register CTF clocks assigned to stream classes
2094 to the writer.
2095
2096 :exc:`ValueError` is raised if the creation fails.
be5a4e67
PP
2097 """
2098
2099 ret = nbt._bt_ctf_writer_add_clock(self._w, clock._c)
2100
2101 if ret < 0:
2102 raise ValueError("Could not add clock to Writer.")
2103
2104 @property
2105 def metadata(self):
2106 """
40529d6d 2107 Current metadata of this trace (:class:`str`).
be5a4e67
PP
2108 """
2109
2110 return nbt._bt_ctf_writer_get_metadata_string(self._w)
2111
2112 def flush_metadata(self):
2113 """
40529d6d 2114 Flushes the trace's metadata to the metadata file.
be5a4e67
PP
2115 """
2116
2117 nbt._bt_ctf_writer_flush_metadata(self._w)
2118
2119 @property
2120 def byte_order(self):
2121 """
40529d6d
PP
2122 Native byte order of this trace (one of
2123 :class:`babeltrace.common.ByteOrder` constants).
2124
2125 This is the actual byte order that is used when a field
2126 declaration has the
2127 :attr:`babeltrace.common.ByteOrder.BYTE_ORDER_NATIVE`
2128 value.
2129
2130 Set this attribute to change the trace's native byte order.
2131
2132 Defaults to the host machine's endianness.
2133
2134 :exc:`ValueError` is raised on error.
be5a4e67
PP
2135 """
2136
2137 raise NotImplementedError("Getter not implemented.")
2138
2139 @byte_order.setter
2140 def byte_order(self, byte_order):
be5a4e67
PP
2141 ret = nbt._bt_ctf_writer_set_byte_order(self._w, byte_order)
2142
2143 if ret < 0:
40529d6d 2144 raise ValueError("Could not set trace byte order.")
This page took 0.142959 seconds and 4 git commands to generate.