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
.linuxtools
.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
;
23 import org
.eclipse
.jdt
.annotation
.NonNull
;
24 import org
.eclipse
.jdt
.annotation
.Nullable
;
25 import org
.eclipse
.linuxtools
.ctf
.core
.event
.IEventDeclaration
;
26 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.IDeclaration
;
27 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.IEventHeaderDeclaration
;
28 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.StructDeclaration
;
29 import org
.eclipse
.linuxtools
.internal
.ctf
.core
.event
.EventDeclaration
;
30 import org
.eclipse
.linuxtools
.internal
.ctf
.core
.event
.metadata
.exceptions
.ParseException
;
33 * <b><u>Stream</u></b>
35 * Represents a stream in a trace.
39 public class CTFStream
{
41 // ------------------------------------------------------------------------
43 // ------------------------------------------------------------------------
46 * The numerical ID of the stream
48 private Long fId
= null;
51 * Declarations of the stream-specific structures
53 private StructDeclaration fPacketContextDecl
= null;
54 private IDeclaration fEventHeaderDecl
= null;
55 private StructDeclaration fEventContextDecl
= null;
58 * The trace to which the stream belongs
60 private CTFTrace fTrace
= null;
63 * Maps event ids to events
65 private final ArrayList
<IEventDeclaration
> fEvents
= new ArrayList
<>();
67 private boolean fEventUnsetId
= false;
70 * The inputs associated to this stream
72 private final Set
<CTFStreamInput
> fInputs
= new HashSet
<>();
74 // ------------------------------------------------------------------------
76 // ------------------------------------------------------------------------
79 * Constructs a Stream that belongs to a Trace
82 * The trace to which belongs this stream.
84 public CTFStream(CTFTrace trace
) {
88 // ------------------------------------------------------------------------
89 // Getters/Setters/Predicates
90 // ------------------------------------------------------------------------
93 * Sets the id of a stream
98 public void setId(long id
) {
103 * Gets the id of a stream
105 * @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
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
;
185 * @return the event header declaration in structdeclaration form
186 * @deprecated use {@link CTFStream#getEventHeaderDeclaration()}
189 public StructDeclaration
getEventHeaderDecl() {
190 return (StructDeclaration
) ((fEventHeaderDecl
instanceof StructDeclaration
) ? fEventHeaderDecl
: null);
194 * Gets the event header declaration
196 * @return the event header declaration in declaration form
199 public IDeclaration
getEventHeaderDeclaration() {
200 return fEventHeaderDecl
;
205 * @return the event context declaration in structdeclaration form
207 public StructDeclaration
getEventContextDecl() {
208 return fEventContextDecl
;
213 * @return the packet context declaration in structdeclaration form
215 public StructDeclaration
getPacketContextDecl() {
216 return fPacketContextDecl
;
221 * @return the set of all stream inputs for this stream
223 public Set
<CTFStreamInput
> getStreamInputs() {
229 * @return the parent trace
231 public CTFTrace
getTrace() {
237 * @return all the event declarations for this stream, using the id as a key
239 * @deprecated use {@link CTFStream#getEventDeclarations()}
242 public Map
<Long
, IEventDeclaration
> getEvents() {
243 throw new UnsupportedOperationException();
247 * Get all the event declarations in this stream.
249 * @return The event declarations for this stream
252 public @NonNull Collection
<IEventDeclaration
> getEventDeclarations() {
253 List
<IEventDeclaration
> retVal
= new ArrayList
<>(fEvents
);
254 retVal
.removeAll(Collections
.<IEventDeclaration
> singletonList(null));
259 * Get the event declaration for a given ID.
262 * The ID, can be {@link EventDeclaration#UNSET_EVENT_ID}, or any
264 * @return The event declaration with the given ID for this stream, or
265 * 'null' if there are no declaration with this ID
266 * @throws IllegalArgumentException
267 * If the passed ID is invalid
270 public @Nullable IEventDeclaration
getEventDeclaration(int eventId
) {
271 int eventIndex
= (eventId
== EventDeclaration
.UNSET_EVENT_ID
) ?
0 : eventId
;
272 if (eventIndex
< 0) {
273 /* Any negative value other than UNSET_EVENT_ID is invalid */
274 throw new IllegalArgumentException("Event ID cannot be negative."); //$NON-NLS-1$
276 if (eventIndex
>= fEvents
.size()) {
277 /* This ID could be valid, but there are no declarations with it */
280 return fEvents
.get(eventIndex
);
283 // ------------------------------------------------------------------------
285 // ------------------------------------------------------------------------
288 * Adds an event to the event list.
290 * An event in a stream can omit its id if it is the only event in this
291 * stream. An event for which no id has been specified has a null id. It is
292 * thus not possible to add an event with the null key if the map is not
293 * empty. It is also not possible to add an event to the map if the null key
294 * is present in the map.
298 * @throws ParseException
299 * If there was a problem reading the event or adding it to the
302 public void addEvent(IEventDeclaration event
) throws ParseException
{
304 throw new ParseException("Event without id with multiple events in a stream"); //$NON-NLS-1$
306 int id
= ((EventDeclaration
) event
).id();
309 * If there is an event without id (the null key), it must be the only
312 if (id
== EventDeclaration
.UNSET_EVENT_ID
) {
313 if (!fEvents
.isEmpty()) {
314 throw new ParseException("Event without id with multiple events in a stream"); //$NON-NLS-1$
316 fEventUnsetId
= true;
319 /* Check if an event with the same ID already exists */
320 if (fEvents
.size() > id
&& fEvents
.get(id
) != null) {
321 throw new ParseException("Event id already exists"); //$NON-NLS-1$
323 ensureSize(fEvents
, id
);
324 /* Put the event in the list */
325 fEvents
.set(id
, event
);
330 * Add a list of event declarations to this stream. There must be no overlap
331 * between the two lists of event declarations. This will merge the two
332 * lists and preserve the indexes of both lists.
335 * list of the events to add
336 * @throws CTFReaderException
337 * if the list already contains data
340 public void addEvents(Collection
<IEventDeclaration
> events
) throws CTFReaderException
{
342 throw new CTFReaderException("Cannot add to a stream with an unidentified event"); //$NON-NLS-1$
344 if (fEvents
.isEmpty()) {
345 fEvents
.addAll(events
);
348 for (IEventDeclaration event
: events
) {
350 int index
= event
.getId().intValue();
351 ensureSize(fEvents
, index
);
352 if (fEvents
.get(index
) != null) {
353 throw new CTFReaderException("Both lists have an event defined at position " + index
); //$NON-NLS-1$
355 fEvents
.set(index
, event
);
360 private static void ensureSize(ArrayList
<?
extends Object
> list
, int index
) {
361 list
.ensureCapacity(index
);
362 while (list
.size() <= index
) {
368 * Add an input to this Stream
371 * The StreamInput to add.
373 public void addInput(CTFStreamInput input
) {
378 public String
toString() {
379 return "Stream [id=" + fId
+ ", packetContextDecl=" + fPacketContextDecl
//$NON-NLS-1$ //$NON-NLS-2$
380 + ", eventHeaderDecl=" + fEventHeaderDecl
//$NON-NLS-1$
381 + ", eventContextDecl=" + fEventContextDecl
+ ", trace=" + fTrace
//$NON-NLS-1$ //$NON-NLS-2$
382 + ", events=" + fEvents
+ ", inputs=" + fInputs
+ "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$