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
.HashSet
;
18 import java
.util
.List
;
21 import org
.eclipse
.jdt
.annotation
.NonNull
;
22 import org
.eclipse
.jdt
.annotation
.Nullable
;
23 import org
.eclipse
.tracecompass
.ctf
.core
.CTFException
;
24 import org
.eclipse
.tracecompass
.ctf
.core
.event
.IEventDeclaration
;
25 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.IDeclaration
;
26 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.IEventHeaderDeclaration
;
27 import org
.eclipse
.tracecompass
.ctf
.core
.event
.types
.StructDeclaration
;
28 import org
.eclipse
.tracecompass
.internal
.ctf
.core
.event
.EventDeclaration
;
29 import org
.eclipse
.tracecompass
.internal
.ctf
.core
.event
.metadata
.exceptions
.ParseException
;
32 * <b><u>Stream</u></b>
34 * Represents a stream in a trace.
36 public class CTFStream
{
38 // ------------------------------------------------------------------------
40 // ------------------------------------------------------------------------
43 * The numerical ID of the stream
48 * Declarations of the stream-specific structures
50 private StructDeclaration fPacketContextDecl
= null;
51 private IDeclaration fEventHeaderDecl
= null;
52 private StructDeclaration fEventContextDecl
= null;
55 * The trace to which the stream belongs
57 private CTFTrace fTrace
= null;
60 * Maps event ids to events
62 private final ArrayList
<@Nullable IEventDeclaration
> fEvents
= new ArrayList
<>();
64 private boolean fEventUnsetId
= false;
65 private boolean fStreamIdSet
= false;
68 * The inputs associated to this stream
70 private final Set
<CTFStreamInput
> fInputs
= new HashSet
<>();
72 // ------------------------------------------------------------------------
74 // ------------------------------------------------------------------------
77 * Constructs a Stream that belongs to a Trace
80 * The trace to which belongs this stream.
82 public CTFStream(CTFTrace trace
) {
86 // ------------------------------------------------------------------------
87 // Getters/Setters/Predicates
88 // ------------------------------------------------------------------------
91 * Sets the id of a stream
96 public void setId(long id
) {
102 * Gets the id of a stream
104 * @return id the id of a stream
107 public long getId() {
112 * Is the id of a stream set
114 * @return If the ID is set or not
116 public boolean isIdSet() {
122 * @return is the event header set (timestamp and stuff) (see Ctf Spec)
124 public boolean isEventHeaderSet() {
125 return fEventHeaderDecl
!= null;
130 * @return is the event context set (pid and stuff) (see Ctf Spec)
132 public boolean isEventContextSet() {
133 return fEventContextDecl
!= null;
138 * @return Is the packet context set (see Ctf Spec)
140 public boolean isPacketContextSet() {
141 return fPacketContextDecl
!= null;
145 * Sets the event header
148 * the current event header for all events in this stream
150 public void setEventHeader(StructDeclaration eventHeader
) {
151 fEventHeaderDecl
= eventHeader
;
155 * Sets the event header, this typically has the id and the timestamp
158 * the current event header for all events in this stream
160 public void setEventHeader(IEventHeaderDeclaration eventHeader
) {
161 fEventHeaderDecl
= eventHeader
;
166 * @param eventContext
167 * the context for all events in this stream
169 public void setEventContext(StructDeclaration eventContext
) {
170 fEventContextDecl
= eventContext
;
175 * @param packetContext
176 * the packet context for all packets in this stream
178 public void setPacketContext(StructDeclaration packetContext
) {
179 fPacketContextDecl
= packetContext
;
183 * Gets the event header declaration
185 * @return the event header declaration in declaration form
187 public IDeclaration
getEventHeaderDeclaration() {
188 return fEventHeaderDecl
;
193 * @return the event context declaration in structdeclaration form
195 public StructDeclaration
getEventContextDecl() {
196 return fEventContextDecl
;
201 * @return the packet context declaration in structdeclaration form
203 public StructDeclaration
getPacketContextDecl() {
204 return fPacketContextDecl
;
209 * @return the set of all stream inputs for this stream
211 public Set
<CTFStreamInput
> getStreamInputs() {
217 * @return the parent trace
219 public CTFTrace
getTrace() {
224 * Get all the event declarations in this stream.
226 * @return The event declarations for this stream
228 public @NonNull Collection
<@NonNull IEventDeclaration
> getEventDeclarations() {
229 List
<@NonNull IEventDeclaration
> retVal
= new ArrayList
<>();
230 for (IEventDeclaration eventDeclaration
: fEvents
) {
231 if (eventDeclaration
!= null) {
232 retVal
.add(eventDeclaration
);
239 * Get the event declaration for a given ID.
242 * The ID, can be {@link EventDeclaration#UNSET_EVENT_ID}, or any
244 * @return The event declaration with the given ID for this stream, or
245 * 'null' if there are no declaration with this ID
246 * @throws IllegalArgumentException
247 * If the passed ID is invalid
249 public @Nullable IEventDeclaration
getEventDeclaration(int eventId
) {
250 int eventIndex
= (eventId
== IEventDeclaration
.UNSET_EVENT_ID
) ?
0 : eventId
;
251 if (eventIndex
< 0) {
252 /* Any negative value other than UNSET_EVENT_ID is invalid */
253 throw new IllegalArgumentException("Event ID cannot be negative."); //$NON-NLS-1$
255 if (eventIndex
>= fEvents
.size()) {
256 /* This ID could be valid, but there are no declarations with it */
259 return fEvents
.get(eventIndex
);
262 // ------------------------------------------------------------------------
264 // ------------------------------------------------------------------------
267 * Adds an event to the event list.
269 * An event in a stream can omit its id if it is the only event in this
270 * stream. An event for which no id has been specified has a null id. It is
271 * thus not possible to add an event with the null key if the map is not
272 * empty. It is also not possible to add an event to the map if the null key
273 * is present in the map.
277 * @throws ParseException
278 * If there was a problem reading the event or adding it to the
281 public void addEvent(IEventDeclaration event
) throws ParseException
{
283 throw new ParseException("Event without id with multiple events in a stream"); //$NON-NLS-1$
285 int id
= ((EventDeclaration
) event
).id();
288 * If there is an event without id (the null key), it must be the only
291 if (id
== IEventDeclaration
.UNSET_EVENT_ID
) {
292 if (!fEvents
.isEmpty()) {
293 throw new ParseException("Event without id with multiple events in a stream"); //$NON-NLS-1$
295 fEventUnsetId
= true;
298 /* Check if an event with the same ID already exists */
299 if (fEvents
.size() > id
&& fEvents
.get(id
) != null) {
300 throw new ParseException("Event id already exists"); //$NON-NLS-1$
302 ensureSize(fEvents
, id
);
303 /* Put the event in the list */
304 fEvents
.set(id
, event
);
309 * Add a list of event declarations to this stream. There must be no overlap
310 * between the two lists of event declarations. This will merge the two
311 * lists and preserve the indexes of both lists.
314 * list of the events to add
315 * @throws CTFException
316 * if the list already contains data
318 public void addEvents(Collection
<IEventDeclaration
> events
) throws CTFException
{
320 throw new CTFException("Cannot add to a stream with an unidentified event"); //$NON-NLS-1$
322 if (fEvents
.isEmpty()) {
323 fEvents
.addAll(events
);
326 for (IEventDeclaration event
: events
) {
328 int index
= event
.getId().intValue();
329 ensureSize(fEvents
, index
);
330 if (fEvents
.get(index
) != null) {
331 throw new CTFException("Both lists have an event defined at position " + index
); //$NON-NLS-1$
333 fEvents
.set(index
, event
);
338 private static void ensureSize(ArrayList
<@Nullable ?
extends Object
> list
, int index
) {
339 list
.ensureCapacity(index
);
340 while (list
.size() <= index
) {
346 * Add an input to this Stream
349 * The StreamInput to add.
351 public void addInput(CTFStreamInput input
) {
356 public String
toString() {
357 return "Stream [id=" + fId
+ ", packetContextDecl=" + fPacketContextDecl
//$NON-NLS-1$ //$NON-NLS-2$
358 + ", eventHeaderDecl=" + fEventHeaderDecl
//$NON-NLS-1$
359 + ", eventContextDecl=" + fEventContextDecl
+ ", trace=" + fTrace
//$NON-NLS-1$ //$NON-NLS-2$
360 + ", events=" + fEvents
+ ", inputs=" + fInputs
+ "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$