Python: document writer.IntegerFieldDeclaration
[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
304 INTEGER_BASE_UNKNOWN = -1
305
306 #: Binary
307 INTEGER_BASE_BINARY = 2
308
309 #: Octal
310 INTEGER_BASE_OCTAL = 8
311
312 #: Decimal
313 INTEGER_BASE_DECIMAL = 10
314
315 #: Hexadecimal
316 INTEGER_BASE_HEXADECIMAL = 16
317
318
be5a4e67
PP
319class FieldDeclaration:
320 """
a20c2934
PP
321 Base class of all field declarations. This class is not meant to
322 be instantiated by the user; use one of the concrete field
323 declaration subclasses instead.
be5a4e67
PP
324 """
325
fe9f5df1
PP
326 class IntegerBase(IntegerBase):
327 pass
be5a4e67
PP
328
329 def __init__(self):
330 if self._ft is None:
331 raise ValueError("FieldDeclaration creation failed.")
332
333 def __del__(self):
334 nbt._bt_ctf_field_type_put(self._ft)
335
336 @staticmethod
337 def _create_field_declaration_from_native_instance(
338 native_field_declaration):
339 type_dict = {
340 common.CTFTypeId.INTEGER: IntegerFieldDeclaration,
341 common.CTFTypeId.FLOAT: FloatFieldDeclaration,
342 common.CTFTypeId.ENUM: EnumerationFieldDeclaration,
343 common.CTFTypeId.STRING: StringFieldDeclaration,
344 common.CTFTypeId.STRUCT: StructureFieldDeclaration,
345 common.CTFTypeId.VARIANT: VariantFieldDeclaration,
346 common.CTFTypeId.ARRAY: ArrayFieldDeclaration,
347 common.CTFTypeId.SEQUENCE: SequenceFieldDeclaration
348 }
349
350 field_type_id = nbt._bt_ctf_field_type_get_type_id(native_field_declaration)
351
352 if field_type_id == common.CTFTypeId.UNKNOWN:
353 raise TypeError("Invalid field instance")
354
355 declaration = Field.__new__(Field)
356 declaration._ft = native_field_declaration
357 declaration.__class__ = type_dict[field_type_id]
358
359 return declaration
360
361 @property
362 def alignment(self):
363 """
a20c2934
PP
364 Field alignment in bits (integer).
365
366 Set this attribute to change this field's alignment.
367
368 :exc:`ValueError` is raised on error.
be5a4e67
PP
369 """
370
371 return nbt._bt_ctf_field_type_get_alignment(self._ft)
372
373 @alignment.setter
374 def alignment(self, alignment):
be5a4e67
PP
375 ret = nbt._bt_ctf_field_type_set_alignment(self._ft, alignment)
376
377 if ret < 0:
378 raise ValueError("Invalid alignment value.")
379
380 @property
381 def byte_order(self):
382 """
a20c2934
PP
383 Field byte order (one of :class:`babeltrace.common.ByteOrder`
384 constants).
385
386 Set this attribute to change this field's byte order.
387
388 :exc:`ValueError` is raised on error.
be5a4e67
PP
389 """
390
391 return nbt._bt_ctf_field_type_get_byte_order(self._ft)
392
393 @byte_order.setter
394 def byte_order(self, byte_order):
be5a4e67
PP
395 ret = nbt._bt_ctf_field_type_set_byte_order(self._ft, byte_order)
396
397 if ret < 0:
398 raise ValueError("Could not set byte order value.")
399
400
401class IntegerFieldDeclaration(FieldDeclaration):
7d06a31a
PP
402 """
403 Integer field declaration.
404 """
405
be5a4e67
PP
406 def __init__(self, size):
407 """
7d06a31a
PP
408 Creates an integer field declaration of size *size* bits.
409
410 :exc:`ValueError` is raised on error.
be5a4e67 411 """
7d06a31a 412
be5a4e67
PP
413 self._ft = nbt._bt_ctf_field_type_integer_create(size)
414 super().__init__()
415
416 @property
417 def size(self):
418 """
7d06a31a
PP
419 Integer size in bits (integer).
420
421 Set this attribute to change this integer's size.
422
423 :exc:`ValueError` is raised on error.
be5a4e67
PP
424 """
425
426 ret = nbt._bt_ctf_field_type_integer_get_size(self._ft)
427
428 if ret < 0:
7d06a31a 429 raise ValueError("Could not get Integer size attribute.")
be5a4e67
PP
430 else:
431 return ret
432
433 @property
434 def signed(self):
435 """
7d06a31a
PP
436 ``True`` if this integer is signed.
437
438 Set this attribute to change this integer's signedness
439 (boolean).
440
441 :exc:`ValueError` is raised on error.
be5a4e67
PP
442 """
443
444 ret = nbt._bt_ctf_field_type_integer_get_signed(self._ft)
445
446 if ret < 0:
7d06a31a 447 raise ValueError("Could not get Integer signed attribute.")
be5a4e67
PP
448 elif ret > 0:
449 return True
450 else:
451 return False
452
453 @signed.setter
454 def signed(self, signed):
be5a4e67
PP
455 ret = nbt._bt_ctf_field_type_integer_set_signed(self._ft, signed)
456
457 if ret < 0:
7d06a31a 458 raise ValueError("Could not set Integer signed attribute.")
be5a4e67
PP
459
460 @property
461 def base(self):
462 """
7d06a31a
PP
463 Integer display base (one of :class:`IntegerBase` constants).
464
465 Set this attribute to change this integer's display base.
466
467 :exc:`ValueError` is raised on error.
be5a4e67
PP
468 """
469
470 return nbt._bt_ctf_field_type_integer_get_base(self._ft)
471
472 @base.setter
473 def base(self, base):
be5a4e67
PP
474 ret = nbt._bt_ctf_field_type_integer_set_base(self._ft, base)
475
476 if ret < 0:
7d06a31a 477 raise ValueError("Could not set Integer base.")
be5a4e67
PP
478
479 @property
480 def encoding(self):
481 """
7d06a31a
PP
482 Integer encoding (one of
483 :class:`babeltrace.common.CTFStringEncoding` constants).
484
485 Set this attribute to change this integer's encoding.
486
487 :exc:`ValueError` is raised on error.
be5a4e67
PP
488 """
489
490 return nbt._bt_ctf_field_type_integer_get_encoding(self._ft)
491
492 @encoding.setter
493 def encoding(self, encoding):
be5a4e67
PP
494 ret = nbt._bt_ctf_field_type_integer_set_encoding(self._ft, encoding)
495
496 if ret < 0:
7d06a31a 497 raise ValueError("Could not set Integer encoding.")
be5a4e67
PP
498
499
500class EnumerationFieldDeclaration(FieldDeclaration):
501 def __init__(self, integer_type):
502 """
503 Create a new enumeration field declaration with the given underlying container type.
504 """
505 isinst = isinstance(integer_type, IntegerFieldDeclaration)
506
507 if integer_type is None or not isinst:
508 raise TypeError("Invalid integer container.")
509
510 self._ft = nbt._bt_ctf_field_type_enumeration_create(integer_type._ft)
511 super().__init__()
512
513 @property
514 def container(self):
515 """
516 Get the enumeration's underlying container type.
517 """
518
519 ret = nbt._bt_ctf_field_type_enumeration_get_container_type(self._ft)
520
521 if ret is None:
522 raise TypeError("Invalid enumeration declaration")
523
524 return FieldDeclaration._create_field_declaration_from_native_instance(ret)
525
526 def add_mapping(self, name, range_start, range_end):
527 """
528 Add a mapping to the enumeration. The range's values are inclusive.
529 """
530
531 if range_start < 0 or range_end < 0:
532 ret = nbt._bt_ctf_field_type_enumeration_add_mapping(self._ft,
533 str(name),
534 range_start,
535 range_end)
536 else:
537 ret = nbt._bt_ctf_field_type_enumeration_add_mapping_unsigned(self._ft,
538 str(name),
539 range_start,
540 range_end)
541
542 if ret < 0:
543 raise ValueError("Could not add mapping to enumeration declaration.")
544
545 @property
546 def mappings(self):
547 """
548 Generator returning instances of EnumerationMapping.
549 """
550
551 signed = self.container.signed
552
553 count = nbt._bt_ctf_field_type_enumeration_get_mapping_count(self._ft)
554
555 for i in range(count):
556 if signed:
557 ret = nbt._bt_python_ctf_field_type_enumeration_get_mapping(self._ft, i)
558 else:
559 ret = nbt._bt_python_ctf_field_type_enumeration_get_mapping_unsigned(self._ft, i)
560
561 if len(ret) != 3:
562 msg = "Could not get Enumeration mapping at index {}".format(i)
563 raise TypeError(msg)
564
565 name, range_start, range_end = ret
566 yield EnumerationMapping(name, range_start, range_end)
567
568 def get_mapping_by_name(self, name):
569 """
570 Get a mapping by name (EnumerationMapping).
571 """
572
573 index = nbt._bt_ctf_field_type_enumeration_get_mapping_index_by_name(self._ft, name)
574
575 if index < 0:
576 return None
577
578 if self.container.signed:
579 ret = nbt._bt_python_ctf_field_type_enumeration_get_mapping(self._ft, index)
580 else:
581 ret = nbt._bt_python_ctf_field_type_enumeration_get_mapping_unsigned(self._ft, index)
582
583 if len(ret) != 3:
584 msg = "Could not get Enumeration mapping at index {}".format(i)
585 raise TypeError(msg)
586
587 name, range_start, range_end = ret
588
589 return EnumerationMapping(name, range_start, range_end)
590
591 def get_mapping_by_value(self, value):
592 """
593 Get a mapping by value (EnumerationMapping).
594 """
595
596 if value < 0:
597 index = nbt._bt_ctf_field_type_enumeration_get_mapping_index_by_value(self._ft, value)
598 else:
599 index = nbt._bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value(self._ft, value)
600
601 if index < 0:
602 return None
603
604 if self.container.signed:
605 ret = nbt._bt_python_ctf_field_type_enumeration_get_mapping(self._ft, index)
606 else:
607 ret = nbt._bt_python_ctf_field_type_enumeration_get_mapping_unsigned(self._ft, index)
608
609 if len(ret) != 3:
610 msg = "Could not get Enumeration mapping at index {}".format(i)
611 raise TypeError(msg)
612
613 name, range_start, range_end = ret
614
615 return EnumerationMapping(name, range_start, range_end)
616
617
618class FloatFieldDeclaration(FieldDeclaration):
619 FLT_EXP_DIG = 8
620 DBL_EXP_DIG = 11
621 FLT_MANT_DIG = 24
622 DBL_MANT_DIG = 53
623
624 def __init__(self):
625 """
626 Create a new floating point field declaration.
627 """
628
629 self._ft = nbt._bt_ctf_field_type_floating_point_create()
630 super().__init__()
631
632 @property
633 def exponent_digits(self):
634 """
635 Get the number of exponent digits used to store the floating point field.
636 """
637
638 ret = nbt._bt_ctf_field_type_floating_point_get_exponent_digits(self._ft)
639
640 if ret < 0:
641 raise TypeError(
642 "Could not get Floating point exponent digit count")
643
644 return ret
645
646 @exponent_digits.setter
647 def exponent_digits(self, exponent_digits):
648 """
649 Set the number of exponent digits to use to store the floating point field.
650 The only values currently supported are FLT_EXP_DIG and DBL_EXP_DIG which
651 are defined as constants of this class.
652 """
653
654 ret = nbt._bt_ctf_field_type_floating_point_set_exponent_digits(self._ft,
655 exponent_digits)
656
657 if ret < 0:
658 raise ValueError("Could not set exponent digit count.")
659
660 @property
661 def mantissa_digits(self):
662 """
663 Get the number of mantissa digits used to store the floating point field.
664 """
665
666 ret = nbt._bt_ctf_field_type_floating_point_get_mantissa_digits(self._ft)
667
668 if ret < 0:
669 raise TypeError("Could not get Floating point mantissa digit count")
670
671 return ret
672
673 @mantissa_digits.setter
674 def mantissa_digits(self, mantissa_digits):
675 """
676 Set the number of mantissa digits to use to store the floating point field.
677 The only values currently supported are FLT_MANT_DIG and DBL_MANT_DIG which
678 are defined as constants of this class.
679 """
680
681 ret = nbt._bt_ctf_field_type_floating_point_set_mantissa_digits(self._ft,
682 mantissa_digits)
683
684 if ret < 0:
685 raise ValueError("Could not set mantissa digit count.")
686
687
688class FloatingPointFieldDeclaration(FloatFieldDeclaration):
689 pass
690
691
692class StructureFieldDeclaration(FieldDeclaration):
693 def __init__(self):
694 """
695 Create a new structure field declaration.
696 """
697
698 self._ft = nbt._bt_ctf_field_type_structure_create()
699 super().__init__()
700
701 def add_field(self, field_type, field_name):
702 """
703 Add a field of type "field_type" to the structure.
704 """
705
706 ret = nbt._bt_ctf_field_type_structure_add_field(self._ft,
707 field_type._ft,
708 str(field_name))
709
710 if ret < 0:
711 raise ValueError("Could not add field to structure.")
712
713 @property
714 def fields(self):
715 """
716 Generator returning the structure's field as tuples of (field name, field declaration).
717 """
718
719 count = nbt._bt_ctf_field_type_structure_get_field_count(self._ft)
720
721 if count < 0:
722 raise TypeError("Could not get Structure field count")
723
724 for i in range(count):
725 field_name = nbt._bt_python_ctf_field_type_structure_get_field_name(self._ft, i)
726
727 if field_name is None:
728 msg = "Could not get Structure field name at index {}".format(i)
729 raise TypeError(msg)
730
731 field_type_native = nbt._bt_python_ctf_field_type_structure_get_field_type(self._ft, i)
732
733 if field_type_native is None:
734 msg = "Could not get Structure field type at index {}".format(i)
735 raise TypeError(msg)
736
737 field_type = FieldDeclaration._create_field_declaration_from_native_instance(field_type_native)
738 yield (field_name, field_type)
739
740 def get_field_by_name(self, name):
741 """
742 Get a field declaration by name (FieldDeclaration).
743 """
744
745 field_type_native = nbt._bt_ctf_field_type_structure_get_field_type_by_name(self._ft, name)
746
747 if field_type_native is None:
748 msg = "Could not find Structure field with name {}".format(name)
749 raise TypeError(msg)
750
751 return FieldDeclaration._create_field_declaration_from_native_instance(field_type_native)
752
753
754class VariantFieldDeclaration(FieldDeclaration):
755 def __init__(self, enum_tag, tag_name):
756 """
757 Create a new variant field declaration.
758 """
759
760 isinst = isinstance(enum_tag, EnumerationFieldDeclaration)
761 if enum_tag is None or not isinst:
762 raise TypeError("Invalid tag type; must be of type EnumerationFieldDeclaration.")
763
764 self._ft = nbt._bt_ctf_field_type_variant_create(enum_tag._ft,
765 str(tag_name))
766 super().__init__()
767
768 @property
769 def tag_name(self):
770 """
771 Get the variant's tag name.
772 """
773
774 ret = nbt._bt_ctf_field_type_variant_get_tag_name(self._ft)
775
776 if ret is None:
777 raise TypeError("Could not get Variant tag name")
778
779 return ret
780
781 @property
782 def tag_type(self):
783 """
784 Get the variant's tag type.
785 """
786
787 ret = nbt._bt_ctf_field_type_variant_get_tag_type(self._ft)
788
789 if ret is None:
790 raise TypeError("Could not get Variant tag type")
791
792 return FieldDeclaration._create_field_declaration_from_native_instance(ret)
793
794 def add_field(self, field_type, field_name):
795 """
796 Add a field of type "field_type" to the variant.
797 """
798
799 ret = nbt._bt_ctf_field_type_variant_add_field(self._ft,
800 field_type._ft,
801 str(field_name))
802
803 if ret < 0:
804 raise ValueError("Could not add field to variant.")
805
806 @property
807 def fields(self):
808 """
809 Generator returning the variant's field as tuples of (field name, field declaration).
810 """
811
812 count = nbt._bt_ctf_field_type_variant_get_field_count(self._ft)
813
814 if count < 0:
815 raise TypeError("Could not get Variant field count")
816
817 for i in range(count):
818 field_name = nbt._bt_python_ctf_field_type_variant_get_field_name(self._ft, i)
819
820 if field_name is None:
821 msg = "Could not get Variant field name at index {}".format(i)
822 raise TypeError(msg)
823
824 field_type_native = nbt._bt_python_ctf_field_type_variant_get_field_type(self._ft, i)
825
826 if field_type_native is None:
827 msg = "Could not get Variant field type at index {}".format(i)
828 raise TypeError(msg)
829
830 field_type = FieldDeclaration._create_field_declaration_from_native_instance(field_type_native)
831 yield (field_name, field_type)
832
833 def get_field_by_name(self, name):
834 """
835 Get a field declaration by name (FieldDeclaration).
836 """
837
838 field_type_native = nbt._bt_ctf_field_type_variant_get_field_type_by_name(self._ft,
839 name)
840
841 if field_type_native is None:
842 msg = "Could not find Variant field with name {}".format(name)
843 raise TypeError(msg)
844
845 return FieldDeclaration._create_field_declaration_from_native_instance(field_type_native)
846
847 def get_field_from_tag(self, tag):
848 """
849 Get a field declaration from tag (EnumerationField).
850 """
851
852 field_type_native = nbt._bt_ctf_field_type_variant_get_field_type_from_tag(self._ft, tag._f)
853
854 if field_type_native is None:
855 msg = "Could not find Variant field with tag value {}".format(tag.value)
856 raise TypeError(msg)
857
858 return FieldDeclaration._create_field_declaration_from_native_instance(field_type_native)
859
860
861class ArrayFieldDeclaration(FieldDeclaration):
862 def __init__(self, element_type, length):
863 """
864 Create a new array field declaration.
865 """
866
867 self._ft = nbt._bt_ctf_field_type_array_create(element_type._ft,
868 length)
869 super().__init__()
870
871 @property
872 def element_type(self):
873 """
874 Get the array's element type.
875 """
876
877 ret = nbt._bt_ctf_field_type_array_get_element_type(self._ft)
878
879 if ret is None:
880 raise TypeError("Could not get Array element type")
881
882 return FieldDeclaration._create_field_declaration_from_native_instance(ret)
883
884 @property
885 def length(self):
886 """
887 Get the array's length.
888 """
889
890 ret = nbt._bt_ctf_field_type_array_get_length(self._ft)
891
892 if ret < 0:
893 raise TypeError("Could not get Array length")
894
895 return ret
896
897
898class SequenceFieldDeclaration(FieldDeclaration):
899 def __init__(self, element_type, length_field_name):
900 """
901 Create a new sequence field declaration.
902 """
903
904 self._ft = nbt._bt_ctf_field_type_sequence_create(element_type._ft,
905 str(length_field_name))
906 super().__init__()
907
908 @property
909 def element_type(self):
910 """
911 Get the sequence's element type.
912 """
913
914 ret = nbt._bt_ctf_field_type_sequence_get_element_type(self._ft)
915
916 if ret is None:
917 raise TypeError("Could not get Sequence element type")
918
919 return FieldDeclaration._create_field_declaration_from_native_instance(ret)
920
921 @property
922 def length_field_name(self):
923 """
924 Get the sequence's length field name.
925 """
926
927 ret = nbt._bt_ctf_field_type_sequence_get_length_field_name(self._ft)
928
929 if ret is None:
930 raise TypeError("Could not get Sequence length field name")
931
932 return ret
933
934
935class StringFieldDeclaration(FieldDeclaration):
936 def __init__(self):
937 """
938 Create a new string field declaration.
939 """
940
941 self._ft = nbt._bt_ctf_field_type_string_create()
942 super().__init__()
943
944 @property
945 def encoding(self):
946 """
947 Get a string declaration's encoding (a constant from the CTFStringEncoding class).
948 """
949
950 return nbt._bt_ctf_field_type_string_get_encoding(self._ft)
951
952 @encoding.setter
953 def encoding(self, encoding):
954 """
955 Set a string declaration's encoding. Must be a constant from the CTFStringEncoding class.
956 """
957
958 ret = nbt._bt_ctf_field_type_string_set_encoding(self._ft, encoding)
959 if ret < 0:
960 raise ValueError("Could not set string encoding.")
961
962
963@staticmethod
964def create_field(field_type):
965 """
966 Create an instance of a field.
967 """
968 isinst = isinstance(field_type, FieldDeclaration)
969
970 if field_type is None or not isinst:
971 raise TypeError("Invalid field_type. Type must be a FieldDeclaration-derived class.")
972
973 if isinstance(field_type, IntegerFieldDeclaration):
974 return IntegerField(field_type)
975 elif isinstance(field_type, EnumerationFieldDeclaration):
976 return EnumerationField(field_type)
977 elif isinstance(field_type, FloatFieldDeclaration):
978 return FloatingPointField(field_type)
979 elif isinstance(field_type, StructureFieldDeclaration):
980 return StructureField(field_type)
981 elif isinstance(field_type, VariantFieldDeclaration):
982 return VariantField(field_type)
983 elif isinstance(field_type, ArrayFieldDeclaration):
984 return ArrayField(field_type)
985 elif isinstance(field_type, SequenceFieldDeclaration):
986 return SequenceField(field_type)
987 elif isinstance(field_type, StringFieldDeclaration):
988 return StringField(field_type)
989
990
991class Field:
992 """
993 Base class, do not instantiate.
994 """
995
996 def __init__(self, field_type):
997 if not isinstance(field_type, FieldDeclaration):
998 raise TypeError("Invalid field_type argument.")
999
1000 self._f = nbt._bt_ctf_field_create(field_type._ft)
1001
1002 if self._f is None:
1003 raise ValueError("Field creation failed.")
1004
1005 def __del__(self):
1006 nbt._bt_ctf_field_put(self._f)
1007
1008 @staticmethod
1009 def _create_field_from_native_instance(native_field_instance):
1010 type_dict = {
1011 common.CTFTypeId.INTEGER: IntegerField,
1012 common.CTFTypeId.FLOAT: FloatingPointField,
1013 common.CTFTypeId.ENUM: EnumerationField,
1014 common.CTFTypeId.STRING: StringField,
1015 common.CTFTypeId.STRUCT: StructureField,
1016 common.CTFTypeId.VARIANT: VariantField,
1017 common.CTFTypeId.ARRAY: ArrayField,
1018 common.CTFTypeId.SEQUENCE: SequenceField
1019 }
1020
1021 field_type = nbt._bt_python_get_field_type(native_field_instance)
1022
1023 if field_type == common.CTFTypeId.UNKNOWN:
1024 raise TypeError("Invalid field instance")
1025
1026 field = Field.__new__(Field)
1027 field._f = native_field_instance
1028 field.__class__ = type_dict[field_type]
1029
1030 return field
1031
1032 @property
1033 def declaration(self):
1034 native_field_type = nbt._bt_ctf_field_get_type(self._f)
1035
1036 if native_field_type is None:
1037 raise TypeError("Invalid field instance")
1038 return FieldDeclaration._create_field_declaration_from_native_instance(
1039 native_field_type)
1040
1041
1042class IntegerField(Field):
1043 @property
1044 def value(self):
1045 """
1046 Get an integer field's value.
1047 """
1048
1049 signedness = nbt._bt_python_field_integer_get_signedness(self._f)
1050
1051 if signedness < 0:
1052 raise TypeError("Invalid integer instance.")
1053
1054 if signedness == 0:
1055 ret, value = nbt._bt_ctf_field_unsigned_integer_get_value(self._f)
1056 else:
1057 ret, value = nbt._bt_ctf_field_signed_integer_get_value(self._f)
1058
1059 if ret < 0:
1060 raise ValueError("Could not get integer field value.")
1061
1062 return value
1063
1064 @value.setter
1065 def value(self, value):
1066 """
1067 Set an integer field's value.
1068 """
1069
1070 if not isinstance(value, int):
1071 raise TypeError("IntegerField's value must be an int")
1072
1073 signedness = nbt._bt_python_field_integer_get_signedness(self._f)
1074 if signedness < 0:
1075 raise TypeError("Invalid integer instance.")
1076
1077 if signedness == 0:
1078 ret = nbt._bt_ctf_field_unsigned_integer_set_value(self._f, value)
1079 else:
1080 ret = nbt._bt_ctf_field_signed_integer_set_value(self._f, value)
1081
1082 if ret < 0:
1083 raise ValueError("Could not set integer field value.")
1084
1085
1086class EnumerationField(Field):
1087 @property
1088 def container(self):
1089 """
1090 Return the enumeration's underlying container field (an integer field).
1091 """
1092
1093 container = IntegerField.__new__(IntegerField)
1094 container._f = nbt._bt_ctf_field_enumeration_get_container(self._f)
1095
1096 if container._f is None:
1097 raise TypeError("Invalid enumeration field type.")
1098
1099 return container
1100
1101 @property
1102 def value(self):
1103 """
1104 Get the enumeration field's mapping name.
1105 """
1106
1107 value = nbt._bt_ctf_field_enumeration_get_mapping_name(self._f)
1108
1109 if value is None:
1110 raise ValueError("Could not get enumeration's mapping name.")
1111
1112 return value
1113
1114 @value.setter
1115 def value(self, value):
1116 """
1117 Set the enumeration field's value. Must be an integer as mapping names
1118 may be ambiguous.
1119 """
1120
1121 if not isinstance(value, int):
1122 raise TypeError("EnumerationField value must be an int")
1123
1124 self.container.value = value
1125
1126
1127class FloatingPointField(Field):
1128 @property
1129 def value(self):
1130 """
1131 Get a floating point field's value.
1132 """
1133
1134 ret, value = nbt._bt_ctf_field_floating_point_get_value(self._f)
1135
1136 if ret < 0:
1137 raise ValueError("Could not get floating point field value.")
1138
1139 return value
1140
1141 @value.setter
1142 def value(self, value):
1143 """
1144 Set a floating point field's value.
1145 """
1146
1147 if not isinstance(value, int) and not isinstance(value, float):
1148 raise TypeError("Value must be either a float or an int")
1149
1150 ret = nbt._bt_ctf_field_floating_point_set_value(self._f, float(value))
1151
1152 if ret < 0:
1153 raise ValueError("Could not set floating point field value.")
1154
1155
1156# oops!! This class is provided to ensure backward-compatibility since
1157# a stable release publicly exposed this abomination.
1158class FloatFieldingPoint(FloatingPointField):
1159 pass
1160
1161
1162class StructureField(Field):
1163 def field(self, field_name):
1164 """
1165 Get the structure's field corresponding to the provided field name.
1166 """
1167
1168 native_instance = nbt._bt_ctf_field_structure_get_field(self._f,
1169 str(field_name))
1170
1171 if native_instance is None:
1172 raise ValueError("Invalid field_name provided.")
1173
1174 return Field._create_field_from_native_instance(native_instance)
1175
1176
1177class VariantField(Field):
1178 def field(self, tag):
1179 """
1180 Return the variant's selected field. The "tag" field is the selector enum field.
1181 """
1182
1183 native_instance = nbt._bt_ctf_field_variant_get_field(self._f, tag._f)
1184
1185 if native_instance is None:
1186 raise ValueError("Invalid tag provided.")
1187
1188 return Field._create_field_from_native_instance(native_instance)
1189
1190
1191class ArrayField(Field):
1192 def field(self, index):
1193 """
1194 Return the array's field at position "index".
1195 """
1196
1197 native_instance = nbt._bt_ctf_field_array_get_field(self._f, index)
1198
1199 if native_instance is None:
1200 raise IndexError("Invalid index provided.")
1201
1202 return Field._create_field_from_native_instance(native_instance)
1203
1204
1205class SequenceField(Field):
1206 @property
1207 def length(self):
1208 """
1209 Get the sequence's length field (IntegerField).
1210 """
1211
1212 native_instance = nbt._bt_ctf_field_sequence_get_length(self._f)
1213
1214 if native_instance is None:
1215 length = -1
1216
1217 return Field._create_field_from_native_instance(native_instance)
1218
1219 @length.setter
1220 def length(self, length_field):
1221 """
1222 Set the sequence's length field (IntegerField).
1223 """
1224
1225 if not isinstance(length_field, IntegerField):
1226 raise TypeError("Invalid length field.")
1227
1228 if length_field.declaration.signed:
1229 raise TypeError("Sequence field length must be unsigned")
1230
1231 ret = nbt._bt_ctf_field_sequence_set_length(self._f, length_field._f)
1232
1233 if ret < 0:
1234 raise ValueError("Could not set sequence length.")
1235
1236 def field(self, index):
1237 """
1238 Return the sequence's field at position "index".
1239 """
1240
1241 native_instance = nbt._bt_ctf_field_sequence_get_field(self._f, index)
1242
1243 if native_instance is None:
1244 raise ValueError("Could not get sequence element at index.")
1245
1246 return Field._create_field_from_native_instance(native_instance)
1247
1248
1249class StringField(Field):
1250 @property
1251 def value(self):
1252 """
1253 Get a string field's value.
1254 """
1255
1256 return nbt._bt_ctf_field_string_get_value(self._f)
1257
1258 @value.setter
1259 def value(self, value):
1260 """
1261 Set a string field's value.
1262 """
1263
1264 ret = nbt._bt_ctf_field_string_set_value(self._f, str(value))
1265
1266 if ret < 0:
1267 raise ValueError("Could not set string field value.")
1268
1269
1270class EventClass:
1271 def __init__(self, name):
1272 """
1273 Create a new event class of the given name.
1274 """
1275
1276 self._ec = nbt._bt_ctf_event_class_create(name)
1277
1278 if self._ec is None:
1279 raise ValueError("Event class creation failed.")
1280
1281 def __del__(self):
1282 nbt._bt_ctf_event_class_put(self._ec)
1283
1284 def add_field(self, field_type, field_name):
1285 """
1286 Add a field of type "field_type" to the event class.
1287 """
1288
1289 ret = nbt._bt_ctf_event_class_add_field(self._ec, field_type._ft,
1290 str(field_name))
1291
1292 if ret < 0:
1293 raise ValueError("Could not add field to event class.")
1294
1295 @property
1296 def name(self):
1297 """
1298 Get the event class' name.
1299 """
1300
1301 name = nbt._bt_ctf_event_class_get_name(self._ec)
1302
1303 if name is None:
1304 raise TypeError("Could not get EventClass name")
1305
1306 return name
1307
1308 @property
1309 def id(self):
1310 """
1311 Get the event class' id. Returns a negative value if unset.
1312 """
1313
1314 id = nbt._bt_ctf_event_class_get_id(self._ec)
1315
1316 if id < 0:
1317 raise TypeError("Could not get EventClass id")
1318
1319 return id
1320
1321 @id.setter
1322 def id(self, id):
1323 """
1324 Set the event class' id. Throws a TypeError if the event class
1325 is already registered to a stream class.
1326 """
1327
1328 ret = nbt._bt_ctf_event_class_set_id(self._ec, id)
1329
1330 if ret < 0:
1331 raise TypeError("Can't change an Event Class's id after it has been assigned to a stream class")
1332
1333 @property
1334 def stream_class(self):
1335 """
1336 Get the event class' stream class. Returns None if unset.
1337 """
1338 stream_class_native = nbt._bt_ctf_event_class_get_stream_class(self._ec)
1339
1340 if stream_class_native is None:
1341 return None
1342
1343 stream_class = StreamClass.__new__(StreamClass)
1344 stream_class._sc = stream_class_native
1345
1346 return stream_class
1347
1348 @property
1349 def fields(self):
1350 """
1351 Generator returning the event class' fields as tuples of (field name, field declaration).
1352 """
1353
1354 count = nbt._bt_ctf_event_class_get_field_count(self._ec)
1355
1356 if count < 0:
1357 raise TypeError("Could not get EventClass' field count")
1358
1359 for i in range(count):
1360 field_name = nbt._bt_python_ctf_event_class_get_field_name(self._ec, i)
1361
1362 if field_name is None:
1363 msg = "Could not get EventClass' field name at index {}".format(i)
1364 raise TypeError(msg)
1365
1366 field_type_native = nbt._bt_python_ctf_event_class_get_field_type(self._ec, i)
1367
1368 if field_type_native is None:
1369 msg = "Could not get EventClass' field type at index {}".format(i)
1370 raise TypeError(msg)
1371
1372 field_type = FieldDeclaration._create_field_declaration_from_native_instance(field_type_native)
1373 yield (field_name, field_type)
1374
1375 def get_field_by_name(self, name):
1376 """
1377 Get a field declaration by name (FieldDeclaration).
1378 """
1379
1380 field_type_native = nbt._bt_ctf_event_class_get_field_by_name(self._ec, name)
1381
1382 if field_type_native is None:
1383 msg = "Could not find EventClass field with name {}".format(name)
1384 raise TypeError(msg)
1385
1386 return FieldDeclaration._create_field_declaration_from_native_instance(field_type_native)
1387
1388
1389class Event:
1390 def __init__(self, event_class):
1391 """
1392 Create a new event of the given event class.
1393 """
1394
1395 if not isinstance(event_class, EventClass):
1396 raise TypeError("Invalid event_class argument.")
1397
1398 self._e = nbt._bt_ctf_event_create(event_class._ec)
1399
1400 if self._e is None:
1401 raise ValueError("Event creation failed.")
1402
1403 def __del__(self):
1404 nbt._bt_ctf_event_put(self._e)
1405
1406 @property
1407 def event_class(self):
1408 """
1409 Get the event's class.
1410 """
1411
1412 event_class_native = nbt._bt_ctf_event_get_class(self._e)
1413
1414 if event_class_native is None:
1415 return None
1416
1417 event_class = EventClass.__new__(EventClass)
1418 event_class._ec = event_class_native
1419
1420 return event_class
1421
1422 def clock(self):
1423 """
1424 Get a clock from event. Returns None if the event's class
1425 is not registered to a stream class.
1426 """
1427
1428 clock_instance = nbt._bt_ctf_event_get_clock(self._e)
1429
1430 if clock_instance is None:
1431 return None
1432
1433 clock = Clock.__new__(Clock)
1434 clock._c = clock_instance
1435
1436 return clock
1437
1438 def payload(self, field_name):
1439 """
1440 Get a field from event.
1441 """
1442
1443 native_instance = nbt._bt_ctf_event_get_payload(self._e,
1444 str(field_name))
1445
1446 if native_instance is None:
1447 raise ValueError("Could not get event payload.")
1448
1449 return Field._create_field_from_native_instance(native_instance)
1450
1451 def set_payload(self, field_name, value_field):
1452 """
1453 Set a manually created field as an event's payload.
1454 """
1455
1456 if not isinstance(value, Field):
1457 raise TypeError("Invalid value type.")
1458
1459 ret = nbt._bt_ctf_event_set_payload(self._e, str(field_name),
1460 value_field._f)
1461
1462 if ret < 0:
1463 raise ValueError("Could not set event field payload.")
1464
1465
1466class StreamClass:
1467 def __init__(self, name):
1468 """
1469 Create a new stream class of the given name.
1470 """
1471
1472 self._sc = nbt._bt_ctf_stream_class_create(name)
1473
1474 if self._sc is None:
1475 raise ValueError("Stream class creation failed.")
1476
1477 def __del__(self):
1478 nbt._bt_ctf_stream_class_put(self._sc)
1479
1480 @property
1481 def name(self):
1482 """
1483 Get a stream class' name.
1484 """
1485
1486 name = nbt._bt_ctf_stream_class_get_name(self._sc)
1487
1488 if name is None:
1489 raise TypeError("Could not get StreamClass name")
1490
1491 return name
1492
1493 @property
1494 def clock(self):
1495 """
1496 Get a stream class' clock.
1497 """
1498
1499 clock_instance = nbt._bt_ctf_stream_class_get_clock(self._sc)
1500
1501 if clock_instance is None:
1502 return None
1503
1504 clock = Clock.__new__(Clock)
1505 clock._c = clock_instance
1506
1507 return clock
1508
1509 @clock.setter
1510 def clock(self, clock):
1511 """
1512 Assign a clock to a stream class.
1513 """
1514
1515 if not isinstance(clock, Clock):
1516 raise TypeError("Invalid clock type.")
1517
1518 ret = nbt._bt_ctf_stream_class_set_clock(self._sc, clock._c)
1519
1520 if ret < 0:
1521 raise ValueError("Could not set stream class clock.")
1522
1523 @property
1524 def id(self):
1525 """
1526 Get a stream class' id.
1527 """
1528
1529 ret = nbt._bt_ctf_stream_class_get_id(self._sc)
1530
1531 if ret < 0:
1532 raise TypeError("Could not get StreamClass id")
1533
1534 return ret
1535
1536 @id.setter
1537 def id(self, id):
1538 """
1539 Assign an id to a stream class.
1540 """
1541
1542 ret = nbt._bt_ctf_stream_class_set_id(self._sc, id)
1543
1544 if ret < 0:
1545 raise TypeError("Could not set stream class id.")
1546
1547 @property
1548 def event_classes(self):
1549 """
1550 Generator returning the stream class' event classes.
1551 """
1552
1553 count = nbt._bt_ctf_stream_class_get_event_class_count(self._sc)
1554
1555 if count < 0:
1556 raise TypeError("Could not get StreamClass' event class count")
1557
1558 for i in range(count):
1559 event_class_native = nbt._bt_ctf_stream_class_get_event_class(self._sc, i)
1560
1561 if event_class_native is None:
1562 msg = "Could not get StreamClass' event class at index {}".format(i)
1563 raise TypeError(msg)
1564
1565 event_class = EventClass.__new__(EventClass)
1566 event_class._ec = event_class_native
1567 yield event_class
1568
1569 def add_event_class(self, event_class):
1570 """
1571 Add an event class to a stream class. New events can be added even after a
1572 stream has been instantiated and events have been appended. However, a stream
1573 will not accept events of a class that has not been added to the stream
1574 class beforehand.
1575 """
1576
1577 if not isinstance(event_class, EventClass):
1578 raise TypeError("Invalid event_class type.")
1579
1580 ret = nbt._bt_ctf_stream_class_add_event_class(self._sc,
1581 event_class._ec)
1582
1583 if ret < 0:
1584 raise ValueError("Could not add event class.")
1585
1586 @property
1587 def packet_context_type(self):
1588 """
1589 Get the StreamClass' packet context type (StructureFieldDeclaration)
1590 """
1591
1592 field_type_native = nbt._bt_ctf_stream_class_get_packet_context_type(self._sc)
1593
1594 if field_type_native is None:
1595 raise ValueError("Invalid StreamClass")
1596
1597 field_type = FieldDeclaration._create_field_declaration_from_native_instance(field_type_native)
1598
1599 return field_type
1600
1601 @packet_context_type.setter
1602 def packet_context_type(self, field_type):
1603 """
1604 Set a StreamClass' packet context type. Must be of type
1605 StructureFieldDeclaration.
1606 """
1607
1608 if not isinstance(field_type, StructureFieldDeclaration):
1609 raise TypeError("field_type argument must be of type StructureFieldDeclaration.")
1610
1611 ret = nbt._bt_ctf_stream_class_set_packet_context_type(self._sc,
1612 field_type._ft)
1613
1614 if ret < 0:
1615 raise ValueError("Failed to set packet context type.")
1616
1617
1618class Stream:
1619 def __init__(self):
1620 raise NotImplementedError("Stream cannot be instantiated; use Writer.create_stream()")
1621
1622 def __del__(self):
1623 nbt._bt_ctf_stream_put(self._s)
1624
1625 @property
1626 def discarded_events(self):
1627 """
1628 Get a stream's discarded event count.
1629 """
1630
1631 ret, count = nbt._bt_ctf_stream_get_discarded_events_count(self._s)
1632
1633 if ret < 0:
1634 raise ValueError("Could not get the stream's discarded events count")
1635
1636 return count
1637
1638 def append_discarded_events(self, event_count):
1639 """
1640 Increase the current packet's discarded event count.
1641 """
1642
1643 nbt._bt_ctf_stream_append_discarded_events(self._s, event_count)
1644
1645 def append_event(self, event):
1646 """
1647 Append "event" to the stream's current packet. The stream's associated clock
1648 will be sampled during this call. The event shall not be modified after
1649 being appended to a stream.
1650 """
1651
1652 ret = nbt._bt_ctf_stream_append_event(self._s, event._e)
1653
1654 if ret < 0:
1655 raise ValueError("Could not append event to stream.")
1656
1657 @property
1658 def packet_context(self):
1659 """
1660 Get a Stream's packet context field (a StructureField).
1661 """
1662
1663 native_field = nbt._bt_ctf_stream_get_packet_context(self._s)
1664
1665 if native_field is None:
1666 raise ValueError("Invalid Stream.")
1667
1668 return Field._create_field_from_native_instance(native_field)
1669
1670 @packet_context.setter
1671 def packet_context(self, field):
1672 """
1673 Set a Stream's packet context field (must be a StructureField).
1674 """
1675
1676 if not isinstance(field, StructureField):
1677 raise TypeError("Argument field must be of type StructureField")
1678
1679 ret = nbt._bt_ctf_stream_set_packet_context(self._s, field._f)
1680
1681 if ret < 0:
1682 raise ValueError("Invalid packet context field.")
1683
1684 def flush(self):
1685 """
1686 The stream's current packet's events will be flushed to disk. Events
1687 subsequently appended to the stream will be added to a new packet.
1688 """
1689
1690 ret = nbt._bt_ctf_stream_flush(self._s)
1691
1692 if ret < 0:
1693 raise ValueError("Could not flush stream.")
1694
1695
1696class Writer:
1697 def __init__(self, path):
1698 """
1699 Create a new writer that will produce a trace in the given path.
1700 """
1701
1702 self._w = nbt._bt_ctf_writer_create(path)
1703
1704 if self._w is None:
1705 raise ValueError("Writer creation failed.")
1706
1707 def __del__(self):
1708 nbt._bt_ctf_writer_put(self._w)
1709
1710 def create_stream(self, stream_class):
1711 """
1712 Create a new stream instance and register it to the writer.
1713 """
1714
1715 if not isinstance(stream_class, StreamClass):
1716 raise TypeError("Invalid stream_class type.")
1717
1718 stream = Stream.__new__(Stream)
1719 stream._s = nbt._bt_ctf_writer_create_stream(self._w, stream_class._sc)
1720
1721 return stream
1722
1723 def add_environment_field(self, name, value):
1724 """
1725 Add an environment field to the trace.
1726 """
1727
1728 ret = nbt._bt_ctf_writer_add_environment_field(self._w, str(name),
1729 str(value))
1730
1731 if ret < 0:
1732 raise ValueError("Could not add environment field to trace.")
1733
1734 def add_clock(self, clock):
1735 """
1736 Add a clock to the trace. Clocks assigned to stream classes must be
1737 registered to the writer.
1738 """
1739
1740 ret = nbt._bt_ctf_writer_add_clock(self._w, clock._c)
1741
1742 if ret < 0:
1743 raise ValueError("Could not add clock to Writer.")
1744
1745 @property
1746 def metadata(self):
1747 """
1748 Get the trace's TSDL meta-data.
1749 """
1750
1751 return nbt._bt_ctf_writer_get_metadata_string(self._w)
1752
1753 def flush_metadata(self):
1754 """
1755 Flush the trace's metadata to the metadata file.
1756 """
1757
1758 nbt._bt_ctf_writer_flush_metadata(self._w)
1759
1760 @property
1761 def byte_order(self):
1762 """
1763 Get the trace's byte order. Must be a constant from the ByteOrder
1764 class.
1765 """
1766
1767 raise NotImplementedError("Getter not implemented.")
1768
1769 @byte_order.setter
1770 def byte_order(self, byte_order):
1771 """
1772 Set the trace's byte order. Must be a constant from the ByteOrder
1773 class. Defaults to the host machine's endianness
1774 """
1775
1776 ret = nbt._bt_ctf_writer_set_byte_order(self._w, byte_order)
1777
1778 if ret < 0:
1779 raise ValueError("Could not set trace's byte order.")
This page took 0.087443 seconds and 4 git commands to generate.