Remove all existing @since annotations
[deliverable/tracecompass.git] / org.eclipse.tracecompass.ctf.core / src / org / eclipse / tracecompass / ctf / core / event / types / VariantDeclaration.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
069efcf5
MK
15import static org.eclipse.tracecompass.common.core.NonNullUtils.equalsNullable;
16
a4fa4e36
MK
17import java.util.Collection;
18import java.util.Collections;
866e5b51 19import java.util.HashMap;
0594c61c 20import java.util.Map;
e00e6663 21import java.util.Map.Entry;
866e5b51 22
453a59f0 23import org.eclipse.tracecompass.ctf.core.CTFReaderException;
f357bcd4
AM
24import org.eclipse.tracecompass.ctf.core.event.io.BitBuffer;
25import org.eclipse.tracecompass.ctf.core.event.scope.IDefinitionScope;
a4fa4e36 26
866e5b51 27/**
d37aaa7f 28 * A CTFC variant declaration.
0594c61c 29 *
d37aaa7f
FC
30 * A variant is similar to a C union, only taking the minimum size of the types,
31 * it is a compound data type that contains other datatypes in fields. they are
32 * stored in an hashmap and indexed by names which are strings.
33 *
34 * @version 1.0
35 * @author Matthew Khouzam
36 * @author Simon Marchi
866e5b51 37 */
a4fa4e36 38public class VariantDeclaration extends Declaration {
866e5b51
FC
39
40 // ------------------------------------------------------------------------
41 // Attributes
42 // ------------------------------------------------------------------------
43
a4fa4e36
MK
44 private String fTag = null;
45 private static final long ALIGNMENT = 1;
46 private final Map<String, IDeclaration> fFields = Collections.synchronizedMap(new HashMap<String, IDeclaration>());
47 private EnumDefinition fTagDef;
48 private IDeclaration fDeclarationToPopulate;
49 private IDefinitionScope fPrevDefinitionScope;
866e5b51
FC
50
51 // ------------------------------------------------------------------------
52 // Constructors
53 // ------------------------------------------------------------------------
54
9ac2eb62 55 /**
a511da0d 56 * Constructor
9ac2eb62 57 */
866e5b51
FC
58 public VariantDeclaration() {
59 }
60
61 // ------------------------------------------------------------------------
62 // Getters/Setters/Predicates
63 // ------------------------------------------------------------------------
64
9ac2eb62
MK
65 /**
66 * @return Does the variant have a tag
67 */
866e5b51 68 public boolean isTagged() {
a4fa4e36 69 return fTag != null;
866e5b51
FC
70 }
71
9ac2eb62
MK
72 /**
73 * Lookup if a field exists in the variant
a4fa4e36
MK
74 *
75 * @param fieldTag
76 * the field tag name
9ac2eb62
MK
77 * @return true = field tag exists
78 */
866e5b51 79 public boolean hasField(String fieldTag) {
a4fa4e36 80 return fFields.containsKey(fieldTag);
866e5b51
FC
81 }
82
9ac2eb62
MK
83 /**
84 * Sets the tag in a variant
a4fa4e36
MK
85 *
86 * @param tag
87 * the tag
9ac2eb62 88 */
866e5b51 89 public void setTag(String tag) {
a4fa4e36
MK
90 fTag = tag;
91 fTagDef = null;
866e5b51
FC
92 }
93
9ac2eb62 94 /**
a511da0d 95 * Gets current variant tag
a4fa4e36 96 *
9ac2eb62
MK
97 * @return the variant tag.
98 */
866e5b51 99 public String getTag() {
a4fa4e36 100 return fTag;
866e5b51
FC
101 }
102
9ac2eb62
MK
103 /**
104 * Gets the fields of the variant
a4fa4e36 105 *
9ac2eb62
MK
106 * @return the fields of the variant
107 */
0594c61c 108 public Map<String, IDeclaration> getFields() {
a4fa4e36 109 return this.fFields;
866e5b51
FC
110 }
111
fd74e6c1
MK
112 @Override
113 public long getAlignment() {
a4fa4e36 114 return ALIGNMENT;
fd74e6c1 115 }
a4fa4e36 116
866e5b51
FC
117 // ------------------------------------------------------------------------
118 // Operations
119 // ------------------------------------------------------------------------
120
121 @Override
122 public VariantDefinition createDefinition(IDefinitionScope definitionScope,
a4fa4e36
MK
123 String fieldName, BitBuffer input) throws CTFReaderException {
124 alignRead(input);
125 if (fPrevDefinitionScope != definitionScope) {
126 fTagDef = null;
127 fPrevDefinitionScope = definitionScope;
128 }
129 EnumDefinition tagDef = fTagDef;
130 if (tagDef == null) {
131 Definition def = definitionScope.lookupDefinition(fTag);
132 tagDef = (EnumDefinition) ((def instanceof EnumDefinition) ? def : null);
133 }
134 if (tagDef == null) {
135 throw new CTFReaderException("Tag is not defined " + fTag); //$NON-NLS-1$
136 }
137 String varFieldName = tagDef.getStringValue();
138 fDeclarationToPopulate = fFields.get(varFieldName);
139 if (fDeclarationToPopulate == null) {
140 throw new CTFReaderException("Unknown enum selector for variant " + //$NON-NLS-1$
141 definitionScope.getScopePath().toString());
142 }
143 Definition fieldValue = fDeclarationToPopulate.createDefinition(definitionScope, fieldName, input);
144 return new VariantDefinition(this, definitionScope, varFieldName, fieldName, fieldValue);
866e5b51
FC
145 }
146
9ac2eb62 147 /**
be6df2d8 148 * Add a field to this CTF Variant
9ac2eb62
MK
149 *
150 * @param fieldTag
be6df2d8 151 * The tag of the new field
9ac2eb62 152 * @param declaration
be6df2d8 153 * The Declaration of this new field
9ac2eb62 154 */
866e5b51 155 public void addField(String fieldTag, IDeclaration declaration) {
a4fa4e36
MK
156 fFields.put(fieldTag, declaration);
157 }
158
159 /**
160 * gets the tag definition
161 *
162 * @return the fTagDef
a4fa4e36
MK
163 */
164 public EnumDefinition getTagDef() {
165 return fTagDef;
166 }
167
a4fa4e36
MK
168 @Override
169 public int getMaximumSize() {
170 Collection<IDeclaration> values = fFields.values();
171 int maxSize = 0;
172 for (IDeclaration field : values) {
173 maxSize = Math.max(maxSize, field.getMaximumSize());
174 }
175 return maxSize;
866e5b51
FC
176 }
177
178 @Override
179 public String toString() {
180 /* Only used for debugging */
66aa25f0
MK
181 StringBuilder sb = new StringBuilder();
182 sb.append("[declaration] variant["); //$NON-NLS-1$
183 for (Entry<String, IDeclaration> field : fFields.entrySet()) {
184 sb.append(field.getKey()).append(':').append(field.getValue());
185 }
186 sb.append(']');
187 return sb.toString();
866e5b51
FC
188 }
189
e00e6663
MK
190 @Override
191 public int hashCode() {
192 final int prime = 31;
193 int result = 1;
194 result = prime * result + ((fDeclarationToPopulate == null) ? 0 : fDeclarationToPopulate.hashCode());
195 if (fFields == null) {
196 result = prime * result;
197 } else {
198 for (Entry<String, IDeclaration> field : fFields.entrySet()) {
199 result = prime * result + field.getValue().hashCode();
200 }
201 }
202 result = prime * result + ((fPrevDefinitionScope == null) ? 0 : fPrevDefinitionScope.hashCode());
203 result = prime * result + ((fTag == null) ? 0 : fTag.hashCode());
204 result = prime * result + ((fTagDef == null) ? 0 : fTagDef.hashCode());
205 return result;
206 }
207
208 @Override
209 public boolean equals(Object obj) {
210 if (this == obj) {
211 return true;
212 }
213 if (obj == null) {
214 return false;
215 }
216 if (getClass() != obj.getClass()) {
217 return false;
218 }
219 VariantDeclaration other = (VariantDeclaration) obj;
220 if (fDeclarationToPopulate == null) {
221 if (other.fDeclarationToPopulate != null) {
222 return false;
223 }
224 } else if (!fDeclarationToPopulate.equals(other.fDeclarationToPopulate)) {
225 return false;
226 }
227 // do not check the order of the fields
228
069efcf5
MK
229 if (!equalsNullable(fFields, other.fFields)) {
230 return false;
e00e6663 231 }
069efcf5 232 if (!equalsNullable(fPrevDefinitionScope, other.fPrevDefinitionScope)) {
e00e6663
MK
233 return false;
234 }
069efcf5 235 if (!equalsNullable(fTag, other.fTag)) {
e00e6663
MK
236 return false;
237 }
069efcf5 238 if (!equalsNullable(fTagDef, other.fTagDef)){
e00e6663
MK
239 return false;
240 }
241 return true;
242 }
243
66aa25f0
MK
244 @Override
245 public boolean isBinaryEquivalent(IDeclaration obj) {
246 if (this == obj) {
247 return true;
248 }
249 if (obj == null) {
250 return false;
251 }
252 if (getClass() != obj.getClass()) {
253 return false;
254 }
255 VariantDeclaration other = (VariantDeclaration) obj;
256 if (fFields == null) {
257 if (other.fFields != null) {
258 return false;
259 }
260 } else {
261 if (fFields.size() != other.fFields.size()) {
262 return false;
263 }
264 for (Entry<String, IDeclaration> field : fFields.entrySet()) {
265 if (!other.fFields.containsKey(field.getKey())) {
266 return false;
267 }
268 IDeclaration field2 = other.fFields.get(field.getKey());
269 if (!field2.isBinaryEquivalent(field.getValue())) {
270 return false;
271 }
272 }
273 }
274 return true;
275 }
276
866e5b51 277}
This page took 0.075712 seconds and 5 git commands to generate.