namespace definition_ref and definition_unref
[babeltrace.git] / types / sequence.c
CommitLineData
2e7d72cf 1/*
ccd7e1c8 2 * sequence.c
2e7d72cf 3 *
ccd7e1c8 4 * BabelTrace - Sequence Type Converter
2e7d72cf 5 *
64fa3fec
MD
6 * Copyright 2010-2011 EfficiOS Inc. and Linux Foundation
7 *
8 * Author: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
2e7d72cf 9 *
ccd7e1c8
MD
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:
2e7d72cf 16 *
ccd7e1c8
MD
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
c462e188
MD
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.
2e7d72cf
MD
27 */
28
29#include <babeltrace/compiler.h>
4c8bfb7e 30#include <babeltrace/format.h>
3122e6f0 31#include <babeltrace/types.h>
0f980a35 32#include <inttypes.h>
2e7d72cf 33
c054553d 34static
f6625916 35struct definition *_sequence_definition_new(struct declaration *declaration,
05c749e5 36 struct definition_scope *parent_scope,
98df1c9f
MD
37 GQuark field_name, int index,
38 const char *root_name);
c054553d 39static
e1151715 40void _sequence_definition_free(struct definition *definition);
c054553d 41
c5e74408 42int sequence_rw(struct stream_pos *pos, struct definition *definition)
2e7d72cf 43{
d11e9c49 44 struct definition_sequence *sequence_definition =
e1151715 45 container_of(definition, struct definition_sequence, p);
d11e9c49
MD
46 const struct declaration_sequence *sequence_declaration =
47 sequence_definition->declaration;
0f980a35 48 uint64_t len, oldlen, i;
c5e74408 49 int ret;
2e7d72cf 50
98df1c9f 51 len = sequence_definition->length->value._unsigned;
0f980a35
MD
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 */
d11e9c49 60 oldlen = sequence_definition->elems->len;
0f980a35 61 if (oldlen < len)
b1a2f580 62 g_ptr_array_set_size(sequence_definition->elems, len);
0f980a35
MD
63
64 for (i = oldlen; i < len; i++) {
b1a2f580 65 struct definition **field;
0f980a35
MD
66 GString *str;
67 GQuark name;
68
69 str = g_string_new("");
70 g_string_printf(str, "[%" PRIu64 "]", i);
0f980a35 71 name = g_quark_from_string(str->str);
518de31c 72 (void) g_string_free(str, TRUE);
2e7d72cf 73
b1a2f580
MD
74 field = (struct definition **) &g_ptr_array_index(sequence_definition->elems, i);
75 *field = sequence_declaration->elem->definition_new(sequence_declaration->elem,
a35173fe 76 sequence_definition->p.scope,
98df1c9f 77 name, i, NULL);
1e36e6c2
MD
78 }
79 for (i = 0; i < len; i++) {
80 struct definition **field;
81
82 field = (struct definition **) &g_ptr_array_index(sequence_definition->elems, i);
b1a2f580 83 ret = generic_rw(pos, *field);
c5e74408
MD
84 if (ret)
85 return ret;
2e7d72cf 86 }
c5e74408 87 return 0;
2e7d72cf
MD
88}
89
c054553d 90static
f6625916 91void _sequence_declaration_free(struct declaration *declaration)
2e7d72cf 92{
f6625916
MD
93 struct declaration_sequence *sequence_declaration =
94 container_of(declaration, struct declaration_sequence, p);
c054553d 95
f6625916 96 free_declaration_scope(sequence_declaration->scope);
98df1c9f 97 g_array_free(sequence_declaration->length_name, TRUE);
e6b4b4f4 98 bt_declaration_unref(sequence_declaration->elem);
f6625916 99 g_free(sequence_declaration);
2e7d72cf
MD
100}
101
f6625916 102struct declaration_sequence *
98df1c9f 103 sequence_declaration_new(const char *length,
f6625916
MD
104 struct declaration *elem_declaration,
105 struct declaration_scope *parent_scope)
2e7d72cf 106{
f6625916
MD
107 struct declaration_sequence *sequence_declaration;
108 struct declaration *declaration;
2e7d72cf 109
f6625916
MD
110 sequence_declaration = g_new(struct declaration_sequence, 1);
111 declaration = &sequence_declaration->p;
98df1c9f
MD
112
113 sequence_declaration->length_name = g_array_new(FALSE, TRUE, sizeof(GQuark));
dd0365d9 114 bt_append_scope_path(length, sequence_declaration->length_name);
98df1c9f 115
e6b4b4f4 116 bt_declaration_ref(elem_declaration);
f6625916
MD
117 sequence_declaration->elem = elem_declaration;
118 sequence_declaration->scope = new_declaration_scope(parent_scope);
119 declaration->id = CTF_TYPE_SEQUENCE;
98df1c9f 120 declaration->alignment = elem_declaration->alignment;
f6625916
MD
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;
2e7d72cf 126}
c054553d
MD
127
128static
f6625916 129struct definition *_sequence_definition_new(struct declaration *declaration,
05c749e5 130 struct definition_scope *parent_scope,
98df1c9f
MD
131 GQuark field_name, int index,
132 const char *root_name)
c054553d 133{
f6625916
MD
134 struct declaration_sequence *sequence_declaration =
135 container_of(declaration, struct declaration_sequence, p);
e1151715
MD
136 struct definition_sequence *sequence;
137 struct definition *len_parent;
98df1c9f 138 int ret;
c054553d 139
e1151715 140 sequence = g_new(struct definition_sequence, 1);
e6b4b4f4 141 bt_declaration_ref(&sequence_declaration->p);
f6625916
MD
142 sequence->p.declaration = declaration;
143 sequence->declaration = sequence_declaration;
c054553d 144 sequence->p.ref = 1;
98df1c9f
MD
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;
b1a2f580 150 sequence->p.name = field_name;
98df1c9f 151 sequence->p.path = new_definition_path(parent_scope, field_name, root_name);
a35173fe 152 sequence->p.scope = new_definition_scope(parent_scope, field_name, root_name);
98df1c9f
MD
153 ret = register_field_definition(field_name, &sequence->p,
154 parent_scope);
155 assert(!ret);
a35173fe
MD
156 len_parent = lookup_path_definition(sequence->p.scope->scope_path,
157 sequence_declaration->length_name,
158 parent_scope);
98df1c9f
MD
159 if (!len_parent) {
160 printf("[error] Lookup for sequence length field failed.\n");
161 goto error;
162 }
163 sequence->length =
e1151715 164 container_of(len_parent, struct definition_integer, p);
98df1c9f
MD
165 if (sequence->length->declaration->signedness) {
166 printf("[error] Sequence length field should be unsigned.\n");
167 goto error;
168 }
13fad8b6 169 bt_definition_ref(len_parent);
81dee1bb
MD
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
b1a2f580 190 sequence->elems = g_ptr_array_new();
c054553d 191 return &sequence->p;
98df1c9f
MD
192
193error:
a35173fe 194 free_definition_scope(sequence->p.scope);
e6b4b4f4 195 bt_declaration_unref(&sequence_declaration->p);
98df1c9f
MD
196 g_free(sequence);
197 return NULL;
c054553d
MD
198}
199
200static
e1151715 201void _sequence_definition_free(struct definition *definition)
c054553d 202{
e1151715
MD
203 struct definition_sequence *sequence =
204 container_of(definition, struct definition_sequence, p);
98df1c9f 205 struct definition *len_definition = &sequence->length->p;
0f980a35
MD
206 uint64_t i;
207
81dee1bb
MD
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 definition *field;
c054553d 213
81dee1bb
MD
214 field = g_ptr_array_index(sequence->elems, i);
215 field->declaration->definition_free(field);
216 }
15d4fe3c 217 (void) g_ptr_array_free(sequence->elems, TRUE);
0f980a35 218 }
13fad8b6 219 bt_definition_unref(len_definition);
a35173fe 220 free_definition_scope(sequence->p.scope);
e6b4b4f4 221 bt_declaration_unref(sequence->p.declaration);
c054553d
MD
222 g_free(sequence);
223}
0f980a35 224
3838df27
MD
225uint64_t sequence_len(struct definition_sequence *sequence)
226{
98df1c9f 227 return sequence->length->value._unsigned;
3838df27
MD
228}
229
0f980a35
MD
230struct definition *sequence_index(struct definition_sequence *sequence, uint64_t i)
231{
81dee1bb
MD
232 if (!sequence->elems)
233 return NULL;
98df1c9f 234 if (i >= sequence->length->value._unsigned)
0f980a35
MD
235 return NULL;
236 assert(i < sequence->elems->len);
b1a2f580 237 return g_ptr_array_index(sequence->elems, i);
0f980a35 238}
This page took 0.037731 seconds and 4 git commands to generate.