blob: ca514dc76a2b57953a101792fc5631425257e109 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2017, 2018 Dortmund University of Applied Sciences and Arts and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Dortmund University of Applied Sciences and Arts - initial API and implementation
*******************************************************************************/
package org.eclipse.app4mc.multicore.execution.logic.btf;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import org.eclipse.app4mc.multicore.execution.logic.btf.model.BtfEntityType;
import org.eclipse.app4mc.multicore.execution.logic.btf.model.BtfEvent;
import org.eclipse.app4mc.multicore.execution.logic.btf.model.BtfTrace;
import org.eclipse.app4mc.multicore.execution.logic.executionmodel.misc.EMTimeType;
public class BtfTraceParser {
private final File file;
private RandomAccessFile fileInput;
private BtfTrace trace;
/** Holds the file position from last line to go one line back. */
long filePosBefore = 0;
/** Counts the number of lines in the file */
long lineCount = 0;
public BtfTraceParser(final File file) {
this.file = file;
}
public void parseTrace() throws BtfException {
this.lineCount = 0;
this.filePosBefore = 0;
this.trace = new BtfTrace();
this.trace.setName(this.file.getName());
try {
this.fileInput = new RandomAccessFile(this.file, "r");
parseHeader();
parseBody();
}
catch (final FileNotFoundException e) {
throw new BtfException(e.getMessage());
}
}
private String readLine() throws IOException {
this.lineCount++;
this.filePosBefore = this.fileInput.getFilePointer();
return this.fileInput.readLine();
}
private void lineBack() throws IOException {
if (this.lineCount > 0) {
this.fileInput.seek(this.filePosBefore);
this.lineCount--;
}
}
private void parseHeader() throws BtfException {
String line;
try {
while (true) {
line = readLine();
if (line == null) {
// end of file while header
throw new BtfException("Trace do not contain data!");
}
if (line.charAt(0) != '#') {
// end of header
lineBack(); // one line back
break;
}
if (line.startsWith("#timeScale")) {
final String[] data = line.split(" ");
if (data.length != 2) {
throw new BtfException("#timeScale not well formed!");
}
final EMTimeType tt = EMTimeType.valueOf(data[1].toUpperCase());
if (tt == null) {
throw new BtfException("#timeScale not well formed!");
}
this.trace.setTimeScale(tt);
}
else if (line.startsWith("#entityTypeTable")) {
parseEntityTypeTable();
}
}
}
catch (final IOException e) {
throw new BtfException(e.getMessage());
}
}
private void parseEntityTypeTable() throws IOException, BtfException {
String line = readLine();
while (line.startsWith("#-")) {
final String[] data = line.split(" ");
if (data.length != 2) {
throw new BtfException("Entity type line not valid: " + line + " line-number: " + this.lineCount);
}
final String type = data[0].substring(2); // cutoff #-
final BtfEntityType t = BtfEntityType.byTypeID(type.toUpperCase());
if (t == null) {
throw new BtfException(type + " (line " + this.lineCount + ") is no valid btf type!");
}
this.trace.getEntityTypeTable().put(data[1], t);
line = readLine();
}
lineBack();
}
private void parseBody() throws BtfException {
String line;
try {
while (true) {
line = readLine();
if (line == null) {
// end of file
return;
}
parseEventLine(this.lineCount, line);
}
}
catch (final IOException e) {
throw new BtfException(e.getMessage());
}
}
private void parseEventLine(final long lineNum, final String line) throws BtfException {
final String[] data = line.split(",");
if (data.length != 7 && data.length != 8) {
throw new BtfException("Miss formed line: " + line);
}
final BtfEvent e = new BtfEvent();
try {
e.setLineNum(lineNum);
e.setTime(Long.parseLong(data[0]));
e.setSource(data[1]);
e.setSourceInstance(Integer.parseInt(data[2]));
final BtfEntityType et = BtfEntityType.byTypeID(data[3].toUpperCase());
e.setTargetType(et);
e.setTarget(data[4]);
e.setTargetInstance(Integer.parseInt(data[5]));
e.setEvent(data[6]);
if (data.length == 8) {
// optional notice
e.setNote(data[7]);
}
this.trace.getEvents().add(e);
}
catch (final Exception ex) {
throw new BtfException(ex.getMessage());
}
}
public BtfTrace getTrace() {
return this.trace;
}
}