trimmer: Update the bounds of the trimmed packets
[babeltrace.git] / plugins / utils / trimmer / copy.c
1 /*
2 * copy.c
3 *
4 * Babeltrace Copy Trace Structure
5 *
6 * Copyright 2017 Julien Desfossez <jdesfossez@efficios.com>
7 *
8 * Author: Julien Desfossez <jdesfossez@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
29 #include <babeltrace/ctf-ir/event.h>
30 #include <babeltrace/ctf-ir/packet.h>
31 #include <babeltrace/ctf-ir/event-class.h>
32 #include <babeltrace/ctf-ir/stream.h>
33 #include <babeltrace/ctf-ir/stream-class.h>
34 #include <babeltrace/ctf-ir/clock-class.h>
35 #include <babeltrace/ctf-ir/fields.h>
36 #include <babeltrace/ctf-writer/stream-class.h>
37 #include <babeltrace/ctf-writer/stream.h>
38
39 #include <ctfcopytrace.h>
40 #include "iterator.h"
41
42 static
43 struct bt_ctf_packet *lookup_packet(struct trimmer_iterator *trim_it,
44 struct bt_ctf_packet *packet)
45 {
46 return (struct bt_ctf_packet *) g_hash_table_lookup(
47 trim_it->packet_map,
48 (gpointer) packet);
49 }
50
51 static
52 struct bt_ctf_packet *insert_new_packet(struct trimmer_iterator *trim_it,
53 struct bt_ctf_packet *packet,
54 struct bt_ctf_stream *stream)
55 {
56 struct bt_ctf_packet *writer_packet;
57
58 writer_packet = bt_ctf_packet_create(stream);
59 if (!writer_packet) {
60 fprintf(trim_it->err, "[error] %s in %s:%d\n", __func__,
61 __FILE__, __LINE__);
62 goto end;
63 }
64 g_hash_table_insert(trim_it->packet_map, (gpointer) packet, writer_packet);
65
66 end:
67 return writer_packet;
68 }
69
70 BT_HIDDEN
71 enum bt_component_status update_packet_context_field(FILE *err,
72 struct bt_ctf_packet *writer_packet,
73 const char *name, int64_t value)
74 {
75 enum bt_component_status ret;
76 struct bt_ctf_field *packet_context, *writer_packet_context;
77 struct bt_ctf_field_type *struct_type, *writer_packet_context_type;
78 struct bt_ctf_stream_class *stream_class;
79 struct bt_ctf_stream *stream;
80 int nr_fields, i, int_ret;
81
82 packet_context = bt_ctf_packet_get_context(writer_packet);
83 if (!packet_context) {
84 ret = BT_COMPONENT_STATUS_ERROR;
85 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
86 __LINE__);
87 goto end;
88 }
89
90 stream = bt_ctf_packet_get_stream(writer_packet);
91 if (!stream) {
92 ret = BT_COMPONENT_STATUS_ERROR;
93 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
94 __LINE__);
95 goto end_put_packet_context;
96 }
97
98 stream_class = bt_ctf_stream_get_class(stream);
99 if (!stream_class) {
100 ret = BT_COMPONENT_STATUS_ERROR;
101 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
102 __LINE__);
103 goto end_put_stream;
104 }
105
106 writer_packet_context_type = bt_ctf_stream_class_get_packet_context_type(
107 stream_class);
108 if (!writer_packet_context_type) {
109 ret = BT_COMPONENT_STATUS_ERROR;
110 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
111 __LINE__);
112 goto end_put_stream_class;
113 }
114
115 struct_type = bt_ctf_field_get_type(packet_context);
116 if (!struct_type) {
117 ret = BT_COMPONENT_STATUS_ERROR;
118 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
119 __LINE__);
120 goto end_put_writer_packet_context_type;
121 }
122
123 writer_packet_context = bt_ctf_packet_get_context(writer_packet);
124 if (!writer_packet_context) {
125 ret = BT_COMPONENT_STATUS_ERROR;
126 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
127 __LINE__);
128 goto end_put_struct_type;
129 }
130
131 nr_fields = bt_ctf_field_type_structure_get_field_count(struct_type);
132 for (i = 0; i < nr_fields; i++) {
133 struct bt_ctf_field *field, *writer_field;
134 struct bt_ctf_field_type *field_type;
135 const char *field_name;
136
137 field = bt_ctf_field_structure_get_field_by_index(
138 packet_context, i);
139 if (!field) {
140 ret = BT_COMPONENT_STATUS_ERROR;
141 fprintf(err, "[error] %s in %s:%d\n", __func__,
142 __FILE__, __LINE__);
143 goto end_put_writer_packet_context;
144 }
145 if (bt_ctf_field_type_structure_get_field(struct_type,
146 &field_name, &field_type, i) < 0) {
147 ret = BT_COMPONENT_STATUS_ERROR;
148 bt_put(field);
149 fprintf(err, "[error] %s in %s:%d\n", __func__,
150 __FILE__, __LINE__);
151 goto end_put_writer_packet_context;
152 }
153 if (strcmp(field_name, name)) {
154 bt_put(field_type);
155 bt_put(field);
156 continue;
157 }
158 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_TYPE_ID_INTEGER) {
159 fprintf(err, "[error] Unexpected packet context field type\n");
160 bt_put(field);
161 ret = BT_COMPONENT_STATUS_ERROR;
162 goto end_put_writer_packet_context;
163 }
164 writer_field = bt_ctf_field_structure_get_field(writer_packet_context,
165 field_name);
166 if (!writer_field) {
167 ret = BT_COMPONENT_STATUS_ERROR;
168 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
169 __LINE__);
170 goto end;
171 }
172
173 int_ret = bt_ctf_field_unsigned_integer_set_value(writer_field, value);
174 bt_put(writer_field);
175 if (int_ret < 0) {
176 ret = BT_COMPONENT_STATUS_ERROR;
177 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
178 __LINE__);
179 goto end_put_writer_packet_context;
180 }
181
182 bt_put(field_type);
183 bt_put(field);
184 }
185
186 ret = BT_COMPONENT_STATUS_OK;
187
188 end_put_writer_packet_context:
189 bt_put(writer_packet_context);
190 end_put_struct_type:
191 bt_put(struct_type);
192 end_put_writer_packet_context_type:
193 bt_put(writer_packet_context_type);
194 end_put_stream_class:
195 bt_put(stream_class);
196 end_put_packet_context:
197 bt_put(packet_context);
198 end_put_stream:
199 bt_put(stream);
200 end:
201 return ret;
202 }
203
204 BT_HIDDEN
205 struct bt_ctf_packet *trimmer_new_packet(
206 struct trimmer_iterator *trim_it,
207 struct bt_ctf_packet *packet)
208 {
209 struct bt_ctf_stream *stream;
210 struct bt_ctf_field *writer_packet_context;
211 struct bt_ctf_packet *writer_packet = NULL;
212 int int_ret;
213
214 stream = bt_ctf_packet_get_stream(packet);
215 if (!stream) {
216 fprintf(trim_it->err, "[error] %s in %s:%d\n",
217 __func__, __FILE__, __LINE__);
218 goto end;
219 }
220
221 /*
222 * If a packet was already opened, close it and remove it from
223 * the HT.
224 */
225 writer_packet = lookup_packet(trim_it, packet);
226 if (writer_packet) {
227 g_hash_table_remove(trim_it->packet_map, packet);
228 bt_put(writer_packet);
229 }
230
231 writer_packet = insert_new_packet(trim_it, packet, stream);
232 if (!writer_packet) {
233 fprintf(trim_it->err, "[error] %s in %s:%d\n",
234 __func__, __FILE__, __LINE__);
235 goto end_put_stream;
236 }
237 bt_get(writer_packet);
238
239 writer_packet_context = ctf_copy_packet_context(trim_it->err, packet,
240 stream);
241 if (!writer_packet_context) {
242 BT_PUT(writer_packet);
243 fprintf(trim_it->err, "[error] %s in %s:%d\n",
244 __func__, __FILE__, __LINE__);
245 goto end_put_stream;
246 }
247
248 int_ret = bt_ctf_packet_set_context(writer_packet, writer_packet_context);
249 if (int_ret) {
250 BT_PUT(writer_packet);
251 fprintf(trim_it->err, "[error] %s in %s:%d\n",
252 __func__, __FILE__, __LINE__);
253 goto end_put_writer_packet_context;
254 }
255
256 end_put_writer_packet_context:
257 bt_put(writer_packet_context);
258 end_put_stream:
259 bt_put(stream);
260 end:
261 return writer_packet;
262 }
263
264 BT_HIDDEN
265 struct bt_ctf_packet *trimmer_close_packet(
266 struct trimmer_iterator *trim_it,
267 struct bt_ctf_packet *packet)
268 {
269 struct bt_ctf_packet *writer_packet;
270
271 writer_packet = lookup_packet(trim_it, packet);
272 if (!writer_packet) {
273 fprintf(trim_it->err, "[error] %s in %s:%d\n", __func__,
274 __FILE__, __LINE__);
275 goto end;
276 }
277
278 g_hash_table_remove(trim_it->packet_map, packet);
279
280 end:
281 return writer_packet;
282 }
283
284 BT_HIDDEN
285 struct bt_ctf_event *trimmer_output_event(
286 struct trimmer_iterator *trim_it,
287 struct bt_ctf_event *event)
288 {
289 struct bt_ctf_event_class *event_class;
290 struct bt_ctf_stream *stream;
291 struct bt_ctf_stream_class *stream_class;
292 struct bt_ctf_event *writer_event = NULL;
293 struct bt_ctf_packet *packet, *writer_packet;
294 const char *event_name;
295 int int_ret;
296
297 event_class = bt_ctf_event_get_class(event);
298 if (!event_class) {
299 fprintf(trim_it->err, "[error] %s in %s:%d\n", __func__,
300 __FILE__, __LINE__);
301 goto end;
302 }
303
304 event_name = bt_ctf_event_class_get_name(event_class);
305 if (!event_name) {
306 fprintf(trim_it->err, "[error] %s in %s:%d\n", __func__,
307 __FILE__, __LINE__);
308 goto end_put_event_class;
309 }
310
311 stream = bt_ctf_event_get_stream(event);
312 if (!stream) {
313 fprintf(trim_it->err, "[error] %s in %s:%d\n", __func__,
314 __FILE__, __LINE__);
315 goto end_put_event_class;
316 }
317
318 stream_class = bt_ctf_event_class_get_stream_class(event_class);
319 if (!stream_class) {
320 fprintf(trim_it->err, "[error] %s in %s:%d\n", __func__,
321 __FILE__, __LINE__);
322 goto end_put_stream;
323 }
324
325 writer_event = ctf_copy_event(trim_it->err, event, event_class, false);
326 if (!writer_event) {
327 fprintf(trim_it->err, "[error] %s in %s:%d\n", __func__,
328 __FILE__, __LINE__);
329 fprintf(trim_it->err, "[error] Failed to copy event %s\n",
330 bt_ctf_event_class_get_name(event_class));
331 goto end_put_stream_class;
332 }
333
334 packet = bt_ctf_event_get_packet(event);
335 if (!packet) {
336 BT_PUT(writer_event);
337 fprintf(trim_it->err, "[error] %s in %s:%d\n", __func__,
338 __FILE__, __LINE__);
339 goto end_put_stream_class;
340 }
341
342 writer_packet = lookup_packet(trim_it, packet);
343 if (!writer_packet) {
344 BT_PUT(writer_event);
345 fprintf(trim_it->err, "[error] %s in %s:%d\n", __func__,
346 __FILE__, __LINE__);
347 goto end_put_packet;
348 }
349 bt_get(writer_packet);
350
351 int_ret = bt_ctf_event_set_packet(writer_event, writer_packet);
352 if (int_ret < 0) {
353 BT_PUT(writer_event);
354 fprintf(trim_it->err, "[error] %s in %s:%d\n", __func__,
355 __FILE__, __LINE__);
356 fprintf(trim_it->err, "[error] Failed to append event %s\n",
357 bt_ctf_event_class_get_name(event_class));
358 goto end_put_writer_packet;
359 }
360
361 /* We keep the reference on the writer event */
362
363 end_put_writer_packet:
364 bt_put(writer_packet);
365 end_put_packet:
366 bt_put(packet);
367 end_put_stream_class:
368 bt_put(stream_class);
369 end_put_stream:
370 bt_put(stream);
371 end_put_event_class:
372 bt_put(event_class);
373 end:
374 return writer_event;
375 }
This page took 0.036711 seconds and 4 git commands to generate.