Commit | Line | Data |
---|---|---|
013f35c6 PP |
1 | #ifndef BABELTRACE_CTFSER_INTERNAL_H |
2 | #define BABELTRACE_CTFSER_INTERNAL_H | |
3 | ||
4 | /* | |
5 | * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation | |
6 | * Copyright 2013, 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com> | |
7 | * Copyright 2017-2019 Philippe Proulx <pproulx@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 | * | |
27 | * The Common Trace Format (CTF) Specification is available at | |
28 | * http://www.efficios.com/ctf | |
29 | */ | |
30 | ||
c4f23e30 | 31 | #include <stdbool.h> |
013f35c6 PP |
32 | #include <stdlib.h> |
33 | #include <stdint.h> | |
34 | #include <limits.h> | |
578e048b | 35 | #include "compat/mman.h" |
013f35c6 PP |
36 | #include <sys/types.h> |
37 | #include <sys/stat.h> | |
38 | #include <fcntl.h> | |
578e048b MJ |
39 | #include "common/align.h" |
40 | #include "compat/endian.h" | |
41 | #include "common/common.h" | |
42 | #include "common/mmap-align.h" | |
3fadfbc0 | 43 | #include <babeltrace2/types.h> |
578e048b | 44 | #include "common/assert.h" |
91d81473 | 45 | #include "common/macros.h" |
578e048b | 46 | #include "compat/bitfield.h" |
013f35c6 PP |
47 | #include <glib.h> |
48 | ||
49 | struct bt_ctfser { | |
50 | /* Stream file's descriptor */ | |
51 | int fd; | |
52 | ||
53 | /* Offset (bytes) of memory map (current packet) in the stream file */ | |
54 | off_t mmap_offset; | |
55 | ||
56 | /* Offset (bytes) of packet's first byte in the memory map */ | |
57 | off_t mmap_base_offset; | |
58 | ||
59 | /* Current offset (bits) within current packet */ | |
60 | uint64_t offset_in_cur_packet_bits; | |
61 | ||
62 | /* Current packet size (bytes) */ | |
63 | uint64_t cur_packet_size_bytes; | |
64 | ||
65 | /* Previous packet size (bytes) */ | |
66 | uint64_t prev_packet_size_bytes; | |
67 | ||
68 | /* Current stream size (bytes) */ | |
69 | uint64_t stream_size_bytes; | |
70 | ||
71 | /* Memory map base address */ | |
72 | struct mmap_align *base_mma; | |
73 | ||
74 | /* Stream file's path (for debugging) */ | |
75 | GString *path; | |
86d8b7b8 PP |
76 | |
77 | /* Serializer's log level */ | |
78 | int log_level; | |
013f35c6 PP |
79 | }; |
80 | ||
013f35c6 PP |
81 | /* |
82 | * Initializes a CTF serializer. | |
83 | * | |
84 | * This function opens the file `path` for writing. | |
85 | */ | |
86 | BT_HIDDEN | |
86d8b7b8 PP |
87 | int bt_ctfser_init(struct bt_ctfser *ctfser, const char *path, |
88 | int log_level); | |
013f35c6 PP |
89 | |
90 | /* | |
91 | * Finalizes a CTF serializer. | |
92 | * | |
93 | * This function truncates the stream file so that there's no extra | |
94 | * padding after the last packet, and then closes the file. | |
95 | */ | |
96 | BT_HIDDEN | |
97 | int bt_ctfser_fini(struct bt_ctfser *ctfser); | |
98 | ||
99 | /* | |
100 | * Opens a new packet. | |
101 | * | |
102 | * All the next writing functions are performed within this new packet. | |
103 | */ | |
104 | BT_HIDDEN | |
105 | int bt_ctfser_open_packet(struct bt_ctfser *ctfser); | |
106 | ||
107 | /* | |
108 | * Closes the current packet, making its size `packet_size_bytes`. | |
109 | */ | |
110 | BT_HIDDEN | |
111 | void bt_ctfser_close_current_packet(struct bt_ctfser *ctfser, | |
112 | uint64_t packet_size_bytes); | |
113 | ||
114 | BT_HIDDEN | |
115 | int _bt_ctfser_increase_cur_packet_size(struct bt_ctfser *ctfser); | |
116 | ||
117 | static inline | |
118 | uint64_t _bt_ctfser_cur_packet_size_bits(struct bt_ctfser *ctfser) | |
119 | { | |
120 | return ctfser->cur_packet_size_bytes * 8; | |
121 | } | |
122 | ||
123 | static inline | |
124 | uint64_t _bt_ctfser_prev_packet_size_bits(struct bt_ctfser *ctfser) | |
125 | { | |
126 | return ctfser->prev_packet_size_bytes * 8; | |
127 | } | |
128 | ||
129 | static inline | |
130 | uint64_t _bt_ctfser_offset_bytes(struct bt_ctfser *ctfser) | |
131 | { | |
132 | return ctfser->offset_in_cur_packet_bits / 8; | |
133 | } | |
134 | ||
135 | static inline | |
136 | uint8_t *_bt_ctfser_get_addr(struct bt_ctfser *ctfser) | |
137 | { | |
138 | /* Only makes sense to get the address after aligning on byte */ | |
98b15851 | 139 | BT_ASSERT_DBG(ctfser->offset_in_cur_packet_bits % 8 == 0); |
013f35c6 PP |
140 | return ((uint8_t *) mmap_align_addr(ctfser->base_mma)) + |
141 | ctfser->mmap_base_offset + _bt_ctfser_offset_bytes(ctfser); | |
142 | } | |
143 | ||
144 | static inline | |
145 | bool _bt_ctfser_has_space_left(struct bt_ctfser *ctfser, uint64_t size_bits) | |
146 | { | |
147 | bool has_space_left = true; | |
148 | ||
91d81473 | 149 | if (G_UNLIKELY((ctfser->offset_in_cur_packet_bits + size_bits > |
013f35c6 PP |
150 | _bt_ctfser_cur_packet_size_bits(ctfser)))) { |
151 | has_space_left = false; | |
152 | goto end; | |
153 | } | |
154 | ||
91d81473 | 155 | if (G_UNLIKELY(size_bits > UINT64_MAX - ctfser->offset_in_cur_packet_bits)) { |
013f35c6 PP |
156 | has_space_left = false; |
157 | goto end; | |
158 | } | |
159 | ||
160 | end: | |
161 | return has_space_left; | |
162 | } | |
163 | ||
164 | static inline | |
165 | void _bt_ctfser_incr_offset(struct bt_ctfser *ctfser, uint64_t size_bits) | |
166 | { | |
98b15851 | 167 | BT_ASSERT_DBG(_bt_ctfser_has_space_left(ctfser, size_bits)); |
013f35c6 PP |
168 | ctfser->offset_in_cur_packet_bits += size_bits; |
169 | } | |
170 | ||
171 | /* | |
172 | * Aligns the current offset within the current packet to | |
173 | * `alignment_bits` bits (power of two, > 0). | |
174 | */ | |
175 | static inline | |
176 | int bt_ctfser_align_offset_in_current_packet(struct bt_ctfser *ctfser, | |
177 | uint64_t alignment_bits) | |
178 | { | |
179 | int ret = 0; | |
180 | uint64_t align_size_bits; | |
181 | ||
98b15851 | 182 | BT_ASSERT_DBG(alignment_bits > 0); |
013f35c6 PP |
183 | align_size_bits = ALIGN(ctfser->offset_in_cur_packet_bits, |
184 | alignment_bits) - ctfser->offset_in_cur_packet_bits; | |
185 | ||
91d81473 | 186 | if (G_UNLIKELY(!_bt_ctfser_has_space_left(ctfser, align_size_bits))) { |
013f35c6 | 187 | ret = _bt_ctfser_increase_cur_packet_size(ctfser); |
91d81473 | 188 | if (G_UNLIKELY(ret)) { |
013f35c6 PP |
189 | goto end; |
190 | } | |
191 | } | |
192 | ||
193 | _bt_ctfser_incr_offset(ctfser, align_size_bits); | |
194 | ||
195 | end: | |
196 | return ret; | |
197 | } | |
198 | ||
199 | static inline | |
d6981059 PP |
200 | int _bt_ctfser_write_byte_aligned_unsigned_int_no_align( |
201 | struct bt_ctfser *ctfser, uint64_t value, | |
202 | unsigned int size_bits, int byte_order) | |
013f35c6 PP |
203 | { |
204 | int ret = 0; | |
205 | ||
206 | /* Reverse byte order? */ | |
207 | bool rbo = byte_order != BYTE_ORDER; | |
208 | ||
98b15851 PP |
209 | BT_ASSERT_DBG(size_bits % 8 == 0); |
210 | BT_ASSERT_DBG(_bt_ctfser_has_space_left(ctfser, size_bits)); | |
013f35c6 | 211 | |
d6981059 PP |
212 | switch (size_bits) { |
213 | case 8: | |
214 | { | |
215 | uint8_t v = (uint8_t) value; | |
216 | ||
217 | memcpy(_bt_ctfser_get_addr(ctfser), &v, sizeof(v)); | |
218 | break; | |
219 | } | |
220 | case 16: | |
221 | { | |
222 | uint16_t v = (uint16_t) value; | |
013f35c6 | 223 | |
d6981059 PP |
224 | if (rbo) { |
225 | v = GUINT16_SWAP_LE_BE(v); | |
013f35c6 | 226 | } |
013f35c6 | 227 | |
d6981059 PP |
228 | memcpy(_bt_ctfser_get_addr(ctfser), &v, sizeof(v)); |
229 | break; | |
230 | } | |
231 | case 32: | |
232 | { | |
233 | uint32_t v = (uint32_t) value; | |
013f35c6 | 234 | |
d6981059 PP |
235 | if (rbo) { |
236 | v = GUINT32_SWAP_LE_BE(v); | |
013f35c6 | 237 | } |
013f35c6 | 238 | |
d6981059 PP |
239 | memcpy(_bt_ctfser_get_addr(ctfser), &v, sizeof(v)); |
240 | break; | |
241 | } | |
242 | case 64: | |
243 | { | |
244 | uint64_t v = (uint64_t) value; | |
013f35c6 | 245 | |
d6981059 PP |
246 | if (rbo) { |
247 | v = GUINT64_SWAP_LE_BE(v); | |
013f35c6 | 248 | } |
013f35c6 | 249 | |
d6981059 PP |
250 | memcpy(_bt_ctfser_get_addr(ctfser), &v, sizeof(v)); |
251 | break; | |
252 | } | |
253 | default: | |
498e7994 | 254 | bt_common_abort(); |
d6981059 | 255 | } |
013f35c6 | 256 | |
d6981059 PP |
257 | _bt_ctfser_incr_offset(ctfser, size_bits); |
258 | return ret; | |
259 | } | |
013f35c6 | 260 | |
d6981059 PP |
261 | static inline |
262 | int _bt_ctfser_write_byte_aligned_signed_int_no_align( | |
263 | struct bt_ctfser *ctfser, int64_t value, | |
264 | unsigned int size_bits, int byte_order) | |
265 | { | |
266 | int ret = 0; | |
013f35c6 | 267 | |
d6981059 PP |
268 | /* Reverse byte order? */ |
269 | bool rbo = byte_order != BYTE_ORDER; | |
013f35c6 | 270 | |
98b15851 PP |
271 | BT_ASSERT_DBG(size_bits % 8 == 0); |
272 | BT_ASSERT_DBG(_bt_ctfser_has_space_left(ctfser, size_bits)); | |
013f35c6 | 273 | |
d6981059 PP |
274 | switch (size_bits) { |
275 | case 8: | |
276 | { | |
277 | int8_t v = (int8_t) value; | |
013f35c6 | 278 | |
d6981059 PP |
279 | memcpy(_bt_ctfser_get_addr(ctfser), &v, sizeof(v)); |
280 | break; | |
281 | } | |
282 | case 16: | |
283 | { | |
284 | int16_t v = (int16_t) value; | |
285 | ||
286 | if (rbo) { | |
287 | v = GUINT16_SWAP_LE_BE(v); | |
013f35c6 | 288 | } |
013f35c6 | 289 | |
d6981059 PP |
290 | memcpy(_bt_ctfser_get_addr(ctfser), &v, sizeof(v)); |
291 | break; | |
292 | } | |
293 | case 32: | |
294 | { | |
295 | int32_t v = (int32_t) value; | |
013f35c6 | 296 | |
d6981059 PP |
297 | if (rbo) { |
298 | v = GUINT32_SWAP_LE_BE(v); | |
013f35c6 | 299 | } |
d6981059 PP |
300 | |
301 | memcpy(_bt_ctfser_get_addr(ctfser), &v, sizeof(v)); | |
302 | break; | |
303 | } | |
304 | case 64: | |
305 | { | |
306 | int64_t v = (int64_t) value; | |
307 | ||
308 | if (rbo) { | |
309 | v = GUINT64_SWAP_LE_BE(v); | |
013f35c6 | 310 | } |
d6981059 PP |
311 | |
312 | memcpy(_bt_ctfser_get_addr(ctfser), &v, sizeof(v)); | |
313 | break; | |
314 | } | |
315 | default: | |
498e7994 | 316 | bt_common_abort(); |
013f35c6 PP |
317 | } |
318 | ||
319 | _bt_ctfser_incr_offset(ctfser, size_bits); | |
320 | return ret; | |
321 | } | |
322 | ||
323 | /* | |
d6981059 PP |
324 | * Writes an unsigned integer known to have a size that is a multiple of |
325 | * 8 and an alignment that is >= 8 at the current offset within the | |
326 | * current packet. | |
013f35c6 PP |
327 | */ |
328 | static inline | |
d6981059 PP |
329 | int bt_ctfser_write_byte_aligned_unsigned_int(struct bt_ctfser *ctfser, |
330 | uint64_t value, unsigned int alignment_bits, | |
331 | unsigned int size_bits, int byte_order) | |
013f35c6 PP |
332 | { |
333 | int ret; | |
334 | ||
98b15851 | 335 | BT_ASSERT_DBG(alignment_bits % 8 == 0); |
013f35c6 | 336 | ret = bt_ctfser_align_offset_in_current_packet(ctfser, alignment_bits); |
91d81473 | 337 | if (G_UNLIKELY(ret)) { |
013f35c6 PP |
338 | goto end; |
339 | } | |
340 | ||
91d81473 | 341 | if (G_UNLIKELY(!_bt_ctfser_has_space_left(ctfser, size_bits))) { |
013f35c6 | 342 | ret = _bt_ctfser_increase_cur_packet_size(ctfser); |
91d81473 | 343 | if (G_UNLIKELY(ret)) { |
013f35c6 PP |
344 | goto end; |
345 | } | |
346 | } | |
347 | ||
d6981059 PP |
348 | ret = _bt_ctfser_write_byte_aligned_unsigned_int_no_align(ctfser, value, |
349 | size_bits, byte_order); | |
91d81473 | 350 | if (G_UNLIKELY(ret)) { |
013f35c6 PP |
351 | goto end; |
352 | } | |
353 | ||
354 | end: | |
355 | return ret; | |
356 | } | |
357 | ||
358 | /* | |
d6981059 PP |
359 | * Writes a signed integer known to have a size that is a multiple of 8 |
360 | * and an alignment that is >= 8 at the current offset within the | |
361 | * current packet. | |
013f35c6 PP |
362 | */ |
363 | static inline | |
d6981059 PP |
364 | int bt_ctfser_write_byte_aligned_signed_int(struct bt_ctfser *ctfser, |
365 | int64_t value, unsigned int alignment_bits, | |
366 | unsigned int size_bits, int byte_order) | |
367 | { | |
368 | int ret; | |
369 | ||
98b15851 | 370 | BT_ASSERT_DBG(alignment_bits % 8 == 0); |
d6981059 | 371 | ret = bt_ctfser_align_offset_in_current_packet(ctfser, alignment_bits); |
91d81473 | 372 | if (G_UNLIKELY(ret)) { |
d6981059 PP |
373 | goto end; |
374 | } | |
375 | ||
91d81473 | 376 | if (G_UNLIKELY(!_bt_ctfser_has_space_left(ctfser, size_bits))) { |
d6981059 | 377 | ret = _bt_ctfser_increase_cur_packet_size(ctfser); |
91d81473 | 378 | if (G_UNLIKELY(ret)) { |
d6981059 PP |
379 | goto end; |
380 | } | |
381 | } | |
382 | ||
383 | ret = _bt_ctfser_write_byte_aligned_signed_int_no_align(ctfser, value, | |
384 | size_bits, byte_order); | |
91d81473 | 385 | if (G_UNLIKELY(ret)) { |
d6981059 PP |
386 | goto end; |
387 | } | |
388 | ||
389 | end: | |
390 | return ret; | |
391 | } | |
392 | ||
393 | /* | |
394 | * Writes an unsigned integer at the current offset within the current | |
395 | * packet. | |
396 | */ | |
397 | static inline | |
398 | int bt_ctfser_write_unsigned_int(struct bt_ctfser *ctfser, uint64_t value, | |
399 | unsigned int alignment_bits, unsigned int size_bits, | |
013f35c6 PP |
400 | int byte_order) |
401 | { | |
402 | int ret = 0; | |
403 | ||
404 | ret = bt_ctfser_align_offset_in_current_packet(ctfser, alignment_bits); | |
91d81473 | 405 | if (G_UNLIKELY(ret)) { |
013f35c6 PP |
406 | goto end; |
407 | } | |
408 | ||
91d81473 | 409 | if (G_UNLIKELY(!_bt_ctfser_has_space_left(ctfser, size_bits))) { |
013f35c6 | 410 | ret = _bt_ctfser_increase_cur_packet_size(ctfser); |
91d81473 | 411 | if (G_UNLIKELY(ret)) { |
013f35c6 PP |
412 | goto end; |
413 | } | |
414 | } | |
415 | ||
416 | if (alignment_bits % 8 == 0 && size_bits % 8 == 0) { | |
d6981059 PP |
417 | ret = _bt_ctfser_write_byte_aligned_unsigned_int_no_align( |
418 | ctfser, value, size_bits, byte_order); | |
013f35c6 PP |
419 | goto end; |
420 | } | |
421 | ||
d6981059 PP |
422 | if (byte_order == LITTLE_ENDIAN) { |
423 | bt_bitfield_write_le(mmap_align_addr(ctfser->base_mma) + | |
424 | ctfser->mmap_base_offset, uint8_t, | |
425 | ctfser->offset_in_cur_packet_bits, size_bits, value); | |
013f35c6 | 426 | } else { |
d6981059 PP |
427 | bt_bitfield_write_be(mmap_align_addr(ctfser->base_mma) + |
428 | ctfser->mmap_base_offset, uint8_t, | |
429 | ctfser->offset_in_cur_packet_bits, size_bits, value); | |
430 | } | |
431 | ||
432 | _bt_ctfser_incr_offset(ctfser, size_bits); | |
433 | ||
434 | end: | |
435 | return ret; | |
436 | } | |
437 | ||
438 | /* | |
439 | * Writes a signed integer at the current offset within the current | |
440 | * packet. | |
441 | */ | |
442 | static inline | |
443 | int bt_ctfser_write_signed_int(struct bt_ctfser *ctfser, int64_t value, | |
444 | unsigned int alignment_bits, unsigned int size_bits, | |
445 | int byte_order) | |
446 | { | |
447 | int ret = 0; | |
448 | ||
449 | ret = bt_ctfser_align_offset_in_current_packet(ctfser, alignment_bits); | |
91d81473 | 450 | if (G_UNLIKELY(ret)) { |
d6981059 PP |
451 | goto end; |
452 | } | |
453 | ||
91d81473 | 454 | if (G_UNLIKELY(!_bt_ctfser_has_space_left(ctfser, size_bits))) { |
d6981059 | 455 | ret = _bt_ctfser_increase_cur_packet_size(ctfser); |
91d81473 | 456 | if (G_UNLIKELY(ret)) { |
d6981059 | 457 | goto end; |
013f35c6 PP |
458 | } |
459 | } | |
460 | ||
d6981059 PP |
461 | if (alignment_bits % 8 == 0 && size_bits % 8 == 0) { |
462 | ret = _bt_ctfser_write_byte_aligned_signed_int_no_align( | |
463 | ctfser, value, size_bits, byte_order); | |
464 | goto end; | |
465 | } | |
466 | ||
467 | if (byte_order == LITTLE_ENDIAN) { | |
468 | bt_bitfield_write_le(mmap_align_addr(ctfser->base_mma) + | |
469 | ctfser->mmap_base_offset, uint8_t, | |
470 | ctfser->offset_in_cur_packet_bits, size_bits, value); | |
471 | } else { | |
472 | bt_bitfield_write_be(mmap_align_addr(ctfser->base_mma) + | |
473 | ctfser->mmap_base_offset, uint8_t, | |
474 | ctfser->offset_in_cur_packet_bits, size_bits, value); | |
475 | } | |
476 | ||
013f35c6 PP |
477 | _bt_ctfser_incr_offset(ctfser, size_bits); |
478 | ||
479 | end: | |
480 | return ret; | |
481 | } | |
482 | ||
483 | /* | |
484 | * Writes a 32-bit floating point number at the current offset within | |
485 | * the current packet. | |
486 | */ | |
487 | static inline | |
488 | int bt_ctfser_write_float32(struct bt_ctfser *ctfser, double value, | |
489 | unsigned int alignment_bits, int byte_order) | |
490 | { | |
013f35c6 PP |
491 | union u32f { |
492 | uint32_t u; | |
493 | float f; | |
494 | } u32f; | |
495 | ||
496 | u32f.f = (float) value; | |
d6981059 PP |
497 | return bt_ctfser_write_unsigned_int(ctfser, (uint64_t) u32f.u, |
498 | alignment_bits, 32, byte_order); | |
013f35c6 PP |
499 | } |
500 | ||
501 | /* | |
502 | * Writes a 64-bit floating point number at the current offset within | |
503 | * the current packet. | |
504 | */ | |
505 | static inline | |
506 | int bt_ctfser_write_float64(struct bt_ctfser *ctfser, double value, | |
507 | unsigned int alignment_bits, int byte_order) | |
508 | { | |
013f35c6 PP |
509 | union u64f { |
510 | uint64_t u; | |
1fba7c7b | 511 | double d; |
013f35c6 PP |
512 | } u64f; |
513 | ||
1fba7c7b | 514 | u64f.d = value; |
d6981059 PP |
515 | return bt_ctfser_write_unsigned_int(ctfser, u64f.u, alignment_bits, |
516 | 64, byte_order); | |
013f35c6 PP |
517 | } |
518 | ||
519 | /* | |
520 | * Writes a C string, including the terminating null character, at the | |
521 | * current offset within the current packet. | |
522 | */ | |
523 | static inline | |
524 | int bt_ctfser_write_string(struct bt_ctfser *ctfser, const char *value) | |
525 | { | |
526 | int ret = 0; | |
527 | const char *at = value; | |
528 | ||
529 | ret = bt_ctfser_align_offset_in_current_packet(ctfser, 8); | |
91d81473 | 530 | if (G_UNLIKELY(ret)) { |
013f35c6 PP |
531 | goto end; |
532 | } | |
533 | ||
534 | while (true) { | |
91d81473 | 535 | if (G_UNLIKELY(!_bt_ctfser_has_space_left(ctfser, 8))) { |
013f35c6 | 536 | ret = _bt_ctfser_increase_cur_packet_size(ctfser); |
91d81473 | 537 | if (G_UNLIKELY(ret)) { |
013f35c6 PP |
538 | goto end; |
539 | } | |
540 | } | |
541 | ||
542 | memcpy(_bt_ctfser_get_addr(ctfser), at, sizeof(*at)); | |
543 | _bt_ctfser_incr_offset(ctfser, 8); | |
544 | ||
91d81473 | 545 | if (G_UNLIKELY(*at == '\0')) { |
013f35c6 PP |
546 | break; |
547 | } | |
548 | ||
549 | at++; | |
550 | } | |
551 | ||
552 | end: | |
553 | return ret; | |
554 | } | |
555 | ||
556 | /* | |
557 | * Returns the current offset within the current packet (bits). | |
558 | */ | |
559 | static inline | |
560 | uint64_t bt_ctfser_get_offset_in_current_packet_bits(struct bt_ctfser *ctfser) | |
561 | { | |
562 | return ctfser->offset_in_cur_packet_bits; | |
563 | } | |
564 | ||
565 | /* | |
566 | * Sets the current offset within the current packet (bits). | |
567 | */ | |
568 | static inline | |
569 | void bt_ctfser_set_offset_in_current_packet_bits(struct bt_ctfser *ctfser, | |
570 | uint64_t offset_bits) | |
571 | { | |
98b15851 | 572 | BT_ASSERT_DBG(offset_bits <= _bt_ctfser_cur_packet_size_bits(ctfser)); |
013f35c6 PP |
573 | ctfser->offset_in_cur_packet_bits = offset_bits; |
574 | } | |
575 | ||
15fe47e0 PP |
576 | static inline |
577 | const char *bt_ctfser_get_file_path(struct bt_ctfser *ctfser) | |
578 | { | |
579 | return ctfser->path->str; | |
580 | } | |
581 | ||
013f35c6 | 582 | #endif /* BABELTRACE_CTFSER_INTERNAL_H */ |