Commit | Line | Data |
---|---|---|
866e5b51 | 1 | /******************************************************************************* |
4bd7f2db | 2 | * Copyright (c) 2011, 2013 Ericsson, Ecole Polytechnique de Montreal and others |
866e5b51 FC |
3 | * |
4 | * All rights reserved. This program and the accompanying materials are made | |
5 | * available under the terms of the Eclipse Public License v1.0 which | |
6 | * accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
8 | * | |
9 | * Contributors: Matthew Khouzam - Initial API and implementation | |
10 | * Contributors: Simon Marchi - Initial API and implementation | |
11 | *******************************************************************************/ | |
12 | ||
13 | package org.eclipse.linuxtools.ctf.core.event.types; | |
14 | ||
843f986b | 15 | import java.util.LinkedHashMap; |
2b7f6f09 | 16 | import java.util.List; |
866e5b51 | 17 | import java.util.ListIterator; |
843f986b | 18 | import java.util.Map; |
866e5b51 | 19 | |
486efb2e | 20 | import org.eclipse.linuxtools.ctf.core.event.io.BitBuffer; |
866e5b51 FC |
21 | |
22 | /** | |
d37aaa7f | 23 | * A CTF structure definition (similar to a C structure). |
486efb2e | 24 | * |
d37aaa7f FC |
25 | * A structure is similar to a C structure, it is a compound data type that |
26 | * contains other datatypes in fields. they are stored in an hashmap and indexed | |
27 | * by names which are strings. | |
28 | * | |
29 | * @version 1.0 | |
30 | * @author Matthew Khouzam | |
31 | * @author Simon Marchi | |
866e5b51 FC |
32 | */ |
33 | public class StructDefinition extends Definition implements IDefinitionScope { | |
34 | ||
35 | // ------------------------------------------------------------------------ | |
36 | // Attributes | |
37 | // ------------------------------------------------------------------------ | |
38 | ||
39 | private final StructDeclaration declaration; | |
843f986b | 40 | private final Map<String, Definition> definitions = new LinkedHashMap<String, Definition>(); |
866e5b51 FC |
41 | |
42 | // ------------------------------------------------------------------------ | |
43 | // Constructors | |
44 | // ------------------------------------------------------------------------ | |
45 | ||
9ac2eb62 MK |
46 | /** |
47 | * Constructor | |
48 | * | |
49 | * @param declaration | |
50 | * the parent declaration | |
51 | * @param definitionScope | |
52 | * the parent scope | |
be6df2d8 | 53 | * @param structFieldName |
9ac2eb62 MK |
54 | * the field name |
55 | */ | |
866e5b51 FC |
56 | public StructDefinition(StructDeclaration declaration, |
57 | IDefinitionScope definitionScope, String structFieldName) { | |
58 | super(definitionScope, structFieldName); | |
59 | ||
60 | this.declaration = declaration; | |
61 | ||
62 | for (String fName : declaration.getFieldsList()) { | |
63 | IDeclaration fieldDecl = declaration.getFields().get(fName); | |
64 | assert (fieldDecl != null); | |
65 | ||
66 | Definition def = fieldDecl.createDefinition(this, fName); | |
67 | definitions.put(fName, def); | |
68 | } | |
69 | } | |
70 | ||
71 | // ------------------------------------------------------------------------ | |
72 | // Getters/Setters/Predicates | |
73 | // ------------------------------------------------------------------------ | |
74 | ||
9ac2eb62 MK |
75 | /** |
76 | * @return The definitions of all the fields | |
843f986b | 77 | * @since 2.0 |
9ac2eb62 | 78 | */ |
843f986b | 79 | public Map<String, Definition> getDefinitions() { |
866e5b51 FC |
80 | return definitions; |
81 | } | |
82 | ||
9ac2eb62 | 83 | @Override |
866e5b51 FC |
84 | public StructDeclaration getDeclaration() { |
85 | return declaration; | |
86 | } | |
87 | ||
88 | // ------------------------------------------------------------------------ | |
89 | // Operations | |
90 | // ------------------------------------------------------------------------ | |
91 | ||
92 | @Override | |
93 | public void read(BitBuffer input) { | |
2b7f6f09 | 94 | final int align = (int) declaration.getAlignment(); |
9ac2eb62 MK |
95 | int pos = input.position() |
96 | + ((align - (input.position() % align)) % align); | |
2b7f6f09 MK |
97 | input.position(pos); |
98 | final List<String> fieldList = declaration.getFieldsList(); | |
99 | for (String fName : fieldList) { | |
866e5b51 FC |
100 | Definition def = definitions.get(fName); |
101 | assert (def != null); | |
866e5b51 FC |
102 | def.read(input); |
103 | } | |
104 | } | |
105 | ||
106 | @Override | |
107 | public Definition lookupDefinition(String lookupPath) { | |
108 | /* | |
109 | * The fields are created in order of appearance, so if a variant or | |
110 | * sequence refers to a field that is after it, the field's definition | |
111 | * will not be there yet in the hashmap. | |
112 | */ | |
91847dfc FC |
113 | Definition retVal = definitions.get(lookupPath); |
114 | if (retVal == null) { | |
115 | retVal = definitions.get("_" + lookupPath); //$NON-NLS-1$ | |
116 | } | |
117 | return retVal; | |
866e5b51 FC |
118 | } |
119 | ||
9ac2eb62 MK |
120 | /** |
121 | * Lookup an array in a struct. if the name returns a non-array (like an | |
122 | * int) than the method returns null | |
123 | * | |
124 | * @param name | |
125 | * the name of the array | |
126 | * @return the array or null. | |
127 | */ | |
866e5b51 | 128 | public ArrayDefinition lookupArray(String name) { |
91847dfc | 129 | Definition def = lookupDefinition(name); |
866e5b51 FC |
130 | return (ArrayDefinition) ((def instanceof ArrayDefinition) ? def : null); |
131 | } | |
132 | ||
9ac2eb62 MK |
133 | /** |
134 | * Lookup an enum in a struct. if the name returns a non-enum (like an int) | |
135 | * than the method returns null | |
136 | * | |
137 | * @param name | |
138 | * the name of the enum | |
139 | * @return the enum or null. | |
140 | */ | |
866e5b51 | 141 | public EnumDefinition lookupEnum(String name) { |
91847dfc | 142 | Definition def = lookupDefinition(name); |
866e5b51 FC |
143 | return (EnumDefinition) ((def instanceof EnumDefinition) ? def : null); |
144 | } | |
145 | ||
9ac2eb62 MK |
146 | /** |
147 | * Lookup an integer in a struct. if the name returns a non-integer (like an | |
148 | * float) than the method returns null | |
149 | * | |
150 | * @param name | |
151 | * the name of the integer | |
152 | * @return the integer or null. | |
153 | */ | |
866e5b51 | 154 | public IntegerDefinition lookupInteger(String name) { |
91847dfc | 155 | Definition def = lookupDefinition(name); |
866e5b51 FC |
156 | return (IntegerDefinition) ((def instanceof IntegerDefinition) ? def |
157 | : null); | |
158 | } | |
159 | ||
9ac2eb62 MK |
160 | /** |
161 | * Lookup a sequence in a struct. if the name returns a non-sequence (like | |
162 | * an int) than the method returns null | |
163 | * | |
164 | * @param name | |
165 | * the name of the sequence | |
166 | * @return the sequence or null. | |
167 | */ | |
866e5b51 | 168 | public SequenceDefinition lookupSequence(String name) { |
91847dfc | 169 | Definition def = lookupDefinition(name); |
866e5b51 FC |
170 | return (SequenceDefinition) ((def instanceof SequenceDefinition) ? def |
171 | : null); | |
172 | } | |
173 | ||
9ac2eb62 MK |
174 | /** |
175 | * Lookup a string in a struct. if the name returns a non-string (like | |
176 | * an int) than the method returns null | |
177 | * | |
178 | * @param name | |
179 | * the name of the string | |
180 | * @return the string or null. | |
181 | */ | |
866e5b51 | 182 | public StringDefinition lookupString(String name) { |
91847dfc | 183 | Definition def = lookupDefinition(name); |
866e5b51 FC |
184 | return (StringDefinition) ((def instanceof StringDefinition) ? def |
185 | : null); | |
186 | } | |
187 | ||
9ac2eb62 MK |
188 | /** |
189 | * Lookup a struct in a struct. if the name returns a non-struct (like | |
190 | * an int) than the method returns null | |
191 | * | |
192 | * @param name | |
193 | * the name of the struct | |
194 | * @return the struct or null. | |
195 | */ | |
866e5b51 | 196 | public StructDefinition lookupStruct(String name) { |
91847dfc | 197 | Definition def = lookupDefinition(name); |
866e5b51 FC |
198 | return (StructDefinition) ((def instanceof StructDefinition) ? def |
199 | : null); | |
200 | } | |
201 | ||
9ac2eb62 MK |
202 | /** |
203 | * Lookup a variant in a struct. if the name returns a non-variant (like | |
204 | * an int) than the method returns null | |
205 | * | |
206 | * @param name | |
207 | * the name of the variant | |
208 | * @return the variant or null. | |
209 | */ | |
866e5b51 | 210 | public VariantDefinition lookupVariant(String name) { |
91847dfc | 211 | Definition def = lookupDefinition(name); |
866e5b51 FC |
212 | return (VariantDefinition) ((def instanceof VariantDefinition) ? def |
213 | : null); | |
214 | } | |
215 | ||
216 | @Override | |
217 | public String toString() { | |
218 | StringBuilder builder = new StringBuilder(); | |
219 | ||
419f09a8 | 220 | builder.append("{ "); //$NON-NLS-1$ |
866e5b51 | 221 | |
9ac2eb62 MK |
222 | ListIterator<String> listIterator = this.declaration.getFieldsList() |
223 | .listIterator(); | |
866e5b51 FC |
224 | |
225 | while (listIterator.hasNext()) { | |
226 | String field = listIterator.next(); | |
419f09a8 SM |
227 | |
228 | builder.append(field); | |
229 | builder.append(" = "); //$NON-NLS-1$ | |
91847dfc | 230 | builder.append(lookupDefinition(field).toString()); |
419f09a8 SM |
231 | |
232 | if (listIterator.hasNext()) { | |
866e5b51 FC |
233 | builder.append(", "); //$NON-NLS-1$ |
234 | } | |
235 | } | |
236 | ||
419f09a8 | 237 | builder.append(" }"); //$NON-NLS-1$ |
866e5b51 FC |
238 | |
239 | return builder.toString(); | |
240 | } | |
241 | } |