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