Commit | Line | Data |
---|---|---|
9c312311 | 1 | /* This file is part of the Linux Trace Toolkit viewer |
2 | * Copyright (C) 2003-2004 Michel Dagenais | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License Version 2 as | |
6 | * published by the Free Software Foundation; | |
7 | * | |
8 | * This program is distributed in the hope that it will be useful, | |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | * GNU General Public License for more details. | |
12 | * | |
13 | * You should have received a copy of the GNU General Public License | |
14 | * along with this program; if not, write to the Free Software | |
15 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, | |
16 | * MA 02111-1307, USA. | |
17 | */ | |
18 | ||
4e4d11b3 | 19 | #ifdef HAVE_CONFIG_H |
20 | #include <config.h> | |
21 | #endif | |
dc877563 | 22 | |
ffd54a90 | 23 | #include <lttv/iattribute.h> |
24 | ||
90e19f82 | 25 | static void lttv_iattribute_base_init (gpointer klass) |
dc877563 | 26 | { |
90e19f82 | 27 | static gboolean initialized = FALSE; |
dc877563 | 28 | |
90e19f82 AM |
29 | if (!initialized) { |
30 | initialized = TRUE; | |
31 | } | |
dc877563 | 32 | } |
33 | ||
34 | ||
90e19f82 | 35 | GType lttv_iattribute_get_type (void) |
dc877563 | 36 | { |
90e19f82 AM |
37 | static GType type = 0; |
38 | if (type == 0) { | |
39 | static const GTypeInfo info = { | |
40 | sizeof (LttvIAttributeClass), | |
41 | lttv_iattribute_base_init, /* base_init */ | |
42 | NULL, /* base_finalize */ | |
43 | NULL, /* class_init */ | |
44 | NULL, /* class_finalize */ | |
45 | NULL, /* class_data */ | |
46 | 0, | |
47 | 0, /* n_preallocs */ | |
48 | NULL /* instance_init */ | |
49 | }; | |
50 | type = g_type_register_static (G_TYPE_INTERFACE, "LttvIAttribute", | |
51 | &info, 0); | |
52 | } | |
53 | return type; | |
dc877563 | 54 | } |
55 | ||
56 | ||
57 | unsigned int lttv_iattribute_get_number(LttvIAttribute *self) | |
58 | { | |
90e19f82 | 59 | return LTTV_IATTRIBUTE_GET_CLASS (self)->get_number (self); |
dc877563 | 60 | } |
61 | ||
62 | ||
63 | gboolean lttv_iattribute_named(LttvIAttribute *self, gboolean *homogeneous) | |
64 | { | |
90e19f82 | 65 | return LTTV_IATTRIBUTE_GET_CLASS (self)->named (self, homogeneous); |
dc877563 | 66 | } |
67 | ||
68 | ||
69 | LttvAttributeType lttv_iattribute_get(LttvIAttribute *self, unsigned i, | |
90e19f82 | 70 | LttvAttributeName *name, LttvAttributeValue *v, gboolean *is_named) |
dc877563 | 71 | { |
90e19f82 | 72 | return LTTV_IATTRIBUTE_GET_CLASS (self)->get (self, i, name, v, is_named); |
dc877563 | 73 | } |
74 | ||
75 | ||
76 | LttvAttributeType lttv_iattribute_get_by_name(LttvIAttribute *self, | |
90e19f82 | 77 | LttvAttributeName name, LttvAttributeValue *v) |
dc877563 | 78 | { |
90e19f82 | 79 | return LTTV_IATTRIBUTE_GET_CLASS (self)->get_by_name (self, name, v); |
dc877563 | 80 | } |
81 | ||
82 | ||
ffd54a90 | 83 | LttvAttributeValue lttv_iattribute_add(LttvIAttribute *self, |
90e19f82 | 84 | LttvAttributeName name, LttvAttributeType t) |
dc877563 | 85 | { |
90e19f82 | 86 | return LTTV_IATTRIBUTE_GET_CLASS (self)->add (self, name, t); |
dc877563 | 87 | } |
88 | ||
c0cb4d12 | 89 | LttvAttributeValue lttv_iattribute_add_unnamed(LttvIAttribute *self, |
90e19f82 | 90 | LttvAttributeName name, LttvAttributeType t) |
c0cb4d12 | 91 | { |
90e19f82 | 92 | return LTTV_IATTRIBUTE_GET_CLASS (self)->add_unnamed (self, name, t); |
c0cb4d12 | 93 | } |
dc877563 | 94 | |
95 | void lttv_iattribute_remove(LttvIAttribute *self, unsigned i) | |
96 | { | |
90e19f82 | 97 | return LTTV_IATTRIBUTE_GET_CLASS (self)->remove (self, i); |
dc877563 | 98 | } |
99 | ||
100 | ||
101 | void lttv_iattribute_remove_by_name(LttvIAttribute *self, | |
90e19f82 | 102 | LttvAttributeName name) |
dc877563 | 103 | { |
90e19f82 | 104 | return LTTV_IATTRIBUTE_GET_CLASS (self)->remove_by_name (self, name); |
dc877563 | 105 | } |
106 | ||
b445142a | 107 | LttvIAttribute* lttv_iattribute_find_subdir(LttvIAttribute *self, |
90e19f82 | 108 | LttvAttributeName name) |
dc877563 | 109 | { |
90e19f82 | 110 | return LTTV_IATTRIBUTE_GET_CLASS (self)->find_subdir (self, name); |
dc877563 | 111 | } |
112 | ||
c0cb4d12 | 113 | LttvIAttribute* lttv_iattribute_find_subdir_unnamed(LttvIAttribute *self, |
90e19f82 | 114 | LttvAttributeName name) |
c0cb4d12 | 115 | { |
90e19f82 | 116 | return LTTV_IATTRIBUTE_GET_CLASS (self)->find_subdir_unnamed (self, name); |
c0cb4d12 | 117 | } |
118 | ||
119 | ||
dc877563 | 120 | |
121 | /* Find the named attribute in the table, which must be of the specified type. | |
122 | If it does not exist, it is created with a default value of 0 (NULL for | |
123 | pointer types). Since the address of the value is obtained, it may be | |
124 | changed easily afterwards. The function returns false when the attribute | |
125 | exists but is of incorrect type. */ | |
126 | ||
127 | gboolean lttv_iattribute_find(LttvIAttribute *self, LttvAttributeName name, | |
90e19f82 | 128 | LttvAttributeType t, LttvAttributeValue *v) |
dc877563 | 129 | { |
90e19f82 | 130 | LttvAttributeType found_type; |
dc877563 | 131 | |
90e19f82 AM |
132 | found_type = lttv_iattribute_get_by_name(self, name, v); |
133 | if(found_type == t) return TRUE; | |
dc877563 | 134 | |
90e19f82 AM |
135 | if(found_type == LTTV_NONE) { |
136 | *v = lttv_iattribute_add(self, name, t); | |
137 | return TRUE; | |
138 | } | |
dc877563 | 139 | |
90e19f82 | 140 | return FALSE; |
dc877563 | 141 | } |
142 | ||
143 | ||
144 | /* Trees of attribute tables may be accessed using a hierarchical path with | |
145 | components separated by /, like in filesystems */ | |
146 | ||
9a9ca632 | 147 | gboolean lttv_iattribute_find_by_path(LttvIAttribute *self, const char *path, |
90e19f82 | 148 | LttvAttributeType t, LttvAttributeValue *v) |
dc877563 | 149 | { |
90e19f82 AM |
150 | LttvIAttribute *node = self; |
151 | ||
152 | LttvAttributeType found_type; | |
153 | ||
154 | LttvAttributeName name; | |
155 | ||
156 | gchar **components, **cursor; | |
157 | ||
158 | components = g_strsplit(path, "\"", G_MAXINT); | |
159 | ||
160 | if(components == NULL || *components == NULL) { | |
161 | g_strfreev(components); | |
162 | return FALSE; | |
163 | } | |
164 | ||
165 | for(cursor = components;;) { | |
166 | name = g_quark_from_string(*cursor); | |
167 | cursor++; | |
168 | ||
169 | if(*cursor == NULL) { | |
170 | g_strfreev(components); | |
171 | return lttv_iattribute_find(node, name, t, v); | |
172 | } else { | |
173 | found_type = lttv_iattribute_get_by_name(node, name, v); | |
174 | if(found_type == LTTV_NONE) { | |
175 | node = lttv_iattribute_find_subdir(node, name); | |
176 | } | |
177 | else if(found_type == LTTV_GOBJECT && | |
178 | LTTV_IS_IATTRIBUTE(*(v->v_gobject))) { | |
179 | node = LTTV_IATTRIBUTE(*(v->v_gobject)); | |
180 | } else { | |
181 | g_strfreev(components); | |
182 | return FALSE; | |
183 | } | |
184 | } | |
185 | } | |
dc877563 | 186 | } |
187 | ||
3e67c985 | 188 | |
dc877563 | 189 | /* Shallow and deep copies */ |
190 | ||
191 | LttvIAttribute *lttv_iattribute_shallow_copy(LttvIAttribute *self) | |
192 | { | |
90e19f82 | 193 | LttvIAttribute *copy; |
dc877563 | 194 | |
90e19f82 | 195 | LttvAttributeType t; |
dc877563 | 196 | |
90e19f82 | 197 | LttvAttributeValue v, v_copy; |
dc877563 | 198 | |
90e19f82 | 199 | LttvAttributeName name; |
dc877563 | 200 | |
c0cb4d12 | 201 | gboolean is_named; |
202 | ||
90e19f82 | 203 | int i; |
dc877563 | 204 | |
90e19f82 | 205 | int nb_attributes = lttv_iattribute_get_number(self); |
dc877563 | 206 | |
90e19f82 | 207 | copy = LTTV_IATTRIBUTE_GET_CLASS(self)->new_attribute(NULL); |
dc877563 | 208 | |
90e19f82 AM |
209 | for(i = 0 ; i < nb_attributes ; i++) { |
210 | t = lttv_iattribute_get(self, i, &name, &v, &is_named); | |
c0cb4d12 | 211 | if(is_named) |
90e19f82 | 212 | v_copy = lttv_iattribute_add(copy, name, t); |
c0cb4d12 | 213 | else |
90e19f82 AM |
214 | v_copy = lttv_iattribute_add_unnamed(copy, name, t); |
215 | lttv_iattribute_copy_value(t, v_copy, v); | |
216 | } | |
217 | return copy; | |
dc877563 | 218 | } |
219 | ||
220 | LttvIAttribute *lttv_iattribute_deep_copy(LttvIAttribute *self) | |
221 | { | |
90e19f82 | 222 | LttvIAttribute *copy, *child; |
dc877563 | 223 | |
90e19f82 | 224 | LttvAttributeType t; |
dc877563 | 225 | |
90e19f82 | 226 | LttvAttributeValue v, v_copy; |
dc877563 | 227 | |
90e19f82 | 228 | LttvAttributeName name; |
dc877563 | 229 | |
c0cb4d12 | 230 | gboolean is_named; |
231 | ||
90e19f82 | 232 | int i; |
dc877563 | 233 | |
90e19f82 | 234 | int nb_attributes = lttv_iattribute_get_number(self); |
dc877563 | 235 | |
90e19f82 | 236 | copy = LTTV_IATTRIBUTE_GET_CLASS(self)->new_attribute(NULL); |
dc877563 | 237 | |
90e19f82 AM |
238 | for(i = 0 ; i < nb_attributes ; i++) { |
239 | t = lttv_iattribute_get(self, i, &name, &v, &is_named); | |
c0cb4d12 | 240 | if(is_named) |
90e19f82 | 241 | v_copy = lttv_iattribute_add(copy, name, t); |
c0cb4d12 | 242 | else |
90e19f82 AM |
243 | v_copy = lttv_iattribute_add_unnamed(copy, name, t); |
244 | if(t == LTTV_GOBJECT && LTTV_IS_IATTRIBUTE(*(v.v_gobject))) { | |
245 | child = LTTV_IATTRIBUTE(*(v.v_gobject)); | |
246 | *(v_copy.v_gobject) = G_OBJECT(lttv_iattribute_deep_copy(child)); | |
247 | } | |
248 | else lttv_iattribute_copy_value(t, v_copy, v); | |
249 | } | |
250 | return copy; | |
dc877563 | 251 | } |
252 | ||
253 | void lttv_iattribute_copy_value(LttvAttributeType t, LttvAttributeValue dest, | |
90e19f82 | 254 | LttvAttributeValue src) |
dc877563 | 255 | { |
90e19f82 AM |
256 | switch(t) { |
257 | case LTTV_INT: | |
258 | *(dest.v_int) = *(src.v_int); | |
259 | break; | |
260 | ||
261 | case LTTV_UINT: | |
262 | *(dest.v_uint) = *(src.v_uint); | |
263 | break; | |
264 | ||
265 | case LTTV_LONG: | |
266 | *(dest.v_long) = *(src.v_long); | |
267 | break; | |
268 | ||
269 | case LTTV_ULONG: | |
270 | *(dest.v_ulong) = *(src.v_ulong); | |
271 | break; | |
272 | ||
273 | case LTTV_FLOAT: | |
274 | *(dest.v_float) = *(src.v_float); | |
275 | break; | |
276 | ||
277 | case LTTV_DOUBLE: | |
278 | *(dest.v_double) = *(src.v_double); | |
279 | break; | |
280 | ||
281 | case LTTV_TIME: | |
282 | *(dest.v_time) = *(src.v_time); | |
283 | break; | |
284 | ||
285 | case LTTV_POINTER: | |
286 | *(dest.v_pointer) = *(src.v_pointer); | |
287 | break; | |
288 | ||
289 | case LTTV_STRING: | |
290 | *(dest.v_string) = *(src.v_string); | |
291 | break; | |
292 | ||
293 | case LTTV_GOBJECT: | |
294 | *(dest.v_gobject) = *(src.v_gobject); | |
295 | if(*(dest.v_gobject) != NULL) g_object_ref(*(dest.v_gobject)); | |
296 | break; | |
297 | ||
298 | case LTTV_NONE: | |
299 | break; | |
300 | } | |
dc877563 | 301 | } |
302 | ||
303 |