TMF: Add class to manage XML view information
[deliverable/tracecompass.git] / org.eclipse.linuxtools.ctf.core / src / org / eclipse / linuxtools / ctf / core / trace / CTFStreamInputReader.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 *******************************************************************************/
12
13package org.eclipse.linuxtools.ctf.core.trace;
14
ce2388e0 15import java.nio.ByteOrder;
866e5b51
FC
16
17import org.eclipse.linuxtools.ctf.core.event.EventDefinition;
53359017 18import org.eclipse.linuxtools.ctf.core.event.IEventDeclaration;
a4fa4e36 19import org.eclipse.linuxtools.ctf.core.event.types.StructDeclaration;
ce2388e0 20import org.eclipse.linuxtools.internal.ctf.core.trace.StreamInputPacketIndexEntry;
866e5b51 21
53359017
MK
22import com.google.common.collect.ImmutableSet;
23
866e5b51 24/**
d37aaa7f 25 * A CTF trace event reader. Reads the events of a trace file.
32ede2ec 26 *
d37aaa7f
FC
27 * @author Matthew Khouzam
28 * @author Simon Marchi
d84419e1 29 * @since 3.0
866e5b51 30 */
d84419e1 31public class CTFStreamInputReader implements AutoCloseable {
866e5b51
FC
32
33 // ------------------------------------------------------------------------
34 // Attributes
35 // ------------------------------------------------------------------------
36
37 /**
38 * The StreamInput we are reading.
39 */
d84419e1 40 private final CTFStreamInput fStreamInput;
866e5b51
FC
41
42 /**
43 * The packet reader used to read packets from this trace file.
44 */
d84419e1 45 private final CTFStreamInputPacketReader fPacketReader;
866e5b51
FC
46
47 /**
48 * Iterator on the packet index
49 */
93a45b54 50 private int fPacketIndex;
866e5b51
FC
51
52 /**
53 * Reference to the current event of this trace file (iow, the last on that
54 * was read, the next one to be returned)
55 */
93a45b54 56 private EventDefinition fCurrentEvent = null;
866e5b51 57
93a45b54 58 private int fId;
866e5b51 59
93a45b54 60 private CTFTraceReader fParent;
bfe038ff 61
6a5251eb
MK
62 /**
63 * Live trace reading
64 */
65 private boolean fLive = false;
66
866e5b51
FC
67 // ------------------------------------------------------------------------
68 // Constructors
69 // ------------------------------------------------------------------------
70
71 /**
72 * Constructs a StreamInputReader that reads a StreamInput.
73 *
74 * @param streamInput
75 * The StreamInput to read.
db8e8f7d
AM
76 * @throws CTFReaderException
77 * if an error occurs
866e5b51 78 */
d84419e1 79 public CTFStreamInputReader(CTFStreamInput streamInput) throws CTFReaderException {
93a45b54 80 fStreamInput = streamInput;
d84419e1 81 fPacketReader = new CTFStreamInputPacketReader(this);
866e5b51
FC
82 /*
83 * Get the iterator on the packet index.
84 */
93a45b54 85 fPacketIndex = 0;
866e5b51
FC
86 /*
87 * Make first packet the current one.
88 */
89 goToNextPacket();
90 }
91
5d1c6919
PT
92 /**
93 * Dispose the StreamInputReader
5d1c6919 94 */
dd9752d5
AM
95 @Override
96 public void close() {
97 fPacketReader.close();
5d1c6919
PT
98 }
99
866e5b51
FC
100 // ------------------------------------------------------------------------
101 // Getters/Setters/Predicates
102 // ------------------------------------------------------------------------
103
9ac2eb62
MK
104 /**
105 * Gets the current event in this stream
106 *
107 * @return the current event in the stream, null if the stream is
108 * finished/empty/malformed
109 */
866e5b51 110 public EventDefinition getCurrentEvent() {
93a45b54 111 return fCurrentEvent;
866e5b51
FC
112 }
113
9ac2eb62
MK
114 /**
115 * Gets the byte order for a trace
116 *
117 * @return the trace byte order
118 */
ce2388e0 119 public ByteOrder getByteOrder() {
93a45b54 120 return fStreamInput.getStream().getTrace().getByteOrder();
866e5b51
FC
121 }
122
9ac2eb62
MK
123 /**
124 * Gets the name of the stream (it's an id and a number)
125 *
126 * @return gets the stream name (it's a number)
127 */
866e5b51 128 public int getName() {
93a45b54 129 return fId;
866e5b51
FC
130 }
131
9ac2eb62
MK
132 /**
133 * Sets the name of the stream
134 *
135 * @param name
136 * the name of the stream, (it's a number)
137 */
866e5b51 138 public void setName(int name) {
93a45b54 139 fId = name;
866e5b51
FC
140 }
141
9ac2eb62
MK
142 /**
143 * Gets the CPU of a stream. It's the same as the one in /proc or running
144 * the asm CPUID instruction
145 *
146 * @return The CPU id (a number)
147 */
866e5b51 148 public int getCPU() {
93a45b54 149 return fPacketReader.getCPU();
866e5b51
FC
150 }
151
9ac2eb62
MK
152 /**
153 * Gets the filename of the stream being read
db8e8f7d 154 *
9ac2eb62
MK
155 * @return The filename of the stream being read
156 */
ce2388e0 157 public String getFilename() {
93a45b54 158 return fStreamInput.getFilename();
ce2388e0
FC
159 }
160
161 /*
162 * for internal use only
163 */
d84419e1 164 CTFStreamInput getStreamInput() {
93a45b54 165 return fStreamInput;
ce2388e0
FC
166 }
167
53359017
MK
168 /**
169 * Gets the event definition set for this StreamInput
170 *
171 * @return Unmodifiable set with the event definitions
53359017
MK
172 */
173 public Iterable<IEventDeclaration> getEventDeclarations() {
174 return ImmutableSet.copyOf(fStreamInput.getStream().getEvents().values());
175 }
176
6a5251eb
MK
177 /**
178 * Set the trace to live mode
179 *
180 * @param live
181 * whether the trace is read live or not
6a5251eb
MK
182 */
183 public void setLive(boolean live) {
184 fLive = live;
185 }
186
187 /**
188 * Get if the trace is to read live or not
189 *
190 * @return whether the trace is live or not
6a5251eb
MK
191 */
192 public boolean isLive() {
193 return fLive;
194 }
195
a4fa4e36
MK
196 /**
197 * Get the event context of the stream
198 *
199 * @return the event context declaration of the stream
a4fa4e36
MK
200 */
201 public StructDeclaration getStreamEventContextDecl() {
202 return getStreamInput().getStream().getEventContextDecl();
203 }
204
866e5b51
FC
205 // ------------------------------------------------------------------------
206 // Operations
207 // ------------------------------------------------------------------------
208 /**
209 * Reads the next event in the current event variable.
210 *
211 * @return If an event has been successfully read.
db8e8f7d
AM
212 * @throws CTFReaderException
213 * if an error occurs
866e5b51 214 */
6a5251eb 215 public CTFResponse readNextEvent() throws CTFReaderException {
bfe038ff 216
866e5b51
FC
217 /*
218 * Change packet if needed
219 */
93a45b54
MK
220 if (!fPacketReader.hasMoreEvents()) {
221 final StreamInputPacketIndexEntry prevPacket = fPacketReader
bfe038ff 222 .getCurrentPacket();
a4fa4e36 223 if (prevPacket != null || fLive) {
bfe038ff 224 goToNextPacket();
bfe038ff 225 }
6a5251eb 226
866e5b51
FC
227 }
228
32ede2ec 229 /*
866e5b51
FC
230 * If an event is available, read it.
231 */
93a45b54 232 if (fPacketReader.hasMoreEvents()) {
6a5251eb
MK
233 setCurrentEvent(fPacketReader.readNextEvent());
234 return CTFResponse.OK;
866e5b51
FC
235 }
236 this.setCurrentEvent(null);
6a5251eb 237 return fLive ? CTFResponse.WAIT : CTFResponse.FINISH;
866e5b51
FC
238 }
239
240 /**
241 * Change the current packet of the packet reader to the next one.
db8e8f7d
AM
242 *
243 * @throws CTFReaderException
244 * if an error occurs
866e5b51 245 */
db8e8f7d 246 private void goToNextPacket() throws CTFReaderException {
93a45b54 247 fPacketIndex++;
6a5251eb 248 // did we already index the packet?
93a45b54
MK
249 if (getPacketSize() >= (fPacketIndex + 1)) {
250 fPacketReader.setCurrentPacket(getPacket());
866e5b51 251 } else {
6a5251eb 252 // go to the next packet if there is one, index it at the same time
93a45b54
MK
253 if (fStreamInput.addPacketHeaderIndex()) {
254 fPacketIndex = getPacketSize() - 1;
255 fPacketReader.setCurrentPacket(getPacket());
cf9a28da 256 } else {
6a5251eb 257 // out of packets
93a45b54 258 fPacketReader.setCurrentPacket(null);
bfe038ff 259 }
866e5b51
FC
260 }
261 }
262
bfe038ff
MK
263 /**
264 * @return
265 */
266 private int getPacketSize() {
93a45b54 267 return fStreamInput.getIndex().getEntries().size();
bfe038ff
MK
268 }
269
866e5b51
FC
270 /**
271 * Changes the location of the trace file reader so that the current event
ecb12461 272 * is the first event with a timestamp greater or equal the given timestamp.
866e5b51
FC
273 *
274 * @param timestamp
275 * The timestamp to seek to.
be6df2d8 276 * @return The offset compared to the current position
db8e8f7d
AM
277 * @throws CTFReaderException
278 * if an error occurs
866e5b51 279 */
db8e8f7d 280 public long seek(long timestamp) throws CTFReaderException {
ce2388e0 281 long offset = 0;
866e5b51 282
eb94f9c9 283 gotoPacket(timestamp);
866e5b51 284
0c59c1a6
MK
285 /*
286 * index up to the desired timestamp.
287 */
93a45b54
MK
288 while ((fPacketReader.getCurrentPacket() != null)
289 && (fPacketReader.getCurrentPacket().getTimestampEnd() < timestamp)) {
0c59c1a6 290 try {
93a45b54 291 fStreamInput.addPacketHeaderIndex();
0c59c1a6
MK
292 goToNextPacket();
293 } catch (CTFReaderException e) {
294 // do nothing here
295 }
296 }
93a45b54 297 if (fPacketReader.getCurrentPacket() == null) {
eb94f9c9
MK
298 gotoPacket(timestamp);
299 }
0c59c1a6 300
866e5b51 301 /*
6a5251eb
MK
302 * Advance until either of these conditions are met:
303 *
304 * - reached the end of the trace file (the given timestamp is after the
305 * last event)
306 *
307 * - found the first event with a timestamp greater or equal the given
308 * timestamp.
866e5b51
FC
309 */
310 readNextEvent();
311 boolean done = (this.getCurrentEvent() == null);
aa572e22 312 while (!done && (this.getCurrentEvent().getTimestamp() < timestamp)) {
866e5b51
FC
313 readNextEvent();
314 done = (this.getCurrentEvent() == null);
ce2388e0 315 offset++;
866e5b51 316 }
ce2388e0
FC
317 return offset;
318 }
319
eb94f9c9
MK
320 /**
321 * @param timestamp
6a5251eb 322 * the time to seek
db8e8f7d
AM
323 * @throws CTFReaderException
324 * if an error occurs
eb94f9c9 325 */
db8e8f7d 326 private void gotoPacket(long timestamp) throws CTFReaderException {
93a45b54 327 fPacketIndex = fStreamInput.getIndex().search(timestamp)
eb94f9c9
MK
328 .previousIndex();
329 /*
330 * Switch to this packet.
331 */
332 goToNextPacket();
333 }
334
9ac2eb62
MK
335 /**
336 * Seeks the last event of a stream and returns it.
db8e8f7d
AM
337 *
338 * @throws CTFReaderException
339 * if an error occurs
9ac2eb62 340 */
db8e8f7d 341 public void goToLastEvent() throws CTFReaderException {
866e5b51
FC
342 /*
343 * Search in the index for the packet to search in.
344 */
93a45b54 345 final int len = fStreamInput.getIndex().getEntries().size();
ec6f5beb 346
866e5b51 347 /*
ec6f5beb 348 * Go to beginning of trace.
866e5b51 349 */
ec6f5beb
MK
350 seek(0);
351 /*
352 * if the trace is empty.
353 */
93a45b54 354 if ((len == 0) || (fPacketReader.hasMoreEvents() == false)) {
ec6f5beb
MK
355 /*
356 * This means the trace is empty. abort.
357 */
358 return;
ce2388e0 359 }
ec6f5beb
MK
360 /*
361 * Go to the last packet that contains events.
362 */
bfe038ff 363 for (int pos = len - 1; pos > 0; pos--) {
93a45b54
MK
364 fPacketIndex = pos;
365 fPacketReader.setCurrentPacket(getPacket());
366 if (fPacketReader.hasMoreEvents()) {
ec6f5beb
MK
367 break;
368 }
866e5b51 369 }
ec6f5beb
MK
370
371 /*
372 * Go until the end of that packet
373 */
374 EventDefinition prevEvent = null;
93a45b54
MK
375 while (fCurrentEvent != null) {
376 prevEvent = fCurrentEvent;
ec6f5beb
MK
377 this.readNextEvent();
378 }
379 /*
380 * Go back to the previous event
381 */
382 this.setCurrentEvent(prevEvent);
866e5b51
FC
383 }
384
bfe038ff
MK
385 /**
386 * @return the parent
387 */
388 public CTFTraceReader getParent() {
93a45b54 389 return fParent;
bfe038ff
MK
390 }
391
392 /**
393 * @param parent
394 * the parent to set
395 */
396 public void setParent(CTFTraceReader parent) {
93a45b54 397 fParent = parent;
bfe038ff
MK
398 }
399
9ac2eb62
MK
400 /**
401 * Sets the current event in a stream input reader
db8e8f7d
AM
402 *
403 * @param currentEvent
404 * the event to set
9ac2eb62 405 */
866e5b51 406 public void setCurrentEvent(EventDefinition currentEvent) {
93a45b54 407 fCurrentEvent = currentEvent;
866e5b51
FC
408 }
409
ce2388e0
FC
410 /**
411 * @return the packetIndexIt
412 */
bfe038ff 413 private int getPacketIndex() {
93a45b54 414 return fPacketIndex;
bfe038ff
MK
415 }
416
417 private StreamInputPacketIndexEntry getPacket() {
93a45b54 418 return fStreamInput.getIndex().getEntries().get(getPacketIndex());
ce2388e0
FC
419 }
420
421 /**
422 * @return the packetReader
423 */
d84419e1 424 public CTFStreamInputPacketReader getPacketReader() {
93a45b54 425 return fPacketReader;
ce2388e0
FC
426 }
427
81c8e6f7
MK
428 @Override
429 public int hashCode() {
430 final int prime = 31;
431 int result = 1;
93a45b54 432 result = (prime * result) + fId;
81c8e6f7 433 result = (prime * result)
93a45b54 434 + ((fStreamInput == null) ? 0 : fStreamInput.hashCode());
81c8e6f7
MK
435 return result;
436 }
437
81c8e6f7
MK
438 @Override
439 public boolean equals(Object obj) {
440 if (this == obj) {
441 return true;
442 }
443 if (obj == null) {
444 return false;
445 }
d84419e1 446 if (!(obj instanceof CTFStreamInputReader)) {
81c8e6f7
MK
447 return false;
448 }
d84419e1 449 CTFStreamInputReader other = (CTFStreamInputReader) obj;
93a45b54 450 if (fId != other.fId) {
81c8e6f7
MK
451 return false;
452 }
93a45b54
MK
453 if (fStreamInput == null) {
454 if (other.fStreamInput != null) {
81c8e6f7
MK
455 return false;
456 }
93a45b54 457 } else if (!fStreamInput.equals(other.fStreamInput)) {
81c8e6f7
MK
458 return false;
459 }
460 return true;
461 }
462
87b60a47
MK
463 @Override
464 public String toString() {
465 // this helps debugging
93a45b54 466 return fId + ' ' + fCurrentEvent.toString();
87b60a47 467 }
866e5b51 468}
This page took 0.069798 seconds and 5 git commands to generate.