R005 Scripted Reader
Outline
If you are reading signal and trace data from a TCP, file, serial or other port input and with a format unknown to the impulse tool, you can get on the right track with a scripted reader. Using a scripted reader is an easy way to read data from any format.
Platforms |
|
|||
Requirements |
|
|||
Known limitations |
|
|||
Status |
|
|||
Operations |
|
|||
Default Parameters: |
|
|||
Configuration: |
|
Video
About scripted reader
A scripted reader calls a user script to perform the actual parsing and generation of the signals.
To enable the use of a scripted read for workspace resources, a user need to add a content type association and script code to verify the validity of the content.
10 Signal Script Script Examples
The impulse JDK
No matter if you develop a reader, a recJs script, a search expression or a Signal Script production, impulse provides you always with the same interfaces to read, compare, analyze or generate signal data.
impulse JDK Open JavaDoc Reference
Usage
A Scripted Reader can be used to open workspace resources and together with ports (direct connection to the target using TCP, Serial, J-Link, ...).
To use a scripted reader as workspace resource, a user need to add a content type association and script code to verify the validity of the content.
Configuration
To create a Scripted Reader, open the preferences and go to "impulse->Serializer-> Scripted Reader", open the configuration dialog and add a new Scripted Reader configuration.
The reader script
Below you find the readers interface to impulse:
- generator
- Record generator object of type ISingleDomainRecordGenerator and IScriptedReader. Its interface allow you to create scopes and signals and synchronize with the reader.
- inputStream
- java.io.InputStream object that provides the input data.
- progress
- Progress indication object of type IProgress. This object allows you to indicate the current progress and to control the timeout.
- console
- Console output of type IScriptConsole.
- Initialize the record
- Add the record content (scopes, signals and proxies)
- Open the writer
- Write samples and synchronize with the reader.
- Close the writer
Here you find a short example for a scripted reader.
// reader : The reader object for synchronisation purpose (de.toem.impulse.serializer.base.IScriptedReader) // generator : Record generator (de.toem.impulse.samples.ISingleDomainRecordGenerator) // inputStream : Input stream object (java.io.InputStream) // progress : Progress control (de.toem.pattern.threading.IProgress) // console : Console output (de.toem.impulse.scripting.IScriptConsole) // Init the record generator.initRecord("Example Record", TimeBase.ns); var a = generator.addSignal(null, "a", "", ProcessType.Discrete, SignalType.Integer, SignalDescriptor.DEFAULT); var b = generator.addSignal(null, "b", "", ProcessType.Discrete, SignalType.Integer, SignalDescriptor.DEFAULT); var c = generator.addSignal(null, "c", "", ProcessType.Discrete, SignalType.Integer, SignalDescriptor.DEFAULT); var d = generator.addSignal(null, "d", "", ProcessType.Discrete, SignalType.Integer, SignalDescriptor.DEFAULT); var wa /*:IIntegerSamplesWriter:*/ = generator.getWriter(a); var wb /*:IIntegerSamplesWriter:*/ = generator.getWriter(b); var wc /*:IIntegerSamplesWriter:*/ = generator.getWriter(c); var wd /*:IIntegerSamplesWriter:*/ = generator.getWriter(d); var current = 0; var started; generator.open(current); reader.changed(IRecordReader.CHANGED_RECORD); try { var input /*:java.io.BufferedReader:*/ = new BufferedReader(new InputStreamReader(inputStream)); var line /*:java.lang.String:*/ = input.readLine(); // skip type header while ((line = input.readLine()) != null) { var splitted = line.split(";"); var parsed = TimeBase.ns.parseUnits(splitted[0] + "ms"); if (started == null) started = parsed; current = parsed - started; console.println(current + " " + line + " " + line.length()); // add samples reader.lock(); wa.writeInt(current, false, splitted[1]); wb.writeInt(current, false, splitted[2]); wc.writeInt(current, false, splitted[3]); wd.writeInt(current, false, splitted[4]); reader.unlock(IRecordReader.CHANGED_SIGNALS); } } catch (e) { console.println(e); } reader.lock(); generator.close(current + 1); reader.unlock(IRecordReader.CHANGED_NONE);
Synchronisation with the reader
When using the reader with a port, new data will arrive over time at the inputStream object.
To display the new data, impulse continuously asks whether the reader has added new samples or created new signals. If this is the case, the reader is flushed and the result is displayed.
public final static int CHANGED_VALUE = 1; // current value has changed (e.g. for the value column) public final static int CHANGED_CURRENT = 2; // signal has changed in domain (e.g. signal duration is longer) public final static int CHANGED_SIGNALS = 3; // signal has changed in value (e.g. added samples) public final static int CHANGED_RECORD = 4; // record has changed (e.g. added signals) public final static int CHANGED_NONE = 0; // no change - no flush need to be performed
Below the synchronisation interface with the reader. The 'changed' method informs the reader about new changes. The optional 'units' parameter shall contain the current end position (the end position may be after the latest sample).
The 'lock' method prevents the reader from executing a 'flush'. The 'unlock' enables the reader to do a 'flush' and includes the change information.
public void changed(int changed, long position); // Notify the current changes. public void changed(int changed); // Notify the current changes. public void lock(); // Lock the reader against parallel flushing operations. public void unlock(int changed, long units); // Un-Lock the reader against parallel flushing operations. public void unlock(int changed); // Un-Lock the reader against parallel flushing operations.
Below a typical synchronisation sequence:
- Init the record
- call reader.changed(IRecordReader.CHANGED_RECORD);
- Iterate over input
- Read and parse input
- call reader.lock();
- Add samples
- call reader.unlock(IRecordReader.CHANGED_SIGNALS);
- call reader.lock();
- Close the record
- call reader.unlock(IRecordReader.CHANGED_NONE);
Content type
To use a scripted reader as workspace resource, a user need to add a content type association and script code to verify the validity of the content.
To add a file association for this reader, press 'Open Content Type Preferences' in the dialog of the scripted reader configuration, select 'Element/Record/SriptedReader Record' and press 'Add' under 'File associations'.
To verify the validity of the content, the dialog of the scripted reader has additional fields above the reader code.
- Sniff no of bytes: Enter the no of bytes, required to check the content type.
- Preferred: If this flag is set, impulse will try to read the requested no of bytes but will accept less.
- Script: Script code to check if the content data is applicable.
A typical script looks like this:
var StringType = Java.type("java.lang.String"); var s = new StringType(buffer); if (s.contains('CANSPEED')) IRecordReader.APPLICABLE;
The above example read the data into a string and checks if a keyword is included. In the case that the data is seen as valid, it return 'IRecordReader.APPLICABLE'.
Parse errors
The reader will provide a parse error message if the input can not be read. The message usually contains the error position, the reason for the failure and a stack trace.
If you can not resolve the problem (e.g. obvious format error in the input file), please send this message together with the input file to "This email address is being protected from spambots. You need JavaScript enabled to view it.".
Reader: de.toem.impulse.serializer.scripted Error at position: 0 Text at position: "null" Message: TypeError: reader.ulock is not a function inat line number 47 Type: class javax.script.ScriptException Stack trace: jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:470) jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:454) jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:406) jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:402) jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:155) javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264) de.toem.impulse.serializer.base.ScriptedReader$2.eval(ScriptedReader.java:169) de.toem.impulse.scripting.Scripting.run(Scripting.java:224) de.toem.impulse.scripting.Scripting.run(Scripting.java:129) de.toem.impulse.serializer.base.ScriptedReader.parse(ScriptedReader.java:177) de.toem.impulse.serializer.AbstractParsingRecordReader.read(AbstractParsingRecordReader.java:117) de.toem.impulse.parts.viewer.PortInput$AdapterStream$1.execute(PortInput.java:445) de.toem.eclipse.hooks.actives.EclipseActives$3.run(EclipseActives.java:73)