control: add service test cases for load and save commands
[deliverable/tracecompass.git] / ctf / 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
615b2145 15import java.nio.ByteOrder;
816fde81
MK
16import java.util.Collections;
17import java.util.HashSet;
866e5b51
FC
18import java.util.LinkedList;
19import java.util.List;
0c2409c1 20import java.util.Map;
816fde81 21import java.util.Set;
866e5b51 22
f78eb6a7 23import org.eclipse.jdt.annotation.Nullable;
680f9173 24import org.eclipse.tracecompass.ctf.core.CTFException;
f357bcd4
AM
25import org.eclipse.tracecompass.ctf.core.event.io.BitBuffer;
26import org.eclipse.tracecompass.ctf.core.event.scope.IDefinitionScope;
a4fa4e36 27
0c2409c1
MK
28import com.google.common.collect.ImmutableMap;
29
866e5b51 30/**
d37aaa7f 31 * A CTF enum declaration.
0594c61c 32 *
816fde81
MK
33 * The definition of a enum point basic data type. It will take the data from a
34 * trace and store it (and make it fit) as an integer and a string.
d37aaa7f
FC
35 *
36 * @version 1.0
37 * @author Matthew Khouzam
38 * @author Simon Marchi
866e5b51 39 */
8fa270f6 40public final class EnumDeclaration extends Declaration implements ISimpleDatatypeDeclaration {
866e5b51 41
0c2409c1
MK
42 /**
43 * A pair of longs class
44 *
0336f981 45 * @since 1.1
0c2409c1
MK
46 */
47 public static class Pair {
48 private final long fFirst;
49 private final long fSecond;
50
51 private Pair(long first, long second) {
52 fFirst = first;
53 fSecond = second;
54 }
55
56 /**
57 * @return the first element
58 */
59 public long getFirst() {
60 return fFirst;
61 }
62
63 /**
64 * @return the second element
65 */
66 public long getSecond() {
67 return fSecond;
68 }
69 }
70
866e5b51
FC
71 // ------------------------------------------------------------------------
72 // Attributes
73 // ------------------------------------------------------------------------
74
816fde81
MK
75 private final EnumTable fTable = new EnumTable();
76 private final IntegerDeclaration fContainerType;
3de23137 77 private final Set<String> fLabels = new HashSet<>();
866e5b51
FC
78
79 // ------------------------------------------------------------------------
80 // Constructors
81 // ------------------------------------------------------------------------
82
9ac2eb62
MK
83 /**
84 * constructor
85 *
86 * @param containerType
87 * the enum is an int, this is the type that the data is
88 * contained in. If you have 1000 possible values, you need at
89 * least a 10 bit enum. If you store 2 values in a 128 bit int,
90 * you are wasting space.
91 */
866e5b51 92 public EnumDeclaration(IntegerDeclaration containerType) {
816fde81 93 fContainerType = containerType;
866e5b51
FC
94 }
95
96 // ------------------------------------------------------------------------
97 // Getters/Setters/Predicates
98 // ------------------------------------------------------------------------
99
9ac2eb62
MK
100 /**
101 *
102 * @return The container type
103 */
866e5b51 104 public IntegerDeclaration getContainerType() {
816fde81 105 return fContainerType;
866e5b51
FC
106 }
107
fd74e6c1
MK
108 @Override
109 public long getAlignment() {
110 return this.getContainerType().getAlignment();
111 }
9ac2eb62 112
a4fa4e36
MK
113 @Override
114 public int getMaximumSize() {
115 return fContainerType.getMaximumSize();
116 }
117
615b2145
MK
118 /**
119 * @since 2.0
120 */
121 @Override
122 public boolean isByteOrderSet() {
123 return fContainerType.isByteOrderSet();
124 }
125
126 /**
127 * @since 2.0
128 */
129 @Override
130 public ByteOrder getByteOrder() {
131 return fContainerType.getByteOrder();
132 }
133
866e5b51
FC
134 // ------------------------------------------------------------------------
135 // Operations
136 // ------------------------------------------------------------------------
137
138 @Override
680f9173 139 public EnumDefinition createDefinition(@Nullable IDefinitionScope definitionScope, String fieldName, BitBuffer input) throws CTFException {
a4fa4e36
MK
140 alignRead(input);
141 IntegerDefinition value = getContainerType().createDefinition(definitionScope, fieldName, input);
142 return new EnumDefinition(this, definitionScope, fieldName, value);
866e5b51
FC
143 }
144
9ac2eb62 145 /**
8fa270f6
MK
146 * Add a value. Do not overlap, this is <em><strong>not</strong></em> an
147 * interval tree.
816fde81
MK
148 *
149 * @param low
150 * lowest value that this int can be to have label as a return
151 * string
152 * @param high
153 * highest value that this int can be to have label as a return
154 * string
155 * @param label
156 * the name of the value.
9ac2eb62
MK
157 * @return was the value be added? true == success
158 */
f78eb6a7 159 public boolean add(long low, long high, @Nullable String label) {
816fde81
MK
160 fLabels.add(label);
161 return fTable.add(low, high, label);
866e5b51
FC
162 }
163
9ac2eb62 164 /**
816fde81
MK
165 * Check if the label for a value (enum a{day=0,night=1} would return "day"
166 * for query(0)
167 *
168 * @param value
169 * the value to lookup
9ac2eb62
MK
170 * @return the label of that value, can be null
171 */
f78eb6a7 172 public @Nullable String query(long value) {
816fde81
MK
173 return fTable.query(value);
174 }
175
0c2409c1
MK
176 /**
177 * Get the lookup table
178 *
179 * @return the lookup table
0336f981 180 * @since 1.1
0c2409c1
MK
181 */
182 public Map<String, Pair> getEnumTable() {
183 ImmutableMap.Builder<String, Pair> builder = new ImmutableMap.Builder<>();
184 for (LabelAndRange range : fTable.ranges) {
185 builder.put(range.getLabel(), new Pair(range.low, range.high));
186 }
187 return builder.build();
188
189 }
190
816fde81
MK
191 /**
192 * Gets a set of labels of the enum
193 *
194 * @return A set of labels of the enum, can be empty but not null
195 */
196 public Set<String> getLabels() {
197 return Collections.unmodifiableSet(fLabels);
866e5b51
FC
198 }
199
866e5b51
FC
200 /*
201 * Maps integer range -> string. A simple list for now, but feel free to
202 * optimize it. Babeltrace suggests an interval tree.
203 */
816fde81 204 private class EnumTable {
866e5b51 205
3de23137 206 private final List<LabelAndRange> ranges = new LinkedList<>();
866e5b51
FC
207
208 public EnumTable() {
209 }
210
e00e6663 211 public synchronized boolean add(long low, long high, @Nullable String label) {
816fde81 212 LabelAndRange newRange = new LabelAndRange(low, high, label);
866e5b51 213
816fde81 214 for (LabelAndRange r : ranges) {
866e5b51
FC
215 if (r.intersects(newRange)) {
216 return false;
217 }
218 }
219
220 ranges.add(newRange);
221
222 return true;
223 }
224
9ac2eb62 225 /**
a511da0d 226 * Return the first label that matches a value
816fde81
MK
227 *
228 * @param value
229 * the value to query
9ac2eb62
MK
230 * @return the label corresponding to that value
231 */
e00e6663 232 public synchronized @Nullable String query(long value) {
816fde81 233 for (LabelAndRange r : ranges) {
866e5b51 234 if (r.intersects(value)) {
096bc534 235 return r.getLabel();
866e5b51
FC
236 }
237 }
866e5b51
FC
238 return null;
239 }
240
e00e6663
MK
241 @Override
242 public synchronized int hashCode() {
243 final int prime = 31;
244 int result = 1;
245 for (LabelAndRange range : ranges) {
246 result = prime * result + range.hashCode();
247 }
248 return result;
249 }
250
251 @Override
252 public synchronized boolean equals(@Nullable Object obj) {
253 if (this == obj) {
254 return true;
255 }
256 if (obj == null) {
257 return false;
258 }
259 if (getClass() != obj.getClass()) {
260 return false;
261 }
262 EnumTable other = (EnumTable) obj;
263 if (ranges.size() != other.ranges.size()) {
264 return false;
265 }
266 for (int i = 0; i < ranges.size(); i++) {
267 if (!ranges.get(i).equals(other.ranges.get(i))) {
268 return false;
269 }
270 }
271 return true;
272 }
273
816fde81 274 }
866e5b51 275
096bc534 276 private static class LabelAndRange {
866e5b51 277
816fde81 278 private final long low, high;
f78eb6a7 279 private final @Nullable String fLabel;
866e5b51 280
096bc534
MK
281 /**
282 * Get the label
283 *
284 * @return the label
285 */
e00e6663 286 public @Nullable String getLabel() {
096bc534
MK
287 return fLabel;
288 }
289
f78eb6a7 290 public LabelAndRange(long low, long high, @Nullable String str) {
816fde81
MK
291 this.low = low;
292 this.high = high;
293 this.fLabel = str;
294 }
866e5b51 295
816fde81
MK
296 public boolean intersects(long i) {
297 return (i >= this.low) && (i <= this.high);
298 }
299
300 public boolean intersects(LabelAndRange other) {
301 return this.intersects(other.low)
302 || this.intersects(other.high);
866e5b51 303 }
e00e6663
MK
304
305 @Override
306 public int hashCode() {
307 final int prime = 31;
308 int result = 1;
309 final String label = fLabel;
310 result = prime * result + ((label == null) ? 0 : label.hashCode());
311 result = prime * result + (int) (high ^ (high >>> 32));
312 result = prime * result + (int) (low ^ (low >>> 32));
313 return result;
314 }
315
316 @Override
317 public boolean equals(@Nullable Object obj) {
318 if (this == obj) {
319 return true;
320 }
321 if (obj == null) {
322 return false;
323 }
324 if (getClass() != obj.getClass()) {
325 return false;
326 }
327 LabelAndRange other = (LabelAndRange) obj;
328 final String label = fLabel;
329 if (label == null) {
330 if (other.fLabel != null) {
331 return false;
332 }
333 } else if (!label.equals(other.fLabel)) {
334 return false;
335 }
336 if (high != other.high) {
337 return false;
338 }
339 if (low != other.low) {
340 return false;
341 }
342 return true;
343 }
866e5b51
FC
344 }
345
346 @Override
347 public String toString() {
348 /* Only used for debugging */
66aa25f0
MK
349 StringBuilder sb = new StringBuilder();
350 sb.append("[declaration] enum["); //$NON-NLS-1$
351 for (String label : fLabels) {
352 sb.append("label:").append(label).append(' '); //$NON-NLS-1$
353 }
354 sb.append("type:").append(fContainerType.toString()); //$NON-NLS-1$
355 sb.append(']');
356 String string = sb.toString();
66aa25f0 357 return string;
866e5b51
FC
358 }
359
e00e6663
MK
360 @Override
361 public int hashCode() {
362 final int prime = 31;
363 int result = prime + fContainerType.hashCode();
364 for (String label : fLabels) {
365 result = prime * result + label.hashCode();
366 }
367 result = prime * result + fTable.hashCode();
368 return result;
369 }
370
371 @Override
372 public boolean equals(@Nullable Object obj) {
373 if (this == obj) {
374 return true;
375 }
376 if (obj == null) {
377 return false;
378 }
379 if (getClass() != obj.getClass()) {
380 return false;
381 }
382 EnumDeclaration other = (EnumDeclaration) obj;
383 if (!fContainerType.equals(other.fContainerType)) {
384 return false;
385 }
386 if (fLabels.size() != other.fLabels.size()) {
387 return false;
388 }
389 if (!fLabels.containsAll(other.fLabels)) {
390 return false;
391 }
392 if (!fTable.equals(other.fTable)) {
393 return false;
394 }
395 return true;
396 }
397
66aa25f0
MK
398 @Override
399 public boolean isBinaryEquivalent(@Nullable IDeclaration obj) {
400 if (this == obj) {
401 return true;
402 }
403 if (obj == null) {
404 return false;
405 }
406 if (getClass() != obj.getClass()) {
407 return false;
408 }
409 EnumDeclaration other = (EnumDeclaration) obj;
410 if (!fContainerType.isBinaryEquivalent(other.fContainerType)) {
411 return false;
412 }
413 if (fLabels.size() != other.fLabels.size()) {
414 return false;
415 }
416 if (!fLabels.containsAll(other.fLabels)) {
417 return false;
418 }
419 if (!fTable.equals(other.fTable)) {
420 return false;
421 }
422 return true;
423 }
424
866e5b51 425}
This page took 0.096112 seconds and 5 git commands to generate.