ctf: fix parser not parsing "thing := keyword typealias;" regression
[deliverable/tracecompass.git] / ctf / org.eclipse.tracecompass.ctf.core / src / org / eclipse / tracecompass / internal / ctf / core / event / EventDeclaration.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.internal.ctf.core.event;
866e5b51 14
8e964be1
MK
15import java.util.HashMap;
16import java.util.Map;
17import java.util.Set;
18
a4fa4e36 19import org.eclipse.jdt.annotation.NonNull;
5b341dc8 20import org.eclipse.jdt.annotation.Nullable;
680f9173 21import org.eclipse.tracecompass.ctf.core.CTFException;
5b341dc8 22import org.eclipse.tracecompass.ctf.core.CTFStrings;
f357bcd4
AM
23import org.eclipse.tracecompass.ctf.core.event.EventDefinition;
24import org.eclipse.tracecompass.ctf.core.event.IEventDeclaration;
25import org.eclipse.tracecompass.ctf.core.event.io.BitBuffer;
fbe6fa6f 26import org.eclipse.tracecompass.ctf.core.event.scope.ILexicalScope;
5b341dc8 27import org.eclipse.tracecompass.ctf.core.event.types.Definition;
778bce67 28import org.eclipse.tracecompass.ctf.core.event.types.ICompositeDefinition;
5b341dc8 29import org.eclipse.tracecompass.ctf.core.event.types.IntegerDefinition;
f357bcd4
AM
30import org.eclipse.tracecompass.ctf.core.event.types.StructDeclaration;
31import org.eclipse.tracecompass.ctf.core.event.types.StructDefinition;
5b341dc8 32import org.eclipse.tracecompass.ctf.core.trace.CTFIOException;
f357bcd4
AM
33import org.eclipse.tracecompass.ctf.core.trace.CTFStream;
34import org.eclipse.tracecompass.ctf.core.trace.CTFStreamInputReader;
5b341dc8 35import org.eclipse.tracecompass.internal.ctf.core.event.types.composite.EventHeaderDefinition;
866e5b51
FC
36
37/**
be6df2d8
AM
38 * Representation of one type of event. A bit like "int" or "long" but for trace
39 * events.
866e5b51 40 */
8e964be1 41public class EventDeclaration implements IEventDeclaration {
866e5b51
FC
42
43 // ------------------------------------------------------------------------
44 // Attributes
45 // ------------------------------------------------------------------------
46
47 /**
48 * Name of the event
49 */
75259c16 50 private String fName;
866e5b51
FC
51
52 /**
53 * Event context structure declaration
54 */
75259c16 55 private StructDeclaration fContext = null;
866e5b51
FC
56
57 /**
58 * Event fields structure declaration
59 */
75259c16 60 private StructDeclaration fFields = null;
866e5b51 61
866e5b51
FC
62 /**
63 * Stream to which belongs this event.
64 */
d84419e1 65 private CTFStream fStream = null;
866e5b51 66
53047a66
MK
67 /**
68 * Loglevel of an event
69 */
75259c16 70 private long fLogLevel;
53047a66 71
8e964be1 72 /** Map of this event type's custom CTF attributes */
75259c16 73 private final Map<String, String> fCustomAttributes = new HashMap<>();
8e964be1 74
5f715709
MK
75 private int fId = (int) UNSET_EVENT_ID;
76
866e5b51
FC
77 // ------------------------------------------------------------------------
78 // Constructors
79 // ------------------------------------------------------------------------
80
be6df2d8
AM
81 /**
82 * Default constructor. Use the setters afterwards to set the fields
83 * accordingly.
84 */
8e964be1
MK
85 public EventDeclaration() {
86 }
be6df2d8 87
94c255ef
MK
88 /**
89 * Creates an instance of EventDefinition corresponding to this declaration.
90 *
91 * @param streamInputReader
92 * The StreamInputReader for which this definition is created.
93 * @param eventHeaderDef
94 * The event header definition
95 * @param input
96 * the bitbuffer input source
5b341dc8 97 * @param prevTimestamp
94c255ef
MK
98 * The timestamp when the event was taken
99 * @return A new EventDefinition.
100 * @throws CTFException
101 * As a bitbuffer is used to read, it could have wrapped
102 * IOExceptions.
103 */
5b341dc8 104 public EventDefinition createDefinition(CTFStreamInputReader streamInputReader, ICompositeDefinition eventHeaderDef, @NonNull BitBuffer input, long prevTimestamp) throws CTFException {
94c255ef
MK
105 StructDeclaration streamEventContextDecl = streamInputReader.getStreamEventContextDecl();
106 StructDefinition streamEventContext = streamEventContextDecl != null ? streamEventContextDecl.createDefinition(fStream.getTrace(), ILexicalScope.STREAM_EVENT_CONTEXT, input) : null;
107 ICompositeDefinition packetContext = streamInputReader.getPacketReader().getCurrentPacketEventHeader();
108 StructDefinition eventContext = fContext != null ? fContext.createFieldDefinition(eventHeaderDef, fStream.getTrace(), ILexicalScope.CONTEXT, input) : null;
109 StructDefinition eventPayload = fFields != null ? fFields.createFieldDefinition(eventHeaderDef, fStream.getTrace(), ILexicalScope.FIELDS, input) : null;
5b341dc8 110 long timestamp = calculateTimestamp(eventHeaderDef, prevTimestamp, eventPayload);
94c255ef 111
94c255ef
MK
112 return new EventDefinition(
113 this,
114 streamInputReader,
115 timestamp,
116 eventHeaderDef,
117 streamEventContext,
118 eventContext,
119 packetContext,
120 eventPayload);
121 }
122
5b341dc8
MK
123 private static long calculateTimestamp(@Nullable ICompositeDefinition eventHeaderDef, long prevTimestamp, StructDefinition eventPayload) throws CTFIOException {
124 long timestamp = 0;
125 Definition def = null;
126 if (eventHeaderDef instanceof EventHeaderDefinition) {
127 EventHeaderDefinition eventHeaderDefinition = (EventHeaderDefinition) eventHeaderDef;
128 timestamp = calculateTimestamp(eventHeaderDefinition.getTimestamp(), eventHeaderDefinition.getTimestampLength(), prevTimestamp);
129 } else if (eventHeaderDef instanceof StructDefinition) {
130 StructDefinition structDefinition = (StructDefinition) eventHeaderDef;
131 def = structDefinition.lookupDefinition(CTFStrings.TIMESTAMP);
132 } else if (eventHeaderDef != null) {
133 throw new CTFIOException("Event header def is not a Struct or an Event Header"); //$NON-NLS-1$
134 }
135 if (def == null && eventPayload != null) {
136 def = eventPayload.lookupDefinition(CTFStrings.TIMESTAMP);
137 }
138 if (def instanceof IntegerDefinition) {
139 IntegerDefinition timestampDef = (IntegerDefinition) def;
140 timestamp = calculateTimestamp(timestampDef, prevTimestamp);
141 }
142 return timestamp;
143 }
144
8e964be1 145 @Override
680f9173 146 public EventDefinition createDefinition(CTFStreamInputReader streamInputReader, @NonNull BitBuffer input, long timestamp) throws CTFException {
a4fa4e36 147 StructDeclaration streamEventContextDecl = streamInputReader.getStreamEventContextDecl();
fbe6fa6f 148 StructDefinition streamEventContext = streamEventContextDecl != null ? streamEventContextDecl.createDefinition(fStream.getTrace(), ILexicalScope.STREAM_EVENT_CONTEXT, input) : null;
778bce67 149 ICompositeDefinition packetContext = streamInputReader.getPacketReader().getCurrentPacketEventHeader();
fbe6fa6f
MK
150 StructDefinition eventContext = fContext != null ? fContext.createDefinition(fStream.getTrace(), ILexicalScope.CONTEXT, input) : null;
151 StructDefinition eventPayload = fFields != null ? fFields.createDefinition(fStream.getTrace(), ILexicalScope.FIELDS, input) : null;
a4fa4e36
MK
152
153 // a bit lttng specific
154 // CTF doesn't require a timestamp,
155 // but it's passed to us
156 return new EventDefinition(
157 this,
158 streamInputReader,
159 timestamp,
160 streamEventContext,
161 eventContext,
162 packetContext,
163 eventPayload);
866e5b51
FC
164 }
165
166 // ------------------------------------------------------------------------
167 // Getters/Setters/Predicates
168 // ------------------------------------------------------------------------
169
9ac2eb62
MK
170 /**
171 * Sets a name for an event Declaration
8e964be1
MK
172 *
173 * @param name
174 * the name
9ac2eb62 175 */
866e5b51 176 public void setName(String name) {
75259c16 177 fName = name;
866e5b51
FC
178 }
179
8e964be1 180 @Override
866e5b51 181 public String getName() {
75259c16 182 return fName;
866e5b51
FC
183 }
184
9ac2eb62
MK
185 /**
186 * Sets the context for an event declaration (see CTF specification)
8e964be1
MK
187 *
188 * @param context
189 * the context in structdeclaration format
9ac2eb62 190 */
866e5b51 191 public void setContext(StructDeclaration context) {
75259c16 192 fContext = context;
866e5b51
FC
193 }
194
9ac2eb62
MK
195 /**
196 * Sets the fields of an event declaration
8e964be1
MK
197 *
198 * @param fields
199 * the fields in structdeclaration format
9ac2eb62 200 */
866e5b51 201 public void setFields(StructDeclaration fields) {
75259c16 202 fFields = fields;
866e5b51
FC
203 }
204
8e964be1 205 @Override
866e5b51 206 public StructDeclaration getFields() {
75259c16 207 return fFields;
866e5b51
FC
208 }
209
8e964be1 210 @Override
866e5b51 211 public StructDeclaration getContext() {
75259c16 212 return fContext;
866e5b51
FC
213 }
214
9ac2eb62 215 /**
ecb12461 216 * Sets the id of an event declaration
8e964be1
MK
217 *
218 * @param id
219 * the id
9ac2eb62 220 */
866e5b51 221 public void setId(long id) {
5f715709
MK
222 if (id < 0 || id > Integer.MAX_VALUE) {
223 throw new IllegalArgumentException("id out of range"); //$NON-NLS-1$
224 }
225 fId = (int) id;
866e5b51
FC
226 }
227
8e964be1 228 @Override
866e5b51 229 public Long getId() {
5f715709
MK
230 return Long.valueOf(fId);
231 }
232
233 /**
234 * Faster get id assuming you have less than a billion event types
235 *
236 * @return the event id
237 */
238 public int id() {
75259c16 239 return fId;
866e5b51
FC
240 }
241
9ac2eb62 242 /**
ecb12461 243 * Sets the stream of an event declaration
8e964be1
MK
244 *
245 * @param stream
246 * the stream
9ac2eb62 247 */
d84419e1 248 public void setStream(CTFStream stream) {
75259c16 249 fStream = stream;
866e5b51
FC
250 }
251
8e964be1 252 @Override
d84419e1 253 public CTFStream getStream() {
75259c16 254 return fStream;
866e5b51
FC
255 }
256
9ac2eb62
MK
257 /**
258 * Is the name of the event declaration set
8e964be1 259 *
9ac2eb62
MK
260 * @return is the name set?
261 */
866e5b51 262 public boolean nameIsSet() {
75259c16 263 return fName != null;
866e5b51
FC
264 }
265
9ac2eb62
MK
266 /**
267 * Is the context set
8e964be1 268 *
9ac2eb62
MK
269 * @return is the context set
270 */
866e5b51 271 public boolean contextIsSet() {
75259c16 272 return fContext != null;
866e5b51
FC
273 }
274
9ac2eb62
MK
275 /**
276 * Is a field set?
8e964be1 277 *
9ac2eb62
MK
278 * @return Is the field set?
279 */
866e5b51 280 public boolean fieldsIsSet() {
75259c16 281 return fFields != null;
866e5b51
FC
282 }
283
9ac2eb62
MK
284 /**
285 * Is the id set?
8e964be1 286 *
9ac2eb62
MK
287 * @return is the id set?
288 */
866e5b51 289 public boolean idIsSet() {
8e0c9d81 290 return (fId != UNSET_EVENT_ID);
866e5b51
FC
291 }
292
9ac2eb62
MK
293 /**
294 * Is the stream set?
8e964be1 295 *
9ac2eb62
MK
296 * @return is the stream set?
297 */
866e5b51 298 public boolean streamIsSet() {
75259c16 299 return fStream != null;
866e5b51
FC
300 }
301
8e964be1 302 @Override
53047a66 303 public long getLogLevel() {
75259c16 304 return fLogLevel;
53047a66
MK
305 }
306
9ac2eb62
MK
307 /**
308 * Sets the log level
8e964be1
MK
309 *
310 * @param level
311 * the log level
9ac2eb62 312 */
8e964be1 313 public void setLogLevel(long level) {
75259c16 314 fLogLevel = level;
53047a66
MK
315 }
316
8e964be1
MK
317 @Override
318 public Set<String> getCustomAttributes() {
75259c16 319 return fCustomAttributes.keySet();
8e964be1
MK
320 }
321
322 @Override
323 public String getCustomAttribute(String key) {
75259c16 324 return fCustomAttributes.get(key);
8e964be1
MK
325 }
326
327 /**
328 * Sets a custom attribute value.
329 *
330 * @param key
331 * the key of the attribute
332 * @param value
333 * the value of the attribute
8e964be1
MK
334 */
335 public void setCustomAttribute(String key, String value) {
75259c16 336 fCustomAttributes.put(key, value);
8e964be1
MK
337 }
338
5b341dc8
MK
339 /**
340 * Calculates the timestamp value of the event, possibly using the timestamp
341 * from the last event.
342 *
343 * @param timestampDef
344 * Integer definition of the timestamp.
345 * @return The calculated timestamp value.
346 */
347 private static long calculateTimestamp(IntegerDefinition timestampDef, long lastTimestamp) {
348 int len = timestampDef.getDeclaration().getLength();
349 final long value = timestampDef.getValue();
350
351 return calculateTimestamp(value, len, lastTimestamp);
352 }
353
354 private static long calculateTimestamp(final long value, int len, long prevTimestamp) {
355 long newval;
356 long majorasbitmask;
357 long lastTimestamp = prevTimestamp;
358 /*
359 * If the timestamp length is 64 bits, it is a full timestamp.
360 */
361 if (len == Long.SIZE) {
362 lastTimestamp = value;
363 return lastTimestamp;
364 }
365
366 /*
367 * Bit mask to keep / remove all old / new bits.
368 */
369 majorasbitmask = (1L << len) - 1;
370
371 /*
372 * If the new value is smaller than the corresponding bits of the last
373 * timestamp, we assume an overflow of the compact representation.
374 */
375 newval = value;
376 if (newval < (lastTimestamp & majorasbitmask)) {
377 newval = newval + (1L << len);
378 }
379
380 /* Keep only the high bits of the old value */
381 lastTimestamp = lastTimestamp & ~majorasbitmask;
382
383 /* Then add the low bits of the new value */
384 lastTimestamp = lastTimestamp + newval;
385
386 return lastTimestamp;
387 }
388
866e5b51
FC
389 // ------------------------------------------------------------------------
390 // Operations
391 // ------------------------------------------------------------------------
392
393 @Override
394 public boolean equals(Object obj) {
395 if (this == obj) {
396 return true;
397 }
398 if (obj == null) {
399 return false;
400 }
401 if (!(obj instanceof EventDeclaration)) {
402 return false;
403 }
404 EventDeclaration other = (EventDeclaration) obj;
75259c16
MK
405 if (fContext == null) {
406 if (other.fContext != null) {
866e5b51
FC
407 return false;
408 }
75259c16 409 } else if (!fContext.equals(other.fContext)) {
866e5b51
FC
410 return false;
411 }
75259c16
MK
412 if (fFields == null) {
413 if (other.fFields != null) {
866e5b51
FC
414 return false;
415 }
75259c16 416 } else if (!fFields.equals(other.fFields)) {
866e5b51
FC
417 return false;
418 }
5f715709 419 if (fId != (other.fId)) {
866e5b51
FC
420 return false;
421 }
75259c16
MK
422 if (fName == null) {
423 if (other.fName != null) {
866e5b51
FC
424 return false;
425 }
75259c16 426 } else if (!fName.equals(other.fName)) {
866e5b51
FC
427 return false;
428 }
75259c16
MK
429 if (fStream == null) {
430 if (other.fStream != null) {
866e5b51
FC
431 return false;
432 }
75259c16 433 } else if (!fStream.equals(other.fStream)) {
866e5b51
FC
434 return false;
435 }
75259c16 436 if (!fCustomAttributes.equals(other.fCustomAttributes)) {
8e964be1
MK
437 return false;
438 }
866e5b51
FC
439 return true;
440 }
441
442 @Override
443 public int hashCode() {
444 final int prime = 31;
445 int result = 1;
446 result = (prime * result)
75259c16
MK
447 + ((fContext == null) ? 0 : fContext.hashCode());
448 result = (prime * result) + ((fFields == null) ? 0 : fFields.hashCode());
5f715709 449 result = (prime * result) + fId;
75259c16
MK
450 result = (prime * result) + ((fName == null) ? 0 : fName.hashCode());
451 result = (prime * result) + ((fStream == null) ? 0 : fStream.hashCode());
452 result = (prime * result) + fCustomAttributes.hashCode();
866e5b51
FC
453 return result;
454 }
455
456}
This page took 0.083213 seconds and 5 git commands to generate.