1 /*******************************************************************************
2 * Copyright (c) 2011, 2014 Ericsson, Ecole Polytechnique de Montreal and others
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
9 * Contributors: Matthew Khouzam - Initial API and implementation
10 * Contributors: Simon Marchi - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.ctf
.core
.event
.types
;
15 import java
.util
.Iterator
;
16 import java
.util
.LinkedHashMap
;
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
;
27 * A CTF structure declaration.
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.
34 * @author Matthew Khouzam
35 * @author Simon Marchi
37 public class StructDeclaration
extends Declaration
{
39 // ------------------------------------------------------------------------
41 // ------------------------------------------------------------------------
43 /** linked list of field names. So fieldName->fieldValue */
44 private final @NonNull Map
<String
, IDeclaration
> fFieldMap
= new LinkedHashMap
<>();
46 /** maximum bit alignment */
47 private long fMaxAlign
;
49 // ------------------------------------------------------------------------
51 // ------------------------------------------------------------------------
54 * The struct declaration, add fields later
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
61 public StructDeclaration(long align
) {
62 fMaxAlign
= Math
.max(align
, 1);
66 * Struct declaration constructor
69 * the names of all the fields
74 public StructDeclaration(String
[] names
, Declaration
[] declarations
) {
77 for (int i
= 0; i
< names
.length
; i
++) {
78 addField(names
[i
], declarations
[i
]);
82 // ------------------------------------------------------------------------
83 // Getters/Setters/Predicates
84 // ------------------------------------------------------------------------
87 * Get current alignment
89 * @return the alignment of the struct and all its fields
91 public long getMaxAlign() {
96 * Query if the struct has a given field
99 * the name of the field, scopeless please
100 * @return does the field exist?
102 public boolean hasField(String name
) {
103 return fFieldMap
.containsKey(name
);
107 * Get the fields of the struct as a map.
109 * @return a Map of the fields (key is the name)
112 public Map
<String
, IDeclaration
> getFields() {
117 * Get the field declaration corresponding to a field name.
121 * @return The declaration of the field, or null if there is no such field.
125 public IDeclaration
getField(String fieldName
) {
126 return fFieldMap
.get(fieldName
);
130 * Gets the field list. Very important since the map of fields does not
131 * retain the order of the fields.
133 * @return the field list.
136 public Iterable
<String
> getFieldsList() {
137 return fFieldMap
.keySet();
141 public long getAlignment() {
142 return this.fMaxAlign
;
149 public int getMaximumSize() {
151 for (IDeclaration field
: fFieldMap
.values()) {
152 maxSize
+= field
.getMaximumSize();
154 return Math
.min(maxSize
, Integer
.MAX_VALUE
);
157 // ------------------------------------------------------------------------
159 // ------------------------------------------------------------------------
165 public StructDefinition
createDefinition(IDefinitionScope definitionScope
,
166 String fieldName
, BitBuffer input
) throws CTFReaderException
{
168 final Definition
[] myFields
= new Definition
[fFieldMap
.size()];
169 StructDefinition structDefinition
= new StructDefinition(this, definitionScope
, fieldName
, fFieldMap
.keySet(), myFields
);
171 Iterator
<Map
.Entry
<String
, IDeclaration
>> iter
= fFieldMap
.entrySet().iterator();
172 for (int i
= 0; i
< fFieldMap
.size(); i
++) {
173 Map
.Entry
<String
, IDeclaration
> entry
= iter
.next();
174 String name
= entry
.getKey();
176 throw new IllegalStateException();
178 myFields
[i
] = entry
.getValue().createDefinition(structDefinition
, name
, input
);
180 return structDefinition
;
184 * Accelerated create definition
186 * @param definitionScope
187 * the definition scope
189 * the lexical scope of this element
191 * the {@Link BitBuffer} to read
192 * @return the Struct definition
193 * @throws CTFReaderException
194 * read error and such
197 public StructDefinition
createDefinition(IDefinitionScope definitionScope
,
198 LexicalScope fieldScope
, @NonNull BitBuffer input
) throws CTFReaderException
{
200 final Definition
[] myFields
= new Definition
[fFieldMap
.size()];
202 * Key set is NOT null
204 @SuppressWarnings("null")
205 StructDefinition structDefinition
= new StructDefinition(this, definitionScope
, fieldScope
, fieldScope
.getName(), fFieldMap
.keySet(), myFields
);
206 Iterator
<Map
.Entry
<String
, IDeclaration
>> iter
= fFieldMap
.entrySet().iterator();
207 for (int i
= 0; i
< fFieldMap
.size(); i
++) {
208 Map
.Entry
<String
, IDeclaration
> entry
= iter
.next();
209 String fieldName
= entry
.getKey();
210 if (fieldName
== null) {
211 throw new IllegalStateException();
213 myFields
[i
] = entry
.getValue().createDefinition(structDefinition
, fieldName
, input
);
215 return structDefinition
;
219 * Add a field to the struct
222 * the name of the field, scopeless
224 * the declaration of the field
226 public void addField(String name
, IDeclaration declaration
) {
227 fFieldMap
.put(name
, declaration
);
228 fMaxAlign
= Math
.max(fMaxAlign
, declaration
.getAlignment());
232 public String
toString() {
233 /* Only used for debugging */
234 return "[declaration] struct[" + Integer
.toHexString(hashCode()) + ']'; //$NON-NLS-1$
238 public int hashCode() {
239 final int prime
= 31;
241 result
= (prime
* result
) + fFieldMap
.entrySet().hashCode();
242 result
= (prime
* result
) + (int) (fMaxAlign ^
(fMaxAlign
>>> 32));
247 public boolean equals(Object obj
) {
254 if (!(obj
instanceof StructDeclaration
)) {
257 StructDeclaration other
= (StructDeclaration
) obj
;
258 if (!fFieldMap
.entrySet().equals(other
.fFieldMap
.entrySet())) {
261 if (fMaxAlign
!= other
.fMaxAlign
) {