Commit | Line | Data |
---|---|---|
19ce87a4 JD |
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 | { | |
9ae49d3d | 56 | struct bt_ctf_packet *writer_packet = NULL; |
19ce87a4 JD |
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; | |
9ae49d3d JD |
76 | struct bt_ctf_field *packet_context = NULL, *writer_packet_context = NULL; |
77 | struct bt_ctf_field_type *struct_type = NULL, *field_type = NULL; | |
78 | struct bt_ctf_field *field = NULL, *writer_field = NULL; | |
19ce87a4 JD |
79 | int nr_fields, i, int_ret; |
80 | ||
81 | packet_context = bt_ctf_packet_get_context(writer_packet); | |
82 | if (!packet_context) { | |
19ce87a4 JD |
83 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, |
84 | __LINE__); | |
9ae49d3d | 85 | goto error; |
19ce87a4 JD |
86 | } |
87 | ||
88 | struct_type = bt_ctf_field_get_type(packet_context); | |
89 | if (!struct_type) { | |
19ce87a4 JD |
90 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, |
91 | __LINE__); | |
9ae49d3d | 92 | goto error; |
19ce87a4 JD |
93 | } |
94 | ||
95 | writer_packet_context = bt_ctf_packet_get_context(writer_packet); | |
96 | if (!writer_packet_context) { | |
19ce87a4 JD |
97 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, |
98 | __LINE__); | |
9ae49d3d | 99 | goto error; |
19ce87a4 JD |
100 | } |
101 | ||
102 | nr_fields = bt_ctf_field_type_structure_get_field_count(struct_type); | |
103 | for (i = 0; i < nr_fields; i++) { | |
19ce87a4 JD |
104 | const char *field_name; |
105 | ||
106 | field = bt_ctf_field_structure_get_field_by_index( | |
107 | packet_context, i); | |
108 | if (!field) { | |
19ce87a4 JD |
109 | fprintf(err, "[error] %s in %s:%d\n", __func__, |
110 | __FILE__, __LINE__); | |
9ae49d3d | 111 | goto error; |
19ce87a4 JD |
112 | } |
113 | if (bt_ctf_field_type_structure_get_field(struct_type, | |
114 | &field_name, &field_type, i) < 0) { | |
19ce87a4 JD |
115 | fprintf(err, "[error] %s in %s:%d\n", __func__, |
116 | __FILE__, __LINE__); | |
9ae49d3d | 117 | goto error; |
19ce87a4 JD |
118 | } |
119 | if (strcmp(field_name, name)) { | |
9ae49d3d JD |
120 | BT_PUT(field_type); |
121 | BT_PUT(field); | |
19ce87a4 JD |
122 | continue; |
123 | } | |
1487a16a | 124 | if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) { |
19ce87a4 | 125 | fprintf(err, "[error] Unexpected packet context field type\n"); |
9ae49d3d | 126 | goto error; |
19ce87a4 JD |
127 | } |
128 | writer_field = bt_ctf_field_structure_get_field(writer_packet_context, | |
129 | field_name); | |
130 | if (!writer_field) { | |
19ce87a4 JD |
131 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, |
132 | __LINE__); | |
9ae49d3d | 133 | goto error; |
19ce87a4 JD |
134 | } |
135 | ||
136 | int_ret = bt_ctf_field_unsigned_integer_set_value(writer_field, value); | |
19ce87a4 | 137 | if (int_ret < 0) { |
19ce87a4 JD |
138 | fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, |
139 | __LINE__); | |
9ae49d3d | 140 | goto error; |
19ce87a4 | 141 | } |
9ae49d3d JD |
142 | BT_PUT(writer_field); |
143 | BT_PUT(field_type); | |
144 | BT_PUT(field); | |
19ce87a4 JD |
145 | } |
146 | ||
147 | ret = BT_COMPONENT_STATUS_OK; | |
9ae49d3d | 148 | goto end; |
19ce87a4 | 149 | |
9ae49d3d JD |
150 | error: |
151 | bt_put(writer_field); | |
152 | bt_put(field_type); | |
153 | bt_put(field); | |
154 | ret = BT_COMPONENT_STATUS_ERROR; | |
155 | end: | |
19ce87a4 | 156 | bt_put(struct_type); |
19ce87a4 | 157 | bt_put(packet_context); |
19ce87a4 JD |
158 | return ret; |
159 | } | |
160 | ||
161 | BT_HIDDEN | |
162 | struct bt_ctf_packet *trimmer_new_packet( | |
163 | struct trimmer_iterator *trim_it, | |
164 | struct bt_ctf_packet *packet) | |
165 | { | |
9ae49d3d JD |
166 | struct bt_ctf_stream *stream = NULL; |
167 | struct bt_ctf_field *writer_packet_context = NULL; | |
19ce87a4 JD |
168 | struct bt_ctf_packet *writer_packet = NULL; |
169 | int int_ret; | |
170 | ||
171 | stream = bt_ctf_packet_get_stream(packet); | |
172 | if (!stream) { | |
173 | fprintf(trim_it->err, "[error] %s in %s:%d\n", | |
174 | __func__, __FILE__, __LINE__); | |
9ae49d3d | 175 | goto error; |
19ce87a4 JD |
176 | } |
177 | ||
178 | /* | |
179 | * If a packet was already opened, close it and remove it from | |
180 | * the HT. | |
181 | */ | |
182 | writer_packet = lookup_packet(trim_it, packet); | |
183 | if (writer_packet) { | |
184 | g_hash_table_remove(trim_it->packet_map, packet); | |
9ae49d3d | 185 | BT_PUT(writer_packet); |
19ce87a4 JD |
186 | } |
187 | ||
188 | writer_packet = insert_new_packet(trim_it, packet, stream); | |
189 | if (!writer_packet) { | |
190 | fprintf(trim_it->err, "[error] %s in %s:%d\n", | |
191 | __func__, __FILE__, __LINE__); | |
9ae49d3d | 192 | goto error; |
19ce87a4 JD |
193 | } |
194 | bt_get(writer_packet); | |
195 | ||
196 | writer_packet_context = ctf_copy_packet_context(trim_it->err, packet, | |
ab80adac | 197 | stream, 0); |
19ce87a4 | 198 | if (!writer_packet_context) { |
19ce87a4 JD |
199 | fprintf(trim_it->err, "[error] %s in %s:%d\n", |
200 | __func__, __FILE__, __LINE__); | |
9ae49d3d | 201 | goto error; |
19ce87a4 JD |
202 | } |
203 | ||
204 | int_ret = bt_ctf_packet_set_context(writer_packet, writer_packet_context); | |
205 | if (int_ret) { | |
19ce87a4 JD |
206 | fprintf(trim_it->err, "[error] %s in %s:%d\n", |
207 | __func__, __FILE__, __LINE__); | |
9ae49d3d | 208 | goto error; |
19ce87a4 JD |
209 | } |
210 | ||
9ae49d3d JD |
211 | goto end; |
212 | ||
213 | error: | |
214 | BT_PUT(writer_packet); | |
215 | end: | |
19ce87a4 | 216 | bt_put(writer_packet_context); |
19ce87a4 | 217 | bt_put(stream); |
19ce87a4 JD |
218 | return writer_packet; |
219 | } | |
220 | ||
221 | BT_HIDDEN | |
222 | struct bt_ctf_packet *trimmer_close_packet( | |
223 | struct trimmer_iterator *trim_it, | |
224 | struct bt_ctf_packet *packet) | |
225 | { | |
9ae49d3d | 226 | struct bt_ctf_packet *writer_packet = NULL; |
19ce87a4 JD |
227 | |
228 | writer_packet = lookup_packet(trim_it, packet); | |
229 | if (!writer_packet) { | |
230 | fprintf(trim_it->err, "[error] %s in %s:%d\n", __func__, | |
231 | __FILE__, __LINE__); | |
232 | goto end; | |
233 | } | |
234 | ||
235 | g_hash_table_remove(trim_it->packet_map, packet); | |
236 | ||
237 | end: | |
238 | return writer_packet; | |
239 | } | |
240 | ||
241 | BT_HIDDEN | |
242 | struct bt_ctf_event *trimmer_output_event( | |
243 | struct trimmer_iterator *trim_it, | |
244 | struct bt_ctf_event *event) | |
245 | { | |
9ae49d3d | 246 | struct bt_ctf_event_class *event_class = NULL; |
19ce87a4 | 247 | struct bt_ctf_event *writer_event = NULL; |
9ae49d3d | 248 | struct bt_ctf_packet *packet = NULL, *writer_packet = NULL; |
19ce87a4 JD |
249 | const char *event_name; |
250 | int int_ret; | |
251 | ||
252 | event_class = bt_ctf_event_get_class(event); | |
253 | if (!event_class) { | |
254 | fprintf(trim_it->err, "[error] %s in %s:%d\n", __func__, | |
255 | __FILE__, __LINE__); | |
9ae49d3d | 256 | goto error; |
19ce87a4 JD |
257 | } |
258 | ||
259 | event_name = bt_ctf_event_class_get_name(event_class); | |
260 | if (!event_name) { | |
261 | fprintf(trim_it->err, "[error] %s in %s:%d\n", __func__, | |
262 | __FILE__, __LINE__); | |
9ae49d3d | 263 | goto error; |
19ce87a4 JD |
264 | } |
265 | ||
266 | writer_event = ctf_copy_event(trim_it->err, event, event_class, false); | |
267 | if (!writer_event) { | |
268 | fprintf(trim_it->err, "[error] %s in %s:%d\n", __func__, | |
269 | __FILE__, __LINE__); | |
270 | fprintf(trim_it->err, "[error] Failed to copy event %s\n", | |
271 | bt_ctf_event_class_get_name(event_class)); | |
9ae49d3d | 272 | goto error; |
19ce87a4 JD |
273 | } |
274 | ||
275 | packet = bt_ctf_event_get_packet(event); | |
276 | if (!packet) { | |
19ce87a4 JD |
277 | fprintf(trim_it->err, "[error] %s in %s:%d\n", __func__, |
278 | __FILE__, __LINE__); | |
9ae49d3d | 279 | goto error; |
19ce87a4 JD |
280 | } |
281 | ||
282 | writer_packet = lookup_packet(trim_it, packet); | |
283 | if (!writer_packet) { | |
19ce87a4 JD |
284 | fprintf(trim_it->err, "[error] %s in %s:%d\n", __func__, |
285 | __FILE__, __LINE__); | |
9ae49d3d | 286 | goto error; |
19ce87a4 JD |
287 | } |
288 | bt_get(writer_packet); | |
289 | ||
290 | int_ret = bt_ctf_event_set_packet(writer_event, writer_packet); | |
291 | if (int_ret < 0) { | |
19ce87a4 JD |
292 | fprintf(trim_it->err, "[error] %s in %s:%d\n", __func__, |
293 | __FILE__, __LINE__); | |
294 | fprintf(trim_it->err, "[error] Failed to append event %s\n", | |
295 | bt_ctf_event_class_get_name(event_class)); | |
9ae49d3d | 296 | goto error; |
19ce87a4 JD |
297 | } |
298 | ||
9ae49d3d JD |
299 | /* We keep the reference on the writer_event to create a notification. */ |
300 | goto end; | |
19ce87a4 | 301 | |
9ae49d3d JD |
302 | error: |
303 | BT_PUT(writer_event); | |
304 | end: | |
19ce87a4 | 305 | bt_put(writer_packet); |
19ce87a4 | 306 | bt_put(packet); |
19ce87a4 | 307 | bt_put(event_class); |
19ce87a4 JD |
308 | return writer_event; |
309 | } |