d04a8089cd6222e20fc4c091c7bdb37e357765bd
[deliverable/tracecompass.git] / org.eclipse.linuxtools.ctf.core / src / org / eclipse / linuxtools / ctf / core / trace / StreamInputReader.java
1 /*******************************************************************************
2 * Copyright (c) 2011-2012 Ericsson, Ecole Polytechnique de Montreal and others
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
13 package org.eclipse.linuxtools.ctf.core.trace;
14
15 import java.nio.ByteOrder;
16
17 import org.eclipse.linuxtools.ctf.core.event.EventDefinition;
18 import org.eclipse.linuxtools.ctf.core.event.types.StructDefinition;
19 import org.eclipse.linuxtools.internal.ctf.core.trace.StreamInput;
20 import org.eclipse.linuxtools.internal.ctf.core.trace.StreamInputPacketIndexEntry;
21
22 /**
23 * <b><u>StreamInputReader</u></b>
24 * <p>
25 * Reads the events of a trace file.
26 */
27 public class StreamInputReader {
28
29 // ------------------------------------------------------------------------
30 // Attributes
31 // ------------------------------------------------------------------------
32
33 /**
34 * The StreamInput we are reading.
35 */
36 private final StreamInput streamInput;
37
38 /**
39 * The packet reader used to read packets from this trace file.
40 */
41 private final StreamInputPacketReader packetReader;
42
43 /**
44 * Iterator on the packet index
45 */
46 private int packetIndex;
47
48 /**
49 * Reference to the current event of this trace file (iow, the last on that
50 * was read, the next one to be returned)
51 */
52 private EventDefinition currentEvent = null;
53
54 private int name;
55
56 private CTFTraceReader parent;
57
58 private final long prevIndex;
59
60 // ------------------------------------------------------------------------
61 // Constructors
62 // ------------------------------------------------------------------------
63
64 /**
65 * Constructs a StreamInputReader that reads a StreamInput.
66 *
67 * @param streamInput
68 * The StreamInput to read.
69 */
70 public StreamInputReader(StreamInput streamInput) {
71 this.streamInput = streamInput;
72 this.packetReader = new StreamInputPacketReader(this);
73 /*
74 * Get the iterator on the packet index.
75 */
76 this.packetIndex = 0;
77
78 this.prevIndex = 0;
79 /*
80 * Make first packet the current one.
81 */
82 goToNextPacket();
83 }
84
85 // ------------------------------------------------------------------------
86 // Getters/Setters/Predicates
87 // ------------------------------------------------------------------------
88
89 /**
90 * Gets the current event in this stream
91 *
92 * @return the current event in the stream, null if the stream is
93 * finished/empty/malformed
94 */
95 public EventDefinition getCurrentEvent() {
96 return this.currentEvent;
97 }
98
99 /**
100 * gets the current packet context
101 *
102 * @return the current packet context (size, lost events and such)
103 */
104 public StructDefinition getCurrentPacketContext() {
105 return this.packetReader.getStreamPacketContextDef();
106 }
107
108 /**
109 * Gets the byte order for a trace
110 *
111 * @return the trace byte order
112 */
113 public ByteOrder getByteOrder() {
114 return streamInput.getStream().getTrace().getByteOrder();
115 }
116
117 /**
118 * Gets the name of the stream (it's an id and a number)
119 *
120 * @return gets the stream name (it's a number)
121 */
122 public int getName() {
123 return this.name;
124 }
125
126 /**
127 * Sets the name of the stream
128 *
129 * @param name
130 * the name of the stream, (it's a number)
131 */
132 public void setName(int name) {
133 this.name = name;
134 }
135
136 /**
137 * Gets the CPU of a stream. It's the same as the one in /proc or running
138 * the asm CPUID instruction
139 *
140 * @return The CPU id (a number)
141 */
142 public int getCPU() {
143 return this.packetReader.getCPU();
144 }
145
146 /**
147 * Gets the filename of the stream being read
148 * @return The filename of the stream being read
149 */
150 public String getFilename() {
151 return streamInput.getFilename();
152 }
153
154 /*
155 * for internal use only
156 */
157 StreamInput getStreamInput() {
158 return streamInput;
159 }
160
161 // ------------------------------------------------------------------------
162 // Operations
163 // ------------------------------------------------------------------------
164 /**
165 * Reads the next event in the current event variable.
166 *
167 * @return If an event has been successfully read.
168 */
169 public boolean readNextEvent() {
170
171 /*
172 * Change packet if needed
173 */
174 if (!this.packetReader.hasMoreEvents()) {
175 final StreamInputPacketIndexEntry prevPacket = this.packetReader
176 .getCurrentPacket();
177 if (prevPacket != null) {
178 goToNextPacket();
179 final StreamInputPacketIndexEntry currentPacket = this.packetReader
180 .getCurrentPacket();
181 }
182 }
183
184 /*autogenerate javadoc getter setter
185 * If an event is available, read it.
186 */
187 if (this.packetReader.hasMoreEvents()) {
188 try {
189 this.setCurrentEvent(this.packetReader.readNextEvent());
190 } catch (CTFReaderException e) {
191 /*
192 * Some problem happened, we'll assume that there are no more
193 * events
194 */
195 return false;
196 }
197 return true;
198 }
199 this.setCurrentEvent(null);
200 return false;
201 }
202
203 /**
204 * Change the current packet of the packet reader to the next one.
205 */
206 private void goToNextPacket() {
207 packetIndex++;
208 if (getPacketSize() >= (packetIndex + 1)) {
209 this.packetReader.setCurrentPacket(getPacket());
210 } else {
211 try {
212 if (this.streamInput.addPacketHeaderIndex()) {
213 packetIndex = getPacketSize() - 1;
214 this.packetReader.setCurrentPacket(getPacket());
215
216 } else {
217 this.packetReader.setCurrentPacket(null);
218 }
219
220 } catch (CTFReaderException e) {
221 this.packetReader.setCurrentPacket(null);
222 }
223 }
224 }
225
226 /**
227 * @return
228 */
229 private int getPacketSize() {
230 return streamInput.getIndex().getEntries().size();
231 }
232
233 /**
234 * Changes the location of the trace file reader so that the current event
235 * is the first event with a timestamp greater than the given timestamp.
236 *
237 * @param timestamp
238 * The timestamp to seek to.
239 */
240 public long seek(long timestamp) {
241 long offset = 0;
242
243 gotoPacket(timestamp);
244
245 /*
246 * index up to the desired timestamp.
247 */
248 while ((this.packetReader.getCurrentPacket() != null)
249 && (this.packetReader.getCurrentPacket().getTimestampEnd() < timestamp)) {
250 try {
251 this.streamInput.addPacketHeaderIndex();
252 goToNextPacket();
253 } catch (CTFReaderException e) {
254 // do nothing here
255 }
256 }
257 if (this.packetReader.getCurrentPacket() == null) {
258 gotoPacket(timestamp);
259 }
260
261 /*
262 * Advance until A. we reached the end of the trace file (which means
263 * the given timestamp is after the last event), or B. we found the
264 * first event with a timestamp greater than the given timestamp.
265 */
266 readNextEvent();
267 boolean done = (this.getCurrentEvent() == null);
268 while (!done && (this.getCurrentEvent().getTimestamp() < timestamp)) {
269 readNextEvent();
270 done = (this.getCurrentEvent() == null);
271 offset++;
272 }
273 return offset;
274 }
275
276 /**
277 * @param timestamp
278 */
279 private void gotoPacket(long timestamp) {
280 this.packetIndex = this.streamInput.getIndex().search(timestamp)
281 .previousIndex();
282 /*
283 * Switch to this packet.
284 */
285 goToNextPacket();
286 }
287
288 /**
289 * Seeks the last event of a stream and returns it.
290 */
291 public void goToLastEvent() {
292 /*
293 * Search in the index for the packet to search in.
294 */
295 final int len = this.streamInput.getIndex().getEntries().size();
296
297 StreamInputPacketIndexEntry entry = null;
298 /*
299 * Go to beginning of trace.
300 */
301 seek(0);
302 /*
303 * if the trace is empty.
304 */
305 if ((len == 0) || (this.packetReader.hasMoreEvents() == false)) {
306 /*
307 * This means the trace is empty. abort.
308 */
309 return;
310 }
311 /*
312 * Go to the last packet that contains events.
313 */
314 for (int pos = len - 1; pos > 0; pos--) {
315 packetIndex = pos;
316 this.packetReader.setCurrentPacket(getPacket());
317 if (this.packetReader.hasMoreEvents()) {
318 break;
319 }
320 }
321
322 /*
323 * Go until the end of that packet
324 */
325 EventDefinition prevEvent = null;
326 while (this.currentEvent != null) {
327 prevEvent = this.currentEvent;
328 this.readNextEvent();
329 }
330 /*
331 * Go back to the previous event
332 */
333 this.setCurrentEvent(prevEvent);
334 }
335
336 /**
337 * @return the parent
338 */
339 public CTFTraceReader getParent() {
340 return parent;
341 }
342
343 /**
344 * @param parent
345 * the parent to set
346 */
347 public void setParent(CTFTraceReader parent) {
348 this.parent = parent;
349 }
350
351 /**
352 * Sets the current event in a stream input reader
353 * @param currentEvent the event to set
354 */
355 public void setCurrentEvent(EventDefinition currentEvent) {
356 this.currentEvent = currentEvent;
357 }
358
359 /**
360 * @return the packetIndexIt
361 */
362 private int getPacketIndex() {
363 return packetIndex;
364 }
365
366 private StreamInputPacketIndexEntry getPacket() {
367 return streamInput.getIndex().getEntries().get(getPacketIndex());
368 }
369
370 /**
371 * @return the packetReader
372 */
373 public StreamInputPacketReader getPacketReader() {
374 return packetReader;
375 }
376
377 /*
378 * (non-Javadoc)
379 *
380 * @see java.lang.Object#hashCode()
381 */
382 @Override
383 public int hashCode() {
384 final int prime = 31;
385 int result = 1;
386 result = (prime * result) + name;
387 result = (prime * result)
388 + ((streamInput == null) ? 0 : streamInput.hashCode());
389 return result;
390 }
391
392 /*
393 * (non-Javadoc)
394 *
395 * @see java.lang.Object#equals(java.lang.Object)
396 */
397 @Override
398 public boolean equals(Object obj) {
399 if (this == obj) {
400 return true;
401 }
402 if (obj == null) {
403 return false;
404 }
405 if (!(obj instanceof StreamInputReader)) {
406 return false;
407 }
408 StreamInputReader other = (StreamInputReader) obj;
409 if (name != other.name) {
410 return false;
411 }
412 if (streamInput == null) {
413 if (other.streamInput != null) {
414 return false;
415 }
416 } else if (!streamInput.equals(other.streamInput)) {
417 return false;
418 }
419 return true;
420 }
421
422 }
This page took 0.039559 seconds and 5 git commands to generate.