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