492734a553f1a327f8cd744cbe5c6571cb3715b9
[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 import java.util.ListIterator;
17
18 import org.eclipse.linuxtools.ctf.core.event.EventDefinition;
19 import org.eclipse.linuxtools.ctf.core.event.types.StructDefinition;
20 import org.eclipse.linuxtools.internal.ctf.core.trace.StreamInput;
21 import org.eclipse.linuxtools.internal.ctf.core.trace.StreamInputPacketIndexEntry;
22
23 /**
24 * <b><u>StreamInputReader</u></b>
25 * <p>
26 * Reads the events of a trace file.
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 ListIterator<StreamInputPacketIndexEntry> packetIndexIt;
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 // ------------------------------------------------------------------------
58 // Constructors
59 // ------------------------------------------------------------------------
60
61 /**
62 * Constructs a StreamInputReader that reads a StreamInput.
63 *
64 * @param streamInput
65 * The StreamInput to read.
66 */
67 public StreamInputReader(StreamInput streamInput) {
68 this.streamInput = streamInput;
69 this.packetReader = new StreamInputPacketReader(this);
70
71 /*
72 * Get the iterator on the packet index.
73 */
74 this.packetIndexIt = streamInput.getIndex().listIterator();
75
76 /*
77 * Make first packet the current one.
78 */
79 goToNextPacket();
80 }
81
82 // ------------------------------------------------------------------------
83 // Getters/Setters/Predicates
84 // ------------------------------------------------------------------------
85
86 public EventDefinition getCurrentEvent() {
87 return this.currentEvent;
88 }
89
90 public StructDefinition getCurrentPacketContext() {
91 return this.packetReader.getStreamPacketContextDef();
92 }
93
94 public ByteOrder getByteOrder() {
95 return streamInput.getStream().getTrace().getByteOrder();
96 }
97
98 public int getName() {
99 return this.name;
100 }
101
102 public void setName(int name) {
103 this.name = name;
104 }
105
106 public int getCPU() {
107 return this.packetReader.getCPU();
108 }
109
110 public String getFilename() {
111 return streamInput.getFilename();
112 }
113
114 /*
115 * for internal use only
116 */
117 StreamInput getStreamInput() {
118 return streamInput;
119 }
120
121 // ------------------------------------------------------------------------
122 // Operations
123 // ------------------------------------------------------------------------
124 /**
125 * Reads the next event in the current event variable.
126 *
127 * @return If an event has been successfully read.
128 */
129 public boolean readNextEvent() {
130 /*
131 * Change packet if needed
132 */
133 if (!this.packetReader.hasMoreEvents()) {
134 goToNextPacket();
135 }
136
137 /*
138 * If an event is available, read it.
139 */
140 if (this.packetReader.hasMoreEvents()) {
141 try {
142 this.setCurrentEvent(this.packetReader.readNextEvent());
143 } catch (CTFReaderException e) {
144 /* Some problem happened, we'll assume there is no more events */
145 return false;
146 }
147 return true;
148 }
149 this.setCurrentEvent(null);
150 return false;
151 }
152
153 /**
154 * Change the current packet of the packet reader to the next one.
155 */
156 private void goToNextPacket() {
157 if (getPacketIndexIt().hasNext()) {
158 StreamInputPacketIndexEntry nextPacket = getPacketIndexIt().next();
159 this.packetReader.setCurrentPacket(nextPacket);
160 } else {
161 this.packetReader.setCurrentPacket(null);
162 }
163 }
164
165 /**
166 * Changes the location of the trace file reader so that the current event
167 * is the first event with a timestamp greater than the given timestamp.
168 *
169 * @param timestamp
170 * The timestamp to seek to.
171 */
172 public long seek(long timestamp) {
173 long offset = 0;
174 /*
175 * Search in the index for the packet to search in.
176 */
177 this.packetIndexIt = this.streamInput.getIndex().search(timestamp);
178
179 /*
180 * Switch to this packet.
181 */
182 goToNextPacket();
183
184 /*
185 * Advance until A. we reached the end of the trace file (which means
186 * the given timestamp is after the last event), or B. we found the
187 * first event with a timestamp greater than the given timestamp.
188 */
189 readNextEvent();
190 boolean done = (this.getCurrentEvent() == null);
191 while (!done && (this.getCurrentEvent().getTimestamp() < timestamp)) {
192 readNextEvent();
193 done = (this.getCurrentEvent() == null);
194 offset++;
195 }
196 return offset;
197 }
198
199 public long seekIndex(long index) throws CTFReaderException {
200 /*
201 * we need to check if a trace is empty too.
202 */
203 StreamInputPacketIndexEntry sipie = null;
204 /*
205 * Search in the index for the packet to search in.
206 */
207 this.packetIndexIt = this.streamInput.getIndex().searchIndex(index);
208 /*
209 * Switch to this packet.
210 */
211 goToNextPacket();
212
213 sipie = this.packetReader.getCurrentPacket();
214 /*
215 * Read the first packet
216 */
217 readNextEvent();
218 /*
219 * get the current index
220 */
221 if (this.packetReader.getCurrentPacket() == null) {
222 if( !((sipie.getIndexBegin() == 0) && (sipie.getIndexEnd() == Long.MAX_VALUE))) {
223 throw new CTFReaderException(
224 "Current packet null in index seek, did you index your trace yet?"); //$NON-NLS-1$
225 }
226 return 0;
227 }
228 return this.packetReader.getCurrentPacket().getIndexBegin();
229
230 }
231
232 public void goToLastEvent() throws CTFReaderException {
233 /*
234 * Search in the index for the packet to search in.
235 */
236 final int len = this.streamInput.getIndex().getEntries().size();
237
238 StreamInputPacketIndexEntry entry = null;
239 /*
240 * Go to beginning of trace.
241 */
242 seek(0);
243 /*
244 * if the trace is empty.
245 */
246 if((len == 0) ||(this.packetReader.hasMoreEvents() == false)) {
247 /*
248 * This means the trace is empty. abort.
249 */
250 return;
251 }
252 /*
253 * Go to the last packet that contains events.
254 */
255 for( int pos = len -1 ; pos > 0 ; pos--){
256 entry = this.streamInput.getIndex().getEntries().get(pos);
257 this.packetReader.setCurrentPacket(entry);
258 if(this.packetReader.hasMoreEvents()) {
259 break;
260 }
261 }
262
263 /*
264 * Go until the end of that packet
265 */
266 EventDefinition prevEvent = null;
267 while (this.currentEvent != null) {
268 prevEvent = this.currentEvent;
269 this.readNextEvent();
270 }
271 /*
272 * Go back to the previous event
273 */
274 this.setCurrentEvent(prevEvent);
275 }
276
277 public void setCurrentEvent(EventDefinition currentEvent) {
278 this.currentEvent = currentEvent;
279 }
280
281 /**
282 * @return the packetIndexIt
283 */
284 private ListIterator<StreamInputPacketIndexEntry> getPacketIndexIt() {
285 return packetIndexIt;
286 }
287
288 /**
289 * @return the packetReader
290 */
291 public StreamInputPacketReader getPacketReader() {
292 return packetReader;
293 }
294
295 /* (non-Javadoc)
296 * @see java.lang.Object#hashCode()
297 */
298 @Override
299 public int hashCode() {
300 final int prime = 31;
301 int result = 1;
302 result = (prime * result) + name;
303 result = (prime * result)
304 + ((streamInput == null) ? 0 : streamInput.hashCode());
305 return result;
306 }
307
308 /* (non-Javadoc)
309 * @see java.lang.Object#equals(java.lang.Object)
310 */
311 @Override
312 public boolean equals(Object obj) {
313 if (this == obj) {
314 return true;
315 }
316 if (obj == null) {
317 return false;
318 }
319 if (!(obj instanceof StreamInputReader)) {
320 return false;
321 }
322 StreamInputReader other = (StreamInputReader) obj;
323 if (name != other.name) {
324 return false;
325 }
326 if (streamInput == null) {
327 if (other.streamInput != null) {
328 return false;
329 }
330 } else if (!streamInput.equals(other.streamInput)) {
331 return false;
332 }
333 return true;
334 }
335
336 }
This page took 0.038313 seconds and 5 git commands to generate.