ctf: Make packet descriptor information available to event
[deliverable/tracecompass.git] / ctf / org.eclipse.tracecompass.ctf.core / src / org / eclipse / tracecompass / internal / ctf / core / trace / CTFPacketReader.java
CommitLineData
42f8feff
MK
1/*******************************************************************************
2 * Copyright (c) 2015 Ericsson
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:
10 * Matthew Khouzam - Initial API and implementation
11 *******************************************************************************/
12
13package org.eclipse.tracecompass.internal.ctf.core.trace;
14
15import java.util.List;
16
17import org.eclipse.jdt.annotation.NonNullByDefault;
18import org.eclipse.jdt.annotation.Nullable;
19import org.eclipse.tracecompass.ctf.core.CTFException;
20import org.eclipse.tracecompass.ctf.core.CTFStrings;
21import org.eclipse.tracecompass.ctf.core.event.EventDefinition;
22import org.eclipse.tracecompass.ctf.core.event.IEventDeclaration;
23import org.eclipse.tracecompass.ctf.core.event.LostEventDeclaration;
24import org.eclipse.tracecompass.ctf.core.event.io.BitBuffer;
25import org.eclipse.tracecompass.ctf.core.event.scope.IDefinitionScope;
26import org.eclipse.tracecompass.ctf.core.event.scope.ILexicalScope;
27import org.eclipse.tracecompass.ctf.core.event.types.ICompositeDefinition;
28import org.eclipse.tracecompass.ctf.core.event.types.IDeclaration;
29import org.eclipse.tracecompass.ctf.core.event.types.IDefinition;
30import org.eclipse.tracecompass.ctf.core.event.types.IEventHeaderDeclaration;
31import org.eclipse.tracecompass.ctf.core.event.types.IntegerDeclaration;
32import org.eclipse.tracecompass.ctf.core.event.types.IntegerDefinition;
33import org.eclipse.tracecompass.ctf.core.event.types.SimpleDatatypeDefinition;
34import org.eclipse.tracecompass.ctf.core.event.types.StructDeclaration;
35import org.eclipse.tracecompass.ctf.core.event.types.StructDefinition;
36import org.eclipse.tracecompass.ctf.core.event.types.VariantDefinition;
37import org.eclipse.tracecompass.ctf.core.trace.CTFIOException;
38import org.eclipse.tracecompass.ctf.core.trace.ICTFPacketDescriptor;
39import org.eclipse.tracecompass.ctf.core.trace.IPacketReader;
40import org.eclipse.tracecompass.internal.ctf.core.event.EventDeclaration;
41import org.eclipse.tracecompass.internal.ctf.core.event.types.composite.EventHeaderDefinition;
42
43/**
44 * Packet reader with a fixed bit buffer, should be the fast and easily
45 * parallelizable one.
46 */
47@NonNullByDefault
48public final class CTFPacketReader implements IPacketReader, IDefinitionScope {
49
50 private static final IDefinitionScope EVENT_HEADER_SCOPE = new IDefinitionScope() {
51
52 @Override
53 public @Nullable IDefinition lookupDefinition(@Nullable String lookupPath) {
54 return null;
55 }
56
57 @Override
58 public @Nullable ILexicalScope getScopePath() {
59 return null;
60 }
61 };
62
63 private final BitBuffer fInput;
64 private final ICTFPacketDescriptor fPacketContext;
32ea78ed 65 private final List<@Nullable IEventDeclaration> fDeclarations;
42f8feff
MK
66 private boolean fHasLost;
67 private long fLastTimestamp;
68 private @Nullable final IDeclaration fStreamEventHeaderDecl;
69
70 private @Nullable final StructDeclaration fStreamContext;
71
72 private @Nullable final ICompositeDefinition fTracePacketHeader;
73
74 private @Nullable final IDefinitionScope fPacketScope;
75
76 private @Nullable ICompositeDefinition fEventHeader;
77
78 /**
79 * Constructor
80 *
81 * @param input
82 * input {@link BitBuffer}
83 * @param packetContext
84 * packet_context where we get info like lost events and cpu_id
85 * @param declarations
86 * event declarations for this packet reader
87 * @param eventHeaderDeclaration
88 * event header declaration, what to read before any given event,
89 * to find it's id
90 * @param streamContext
91 * the context declaration
92 * @param packetHeader
93 * the header with the magic numbers and such
94 * @param packetScope
95 * the scope of the packetHeader
96 */
32ea78ed 97 public CTFPacketReader(BitBuffer input, ICTFPacketDescriptor packetContext, List<@Nullable IEventDeclaration> declarations, @Nullable IDeclaration eventHeaderDeclaration, @Nullable StructDeclaration streamContext, @Nullable ICompositeDefinition packetHeader,
42f8feff
MK
98 IDefinitionScope packetScope) {
99 fInput = input;
100 fPacketContext = packetContext;
101 fDeclarations = declarations;
102 fPacketScope = packetScope;
103 fHasLost = fPacketContext.getLostEvents() != 0;
104 fLastTimestamp = fPacketContext.getTimestampBegin();
105 fStreamEventHeaderDecl = eventHeaderDeclaration;
106 fStreamContext = streamContext;
107 fTracePacketHeader = packetHeader;
108 }
109
110 @Override
111 public int getCPU() {
112 return (int) fPacketContext.getTargetId();
113 }
114
115 @Override
116 public boolean hasMoreEvents() {
f450c256 117 return fHasLost || (fInput.position() < fPacketContext.getContentSizeBits());
42f8feff
MK
118 }
119
120 @Override
121 public EventDefinition readNextEvent() throws CTFException {
122 int eventID = (int) IEventDeclaration.UNSET_EVENT_ID;
123 final long posStart = fInput.position();
124 /*
125 * Return the Lost Event after all other events in this packet. We need
126 * to check if the bytebuffer is at the beginning too.
127 */
f450c256 128 if (fHasLost && (posStart >= fPacketContext.getContentSizeBits())) {
42f8feff
MK
129 fHasLost = false;
130 return createLostEvent(fPacketContext);
131 }
132
133 fEventHeader = null;
134 /* Read the stream event header. */
135 final IDeclaration streamEventHeaderDecl = fStreamEventHeaderDecl;
136 if (streamEventHeaderDecl instanceof IEventHeaderDeclaration) {
137 IEventHeaderDeclaration eventHeaderDeclaration = (IEventHeaderDeclaration) streamEventHeaderDecl;
138 EventHeaderDefinition ehd = (EventHeaderDefinition) eventHeaderDeclaration.createDefinition(EVENT_HEADER_SCOPE, "", fInput); //$NON-NLS-1$
139 fEventHeader = ehd;
140 eventID = ehd.getId();
141 } else if (streamEventHeaderDecl instanceof StructDeclaration) {
142 StructDefinition structEventHeaderDef = ((StructDeclaration) streamEventHeaderDecl).createDefinition(EVENT_HEADER_SCOPE, ILexicalScope.EVENT_HEADER, fInput);
143 fEventHeader = structEventHeaderDef;
144 /* Check for the event id. */
145 IDefinition idDef = structEventHeaderDef.lookupDefinition("id"); //$NON-NLS-1$
146 SimpleDatatypeDefinition simpleIdDef = null;
147 if (idDef instanceof SimpleDatatypeDefinition) {
148 simpleIdDef = ((SimpleDatatypeDefinition) idDef);
149 } else if (idDef != null) {
150 throw new CTFIOException("Id defintion not an integer, enum or float definiton in event header."); //$NON-NLS-1$
151 }
152 /* Check for the variant v. */
153 IDefinition variantDef = structEventHeaderDef.lookupDefinition("v"); //$NON-NLS-1$
154 if (variantDef instanceof VariantDefinition) {
155
156 /* Get the variant current field */
157 StructDefinition variantCurrentField = (StructDefinition) ((VariantDefinition) variantDef).getCurrentField();
158
159 /*
160 * Try to get the id field in the current field of the variant.
161 * If it is present, it overrides the previously read event id.
162 */
163 IDefinition vIdDef = variantCurrentField.lookupDefinition("id"); //$NON-NLS-1$
164 if (vIdDef instanceof IntegerDefinition) {
165 simpleIdDef = (SimpleDatatypeDefinition) vIdDef;
166 }
167
168 }
169 if (simpleIdDef != null) {
170 eventID = simpleIdDef.getIntegerValue().intValue();
171 }
172 }
173 /* Single event type in a trace */
174 if (eventID == IEventDeclaration.UNSET_EVENT_ID && fDeclarations.size() == 1) {
175 eventID = 0;
176 }
177 /* Get the right event definition using the event id. */
178 IEventDeclaration eventDeclaration = fDeclarations.get(eventID);
179 if (!(eventDeclaration instanceof EventDeclaration)) {
180 throw new CTFIOException("Incorrect event id : " + eventID); //$NON-NLS-1$
181 }
182 EventDeclaration declaration = (EventDeclaration) eventDeclaration;
183 EventDefinition eventDef = declaration.createDefinition(fStreamContext, fPacketContext, fTracePacketHeader, fEventHeader, fInput, fLastTimestamp);
184 fLastTimestamp = eventDef.getTimestamp();
185 /*
186 * Set the event timestamp using the timestamp calculated by
187 * updateTimestamp.
188 */
189
190 if (posStart == fInput.position()) {
191 throw new CTFIOException("Empty event not allowed, event: " + eventDef.getDeclaration().getName()); //$NON-NLS-1$
192 }
193
194 return eventDef;
195 }
196
197 private EventDefinition createLostEvent(final ICTFPacketDescriptor currentPacket) {
198 IEventDeclaration lostEventDeclaration = LostEventDeclaration.INSTANCE;
199 StructDeclaration lostFields = lostEventDeclaration.getFields();
200 // this is a hard coded map, we know it's not null
201 IntegerDeclaration lostFieldsDecl = (IntegerDeclaration) lostFields.getField(CTFStrings.LOST_EVENTS_FIELD);
202 if (lostFieldsDecl == null) {
203 throw new IllegalStateException("Lost events count not declared!"); //$NON-NLS-1$
204 }
205 IntegerDeclaration lostEventsDurationDecl = (IntegerDeclaration) lostFields.getField(CTFStrings.LOST_EVENTS_DURATION);
206 if (lostEventsDurationDecl == null) {
207 throw new IllegalStateException("Lost events duration not declared!"); //$NON-NLS-1$
208 }
209 long lostEventsTimestamp = fLastTimestamp;
210 long lostEventsDuration = currentPacket.getTimestampEnd() - lostEventsTimestamp;
211 IntegerDefinition lostDurationDef = new IntegerDefinition(lostFieldsDecl, null, CTFStrings.LOST_EVENTS_DURATION, lostEventsDuration);
212 IntegerDefinition lostCountDef = new IntegerDefinition(lostEventsDurationDecl, null, CTFStrings.LOST_EVENTS_FIELD, fPacketContext.getLostEvents());
213 IntegerDefinition[] fields = new IntegerDefinition[] { lostCountDef, lostDurationDef };
214 int cpu = (int) fPacketContext.getTargetId();
215 return new EventDefinition(
216 lostEventDeclaration,
217 cpu,
218 lostEventsTimestamp,
219 null,
220 null,
221 null,
222 null,
223 new StructDefinition(
224 lostFields,
225 this, "fields", //$NON-NLS-1$
6b8f960d
MK
226 fields),
227 fPacketContext);
42f8feff
MK
228 }
229
230 @Override
231 public ILexicalScope getScopePath() {
232 return ILexicalScope.PACKET;
233 }
234
235 @Override
236 public @Nullable IDefinition lookupDefinition(@Nullable String lookupPath) {
237 if (ILexicalScope.TRACE_PACKET_HEADER.getPath().equals(lookupPath)) {
238 return fTracePacketHeader;
239 } else if (ILexicalScope.STREAM_PACKET_CONTEXT.getPath().equals(lookupPath) && fPacketScope != null) {
240 return fPacketScope.lookupDefinition(lookupPath);
241 }
242 return null;
243 }
244
245 @Override
246 public ICTFPacketDescriptor getCurrentPacket() {
247 return fPacketContext;
248 }
249
250 /**
251 * TODO: remove when API is reworked a bit.
252 */
253 @Override
254 public @Nullable ICompositeDefinition getCurrentPacketEventHeader() {
255 return fEventHeader;
256 }
257
258}
This page took 0.058433 seconds and 5 git commands to generate.