Update help
[babeltrace.git] / types / array.c
1 /*
2 * array.c
3 *
4 * BabelTrace - Array 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
21 #include <babeltrace/compiler.h>
22 #include <babeltrace/format.h>
23 #include <inttypes.h>
24
25 static
26 struct definition *_array_definition_new(struct declaration *declaration,
27 struct definition_scope *parent_scope,
28 GQuark field_name, int index, const char *root_name);
29 static
30 void _array_definition_free(struct definition *definition);
31
32 int array_rw(struct stream_pos *pos, struct definition *definition)
33 {
34 struct definition_array *array_definition =
35 container_of(definition, struct definition_array, p);
36 const struct declaration_array *array_declaration =
37 array_definition->declaration;
38 uint64_t i;
39 int ret;
40
41 /* No need to align, because the first field will align itself. */
42 for (i = 0; i < array_declaration->len; i++) {
43 struct definition *field =
44 g_ptr_array_index(array_definition->elems, i);
45 ret = generic_rw(pos, field);
46 if (ret)
47 return ret;
48 }
49 return 0;
50 }
51
52 static
53 void _array_declaration_free(struct declaration *declaration)
54 {
55 struct declaration_array *array_declaration =
56 container_of(declaration, struct declaration_array, p);
57
58 free_declaration_scope(array_declaration->scope);
59 declaration_unref(array_declaration->elem);
60 g_free(array_declaration);
61 }
62
63 struct declaration_array *
64 array_declaration_new(size_t len,
65 struct declaration *elem_declaration,
66 struct declaration_scope *parent_scope)
67 {
68 struct declaration_array *array_declaration;
69 struct declaration *declaration;
70
71 array_declaration = g_new(struct declaration_array, 1);
72 declaration = &array_declaration->p;
73 array_declaration->len = len;
74 declaration_ref(elem_declaration);
75 array_declaration->elem = elem_declaration;
76 array_declaration->scope = new_declaration_scope(parent_scope);
77 declaration->id = CTF_TYPE_ARRAY;
78 /* No need to align the array, the first element will align itself */
79 declaration->alignment = 1;
80 declaration->declaration_free = _array_declaration_free;
81 declaration->definition_new = _array_definition_new;
82 declaration->definition_free = _array_definition_free;
83 declaration->ref = 1;
84 return array_declaration;
85 }
86
87 static
88 struct definition *
89 _array_definition_new(struct declaration *declaration,
90 struct definition_scope *parent_scope,
91 GQuark field_name, int index, const char *root_name)
92 {
93 struct declaration_array *array_declaration =
94 container_of(declaration, struct declaration_array, p);
95 struct definition_array *array;
96 int ret;
97 int i;
98
99 array = g_new(struct definition_array, 1);
100 declaration_ref(&array_declaration->p);
101 array->p.declaration = declaration;
102 array->declaration = array_declaration;
103 array->p.ref = 1;
104 /*
105 * Use INT_MAX order to ensure that all fields of the parent
106 * scope are seen as being prior to this scope.
107 */
108 array->p.index = root_name ? INT_MAX : index;
109 array->p.name = field_name;
110 array->p.path = new_definition_path(parent_scope, field_name, root_name);
111 array->p.scope = new_definition_scope(parent_scope, field_name, root_name);
112 ret = register_field_definition(field_name, &array->p,
113 parent_scope);
114 assert(!ret);
115 array->string = NULL;
116 array->elems = NULL;
117
118 if (array_declaration->elem->id == CTF_TYPE_INTEGER) {
119 struct declaration_integer *integer_declaration =
120 container_of(array_declaration->elem, struct declaration_integer, p);
121
122 if (integer_declaration->encoding == CTF_STRING_UTF8
123 || integer_declaration->encoding == CTF_STRING_ASCII) {
124
125 array->string = g_string_new("");
126
127 if (integer_declaration->len == CHAR_BIT
128 && integer_declaration->p.alignment == CHAR_BIT) {
129 return &array->p;
130 }
131 }
132 }
133
134 array->elems = g_ptr_array_sized_new(array_declaration->len);
135 g_ptr_array_set_size(array->elems, array_declaration->len);
136 for (i = 0; i < array_declaration->len; i++) {
137 struct definition **field;
138 GString *str;
139 GQuark name;
140
141 str = g_string_new("");
142 g_string_printf(str, "[%u]", (unsigned int) i);
143 name = g_quark_from_string(str->str);
144 (void) g_string_free(str, TRUE);
145
146 field = (struct definition **) &g_ptr_array_index(array->elems, i);
147 *field = array_declaration->elem->definition_new(array_declaration->elem,
148 array->p.scope,
149 name, i, NULL);
150 if (!*field)
151 goto error;
152 }
153
154 return &array->p;
155
156 error:
157 for (i--; i >= 0; i--) {
158 struct definition *field;
159
160 field = g_ptr_array_index(array->elems, i);
161 field->declaration->definition_free(field);
162 }
163 (void) g_ptr_array_free(array->elems, TRUE);
164 free_definition_scope(array->p.scope);
165 declaration_unref(array->p.declaration);
166 g_free(array);
167 return NULL;
168 }
169
170 static
171 void _array_definition_free(struct definition *definition)
172 {
173 struct definition_array *array =
174 container_of(definition, struct definition_array, p);
175 uint64_t i;
176
177 if (array->string)
178 (void) g_string_free(array->string, TRUE);
179 if (array->elems) {
180 for (i = 0; i < array->elems->len; i++) {
181 struct definition *field;
182
183 field = g_ptr_array_index(array->elems, i);
184 field->declaration->definition_free(field);
185 }
186 (void) g_ptr_array_free(array->elems, TRUE);
187 }
188 free_definition_scope(array->p.scope);
189 declaration_unref(array->p.declaration);
190 g_free(array);
191 }
192
193 uint64_t array_len(struct definition_array *array)
194 {
195 if (!array->elems)
196 return array->string->len;
197 return array->elems->len;
198 }
199
200 struct definition *array_index(struct definition_array *array, uint64_t i)
201 {
202 if (!array->elems)
203 return NULL;
204 if (i >= array->elems->len)
205 return NULL;
206 return g_ptr_array_index(array->elems, i);
207 }
208
209 GString *get_char_array(struct definition *field)
210 {
211 struct definition_array *array_definition;
212 struct declaration_array *array_declaration;
213 struct declaration *elem;
214
215 array_definition = container_of(field, struct definition_array, p);
216 array_declaration = array_definition->declaration;
217 elem = array_declaration->elem;
218 if (elem->id == CTF_TYPE_INTEGER) {
219 struct declaration_integer *integer_declaration =
220 container_of(elem, struct declaration_integer, p);
221
222 if (integer_declaration->encoding == CTF_STRING_UTF8
223 || integer_declaration->encoding == CTF_STRING_ASCII) {
224
225 if (integer_declaration->len == CHAR_BIT
226 && integer_declaration->p.alignment == CHAR_BIT) {
227
228 return array_definition->string;
229 }
230 }
231 }
232 fprintf(stderr, "[warning] Extracting string\n");
233 return NULL;
234 }
This page took 0.032773 seconds and 4 git commands to generate.