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
1 /*******************************************************************************
2 * Copyright (c) 2011, 2014 Ericsson, Ecole Polytechnique de Montreal and others
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
13 package org.eclipse.tracecompass.internal.ctf.core.event;
14
15 import java.util.HashMap;
16 import java.util.Map;
17 import java.util.Set;
18
19 import org.eclipse.jdt.annotation.NonNull;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.eclipse.tracecompass.ctf.core.CTFException;
22 import org.eclipse.tracecompass.ctf.core.CTFStrings;
23 import org.eclipse.tracecompass.ctf.core.event.EventDefinition;
24 import org.eclipse.tracecompass.ctf.core.event.IEventDeclaration;
25 import org.eclipse.tracecompass.ctf.core.event.io.BitBuffer;
26 import org.eclipse.tracecompass.ctf.core.event.scope.ILexicalScope;
27 import org.eclipse.tracecompass.ctf.core.event.types.Definition;
28 import org.eclipse.tracecompass.ctf.core.event.types.ICompositeDefinition;
29 import org.eclipse.tracecompass.ctf.core.event.types.IntegerDefinition;
30 import org.eclipse.tracecompass.ctf.core.event.types.StructDeclaration;
31 import org.eclipse.tracecompass.ctf.core.event.types.StructDefinition;
32 import org.eclipse.tracecompass.ctf.core.trace.CTFIOException;
33 import org.eclipse.tracecompass.ctf.core.trace.CTFStream;
34 import org.eclipse.tracecompass.ctf.core.trace.CTFStreamInputReader;
35 import org.eclipse.tracecompass.internal.ctf.core.event.types.composite.EventHeaderDefinition;
36
37 /**
38 * Representation of one type of event. A bit like "int" or "long" but for trace
39 * events.
40 */
41 public class EventDeclaration implements IEventDeclaration {
42
43 // ------------------------------------------------------------------------
44 // Attributes
45 // ------------------------------------------------------------------------
46
47 /**
48 * Name of the event
49 */
50 private String fName;
51
52 /**
53 * Event context structure declaration
54 */
55 private StructDeclaration fContext = null;
56
57 /**
58 * Event fields structure declaration
59 */
60 private StructDeclaration fFields = null;
61
62 /**
63 * Stream to which belongs this event.
64 */
65 private CTFStream fStream = null;
66
67 /**
68 * Loglevel of an event
69 */
70 private long fLogLevel;
71
72 /** Map of this event type's custom CTF attributes */
73 private final Map<String, String> fCustomAttributes = new HashMap<>();
74
75 private int fId = (int) UNSET_EVENT_ID;
76
77 // ------------------------------------------------------------------------
78 // Constructors
79 // ------------------------------------------------------------------------
80
81 /**
82 * Default constructor. Use the setters afterwards to set the fields
83 * accordingly.
84 */
85 public EventDeclaration() {
86 }
87
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
97 * @param prevTimestamp
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 */
104 public EventDefinition createDefinition(CTFStreamInputReader streamInputReader, ICompositeDefinition eventHeaderDef, @NonNull BitBuffer input, long prevTimestamp) throws CTFException {
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;
110 long timestamp = calculateTimestamp(eventHeaderDef, prevTimestamp, eventPayload);
111
112 return new EventDefinition(
113 this,
114 streamInputReader,
115 timestamp,
116 eventHeaderDef,
117 streamEventContext,
118 eventContext,
119 packetContext,
120 eventPayload);
121 }
122
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
145 @Override
146 public EventDefinition createDefinition(CTFStreamInputReader streamInputReader, @NonNull BitBuffer input, long timestamp) throws CTFException {
147 StructDeclaration streamEventContextDecl = streamInputReader.getStreamEventContextDecl();
148 StructDefinition streamEventContext = streamEventContextDecl != null ? streamEventContextDecl.createDefinition(fStream.getTrace(), ILexicalScope.STREAM_EVENT_CONTEXT, input) : null;
149 ICompositeDefinition packetContext = streamInputReader.getPacketReader().getCurrentPacketEventHeader();
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;
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);
164 }
165
166 // ------------------------------------------------------------------------
167 // Getters/Setters/Predicates
168 // ------------------------------------------------------------------------
169
170 /**
171 * Sets a name for an event Declaration
172 *
173 * @param name
174 * the name
175 */
176 public void setName(String name) {
177 fName = name;
178 }
179
180 @Override
181 public String getName() {
182 return fName;
183 }
184
185 /**
186 * Sets the context for an event declaration (see CTF specification)
187 *
188 * @param context
189 * the context in structdeclaration format
190 */
191 public void setContext(StructDeclaration context) {
192 fContext = context;
193 }
194
195 /**
196 * Sets the fields of an event declaration
197 *
198 * @param fields
199 * the fields in structdeclaration format
200 */
201 public void setFields(StructDeclaration fields) {
202 fFields = fields;
203 }
204
205 @Override
206 public StructDeclaration getFields() {
207 return fFields;
208 }
209
210 @Override
211 public StructDeclaration getContext() {
212 return fContext;
213 }
214
215 /**
216 * Sets the id of an event declaration
217 *
218 * @param id
219 * the id
220 */
221 public void setId(long id) {
222 if (id < 0 || id > Integer.MAX_VALUE) {
223 throw new IllegalArgumentException("id out of range"); //$NON-NLS-1$
224 }
225 fId = (int) id;
226 }
227
228 @Override
229 public Long getId() {
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() {
239 return fId;
240 }
241
242 /**
243 * Sets the stream of an event declaration
244 *
245 * @param stream
246 * the stream
247 */
248 public void setStream(CTFStream stream) {
249 fStream = stream;
250 }
251
252 @Override
253 public CTFStream getStream() {
254 return fStream;
255 }
256
257 /**
258 * Is the name of the event declaration set
259 *
260 * @return is the name set?
261 */
262 public boolean nameIsSet() {
263 return fName != null;
264 }
265
266 /**
267 * Is the context set
268 *
269 * @return is the context set
270 */
271 public boolean contextIsSet() {
272 return fContext != null;
273 }
274
275 /**
276 * Is a field set?
277 *
278 * @return Is the field set?
279 */
280 public boolean fieldsIsSet() {
281 return fFields != null;
282 }
283
284 /**
285 * Is the id set?
286 *
287 * @return is the id set?
288 */
289 public boolean idIsSet() {
290 return (fId != UNSET_EVENT_ID);
291 }
292
293 /**
294 * Is the stream set?
295 *
296 * @return is the stream set?
297 */
298 public boolean streamIsSet() {
299 return fStream != null;
300 }
301
302 @Override
303 public long getLogLevel() {
304 return fLogLevel;
305 }
306
307 /**
308 * Sets the log level
309 *
310 * @param level
311 * the log level
312 */
313 public void setLogLevel(long level) {
314 fLogLevel = level;
315 }
316
317 @Override
318 public Set<String> getCustomAttributes() {
319 return fCustomAttributes.keySet();
320 }
321
322 @Override
323 public String getCustomAttribute(String key) {
324 return fCustomAttributes.get(key);
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
334 */
335 public void setCustomAttribute(String key, String value) {
336 fCustomAttributes.put(key, value);
337 }
338
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
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;
405 if (fContext == null) {
406 if (other.fContext != null) {
407 return false;
408 }
409 } else if (!fContext.equals(other.fContext)) {
410 return false;
411 }
412 if (fFields == null) {
413 if (other.fFields != null) {
414 return false;
415 }
416 } else if (!fFields.equals(other.fFields)) {
417 return false;
418 }
419 if (fId != (other.fId)) {
420 return false;
421 }
422 if (fName == null) {
423 if (other.fName != null) {
424 return false;
425 }
426 } else if (!fName.equals(other.fName)) {
427 return false;
428 }
429 if (fStream == null) {
430 if (other.fStream != null) {
431 return false;
432 }
433 } else if (!fStream.equals(other.fStream)) {
434 return false;
435 }
436 if (!fCustomAttributes.equals(other.fCustomAttributes)) {
437 return false;
438 }
439 return true;
440 }
441
442 @Override
443 public int hashCode() {
444 final int prime = 31;
445 int result = 1;
446 result = (prime * result)
447 + ((fContext == null) ? 0 : fContext.hashCode());
448 result = (prime * result) + ((fFields == null) ? 0 : fFields.hashCode());
449 result = (prime * result) + fId;
450 result = (prime * result) + ((fName == null) ? 0 : fName.hashCode());
451 result = (prime * result) + ((fStream == null) ? 0 : fStream.hashCode());
452 result = (prime * result) + fCustomAttributes.hashCode();
453 return result;
454 }
455
456 }
This page took 0.040675 seconds and 5 git commands to generate.