lttng: Restrict version of jdt.annotation in Tycho target platform
[deliverable/tracecompass.git] / org.eclipse.linuxtools.ctf.core / src / org / eclipse / linuxtools / ctf / core / trace / StreamInputPacketReader.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 *******************************************************************************/
12package org.eclipse.linuxtools.ctf.core.trace;
13
14import java.io.IOException;
526c823c 15import java.nio.ByteBuffer;
866e5b51 16
a4fa4e36 17import org.eclipse.jdt.annotation.NonNull;
c26d0fe0 18import org.eclipse.linuxtools.ctf.core.CTFStrings;
866e5b51 19import org.eclipse.linuxtools.ctf.core.event.EventDefinition;
a4fa4e36 20import org.eclipse.linuxtools.ctf.core.event.IEventDeclaration;
486efb2e 21import org.eclipse.linuxtools.ctf.core.event.io.BitBuffer;
a4fa4e36
MK
22import org.eclipse.linuxtools.ctf.core.event.scope.IDefinitionScope;
23import org.eclipse.linuxtools.ctf.core.event.scope.LexicalScope;
866e5b51 24import org.eclipse.linuxtools.ctf.core.event.types.Definition;
a4fa4e36 25import org.eclipse.linuxtools.ctf.core.event.types.IntegerDeclaration;
866e5b51 26import org.eclipse.linuxtools.ctf.core.event.types.IntegerDefinition;
21fb02fa 27import org.eclipse.linuxtools.ctf.core.event.types.SimpleDatatypeDefinition;
866e5b51
FC
28import org.eclipse.linuxtools.ctf.core.event.types.StructDeclaration;
29import org.eclipse.linuxtools.ctf.core.event.types.StructDefinition;
30import org.eclipse.linuxtools.ctf.core.event.types.VariantDefinition;
8e964be1 31import org.eclipse.linuxtools.internal.ctf.core.event.EventDeclaration;
ce2388e0 32import org.eclipse.linuxtools.internal.ctf.core.trace.StreamInputPacketIndexEntry;
866e5b51 33
a4fa4e36
MK
34import com.google.common.collect.ImmutableList;
35
866e5b51 36/**
d37aaa7f 37 * CTF trace packet reader. Reads the events of a packet of a trace file.
5c7202b5 38 *
d37aaa7f
FC
39 * @version 1.0
40 * @author Matthew Khouzam
41 * @author Simon Marchi
866e5b51 42 */
dd9752d5 43public class StreamInputPacketReader implements IDefinitionScope, AutoCloseable {
866e5b51
FC
44
45 // ------------------------------------------------------------------------
6bdc9fac 46 // Attributes
866e5b51
FC
47 // ------------------------------------------------------------------------
48
6bdc9fac 49 /** BitBuffer used to read the trace file. */
a4fa4e36 50 @NonNull
2882273c 51 private final BitBuffer fBitBuffer;
866e5b51 52
6bdc9fac 53 /** StreamInputReader that uses this StreamInputPacketReader. */
2882273c 54 private final StreamInputReader fStreamInputReader;
866e5b51 55
6bdc9fac 56 /** Trace packet header. */
a4fa4e36 57 private final StructDeclaration fTracePacketHeaderDecl;
866e5b51 58
6bdc9fac 59 /** Stream packet context definition. */
a4fa4e36 60 private final StructDeclaration fStreamPacketContextDecl;
866e5b51 61
6bdc9fac 62 /** Stream event header definition. */
a4fa4e36 63 private final StructDeclaration fStreamEventHeaderDecl;
866e5b51 64
c26d0fe0 65 /** Stream event context definition. */
a4fa4e36 66 private final StructDeclaration fStreamEventContextDecl;
866e5b51 67
a4fa4e36
MK
68 private StructDefinition fCurrentTracePacketHeaderDef;
69 private StructDefinition fCurrentStreamEventHeaderDef;
70 private Definition fCurrentStreamPacketContextDef;
6bdc9fac 71 /** Reference to the index entry of the current packet. */
2882273c 72 private StreamInputPacketIndexEntry fCurrentPacket = null;
6bdc9fac 73
866e5b51 74 /**
6bdc9fac
AM
75 * Last timestamp recorded.
76 *
77 * Needed to calculate the complete timestamp values for the events with
78 * compact headers.
866e5b51 79 */
2882273c 80 private long fLastTimestamp = 0;
6bdc9fac
AM
81
82 /** CPU id of current packet. */
2882273c 83 private int fCurrentCpu = 0;
866e5b51 84
2882273c 85 private int fLostEventsInThisPacket;
5c7202b5 86
2882273c 87 private long fLostEventsDuration;
c26d0fe0 88
2882273c 89 private boolean fHasLost = false;
c26d0fe0 90
866e5b51 91 // ------------------------------------------------------------------------
6bdc9fac 92 // Constructors
866e5b51
FC
93 // ------------------------------------------------------------------------
94
95 /**
96 * Constructs a StreamInputPacketReader.
97 *
98 * @param streamInputReader
99 * The StreamInputReader to which this packet reader belongs to.
100 */
101 public StreamInputPacketReader(StreamInputReader streamInputReader) {
2882273c 102 fStreamInputReader = streamInputReader;
866e5b51 103
6bdc9fac 104 /* Set the BitBuffer's byte order. */
2882273c
MK
105 fBitBuffer = new BitBuffer();
106 fBitBuffer.setByteOrder(streamInputReader.getByteOrder());
33656d8e 107
6bdc9fac 108 final Stream currentStream = streamInputReader.getStreamInput().getStream();
a4fa4e36
MK
109 fTracePacketHeaderDecl = currentStream.getTrace().getPacketHeader();
110 fStreamPacketContextDecl = currentStream.getPacketContextDecl();
111 fStreamEventHeaderDecl = currentStream.getEventHeaderDecl();
112 fStreamEventContextDecl = currentStream.getEventContextDecl();
113 }
6bdc9fac 114
a4fa4e36
MK
115 /**
116 * Get the event context defintiion
117 *
118 * @param input
119 * the bitbuffer to read from
120 * @return an context definition, can be null
121 * @throws CTFReaderException
122 * out of bounds exception or such
123 * @since 3.0
124 */
125 public StructDefinition getEventContextDefinition(@NonNull BitBuffer input) throws CTFReaderException {
126 return fStreamEventContextDecl.createDefinition(this, LexicalScope.STREAM_EVENT_CONTEXT.getName(), input);
127 }
6bdc9fac 128
a4fa4e36
MK
129 /**
130 * Get the stream context defintiion
131 *
132 * @param input
133 * the bitbuffer to read from
134 * @return an context definition, can be null
135 * @throws CTFReaderException
136 * out of bounds exception or such
137 * @since 3.0
138 */
139 public StructDefinition getStreamEventHeaderDefinition(@NonNull BitBuffer input) throws CTFReaderException {
140 return fStreamEventHeaderDecl.createDefinition(this, LexicalScope.STREAM_EVENT_HEADER.getName(), input);
141 }
6bdc9fac 142
a4fa4e36
MK
143 /**
144 * Get the packet context defintiion
145 *
146 * @param input
147 * the bitbuffer to read from
148 * @return an context definition, can be null
149 * @throws CTFReaderException
150 * out of bounds exception or such
151 * @since 3.0
152 */
153 public StructDefinition getStreamPacketContextDefinition(@NonNull BitBuffer input) throws CTFReaderException {
154 return fStreamPacketContextDecl.createDefinition(this, LexicalScope.STREAM_PACKET_CONTEXT.getName(), input);
155 }
6bdc9fac 156
a4fa4e36
MK
157 /**
158 * Get the event header defintiion
159 *
160 * @param input
161 * the bitbuffer to read from
162 * @return an header definition, can be null
163 * @throws CTFReaderException
164 * out of bounds exception or such
165 * @since 3.0
166 */
167 public StructDefinition getTracePacketHeaderDefinition(@NonNull BitBuffer input) throws CTFReaderException {
168 return fTracePacketHeaderDecl.createDefinition(this, LexicalScope.TRACE_PACKET_HEADER.getName(), input);
6bdc9fac 169 }
866e5b51 170
5d1c6919
PT
171 /**
172 * Dispose the StreamInputPacketReader
c26d0fe0 173 *
dd9752d5 174 * @since 3.0
5d1c6919 175 */
dd9752d5
AM
176 @Override
177 public void close() {
2882273c 178 fBitBuffer.setByteBuffer(null);
5d1c6919
PT
179 }
180
866e5b51
FC
181 // ------------------------------------------------------------------------
182 // Getters/Setters/Predicates
183 // ------------------------------------------------------------------------
184
9ac2eb62
MK
185 /**
186 * Gets the current packet
187 *
188 * @return the current packet
189 */
486efb2e 190 StreamInputPacketIndexEntry getCurrentPacket() {
2882273c 191 return fCurrentPacket;
866e5b51
FC
192 }
193
9ac2eb62
MK
194 /**
195 * Gets the CPU (core) number
196 *
197 * @return the CPU (core) number
198 */
866e5b51 199 public int getCPU() {
2882273c 200 return fCurrentCpu;
866e5b51
FC
201 }
202
a4fa4e36
MK
203 /**
204 * @since 3.0
205 */
866e5b51 206 @Override
a4fa4e36
MK
207 public LexicalScope getScopePath() {
208 return LexicalScope.PACKET;
866e5b51
FC
209 }
210
211 // ------------------------------------------------------------------------
212 // Operations
213 // ------------------------------------------------------------------------
214
866e5b51
FC
215 /**
216 * Changes the current packet to the given one.
217 *
218 * @param currentPacket
219 * The index entry of the packet to switch to.
db8e8f7d
AM
220 * @throws CTFReaderException
221 * If we get an error reading the packet
866e5b51 222 */
db8e8f7d 223 void setCurrentPacket(StreamInputPacketIndexEntry currentPacket) throws CTFReaderException {
c26d0fe0 224 StreamInputPacketIndexEntry prevPacket = null;
2882273c 225 fCurrentPacket = currentPacket;
866e5b51 226
2882273c 227 if (fCurrentPacket != null) {
866e5b51
FC
228 /*
229 * Change the map of the BitBuffer.
230 */
526c823c 231 ByteBuffer bb = null;
866e5b51 232 try {
2882273c 233 bb = fStreamInputReader.getStreamInput().getByteBufferAt(
a4fa4e36
MK
234 fCurrentPacket.getOffsetBytes(),
235 (fCurrentPacket.getPacketSizeBits() + 7) / 8);
866e5b51 236 } catch (IOException e) {
cf9a28da 237 throw new CTFReaderException(e.getMessage(), e);
866e5b51
FC
238 }
239
2882273c 240 fBitBuffer.setByteBuffer(bb);
866e5b51
FC
241
242 /*
243 * Read trace packet header.
244 */
a4fa4e36
MK
245 if (fTracePacketHeaderDecl != null) {
246 fCurrentTracePacketHeaderDef = getTracePacketHeaderDefinition(fBitBuffer);
866e5b51
FC
247 }
248
249 /*
250 * Read stream packet context.
251 */
a4fa4e36
MK
252 if (fStreamPacketContextDecl != null) {
253 fCurrentStreamPacketContextDef = getStreamPacketContextDefinition(fBitBuffer);
33656d8e 254
132a02b0 255 /* Read CPU ID */
2882273c
MK
256 if (getCurrentPacket().getTarget() != null) {
257 fCurrentCpu = (int) getCurrentPacket().getTargetId();
866e5b51 258 }
21fb02fa 259
132a02b0 260 /* Read number of lost events */
2882273c
MK
261 fLostEventsInThisPacket = (int) getCurrentPacket().getLostEvents();
262 if (fLostEventsInThisPacket != 0) {
263 fHasLost = true;
c26d0fe0
AM
264 /*
265 * Compute the duration of the lost event time range. If the
266 * current packet is the first packet, duration will be set
267 * to 1.
268 */
269 long lostEventsStartTime;
2882273c 270 int index = fStreamInputReader.getStreamInput().getIndex().getEntries().indexOf(currentPacket);
c26d0fe0
AM
271 if (index == 0) {
272 lostEventsStartTime = currentPacket.getTimestampBegin() + 1;
273 } else {
2882273c 274 prevPacket = fStreamInputReader.getStreamInput().getIndex().getEntries().get(index - 1);
c26d0fe0
AM
275 lostEventsStartTime = prevPacket.getTimestampEnd();
276 }
2882273c 277 fLostEventsDuration = Math.abs(lostEventsStartTime - currentPacket.getTimestampBegin());
c26d0fe0 278 }
866e5b51
FC
279 }
280
281 /*
282 * Use the timestamp begin of the packet as the reference for the
283 * timestamp reconstitution.
284 */
2882273c 285 fLastTimestamp = currentPacket.getTimestampBegin();
866e5b51 286 } else {
2882273c 287 fBitBuffer.setByteBuffer(null);
866e5b51 288
2882273c 289 fLastTimestamp = 0;
866e5b51
FC
290 }
291 }
292
293 /**
294 * Returns whether it is possible to read any more events from this packet.
295 *
296 * @return True if it is possible to read any more events from this packet.
297 */
298 public boolean hasMoreEvents() {
2882273c
MK
299 if (fCurrentPacket != null) {
300 return fHasLost || (fBitBuffer.position() < fCurrentPacket.getContentSizeBits());
866e5b51
FC
301 }
302 return false;
303 }
304
305 /**
306 * Reads the next event of the packet into the right event definition.
307 *
308 * @return The event definition containing the event data that was just
309 * read.
310 * @throws CTFReaderException
be6df2d8 311 * If there was a problem reading the trace
866e5b51
FC
312 */
313 public EventDefinition readNextEvent() throws CTFReaderException {
1fbaecd1 314 /* Default values for those fields */
b73145e2 315 long eventID = EventDeclaration.UNSET_EVENT_ID;
866e5b51 316 long timestamp = 0;
2882273c
MK
317 if (fHasLost) {
318 fHasLost = false;
a4fa4e36
MK
319 EventDeclaration lostEventDeclaration = EventDeclaration.getLostEventDeclaration();
320 StructDeclaration lostFields = lostEventDeclaration.getFields();
321 // this is a hard coded map, we know it's not null
322 IntegerDeclaration lostFieldsDecl = (IntegerDeclaration) lostFields.getFields().get(CTFStrings.LOST_EVENTS_FIELD);
323 if (lostFieldsDecl == null)
324 {
325 throw new IllegalStateException("Lost events count not declared!"); //$NON-NLS-1$
326 }
327 IntegerDeclaration lostEventsDurationDecl = (IntegerDeclaration) lostFields.getFields().get(CTFStrings.LOST_EVENTS_DURATION);
328 if (lostEventsDurationDecl == null) {
329 throw new IllegalStateException("Lost events duration not declared!"); //$NON-NLS-1$
330 }
331 IntegerDefinition lostDurationDef = new IntegerDefinition(lostFieldsDecl, null, CTFStrings.LOST_EVENTS_DURATION, fLostEventsDuration);
332 IntegerDefinition lostCountDef = new IntegerDefinition(lostEventsDurationDecl, null, CTFStrings.LOST_EVENTS_FIELD, fLostEventsInThisPacket);
333 IntegerDefinition[] fields = new IntegerDefinition[] { lostCountDef, lostDurationDef };
334 /* this is weird notation, but it's the java notation */
335 final ImmutableList<String> fieldNameList = ImmutableList.<String> builder().add(CTFStrings.LOST_EVENTS_FIELD).add(CTFStrings.LOST_EVENTS_DURATION).build();
336 return new EventDefinition(
337 lostEventDeclaration,
338 fStreamInputReader,
339 fLastTimestamp,
340 null,
341 null,
342 null,
343 new StructDefinition(
344 lostFields,
345 this, "fields", //$NON-NLS-1$
346 fieldNameList,
347 fields
348 ));
349
33656d8e 350 }
132a02b0 351
2882273c 352 final BitBuffer currentBitBuffer = fBitBuffer;
cf9a28da 353 final long posStart = currentBitBuffer.position();
1fbaecd1 354 /* Read the stream event header. */
a4fa4e36
MK
355 if (fStreamEventHeaderDecl != null) {
356 fCurrentStreamEventHeaderDef = getStreamEventHeaderDefinition(currentBitBuffer);
866e5b51 357
1fbaecd1 358 /* Check for the event id. */
a4fa4e36 359 Definition idDef = fCurrentStreamEventHeaderDef.lookupDefinition("id"); //$NON-NLS-1$
1fbaecd1
AM
360 if (idDef instanceof SimpleDatatypeDefinition) {
361 eventID = ((SimpleDatatypeDefinition) idDef).getIntegerValue();
b8cb28f6 362 } else if (idDef != null) {
816fde81 363 throw new CTFReaderException("Incorrect event id : " + eventID); //$NON-NLS-1$
b8cb28f6 364 }
866e5b51 365
c26d0fe0
AM
366 /*
367 * Get the timestamp from the event header (may be overridden later
368 * on)
369 */
a4fa4e36 370 IntegerDefinition timestampDef = fCurrentStreamEventHeaderDef.lookupInteger("timestamp"); //$NON-NLS-1$
0594c61c
AM
371 if (timestampDef != null) {
372 timestamp = calculateTimestamp(timestampDef);
6bdc9fac 373 } // else timestamp remains 0
1fbaecd1
AM
374
375 /* Check for the variant v. */
a4fa4e36 376 Definition variantDef = fCurrentStreamEventHeaderDef.lookupDefinition("v"); //$NON-NLS-1$
6bdc9fac 377 if (variantDef instanceof VariantDefinition) {
866e5b51 378
1fbaecd1 379 /* Get the variant current field */
6bdc9fac 380 StructDefinition variantCurrentField = (StructDefinition) ((VariantDefinition) variantDef).getCurrentField();
866e5b51 381
21fb02fa
MK
382 /*
383 * Try to get the id field in the current field of the variant.
384 * If it is present, it overrides the previously read event id.
385 */
6bdc9fac
AM
386 Definition idIntegerDef = variantCurrentField.lookupDefinition("id"); //$NON-NLS-1$
387 if (idIntegerDef instanceof IntegerDefinition) {
388 eventID = ((IntegerDefinition) idIntegerDef).getValue();
21fb02fa 389 }
866e5b51 390
c26d0fe0
AM
391 /*
392 * Get the timestamp. This would overwrite any previous
393 * timestamp definition
394 */
0594c61c
AM
395 Definition def = variantCurrentField.lookupDefinition("timestamp"); //$NON-NLS-1$
396 if (def instanceof IntegerDefinition) {
397 timestamp = calculateTimestamp((IntegerDefinition) def);
6bdc9fac 398 }
21fb02fa 399 }
866e5b51
FC
400 }
401
1fbaecd1 402 /* Get the right event definition using the event id. */
a4fa4e36
MK
403 IEventDeclaration eventDeclaration = fStreamInputReader.getStreamInput().getStream().getEvents().get(eventID);
404 if (eventDeclaration == null) {
866e5b51
FC
405 throw new CTFReaderException("Incorrect event id : " + eventID); //$NON-NLS-1$
406 }
a4fa4e36 407 EventDefinition eventDef = eventDeclaration.createDefinition(fStreamInputReader, fBitBuffer, timestamp);
866e5b51
FC
408
409 /*
410 * Set the event timestamp using the timestamp calculated by
411 * updateTimestamp.
412 */
866e5b51 413
cf9a28da
MK
414 if (posStart == currentBitBuffer.position()) {
415 throw new CTFReaderException("Empty event not allowed, event: " + eventDef.getDeclaration().getName()); //$NON-NLS-1$
416 }
417
866e5b51
FC
418 return eventDef;
419 }
420
421 /**
422 * Calculates the timestamp value of the event, possibly using the timestamp
423 * from the last event.
424 *
425 * @param timestampDef
426 * Integer definition of the timestamp.
427 * @return The calculated timestamp value.
428 */
429 private long calculateTimestamp(IntegerDefinition timestampDef) {
430 long newval;
431 long majorasbitmask;
432 int len = timestampDef.getDeclaration().getLength();
433
434 /*
435 * If the timestamp length is 64 bits, it is a full timestamp.
436 */
437 if (timestampDef.getDeclaration().getLength() == 64) {
2882273c
MK
438 fLastTimestamp = timestampDef.getValue();
439 return fLastTimestamp;
866e5b51
FC
440 }
441
442 /*
443 * Bit mask to keep / remove all old / new bits.
444 */
445 majorasbitmask = (1L << len) - 1;
446
447 /*
448 * If the new value is smaller than the corresponding bits of the last
449 * timestamp, we assume an overflow of the compact representation.
450 */
451 newval = timestampDef.getValue();
2882273c 452 if (newval < (fLastTimestamp & majorasbitmask)) {
866e5b51
FC
453 newval = newval + (1L << len);
454 }
455
456 /* Keep only the high bits of the old value */
2882273c 457 fLastTimestamp = fLastTimestamp & ~majorasbitmask;
866e5b51
FC
458
459 /* Then add the low bits of the new value */
2882273c 460 fLastTimestamp = fLastTimestamp + newval;
866e5b51 461
2882273c 462 return fLastTimestamp;
866e5b51
FC
463 }
464
465 @Override
466 public Definition lookupDefinition(String lookupPath) {
a4fa4e36
MK
467 if (lookupPath.equals(LexicalScope.STREAM_PACKET_CONTEXT)) {
468 return fCurrentStreamPacketContextDef;
469 }
470 if (lookupPath.equals(LexicalScope.TRACE_PACKET_HEADER)) {
471 return fCurrentTracePacketHeaderDef;
472 }
866e5b51
FC
473 return null;
474 }
a4fa4e36
MK
475
476 /**
477 * Get stream event header
478 *
479 * @return the stream event header
480 * @since 3.0
481 */
482 public StructDefinition getCurrentStreamEventHeader() {
483 return fCurrentStreamEventHeaderDef;
484 }
485
486 /**
487 * Get the current packet event header
488 *
489 * @return the current packet event header
490 * @since 3.0
491 */
492 public StructDefinition getCurrentPacketEventHeader() {
493 return fCurrentTracePacketHeaderDef;
494 }
866e5b51 495}
This page took 0.066367 seconds and 5 git commands to generate.