Improve test cases. Coverage of 85%+ and fix bugs.
[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().timestamp < 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 int len = this.streamInput.getIndex().getEntries().size();
237 int back = 0;
238 long desired_timestamp = -1;
239 do {
240 back++;
241 StreamInputPacketIndexEntry entry = this.streamInput.getIndex()
242 .getEntries().get(len - back);
243 desired_timestamp = entry.getTimestampBegin() + 1;
244 seek(desired_timestamp);
245
246 } while (!this.packetReader.hasMoreEvents());
247 /*
248 * Go until the end of that packet
249 */
250
251 int packet_size = 0;
252 while (this.packetReader.hasMoreEvents()) {
253 this.packetReader.readNextEvent();
254 packet_size++;
255 }
256 seek(desired_timestamp);
257 for (int i = 0; i < (packet_size - 1); i++) {
258 this.packetReader.readNextEvent();
259 }
260 }
261
262 public void setCurrentEvent(EventDefinition currentEvent) {
263 this.currentEvent = currentEvent;
264 }
265
266 /**
267 * @return the packetIndexIt
268 */
269 private ListIterator<StreamInputPacketIndexEntry> getPacketIndexIt() {
270 return packetIndexIt;
271 }
272
273 /**
274 * @return the packetReader
275 */
276 public StreamInputPacketReader getPacketReader() {
277 return packetReader;
278 }
279
280 /* (non-Javadoc)
281 * @see java.lang.Object#hashCode()
282 */
283 @Override
284 public int hashCode() {
285 final int prime = 31;
286 int result = 1;
287 result = (prime * result) + name;
288 result = (prime * result)
289 + ((streamInput == null) ? 0 : streamInput.hashCode());
290 return result;
291 }
292
293 /* (non-Javadoc)
294 * @see java.lang.Object#equals(java.lang.Object)
295 */
296 @Override
297 public boolean equals(Object obj) {
298 if (this == obj) {
299 return true;
300 }
301 if (obj == null) {
302 return false;
303 }
304 if (!(obj instanceof StreamInputReader)) {
305 return false;
306 }
307 StreamInputReader other = (StreamInputReader) obj;
308 if (name != other.name) {
309 return false;
310 }
311 if (streamInput == null) {
312 if (other.streamInput != null) {
313 return false;
314 }
315 } else if (!streamInput.equals(other.streamInput)) {
316 return false;
317 }
318 return true;
319 }
320
321 }
This page took 0.039369 seconds and 6 git commands to generate.