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