rcp: Change workspace directory to .tracecompass
[deliverable/tracecompass.git] / org.eclipse.tracecompass.ctf.core / src / org / eclipse / tracecompass / ctf / core / event / types / EnumDeclaration.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
816fde81
MK
15import java.util.Collections;
16import java.util.HashSet;
866e5b51
FC
17import java.util.LinkedList;
18import java.util.List;
816fde81 19import java.util.Set;
866e5b51 20
f78eb6a7 21import org.eclipse.jdt.annotation.Nullable;
f357bcd4
AM
22import org.eclipse.tracecompass.ctf.core.event.io.BitBuffer;
23import org.eclipse.tracecompass.ctf.core.event.scope.IDefinitionScope;
24import org.eclipse.tracecompass.ctf.core.trace.CTFReaderException;
a4fa4e36 25
866e5b51 26/**
d37aaa7f 27 * A CTF enum declaration.
0594c61c 28 *
816fde81
MK
29 * The definition of a enum point basic data type. It will take the data from a
30 * trace and store it (and make it fit) as an integer and a string.
d37aaa7f
FC
31 *
32 * @version 1.0
33 * @author Matthew Khouzam
34 * @author Simon Marchi
866e5b51 35 */
8fa270f6 36public final class EnumDeclaration extends Declaration implements ISimpleDatatypeDeclaration {
866e5b51
FC
37
38 // ------------------------------------------------------------------------
39 // Attributes
40 // ------------------------------------------------------------------------
41
816fde81
MK
42 private final EnumTable fTable = new EnumTable();
43 private final IntegerDeclaration fContainerType;
3de23137 44 private final Set<String> fLabels = new HashSet<>();
866e5b51
FC
45
46 // ------------------------------------------------------------------------
47 // Constructors
48 // ------------------------------------------------------------------------
49
9ac2eb62
MK
50 /**
51 * constructor
52 *
53 * @param containerType
54 * the enum is an int, this is the type that the data is
55 * contained in. If you have 1000 possible values, you need at
56 * least a 10 bit enum. If you store 2 values in a 128 bit int,
57 * you are wasting space.
58 */
866e5b51 59 public EnumDeclaration(IntegerDeclaration containerType) {
816fde81 60 fContainerType = containerType;
866e5b51
FC
61 }
62
63 // ------------------------------------------------------------------------
64 // Getters/Setters/Predicates
65 // ------------------------------------------------------------------------
66
9ac2eb62
MK
67 /**
68 *
69 * @return The container type
70 */
866e5b51 71 public IntegerDeclaration getContainerType() {
816fde81 72 return fContainerType;
866e5b51
FC
73 }
74
fd74e6c1
MK
75 @Override
76 public long getAlignment() {
77 return this.getContainerType().getAlignment();
78 }
9ac2eb62 79
a4fa4e36
MK
80 /**
81 * @since 3.0
82 */
83 @Override
84 public int getMaximumSize() {
85 return fContainerType.getMaximumSize();
86 }
87
866e5b51
FC
88 // ------------------------------------------------------------------------
89 // Operations
90 // ------------------------------------------------------------------------
91
a4fa4e36
MK
92 /**
93 * @since 3.0
94 */
866e5b51 95 @Override
f78eb6a7 96 public EnumDefinition createDefinition(@Nullable IDefinitionScope definitionScope, String fieldName, BitBuffer input) throws CTFReaderException {
a4fa4e36
MK
97 alignRead(input);
98 IntegerDefinition value = getContainerType().createDefinition(definitionScope, fieldName, input);
99 return new EnumDefinition(this, definitionScope, fieldName, value);
866e5b51
FC
100 }
101
9ac2eb62 102 /**
8fa270f6
MK
103 * Add a value. Do not overlap, this is <em><strong>not</strong></em> an
104 * interval tree.
816fde81
MK
105 *
106 * @param low
107 * lowest value that this int can be to have label as a return
108 * string
109 * @param high
110 * highest value that this int can be to have label as a return
111 * string
112 * @param label
113 * the name of the value.
9ac2eb62
MK
114 * @return was the value be added? true == success
115 */
f78eb6a7 116 public boolean add(long low, long high, @Nullable String label) {
816fde81
MK
117 fLabels.add(label);
118 return fTable.add(low, high, label);
866e5b51
FC
119 }
120
9ac2eb62 121 /**
816fde81
MK
122 * Check if the label for a value (enum a{day=0,night=1} would return "day"
123 * for query(0)
124 *
125 * @param value
126 * the value to lookup
9ac2eb62
MK
127 * @return the label of that value, can be null
128 */
f78eb6a7 129 public @Nullable String query(long value) {
816fde81
MK
130 return fTable.query(value);
131 }
132
133 /**
134 * Gets a set of labels of the enum
135 *
136 * @return A set of labels of the enum, can be empty but not null
c4767854 137 * @since 3.0
816fde81
MK
138 */
139 public Set<String> getLabels() {
140 return Collections.unmodifiableSet(fLabels);
866e5b51
FC
141 }
142
866e5b51
FC
143 /*
144 * Maps integer range -> string. A simple list for now, but feel free to
145 * optimize it. Babeltrace suggests an interval tree.
146 */
816fde81 147 private class EnumTable {
866e5b51 148
3de23137 149 private final List<LabelAndRange> ranges = new LinkedList<>();
866e5b51
FC
150
151 public EnumTable() {
152 }
153
e00e6663 154 public synchronized boolean add(long low, long high, @Nullable String label) {
816fde81 155 LabelAndRange newRange = new LabelAndRange(low, high, label);
866e5b51 156
816fde81 157 for (LabelAndRange r : ranges) {
866e5b51
FC
158 if (r.intersects(newRange)) {
159 return false;
160 }
161 }
162
163 ranges.add(newRange);
164
165 return true;
166 }
167
9ac2eb62 168 /**
a511da0d 169 * Return the first label that matches a value
816fde81
MK
170 *
171 * @param value
172 * the value to query
9ac2eb62
MK
173 * @return the label corresponding to that value
174 */
e00e6663 175 public synchronized @Nullable String query(long value) {
816fde81 176 for (LabelAndRange r : ranges) {
866e5b51 177 if (r.intersects(value)) {
096bc534 178 return r.getLabel();
866e5b51
FC
179 }
180 }
866e5b51
FC
181 return null;
182 }
183
e00e6663
MK
184 @Override
185 public synchronized int hashCode() {
186 final int prime = 31;
187 int result = 1;
188 for (LabelAndRange range : ranges) {
189 result = prime * result + range.hashCode();
190 }
191 return result;
192 }
193
194 @Override
195 public synchronized boolean equals(@Nullable Object obj) {
196 if (this == obj) {
197 return true;
198 }
199 if (obj == null) {
200 return false;
201 }
202 if (getClass() != obj.getClass()) {
203 return false;
204 }
205 EnumTable other = (EnumTable) obj;
206 if (ranges.size() != other.ranges.size()) {
207 return false;
208 }
209 for (int i = 0; i < ranges.size(); i++) {
210 if (!ranges.get(i).equals(other.ranges.get(i))) {
211 return false;
212 }
213 }
214 return true;
215 }
216
816fde81 217 }
866e5b51 218
096bc534 219 private static class LabelAndRange {
866e5b51 220
816fde81 221 private final long low, high;
f78eb6a7 222 private final @Nullable String fLabel;
866e5b51 223
096bc534
MK
224 /**
225 * Get the label
226 *
227 * @return the label
228 */
e00e6663 229 public @Nullable String getLabel() {
096bc534
MK
230 return fLabel;
231 }
232
f78eb6a7 233 public LabelAndRange(long low, long high, @Nullable String str) {
816fde81
MK
234 this.low = low;
235 this.high = high;
236 this.fLabel = str;
237 }
866e5b51 238
816fde81
MK
239 public boolean intersects(long i) {
240 return (i >= this.low) && (i <= this.high);
241 }
242
243 public boolean intersects(LabelAndRange other) {
244 return this.intersects(other.low)
245 || this.intersects(other.high);
866e5b51 246 }
e00e6663
MK
247
248 @Override
249 public int hashCode() {
250 final int prime = 31;
251 int result = 1;
252 final String label = fLabel;
253 result = prime * result + ((label == null) ? 0 : label.hashCode());
254 result = prime * result + (int) (high ^ (high >>> 32));
255 result = prime * result + (int) (low ^ (low >>> 32));
256 return result;
257 }
258
259 @Override
260 public boolean equals(@Nullable Object obj) {
261 if (this == obj) {
262 return true;
263 }
264 if (obj == null) {
265 return false;
266 }
267 if (getClass() != obj.getClass()) {
268 return false;
269 }
270 LabelAndRange other = (LabelAndRange) obj;
271 final String label = fLabel;
272 if (label == null) {
273 if (other.fLabel != null) {
274 return false;
275 }
276 } else if (!label.equals(other.fLabel)) {
277 return false;
278 }
279 if (high != other.high) {
280 return false;
281 }
282 if (low != other.low) {
283 return false;
284 }
285 return true;
286 }
866e5b51
FC
287 }
288
289 @Override
290 public String toString() {
291 /* Only used for debugging */
292 return "[declaration] enum[" + Integer.toHexString(hashCode()) + ']'; //$NON-NLS-1$
293 }
294
e00e6663
MK
295 @Override
296 public int hashCode() {
297 final int prime = 31;
298 int result = prime + fContainerType.hashCode();
299 for (String label : fLabels) {
300 result = prime * result + label.hashCode();
301 }
302 result = prime * result + fTable.hashCode();
303 return result;
304 }
305
306 @Override
307 public boolean equals(@Nullable Object obj) {
308 if (this == obj) {
309 return true;
310 }
311 if (obj == null) {
312 return false;
313 }
314 if (getClass() != obj.getClass()) {
315 return false;
316 }
317 EnumDeclaration other = (EnumDeclaration) obj;
318 if (!fContainerType.equals(other.fContainerType)) {
319 return false;
320 }
321 if (fLabels.size() != other.fLabels.size()) {
322 return false;
323 }
324 if (!fLabels.containsAll(other.fLabels)) {
325 return false;
326 }
327 if (!fTable.equals(other.fTable)) {
328 return false;
329 }
330 return true;
331 }
332
866e5b51 333}
This page took 0.064868 seconds and 5 git commands to generate.