/******************************************************************************* | |
* 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; | |
} | |
} |