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