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