Support for live sessions using LTTng MI (2.6)
[deliverable/tracecompass.git] / org.eclipse.tracecompass.ctf.core / src / org / eclipse / tracecompass / ctf / core / event / types / StructDeclaration.java
CommitLineData
866e5b51 1/*******************************************************************************
60ae41e1 2 * Copyright (c) 2011, 2014 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
f357bcd4 13package org.eclipse.tracecompass.ctf.core.event.types;
866e5b51 14
e00e6663 15import java.util.ArrayList;
2db699c2 16import java.util.Iterator;
a4fa4e36 17import java.util.LinkedHashMap;
e00e6663 18import java.util.List;
0594c61c 19import java.util.Map;
e00e6663 20import java.util.Map.Entry;
866e5b51 21
a4fa4e36 22import org.eclipse.jdt.annotation.NonNull;
2db699c2 23import org.eclipse.jdt.annotation.Nullable;
f357bcd4
AM
24import org.eclipse.tracecompass.ctf.core.event.io.BitBuffer;
25import org.eclipse.tracecompass.ctf.core.event.scope.IDefinitionScope;
26import org.eclipse.tracecompass.ctf.core.event.scope.LexicalScope;
27import org.eclipse.tracecompass.ctf.core.trace.CTFReaderException;
a4fa4e36 28
866e5b51 29/**
d37aaa7f 30 * A CTF structure declaration.
77fdc5df 31 *
d37aaa7f
FC
32 * A structure is similar to a C structure, it is a compound data type that
33 * contains other datatypes in fields. they are stored in an hashmap and indexed
34 * by names which are strings.
35 *
36 * @version 1.0
37 * @author Matthew Khouzam
38 * @author Simon Marchi
866e5b51 39 */
a4fa4e36 40public class StructDeclaration extends Declaration {
866e5b51
FC
41
42 // ------------------------------------------------------------------------
43 // Attributes
44 // ------------------------------------------------------------------------
45
a4fa4e36 46 /** linked list of field names. So fieldName->fieldValue */
2db699c2 47 private final @NonNull Map<String, IDeclaration> fFieldMap = new LinkedHashMap<>();
a4fa4e36
MK
48
49 /** maximum bit alignment */
50 private long fMaxAlign;
866e5b51
FC
51
52 // ------------------------------------------------------------------------
53 // Constructors
54 // ------------------------------------------------------------------------
55
9ac2eb62
MK
56 /**
57 * The struct declaration, add fields later
58 *
59 * @param align
60 * the minimum alignment of the struct. (if a struct is 8bit
61 * aligned and has a 32 bit aligned field, the struct becomes 32
62 * bit aligned.
63 */
2b7f6f09 64 public StructDeclaration(long align) {
a4fa4e36 65 fMaxAlign = Math.max(align, 1);
a4fa4e36
MK
66 }
67
68 /**
69 * Struct declaration constructor
70 *
71 * @param names
72 * the names of all the fields
73 * @param declarations
74 * all the fields
75 * @since 3.0
76 */
a4fa4e36
MK
77 public StructDeclaration(String[] names, Declaration[] declarations) {
78 fMaxAlign = 1;
2db699c2 79
a4fa4e36
MK
80 for (int i = 0; i < names.length; i++) {
81 addField(names[i], declarations[i]);
82 }
866e5b51
FC
83 }
84
85 // ------------------------------------------------------------------------
86 // Getters/Setters/Predicates
87 // ------------------------------------------------------------------------
88
9ac2eb62
MK
89 /**
90 * Get current alignment
a4fa4e36 91 *
9ac2eb62
MK
92 * @return the alignment of the struct and all its fields
93 */
2b7f6f09 94 public long getMaxAlign() {
a4fa4e36 95 return fMaxAlign;
866e5b51
FC
96 }
97
9ac2eb62
MK
98 /**
99 * Query if the struct has a given field
a4fa4e36
MK
100 *
101 * @param name
102 * the name of the field, scopeless please
9ac2eb62
MK
103 * @return does the field exist?
104 */
866e5b51 105 public boolean hasField(String name) {
a4fa4e36 106 return fFieldMap.containsKey(name);
866e5b51
FC
107 }
108
9ac2eb62 109 /**
2db699c2 110 * Get the fields of the struct as a map.
a4fa4e36 111 *
2db699c2 112 * @return a Map of the fields (key is the name)
0594c61c 113 * @since 2.0
9ac2eb62 114 */
0594c61c 115 public Map<String, IDeclaration> getFields() {
a4fa4e36 116 return fFieldMap;
866e5b51
FC
117 }
118
2db699c2
AM
119 /**
120 * Get the field declaration corresponding to a field name.
121 *
122 * @param fieldName
123 * The field name
124 * @return The declaration of the field, or null if there is no such field.
125 * @since 3.1
126 */
127 @Nullable
128 public IDeclaration getField(String fieldName) {
129 return fFieldMap.get(fieldName);
130 }
131
9ac2eb62 132 /**
a4fa4e36
MK
133 * Gets the field list. Very important since the map of fields does not
134 * retain the order of the fields.
135 *
9ac2eb62 136 * @return the field list.
a4fa4e36 137 * @since 3.0
9ac2eb62 138 */
a4fa4e36
MK
139 public Iterable<String> getFieldsList() {
140 return fFieldMap.keySet();
866e5b51
FC
141 }
142
fd74e6c1
MK
143 @Override
144 public long getAlignment() {
a4fa4e36
MK
145 return this.fMaxAlign;
146 }
147
148 /**
149 * @since 3.0
150 */
151 @Override
152 public int getMaximumSize() {
153 int maxSize = 0;
2db699c2
AM
154 for (IDeclaration field : fFieldMap.values()) {
155 maxSize += field.getMaximumSize();
a4fa4e36
MK
156 }
157 return Math.min(maxSize, Integer.MAX_VALUE);
fd74e6c1 158 }
9ac2eb62 159
866e5b51
FC
160 // ------------------------------------------------------------------------
161 // Operations
162 // ------------------------------------------------------------------------
163
a4fa4e36
MK
164 /**
165 * @since 3.0
166 */
866e5b51
FC
167 @Override
168 public StructDefinition createDefinition(IDefinitionScope definitionScope,
a4fa4e36
MK
169 String fieldName, BitBuffer input) throws CTFReaderException {
170 alignRead(input);
2db699c2
AM
171 final Definition[] myFields = new Definition[fFieldMap.size()];
172 StructDefinition structDefinition = new StructDefinition(this, definitionScope, fieldName, fFieldMap.keySet(), myFields);
cc575f45 173 fillStruct(input, myFields, structDefinition);
a4fa4e36 174 return structDefinition;
866e5b51
FC
175 }
176
70f60307 177 /**
6c7592e1
MK
178 * Create a definition from this declaration. This is a faster constructor
179 * as it has a lexical scope and this does not need to look it up.
70f60307
MK
180 *
181 * @param definitionScope
6c7592e1
MK
182 * the definition scope, the parent where the definition will be
183 * placed
70f60307 184 * @param fieldScope
6c7592e1 185 * the scope of the definition
70f60307 186 * @param input
6c7592e1
MK
187 * a bitbuffer to read from
188 * @return a reference to the definition
70f60307 189 * @throws CTFReaderException
6c7592e1 190 * error in reading
70f60307
MK
191 * @since 3.1
192 */
193 public StructDefinition createDefinition(IDefinitionScope definitionScope,
194 LexicalScope fieldScope, @NonNull BitBuffer input) throws CTFReaderException {
195 alignRead(input);
196 final Definition[] myFields = new Definition[fFieldMap.size()];
bbe3a6a4
MK
197 /*
198 * Key set is NOT null
199 */
200 @SuppressWarnings("null")
201 StructDefinition structDefinition = new StructDefinition(this, definitionScope, fieldScope, fieldScope.getName(), fFieldMap.keySet(), myFields);
cc575f45 202 fillStruct(input, myFields, structDefinition);
70f60307
MK
203 return structDefinition;
204 }
205
9ac2eb62
MK
206 /**
207 * Add a field to the struct
a4fa4e36
MK
208 *
209 * @param name
210 * the name of the field, scopeless
211 * @param declaration
212 * the declaration of the field
9ac2eb62 213 */
866e5b51 214 public void addField(String name, IDeclaration declaration) {
a4fa4e36
MK
215 fFieldMap.put(name, declaration);
216 fMaxAlign = Math.max(fMaxAlign, declaration.getAlignment());
866e5b51
FC
217 }
218
cc575f45
MK
219 @SuppressWarnings("null")
220 private void fillStruct(@NonNull BitBuffer input, final Definition[] myFields, StructDefinition structDefinition) throws CTFReaderException {
221 Iterator<Map.Entry<String, IDeclaration>> iter = fFieldMap.entrySet().iterator();
222 for (int i = 0; i < fFieldMap.size(); i++) {
223 Map.Entry<String, IDeclaration> entry = iter.next();
224 myFields[i] = entry.getValue().createDefinition(structDefinition, entry.getKey(), input);
225 }
226 }
227
866e5b51
FC
228 @Override
229 public String toString() {
230 /* Only used for debugging */
66aa25f0
MK
231 StringBuilder sb = new StringBuilder();
232 sb.append("[declaration] struct["); //$NON-NLS-1$
233 for (Entry<String, IDeclaration> field : fFieldMap.entrySet()) {
234 sb.append(field.getKey()).append(':').append(field.getValue());
235 }
236 sb.append(']');
237 return sb.toString();
866e5b51
FC
238 }
239
4dd0eaed
MK
240 @Override
241 public int hashCode() {
242 final int prime = 31;
243 int result = 1;
e00e6663
MK
244 for (Entry<String, IDeclaration> field : fFieldMap.entrySet()) {
245 result = prime * result + field.getKey().hashCode();
246 result = prime * result + field.getValue().hashCode();
247 }
a4fa4e36 248 result = (prime * result) + (int) (fMaxAlign ^ (fMaxAlign >>> 32));
4dd0eaed
MK
249 return result;
250 }
251
4dd0eaed
MK
252 @Override
253 public boolean equals(Object obj) {
254 if (this == obj) {
255 return true;
256 }
257 if (obj == null) {
258 return false;
259 }
260 if (!(obj instanceof StructDeclaration)) {
261 return false;
262 }
263 StructDeclaration other = (StructDeclaration) obj;
e00e6663 264 if (fFieldMap.size() != other.fFieldMap.size()) {
4dd0eaed
MK
265 return false;
266 }
e00e6663
MK
267
268 List<String> localFieldNames = new ArrayList<>();
269 localFieldNames.addAll(fFieldMap.keySet());
270
271 List<IDeclaration> localDecs = new ArrayList<>();
272 localDecs.addAll(fFieldMap.values());
273
274 List<String> otherFieldNames = new ArrayList<>();
275 otherFieldNames.addAll(other.fFieldMap.keySet());
276
277 List<IDeclaration> otherDecs = new ArrayList<>();
278 otherDecs.addAll(other.fFieldMap.values());
279
280 //check fields in order
281 for (int i = 0; i < fFieldMap.size(); i++) {
282 if ((!localFieldNames.get(i).equals(otherFieldNames.get(i))) ||
283 (!otherDecs.get(i).equals(localDecs.get(i)))) {
284 return false;
285 }
286 }
287
a4fa4e36 288 if (fMaxAlign != other.fMaxAlign) {
4dd0eaed
MK
289 return false;
290 }
291 return true;
292 }
293
66aa25f0
MK
294 @Override
295 public boolean isBinaryEquivalent(IDeclaration obj) {
296 if (this == obj) {
297 return true;
298 }
299 if (obj == null) {
300 return false;
301 }
302 if (!(obj instanceof StructDeclaration)) {
303 return false;
304 }
305 StructDeclaration other = (StructDeclaration) obj;
306 if (fFieldMap.size() != other.fFieldMap.size()) {
307 return false;
308 }
309 List<IDeclaration> localDecs = new ArrayList<>();
310 localDecs.addAll(fFieldMap.values());
311 List<IDeclaration> otherDecs = new ArrayList<>();
312 otherDecs.addAll(other.fFieldMap.values());
313 for (int i = 0; i < fFieldMap.size(); i++) {
314 if (!otherDecs.get(i).isBinaryEquivalent(localDecs.get(i))) {
315 return false;
316 }
317 }
318
319 if (fMaxAlign != other.fMaxAlign) {
320 return false;
321 }
322 return true;
323 }
324
866e5b51 325}
This page took 0.063928 seconds and 5 git commands to generate.