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