Python: CTFWriter: FloatFieldingPoint -> FloatingPointField
[babeltrace.git] / bindings / python / bt.py
CommitLineData
6fd49698
PP
1# nativebt.i.in
2#
3# Babeltrace native interface Python module
4#
5# Copyright 2012-2015 EfficiOS Inc.
6#
7# Author: Danny Serres <danny.serres@efficios.com>
8# Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
9#
10# Permission is hereby granted, free of charge, to any person obtaining a copy
11# of this software and associated documentation files (the "Software"), to deal
12# in the Software without restriction, including without limitation the rights
13# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14# copies of the Software, and to permit persons to whom the Software is
15# furnished to do so, subject to the following conditions:
16#
17# The above copyright notice and this permission notice shall be included in
18# all copies or substantial portions of the Software.
19#
20# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26# SOFTWARE.
27
28import babeltrace.nativebt as nbt
29import collections
30import os
31from datetime import datetime
32from uuid import UUID
33
34
35class TraceCollection:
6fd49698
PP
36 """
37 The TraceCollection is the object that contains all currently opened traces.
38 """
39
40 def __init__(self):
41 self._tc = nbt._bt_context_create()
42
43 def __del__(self):
44 nbt._bt_context_put(self._tc)
45
46 def add_trace(self, path, format_str):
47 """
48 Add a trace by path to the TraceCollection.
49
50 Open a trace.
51
52 path is the path to the trace, it is not recursive.
53 If "path" is None, stream_list is used instead as a list
54 of mmap streams to open for the trace.
55
56 format is a string containing the format name in which the trace was
57 produced.
58
59 Return: the corresponding TraceHandle on success or None on error.
60 """
82839121
PP
61
62 ret = nbt._bt_context_add_trace(self._tc, path, format_str,
63 None, None, None)
64
6fd49698
PP
65 if ret < 0:
66 return None
67
68 th = TraceHandle.__new__(TraceHandle)
69 th._id = ret
70 th._trace_collection = self
82839121 71
6fd49698
PP
72 return th
73
74 def add_traces_recursive(self, path, format_str):
75 """
76 Open a trace recursively.
77
78 Find each trace present in the subdirectory starting from the given
79 path, and add them to the TraceCollection.
80
81 Return a dict of TraceHandle instances (the full path is the key).
82 Return None on error.
83 """
84
85 trace_handles = {}
6fd49698
PP
86 noTrace = True
87 error = False
88
89 for fullpath, dirs, files in os.walk(path):
90 if "metadata" in files:
91 trace_handle = self.add_trace(fullpath, format_str)
82839121 92
6fd49698
PP
93 if trace_handle is None:
94 error = True
95 continue
96
97 trace_handles[fullpath] = trace_handle
98 noTrace = False
99
100 if noTrace and error:
101 return None
82839121 102
6fd49698
PP
103 return trace_handles
104
105 def remove_trace(self, trace_handle):
106 """
107 Remove a trace from the TraceCollection.
108 Effectively closing the trace.
109 """
82839121 110
6fd49698
PP
111 try:
112 nbt._bt_context_remove_trace(self._tc, trace_handle._id)
113 except AttributeError:
82839121 114 raise TypeError("in remove_trace, argument 2 must be a TraceHandle instance")
6fd49698
PP
115
116 @property
117 def events(self):
118 """
119 Generator function to iterate over the events of open in the current
120 TraceCollection.
121
122 Due to limitations of the native Babeltrace API, only one event
123 may be "alive" at a time (i.e. a user should never store a copy
124 of the events returned by this function for ulterior use). Users
125 shall make sure to copy the information they need from an event
126 before accessing the next one.
127
128 Furthermore, event objects become invalid when the generator goes
129 out of scope as the underlying iterator will be reclaimed. Using an
130 event after the the generator has gone out of scope may result in a
131 crash or data corruption.
132 """
82839121 133
6fd49698
PP
134 begin_pos_ptr = nbt._bt_iter_pos()
135 end_pos_ptr = nbt._bt_iter_pos()
136 begin_pos_ptr.type = nbt.SEEK_BEGIN
137 end_pos_ptr.type = nbt.SEEK_LAST
138
139 for event in self._events(begin_pos_ptr, end_pos_ptr):
140 yield event
141
142 def events_timestamps(self, timestamp_begin, timestamp_end):
143 """
144 Generator function to iterate over the events of open in the current
145 TraceCollection from timestamp_begin to timestamp_end.
146 """
82839121 147
6fd49698
PP
148 begin_pos_ptr = nbt._bt_iter_pos()
149 end_pos_ptr = nbt._bt_iter_pos()
150 begin_pos_ptr.type = end_pos_ptr.type = nbt.SEEK_TIME
151 begin_pos_ptr.u.seek_time = timestamp_begin
152 end_pos_ptr.u.seek_time = timestamp_end
153
154 for event in self._events(begin_pos_ptr, end_pos_ptr):
155 yield event
156
157 @property
158 def timestamp_begin(self):
159 pos_ptr = nbt._bt_iter_pos()
160 pos_ptr.type = nbt.SEEK_BEGIN
82839121 161
6fd49698
PP
162 return self._timestamp_at_pos(pos_ptr)
163
164 @property
165 def timestamp_end(self):
166 pos_ptr = nbt._bt_iter_pos()
167 pos_ptr.type = nbt.SEEK_LAST
82839121 168
6fd49698
PP
169 return self._timestamp_at_pos(pos_ptr)
170
171 def _timestamp_at_pos(self, pos_ptr):
172 ctf_it_ptr = nbt._bt_ctf_iter_create(self._tc, pos_ptr, pos_ptr)
82839121 173
6fd49698 174 if ctf_it_ptr is None:
82839121
PP
175 raise NotImplementedError("Creation of multiple iterators is unsupported.")
176
6fd49698
PP
177 ev_ptr = nbt._bt_ctf_iter_read_event(ctf_it_ptr)
178 nbt._bt_ctf_iter_destroy(ctf_it_ptr)
82839121 179
6fd49698
PP
180 def _events(self, begin_pos_ptr, end_pos_ptr):
181 ctf_it_ptr = nbt._bt_ctf_iter_create(self._tc, begin_pos_ptr, end_pos_ptr)
82839121 182
6fd49698 183 if ctf_it_ptr is None:
82839121 184 raise NotImplementedError("Creation of multiple iterators is unsupported.")
6fd49698
PP
185
186 while True:
187 ev_ptr = nbt._bt_ctf_iter_read_event(ctf_it_ptr)
82839121 188
6fd49698
PP
189 if ev_ptr is None:
190 break
191
192 ev = Event.__new__(Event)
193 ev._e = ev_ptr
82839121 194
6fd49698
PP
195 try:
196 yield ev
197 except GeneratorExit:
198 break
199
200 ret = nbt._bt_iter_next(nbt._bt_ctf_get_iter(ctf_it_ptr))
82839121 201
6fd49698
PP
202 if ret != 0:
203 break
204
205 nbt._bt_ctf_iter_destroy(ctf_it_ptr)
206
207
208def print_format_list(babeltrace_file):
209 """
210 Print a list of available formats to file.
211
212 babeltrace_file must be a File instance opened in write mode.
213 """
82839121 214
6fd49698
PP
215 try:
216 if babeltrace_file._file is not None:
217 nbt._bt_print_format_list(babeltrace_file._file)
218 except AttributeError:
82839121 219 raise TypeError("in print_format_list, argument 1 must be a File instance")
6fd49698
PP
220
221
222# Based on enum bt_clock_type in clock-type.h
8f52f384 223class _ClockType:
6fd49698
PP
224 CLOCK_CYCLES = 0
225 CLOCK_REAL = 1
226
227
4cde866e 228class TraceHandle:
6fd49698
PP
229 """
230 The TraceHandle allows the user to manipulate a trace file directly.
231 It is a unique identifier representing a trace file.
232 Do not instantiate.
233 """
234
235 def __init__(self):
236 raise NotImplementedError("TraceHandle cannot be instantiated")
237
238 def __repr__(self):
239 return "Babeltrace TraceHandle: trace_id('{0}')".format(self._id)
240
241 @property
242 def id(self):
243 """Return the TraceHandle id."""
82839121 244
6fd49698
PP
245 return self._id
246
247 @property
248 def path(self):
249 """Return the path of a TraceHandle."""
82839121
PP
250
251 return nbt._bt_trace_handle_get_path(self._trace_collection._tc,
252 self._id)
6fd49698
PP
253
254 @property
255 def timestamp_begin(self):
256 """Return the creation time of the buffers of a trace."""
82839121
PP
257
258 return nbt._bt_trace_handle_get_timestamp_begin(self._trace_collection._tc,
259 self._id,
8f52f384 260 _ClockType.CLOCK_REAL)
6fd49698
PP
261
262 @property
263 def timestamp_end(self):
264 """Return the destruction timestamp of the buffers of a trace."""
82839121
PP
265
266 return nbt._bt_trace_handle_get_timestamp_end(self._trace_collection._tc,
267 self._id,
8f52f384 268 _ClockType.CLOCK_REAL)
6fd49698
PP
269
270 @property
271 def events(self):
272 """
273 Generator returning all events (EventDeclaration) in a trace.
274 """
82839121
PP
275
276 ret = nbt._bt_python_event_decl_listcaller(self.id,
277 self._trace_collection._tc)
6fd49698
PP
278
279 if not isinstance(ret, list):
280 return
281
282 ptr_list, count = ret
82839121 283
6fd49698
PP
284 for i in range(count):
285 tmp = EventDeclaration.__new__(EventDeclaration)
286 tmp._ed = nbt._bt_python_decl_one_from_list(ptr_list, i)
287 yield tmp
288
289
290class CTFStringEncoding:
291 NONE = 0
292 UTF8 = 1
293 ASCII = 2
294 UNKNOWN = 3
295
296
297# Based on the enum in ctf-writer/writer.h
298class ByteOrder:
299 BYTE_ORDER_NATIVE = 0
300 BYTE_ORDER_LITTLE_ENDIAN = 1
301 BYTE_ORDER_BIG_ENDIAN = 2
302 BYTE_ORDER_NETWORK = 3
303 BYTE_ORDER_UNKNOWN = 4 # Python-specific entry
304
305
306# enum equivalent, accessible constants
307# These are taken directly from ctf/events.h
308# All changes to enums must also be made here
309class CTFTypeId:
310 UNKNOWN = 0
311 INTEGER = 1
312 FLOAT = 2
313 ENUM = 3
314 STRING = 4
315 STRUCT = 5
316 UNTAGGED_VARIANT = 6
317 VARIANT = 7
318 ARRAY = 8
319 SEQUENCE = 9
320 NR_CTF_TYPES = 10
321
322 def type_name(id):
323 name = "UNKNOWN_TYPE"
324 constants = [
325 attr for attr in dir(CTFTypeId) if not callable(
326 getattr(
327 CTFTypeId,
328 attr)) and not attr.startswith("__")]
82839121 329
6fd49698
PP
330 for attr in constants:
331 if getattr(CTFTypeId, attr) == id:
332 name = attr
333 break
82839121 334
6fd49698
PP
335 return name
336
337
338class CTFScope:
339 TRACE_PACKET_HEADER = 0
340 STREAM_PACKET_CONTEXT = 1
341 STREAM_EVENT_HEADER = 2
342 STREAM_EVENT_CONTEXT = 3
343 EVENT_CONTEXT = 4
344 EVENT_FIELDS = 5
345
346 def scope_name(scope):
347 name = "UNKNOWN_SCOPE"
348 constants = [
349 attr for attr in dir(CTFScope) if not callable(
350 getattr(
351 CTFScope,
352 attr)) and not attr.startswith("__")]
82839121 353
6fd49698
PP
354 for attr in constants:
355 if getattr(CTFScope, attr) == scope:
356 name = attr
357 break
82839121 358
6fd49698
PP
359 return name
360
361
362# Priority of the scopes when searching for event fields
82839121
PP
363_scopes = [
364 CTFScope.EVENT_FIELDS,
365 CTFScope.EVENT_CONTEXT,
366 CTFScope.STREAM_EVENT_CONTEXT,
367 CTFScope.STREAM_EVENT_HEADER,
368 CTFScope.STREAM_PACKET_CONTEXT,
369 CTFScope.TRACE_PACKET_HEADER
370]
6fd49698
PP
371
372
373class Event(collections.Mapping):
6fd49698
PP
374 """
375 This class represents an event from the trace.
376 It is obtained using the TraceCollection generator functions.
377 Do not instantiate.
378 """
379
380 def __init__(self):
381 raise NotImplementedError("Event cannot be instantiated")
382
383 @property
384 def name(self):
385 """Return the name of the event or None on error."""
82839121 386
6fd49698
PP
387 return nbt._bt_ctf_event_name(self._e)
388
389 @property
390 def cycles(self):
391 """
392 Return the timestamp of the event as written in
393 the packet (in cycles) or -1ULL on error.
394 """
82839121 395
6fd49698
PP
396 return nbt._bt_ctf_get_cycles(self._e)
397
398 @property
399 def timestamp(self):
400 """
401 Return the timestamp of the event offset with the
402 system clock source or -1ULL on error.
403 """
82839121 404
6fd49698
PP
405 return nbt._bt_ctf_get_timestamp(self._e)
406
407 @property
408 def datetime(self):
409 """
410 Return a datetime object based on the event's
411 timestamp. Note that the datetime class' precision
412 is limited to microseconds.
413 """
82839121 414
6fd49698
PP
415 return datetime.fromtimestamp(self.timestamp / 1E9)
416
417 def field_with_scope(self, field_name, scope):
418 """
419 Get field_name's value in scope.
420 None is returned if no field matches field_name.
421 """
82839121
PP
422
423 if scope not in _scopes:
6fd49698 424 raise ValueError("Invalid scope provided")
82839121 425
6fd49698 426 field = self._field_with_scope(field_name, scope)
82839121 427
6fd49698
PP
428 if field is not None:
429 return field.value
82839121 430
6fd49698
PP
431 def field_list_with_scope(self, scope):
432 """Return a list of field names in scope."""
82839121
PP
433
434 if scope not in _scopes:
6fd49698 435 raise ValueError("Invalid scope provided")
82839121 436
6fd49698 437 field_names = []
82839121 438
6fd49698
PP
439 for field in self._field_list_with_scope(scope):
440 field_names.append(field.name)
82839121 441
6fd49698
PP
442 return field_names
443
444 @property
445 def handle(self):
446 """
447 Get the TraceHandle associated with this event
448 Return None on error
449 """
82839121 450
6fd49698 451 ret = nbt._bt_ctf_event_get_handle_id(self._e)
82839121 452
6fd49698
PP
453 if ret < 0:
454 return None
455
456 th = TraceHandle.__new__(TraceHandle)
457 th._id = ret
458 th._trace_collection = self.get_trace_collection()
82839121 459
6fd49698
PP
460 return th
461
462 @property
463 def trace_collection(self):
464 """
465 Get the TraceCollection associated with this event.
466 Return None on error.
467 """
82839121 468
6fd49698
PP
469 trace_collection = TraceCollection()
470 trace_collection._tc = nbt._bt_ctf_event_get_context(self._e)
82839121 471
decd548b 472 if trace_collection._tc is not None:
6fd49698
PP
473 return trace_collection
474
475 def __getitem__(self, field_name):
476 """
477 Get field_name's value. If the field_name exists in multiple
478 scopes, the first field found is returned. The scopes are searched
479 in the following order:
480 1) EVENT_FIELDS
481 2) EVENT_CONTEXT
482 3) STREAM_EVENT_CONTEXT
483 4) STREAM_EVENT_HEADER
484 5) STREAM_PACKET_CONTEXT
485 6) TRACE_PACKET_HEADER
486 None is returned if no field matches field_name.
487
488 Use field_with_scope() to explicitly access fields in a given
489 scope.
490 """
82839121 491
6fd49698 492 field = self._field(field_name)
82839121 493
6fd49698
PP
494 if field is not None:
495 return field.value
82839121 496
6fd49698
PP
497 raise KeyError(field_name)
498
499 def __iter__(self):
500 for key in self.keys():
501 yield key
502
503 def __len__(self):
504 count = 0
82839121 505
6fd49698
PP
506 for scope in _scopes:
507 scope_ptr = nbt._bt_ctf_get_top_level_scope(self._e, scope)
508 ret = nbt._bt_python_field_listcaller(self._e, scope_ptr)
82839121 509
6fd49698
PP
510 if isinstance(ret, list):
511 count += ret[1]
82839121 512
6fd49698
PP
513 return count
514
515 def __contains__(self, field_name):
516 return self._field(field_name) is not None
517
518 def keys(self):
519 """Return a list of field names."""
82839121 520
6fd49698 521 field_names = set()
82839121 522
6fd49698
PP
523 for scope in _scopes:
524 for name in self.field_list_with_scope(scope):
525 field_names.add(name)
82839121 526
6fd49698
PP
527 return list(field_names)
528
529 def get(self, field_name, default=None):
530 field = self._field(field_name)
82839121 531
6fd49698
PP
532 if field is None:
533 return default
82839121 534
6fd49698
PP
535 return field.value
536
537 def items(self):
538 for field in self.keys():
539 yield (field, self[field])
540
541 def _field_with_scope(self, field_name, scope):
542 scope_ptr = nbt._bt_ctf_get_top_level_scope(self._e, scope)
82839121 543
6fd49698
PP
544 if scope_ptr is None:
545 return None
546
547 definition_ptr = nbt._bt_ctf_get_field(self._e, scope_ptr, field_name)
82839121 548
6fd49698
PP
549 if definition_ptr is None:
550 return None
551
552 field = _Definition(definition_ptr, scope)
82839121 553
6fd49698
PP
554 return field
555
556 def _field(self, field_name):
557 field = None
82839121 558
6fd49698
PP
559 for scope in _scopes:
560 field = self._field_with_scope(field_name, scope)
82839121 561
6fd49698
PP
562 if field is not None:
563 break
82839121 564
6fd49698
PP
565 return field
566
567 def _field_list_with_scope(self, scope):
568 fields = []
569 scope_ptr = nbt._bt_ctf_get_top_level_scope(self._e, scope)
570
571 # Returns a list [list_ptr, count]. If list_ptr is NULL, SWIG will only
572 # provide the "count" return value
573 count = 0
574 list_ptr = None
575 ret = nbt._bt_python_field_listcaller(self._e, scope_ptr)
82839121 576
6fd49698
PP
577 if isinstance(ret, list):
578 list_ptr, count = ret
579
580 for i in range(count):
581 definition_ptr = nbt._bt_python_field_one_from_list(list_ptr, i)
82839121 582
6fd49698
PP
583 if definition_ptr is not None:
584 definition = _Definition(definition_ptr, scope)
585 fields.append(definition)
82839121 586
6fd49698
PP
587 return fields
588
589
590class FieldError(Exception):
6fd49698
PP
591 def __init__(self, value):
592 self.value = value
593
594 def __str__(self):
595 return repr(self.value)
596
597
4cde866e 598class EventDeclaration:
6fd49698 599 """Event declaration class. Do not instantiate."""
82839121 600
6fd49698
PP
601 MAX_UINT64 = 0xFFFFFFFFFFFFFFFF
602
603 def __init__(self):
604 raise NotImplementedError("EventDeclaration cannot be instantiated")
605
606 @property
607 def name(self):
608 """Return the name of the event or None on error"""
82839121 609
6fd49698
PP
610 return nbt._bt_ctf_get_decl_event_name(self._ed)
611
612 @property
613 def id(self):
614 """Return the event-ID of the event or -1 on error"""
82839121 615
6fd49698 616 id = nbt._bt_ctf_get_decl_event_id(self._ed)
82839121 617
6fd49698
PP
618 if id == self.MAX_UINT64:
619 id = -1
82839121 620
6fd49698
PP
621 return id
622
623 @property
624 def fields(self):
625 """
626 Generator returning all FieldDeclarations of an event, going through
627 each scope in the following order:
628 1) EVENT_FIELDS
629 2) EVENT_CONTEXT
630 3) STREAM_EVENT_CONTEXT
631 4) STREAM_EVENT_HEADER
632 5) STREAM_PACKET_CONTEXT
633 6) TRACE_PACKET_HEADER
634 """
82839121 635
6fd49698
PP
636 for scope in _scopes:
637 for declaration in self.fields_scope(scope):
638 yield declaration
639
640 def fields_scope(self, scope):
641 """
642 Generator returning FieldDeclarations of the current event in scope.
643 """
644 ret = nbt._by_python_field_decl_listcaller(self._ed, scope)
645
646 if not isinstance(ret, list):
647 return
648
649 list_ptr, count = ret
82839121 650
6fd49698 651 for i in range(count):
82839121
PP
652 field_decl_ptr = nbt._bt_python_field_decl_one_from_list(list_ptr, i)
653
654 if field_decl_ptr is not None:
655 decl_ptr = nbt._bt_ctf_get_decl_from_field_decl(field_decl_ptr)
656 name = nbt._bt_ctf_get_decl_field_name(field_decl_ptr)
657 field_declaration = _create_field_declaration(decl_ptr, name,
658 scope)
6fd49698
PP
659 yield field_declaration
660
661
4cde866e 662class FieldDeclaration:
6fd49698
PP
663 """Field declaration class. Do not instantiate."""
664
665 def __init__(self):
666 raise NotImplementedError("FieldDeclaration cannot be instantiated")
667
668 def __repr__(self):
82839121
PP
669 return "({0}) {1} {2}".format(CTFScope.scope_name(self.scope),
670 CTFTypeId.type_name(self.type),
671 self.name)
6fd49698
PP
672
673 @property
674 def name(self):
675 """Return the name of a FieldDeclaration or None on error."""
82839121 676
6fd49698
PP
677 return self._name
678
679 @property
680 def type(self):
681 """
682 Return the FieldDeclaration's type. One of the entries in class
683 CTFTypeId.
684 """
82839121 685
6fd49698
PP
686 return nbt._bt_ctf_field_type(self._fd)
687
688 @property
689 def scope(self):
690 """
691 Return the FieldDeclaration's scope.
692 """
82839121 693
6fd49698
PP
694 return self._s
695
696
697class IntegerFieldDeclaration(FieldDeclaration):
6fd49698
PP
698 """Do not instantiate."""
699
700 def __init__(self):
82839121 701 raise NotImplementedError("IntegerFieldDeclaration cannot be instantiated")
6fd49698
PP
702
703 @property
704 def signedness(self):
705 """
706 Return the signedness of an integer:
707 0 if unsigned; 1 if signed; -1 on error.
708 """
82839121 709
6fd49698
PP
710 return nbt._bt_ctf_get_int_signedness(self._fd)
711
712 @property
713 def base(self):
714 """Return the base of an int or a negative value on error."""
82839121 715
6fd49698
PP
716 return nbt._bt_ctf_get_int_base(self._fd)
717
718 @property
719 def byte_order(self):
720 """
721 Return the byte order. One of class ByteOrder's entries.
722 """
82839121 723
6fd49698 724 ret = nbt._bt_ctf_get_int_byte_order(self._fd)
82839121 725
6fd49698
PP
726 if ret == 1234:
727 return ByteOrder.BYTE_ORDER_LITTLE_ENDIAN
728 elif ret == 4321:
729 return ByteOrder.BYTE_ORDER_BIG_ENDIAN
730 else:
731 return ByteOrder.BYTE_ORDER_UNKNOWN
732
733 @property
734 def length(self):
735 """
736 Return the size, in bits, of an int or a negative
737 value on error.
738 """
82839121 739
6fd49698
PP
740 return nbt._bt_ctf_get_int_len(self._fd)
741
742 @property
743 def encoding(self):
744 """
745 Return the encoding. One of class CTFStringEncoding's entries.
746 Return a negative value on error.
747 """
82839121 748
6fd49698
PP
749 return nbt._bt_ctf_get_encoding(self._fd)
750
751
752class EnumerationFieldDeclaration(FieldDeclaration):
6fd49698
PP
753 """Do not instantiate."""
754
755 def __init__(self):
82839121 756 raise NotImplementedError("EnumerationFieldDeclaration cannot be instantiated")
6fd49698
PP
757
758
759class ArrayFieldDeclaration(FieldDeclaration):
6fd49698
PP
760 """Do not instantiate."""
761
762 def __init__(self):
82839121 763 raise NotImplementedError("ArrayFieldDeclaration cannot be instantiated")
6fd49698
PP
764
765 @property
766 def length(self):
767 """
768 Return the length of an array or a negative
769 value on error.
770 """
82839121 771
6fd49698
PP
772 return nbt._bt_ctf_get_array_len(self._fd)
773
774 @property
775 def element_declaration(self):
776 """
777 Return element declaration.
778 """
82839121 779
6fd49698 780 field_decl_ptr = nbt._bt_python_get_array_element_declaration(self._fd)
82839121 781
6fd49698
PP
782 return _create_field_declaration(field_decl_ptr, "", self.scope)
783
784
785class SequenceFieldDeclaration(FieldDeclaration):
6fd49698
PP
786 """Do not instantiate."""
787
788 def __init__(self):
82839121 789 raise NotImplementedError("SequenceFieldDeclaration cannot be instantiated")
6fd49698
PP
790
791 @property
792 def element_declaration(self):
793 """
794 Return element declaration.
795 """
82839121 796
6fd49698 797 field_decl_ptr = nbt._bt_python_get_sequence_element_declaration(self._fd)
82839121 798
6fd49698
PP
799 return _create_field_declaration(field_decl_ptr, "", self.scope)
800
801
802class FloatFieldDeclaration(FieldDeclaration):
6fd49698
PP
803 """Do not instantiate."""
804
805 def __init__(self):
82839121 806 raise NotImplementedError("FloatFieldDeclaration cannot be instantiated")
6fd49698
PP
807
808
809class StructureFieldDeclaration(FieldDeclaration):
6fd49698
PP
810 """Do not instantiate."""
811
812 def __init__(self):
82839121 813 raise NotImplementedError("StructureFieldDeclaration cannot be instantiated")
6fd49698
PP
814
815
816class StringFieldDeclaration(FieldDeclaration):
6fd49698
PP
817 """Do not instantiate."""
818
819 def __init__(self):
82839121 820 raise NotImplementedError("StringFieldDeclaration cannot be instantiated")
6fd49698
PP
821
822
823class VariantFieldDeclaration(FieldDeclaration):
6fd49698
PP
824 """Do not instantiate."""
825
826 def __init__(self):
82839121 827 raise NotImplementedError("VariantFieldDeclaration cannot be instantiated")
6fd49698
PP
828
829
830def field_error():
831 """
832 Return the last error code encountered while
833 accessing a field and reset the error flag.
834 Return 0 if no error, a negative value otherwise.
835 """
82839121 836
6fd49698
PP
837 return nbt._bt_ctf_field_get_error()
838
839
840def _create_field_declaration(declaration_ptr, name, scope):
841 """
842 Private field declaration factory.
843 """
82839121 844
6fd49698
PP
845 if declaration_ptr is None:
846 raise ValueError("declaration_ptr must be valid")
82839121 847 if scope not in _scopes:
6fd49698
PP
848 raise ValueError("Invalid scope provided")
849
850 type = nbt._bt_ctf_field_type(declaration_ptr)
851 declaration = None
82839121 852
6fd49698
PP
853 if type == CTFTypeId.INTEGER:
854 declaration = IntegerFieldDeclaration.__new__(IntegerFieldDeclaration)
855 elif type == CTFTypeId.ENUM:
82839121 856 declaration = EnumerationFieldDeclaration.__new__(EnumerationFieldDeclaration)
6fd49698
PP
857 elif type == CTFTypeId.ARRAY:
858 declaration = ArrayFieldDeclaration.__new__(ArrayFieldDeclaration)
859 elif type == CTFTypeId.SEQUENCE:
82839121 860 declaration = SequenceFieldDeclaration.__new__(SequenceFieldDeclaration)
6fd49698
PP
861 elif type == CTFTypeId.FLOAT:
862 declaration = FloatFieldDeclaration.__new__(FloatFieldDeclaration)
863 elif type == CTFTypeId.STRUCT:
82839121 864 declaration = StructureFieldDeclaration.__new__(StructureFieldDeclaration)
6fd49698
PP
865 elif type == CTFTypeId.STRING:
866 declaration = StringFieldDeclaration.__new__(StringFieldDeclaration)
867 elif type == CTFTypeId.VARIANT:
868 declaration = VariantFieldDeclaration.__new__(VariantFieldDeclaration)
869 else:
870 return declaration
871
872 declaration._fd = declaration_ptr
873 declaration._s = scope
874 declaration._name = name
82839121 875
6fd49698
PP
876 return declaration
877
878
4cde866e 879class _Definition:
6fd49698
PP
880 def __init__(self, definition_ptr, scope):
881 self._d = definition_ptr
882 self._s = scope
82839121
PP
883
884 if scope not in _scopes:
6fd49698
PP
885 ValueError("Invalid scope provided")
886
887 @property
888 def name(self):
889 """Return the name of a field or None on error."""
82839121 890
6fd49698
PP
891 return nbt._bt_ctf_field_name(self._d)
892
893 @property
894 def type(self):
895 """Return the type of a field or -1 if unknown."""
82839121 896
6fd49698
PP
897 return nbt._bt_ctf_field_type(nbt._bt_ctf_get_decl_from_def(self._d))
898
899 @property
900 def declaration(self):
901 """Return the associated Definition object."""
82839121 902
6fd49698
PP
903 return _create_field_declaration(
904 nbt._bt_ctf_get_decl_from_def(self._d), self.name, self.scope)
905
906 def _get_enum_str(self):
907 """
908 Return the string matching the current enumeration.
909 Return None on error.
910 """
82839121 911
6fd49698
PP
912 return nbt._bt_ctf_get_enum_str(self._d)
913
914 def _get_array_element_at(self, index):
915 """
916 Return the array's element at position index.
917 Return None on error
918 """
82839121 919
6fd49698 920 array_ptr = nbt._bt_python_get_array_from_def(self._d)
82839121 921
6fd49698
PP
922 if array_ptr is None:
923 return None
924
925 definition_ptr = nbt._bt_array_index(array_ptr, index)
82839121 926
6fd49698
PP
927 if definition_ptr is None:
928 return None
82839121 929
6fd49698
PP
930 return _Definition(definition_ptr, self.scope)
931
932 def _get_sequence_len(self):
933 """
934 Return the len of a sequence or a negative
935 value on error.
936 """
82839121 937
6fd49698 938 seq = nbt._bt_python_get_sequence_from_def(self._d)
82839121 939
6fd49698
PP
940 return nbt._bt_sequence_len(seq)
941
942 def _get_sequence_element_at(self, index):
943 """
944 Return the sequence's element at position index,
945 otherwise return None
946 """
82839121 947
6fd49698 948 seq = nbt._bt_python_get_sequence_from_def(self._d)
82839121 949
6fd49698
PP
950 if seq is not None:
951 definition_ptr = nbt._bt_sequence_index(seq, index)
82839121 952
6fd49698
PP
953 if definition_ptr is not None:
954 return _Definition(definition_ptr, self.scope)
82839121 955
6fd49698
PP
956 def _get_uint64(self):
957 """
958 Return the value associated with the field.
959 If the field does not exist or is not of the type requested,
960 the value returned is undefined. To check if an error occured,
961 use the field_error() function after accessing a field.
962 """
82839121 963
6fd49698
PP
964 return nbt._bt_ctf_get_uint64(self._d)
965
966 def _get_int64(self):
967 """
968 Return the value associated with the field.
969 If the field does not exist or is not of the type requested,
970 the value returned is undefined. To check if an error occured,
971 use the field_error() function after accessing a field.
972 """
82839121 973
6fd49698
PP
974 return nbt._bt_ctf_get_int64(self._d)
975
976 def _get_char_array(self):
977 """
978 Return the value associated with the field.
979 If the field does not exist or is not of the type requested,
980 the value returned is undefined. To check if an error occurred,
981 use the field_error() function after accessing a field.
982 """
82839121 983
6fd49698
PP
984 return nbt._bt_ctf_get_char_array(self._d)
985
986 def _get_str(self):
987 """
988 Return the value associated with the field.
989 If the field does not exist or is not of the type requested,
990 the value returned is undefined. To check if an error occurred,
991 use the field_error() function after accessing a field.
992 """
82839121 993
6fd49698
PP
994 return nbt._bt_ctf_get_string(self._d)
995
996 def _get_float(self):
997 """
998 Return the value associated with the field.
999 If the field does not exist or is not of the type requested,
1000 the value returned is undefined. To check if an error occurred,
1001 use the field_error() function after accessing a field.
1002 """
82839121 1003
6fd49698
PP
1004 return nbt._bt_ctf_get_float(self._d)
1005
1006 def _get_variant(self):
1007 """
1008 Return the variant's selected field.
1009 If the field does not exist or is not of the type requested,
1010 the value returned is undefined. To check if an error occurred,
1011 use the field_error() function after accessing a field.
1012 """
82839121 1013
6fd49698
PP
1014 return nbt._bt_ctf_get_variant(self._d)
1015
1016 def _get_struct_field_count(self):
1017 """
1018 Return the number of fields contained in the structure.
1019 If the field does not exist or is not of the type requested,
1020 the value returned is undefined.
1021 """
82839121 1022
6fd49698
PP
1023 return nbt._bt_ctf_get_struct_field_count(self._d)
1024
1025 def _get_struct_field_at(self, i):
1026 """
1027 Return the structure's field at position i.
1028 If the field does not exist or is not of the type requested,
1029 the value returned is undefined. To check if an error occurred,
1030 use the field_error() function after accessing a field.
1031 """
82839121 1032
6fd49698
PP
1033 return nbt._bt_ctf_get_struct_field_index(self._d, i)
1034
1035 @property
1036 def value(self):
1037 """
1038 Return the value associated with the field according to its type.
1039 Return None on error.
1040 """
82839121 1041
6fd49698
PP
1042 id = self.type
1043 value = None
1044
1045 if id == CTFTypeId.STRING:
1046 value = self._get_str()
1047 elif id == CTFTypeId.ARRAY:
1048 element_decl = self.declaration.element_declaration
82839121 1049
6fd49698
PP
1050 if ((element_decl.type == CTFTypeId.INTEGER
1051 and element_decl.length == 8)
1052 and (element_decl.encoding == CTFStringEncoding.ASCII or element_decl.encoding == CTFStringEncoding.UTF8)):
1053 value = nbt._bt_python_get_array_string(self._d)
1054 else:
1055 value = []
82839121 1056
6fd49698
PP
1057 for i in range(self.declaration.length):
1058 element = self._get_array_element_at(i)
1059 value.append(element.value)
1060 elif id == CTFTypeId.INTEGER:
1061 if self.declaration.signedness == 0:
1062 value = self._get_uint64()
1063 else:
1064 value = self._get_int64()
1065 elif id == CTFTypeId.ENUM:
1066 value = self._get_enum_str()
1067 elif id == CTFTypeId.SEQUENCE:
1068 element_decl = self.declaration.element_declaration
82839121 1069
6fd49698
PP
1070 if ((element_decl.type == CTFTypeId.INTEGER
1071 and element_decl.length == 8)
1072 and (element_decl.encoding == CTFStringEncoding.ASCII or element_decl.encoding == CTFStringEncoding.UTF8)):
1073 value = nbt._bt_python_get_sequence_string(self._d)
1074 else:
1075 seq_len = self._get_sequence_len()
1076 value = []
82839121 1077
6fd49698
PP
1078 for i in range(seq_len):
1079 evDef = self._get_sequence_element_at(i)
1080 value.append(evDef.value)
1081 elif id == CTFTypeId.FLOAT:
1082 value = self._get_float()
1083 elif id == CTFTypeId.VARIANT:
1084 variant = _Definition.__new__(_Definition)
1085 variant._d = self._get_variant()
1086 value = variant.value
1087 elif id == CTFTypeId.STRUCT:
1088 value = {}
82839121 1089
6fd49698
PP
1090 for i in range(self._get_struct_field_count()):
1091 member = _Definition(self._get_struct_field_at(i), self.scope)
1092 value[member.name] = member.value
1093
1094 if field_error():
1095 raise FieldError(
1096 "Error occurred while accessing field {} of type {}".format(
1097 self.name,
1098 CTFTypeId.type_name(id)))
82839121 1099
6fd49698
PP
1100 return value
1101
1102 @property
1103 def scope(self):
1104 """Return the scope of a field or None on error."""
82839121 1105
6fd49698
PP
1106 return self._s
1107
1108
1109class CTFWriter:
1110 # Used to compare to -1ULL in error checks
1111 _MAX_UINT64 = 0xFFFFFFFFFFFFFFFF
1112
6fd49698 1113 class EnumerationMapping:
82839121
PP
1114 """
1115 Enumeration mapping class. start and end values are inclusive.
1116 """
6fd49698
PP
1117
1118 def __init__(self, name, start, end):
1119 self.name = name
1120 self.start = start
1121 self.end = end
1122
1123 class Clock:
6fd49698
PP
1124 def __init__(self, name):
1125 self._c = nbt._bt_ctf_clock_create(name)
82839121 1126
6fd49698
PP
1127 if self._c is None:
1128 raise ValueError("Invalid clock name.")
1129
1130 def __del__(self):
1131 nbt._bt_ctf_clock_put(self._c)
1132
6fd49698
PP
1133 @property
1134 def name(self):
82839121
PP
1135 """
1136 Get the clock's name.
1137 """
1138
6fd49698 1139 name = nbt._bt_ctf_clock_get_name(self._c)
82839121 1140
6fd49698
PP
1141 if name is None:
1142 raise ValueError("Invalid clock instance.")
82839121 1143
6fd49698
PP
1144 return name
1145
6fd49698
PP
1146 @property
1147 def description(self):
82839121
PP
1148 """
1149 Get the clock's description. None if unset.
1150 """
1151
6fd49698
PP
1152 return nbt._bt_ctf_clock_get_description(self._c)
1153
6fd49698
PP
1154 @description.setter
1155 def description(self, desc):
82839121
PP
1156 """
1157 Set the clock's description. The description appears in the clock's TSDL
1158 meta-data.
1159 """
1160
6fd49698 1161 ret = nbt._bt_ctf_clock_set_description(self._c, str(desc))
82839121 1162
6fd49698
PP
1163 if ret < 0:
1164 raise ValueError("Invalid clock description.")
1165
6fd49698
PP
1166 @property
1167 def frequency(self):
82839121
PP
1168 """
1169 Get the clock's frequency (Hz).
1170 """
1171
6fd49698 1172 freq = nbt._bt_ctf_clock_get_frequency(self._c)
82839121 1173
6fd49698
PP
1174 if freq == CTFWriter._MAX_UINT64:
1175 raise ValueError("Invalid clock instance")
82839121 1176
6fd49698
PP
1177 return freq
1178
6fd49698
PP
1179 @frequency.setter
1180 def frequency(self, freq):
82839121
PP
1181 """
1182 Set the clock's frequency (Hz).
1183 """
1184
6fd49698 1185 ret = nbt._bt_ctf_clock_set_frequency(self._c, freq)
82839121 1186
6fd49698
PP
1187 if ret < 0:
1188 raise ValueError("Invalid frequency value.")
1189
6fd49698
PP
1190 @property
1191 def precision(self):
82839121
PP
1192 """
1193 Get the clock's precision (in clock ticks).
1194 """
1195
6fd49698 1196 precision = nbt._bt_ctf_clock_get_precision(self._c)
82839121 1197
6fd49698
PP
1198 if precision == CTFWriter._MAX_UINT64:
1199 raise ValueError("Invalid clock instance")
82839121 1200
6fd49698
PP
1201 return precision
1202
6fd49698
PP
1203 @precision.setter
1204 def precision(self, precision):
82839121
PP
1205 """
1206 Set the clock's precision (in clock ticks).
1207 """
1208
6fd49698
PP
1209 ret = nbt._bt_ctf_clock_set_precision(self._c, precision)
1210
6fd49698
PP
1211 @property
1212 def offset_seconds(self):
82839121
PP
1213 """
1214 Get the clock's offset in seconds from POSIX.1 Epoch.
1215 """
1216
6fd49698 1217 offset_s = nbt._bt_ctf_clock_get_offset_s(self._c)
82839121 1218
6fd49698
PP
1219 if offset_s == CTFWriter._MAX_UINT64:
1220 raise ValueError("Invalid clock instance")
82839121 1221
6fd49698
PP
1222 return offset_s
1223
6fd49698
PP
1224 @offset_seconds.setter
1225 def offset_seconds(self, offset_s):
82839121
PP
1226 """
1227 Set the clock's offset in seconds from POSIX.1 Epoch.
1228 """
1229
6fd49698 1230 ret = nbt._bt_ctf_clock_set_offset_s(self._c, offset_s)
82839121 1231
6fd49698
PP
1232 if ret < 0:
1233 raise ValueError("Invalid offset value.")
1234
6fd49698
PP
1235 @property
1236 def offset(self):
82839121
PP
1237 """
1238 Get the clock's offset in ticks from POSIX.1 Epoch + offset in seconds.
1239 """
1240
6fd49698 1241 offset = nbt._bt_ctf_clock_get_offset(self._c)
82839121 1242
6fd49698
PP
1243 if offset == CTFWriter._MAX_UINT64:
1244 raise ValueError("Invalid clock instance")
82839121 1245
6fd49698
PP
1246 return offset
1247
6fd49698
PP
1248 @offset.setter
1249 def offset(self, offset):
82839121
PP
1250 """
1251 Set the clock's offset in ticks from POSIX.1 Epoch + offset in seconds.
1252 """
1253
6fd49698 1254 ret = nbt._bt_ctf_clock_set_offset(self._c, offset)
82839121 1255
6fd49698
PP
1256 if ret < 0:
1257 raise ValueError("Invalid offset value.")
1258
6fd49698
PP
1259 @property
1260 def absolute(self):
82839121
PP
1261 """
1262 Get a clock's absolute attribute. A clock is absolute if the clock
1263 is a global reference across the trace's other clocks.
1264 """
1265
6fd49698 1266 is_absolute = nbt._bt_ctf_clock_get_is_absolute(self._c)
82839121 1267
6fd49698
PP
1268 if is_absolute == -1:
1269 raise ValueError("Invalid clock instance")
82839121 1270
6fd49698
PP
1271 return False if is_absolute == 0 else True
1272
6fd49698
PP
1273 @absolute.setter
1274 def absolute(self, is_absolute):
82839121
PP
1275 """
1276 Set a clock's absolute attribute. A clock is absolute if the clock
1277 is a global reference across the trace's other clocks.
1278 """
1279
6fd49698 1280 ret = nbt._bt_ctf_clock_set_is_absolute(self._c, int(is_absolute))
82839121 1281
6fd49698 1282 if ret < 0:
82839121 1283 raise ValueError("Could not set the clock's absolute attribute.")
6fd49698 1284
6fd49698
PP
1285 @property
1286 def uuid(self):
82839121
PP
1287 """
1288 Get a clock's UUID (an object of type UUID).
1289 """
1290
6fd49698 1291 uuid_list = []
82839121 1292
6fd49698
PP
1293 for i in range(16):
1294 ret, value = nbt._bt_python_ctf_clock_get_uuid_index(self._c, i)
82839121 1295
6fd49698
PP
1296 if ret < 0:
1297 raise ValueError("Invalid clock instance")
82839121 1298
6fd49698 1299 uuid_list.append(value)
82839121 1300
6fd49698
PP
1301 return UUID(bytes=bytes(uuid_list))
1302
6fd49698
PP
1303 @uuid.setter
1304 def uuid(self, uuid):
82839121
PP
1305 """
1306 Set a clock's UUID (an object of type UUID).
1307 """
1308
6fd49698 1309 uuid_bytes = uuid.bytes
82839121 1310
6fd49698 1311 if len(uuid_bytes) != 16:
82839121
PP
1312 raise ValueError("Invalid UUID provided. UUID length must be 16 bytes")
1313
6fd49698 1314 for i in range(len(uuid_bytes)):
82839121
PP
1315 ret = nbt._bt_python_ctf_clock_set_uuid_index(self._c, i,
1316 uuid_bytes[i])
1317
6fd49698
PP
1318 if ret < 0:
1319 raise ValueError("Invalid clock instance")
1320
6fd49698
PP
1321 @property
1322 def time(self):
82839121
PP
1323 """
1324 Get the current time in nanoseconds since the clock's origin (offset and
1325 offset_s attributes).
1326 """
1327
6fd49698 1328 time = nbt._bt_ctf_clock_get_time(self._c)
82839121 1329
6fd49698
PP
1330 if time == CTFWriter._MAX_UINT64:
1331 raise ValueError("Invalid clock instance")
82839121 1332
6fd49698
PP
1333 return time
1334
6fd49698
PP
1335 @time.setter
1336 def time(self, time):
82839121
PP
1337 """
1338 Set the current time in nanoseconds since the clock's origin (offset and
1339 offset_s attributes). The clock's value will be sampled as events are
1340 appended to a stream.
1341 """
1342
6fd49698 1343 ret = nbt._bt_ctf_clock_set_time(self._c, time)
82839121 1344
6fd49698
PP
1345 if ret < 0:
1346 raise ValueError("Invalid time value.")
1347
1348 class FieldDeclaration:
6fd49698
PP
1349 """
1350 FieldDeclaration should not be instantiated directly. Instantiate
1351 one of the concrete FieldDeclaration classes.
1352 """
82839121 1353
6fd49698
PP
1354 class IntegerBase:
1355 # These values are based on the bt_ctf_integer_base enum
1356 # declared in event-types.h.
1357 INTEGER_BASE_UNKNOWN = -1
1358 INTEGER_BASE_BINARY = 2
1359 INTEGER_BASE_OCTAL = 8
1360 INTEGER_BASE_DECIMAL = 10
1361 INTEGER_BASE_HEXADECIMAL = 16
1362
1363 def __init__(self):
1364 if self._ft is None:
1365 raise ValueError("FieldDeclaration creation failed.")
1366
1367 def __del__(self):
1368 nbt._bt_ctf_field_type_put(self._ft)
1369
1370 @staticmethod
1371 def _create_field_declaration_from_native_instance(
1372 native_field_declaration):
1373 type_dict = {
1374 CTFTypeId.INTEGER: CTFWriter.IntegerFieldDeclaration,
1375 CTFTypeId.FLOAT: CTFWriter.FloatFieldDeclaration,
1376 CTFTypeId.ENUM: CTFWriter.EnumerationFieldDeclaration,
1377 CTFTypeId.STRING: CTFWriter.StringFieldDeclaration,
1378 CTFTypeId.STRUCT: CTFWriter.StructureFieldDeclaration,
1379 CTFTypeId.VARIANT: CTFWriter.VariantFieldDeclaration,
1380 CTFTypeId.ARRAY: CTFWriter.ArrayFieldDeclaration,
1381 CTFTypeId.SEQUENCE: CTFWriter.SequenceFieldDeclaration
1382 }
1383
82839121
PP
1384 field_type_id = nbt._bt_ctf_field_type_get_type_id(native_field_declaration)
1385
6fd49698
PP
1386 if field_type_id == CTFTypeId.UNKNOWN:
1387 raise TypeError("Invalid field instance")
1388
1389 declaration = CTFWriter.Field.__new__(CTFWriter.Field)
1390 declaration._ft = native_field_declaration
1391 declaration.__class__ = type_dict[field_type_id]
82839121 1392
6fd49698
PP
1393 return declaration
1394
6fd49698
PP
1395 @property
1396 def alignment(self):
82839121
PP
1397 """
1398 Get the field declaration's alignment. Returns -1 on error.
1399 """
1400
6fd49698
PP
1401 return nbt._bt_ctf_field_type_get_alignment(self._ft)
1402
6fd49698
PP
1403 @alignment.setter
1404 def alignment(self, alignment):
82839121
PP
1405 """
1406 Set the field declaration's alignment. Defaults to 1 (bit-aligned). However,
1407 some types, such as structures and string, may impose other alignment
1408 constraints.
1409 """
1410
6fd49698 1411 ret = nbt._bt_ctf_field_type_set_alignment(self._ft, alignment)
82839121 1412
6fd49698
PP
1413 if ret < 0:
1414 raise ValueError("Invalid alignment value.")
1415
6fd49698
PP
1416 @property
1417 def byte_order(self):
82839121
PP
1418 """
1419 Get the field declaration's byte order. One of the ByteOrder's constant.
1420 """
1421
6fd49698
PP
1422 return nbt._bt_ctf_field_type_get_byte_order(self._ft)
1423
6fd49698
PP
1424 @byte_order.setter
1425 def byte_order(self, byte_order):
82839121
PP
1426 """
1427 Set the field declaration's byte order. Use constants defined in the ByteOrder
1428 class.
1429 """
1430
6fd49698 1431 ret = nbt._bt_ctf_field_type_set_byte_order(self._ft, byte_order)
82839121 1432
6fd49698
PP
1433 if ret < 0:
1434 raise ValueError("Could not set byte order value.")
1435
1436 class IntegerFieldDeclaration(FieldDeclaration):
6fd49698 1437 def __init__(self, size):
82839121
PP
1438 """
1439 Create a new integer field declaration of the given size.
1440 """
6fd49698
PP
1441 self._ft = nbt._bt_ctf_field_type_integer_create(size)
1442 super().__init__()
1443
6fd49698
PP
1444 @property
1445 def size(self):
82839121
PP
1446 """
1447 Get an integer's size.
1448 """
1449
6fd49698 1450 ret = nbt._bt_ctf_field_type_integer_get_size(self._ft)
82839121 1451
6fd49698
PP
1452 if ret < 0:
1453 raise ValueError("Could not get Integer's size attribute.")
1454 else:
1455 return ret
1456
6fd49698
PP
1457 @property
1458 def signed(self):
82839121
PP
1459 """
1460 Get an integer's signedness attribute.
1461 """
1462
6fd49698 1463 ret = nbt._bt_ctf_field_type_integer_get_signed(self._ft)
82839121 1464
6fd49698
PP
1465 if ret < 0:
1466 raise ValueError("Could not get Integer's signed attribute.")
1467 elif ret > 0:
1468 return True
1469 else:
1470 return False
1471
6fd49698
PP
1472 @signed.setter
1473 def signed(self, signed):
82839121
PP
1474 """
1475 Set an integer's signedness attribute.
1476 """
1477
6fd49698 1478 ret = nbt._bt_ctf_field_type_integer_set_signed(self._ft, signed)
82839121 1479
6fd49698
PP
1480 if ret < 0:
1481 raise ValueError("Could not set Integer's signed attribute.")
1482
6fd49698
PP
1483 @property
1484 def base(self):
82839121
PP
1485 """
1486 Get the integer's base used to pretty-print the resulting trace.
1487 Returns a constant from the FieldDeclaration.IntegerBase class.
1488 """
1489
6fd49698
PP
1490 return nbt._bt_ctf_field_type_integer_get_base(self._ft)
1491
6fd49698
PP
1492 @base.setter
1493 def base(self, base):
82839121
PP
1494 """
1495 Set the integer's base used to pretty-print the resulting trace.
1496 The base must be a constant of the FieldDeclarationIntegerBase class.
1497 """
1498
6fd49698 1499 ret = nbt._bt_ctf_field_type_integer_set_base(self._ft, base)
82839121 1500
6fd49698
PP
1501 if ret < 0:
1502 raise ValueError("Could not set Integer's base.")
1503
6fd49698
PP
1504 @property
1505 def encoding(self):
82839121
PP
1506 """
1507 Get the integer's encoding (one of the constants of the
1508 CTFStringEncoding class).
1509 Returns a constant from the CTFStringEncoding class.
1510 """
1511
6fd49698
PP
1512 return nbt._bt_ctf_field_type_integer_get_encoding(self._ft)
1513
6fd49698
PP
1514 @encoding.setter
1515 def encoding(self, encoding):
82839121
PP
1516 """
1517 An integer encoding may be set to signal that the integer must be printed
1518 as a text character. Must be a constant from the CTFStringEncoding class.
1519 """
1520
6fd49698 1521 ret = nbt._bt_ctf_field_type_integer_set_encoding(self._ft, encoding)
82839121 1522
6fd49698
PP
1523 if ret < 0:
1524 raise ValueError("Could not set Integer's encoding.")
1525
1526 class EnumerationFieldDeclaration(FieldDeclaration):
6fd49698 1527 def __init__(self, integer_type):
82839121
PP
1528 """
1529 Create a new enumeration field declaration with the given underlying container type.
1530 """
1531 isinst = isinstance(integer_type, CTFWriter.IntegerFieldDeclaration)
1532
1533 if integer_type is None or not isinst:
6fd49698
PP
1534 raise TypeError("Invalid integer container.")
1535
1536 self._ft = nbt._bt_ctf_field_type_enumeration_create(integer_type._ft)
1537 super().__init__()
1538
6fd49698
PP
1539 @property
1540 def container(self):
82839121
PP
1541 """
1542 Get the enumeration's underlying container type.
1543 """
1544
6fd49698 1545 ret = nbt._bt_ctf_field_type_enumeration_get_container_type(self._ft)
82839121 1546
6fd49698
PP
1547 if ret is None:
1548 raise TypeError("Invalid enumeration declaration")
6fd49698 1549
82839121 1550 return CTFWriter.FieldDeclaration._create_field_declaration_from_native_instance(ret)
6fd49698
PP
1551
1552 def add_mapping(self, name, range_start, range_end):
82839121
PP
1553 """
1554 Add a mapping to the enumeration. The range's values are inclusive.
1555 """
1556
6fd49698 1557 if range_start < 0 or range_end < 0:
82839121
PP
1558 ret = nbt._bt_ctf_field_type_enumeration_add_mapping(self._ft,
1559 str(name),
1560 range_start,
1561 range_end)
6fd49698 1562 else:
82839121
PP
1563 ret = nbt._bt_ctf_field_type_enumeration_add_mapping_unsigned(self._ft,
1564 str(name),
1565 range_start,
1566 range_end)
6fd49698
PP
1567
1568 if ret < 0:
82839121 1569 raise ValueError("Could not add mapping to enumeration declaration.")
6fd49698 1570
6fd49698
PP
1571 @property
1572 def mappings(self):
82839121
PP
1573 """
1574 Generator returning instances of EnumerationMapping.
1575 """
1576
6fd49698
PP
1577 signed = self.container.signed
1578
1579 count = nbt._bt_ctf_field_type_enumeration_get_mapping_count(self._ft)
82839121 1580
6fd49698
PP
1581 for i in range(count):
1582 if signed:
82839121 1583 ret = nbt._bt_python_ctf_field_type_enumeration_get_mapping(self._ft, i)
6fd49698 1584 else:
82839121 1585 ret = nbt._bt_python_ctf_field_type_enumeration_get_mapping_unsigned(self._ft, i)
6fd49698
PP
1586
1587 if len(ret) != 3:
82839121
PP
1588 msg = "Could not get Enumeration mapping at index {}".format(i)
1589 raise TypeError(msg)
1590
6fd49698
PP
1591 name, range_start, range_end = ret
1592 yield CTFWriter.EnumerationMapping(name, range_start, range_end)
1593
6fd49698 1594 def get_mapping_by_name(self, name):
82839121
PP
1595 """
1596 Get a mapping by name (EnumerationMapping).
1597 """
1598
1599 index = nbt._bt_ctf_field_type_enumeration_get_mapping_index_by_name(self._ft, name)
1600
6fd49698
PP
1601 if index < 0:
1602 return None
1603
1604 if self.container.signed:
82839121 1605 ret = nbt._bt_python_ctf_field_type_enumeration_get_mapping(self._ft, index)
6fd49698 1606 else:
82839121 1607 ret = nbt._bt_python_ctf_field_type_enumeration_get_mapping_unsigned(self._ft, index)
6fd49698
PP
1608
1609 if len(ret) != 3:
82839121
PP
1610 msg = "Could not get Enumeration mapping at index {}".format(i)
1611 raise TypeError(msg)
1612
6fd49698 1613 name, range_start, range_end = ret
6fd49698 1614
82839121 1615 return CTFWriter.EnumerationMapping(name, range_start, range_end)
6fd49698
PP
1616
1617 def get_mapping_by_value(self, value):
82839121
PP
1618 """
1619 Get a mapping by value (EnumerationMapping).
1620 """
1621
6fd49698 1622 if value < 0:
82839121 1623 index = nbt._bt_ctf_field_type_enumeration_get_mapping_index_by_value(self._ft, value)
6fd49698 1624 else:
82839121 1625 index = nbt._bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value(self._ft, value)
6fd49698
PP
1626
1627 if index < 0:
1628 return None
1629
1630 if self.container.signed:
82839121 1631 ret = nbt._bt_python_ctf_field_type_enumeration_get_mapping(self._ft, index)
6fd49698 1632 else:
82839121 1633 ret = nbt._bt_python_ctf_field_type_enumeration_get_mapping_unsigned(self._ft, index)
6fd49698
PP
1634
1635 if len(ret) != 3:
82839121
PP
1636 msg = "Could not get Enumeration mapping at index {}".format(i)
1637 raise TypeError(msg)
1638
6fd49698 1639 name, range_start, range_end = ret
82839121 1640
6fd49698
PP
1641 return CTFWriter.EnumerationMapping(name, range_start, range_end)
1642
1643 class FloatFieldDeclaration(FieldDeclaration):
1644 FLT_EXP_DIG = 8
1645 DBL_EXP_DIG = 11
1646 FLT_MANT_DIG = 24
1647 DBL_MANT_DIG = 53
1648
6fd49698 1649 def __init__(self):
82839121
PP
1650 """
1651 Create a new floating point field declaration.
1652 """
1653
6fd49698
PP
1654 self._ft = nbt._bt_ctf_field_type_floating_point_create()
1655 super().__init__()
1656
6fd49698
PP
1657 @property
1658 def exponent_digits(self):
82839121
PP
1659 """
1660 Get the number of exponent digits used to store the floating point field.
1661 """
1662
1663 ret = nbt._bt_ctf_field_type_floating_point_get_exponent_digits(self._ft)
1664
6fd49698
PP
1665 if ret < 0:
1666 raise TypeError(
1667 "Could not get Floating point exponent digit count")
82839121 1668
6fd49698
PP
1669 return ret
1670
6fd49698
PP
1671 @exponent_digits.setter
1672 def exponent_digits(self, exponent_digits):
82839121
PP
1673 """
1674 Set the number of exponent digits to use to store the floating point field.
1675 The only values currently supported are FLT_EXP_DIG and DBL_EXP_DIG which
1676 are defined as constants of this class.
1677 """
1678
1679 ret = nbt._bt_ctf_field_type_floating_point_set_exponent_digits(self._ft,
1680 exponent_digits)
1681
6fd49698
PP
1682 if ret < 0:
1683 raise ValueError("Could not set exponent digit count.")
1684
6fd49698
PP
1685 @property
1686 def mantissa_digits(self):
82839121
PP
1687 """
1688 Get the number of mantissa digits used to store the floating point field.
1689 """
1690
1691 ret = nbt._bt_ctf_field_type_floating_point_get_mantissa_digits(self._ft)
1692
6fd49698 1693 if ret < 0:
82839121
PP
1694 raise TypeError("Could not get Floating point mantissa digit count")
1695
6fd49698
PP
1696 return ret
1697
6fd49698
PP
1698 @mantissa_digits.setter
1699 def mantissa_digits(self, mantissa_digits):
82839121
PP
1700 """
1701 Set the number of mantissa digits to use to store the floating point field.
1702 The only values currently supported are FLT_MANT_DIG and DBL_MANT_DIG which
1703 are defined as constants of this class.
1704 """
1705
1706 ret = nbt._bt_ctf_field_type_floating_point_set_mantissa_digits(self._ft,
1707 mantissa_digits)
1708
6fd49698
PP
1709 if ret < 0:
1710 raise ValueError("Could not set mantissa digit count.")
1711
1712 class StructureFieldDeclaration(FieldDeclaration):
6fd49698 1713 def __init__(self):
82839121
PP
1714 """
1715 Create a new structure field declaration.
1716 """
1717
6fd49698
PP
1718 self._ft = nbt._bt_ctf_field_type_structure_create()
1719 super().__init__()
1720
6fd49698 1721 def add_field(self, field_type, field_name):
82839121
PP
1722 """
1723 Add a field of type "field_type" to the structure.
1724 """
1725
1726 ret = nbt._bt_ctf_field_type_structure_add_field(self._ft,
1727 field_type._ft,
1728 str(field_name))
1729
6fd49698
PP
1730 if ret < 0:
1731 raise ValueError("Could not add field to structure.")
1732
6fd49698
PP
1733 @property
1734 def fields(self):
82839121
PP
1735 """
1736 Generator returning the structure's field as tuples of (field name, field declaration).
1737 """
1738
6fd49698 1739 count = nbt._bt_ctf_field_type_structure_get_field_count(self._ft)
82839121 1740
6fd49698
PP
1741 if count < 0:
1742 raise TypeError("Could not get Structure field count")
1743
1744 for i in range(count):
82839121
PP
1745 field_name = nbt._bt_python_ctf_field_type_structure_get_field_name(self._ft, i)
1746
6fd49698 1747 if field_name is None:
82839121
PP
1748 msg = "Could not get Structure field name at index {}".format(i)
1749 raise TypeError(msg)
1750
1751 field_type_native = nbt._bt_python_ctf_field_type_structure_get_field_type(self._ft, i)
6fd49698 1752
6fd49698 1753 if field_type_native is None:
82839121
PP
1754 msg = "Could not get Structure field type at index {}".format(i)
1755 raise TypeError(msg)
6fd49698 1756
82839121 1757 field_type = CTFWriter.FieldDeclaration._create_field_declaration_from_native_instance(field_type_native)
6fd49698
PP
1758 yield (field_name, field_type)
1759
6fd49698 1760 def get_field_by_name(self, name):
82839121
PP
1761 """
1762 Get a field declaration by name (FieldDeclaration).
1763 """
6fd49698 1764
82839121 1765 field_type_native = nbt._bt_ctf_field_type_structure_get_field_type_by_name(self._ft, name)
6fd49698 1766
82839121
PP
1767 if field_type_native is None:
1768 msg = "Could not find Structure field with name {}".format(name)
1769 raise TypeError(msg)
6fd49698 1770
82839121 1771 return CTFWriter.FieldDeclaration._create_field_declaration_from_native_instance(field_type_native)
6fd49698 1772
82839121 1773 class VariantFieldDeclaration(FieldDeclaration):
6fd49698 1774 def __init__(self, enum_tag, tag_name):
82839121
PP
1775 """
1776 Create a new variant field declaration.
1777 """
1778
1779 isinst = isinstance(enum_tag, CTFWriter.EnumerationFieldDeclaration)
1780 if enum_tag is None or not isinst:
1781 raise TypeError("Invalid tag type; must be of type EnumerationFieldDeclaration.")
6fd49698 1782
82839121
PP
1783 self._ft = nbt._bt_ctf_field_type_variant_create(enum_tag._ft,
1784 str(tag_name))
6fd49698
PP
1785 super().__init__()
1786
6fd49698
PP
1787 @property
1788 def tag_name(self):
82839121
PP
1789 """
1790 Get the variant's tag name.
1791 """
1792
6fd49698 1793 ret = nbt._bt_ctf_field_type_variant_get_tag_name(self._ft)
82839121 1794
6fd49698
PP
1795 if ret is None:
1796 raise TypeError("Could not get Variant tag name")
82839121 1797
6fd49698
PP
1798 return ret
1799
6fd49698
PP
1800 @property
1801 def tag_type(self):
82839121
PP
1802 """
1803 Get the variant's tag type.
1804 """
1805
6fd49698 1806 ret = nbt._bt_ctf_field_type_variant_get_tag_type(self._ft)
82839121 1807
6fd49698
PP
1808 if ret is None:
1809 raise TypeError("Could not get Variant tag type")
6fd49698 1810
82839121 1811 return CTFWriter.FieldDeclaration._create_field_declaration_from_native_instance(ret)
6fd49698
PP
1812
1813 def add_field(self, field_type, field_name):
82839121
PP
1814 """
1815 Add a field of type "field_type" to the variant.
1816 """
1817
1818 ret = nbt._bt_ctf_field_type_variant_add_field(self._ft,
1819 field_type._ft,
1820 str(field_name))
1821
6fd49698
PP
1822 if ret < 0:
1823 raise ValueError("Could not add field to variant.")
1824
6fd49698
PP
1825 @property
1826 def fields(self):
82839121
PP
1827 """
1828 Generator returning the variant's field as tuples of (field name, field declaration).
1829 """
1830
6fd49698 1831 count = nbt._bt_ctf_field_type_variant_get_field_count(self._ft)
82839121 1832
6fd49698
PP
1833 if count < 0:
1834 raise TypeError("Could not get Variant field count")
1835
1836 for i in range(count):
82839121
PP
1837 field_name = nbt._bt_python_ctf_field_type_variant_get_field_name(self._ft, i)
1838
6fd49698 1839 if field_name is None:
82839121
PP
1840 msg = "Could not get Variant field name at index {}".format(i)
1841 raise TypeError(msg)
1842
1843 field_type_native = nbt._bt_python_ctf_field_type_variant_get_field_type(self._ft, i)
6fd49698 1844
6fd49698 1845 if field_type_native is None:
82839121
PP
1846 msg = "Could not get Variant field type at index {}".format(i)
1847 raise TypeError(msg)
6fd49698 1848
82839121 1849 field_type = CTFWriter.FieldDeclaration._create_field_declaration_from_native_instance(field_type_native)
6fd49698
PP
1850 yield (field_name, field_type)
1851
6fd49698 1852 def get_field_by_name(self, name):
82839121
PP
1853 """
1854 Get a field declaration by name (FieldDeclaration).
1855 """
6fd49698 1856
82839121
PP
1857 field_type_native = nbt._bt_ctf_field_type_variant_get_field_type_by_name(self._ft,
1858 name)
6fd49698 1859
82839121
PP
1860 if field_type_native is None:
1861 msg = "Could not find Variant field with name {}".format(name)
1862 raise TypeError(msg)
1863
1864 return CTFWriter.FieldDeclaration._create_field_declaration_from_native_instance(field_type_native)
6fd49698
PP
1865
1866 def get_field_from_tag(self, tag):
82839121
PP
1867 """
1868 Get a field declaration from tag (EnumerationField).
1869 """
6fd49698 1870
82839121 1871 field_type_native = nbt._bt_ctf_field_type_variant_get_field_type_from_tag(self._ft, tag._f)
6fd49698 1872
82839121
PP
1873 if field_type_native is None:
1874 msg = "Could not find Variant field with tag value {}".format(tag.value)
1875 raise TypeError(msg)
6fd49698 1876
82839121 1877 return CTFWriter.FieldDeclaration._create_field_declaration_from_native_instance(field_type_native)
6fd49698 1878
82839121 1879 class ArrayFieldDeclaration(FieldDeclaration):
6fd49698 1880 def __init__(self, element_type, length):
82839121
PP
1881 """
1882 Create a new array field declaration.
1883 """
1884
1885 self._ft = nbt._bt_ctf_field_type_array_create(element_type._ft,
1886 length)
6fd49698
PP
1887 super().__init__()
1888
6fd49698
PP
1889 @property
1890 def element_type(self):
82839121
PP
1891 """
1892 Get the array's element type.
1893 """
1894
6fd49698 1895 ret = nbt._bt_ctf_field_type_array_get_element_type(self._ft)
82839121 1896
6fd49698
PP
1897 if ret is None:
1898 raise TypeError("Could not get Array element type")
6fd49698 1899
82839121
PP
1900 return CTFWriter.FieldDeclaration._create_field_declaration_from_native_instance(ret)
1901
6fd49698
PP
1902 @property
1903 def length(self):
82839121
PP
1904 """
1905 Get the array's length.
1906 """
1907
6fd49698 1908 ret = nbt._bt_ctf_field_type_array_get_length(self._ft)
82839121 1909
6fd49698
PP
1910 if ret < 0:
1911 raise TypeError("Could not get Array length")
82839121 1912
6fd49698
PP
1913 return ret
1914
1915 class SequenceFieldDeclaration(FieldDeclaration):
6fd49698 1916 def __init__(self, element_type, length_field_name):
82839121
PP
1917 """
1918 Create a new sequence field declaration.
1919 """
1920
1921 self._ft = nbt._bt_ctf_field_type_sequence_create(element_type._ft,
1922 str(length_field_name))
6fd49698
PP
1923 super().__init__()
1924
6fd49698
PP
1925 @property
1926 def element_type(self):
82839121
PP
1927 """
1928 Get the sequence's element type.
1929 """
1930
6fd49698 1931 ret = nbt._bt_ctf_field_type_sequence_get_element_type(self._ft)
82839121 1932
6fd49698
PP
1933 if ret is None:
1934 raise TypeError("Could not get Sequence element type")
6fd49698 1935
82839121
PP
1936 return CTFWriter.FieldDeclaration._create_field_declaration_from_native_instance(ret)
1937
6fd49698
PP
1938 @property
1939 def length_field_name(self):
82839121
PP
1940 """
1941 Get the sequence's length field name.
1942 """
1943
6fd49698 1944 ret = nbt._bt_ctf_field_type_sequence_get_length_field_name(self._ft)
82839121 1945
6fd49698
PP
1946 if ret is None:
1947 raise TypeError("Could not get Sequence length field name")
82839121 1948
6fd49698
PP
1949 return ret
1950
1951 class StringFieldDeclaration(FieldDeclaration):
6fd49698 1952 def __init__(self):
82839121
PP
1953 """
1954 Create a new string field declaration.
1955 """
1956
6fd49698
PP
1957 self._ft = nbt._bt_ctf_field_type_string_create()
1958 super().__init__()
1959
6fd49698
PP
1960 @property
1961 def encoding(self):
82839121
PP
1962 """
1963 Get a string declaration's encoding (a constant from the CTFStringEncoding class).
1964 """
1965
6fd49698
PP
1966 return nbt._bt_ctf_field_type_string_get_encoding(self._ft)
1967
6fd49698
PP
1968 @encoding.setter
1969 def encoding(self, encoding):
82839121
PP
1970 """
1971 Set a string declaration's encoding. Must be a constant from the CTFStringEncoding class.
1972 """
1973
6fd49698
PP
1974 ret = nbt._bt_ctf_field_type_string_set_encoding(self._ft, encoding)
1975 if ret < 0:
1976 raise ValueError("Could not set string encoding.")
1977
6fd49698
PP
1978 @staticmethod
1979 def create_field(field_type):
82839121
PP
1980 """
1981 Create an instance of a field.
1982 """
1983 isinst = isinstance(field_type, CTFWriter.FieldDeclaration)
1984
1985 if field_type is None or not isinst:
1986 raise TypeError("Invalid field_type. Type must be a FieldDeclaration-derived class.")
6fd49698
PP
1987
1988 if isinstance(field_type, CTFWriter.IntegerFieldDeclaration):
1989 return CTFWriter.IntegerField(field_type)
1990 elif isinstance(field_type, CTFWriter.EnumerationFieldDeclaration):
1991 return CTFWriter.EnumerationField(field_type)
1992 elif isinstance(field_type, CTFWriter.FloatFieldDeclaration):
60318a5f 1993 return CTFWriter.FloatingPointField(field_type)
6fd49698
PP
1994 elif isinstance(field_type, CTFWriter.StructureFieldDeclaration):
1995 return CTFWriter.StructureField(field_type)
1996 elif isinstance(field_type, CTFWriter.VariantFieldDeclaration):
1997 return CTFWriter.VariantField(field_type)
1998 elif isinstance(field_type, CTFWriter.ArrayFieldDeclaration):
1999 return CTFWriter.ArrayField(field_type)
2000 elif isinstance(field_type, CTFWriter.SequenceFieldDeclaration):
2001 return CTFWriter.SequenceField(field_type)
2002 elif isinstance(field_type, CTFWriter.StringFieldDeclaration):
2003 return CTFWriter.StringField(field_type)
2004
2005 class Field:
6fd49698
PP
2006 """
2007 Base class, do not instantiate.
2008 """
2009
2010 def __init__(self, field_type):
2011 if not isinstance(field_type, CTFWriter.FieldDeclaration):
2012 raise TypeError("Invalid field_type argument.")
2013
2014 self._f = nbt._bt_ctf_field_create(field_type._ft)
82839121 2015
6fd49698
PP
2016 if self._f is None:
2017 raise ValueError("Field creation failed.")
2018
2019 def __del__(self):
2020 nbt._bt_ctf_field_put(self._f)
2021
2022 @staticmethod
2023 def _create_field_from_native_instance(native_field_instance):
2024 type_dict = {
2025 CTFTypeId.INTEGER: CTFWriter.IntegerField,
60318a5f 2026 CTFTypeId.FLOAT: CTFWriter.FloatingPointField,
6fd49698
PP
2027 CTFTypeId.ENUM: CTFWriter.EnumerationField,
2028 CTFTypeId.STRING: CTFWriter.StringField,
2029 CTFTypeId.STRUCT: CTFWriter.StructureField,
2030 CTFTypeId.VARIANT: CTFWriter.VariantField,
2031 CTFTypeId.ARRAY: CTFWriter.ArrayField,
2032 CTFTypeId.SEQUENCE: CTFWriter.SequenceField
2033 }
2034
2035 field_type = nbt._bt_python_get_field_type(native_field_instance)
82839121 2036
6fd49698
PP
2037 if field_type == CTFTypeId.UNKNOWN:
2038 raise TypeError("Invalid field instance")
2039
2040 field = CTFWriter.Field.__new__(CTFWriter.Field)
2041 field._f = native_field_instance
2042 field.__class__ = type_dict[field_type]
82839121 2043
6fd49698
PP
2044 return field
2045
2046 @property
2047 def declaration(self):
2048 native_field_type = nbt._bt_ctf_field_get_type(self._f)
82839121 2049
6fd49698
PP
2050 if native_field_type is None:
2051 raise TypeError("Invalid field instance")
2052 return CTFWriter.FieldDeclaration._create_field_declaration_from_native_instance(
2053 native_field_type)
2054
2055 class IntegerField(Field):
6fd49698
PP
2056 @property
2057 def value(self):
82839121
PP
2058 """
2059 Get an integer field's value.
2060 """
2061
6fd49698 2062 signedness = nbt._bt_python_field_integer_get_signedness(self._f)
82839121 2063
6fd49698
PP
2064 if signedness < 0:
2065 raise TypeError("Invalid integer instance.")
2066
2067 if signedness == 0:
2068 ret, value = nbt._bt_ctf_field_unsigned_integer_get_value(self._f)
2069 else:
2070 ret, value = nbt._bt_ctf_field_signed_integer_get_value(self._f)
2071
2072 if ret < 0:
2073 raise ValueError("Could not get integer field value.")
82839121 2074
6fd49698
PP
2075 return value
2076
6fd49698
PP
2077 @value.setter
2078 def value(self, value):
82839121
PP
2079 """
2080 Set an integer field's value.
2081 """
2082
6fd49698
PP
2083 if not isinstance(value, int):
2084 raise TypeError("IntegerField's value must be an int")
2085
2086 signedness = nbt._bt_python_field_integer_get_signedness(self._f)
2087 if signedness < 0:
2088 raise TypeError("Invalid integer instance.")
2089
2090 if signedness == 0:
2091 ret = nbt._bt_ctf_field_unsigned_integer_set_value(self._f, value)
2092 else:
2093 ret = nbt._bt_ctf_field_signed_integer_set_value(self._f, value)
2094
2095 if ret < 0:
2096 raise ValueError("Could not set integer field value.")
2097
2098 class EnumerationField(Field):
6fd49698
PP
2099 @property
2100 def container(self):
82839121
PP
2101 """
2102 Return the enumeration's underlying container field (an integer field).
2103 """
2104
6fd49698
PP
2105 container = CTFWriter.IntegerField.__new__(CTFWriter.IntegerField)
2106 container._f = nbt._bt_ctf_field_enumeration_get_container(self._f)
82839121 2107
6fd49698
PP
2108 if container._f is None:
2109 raise TypeError("Invalid enumeration field type.")
82839121 2110
6fd49698
PP
2111 return container
2112
6fd49698
PP
2113 @property
2114 def value(self):
82839121
PP
2115 """
2116 Get the enumeration field's mapping name.
2117 """
2118
6fd49698 2119 value = nbt._bt_ctf_field_enumeration_get_mapping_name(self._f)
82839121 2120
6fd49698
PP
2121 if value is None:
2122 raise ValueError("Could not get enumeration's mapping name.")
82839121 2123
6fd49698
PP
2124 return value
2125
6fd49698
PP
2126 @value.setter
2127 def value(self, value):
82839121
PP
2128 """
2129 Set the enumeration field's value. Must be an integer as mapping names
2130 may be ambiguous.
2131 """
2132
6fd49698
PP
2133 if not isinstance(value, int):
2134 raise TypeError("EnumerationField value must be an int")
82839121 2135
6fd49698
PP
2136 self.container.value = value
2137
60318a5f 2138 class FloatingPointField(Field):
6fd49698
PP
2139 @property
2140 def value(self):
82839121
PP
2141 """
2142 Get a floating point field's value.
2143 """
2144
6fd49698 2145 ret, value = nbt._bt_ctf_field_floating_point_get_value(self._f)
82839121 2146
6fd49698
PP
2147 if ret < 0:
2148 raise ValueError("Could not get floating point field value.")
82839121 2149
6fd49698
PP
2150 return value
2151
6fd49698
PP
2152 @value.setter
2153 def value(self, value):
82839121
PP
2154 """
2155 Set a floating point field's value.
2156 """
2157
6fd49698
PP
2158 if not isinstance(value, int) and not isinstance(value, float):
2159 raise TypeError("Value must be either a float or an int")
2160
2161 ret = nbt._bt_ctf_field_floating_point_set_value(self._f, float(value))
82839121 2162
6fd49698
PP
2163 if ret < 0:
2164 raise ValueError("Could not set floating point field value.")
2165
60318a5f
PP
2166 # oops!! This class is provided to ensure backward-compatibility since
2167 # a stable release publicly exposed this abomination.
2168 class FloatFieldingPoint(FloatingPointField):
2169 pass
2170
6fd49698 2171 class StructureField(Field):
82839121
PP
2172 def field(self, field_name):
2173 """
2174 Get the structure's field corresponding to the provided field name.
2175 """
6fd49698 2176
82839121
PP
2177 native_instance = nbt._bt_ctf_field_structure_get_field(self._f,
2178 str(field_name))
6fd49698 2179
6fd49698
PP
2180 if native_instance is None:
2181 raise ValueError("Invalid field_name provided.")
6fd49698 2182
82839121 2183 return CTFWriter.Field._create_field_from_native_instance(native_instance)
6fd49698 2184
82839121 2185 class VariantField(Field):
6fd49698 2186 def field(self, tag):
82839121
PP
2187 """
2188 Return the variant's selected field. The "tag" field is the selector enum field.
2189 """
2190
6fd49698 2191 native_instance = nbt._bt_ctf_field_variant_get_field(self._f, tag._f)
82839121 2192
6fd49698
PP
2193 if native_instance is None:
2194 raise ValueError("Invalid tag provided.")
6fd49698 2195
82839121 2196 return CTFWriter.Field._create_field_from_native_instance(native_instance)
6fd49698 2197
82839121 2198 class ArrayField(Field):
6fd49698 2199 def field(self, index):
82839121
PP
2200 """
2201 Return the array's field at position "index".
2202 """
2203
6fd49698 2204 native_instance = nbt._bt_ctf_field_array_get_field(self._f, index)
82839121 2205
6fd49698
PP
2206 if native_instance is None:
2207 raise IndexError("Invalid index provided.")
6fd49698 2208
82839121 2209 return CTFWriter.Field._create_field_from_native_instance(native_instance)
6fd49698 2210
82839121 2211 class SequenceField(Field):
6fd49698
PP
2212 @property
2213 def length(self):
82839121
PP
2214 """
2215 Get the sequence's length field (IntegerField).
2216 """
2217
6fd49698 2218 native_instance = nbt._bt_ctf_field_sequence_get_length(self._f)
82839121 2219
6fd49698
PP
2220 if native_instance is None:
2221 length = -1
6fd49698 2222
82839121
PP
2223 return CTFWriter.Field._create_field_from_native_instance(native_instance)
2224
6fd49698
PP
2225 @length.setter
2226 def length(self, length_field):
82839121
PP
2227 """
2228 Set the sequence's length field (IntegerField).
2229 """
2230
6fd49698
PP
2231 if not isinstance(length_field, CTFWriter.IntegerField):
2232 raise TypeError("Invalid length field.")
82839121 2233
6fd49698
PP
2234 if length_field.declaration.signed:
2235 raise TypeError("Sequence field length must be unsigned")
82839121 2236
6fd49698 2237 ret = nbt._bt_ctf_field_sequence_set_length(self._f, length_field._f)
82839121 2238
6fd49698
PP
2239 if ret < 0:
2240 raise ValueError("Could not set sequence length.")
2241
6fd49698 2242 def field(self, index):
82839121
PP
2243 """
2244 Return the sequence's field at position "index".
2245 """
2246
6fd49698 2247 native_instance = nbt._bt_ctf_field_sequence_get_field(self._f, index)
82839121 2248
6fd49698
PP
2249 if native_instance is None:
2250 raise ValueError("Could not get sequence element at index.")
6fd49698 2251
82839121 2252 return CTFWriter.Field._create_field_from_native_instance(native_instance)
6fd49698 2253
82839121 2254 class StringField(Field):
6fd49698
PP
2255 @property
2256 def value(self):
82839121
PP
2257 """
2258 Get a string field's value.
2259 """
2260
6fd49698
PP
2261 return nbt._bt_ctf_field_string_get_value(self._f)
2262
6fd49698
PP
2263 @value.setter
2264 def value(self, value):
82839121
PP
2265 """
2266 Set a string field's value.
2267 """
2268
6fd49698 2269 ret = nbt._bt_ctf_field_string_set_value(self._f, str(value))
82839121 2270
6fd49698
PP
2271 if ret < 0:
2272 raise ValueError("Could not set string field value.")
2273
2274 class EventClass:
6fd49698 2275 def __init__(self, name):
82839121
PP
2276 """
2277 Create a new event class of the given name.
2278 """
2279
6fd49698 2280 self._ec = nbt._bt_ctf_event_class_create(name)
82839121 2281
6fd49698
PP
2282 if self._ec is None:
2283 raise ValueError("Event class creation failed.")
2284
2285 def __del__(self):
2286 nbt._bt_ctf_event_class_put(self._ec)
2287
6fd49698 2288 def add_field(self, field_type, field_name):
82839121
PP
2289 """
2290 Add a field of type "field_type" to the event class.
2291 """
2292
2293 ret = nbt._bt_ctf_event_class_add_field(self._ec, field_type._ft,
2294 str(field_name))
2295
6fd49698
PP
2296 if ret < 0:
2297 raise ValueError("Could not add field to event class.")
2298
6fd49698
PP
2299 @property
2300 def name(self):
82839121
PP
2301 """
2302 Get the event class' name.
2303 """
2304
6fd49698 2305 name = nbt._bt_ctf_event_class_get_name(self._ec)
82839121 2306
6fd49698
PP
2307 if name is None:
2308 raise TypeError("Could not get EventClass name")
82839121 2309
6fd49698
PP
2310 return name
2311
6fd49698
PP
2312 @property
2313 def id(self):
82839121
PP
2314 """
2315 Get the event class' id. Returns a negative value if unset.
2316 """
2317
6fd49698 2318 id = nbt._bt_ctf_event_class_get_id(self._ec)
82839121 2319
6fd49698
PP
2320 if id < 0:
2321 raise TypeError("Could not get EventClass id")
82839121 2322
6fd49698
PP
2323 return id
2324
6fd49698
PP
2325 @id.setter
2326 def id(self, id):
82839121
PP
2327 """
2328 Set the event class' id. Throws a TypeError if the event class
2329 is already registered to a stream class.
2330 """
2331
6fd49698 2332 ret = nbt._bt_ctf_event_class_set_id(self._ec, id)
82839121 2333
6fd49698 2334 if ret < 0:
82839121 2335 raise TypeError("Can't change an Event Class's id after it has been assigned to a stream class")
6fd49698 2336
6fd49698
PP
2337 @property
2338 def stream_class(self):
82839121
PP
2339 """
2340 Get the event class' stream class. Returns None if unset.
2341 """
2342 stream_class_native = nbt._bt_ctf_event_class_get_stream_class(self._ec)
2343
6fd49698
PP
2344 if stream_class_native is None:
2345 return None
82839121 2346
6fd49698
PP
2347 stream_class = CTFWriter.StreamClass.__new__(CTFWriter.StreamClass)
2348 stream_class._sc = stream_class_native
82839121 2349
6fd49698
PP
2350 return stream_class
2351
6fd49698
PP
2352 @property
2353 def fields(self):
82839121
PP
2354 """
2355 Generator returning the event class' fields as tuples of (field name, field declaration).
2356 """
2357
6fd49698 2358 count = nbt._bt_ctf_event_class_get_field_count(self._ec)
82839121 2359
6fd49698
PP
2360 if count < 0:
2361 raise TypeError("Could not get EventClass' field count")
2362
2363 for i in range(count):
82839121
PP
2364 field_name = nbt._bt_python_ctf_event_class_get_field_name(self._ec, i)
2365
6fd49698 2366 if field_name is None:
82839121
PP
2367 msg = "Could not get EventClass' field name at index {}".format(i)
2368 raise TypeError(msg)
2369
2370 field_type_native = nbt._bt_python_ctf_event_class_get_field_type(self._ec, i)
6fd49698 2371
6fd49698 2372 if field_type_native is None:
82839121
PP
2373 msg = "Could not get EventClass' field type at index {}".format(i)
2374 raise TypeError(msg)
6fd49698 2375
82839121 2376 field_type = CTFWriter.FieldDeclaration._create_field_declaration_from_native_instance(field_type_native)
6fd49698
PP
2377 yield (field_name, field_type)
2378
6fd49698 2379 def get_field_by_name(self, name):
82839121
PP
2380 """
2381 Get a field declaration by name (FieldDeclaration).
2382 """
6fd49698 2383
82839121 2384 field_type_native = nbt._bt_ctf_event_class_get_field_by_name(self._ec, name)
6fd49698 2385
82839121
PP
2386 if field_type_native is None:
2387 msg = "Could not find EventClass field with name {}".format(name)
2388 raise TypeError(msg)
6fd49698 2389
82839121
PP
2390 return CTFWriter.FieldDeclaration._create_field_declaration_from_native_instance(field_type_native)
2391
2392 class Event:
6fd49698 2393 def __init__(self, event_class):
82839121
PP
2394 """
2395 Create a new event of the given event class.
2396 """
2397
6fd49698
PP
2398 if not isinstance(event_class, CTFWriter.EventClass):
2399 raise TypeError("Invalid event_class argument.")
2400
2401 self._e = nbt._bt_ctf_event_create(event_class._ec)
82839121 2402
6fd49698
PP
2403 if self._e is None:
2404 raise ValueError("Event creation failed.")
2405
2406 def __del__(self):
2407 nbt._bt_ctf_event_put(self._e)
2408
6fd49698
PP
2409 @property
2410 def event_class(self):
82839121
PP
2411 """
2412 Get the event's class.
2413 """
2414
6fd49698 2415 event_class_native = nbt._bt_ctf_event_get_class(self._e)
82839121 2416
6fd49698
PP
2417 if event_class_native is None:
2418 return None
82839121 2419
6fd49698
PP
2420 event_class = CTFWriter.EventClass.__new__(CTFWriter.EventClass)
2421 event_class._ec = event_class_native
6fd49698 2422
82839121 2423 return event_class
6fd49698
PP
2424
2425 def clock(self):
82839121
PP
2426 """
2427 Get a clock from event. Returns None if the event's class
2428 is not registered to a stream class.
2429 """
2430
6fd49698 2431 clock_instance = nbt._bt_ctf_event_get_clock(self._e)
82839121 2432
6fd49698
PP
2433 if clock_instance is None:
2434 return None
82839121 2435
6fd49698
PP
2436 clock = CTFWriter.Clock.__new__(CTFWriter.Clock)
2437 clock._c = clock_instance
6fd49698 2438
82839121 2439 return clock
6fd49698
PP
2440
2441 def payload(self, field_name):
82839121
PP
2442 """
2443 Get a field from event.
2444 """
2445
2446 native_instance = nbt._bt_ctf_event_get_payload(self._e,
2447 str(field_name))
2448
6fd49698
PP
2449 if native_instance is None:
2450 raise ValueError("Could not get event payload.")
6fd49698 2451
82839121 2452 return CTFWriter.Field._create_field_from_native_instance(native_instance)
6fd49698
PP
2453
2454 def set_payload(self, field_name, value_field):
82839121
PP
2455 """
2456 Set a manually created field as an event's payload.
2457 """
2458
6fd49698
PP
2459 if not isinstance(value, CTFWriter.Field):
2460 raise TypeError("Invalid value type.")
82839121
PP
2461
2462 ret = nbt._bt_ctf_event_set_payload(self._e, str(field_name),
2463 value_field._f)
2464
6fd49698
PP
2465 if ret < 0:
2466 raise ValueError("Could not set event field payload.")
2467
2468 class StreamClass:
6fd49698 2469 def __init__(self, name):
82839121
PP
2470 """
2471 Create a new stream class of the given name.
2472 """
2473
6fd49698 2474 self._sc = nbt._bt_ctf_stream_class_create(name)
82839121 2475
6fd49698
PP
2476 if self._sc is None:
2477 raise ValueError("Stream class creation failed.")
2478
2479 def __del__(self):
2480 nbt._bt_ctf_stream_class_put(self._sc)
2481
6fd49698
PP
2482 @property
2483 def name(self):
82839121
PP
2484 """
2485 Get a stream class' name.
2486 """
2487
6fd49698 2488 name = nbt._bt_ctf_stream_class_get_name(self._sc)
82839121 2489
6fd49698
PP
2490 if name is None:
2491 raise TypeError("Could not get StreamClass name")
82839121 2492
6fd49698
PP
2493 return name
2494
6fd49698
PP
2495 @property
2496 def clock(self):
82839121
PP
2497 """
2498 Get a stream class' clock.
2499 """
2500
6fd49698 2501 clock_instance = nbt._bt_ctf_stream_class_get_clock(self._sc)
82839121 2502
6fd49698
PP
2503 if clock_instance is None:
2504 return None
82839121 2505
6fd49698
PP
2506 clock = CTFWriter.Clock.__new__(CTFWriter.Clock)
2507 clock._c = clock_instance
82839121 2508
6fd49698
PP
2509 return clock
2510
6fd49698
PP
2511 @clock.setter
2512 def clock(self, clock):
82839121
PP
2513 """
2514 Assign a clock to a stream class.
2515 """
2516
6fd49698
PP
2517 if not isinstance(clock, CTFWriter.Clock):
2518 raise TypeError("Invalid clock type.")
2519
2520 ret = nbt._bt_ctf_stream_class_set_clock(self._sc, clock._c)
82839121 2521
6fd49698
PP
2522 if ret < 0:
2523 raise ValueError("Could not set stream class clock.")
2524
6fd49698
PP
2525 @property
2526 def id(self):
82839121
PP
2527 """
2528 Get a stream class' id.
2529 """
2530
6fd49698 2531 ret = nbt._bt_ctf_stream_class_get_id(self._sc)
82839121 2532
6fd49698
PP
2533 if ret < 0:
2534 raise TypeError("Could not get StreamClass id")
82839121 2535
6fd49698
PP
2536 return ret
2537
6fd49698
PP
2538 @id.setter
2539 def id(self, id):
82839121
PP
2540 """
2541 Assign an id to a stream class.
2542 """
2543
6fd49698 2544 ret = nbt._bt_ctf_stream_class_set_id(self._sc, id)
82839121 2545
6fd49698
PP
2546 if ret < 0:
2547 raise TypeError("Could not set stream class id.")
2548
6fd49698
PP
2549 @property
2550 def event_classes(self):
82839121
PP
2551 """
2552 Generator returning the stream class' event classes.
2553 """
2554
6fd49698 2555 count = nbt._bt_ctf_stream_class_get_event_class_count(self._sc)
82839121 2556
6fd49698
PP
2557 if count < 0:
2558 raise TypeError("Could not get StreamClass' event class count")
2559
2560 for i in range(count):
82839121
PP
2561 event_class_native = nbt._bt_ctf_stream_class_get_event_class(self._sc, i)
2562
6fd49698 2563 if event_class_native is None:
82839121
PP
2564 msg = "Could not get StreamClass' event class at index {}".format(i)
2565 raise TypeError(msg)
6fd49698 2566
82839121 2567 event_class = CTFWriter.EventClass.__new__(CTFWriter.EventClass)
6fd49698
PP
2568 event_class._ec = event_class_native
2569 yield event_class
2570
6fd49698 2571 def add_event_class(self, event_class):
82839121
PP
2572 """
2573 Add an event class to a stream class. New events can be added even after a
2574 stream has been instantiated and events have been appended. However, a stream
2575 will not accept events of a class that has not been added to the stream
2576 class beforehand.
2577 """
2578
6fd49698
PP
2579 if not isinstance(event_class, CTFWriter.EventClass):
2580 raise TypeError("Invalid event_class type.")
2581
82839121
PP
2582 ret = nbt._bt_ctf_stream_class_add_event_class(self._sc,
2583 event_class._ec)
2584
6fd49698
PP
2585 if ret < 0:
2586 raise ValueError("Could not add event class.")
2587
6fd49698
PP
2588 @property
2589 def packet_context_type(self):
82839121
PP
2590 """
2591 Get the StreamClass' packet context type (StructureFieldDeclaration)
2592 """
2593
2594 field_type_native = nbt._bt_ctf_stream_class_get_packet_context_type(self._sc)
2595
6fd49698
PP
2596 if field_type_native is None:
2597 raise ValueError("Invalid StreamClass")
82839121
PP
2598
2599 field_type = CTFWriter.FieldDeclaration._create_field_declaration_from_native_instance(field_type_native)
2600
6fd49698
PP
2601 return field_type
2602
6fd49698
PP
2603 @packet_context_type.setter
2604 def packet_context_type(self, field_type):
82839121
PP
2605 """
2606 Set a StreamClass' packet context type. Must be of type
2607 StructureFieldDeclaration.
2608 """
2609
6fd49698 2610 if not isinstance(field_type, CTFWriter.StructureFieldDeclaration):
82839121
PP
2611 raise TypeError("field_type argument must be of type StructureFieldDeclaration.")
2612
2613 ret = nbt._bt_ctf_stream_class_set_packet_context_type(self._sc,
2614 field_type._ft)
2615
6fd49698
PP
2616 if ret < 0:
2617 raise ValueError("Failed to set packet context type.")
2618
2619 class Stream:
6fd49698 2620 def __init__(self, stream_class):
82839121
PP
2621 """
2622 Create a stream of the given class.
2623 """
2624
6fd49698 2625 if not isinstance(stream_class, CTFWriter.StreamClass):
82839121 2626 raise TypeError("Invalid stream_class argument must be of type StreamClass.")
6fd49698
PP
2627
2628 self._s = nbt._bt_ctf_stream_create(stream_class._sc)
82839121 2629
6fd49698
PP
2630 if self._s is None:
2631 raise ValueError("Stream creation failed.")
2632
2633 def __del__(self):
2634 nbt._bt_ctf_stream_put(self._s)
2635
6fd49698
PP
2636 @property
2637 def discarded_events(self):
82839121
PP
2638 """
2639 Get a stream's discarded event count.
2640 """
2641
6fd49698 2642 ret, count = nbt._bt_ctf_stream_get_discarded_events_count(self._s)
82839121 2643
6fd49698 2644 if ret < 0:
82839121 2645 raise ValueError("Could not get the stream's discarded events count")
6fd49698 2646
82839121 2647 return count
6fd49698
PP
2648
2649 def append_discarded_events(self, event_count):
82839121
PP
2650 """
2651 Increase the current packet's discarded event count.
2652 """
6fd49698 2653
82839121 2654 nbt._bt_ctf_stream_append_discarded_events(self._s, event_count)
6fd49698
PP
2655
2656 def append_event(self, event):
82839121
PP
2657 """
2658 Append "event" to the stream's current packet. The stream's associated clock
2659 will be sampled during this call. The event shall not be modified after
2660 being appended to a stream.
2661 """
2662
6fd49698 2663 ret = nbt._bt_ctf_stream_append_event(self._s, event._e)
82839121 2664
6fd49698
PP
2665 if ret < 0:
2666 raise ValueError("Could not append event to stream.")
2667
6fd49698
PP
2668 @property
2669 def packet_context(self):
82839121
PP
2670 """
2671 Get a Stream's packet context field (a StructureField).
2672 """
2673
6fd49698 2674 native_field = nbt._bt_ctf_stream_get_packet_context(self._s)
82839121 2675
6fd49698
PP
2676 if native_field is None:
2677 raise ValueError("Invalid Stream.")
6fd49698 2678
82839121
PP
2679 return CTFWriter.Field._create_field_from_native_instance(native_field)
2680
6fd49698
PP
2681 @packet_context.setter
2682 def packet_context(self, field):
82839121
PP
2683 """
2684 Set a Stream's packet context field (must be a StructureField).
2685 """
2686
6fd49698 2687 if not isinstance(field, CTFWriter.StructureField):
82839121
PP
2688 raise TypeError("Argument field must be of type StructureField")
2689
6fd49698 2690 ret = nbt._bt_ctf_stream_set_packet_context(self._s, field._f)
82839121 2691
6fd49698
PP
2692 if ret < 0:
2693 raise ValueError("Invalid packet context field.")
2694
6fd49698 2695 def flush(self):
82839121
PP
2696 """
2697 The stream's current packet's events will be flushed to disk. Events
2698 subsequently appended to the stream will be added to a new packet.
2699 """
2700
6fd49698 2701 ret = nbt._bt_ctf_stream_flush(self._s)
82839121 2702
6fd49698
PP
2703 if ret < 0:
2704 raise ValueError("Could not flush stream.")
2705
2706 class Writer:
6fd49698 2707 def __init__(self, path):
82839121
PP
2708 """
2709 Create a new writer that will produce a trace in the given path.
2710 """
2711
6fd49698 2712 self._w = nbt._bt_ctf_writer_create(path)
82839121 2713
6fd49698
PP
2714 if self._w is None:
2715 raise ValueError("Writer creation failed.")
2716
2717 def __del__(self):
2718 nbt._bt_ctf_writer_put(self._w)
2719
6fd49698 2720 def create_stream(self, stream_class):
82839121
PP
2721 """
2722 Create a new stream instance and register it to the writer.
2723 """
2724
6fd49698
PP
2725 if not isinstance(stream_class, CTFWriter.StreamClass):
2726 raise TypeError("Invalid stream_class type.")
2727
2728 stream = CTFWriter.Stream.__new__(CTFWriter.Stream)
2729 stream._s = nbt._bt_ctf_writer_create_stream(self._w, stream_class._sc)
6fd49698 2730
82839121 2731 return stream
6fd49698
PP
2732
2733 def add_environment_field(self, name, value):
82839121
PP
2734 """
2735 Add an environment field to the trace.
2736 """
2737
2738 ret = nbt._bt_ctf_writer_add_environment_field(self._w, str(name),
2739 str(value))
2740
6fd49698
PP
2741 if ret < 0:
2742 raise ValueError("Could not add environment field to trace.")
2743
6fd49698 2744 def add_clock(self, clock):
82839121
PP
2745 """
2746 Add a clock to the trace. Clocks assigned to stream classes must be
2747 registered to the writer.
2748 """
2749
6fd49698 2750 ret = nbt._bt_ctf_writer_add_clock(self._w, clock._c)
82839121 2751
6fd49698
PP
2752 if ret < 0:
2753 raise ValueError("Could not add clock to Writer.")
2754
6fd49698
PP
2755 @property
2756 def metadata(self):
82839121
PP
2757 """
2758 Get the trace's TSDL meta-data.
2759 """
6fd49698 2760
82839121 2761 return nbt._bt_ctf_writer_get_metadata_string(self._w)
6fd49698
PP
2762
2763 def flush_metadata(self):
82839121
PP
2764 """
2765 Flush the trace's metadata to the metadata file.
2766 """
2767
6fd49698
PP
2768 nbt._bt_ctf_writer_flush_metadata(self._w)
2769
6fd49698
PP
2770 @property
2771 def byte_order(self):
82839121
PP
2772 """
2773 Get the trace's byte order. Must be a constant from the ByteOrder
2774 class.
2775 """
2776
6fd49698
PP
2777 raise NotImplementedError("Getter not implemented.")
2778
6fd49698
PP
2779 @byte_order.setter
2780 def byte_order(self, byte_order):
82839121
PP
2781 """
2782 Set the trace's byte order. Must be a constant from the ByteOrder
2783 class. Defaults to the host machine's endianness
2784 """
2785
6fd49698 2786 ret = nbt._bt_ctf_writer_set_byte_order(self._w, byte_order)
82839121 2787
6fd49698
PP
2788 if ret < 0:
2789 raise ValueError("Could not set trace's byte order.")
This page took 0.145793 seconds and 4 git commands to generate.