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