ctf: rename CTFReaderException to CTFException
[deliverable/tracecompass.git] / org.eclipse.tracecompass.ctf.core / src / org / eclipse / tracecompass / ctf / core / event / types / VariantDeclaration.java
CommitLineData
866e5b51 1/*******************************************************************************
814d059f 2 * Copyright (c) 2011, 2015 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
680f9173 23import org.eclipse.tracecompass.ctf.core.CTFException;
f357bcd4
AM
24import org.eclipse.tracecompass.ctf.core.event.io.BitBuffer;
25import org.eclipse.tracecompass.ctf.core.event.scope.IDefinitionScope;
a4fa4e36 26
866e5b51 27/**
814d059f 28 * A CTF C 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>());
a4fa4e36 47 private IDeclaration fDeclarationToPopulate;
866e5b51
FC
48
49 // ------------------------------------------------------------------------
50 // Constructors
51 // ------------------------------------------------------------------------
52
9ac2eb62 53 /**
a511da0d 54 * Constructor
9ac2eb62 55 */
866e5b51
FC
56 public VariantDeclaration() {
57 }
58
59 // ------------------------------------------------------------------------
60 // Getters/Setters/Predicates
61 // ------------------------------------------------------------------------
62
9ac2eb62
MK
63 /**
64 * @return Does the variant have a tag
65 */
866e5b51 66 public boolean isTagged() {
a4fa4e36 67 return fTag != null;
866e5b51
FC
68 }
69
9ac2eb62
MK
70 /**
71 * Lookup if a field exists in the variant
a4fa4e36
MK
72 *
73 * @param fieldTag
74 * the field tag name
9ac2eb62
MK
75 * @return true = field tag exists
76 */
866e5b51 77 public boolean hasField(String fieldTag) {
a4fa4e36 78 return fFields.containsKey(fieldTag);
866e5b51
FC
79 }
80
9ac2eb62
MK
81 /**
82 * Sets the tag in a variant
a4fa4e36
MK
83 *
84 * @param tag
85 * the tag
9ac2eb62 86 */
866e5b51 87 public void setTag(String tag) {
a4fa4e36 88 fTag = tag;
866e5b51
FC
89 }
90
9ac2eb62 91 /**
a511da0d 92 * Gets current variant tag
a4fa4e36 93 *
9ac2eb62
MK
94 * @return the variant tag.
95 */
866e5b51 96 public String getTag() {
a4fa4e36 97 return fTag;
866e5b51
FC
98 }
99
9ac2eb62
MK
100 /**
101 * Gets the fields of the variant
a4fa4e36 102 *
9ac2eb62
MK
103 * @return the fields of the variant
104 */
0594c61c 105 public Map<String, IDeclaration> getFields() {
a4fa4e36 106 return this.fFields;
866e5b51
FC
107 }
108
fd74e6c1
MK
109 @Override
110 public long getAlignment() {
a4fa4e36 111 return ALIGNMENT;
fd74e6c1 112 }
a4fa4e36 113
866e5b51
FC
114 // ------------------------------------------------------------------------
115 // Operations
116 // ------------------------------------------------------------------------
117
118 @Override
119 public VariantDefinition createDefinition(IDefinitionScope definitionScope,
680f9173 120 String fieldName, BitBuffer input) throws CTFException {
a4fa4e36 121 alignRead(input);
814d059f
MK
122 Definition def = definitionScope.lookupDefinition(fTag);
123 EnumDefinition tagDef = (EnumDefinition) ((def instanceof EnumDefinition) ? def : null);
a4fa4e36 124 if (tagDef == null) {
680f9173 125 throw new CTFException("Tag is not defined " + fTag); //$NON-NLS-1$
a4fa4e36
MK
126 }
127 String varFieldName = tagDef.getStringValue();
128 fDeclarationToPopulate = fFields.get(varFieldName);
129 if (fDeclarationToPopulate == null) {
680f9173 130 throw new CTFException("Unknown enum selector for variant " + //$NON-NLS-1$
fbe6fa6f 131 definitionScope.getScopePath().getPath());
a4fa4e36
MK
132 }
133 Definition fieldValue = fDeclarationToPopulate.createDefinition(definitionScope, fieldName, input);
134 return new VariantDefinition(this, definitionScope, varFieldName, fieldName, fieldValue);
866e5b51
FC
135 }
136
9ac2eb62 137 /**
be6df2d8 138 * Add a field to this CTF Variant
9ac2eb62
MK
139 *
140 * @param fieldTag
be6df2d8 141 * The tag of the new field
9ac2eb62 142 * @param declaration
be6df2d8 143 * The Declaration of this new field
9ac2eb62 144 */
866e5b51 145 public void addField(String fieldTag, IDeclaration declaration) {
a4fa4e36
MK
146 fFields.put(fieldTag, declaration);
147 }
148
a4fa4e36
MK
149 @Override
150 public int getMaximumSize() {
151 Collection<IDeclaration> values = fFields.values();
152 int maxSize = 0;
153 for (IDeclaration field : values) {
154 maxSize = Math.max(maxSize, field.getMaximumSize());
155 }
156 return maxSize;
866e5b51
FC
157 }
158
159 @Override
160 public String toString() {
161 /* Only used for debugging */
66aa25f0
MK
162 StringBuilder sb = new StringBuilder();
163 sb.append("[declaration] variant["); //$NON-NLS-1$
164 for (Entry<String, IDeclaration> field : fFields.entrySet()) {
165 sb.append(field.getKey()).append(':').append(field.getValue());
166 }
167 sb.append(']');
168 return sb.toString();
866e5b51
FC
169 }
170
e00e6663
MK
171 @Override
172 public int hashCode() {
173 final int prime = 31;
174 int result = 1;
175 result = prime * result + ((fDeclarationToPopulate == null) ? 0 : fDeclarationToPopulate.hashCode());
176 if (fFields == null) {
177 result = prime * result;
178 } else {
179 for (Entry<String, IDeclaration> field : fFields.entrySet()) {
180 result = prime * result + field.getValue().hashCode();
181 }
182 }
e00e6663 183 result = prime * result + ((fTag == null) ? 0 : fTag.hashCode());
e00e6663
MK
184 return result;
185 }
186
187 @Override
188 public boolean equals(Object obj) {
189 if (this == obj) {
190 return true;
191 }
192 if (obj == null) {
193 return false;
194 }
195 if (getClass() != obj.getClass()) {
196 return false;
197 }
198 VariantDeclaration other = (VariantDeclaration) obj;
814d059f
MK
199
200 if (!equalsNullable(fDeclarationToPopulate, other.fDeclarationToPopulate)) {
e00e6663
MK
201 return false;
202 }
203 // do not check the order of the fields
069efcf5
MK
204 if (!equalsNullable(fFields, other.fFields)) {
205 return false;
e00e6663 206 }
069efcf5 207 if (!equalsNullable(fTag, other.fTag)) {
e00e6663
MK
208 return false;
209 }
e00e6663
MK
210 return true;
211 }
212
66aa25f0
MK
213 @Override
214 public boolean isBinaryEquivalent(IDeclaration obj) {
215 if (this == obj) {
216 return true;
217 }
218 if (obj == null) {
219 return false;
220 }
221 if (getClass() != obj.getClass()) {
222 return false;
223 }
224 VariantDeclaration other = (VariantDeclaration) obj;
225 if (fFields == null) {
226 if (other.fFields != null) {
227 return false;
228 }
229 } else {
230 if (fFields.size() != other.fFields.size()) {
231 return false;
232 }
233 for (Entry<String, IDeclaration> field : fFields.entrySet()) {
234 if (!other.fFields.containsKey(field.getKey())) {
235 return false;
236 }
237 IDeclaration field2 = other.fFields.get(field.getKey());
238 if (!field2.isBinaryEquivalent(field.getValue())) {
239 return false;
240 }
241 }
242 }
243 return true;
244 }
245
866e5b51 246}
This page took 0.068209 seconds and 5 git commands to generate.