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