[Bug309042] Improved test code coverage and other mundane issues.
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng / src / org / eclipse / linuxtools / lttng / trace / LTTngTextTrace.java
CommitLineData
5d10d135
ASL
1/*******************************************************************************
2 * Copyright (c) 2009 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made 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:
10 * William Bourque (wbourque@gmail.com) - Initial API and implementation
11 *******************************************************************************/
12
13package org.eclipse.linuxtools.lttng.trace;
14
15import java.io.BufferedReader;
16import java.io.FileReader;
17import java.io.IOException;
18import java.util.HashMap;
19
20import org.eclipse.linuxtools.lttng.event.LttngEvent;
21import org.eclipse.linuxtools.lttng.event.LttngEventContent;
22import org.eclipse.linuxtools.lttng.event.LttngEventField;
23import org.eclipse.linuxtools.lttng.event.LttngEventReference;
24import org.eclipse.linuxtools.lttng.event.LttngEventSource;
25import org.eclipse.linuxtools.lttng.event.LttngEventType;
26import org.eclipse.linuxtools.lttng.event.LttngTimestamp;
27import org.eclipse.linuxtools.lttng.jni.JniEvent;
cbd4ad82 28import org.eclipse.linuxtools.tmf.event.TmfNoSuchFieldException;
5d10d135 29import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
e31e01e8 30import org.eclipse.linuxtools.tmf.request.TmfDataRequest;
9f584e4c
FC
31import org.eclipse.linuxtools.tmf.trace.ITmfContext;
32import org.eclipse.linuxtools.tmf.trace.ITmfLocation;
5d10d135 33import org.eclipse.linuxtools.tmf.trace.ITmfTrace;
9f584e4c
FC
34import org.eclipse.linuxtools.tmf.trace.TmfCheckpoint;
35import org.eclipse.linuxtools.tmf.trace.TmfContext;
36import org.eclipse.linuxtools.tmf.trace.TmfLocation;
5d10d135
ASL
37import org.eclipse.linuxtools.tmf.trace.TmfTrace;
38
e31e01e8 39public class LTTngTextTrace extends TmfTrace<LttngEvent> implements ITmfTrace {
5d10d135
ASL
40 private LttngTimestamp eventTimestamp = null;
41 private LttngEventSource eventSource = null;
42 private LttngEventType eventType = null;
43 private TextLttngEventContent eventContent = null;
44 private LttngEventReference eventReference = null;
45 // The actual event
46 private TextLttngEvent currentLttngEvent = null;
47
48 private HashMap<String, LttngEventType> traceTypes = null;
49
50 private String tracepath = "";
51 private FileReader fr = null;
52 private BufferedReader br = null;
53 private Long nbCharRead = 0L;
54
55 private int cpuNumber = -1;
56
a55a769e 57 private boolean showDebug = false;
5d10d135
ASL
58
59 public LTTngTextTrace(String path) throws Exception {
60 this(path, false);
61 }
62
63 public LTTngTextTrace(String path, boolean skipIndexing) throws Exception {
e31e01e8 64 super(LttngEvent.class, path, 1);
5d10d135
ASL
65
66 tracepath = path;
67 traceTypes = new HashMap<String, LttngEventType>();
68
69 eventTimestamp = new LttngTimestamp();
70 eventSource = new LttngEventSource();
71 eventType = new LttngEventType();
72 eventContent = new TextLttngEventContent(currentLttngEvent);
73 eventReference = new LttngEventReference(this.getName());
74
b7f0ec69 75 currentLttngEvent = new TextLttngEvent(this, eventTimestamp, eventSource, eventType, eventContent, eventReference);
5d10d135
ASL
76 eventContent.setEvent(currentLttngEvent);
77
78 if ( positionToFirstEvent() == false ) {
79 throw new IOException("Fail to position to the beginning of the trace");
80 }
81 else {
9f584e4c 82 fIndexPageSize = 1000;
5d10d135
ASL
83
84 // Skip indexing if asked
88144d4a 85 if ( skipIndexing == true ) {
9f584e4c 86 fCheckpoints.add(new TmfCheckpoint(new LttngTimestamp(0L), new TmfLocation<Long>(0L)));
88144d4a
ASL
87 }
88 else {
e31e01e8 89 indexTrace(true);
88144d4a 90 }
5d10d135
ASL
91
92 Long endTime = currentLttngEvent.getTimestamp().getValue();
93 positionToFirstEvent();
94
9f584e4c 95 getNextEvent(new TmfContext(null, 0));
5d10d135
ASL
96 Long starTime = currentLttngEvent.getTimestamp().getValue();
97 positionToFirstEvent();
98
99 setTimeRange( new TmfTimeRange( new LttngTimestamp(starTime),
100 new LttngTimestamp(endTime)
101 ) );
102 }
103 }
104
105
88144d4a 106 private LTTngTextTrace(LTTngTrace oldStream) throws Exception {
e31e01e8 107 super(LttngEvent.class, null);
88144d4a 108 throw new Exception("Copy constructor should never be use with a LTTngTrace!");
5d10d135
ASL
109 }
110
5d10d135
ASL
111 private boolean positionToFirstEvent() {
112
113 boolean isSuccessful = true;
114
115 try {
116 if ( br != null ) {
117 br.close();
118 fr.close();
119 }
120
121 fr = new FileReader(tracepath);
122 br = new BufferedReader(fr);
123
124 // Skip the 2 lines header
125 br.readLine();
126 br.readLine();
127
128 // Make sure the event time is consistent
129 eventTimestamp.setValue(0L);
130 }
131 catch (Exception e) {
132 isSuccessful = false;
133 }
134
135 return isSuccessful;
136 }
137
9f584e4c 138 private void skipToPosition(TmfLocation<Long> skip) {
5d10d135 139 try {
452ad365 140 long skipPosition = skip.getLocation();
e31e01e8
FC
141 if ( skipPosition < 0 ) {
142 skipPosition = 0L;
143 }
144
5d10d135
ASL
145 if ( showDebug == true ) {
146 System.out.println("skipToPosition(Long skipPosition)");
147 System.out.println("\tSkipping to : " + skipPosition);
148 System.out.println();
149 }
150 positionToFirstEvent();
88144d4a 151 br.skip(skipPosition);
5d10d135
ASL
152
153 nbCharRead = skipPosition;
154 }
155 catch (Exception e) {
156 e.printStackTrace();
157 }
158 }
159
452ad365
FC
160 @Override
161 @SuppressWarnings("unchecked")
162 public TmfContext seekLocation(ITmfLocation<?> location) {
5d10d135 163 if (location == null) {
9f584e4c 164 location = new TmfLocation<Long>(0L);
5d10d135 165 }
88144d4a 166
452ad365 167 if (!((TmfLocation<Long>) location).getLocation().equals(nbCharRead)) {
9f584e4c 168 skipToPosition((TmfLocation<Long>) location);
88144d4a 169 }
e31e01e8 170
9f584e4c 171 TmfContext tmpTraceContext = new TmfContext(location, 0L);
88144d4a 172
e31e01e8 173 return tmpTraceContext;
88144d4a
ASL
174 }
175
9f584e4c 176 private LttngEvent parseMyNextEvent(TmfContext context) {
5d10d135
ASL
177
178 // All parsing variables declared here so to be able to print them into the catch if needed
179 String tmpContent = null;
180 int tmpCurIndex = 0;
181 int tmpPrevIndex = 0;
182
183 String tracefile = "";
184 long tmpCpu = 0;
185 String marker = "";
186
187 long tmpSecond = 0;
188 long tmpNanosecond = 0;
189
190 String parsedPayload = "";
191 String markerName = "";
192 Object payload = "";
193
194 HashMap<String, LttngEventField> fieldsMap = null;
195
196 LttngEvent returnedEvent = null;
197
198 try {
199 tmpContent = br.readLine();
200
201 if (tmpContent != null) {
202 // *** NOTE :
203 // -1 is the skip the end of line (\n)
204 nbCharRead += (tmpContent.length()+1);
205
206 if ( (currentLttngEvent != null) && (currentLttngEvent.getContent().getRawContent() != null) ) {
207 currentLttngEvent.getContent().emptyContent();
208 }
209
210 // EventSource is always the same for now :
211 eventSource.setSourceId("Kernel Core");
212
213
214 // Tracefile and marker are first in the file
215 // Sound like :
216 // kernel.syscall_entry:
217 tmpCurIndex = tmpContent.indexOf(".", tmpPrevIndex);
218
219 // *** HACK ***
220 // Evil exit case here : the two last line of the text dump does not contain "."
e31e01e8 221 // We should check in a better way (string comparison and such) but it make the whole process to weight a lot more
5d10d135
ASL
222 // Conclusion : this is ugly but fast.
223 if ( tmpCurIndex < 0 ) {
224 if ( showDebug == true ) {
225 System.out.println("END OF FILE.");
226 System.out.println();
227 }
e31e01e8 228 return null;
5d10d135
ASL
229 }
230
231 tracefile = tmpContent.substring(tmpPrevIndex, tmpCurIndex ).trim();
232 /*System.out.println(tracefile);*/
233
234 tmpPrevIndex = tmpCurIndex;
235 tmpCurIndex = tmpContent.indexOf(":", tmpPrevIndex);
236 marker = tmpContent.substring(tmpPrevIndex+1, tmpCurIndex ).trim();
237 /*System.out.println(marker);*/
238
239 // Timestamp is next but is presented in second.milisecond format, we have to split them
240 // Sound like :
241 // 952.162637168
242 tmpPrevIndex = tmpCurIndex+1;
243 tmpCurIndex = tmpContent.indexOf(".", tmpPrevIndex);
244 tmpSecond = Long.parseLong( tmpContent.substring(tmpPrevIndex, tmpCurIndex ).trim() );
245 /*System.out.println(tmpSecond);*/
246
247 tmpPrevIndex = tmpCurIndex+1;
248 tmpCurIndex = tmpContent.indexOf(" ", tmpPrevIndex);
249 tmpNanosecond = Long.parseLong( tmpContent.substring(tmpPrevIndex, tmpCurIndex ).trim() );
250 /*System.out.println(tmpNanosecond);*/
251
252 // We have enough information here to set the timestamp
253 eventTimestamp.setValue( (tmpSecond * 1000000000) + tmpNanosecond );
254 /*System.out.println(eventTimestamp.toString());*/
255
256 // Next field is the reference
257 // A long string enclosed by parenthesis and ending with a comma
258 // (/home/william/workspace/org.eclipse.linuxtools.lttng.tests/traceset/trace-618339events-1293lost-1cpu/kernel_0),
259 tmpPrevIndex = tmpCurIndex+1;
260 tmpCurIndex = tmpContent.indexOf("(", tmpPrevIndex);
261 tmpPrevIndex = tmpCurIndex+1;
262 tmpCurIndex = tmpContent.indexOf("),", tmpPrevIndex);
263 String fullTracePath = tmpContent.substring(tmpPrevIndex, tmpCurIndex ).trim();
264 /*System.out.println(fullTracePath);*/
265
266 eventReference.setValue(fullTracePath);
267 String traceName = fullTracePath.substring(fullTracePath.lastIndexOf("/")+1).trim();
268 /*System.out.println(traceName);*/
269 eventReference.setTracepath(traceName);
270
271
272 // The next few fields are relatives to the state system (pid, ppid, etc...) we need to skip them.
273 // They should be like the following :
274 // 4175, 4175, hal-acl-tool, , 4168,
275
276 // 1st comma
277 tmpPrevIndex = tmpCurIndex+1;
278 tmpCurIndex = tmpContent.indexOf(",", tmpPrevIndex);
279 // 2nd comma
280 tmpPrevIndex = tmpCurIndex+1;
281 tmpCurIndex = tmpContent.indexOf(",", tmpPrevIndex);
282 // 3rd comma
283 tmpPrevIndex = tmpCurIndex+1;
284 tmpCurIndex = tmpContent.indexOf(",", tmpPrevIndex);
285 // 4th comma
286 tmpPrevIndex = tmpCurIndex+1;
287 tmpCurIndex = tmpContent.indexOf(",", tmpPrevIndex);
288 // 5th comma
289 tmpPrevIndex = tmpCurIndex+1;
290 tmpCurIndex = tmpContent.indexOf(",", tmpPrevIndex);
291 // 6th comma
292 tmpPrevIndex = tmpCurIndex+1;
293 tmpCurIndex = tmpContent.indexOf(",", tmpPrevIndex);
294
295 // The next field is the CPU, in hexadecimal format
296 // Should be like :
297 // 0x0,
298 tmpPrevIndex = tmpCurIndex+1;
299 tmpCurIndex = tmpContent.indexOf("0x", tmpPrevIndex);
300 tmpPrevIndex = tmpCurIndex+2;
301
302 tmpCurIndex = tmpContent.indexOf(",", tmpPrevIndex);
303 tmpCpu = Long.parseLong( tmpContent.substring(tmpPrevIndex, tmpCurIndex ).trim() );
304
305 // Set the cpu number of trace if we found a "new" cpu
306 if ( cpuNumber < (tmpCpu + 1) ) {
307 cpuNumber = (int)(tmpCpu+1);
308 }
309 /*System.out.println(tmpCpu);*/
310
311
312 // The last field is the parsed content
313 // It is enclosed by { }
314 // Look like :
315 // SYSCALL { ip = 0xb7f05422, syscall_id = 221 [sys_fcntl64+0x0/0x79] }
316 //
2d32a807
WB
317 // NOTE : it seems some state system events do not respect this format as they have no payload.
318 // We will create empty payload then.
5d10d135
ASL
319 int tmpIndex = tmpContent.indexOf("{", tmpPrevIndex);
320 if ( tmpIndex != -1 ) {
321 tmpPrevIndex = tmpCurIndex+1;
322 tmpCurIndex = tmpIndex;
323 tmpPrevIndex = tmpCurIndex+1;
324 tmpCurIndex = tmpContent.indexOf("}", tmpPrevIndex);
325 parsedPayload = tmpContent.substring(tmpPrevIndex, tmpCurIndex ).trim();
326
327 // Now add each LttngField
328 boolean isDone = false;
329 int tmpIndexBegin = 0;
330 int tmpIndexEqual = 0;
331 int tmpIndexEnd = 0;
332
333 fieldsMap = new HashMap<String, LttngEventField>();
334
335 while ( isDone == false ) {
336 tmpIndexEqual = parsedPayload.indexOf("=", (int)tmpIndexBegin);
337 tmpIndexEnd = parsedPayload.indexOf(", ", (int)tmpIndexEqual);
338 if ( tmpIndexEnd == -1 ) {
339 tmpIndexEnd = parsedPayload.length();
340 isDone = true;
341 }
342
343 markerName = parsedPayload.substring((int)tmpIndexBegin, (int)tmpIndexEqual-1 ).trim();
344 payload = ((String)parsedPayload.substring((int)tmpIndexEqual+1, (int)tmpIndexEnd )).replace("\"", " ").trim();
345
346 // Try to cast the payload into the correct type
347 try {
348 payload = Long.parseLong((String)payload);
349 }
350 catch (NumberFormatException e) { }
351
352 LttngEventField tmpField = new LttngEventField(eventContent, markerName, payload);
353 fieldsMap.put(markerName, tmpField);
354
355 tmpIndexBegin = tmpIndexEnd+1;
356 }
2d32a807
WB
357 }
358 else {
359 fieldsMap = new HashMap<String, LttngEventField>();
a3fe52fc 360
2d32a807
WB
361 markerName = "";
362 payload = "";
363
364 LttngEventField tmpField = new LttngEventField(eventContent, markerName, payload);
365 fieldsMap.put(markerName, tmpField);
5d10d135
ASL
366 }
367
2d32a807
WB
368 eventContent = new TextLttngEventContent(currentLttngEvent, fieldsMap);
369
370 // We now have what we need for the type
371 String tmpTypeKey = tracefile + "/" + tmpCpu + "/" + marker;
372 if ( traceTypes.get(tmpTypeKey) == null ) {
373 traceTypes.put(tmpTypeKey, new LttngEventType(tracefile, tmpCpu, marker, fieldsMap.keySet().toArray(new String[fieldsMap.size()] )) );
374 }
375
376 currentLttngEvent.setContent(eventContent);
377 currentLttngEvent.setType(traceTypes.get(tmpTypeKey));
378
5d10d135
ASL
379 returnedEvent = currentLttngEvent;
380 }
381 else if ( showDebug == true ) {
382 System.out.println("NULL READING");
383 System.out.println();
2d32a807 384 returnedEvent = null;
5d10d135
ASL
385 }
386 }
387 catch (Exception e) {
2d32a807 388 System.out.println("Pos is :" + nbCharRead);
5d10d135
ASL
389 if ( tmpContent != null ) {
390 System.out.println("Erroneous content is :" + tmpContent);
391 }
392
393 tmpContent = null;
394 e.printStackTrace();
2d32a807 395 returnedEvent = null;
5d10d135
ASL
396 }
397
398 return returnedEvent;
399 }
400
401 @Override
452ad365 402 public ITmfLocation<?> getCurrentLocation() {
9f584e4c 403 return new TmfLocation<Long>(nbCharRead);
5d10d135
ASL
404 }
405
e31e01e8 406 @Override
9f584e4c
FC
407 public LttngEvent parseEvent(TmfContext context) {
408 context = seekLocation(context.getLocation());
e31e01e8 409 return parseMyNextEvent(context);
88144d4a 410
5d10d135
ASL
411 }
412
e31e01e8 413 public int getCpuNumber() {
5d10d135
ASL
414 return cpuNumber;
415 }
e31e01e8
FC
416
417 @Override
fc6ccf6f 418 public ITmfContext armRequest(TmfDataRequest<LttngEvent> request) {
e31e01e8
FC
419 // TODO Auto-generated method stub
420 return null;
421 }
422
5d10d135
ASL
423}
424
425
426// Redefine event to override method we know won't work with a Text tracefile
427class TextLttngEvent extends LttngEvent {
428
b7f0ec69
WB
429 public TextLttngEvent( TmfTrace<LttngEvent> parent,
430 LttngTimestamp timestamp,
5d10d135
ASL
431 LttngEventSource source,
432 LttngEventType type,
433 LttngEventContent content,
434 LttngEventReference reference)
435 {
b7f0ec69 436 super(parent, timestamp, source, type, content, reference, null);
5d10d135
ASL
437 }
438
439 public TextLttngEvent(TextLttngEvent oldEvent) {
440 this(
b7f0ec69 441 oldEvent.getParentTrace(),
5d10d135
ASL
442 (LttngTimestamp)oldEvent.getTimestamp(),
443 (LttngEventSource)oldEvent.getSource(),
444 (LttngEventType)oldEvent.getType(),
445 (LttngEventContent)oldEvent.getContent(),
446 (LttngEventReference)oldEvent.getReference()
447 );
448 }
449
450 @Override
451 public JniEvent convertEventTmfToJni() {
452 System.out.println("WARNING : Cannot use convertEventTmfToJni() on a trace in text format.");
453 return null;
454 }
455
456 @Override
457 public void updateJniEventReference(JniEvent newJniEventReference) {
458 System.out.println("WARNING : Cannot use updateJniEventReference on a trace in text format. Using null.");
459 }
460}
461
462
463class TextLttngEventContent extends LttngEventContent {
464
465 public TextLttngEventContent() {
466 super();
467 }
468
469 public TextLttngEventContent(TextLttngEvent thisParent) {
470 super(thisParent, null);
471 }
472
473 public TextLttngEventContent(TextLttngEvent thisParent, HashMap<String, LttngEventField> thisContent) {
474 super(thisParent, thisContent);
475 }
476
477 public TextLttngEventContent(TextLttngEventContent oldContent) {
478 this( (TextLttngEvent)oldContent.fParentEvent, oldContent.getRawContent());
479 }
480
481 @Override
482 public LttngEventField[] getFields() {
483 return getRawContent().values().toArray(new LttngEventField[getRawContent().size()]);
484 }
485
486 @Override
487 public LttngEventField getField(String name) {
488 LttngEventField returnedField = getRawContent().get(name);
489
490 return returnedField;
491 }
492
493 @Override
494 public LttngEventField getField(int position) {
495 LttngEventField returnedField = null;
cbd4ad82
FC
496 String label = null;
497 try {
498 label = fParentEvent.getType().getLabel(position);
499 } catch (TmfNoSuchFieldException e) {
500 }
88144d4a
ASL
501
502 if ( label != null ) {
503 returnedField = this.getField(label);
504 }
5d10d135
ASL
505
506 return returnedField;
507 }
e31e01e8 508}
This page took 0.049928 seconds and 5 git commands to generate.