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