Python bindings: add has_intersection property to TraceCollection
[babeltrace.git] / types / sequence.c
1 /*
2 * sequence.c
3 *
4 * BabelTrace - Sequence Type Converter
5 *
6 * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
7 *
8 * Author: Mathieu Desnoyers <mathieu.desnoyers@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/compiler.h>
30 #include <babeltrace/format.h>
31 #include <babeltrace/types.h>
32 #include <inttypes.h>
33
34 static
35 struct bt_definition *_sequence_definition_new(struct bt_declaration *declaration,
36 struct definition_scope *parent_scope,
37 GQuark field_name, int index,
38 const char *root_name);
39 static
40 void _sequence_definition_free(struct bt_definition *definition);
41
42 int bt_sequence_rw(struct bt_stream_pos *pos, struct bt_definition *definition)
43 {
44 struct definition_sequence *sequence_definition =
45 container_of(definition, struct definition_sequence, p);
46 const struct declaration_sequence *sequence_declaration =
47 sequence_definition->declaration;
48 uint64_t len, oldlen, i;
49 int ret;
50
51 len = sequence_definition->length->value._unsigned;
52 /*
53 * Yes, large sequences could be _painfully slow_ to parse due
54 * to memory allocation for each event read. At least, never
55 * shrink the sequence. Note: the sequence GArray len should
56 * never be used as indicator of the current sequence length.
57 * One should always look at the sequence->len->value._unsigned
58 * value for that.
59 */
60 oldlen = sequence_definition->elems->len;
61 if (oldlen < len)
62 g_ptr_array_set_size(sequence_definition->elems, len);
63
64 for (i = oldlen; i < len; i++) {
65 struct bt_definition **field;
66 GString *str;
67 GQuark name;
68
69 str = g_string_new("");
70 g_string_printf(str, "[%" PRIu64 "]", i);
71 name = g_quark_from_string(str->str);
72 (void) g_string_free(str, TRUE);
73
74 field = (struct bt_definition **) &g_ptr_array_index(sequence_definition->elems, i);
75 *field = sequence_declaration->elem->definition_new(sequence_declaration->elem,
76 sequence_definition->p.scope,
77 name, i, NULL);
78 }
79 for (i = 0; i < len; i++) {
80 struct bt_definition **field;
81
82 field = (struct bt_definition **) &g_ptr_array_index(sequence_definition->elems, i);
83 ret = generic_rw(pos, *field);
84 if (ret)
85 return ret;
86 }
87 return 0;
88 }
89
90 static
91 void _sequence_declaration_free(struct bt_declaration *declaration)
92 {
93 struct declaration_sequence *sequence_declaration =
94 container_of(declaration, struct declaration_sequence, p);
95
96 bt_free_declaration_scope(sequence_declaration->scope);
97 g_array_free(sequence_declaration->length_name, TRUE);
98 bt_declaration_unref(sequence_declaration->elem);
99 g_free(sequence_declaration);
100 }
101
102 struct declaration_sequence *
103 bt_sequence_declaration_new(const char *length,
104 struct bt_declaration *elem_declaration,
105 struct declaration_scope *parent_scope)
106 {
107 struct declaration_sequence *sequence_declaration;
108 struct bt_declaration *declaration;
109
110 sequence_declaration = g_new(struct declaration_sequence, 1);
111 declaration = &sequence_declaration->p;
112
113 sequence_declaration->length_name = g_array_new(FALSE, TRUE, sizeof(GQuark));
114 bt_append_scope_path(length, sequence_declaration->length_name);
115
116 bt_declaration_ref(elem_declaration);
117 sequence_declaration->elem = elem_declaration;
118 sequence_declaration->scope = bt_new_declaration_scope(parent_scope);
119 declaration->id = CTF_TYPE_SEQUENCE;
120 declaration->alignment = elem_declaration->alignment;
121 declaration->declaration_free = _sequence_declaration_free;
122 declaration->definition_new = _sequence_definition_new;
123 declaration->definition_free = _sequence_definition_free;
124 declaration->ref = 1;
125 return sequence_declaration;
126 }
127
128 static
129 struct bt_definition *_sequence_definition_new(struct bt_declaration *declaration,
130 struct definition_scope *parent_scope,
131 GQuark field_name, int index,
132 const char *root_name)
133 {
134 struct declaration_sequence *sequence_declaration =
135 container_of(declaration, struct declaration_sequence, p);
136 struct definition_sequence *sequence;
137 struct bt_definition *len_parent;
138 int ret;
139
140 sequence = g_new(struct definition_sequence, 1);
141 bt_declaration_ref(&sequence_declaration->p);
142 sequence->p.declaration = declaration;
143 sequence->declaration = sequence_declaration;
144 sequence->p.ref = 1;
145 /*
146 * Use INT_MAX order to ensure that all fields of the parent
147 * scope are seen as being prior to this scope.
148 */
149 sequence->p.index = root_name ? INT_MAX : index;
150 sequence->p.name = field_name;
151 sequence->p.path = bt_new_definition_path(parent_scope, field_name, root_name);
152 sequence->p.scope = bt_new_definition_scope(parent_scope, field_name, root_name);
153 ret = bt_register_field_definition(field_name, &sequence->p,
154 parent_scope);
155 assert(!ret);
156 len_parent = bt_lookup_path_definition(sequence->p.scope->scope_path,
157 sequence_declaration->length_name,
158 parent_scope);
159 if (!len_parent) {
160 printf("[error] Lookup for sequence length field failed.\n");
161 goto error;
162 }
163 sequence->length =
164 container_of(len_parent, struct definition_integer, p);
165 if (sequence->length->declaration->signedness) {
166 printf("[error] Sequence length field should be unsigned.\n");
167 goto error;
168 }
169 bt_definition_ref(len_parent);
170
171 sequence->string = NULL;
172 sequence->elems = NULL;
173
174 if (sequence_declaration->elem->id == CTF_TYPE_INTEGER) {
175 struct declaration_integer *integer_declaration =
176 container_of(sequence_declaration->elem, struct declaration_integer, p);
177
178 if (integer_declaration->encoding == CTF_STRING_UTF8
179 || integer_declaration->encoding == CTF_STRING_ASCII) {
180
181 sequence->string = g_string_new("");
182
183 if (integer_declaration->len == CHAR_BIT
184 && integer_declaration->p.alignment == CHAR_BIT) {
185 return &sequence->p;
186 }
187 }
188 }
189
190 sequence->elems = g_ptr_array_new();
191 return &sequence->p;
192
193 error:
194 bt_free_definition_scope(sequence->p.scope);
195 bt_declaration_unref(&sequence_declaration->p);
196 g_free(sequence);
197 return NULL;
198 }
199
200 static
201 void _sequence_definition_free(struct bt_definition *definition)
202 {
203 struct definition_sequence *sequence =
204 container_of(definition, struct definition_sequence, p);
205 struct bt_definition *len_definition = &sequence->length->p;
206 uint64_t i;
207
208 if (sequence->string)
209 (void) g_string_free(sequence->string, TRUE);
210 if (sequence->elems) {
211 for (i = 0; i < sequence->elems->len; i++) {
212 struct bt_definition *field;
213
214 field = g_ptr_array_index(sequence->elems, i);
215 field->declaration->definition_free(field);
216 }
217 (void) g_ptr_array_free(sequence->elems, TRUE);
218 }
219 bt_definition_unref(len_definition);
220 bt_free_definition_scope(sequence->p.scope);
221 bt_declaration_unref(sequence->p.declaration);
222 g_free(sequence);
223 }
224
225 uint64_t bt_sequence_len(struct definition_sequence *sequence)
226 {
227 return sequence->length->value._unsigned;
228 }
229
230 struct bt_definition *bt_sequence_index(struct definition_sequence *sequence, uint64_t i)
231 {
232 if (!sequence->elems)
233 return NULL;
234 if (i >= sequence->length->value._unsigned)
235 return NULL;
236 assert(i < sequence->elems->len);
237 return g_ptr_array_index(sequence->elems, i);
238 }
This page took 0.049713 seconds and 4 git commands to generate.