Commit | Line | Data |
---|---|---|
cab3f160 JG |
1 | /* |
2 | * iterator.c | |
3 | * | |
4 | * Babeltrace Trace Trimmer Iterator | |
5 | * | |
6 | * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com> | |
7 | * | |
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 | */ | |
28 | ||
9705ddba | 29 | #define BT_LOG_TAG "PLUGIN-UTILS-TRIMMER-FLT-ITER" |
b4565e8b PP |
30 | #include "logging.h" |
31 | ||
58a2480d | 32 | #include <babeltrace/compat/time-internal.h> |
3d2f08e7 | 33 | #include <babeltrace/compat/utc-internal.h> |
9d408fca | 34 | #include <babeltrace/babeltrace.h> |
f6ccaed9 | 35 | #include <babeltrace/assert-internal.h> |
8b0ce102 | 36 | #include <plugins-common.h> |
44d3cbf0 | 37 | |
19ce87a4 JD |
38 | #include "trimmer.h" |
39 | #include "iterator.h" | |
40 | #include "copy.h" | |
41 | ||
86e20162 JD |
42 | static |
43 | gboolean close_packets(gpointer key, gpointer value, gpointer user_data) | |
44 | { | |
b19ff26f | 45 | const bt_packet *writer_packet = value; |
86e20162 | 46 | |
c5b9b441 | 47 | bt_packet_put_ref(writer_packet); |
86e20162 JD |
48 | return TRUE; |
49 | } | |
50 | ||
d3eb6e8f | 51 | BT_HIDDEN |
d6e69534 | 52 | void trimmer_iterator_finalize(bt_self_message_iterator *it) |
44d3cbf0 | 53 | { |
86e20162 | 54 | struct trimmer_iterator *trim_it; |
44d3cbf0 | 55 | |
d6e69534 | 56 | trim_it = bt_self_message_iterator_get_user_data(it); |
f6ccaed9 | 57 | BT_ASSERT(trim_it); |
44d3cbf0 | 58 | |
65300d60 | 59 | bt_object_put_ref(trim_it->input_iterator); |
86e20162 JD |
60 | g_hash_table_foreach_remove(trim_it->packet_map, |
61 | close_packets, NULL); | |
62 | g_hash_table_destroy(trim_it->packet_map); | |
63 | g_free(trim_it); | |
44d3cbf0 | 64 | } |
cab3f160 JG |
65 | |
66 | BT_HIDDEN | |
d6e69534 PP |
67 | enum bt_message_iterator_status trimmer_iterator_init( |
68 | bt_self_message_iterator *iterator, | |
91457551 | 69 | struct bt_private_port *port) |
cab3f160 | 70 | { |
d6e69534 PP |
71 | enum bt_message_iterator_status ret = |
72 | BT_MESSAGE_ITERATOR_STATUS_OK; | |
73 | enum bt_message_iterator_status it_ret; | |
73d5c1ad | 74 | enum bt_connection_status conn_status; |
890882ef PP |
75 | struct bt_private_port *input_port = NULL; |
76 | struct bt_private_connection *connection = NULL; | |
b19ff26f | 77 | bt_self_component *component = |
d6e69534 | 78 | bt_self_message_iterator_get_private_component(iterator); |
44d3cbf0 JG |
79 | struct trimmer_iterator *it_data = g_new0(struct trimmer_iterator, 1); |
80 | ||
81 | if (!it_data) { | |
d6e69534 | 82 | ret = BT_MESSAGE_ITERATOR_STATUS_NOMEM; |
44d3cbf0 JG |
83 | goto end; |
84 | } | |
85 | ||
99cdb69e | 86 | /* Create a new iterator on the upstream component. */ |
d94d92ac | 87 | input_port = bt_self_component_filter_get_input_port_by_name( |
b9d103be | 88 | component, "in"); |
f6ccaed9 | 89 | BT_ASSERT(input_port); |
28e6ca8b | 90 | connection = bt_private_port_get_connection(input_port); |
f6ccaed9 | 91 | BT_ASSERT(connection); |
99cdb69e | 92 | |
d6e69534 | 93 | conn_status = bt_private_connection_create_message_iterator(connection, |
f42867e2 | 94 | &it_data->input_iterator); |
73d5c1ad | 95 | if (conn_status != BT_CONNECTION_STATUS_OK) { |
d6e69534 | 96 | ret = BT_MESSAGE_ITERATOR_STATUS_ERROR; |
99cdb69e JG |
97 | goto end; |
98 | } | |
99 | ||
19ce87a4 JD |
100 | it_data->err = stderr; |
101 | it_data->packet_map = g_hash_table_new_full(g_direct_hash, | |
102 | g_direct_equal, NULL, NULL); | |
103 | ||
d6e69534 | 104 | it_ret = bt_self_message_iterator_set_user_data(iterator, |
890882ef | 105 | it_data); |
44d3cbf0 JG |
106 | if (it_ret) { |
107 | goto end; | |
108 | } | |
cab3f160 | 109 | end: |
65300d60 PP |
110 | bt_object_put_ref(component); |
111 | bt_object_put_ref(connection); | |
112 | bt_object_put_ref(input_port); | |
cab3f160 JG |
113 | return ret; |
114 | } | |
115 | ||
528debdf MD |
116 | static |
117 | int update_lazy_bound(struct trimmer_bound *bound, const char *name, | |
55595636 | 118 | int64_t ts, bool *lazy_update) |
528debdf MD |
119 | { |
120 | struct tm tm; | |
121 | int64_t value; | |
122 | time_t timeval; | |
123 | ||
55595636 MD |
124 | *lazy_update = false; |
125 | ||
528debdf MD |
126 | if (!bound->lazy) { |
127 | return 0; | |
128 | } | |
129 | tm.tm_isdst = -1; | |
130 | timeval = ts / NSEC_PER_SEC; | |
131 | ||
132 | if (bound->lazy_values.gmt) { | |
133 | /* Get day, month, year. */ | |
58a2480d | 134 | if (!bt_gmtime_r(&timeval, &tm)) { |
c59fc0d5 | 135 | BT_LOGE_STR("Failure in bt_gmtime_r()."); |
528debdf MD |
136 | goto error; |
137 | } | |
138 | tm.tm_sec = bound->lazy_values.ss; | |
139 | tm.tm_min = bound->lazy_values.mm; | |
c6bd8523 | 140 | tm.tm_hour = bound->lazy_value.hh; |
3d2f08e7 | 141 | timeval = bt_timegm(&tm); |
528debdf | 142 | if (timeval < 0) { |
b4565e8b | 143 | BT_LOGE("Failure in bt_timegm(), incorrectly formatted %s timestamp", |
55595636 | 144 | name); |
528debdf MD |
145 | goto error; |
146 | } | |
147 | } else { | |
148 | /* Get day, month, year. */ | |
58a2480d | 149 | if (!bt_localtime_r(&timeval, &tm)) { |
c59fc0d5 | 150 | BT_LOGE_STR("Failure in bt_localtime_r()."); |
528debdf MD |
151 | goto error; |
152 | } | |
153 | tm.tm_sec = bound->lazy_values.ss; | |
154 | tm.tm_min = bound->lazy_values.mm; | |
c6bd8523 | 155 | tm.tm_hour = bound->lazy_value.hh; |
528debdf MD |
156 | timeval = mktime(&tm); |
157 | if (timeval < 0) { | |
b4565e8b | 158 | BT_LOGE("Failure in mktime(), incorrectly formatted %s timestamp", |
528debdf MD |
159 | name); |
160 | goto error; | |
161 | } | |
162 | } | |
163 | value = (int64_t) timeval; | |
164 | value *= NSEC_PER_SEC; | |
165 | value += bound->lazy_values.ns; | |
166 | bound->value = value; | |
167 | bound->set = true; | |
168 | bound->lazy = false; | |
55595636 | 169 | *lazy_update = true; |
528debdf MD |
170 | return 0; |
171 | ||
172 | error: | |
528debdf MD |
173 | return -1; |
174 | } | |
175 | ||
44d3cbf0 | 176 | static |
d6e69534 PP |
177 | const bt_message *evaluate_event_message( |
178 | const bt_message *message, | |
19ce87a4 | 179 | struct trimmer_iterator *trim_it, |
55595636 | 180 | struct trimmer_bound *begin, struct trimmer_bound *end, |
907b1704 | 181 | bool *_event_in_range, bool *finished) |
44d3cbf0 | 182 | { |
72208f03 JG |
183 | int64_t ts; |
184 | int clock_ret; | |
b19ff26f | 185 | const bt_event *event = NULL, *writer_event; |
72208f03 | 186 | bool in_range = true; |
b19ff26f PP |
187 | const bt_clock_class *clock_class = NULL; |
188 | const bt_trace *trace = NULL; | |
189 | const bt_stream *stream = NULL; | |
190 | const bt_stream_class *stream_class = NULL; | |
191 | bt_clock_value *clock_value = NULL; | |
55595636 | 192 | bool lazy_update = false; |
d6e69534 | 193 | const bt_message *new_message = NULL; |
b19ff26f | 194 | bt_clock_class_priority_map *cc_prio_map; |
44d3cbf0 | 195 | |
d6e69534 | 196 | event = bt_message_event_get_event(message); |
f6ccaed9 | 197 | BT_ASSERT(event); |
d6e69534 PP |
198 | cc_prio_map = bt_message_event_get_clock_class_priority_map( |
199 | message); | |
f6ccaed9 | 200 | BT_ASSERT(cc_prio_map); |
19ce87a4 | 201 | writer_event = trimmer_output_event(trim_it, event); |
f6ccaed9 | 202 | BT_ASSERT(writer_event); |
d6e69534 PP |
203 | new_message = bt_message_event_create(writer_event, cc_prio_map); |
204 | BT_ASSERT(new_message); | |
65300d60 | 205 | bt_object_put_ref(cc_prio_map); |
44d3cbf0 | 206 | |
50842bdc | 207 | stream = bt_event_get_stream(event); |
f6ccaed9 | 208 | BT_ASSERT(stream); |
44d3cbf0 | 209 | |
50842bdc | 210 | stream_class = bt_stream_get_class(stream); |
f6ccaed9 | 211 | BT_ASSERT(stream_class); |
72208f03 | 212 | |
50842bdc | 213 | trace = bt_stream_class_get_trace(stream_class); |
f6ccaed9 | 214 | BT_ASSERT(trace); |
72208f03 JG |
215 | |
216 | /* FIXME multi-clock? */ | |
50842bdc | 217 | clock_class = bt_trace_get_clock_class_by_index(trace, 0); |
ac0c6bdd | 218 | if (!clock_class) { |
72208f03 | 219 | goto end; |
44d3cbf0 | 220 | } |
44d3cbf0 | 221 | |
50842bdc | 222 | clock_value = bt_event_get_clock_value(event, clock_class); |
72208f03 | 223 | if (!clock_value) { |
c59fc0d5 | 224 | BT_LOGE_STR("Failed to retrieve clock value."); |
19ce87a4 | 225 | goto error; |
44d3cbf0 | 226 | } |
72208f03 | 227 | |
50842bdc | 228 | clock_ret = bt_clock_value_get_value_ns_from_epoch( |
72208f03 JG |
229 | clock_value, &ts); |
230 | if (clock_ret) { | |
c59fc0d5 | 231 | BT_LOGE_STR("Failed to retrieve clock value timestamp."); |
19ce87a4 | 232 | goto error; |
44d3cbf0 | 233 | } |
55595636 | 234 | if (update_lazy_bound(begin, "begin", ts, &lazy_update)) { |
528debdf MD |
235 | goto end; |
236 | } | |
55595636 | 237 | if (update_lazy_bound(end, "end", ts, &lazy_update)) { |
528debdf MD |
238 | goto end; |
239 | } | |
55595636 MD |
240 | if (lazy_update && begin->set && end->set) { |
241 | if (begin->value > end->value) { | |
c59fc0d5 | 242 | BT_LOGE_STR("Unexpected: time range begin value is above end value."); |
19ce87a4 | 243 | goto error; |
55595636 MD |
244 | } |
245 | } | |
72208f03 JG |
246 | if (begin->set && ts < begin->value) { |
247 | in_range = false; | |
248 | } | |
249 | if (end->set && ts > end->value) { | |
250 | in_range = false; | |
907b1704 | 251 | *finished = true; |
72208f03 | 252 | } |
19ce87a4 JD |
253 | |
254 | goto end; | |
255 | ||
256 | error: | |
d6e69534 | 257 | BT_MESSAGE_PUT_REF_AND_RESET(new_message); |
44d3cbf0 | 258 | end: |
65300d60 PP |
259 | bt_object_put_ref(event); |
260 | bt_object_put_ref(writer_event); | |
c5b9b441 PP |
261 | bt_clock_class_put_ref(clock_class); |
262 | bt_trace_put_ref(trace); | |
263 | bt_stream_put_ref(stream); | |
264 | bt_stream_class_put_ref(stream_class); | |
65300d60 | 265 | bt_object_put_ref(clock_value); |
55595636 | 266 | *_event_in_range = in_range; |
d6e69534 | 267 | return new_message; |
44d3cbf0 JG |
268 | } |
269 | ||
44d3cbf0 | 270 | static |
b19ff26f | 271 | int ns_from_integer_field(const bt_field *integer, int64_t *ns) |
44d3cbf0 | 272 | { |
72208f03 JG |
273 | int ret = 0; |
274 | int is_signed; | |
275 | uint64_t raw_clock_value; | |
b19ff26f PP |
276 | const bt_field_class *integer_class = NULL; |
277 | const bt_clock_class *clock_class = NULL; | |
278 | bt_clock_value *clock_value = NULL; | |
44d3cbf0 | 279 | |
5cd6d0e5 PP |
280 | integer_class = bt_field_get_class(integer); |
281 | BT_ASSERT(integer_class); | |
282 | clock_class = bt_field_class_integer_get_mapped_clock_class( | |
283 | integer_class); | |
ac0c6bdd | 284 | if (!clock_class) { |
72208f03 | 285 | ret = -1; |
44d3cbf0 JG |
286 | goto end; |
287 | } | |
288 | ||
5cd6d0e5 | 289 | is_signed = bt_field_class_integer_is_signed(integer_class); |
72208f03 | 290 | if (!is_signed) { |
50842bdc | 291 | ret = bt_field_unsigned_integer_get_value(integer, |
72208f03 JG |
292 | &raw_clock_value); |
293 | if (ret) { | |
44d3cbf0 JG |
294 | goto end; |
295 | } | |
72208f03 JG |
296 | } else { |
297 | /* Signed clock values are unsupported. */ | |
a8e317ff | 298 | ret = -1; |
72208f03 JG |
299 | goto end; |
300 | } | |
44d3cbf0 | 301 | |
50842bdc | 302 | clock_value = bt_clock_value_create(clock_class, raw_clock_value); |
72208f03 JG |
303 | if (!clock_value) { |
304 | goto end; | |
305 | } | |
44d3cbf0 | 306 | |
50842bdc | 307 | ret = bt_clock_value_get_value_ns_from_epoch(clock_value, ns); |
72208f03 | 308 | end: |
c5b9b441 PP |
309 | bt_field_class_put_ref(integer_class); |
310 | bt_clock_class_put_ref(clock_class); | |
65300d60 | 311 | bt_object_put_ref(clock_value); |
72208f03 JG |
312 | return ret; |
313 | } | |
44d3cbf0 | 314 | |
19ce87a4 JD |
315 | static uint64_t ns_from_value(uint64_t frequency, uint64_t value) |
316 | { | |
317 | uint64_t ns; | |
318 | ||
319 | if (frequency == NSEC_PER_SEC) { | |
320 | ns = value; | |
321 | } else { | |
322 | ns = (uint64_t) ((1e9 * (double) value) / (double) frequency); | |
323 | } | |
324 | ||
325 | return ns; | |
326 | } | |
327 | ||
328 | /* | |
329 | * timestamp minus the offset. | |
330 | */ | |
72208f03 | 331 | static |
b19ff26f | 332 | int64_t get_raw_timestamp(const bt_packet *writer_packet, |
19ce87a4 JD |
333 | int64_t timestamp) |
334 | { | |
b19ff26f | 335 | const bt_clock_class *writer_clock_class; |
19ce87a4 | 336 | int64_t sec_offset, cycles_offset, ns; |
b19ff26f PP |
337 | const bt_trace *writer_trace; |
338 | const bt_stream *writer_stream; | |
339 | const bt_stream_class *writer_stream_class; | |
19ce87a4 JD |
340 | int ret; |
341 | uint64_t freq; | |
342 | ||
50842bdc | 343 | writer_stream = bt_packet_get_stream(writer_packet); |
f6ccaed9 | 344 | BT_ASSERT(writer_stream); |
19ce87a4 | 345 | |
50842bdc | 346 | writer_stream_class = bt_stream_get_class(writer_stream); |
f6ccaed9 | 347 | BT_ASSERT(writer_stream_class); |
19ce87a4 | 348 | |
50842bdc | 349 | writer_trace = bt_stream_class_get_trace(writer_stream_class); |
f6ccaed9 | 350 | BT_ASSERT(writer_trace); |
19ce87a4 JD |
351 | |
352 | /* FIXME multi-clock? */ | |
50842bdc | 353 | writer_clock_class = bt_trace_get_clock_class_by_index( |
9ac68eb1 | 354 | writer_trace, 0); |
f6ccaed9 | 355 | BT_ASSERT(writer_clock_class); |
19ce87a4 | 356 | |
50842bdc | 357 | ret = bt_clock_class_get_offset_s(writer_clock_class, &sec_offset); |
f6ccaed9 | 358 | BT_ASSERT(!ret); |
19ce87a4 JD |
359 | ns = sec_offset * NSEC_PER_SEC; |
360 | ||
50842bdc | 361 | freq = bt_clock_class_get_frequency(writer_clock_class); |
f6ccaed9 | 362 | BT_ASSERT(freq != -1ULL); |
19ce87a4 | 363 | |
50842bdc | 364 | ret = bt_clock_class_get_offset_cycles(writer_clock_class, &cycles_offset); |
f6ccaed9 | 365 | BT_ASSERT(!ret); |
19ce87a4 JD |
366 | |
367 | ns += ns_from_value(freq, cycles_offset); | |
368 | ||
c5b9b441 PP |
369 | bt_clock_class_put_ref(writer_clock_class); |
370 | bt_trace_put_ref(writer_trace); | |
371 | bt_stream_class_put_ref(writer_stream_class); | |
372 | bt_stream_put_ref(writer_stream); | |
19ce87a4 JD |
373 | |
374 | return timestamp - ns; | |
375 | } | |
376 | ||
377 | static | |
d6e69534 PP |
378 | const bt_message *evaluate_packet_message( |
379 | const bt_message *message, | |
19ce87a4 | 380 | struct trimmer_iterator *trim_it, |
55595636 | 381 | struct trimmer_bound *begin, struct trimmer_bound *end, |
907b1704 | 382 | bool *_packet_in_range, bool *finished) |
72208f03 | 383 | { |
72208f03 JG |
384 | int64_t begin_ns, pkt_begin_ns, end_ns, pkt_end_ns; |
385 | bool in_range = true; | |
b19ff26f PP |
386 | const bt_packet *packet = NULL, *writer_packet = NULL; |
387 | const bt_field *packet_context = NULL, | |
72208f03 JG |
388 | *timestamp_begin = NULL, |
389 | *timestamp_end = NULL; | |
d6e69534 | 390 | const bt_message *new_message = NULL; |
19ce87a4 JD |
391 | enum bt_component_status ret; |
392 | bool lazy_update = false; | |
72208f03 | 393 | |
d6e69534 PP |
394 | switch (bt_message_get_type(message)) { |
395 | case BT_MESSAGE_TYPE_PACKET_BEGINNING: | |
396 | packet = bt_message_packet_beginning_get_packet(message); | |
f6ccaed9 | 397 | BT_ASSERT(packet); |
19ce87a4 | 398 | writer_packet = trimmer_new_packet(trim_it, packet); |
f6ccaed9 | 399 | BT_ASSERT(writer_packet); |
44d3cbf0 | 400 | break; |
d6e69534 PP |
401 | case BT_MESSAGE_TYPE_PACKET_END: |
402 | packet = bt_message_packet_end_get_packet(message); | |
f6ccaed9 | 403 | BT_ASSERT(packet); |
19ce87a4 | 404 | writer_packet = trimmer_close_packet(trim_it, packet); |
f6ccaed9 | 405 | BT_ASSERT(writer_packet); |
72208f03 JG |
406 | break; |
407 | default: | |
19ce87a4 | 408 | goto end; |
44d3cbf0 | 409 | } |
72208f03 | 410 | |
50842bdc | 411 | packet_context = bt_packet_get_context(writer_packet); |
72208f03 | 412 | if (!packet_context) { |
d6e69534 | 413 | goto end_no_msg; |
72208f03 JG |
414 | } |
415 | ||
50842bdc | 416 | if (!bt_field_is_structure(packet_context)) { |
d6e69534 | 417 | goto end_no_msg; |
72208f03 JG |
418 | } |
419 | ||
50842bdc | 420 | timestamp_begin = bt_field_structure_get_field_by_name( |
72208f03 | 421 | packet_context, "timestamp_begin"); |
50842bdc | 422 | if (!timestamp_begin || !bt_field_is_integer(timestamp_begin)) { |
d6e69534 | 423 | goto end_no_msg; |
72208f03 | 424 | } |
50842bdc | 425 | timestamp_end = bt_field_structure_get_field_by_name( |
72208f03 | 426 | packet_context, "timestamp_end"); |
50842bdc | 427 | if (!timestamp_end || !bt_field_is_integer(timestamp_end)) { |
d6e69534 | 428 | goto end_no_msg; |
72208f03 JG |
429 | } |
430 | ||
55595636 | 431 | if (ns_from_integer_field(timestamp_begin, &pkt_begin_ns)) { |
d6e69534 | 432 | goto end_no_msg; |
72208f03 | 433 | } |
55595636 | 434 | if (ns_from_integer_field(timestamp_end, &pkt_end_ns)) { |
d6e69534 | 435 | goto end_no_msg; |
19ce87a4 JD |
436 | } |
437 | ||
438 | if (update_lazy_bound(begin, "begin", pkt_begin_ns, &lazy_update)) { | |
d6e69534 | 439 | goto end_no_msg; |
19ce87a4 JD |
440 | } |
441 | if (update_lazy_bound(end, "end", pkt_end_ns, &lazy_update)) { | |
d6e69534 | 442 | goto end_no_msg; |
19ce87a4 JD |
443 | } |
444 | if (lazy_update && begin->set && end->set) { | |
445 | if (begin->value > end->value) { | |
c59fc0d5 | 446 | BT_LOGE_STR("Unexpected: time range begin value is above end value."); |
d6e69534 | 447 | goto end_no_msg; |
19ce87a4 | 448 | } |
72208f03 JG |
449 | } |
450 | ||
451 | begin_ns = begin->set ? begin->value : INT64_MIN; | |
452 | end_ns = end->set ? end->value : INT64_MAX; | |
453 | ||
454 | /* | |
455 | * Accept if there is any overlap between the selected region and the | |
456 | * packet. | |
457 | */ | |
458 | in_range = (pkt_end_ns >= begin_ns) && (pkt_begin_ns <= end_ns); | |
19ce87a4 | 459 | if (!in_range) { |
d6e69534 | 460 | goto end_no_msg; |
19ce87a4 | 461 | } |
907b1704 JD |
462 | if (pkt_begin_ns > end_ns) { |
463 | *finished = true; | |
464 | } | |
19ce87a4 JD |
465 | |
466 | if (begin_ns > pkt_begin_ns) { | |
467 | ret = update_packet_context_field(trim_it->err, writer_packet, | |
468 | "timestamp_begin", | |
469 | get_raw_timestamp(writer_packet, begin_ns)); | |
f6ccaed9 | 470 | BT_ASSERT(!ret); |
19ce87a4 JD |
471 | } |
472 | ||
473 | if (end_ns < pkt_end_ns) { | |
474 | ret = update_packet_context_field(trim_it->err, writer_packet, | |
475 | "timestamp_end", | |
476 | get_raw_timestamp(writer_packet, end_ns)); | |
f6ccaed9 | 477 | BT_ASSERT(!ret); |
19ce87a4 JD |
478 | } |
479 | ||
72208f03 | 480 | end: |
d6e69534 PP |
481 | switch (bt_message_get_type(message)) { |
482 | case BT_MESSAGE_TYPE_PACKET_BEGINNING: | |
483 | new_message = bt_message_packet_beginning_create(writer_packet); | |
484 | BT_ASSERT(new_message); | |
19ce87a4 | 485 | break; |
d6e69534 PP |
486 | case BT_MESSAGE_TYPE_PACKET_END: |
487 | new_message = bt_message_packet_end_create(writer_packet); | |
488 | BT_ASSERT(new_message); | |
19ce87a4 JD |
489 | break; |
490 | default: | |
491 | break; | |
492 | } | |
d6e69534 | 493 | end_no_msg: |
55595636 | 494 | *_packet_in_range = in_range; |
c5b9b441 PP |
495 | bt_packet_put_ref(packet); |
496 | bt_packet_put_ref(writer_packet); | |
65300d60 PP |
497 | bt_object_put_ref(packet_context); |
498 | bt_object_put_ref(timestamp_begin); | |
499 | bt_object_put_ref(timestamp_end); | |
d6e69534 | 500 | return new_message; |
19ce87a4 JD |
501 | } |
502 | ||
503 | static | |
d6e69534 PP |
504 | const bt_message *evaluate_stream_message( |
505 | const bt_message *message, | |
19ce87a4 JD |
506 | struct trimmer_iterator *trim_it) |
507 | { | |
b19ff26f | 508 | const bt_stream *stream; |
19ce87a4 | 509 | |
d6e69534 | 510 | stream = bt_message_stream_end_get_stream(message); |
f6ccaed9 | 511 | BT_ASSERT(stream); |
19ce87a4 JD |
512 | |
513 | /* FIXME: useless copy */ | |
d6e69534 | 514 | return bt_message_stream_end_create(stream); |
72208f03 JG |
515 | } |
516 | ||
d6e69534 | 517 | /* Return true if the message should be forwarded. */ |
72208f03 | 518 | static |
d6e69534 PP |
519 | enum bt_message_iterator_status evaluate_message( |
520 | const bt_message **message, | |
19ce87a4 | 521 | struct trimmer_iterator *trim_it, |
55595636 MD |
522 | struct trimmer_bound *begin, struct trimmer_bound *end, |
523 | bool *in_range) | |
72208f03 | 524 | { |
d6e69534 PP |
525 | enum bt_message_type type; |
526 | const bt_message *new_message = NULL; | |
907b1704 | 527 | bool finished = false; |
72208f03 | 528 | |
b61397c4 | 529 | *in_range = true; |
d6e69534 | 530 | type = bt_message_get_type(*message); |
72208f03 | 531 | switch (type) { |
d6e69534 PP |
532 | case BT_MESSAGE_TYPE_EVENT: |
533 | new_message = evaluate_event_message(*message, | |
907b1704 | 534 | trim_it, begin, end, in_range, &finished); |
72208f03 | 535 | break; |
d6e69534 PP |
536 | case BT_MESSAGE_TYPE_PACKET_BEGINNING: |
537 | case BT_MESSAGE_TYPE_PACKET_END: | |
538 | new_message = evaluate_packet_message(*message, | |
907b1704 | 539 | trim_it, begin, end, in_range, &finished); |
19ce87a4 | 540 | break; |
d6e69534 PP |
541 | case BT_MESSAGE_TYPE_STREAM_END: |
542 | new_message = evaluate_stream_message(*message, | |
19ce87a4 | 543 | trim_it); |
72208f03 | 544 | break; |
44d3cbf0 JG |
545 | default: |
546 | break; | |
547 | } | |
d6e69534 PP |
548 | BT_MESSAGE_PUT_REF_AND_RESET(*message); |
549 | *message = new_message; | |
19ce87a4 | 550 | |
907b1704 | 551 | if (finished) { |
d6e69534 | 552 | return BT_MESSAGE_ITERATOR_STATUS_END; |
907b1704 JD |
553 | } |
554 | ||
d6e69534 | 555 | return BT_MESSAGE_ITERATOR_STATUS_OK; |
cab3f160 JG |
556 | } |
557 | ||
558 | BT_HIDDEN | |
d6e69534 PP |
559 | bt_message_iterator_next_method_return trimmer_iterator_next( |
560 | bt_self_message_iterator *iterator) | |
cab3f160 | 561 | { |
44d3cbf0 | 562 | struct trimmer_iterator *trim_it = NULL; |
b19ff26f | 563 | bt_self_component *component = NULL; |
44d3cbf0 | 564 | struct trimmer *trimmer = NULL; |
d6e69534 PP |
565 | bt_message_iterator *source_it = NULL; |
566 | bt_message_iterator_next_method_return ret = { | |
567 | .status = BT_MESSAGE_ITERATOR_STATUS_OK, | |
568 | .message = NULL, | |
41a2b7ae | 569 | }; |
d6e69534 | 570 | bool message_in_range = false; |
cab3f160 | 571 | |
d6e69534 | 572 | trim_it = bt_self_message_iterator_get_user_data(iterator); |
f6ccaed9 | 573 | BT_ASSERT(trim_it); |
44d3cbf0 | 574 | |
d6e69534 | 575 | component = bt_self_message_iterator_get_private_component( |
890882ef | 576 | iterator); |
f6ccaed9 | 577 | BT_ASSERT(component); |
d94d92ac | 578 | trimmer = bt_self_component_get_user_data(component); |
f6ccaed9 | 579 | BT_ASSERT(trimmer); |
44d3cbf0 | 580 | |
99cdb69e | 581 | source_it = trim_it->input_iterator; |
f6ccaed9 | 582 | BT_ASSERT(source_it); |
44d3cbf0 | 583 | |
d6e69534 PP |
584 | while (!message_in_range) { |
585 | ret.status = bt_message_iterator_next(source_it); | |
586 | if (ret.status != BT_MESSAGE_ITERATOR_STATUS_OK) { | |
44d3cbf0 JG |
587 | goto end; |
588 | } | |
589 | ||
d6e69534 | 590 | ret.message = bt_message_iterator_get_message( |
44d3cbf0 | 591 | source_it); |
d6e69534 PP |
592 | if (!ret.message) { |
593 | ret.status = BT_MESSAGE_ITERATOR_STATUS_ERROR; | |
44d3cbf0 JG |
594 | goto end; |
595 | } | |
596 | ||
d6e69534 | 597 | ret.status = evaluate_message(&ret.message, trim_it, |
55595636 | 598 | &trimmer->begin, &trimmer->end, |
d6e69534 PP |
599 | &message_in_range); |
600 | if (!message_in_range) { | |
601 | BT_OBJECT_PUT_REF_AND_RESET(ret.message); | |
44d3cbf0 | 602 | } |
6d5f6792 | 603 | |
d6e69534 | 604 | if (ret.status != BT_MESSAGE_ITERATOR_STATUS_OK) { |
6d5f6792 JG |
605 | break; |
606 | } | |
44d3cbf0 | 607 | } |
cab3f160 | 608 | end: |
65300d60 | 609 | bt_object_put_ref(component); |
cab3f160 JG |
610 | return ret; |
611 | } |