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
);
170 fillStruct(input
, myFields
, structDefinition
);
171 return structDefinition
;
175 * Accelerated create definition
177 * @param definitionScope
178 * the definition scope
180 * the lexical scope of this element
182 * the {@Link BitBuffer} to read
183 * @return the Struct definition
184 * @throws CTFReaderException
185 * read error and such
188 public StructDefinition
createDefinition(IDefinitionScope definitionScope
,
189 LexicalScope fieldScope
, @NonNull BitBuffer input
) throws CTFReaderException
{
191 final Definition
[] myFields
= new Definition
[fFieldMap
.size()];
193 * Key set is NOT null
195 @SuppressWarnings("null")
196 StructDefinition structDefinition
= new StructDefinition(this, definitionScope
, fieldScope
, fieldScope
.getName(), fFieldMap
.keySet(), myFields
);
197 fillStruct(input
, myFields
, structDefinition
);
198 return structDefinition
;
202 * Add a field to the struct
205 * the name of the field, scopeless
207 * the declaration of the field
209 public void addField(String name
, IDeclaration declaration
) {
210 fFieldMap
.put(name
, declaration
);
211 fMaxAlign
= Math
.max(fMaxAlign
, declaration
.getAlignment());
214 @SuppressWarnings("null")
215 private void fillStruct(@NonNull BitBuffer input
, final Definition
[] myFields
, StructDefinition structDefinition
) throws CTFReaderException
{
216 Iterator
<Map
.Entry
<String
, IDeclaration
>> iter
= fFieldMap
.entrySet().iterator();
217 for (int i
= 0; i
< fFieldMap
.size(); i
++) {
218 Map
.Entry
<String
, IDeclaration
> entry
= iter
.next();
219 myFields
[i
] = entry
.getValue().createDefinition(structDefinition
, entry
.getKey(), input
);
224 public String
toString() {
225 /* Only used for debugging */
226 return "[declaration] struct[" + Integer
.toHexString(hashCode()) + ']'; //$NON-NLS-1$
230 public int hashCode() {
231 final int prime
= 31;
233 result
= (prime
* result
) + fFieldMap
.entrySet().hashCode();
234 result
= (prime
* result
) + (int) (fMaxAlign ^
(fMaxAlign
>>> 32));
239 public boolean equals(Object obj
) {
246 if (!(obj
instanceof StructDeclaration
)) {
249 StructDeclaration other
= (StructDeclaration
) obj
;
250 if (!fFieldMap
.entrySet().equals(other
.fFieldMap
.entrySet())) {
253 if (fMaxAlign
!= other
.fMaxAlign
) {