1 /*******************************************************************************
2 * Copyright (c) 2011, 2014 Ericsson, Ecole Polytechnique de Montreal and others
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
9 * Contributors: Matthew Khouzam - Initial API and implementation
10 * Contributors: Simon Marchi - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.tracecompass
.ctf
.core
.trace
;
15 import java
.util
.ArrayList
;
16 import java
.util
.Collection
;
17 import java
.util
.Collections
;
18 import java
.util
.HashSet
;
19 import java
.util
.List
;
22 import org
.eclipse
.jdt
.annotation
.NonNull
;
23 import org
.eclipse
.jdt
.annotation
.Nullable
;
24 import org
.eclipse
.tracecompass
.ctf
.core
.CTFException
;
25 import org
.eclipse
.tracecompass
.ctf
.core
.event
.IEventDeclaration
;
26 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.IDeclaration
;
27 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.IEventHeaderDeclaration
;
28 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.StructDeclaration
;
29 import org
.eclipse
.tracecompass
.internal
.ctf
.core
.event
.EventDeclaration
;
30 import org
.eclipse
.tracecompass
.internal
.ctf
.core
.event
.metadata
.exceptions
.ParseException
;
33 * <b><u>Stream</u></b>
35 * Represents a stream in a trace.
37 public class CTFStream
{
39 // ------------------------------------------------------------------------
41 // ------------------------------------------------------------------------
44 * The numerical ID of the stream
49 * Declarations of the stream-specific structures
51 private StructDeclaration fPacketContextDecl
= null;
52 private IDeclaration fEventHeaderDecl
= null;
53 private StructDeclaration fEventContextDecl
= null;
56 * The trace to which the stream belongs
58 private CTFTrace fTrace
= null;
61 * Maps event ids to events
63 private final ArrayList
<IEventDeclaration
> fEvents
= new ArrayList
<>();
65 private boolean fEventUnsetId
= false;
66 private boolean fStreamIdSet
= false;
69 * The inputs associated to this stream
71 private final Set
<CTFStreamInput
> fInputs
= new HashSet
<>();
73 // ------------------------------------------------------------------------
75 // ------------------------------------------------------------------------
78 * Constructs a Stream that belongs to a Trace
81 * The trace to which belongs this stream.
83 public CTFStream(CTFTrace trace
) {
87 // ------------------------------------------------------------------------
88 // Getters/Setters/Predicates
89 // ------------------------------------------------------------------------
92 * Sets the id of a stream
97 public void setId(long id
) {
103 * Gets the id of a stream
105 * @return id the id of a stream
108 public long getId() {
113 * Is the id of a stream set
115 * @return If the ID is set or not
117 public boolean isIdSet() {
123 * @return is the event header set (timestamp and stuff) (see Ctf Spec)
125 public boolean isEventHeaderSet() {
126 return fEventHeaderDecl
!= null;
131 * @return is the event context set (pid and stuff) (see Ctf Spec)
133 public boolean isEventContextSet() {
134 return fEventContextDecl
!= null;
139 * @return Is the packet context set (see Ctf Spec)
141 public boolean isPacketContextSet() {
142 return fPacketContextDecl
!= null;
146 * Sets the event header
149 * the current event header for all events in this stream
151 public void setEventHeader(StructDeclaration eventHeader
) {
152 fEventHeaderDecl
= eventHeader
;
156 * Sets the event header, this typically has the id and the timestamp
159 * the current event header for all events in this stream
161 public void setEventHeader(IEventHeaderDeclaration eventHeader
) {
162 fEventHeaderDecl
= eventHeader
;
167 * @param eventContext
168 * the context for all events in this stream
170 public void setEventContext(StructDeclaration eventContext
) {
171 fEventContextDecl
= eventContext
;
176 * @param packetContext
177 * the packet context for all packets in this stream
179 public void setPacketContext(StructDeclaration packetContext
) {
180 fPacketContextDecl
= packetContext
;
184 * Gets the event header declaration
186 * @return the event header declaration in declaration form
188 public IDeclaration
getEventHeaderDeclaration() {
189 return fEventHeaderDecl
;
194 * @return the event context declaration in structdeclaration form
196 public StructDeclaration
getEventContextDecl() {
197 return fEventContextDecl
;
202 * @return the packet context declaration in structdeclaration form
204 public StructDeclaration
getPacketContextDecl() {
205 return fPacketContextDecl
;
210 * @return the set of all stream inputs for this stream
212 public Set
<CTFStreamInput
> getStreamInputs() {
218 * @return the parent trace
220 public CTFTrace
getTrace() {
225 * Get all the event declarations in this stream.
227 * @return The event declarations for this stream
229 public @NonNull Collection
<IEventDeclaration
> getEventDeclarations() {
230 List
<IEventDeclaration
> retVal
= new ArrayList
<>(fEvents
);
231 retVal
.removeAll(Collections
.<IEventDeclaration
> singletonList(null));
236 * Get the event declaration for a given ID.
239 * The ID, can be {@link EventDeclaration#UNSET_EVENT_ID}, or any
241 * @return The event declaration with the given ID for this stream, or
242 * 'null' if there are no declaration with this ID
243 * @throws IllegalArgumentException
244 * If the passed ID is invalid
246 public @Nullable IEventDeclaration
getEventDeclaration(int eventId
) {
247 int eventIndex
= (eventId
== IEventDeclaration
.UNSET_EVENT_ID
) ?
0 : eventId
;
248 if (eventIndex
< 0) {
249 /* Any negative value other than UNSET_EVENT_ID is invalid */
250 throw new IllegalArgumentException("Event ID cannot be negative."); //$NON-NLS-1$
252 if (eventIndex
>= fEvents
.size()) {
253 /* This ID could be valid, but there are no declarations with it */
256 return fEvents
.get(eventIndex
);
259 // ------------------------------------------------------------------------
261 // ------------------------------------------------------------------------
264 * Adds an event to the event list.
266 * An event in a stream can omit its id if it is the only event in this
267 * stream. An event for which no id has been specified has a null id. It is
268 * thus not possible to add an event with the null key if the map is not
269 * empty. It is also not possible to add an event to the map if the null key
270 * is present in the map.
274 * @throws ParseException
275 * If there was a problem reading the event or adding it to the
278 public void addEvent(IEventDeclaration event
) throws ParseException
{
280 throw new ParseException("Event without id with multiple events in a stream"); //$NON-NLS-1$
282 int id
= ((EventDeclaration
) event
).id();
285 * If there is an event without id (the null key), it must be the only
288 if (id
== IEventDeclaration
.UNSET_EVENT_ID
) {
289 if (!fEvents
.isEmpty()) {
290 throw new ParseException("Event without id with multiple events in a stream"); //$NON-NLS-1$
292 fEventUnsetId
= true;
295 /* Check if an event with the same ID already exists */
296 if (fEvents
.size() > id
&& fEvents
.get(id
) != null) {
297 throw new ParseException("Event id already exists"); //$NON-NLS-1$
299 ensureSize(fEvents
, id
);
300 /* Put the event in the list */
301 fEvents
.set(id
, event
);
306 * Add a list of event declarations to this stream. There must be no overlap
307 * between the two lists of event declarations. This will merge the two
308 * lists and preserve the indexes of both lists.
311 * list of the events to add
312 * @throws CTFException
313 * if the list already contains data
315 public void addEvents(Collection
<IEventDeclaration
> events
) throws CTFException
{
317 throw new CTFException("Cannot add to a stream with an unidentified event"); //$NON-NLS-1$
319 if (fEvents
.isEmpty()) {
320 fEvents
.addAll(events
);
323 for (IEventDeclaration event
: events
) {
325 int index
= event
.getId().intValue();
326 ensureSize(fEvents
, index
);
327 if (fEvents
.get(index
) != null) {
328 throw new CTFException("Both lists have an event defined at position " + index
); //$NON-NLS-1$
330 fEvents
.set(index
, event
);
335 private static void ensureSize(ArrayList
<?
extends Object
> list
, int index
) {
336 list
.ensureCapacity(index
);
337 while (list
.size() <= index
) {
343 * Add an input to this Stream
346 * The StreamInput to add.
348 public void addInput(CTFStreamInput input
) {
353 public String
toString() {
354 return "Stream [id=" + fId
+ ", packetContextDecl=" + fPacketContextDecl
//$NON-NLS-1$ //$NON-NLS-2$
355 + ", eventHeaderDecl=" + fEventHeaderDecl
//$NON-NLS-1$
356 + ", eventContextDecl=" + fEventContextDecl
+ ", trace=" + fTrace
//$NON-NLS-1$ //$NON-NLS-2$
357 + ", events=" + fEvents
+ ", inputs=" + fInputs
+ "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$