Compare commits
157 Commits
Author | SHA1 | Date | |
---|---|---|---|
e0f174173c | |||
12a7c701e3 | |||
cb259503cb | |||
8aca26e499 | |||
ebf3f920bf | |||
3b57ec029b | |||
01c9b7f1c2 | |||
a737f5588d | |||
f7f512a5f3 | |||
8f838a96b7 | |||
4d49e3b53f | |||
b809042189 | |||
0e705ce0e9 | |||
25064f9744 | |||
31fd54c6be | |||
3a931d59d5 | |||
a1094ff870 | |||
e53764cd7b | |||
3f7bdc7e28 | |||
8d94b517c1 | |||
d5e50a06b2 | |||
fda4c64ac7 | |||
8dcfc061cb | |||
79a5343cde | |||
c9c6db8e4c | |||
e629bdc5bc | |||
8522627081 | |||
d7f6d9b879 | |||
8f48abf0ae | |||
fbec708522 | |||
5c59fb0676 | |||
2a9c5ff6a5 | |||
9fe7a83dfa | |||
eb4e2301c1 | |||
a6aa9859ea | |||
1866ae17a9 | |||
6987985e36 | |||
f81f84d60e | |||
fd8e2ea751 | |||
2d11e39653 | |||
ab419a743f | |||
fc64fa781a | |||
c474ca33d8 | |||
8119c1a4f3 | |||
5f84194145 | |||
7dbcffe95d | |||
20934a9f47 | |||
24890f9bbb | |||
bd0629301b | |||
71da420d86 | |||
f9be6758e2 | |||
93a8c067fc | |||
5a372d0f90 | |||
806000c4cc | |||
539e5de813 | |||
c32d46cdc0 | |||
5736279e8d | |||
e3f4dc6616 | |||
a64e06ff7a | |||
a42b786835 | |||
e76000d87b | |||
60ead71029 | |||
4c48fda5ad | |||
6a591f2dbc | |||
86c30ad948 | |||
0ae055b486 | |||
efcd4f5ab8 | |||
232d2d4275 | |||
44f96e5383 | |||
44812310b0 | |||
6ef91bb5e7 | |||
aa459b0ea6 | |||
a2adf66618 | |||
3405e90df9 | |||
9a59947e67 | |||
9384d3278c | |||
1af3171b2e | |||
03fd9e154b | |||
3572f683e3 | |||
524ffb189c | |||
7fac6c8f74 | |||
037c645075 | |||
2f9bd29dc8 | |||
92662c546a | |||
efa6544623 | |||
52cf9daeec | |||
4a315722b1 | |||
a52efd1a12 | |||
535df30ada | |||
bad34dd1d1 | |||
5ac7f05f57 | |||
8353b59a27 | |||
2c6ca6c376 | |||
f4b03cb0e6 | |||
c7858997c0 | |||
bd99ab3992 | |||
66f365d38d | |||
59987f262d | |||
452a28362e | |||
d6805f383b | |||
076611eec7 | |||
e0fa55e2c0 | |||
9ea1994228 | |||
36f628c365 | |||
ff87e72510 | |||
aef1e29a53 | |||
1ebf9ba382 | |||
929408d08c | |||
f57fb93525 | |||
788065e456 | |||
22b46e0525 | |||
b75018239a | |||
598bb8eec7 | |||
869265fc13 | |||
5ad813527a | |||
73f8d3d50a | |||
da1701195d | |||
9b6334509e | |||
ac4acc34a4 | |||
b6963f38d6 | |||
182a036ade | |||
97f2182290 | |||
1986a8c9c3 | |||
6905d96329 | |||
818f786b1d | |||
2948c1bd33 | |||
78faab404c | |||
64b10970a8 | |||
6ab8fd232e | |||
f337a94112 | |||
0135631a3e | |||
d0e1e8801f | |||
d1b3a91979 | |||
45c1396e0e | |||
b7301733f0 | |||
5df91dbaa8 | |||
68918689e7 | |||
c41dd646da | |||
a077389b83 | |||
caa37375c0 | |||
3daea8ab43 | |||
c5d77af0d0 | |||
7f7fdf09f4 | |||
7aba6a2ecb | |||
012395b933 | |||
787e3accc0 | |||
b778940c83 | |||
71297c4e5a | |||
1d2395e00d | |||
b69e1886b9 | |||
d65803a4b7 | |||
0e49a68e09 | |||
7af5593fd4 | |||
25545dac51 | |||
df77af64ca | |||
e264ab2cbe | |||
8c17ed4146 |
@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.m2e.Maven2LaunchConfigurationType">
|
||||
<intAttribute key="M2_COLORS" value="0"/>
|
||||
<booleanAttribute key="M2_DEBUG_OUTPUT" value="false"/>
|
||||
<stringAttribute key="M2_GOALS" value="package"/>
|
||||
<booleanAttribute key="M2_NON_RECURSIVE" value="false"/>
|
||||
@ -12,6 +13,9 @@
|
||||
<booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/>
|
||||
<stringAttribute key="M2_USER_SETTINGS" value=""/>
|
||||
<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_ATTR_USE_ARGFILE" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_CLASSPATH_ONLY_JAR" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${project_loc:com.minres.scviewer.parent}"/>
|
||||
</launchConfiguration>
|
||||
|
@ -12,7 +12,8 @@
|
||||
<booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/>
|
||||
<stringAttribute key="M2_USER_SETTINGS" value=""/>
|
||||
<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_ATTR_USE_ARGFILE" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_CLASSPATH_ONLY_JAR" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.launching.macosx.MacOSXType/AdoptOpenJDK 8 [1.8.0_232]"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${project_loc:com.minres.scviewer.parent}"/>
|
||||
</launchConfiguration>
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.m2e.Maven2LaunchConfigurationType">
|
||||
<intAttribute key="M2_COLORS" value="0"/>
|
||||
<booleanAttribute key="M2_DEBUG_OUTPUT" value="false"/>
|
||||
<stringAttribute key="M2_GOALS" value="tycho-versions:set-version tycho-versions:update-pom"/>
|
||||
<booleanAttribute key="M2_NON_RECURSIVE" value="false"/>
|
||||
@ -15,6 +16,9 @@
|
||||
<stringAttribute key="M2_USER_SETTINGS" value=""/>
|
||||
<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="false"/>
|
||||
<stringAttribute key="bad_container_name" value="/com.minres.scviewer.parent/.launch"/>
|
||||
<booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_ATTR_USE_ARGFILE" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_CLASSPATH_ONLY_JAR" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${project_loc:com.minres.scviewer.parent}"/>
|
||||
</launchConfiguration>
|
||||
|
61
README.md
61
README.md
@ -18,14 +18,55 @@ The viewer has the following features
|
||||
- sqlite based
|
||||
- visualization of transaction relations
|
||||
|
||||
To build the plugins the Eclipse SDK or PDE can be used. In both cases the Groovy
|
||||
eclipse plugin (http://groovy.codehaus.org/Eclipse+Plugin or Market) has to be
|
||||
installed.
|
||||
To build the plugins the Eclipse SDK or PDE can be used.
|
||||
|
||||
Key Shortcuts
|
||||
=============
|
||||
|
||||
Legend:
|
||||
|
||||
* Left Mouse Button: LMB
|
||||
* Middle Mouse Button: MMB
|
||||
* Mouse Scroll wheel: MScrl
|
||||
* Context any means Name List, Value List or Waveform
|
||||
|
||||
| Input | Modifier | Context | Action |
|
||||
|------------|----------|----------|-----------------------------------|
|
||||
| LMB click | | any | select |
|
||||
| LMB click | Shift | Waveform | move selected marker to position |
|
||||
| LMB click | Control | Waveform | move cursor to position |
|
||||
| LMB drag | | Waveform | zoom to range |
|
||||
| MMB click | | Waveform | move selected marker to position |
|
||||
| MScrl | | any | scroll window up/down |
|
||||
| MScrl | Shift | any | scroll window left/right |
|
||||
| MScrl | Control | Waveform | zoom in/out |
|
||||
| Key left | | Waveform | scroll window to the left (slow) |
|
||||
| Key right | | Waveform | scroll window to the right (slow) |
|
||||
| Key left | Shift | Waveform | scroll window to the left (fast) |
|
||||
| Key right | Shift | Waveform | scroll window to the right (fast) |
|
||||
| Key up | | Waveform | move selection up |
|
||||
| Key down | | Waveform | move selection down |
|
||||
| Key up | Control | Waveform | move selected track up |
|
||||
| Key down | Control | Waveform | move selected track down |
|
||||
| Key + | Control | Waveform | zoom in |
|
||||
| Key - | Control | Waveform | zoom out |
|
||||
| Key Pos1 | | Waveform | jump to selected marker |
|
||||
| Key End | | Waveform | jump to cursor |
|
||||
| Key Del | | any | delete selected entries |
|
||||
| LMB click | | ZoomBar | increment/decrement 1 page |
|
||||
| LMB drag | | ZoomBar | drag both markers (pan) |
|
||||
| LMB drag | Control | ZoomBar | drag one marker (zoom) |
|
||||
| MMB drag | | ZoomBar | drag one marker (zoom) |
|
||||
| xMB dclick | | ZoomBar | pan to position |
|
||||
| MScrl | | ZoomBar | scroll window left/right |
|
||||
| MScrl | Shift | ZoomBar | scroll window left/right double speed |
|
||||
| MScrl | Control | ZoomBar | zoom in/out |
|
||||
| Key left | | ZoomBar | scroll window to the left (slow) |
|
||||
| Key right | | ZoomBar | scroll window to the right (slow) |
|
||||
| Key up | | ZoomBar | scroll window to the left (slow) |
|
||||
| Key down | | ZoomBar | scroll window to the right (slow) |
|
||||
| Key PgUp | | ZoomBar | scroll window to the left (fast) |
|
||||
| Key PgDown | | ZoomBar | scroll window to the right (fast) |
|
||||
| Key Pos1 | | ZoomBar | scroll to begin |
|
||||
| Key End | | ZoomBar | scroll to end |
|
||||
|
||||
TODO
|
||||
====
|
||||
- add more tests
|
||||
- move to feature based product to allow automatic updates
|
||||
- improve graphics
|
||||
- catch-up e3 plugin to functionality of e4 product
|
||||
- add calculated traces
|
||||
|
1
doc/com.minres.scviewer.doc/.gitignore
vendored
Normal file
1
doc/com.minres.scviewer.doc/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target/
|
11
doc/com.minres.scviewer.doc/.project
Normal file
11
doc/com.minres.scviewer.doc/.project
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.minres.scviewer.doc</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
</natures>
|
||||
</projectDescription>
|
168
doc/com.minres.scviewer.doc/pom.xml
Normal file
168
doc/com.minres.scviewer.doc/pom.xml
Normal file
@ -0,0 +1,168 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>com.minres.scviewer.doc</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<parent>
|
||||
<groupId>com.minres.scviewer</groupId>
|
||||
<artifactId>com.minres.scviewer.parent</artifactId>
|
||||
<version>2.17.1</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<asciidoctor.maven.plugin.version>2.0.0</asciidoctor.maven.plugin.version>
|
||||
<asciidoctorj.pdf.version>1.6.2</asciidoctorj.pdf.version>
|
||||
<help.plugin.target.dir>../../plugins/com.minres.scviewer.e4.application.help</help.plugin.target.dir>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.asciidoctor</groupId>
|
||||
<artifactId>asciidoctor-maven-plugin</artifactId>
|
||||
<version>${asciidoctor.maven.plugin.version}</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.asciidoctor</groupId>
|
||||
<artifactId>asciidoctorj-pdf</artifactId>
|
||||
<version>${asciidoctorj.pdf.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<configuration>
|
||||
<sourceDirectory>src/asciidoc</sourceDirectory>
|
||||
<sourceDocumentName>SCViewerHelp.adoc</sourceDocumentName>
|
||||
<headerFooter>true</headerFooter>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>output-html</id>
|
||||
<phase>generate-resources</phase>
|
||||
<goals>
|
||||
<goal>process-asciidoc</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sourceHighlighter>coderay</sourceHighlighter>
|
||||
<backend>html</backend>
|
||||
<attributes>
|
||||
<toc />
|
||||
<linkcss>false</linkcss>
|
||||
</attributes>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>output-docbook</id>
|
||||
<phase>generate-resources</phase>
|
||||
<goals>
|
||||
<goal>process-asciidoc</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<backend>docbook</backend>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>output-pdf</id>
|
||||
<phase>generate-resources</phase>
|
||||
<goals>
|
||||
<goal>process-asciidoc</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<backend>pdf</backend>
|
||||
<sourceHighlighter>coderay</sourceHighlighter>
|
||||
<attributes>
|
||||
<icons>font</icons>
|
||||
<pagenums />
|
||||
<toc />
|
||||
<idprefix />
|
||||
<idseparator>-</idseparator>
|
||||
</attributes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>2.6</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-asciidoc-resources</id>
|
||||
<phase>generate-resources</phase>
|
||||
<goals>
|
||||
<goal>copy-resources</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>target/generated-docs/</directory>
|
||||
<includes>
|
||||
<include>SCViewerHelp.xml</include>
|
||||
<include>**/*.jpg</include>
|
||||
<include>**/*.png</include>
|
||||
<include>**/*.svg</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
<outputDirectory>src/docbkx</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.agilejava.docbkx</groupId>
|
||||
<artifactId>docbkx-maven-plugin</artifactId>
|
||||
<version>2.0.17</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<!-- <phase>generate-sources</phase> -->
|
||||
<phase>generate-resources</phase>
|
||||
<goals>
|
||||
<goal>generate-eclipse</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.docbook</groupId>
|
||||
<artifactId>docbook-xml</artifactId>
|
||||
<version>4.4</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<configuration>
|
||||
<sourceDirectory>src/docbkx</sourceDirectory>
|
||||
<targetDirectory>${help.plugin.target.dir}</targetDirectory>
|
||||
<preProcess>
|
||||
<copy todir="${help.plugin.target.dir}/images">
|
||||
<fileset dir="src/docbkx/images" />
|
||||
</copy>
|
||||
<copy todir="${help.plugin.target.dir}/css">
|
||||
<fileset dir="src/docbkx/css" />
|
||||
</copy>
|
||||
</preProcess>
|
||||
<imgSrcPath>./</imgSrcPath>
|
||||
|
||||
<useExtensions>1</useExtensions>
|
||||
<highlightSource>1</highlightSource>
|
||||
<highlightDefaultLanguage>java</highlightDefaultLanguage>
|
||||
<calloutsExtension>1</calloutsExtension>
|
||||
<paperType>A4</paperType>
|
||||
<!--<fop1Extensions>1</fop1Extensions>
|
||||
<foCustomization>${basedir}/conf/customization-fopdf.xsl</foCustomization>-->
|
||||
|
||||
<!-- This copies content (images, etc) for the HTML version -->
|
||||
<!-- Any parameters specific to HTML version go here -->
|
||||
<htmlStylesheet>css/narrow_style.css</htmlStylesheet>
|
||||
<!-- <includes>titlepage/titlepage.templates.xml</includes> -->
|
||||
<includes>SCViewerHelp.xml</includes>
|
||||
<chunkedOutput>true</chunkedOutput>
|
||||
<xincludeSupported>true</xincludeSupported>
|
||||
<!-- <foCustomization>src/test/resources/docbook-fo.xsl</foCustomization> -->
|
||||
<eclipsePluginId>com.minres.scviewer.e4.application.help</eclipsePluginId>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
25
doc/com.minres.scviewer.doc/src/asciidoc/Overview.adoc
Normal file
25
doc/com.minres.scviewer.doc/src/asciidoc/Overview.adoc
Normal file
@ -0,0 +1,25 @@
|
||||
[#_introduction]
|
||||
== Introduction
|
||||
|
||||
[#_overview]
|
||||
=== SCViewer overview
|
||||
|
||||
SCViewer is composed of a set of eclipse plugins to display VCD and transaction streams
|
||||
created by the SystemC VCD trace implementation and the SystemC Verification Library (SCV).
|
||||
For further description of the SCV please refer to
|
||||
http://www.accellera.org/activities/committees/systemc-verification.
|
||||
|
||||
|
||||
[#_features]
|
||||
=== SCViewer features
|
||||
|
||||
Features include:
|
||||
|
||||
* support of VCD files (compressed and uncompressed)
|
||||
** real numbers
|
||||
** showing vectors and real numbers as analog (step-wise & continuous)
|
||||
* various value representations of bit vectors
|
||||
* support of SCV transaction recordings in various formats
|
||||
** text log files (compressed and uncompressed)
|
||||
** sqlite based
|
||||
** visualization of transaction relations
|
55
doc/com.minres.scviewer.doc/src/asciidoc/Reference.adoc
Normal file
55
doc/com.minres.scviewer.doc/src/asciidoc/Reference.adoc
Normal file
@ -0,0 +1,55 @@
|
||||
[#_reference]
|
||||
== Reference
|
||||
|
||||
In this section you will find detailed descriptions of all GUI and menu elements of the SCViewer including their functions and keyboard shortcuts.
|
||||
|
||||
[#_keybindings]
|
||||
=== Key Shortcuts
|
||||
|
||||
Legend:
|
||||
|
||||
* Left Mouse Button: LMB
|
||||
* Middle Mouse Button: MMB
|
||||
* Mouse Scroll wheel: MScrl
|
||||
* Context any means Name List, Value List or Waveform
|
||||
|
||||
[cols="1,1,1,4",options="header"]
|
||||
|===
|
||||
| Input | Modifier | Context | Action
|
||||
| LMB click | | any | select
|
||||
| LMB click | Shift | Waveform | move selected marker to position
|
||||
| LMB click | Control | Waveform | move cursor to position
|
||||
| LMB drag | | Waveform | zoom to range
|
||||
| MMB click | | Waveform | move selected marker to position
|
||||
| MScrl | | any | scroll window up/down
|
||||
| MScrl | Shift | any | scroll window left/right
|
||||
| Key left | | Waveform | scroll window to the left (slow)
|
||||
| Key right | | Waveform | scroll window to the right (slow)
|
||||
| Key left | Shift | Waveform | scroll window to the left (fast)
|
||||
| Key right | Shift | Waveform | scroll window to the right (fast)
|
||||
| Key up | | Waveform | move selection up
|
||||
| Key down | | Waveform | move selection down
|
||||
| Key up | Control | Waveform | move selected track up
|
||||
| Key down | Control | Waveform | move selected track down
|
||||
| Key + | Control | Waveform | zoom in
|
||||
| Key - | Control | Waveform | zoom out
|
||||
| Key Pos1 | | Waveform | jump to selected marker
|
||||
| Key End | | Waveform | jump to cursor
|
||||
| Key Del | | any | delete selected entries
|
||||
| LMB click | | ZoomBar | increment/decrement 1 page
|
||||
| LMB drag | | ZoomBar | drag both markers (pan)
|
||||
| LMB drag | Control | ZoomBar | drag one marker (zoom)
|
||||
| MMB drag | | ZoomBar | drag one marker (zoom)
|
||||
| xMB dclick | | ZoomBar | pan to position
|
||||
| MScrl | | ZoomBar | scroll window left/right
|
||||
| MScrl | Shift | ZoomBar | scroll window left/right double speed
|
||||
| MScrl | Control | ZoomBar | zoom in/out
|
||||
| Key left | | ZoomBar | scroll window to the left (slow)
|
||||
| Key right | | ZoomBar | scroll window to the right (slow)
|
||||
| Key up | | ZoomBar | scroll window to the left (slow)
|
||||
| Key down | | ZoomBar | scroll window to the right (slow)
|
||||
| Key PgUp | | ZoomBar | scroll window to the left (fast)
|
||||
| Key PgDown | | ZoomBar | scroll window to the right (fast)
|
||||
| Key Pos1 | | ZoomBar | scroll to begin
|
||||
| Key End | | ZoomBar | scroll to end
|
||||
|===
|
39
doc/com.minres.scviewer.doc/src/asciidoc/SCViewerHelp.adoc
Normal file
39
doc/com.minres.scviewer.doc/src/asciidoc/SCViewerHelp.adoc
Normal file
@ -0,0 +1,39 @@
|
||||
[#_start]
|
||||
= SCViewer User Guide
|
||||
:title-logo-image: image:Minres_logo_docs.png[width=750, align="right"]
|
||||
:doctype: book
|
||||
:source-highlighter: coderay
|
||||
:coderay-linenums-mode: inline
|
||||
:coderay-css: class
|
||||
:listing-caption: Listing
|
||||
:icons: font
|
||||
//add table-of-contents (toc) and set its depth
|
||||
:toc:
|
||||
:toclevels: 3
|
||||
:data-uri:
|
||||
:sectnums:
|
||||
:toc-title: Contents
|
||||
:homepage: https://www.minres.com/
|
||||
:keywords:
|
||||
:title-page:
|
||||
:xrefstyle: short
|
||||
:table-caption: Table
|
||||
:figure-caption: Figure
|
||||
:appendix-caption: Appendix
|
||||
:section-refsig: Chapter
|
||||
//set directories
|
||||
:imagesdir: ./images
|
||||
:iconsdir: ./icons
|
||||
:stylesdir: ./styles
|
||||
:scriptsdir: ./js
|
||||
:pdf-themesdir: ./themes
|
||||
:pdf-theme: mnrs-doc
|
||||
:pdf-fontsdir: ./fonts
|
||||
|
||||
|
||||
// unset toc, otherwise it appears in table cells -> known bug, should be fixed in later versions!
|
||||
:toc!:
|
||||
|
||||
include::Overview.adoc[]
|
||||
|
||||
include::Reference.adoc[]
|
93
doc/com.minres.scviewer.doc/src/asciidoc/fonts/OFL.txt
Normal file
93
doc/com.minres.scviewer.doc/src/asciidoc/fonts/OFL.txt
Normal file
@ -0,0 +1,93 @@
|
||||
Copyright (c) 2009-2011 by Accademia di Belle Arti di Urbino and students of MA course of Visual design. Some rights reserved.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
doc/com.minres.scviewer.doc/src/asciidoc/images/Minres_logo.png
Normal file
BIN
doc/com.minres.scviewer.doc/src/asciidoc/images/Minres_logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
Binary file not shown.
After Width: | Height: | Size: 35 KiB |
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
@ -0,0 +1,55 @@
|
||||
page:
|
||||
layout: portrait
|
||||
margin: [2.3cm, 2cm, 2cm, 2.2cm]
|
||||
size: A4
|
||||
base:
|
||||
font-color: #000000
|
||||
font-color-mnrs-grey: #6a747c
|
||||
font-color-mnrs-blue: #197788
|
||||
font-family: titillium
|
||||
font-size: 12
|
||||
line-height-length: 16
|
||||
line-height: $base-line-height-length / $base-font-size
|
||||
align: justify
|
||||
vertical-spacing: $base-line-height-length
|
||||
heading:
|
||||
font-color: $base-font-color-mnrs-grey
|
||||
font-size: $base-font-size * 1.25
|
||||
font-style: bold
|
||||
line-height: $base-line-height * 1.2
|
||||
margin-bottom: $vertical-spacing
|
||||
link:
|
||||
font-color: $base_font-color-mnrs-blue
|
||||
outline-list:
|
||||
indent: $base-font-size * 1.5
|
||||
footer:
|
||||
height: $base-line-height-length * 3.0
|
||||
font-color: $base-font-color-mnrs-grey
|
||||
font-size: $base-font-size * 0.9
|
||||
line-height: 1
|
||||
recto:
|
||||
left:
|
||||
content: '{description} v{revision}, © 2021 MINRES'
|
||||
right:
|
||||
content: '{page-number}'
|
||||
verso:
|
||||
left:
|
||||
content: $footer_recto_right_content
|
||||
right:
|
||||
content: $footer_recto_left_content
|
||||
table:
|
||||
border_color: $base-font-color
|
||||
border_width: 0.1
|
||||
title-page:
|
||||
align: right
|
||||
font-color: $base-font-color-mnrs-grey
|
||||
font-size: $base-font-size * 1.80
|
||||
font-style: bold
|
||||
font:
|
||||
fallbacks: titilliumtext22l002-webfont.ttf
|
||||
catalog:
|
||||
titillium:
|
||||
normal: titilliumtext22l002-webfont.ttf
|
||||
bold: titilliumtext22l005-webfont.ttf
|
||||
italic: TitilliumWeb-Italic.ttf
|
||||
bold_italic: TitilliumWeb-BoldItalic.ttf
|
1
doc/com.minres.scviewer.doc/src/docbkx/.gitignore
vendored
Normal file
1
doc/com.minres.scviewer.doc/src/docbkx/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/SCViewerHelp.xml
|
124
doc/com.minres.scviewer.doc/src/docbkx/css/narrow_style.css
Normal file
124
doc/com.minres.scviewer.doc/src/docbkx/css/narrow_style.css
Normal file
@ -0,0 +1,124 @@
|
||||
P.Code {
|
||||
display: block;
|
||||
text-align: left;
|
||||
text-indent: 0.00pt;
|
||||
margin-top: 0.000000pt;
|
||||
margin-bottom: 0.000000pt;
|
||||
margin-right: 0.000000pt;
|
||||
margin-left: 1.5em;
|
||||
font-size: 100%;
|
||||
font-weight: medium;
|
||||
font-style: Regular;
|
||||
color: #4444CC;
|
||||
text-decoration: none;
|
||||
vertical-align: baseline;
|
||||
text-transform: none;
|
||||
font-family: "Courier New";
|
||||
}
|
||||
H6.CaptionFigColumn {
|
||||
display: block;
|
||||
text-align: left;
|
||||
text-indent: 0.000000pt;
|
||||
margin-top: 0.3em;
|
||||
margin-bottom: 1.1em;
|
||||
margin-right: 0.000000pt;
|
||||
margin-left: 0.000000pt;
|
||||
font-size: 90%;
|
||||
font-weight: medium;
|
||||
font-style: Italic;
|
||||
color: #000000;
|
||||
text-decoration: none;
|
||||
vertical-align: baseline;
|
||||
text-transform: none;
|
||||
font-family: "Arial";
|
||||
}
|
||||
P.Note {
|
||||
display: block;
|
||||
text-align: left;
|
||||
text-indent: 0pt;
|
||||
margin-top: 1.95em;
|
||||
margin-bottom: 1.95em;
|
||||
margin-right: 0.000000pt;
|
||||
margin-left: 3.0em;
|
||||
font-size: 110%;
|
||||
font-weight: medium;
|
||||
font-style: Italic;
|
||||
color: #000000;
|
||||
text-decoration: none;
|
||||
vertical-align: baseline;
|
||||
text-transform: none;
|
||||
font-family: "Arial";
|
||||
}
|
||||
EM.UILabel {
|
||||
font-weight: Bold;
|
||||
font-style: Regular;
|
||||
text-decoration: none;
|
||||
vertical-align: baseline;
|
||||
text-transform: none;
|
||||
}
|
||||
EM.CodeName {
|
||||
font-weight: Bold;
|
||||
font-style: Regular;
|
||||
text-decoration: none;
|
||||
vertical-align: baseline;
|
||||
text-transform: none;
|
||||
font-family:"Courier New";
|
||||
}
|
||||
|
||||
|
||||
|
||||
body, html { border: 0px }
|
||||
|
||||
/* following font face declarations need to be removed for DBCS */
|
||||
|
||||
body, h1, h2, h3, h4, h5, h6, p, table, td, caption, th, ul, ol, dl, li, dd, dt {font: message-box; color: #000000}
|
||||
pre { font-family: Courier, monospace}
|
||||
|
||||
/* end font face declarations */
|
||||
|
||||
/* following font size declarations should be OK for DBCS */
|
||||
body, h1, h2, h3, h4, h5, h6, p, table, td, caption, th, ul, ol, dl, li, dd, dt {font: message-box; }
|
||||
pre { font-size: 100% }
|
||||
code,samp { font-size: 100%; }
|
||||
|
||||
/* end font size declarations */
|
||||
|
||||
body { background: #FFFFFF}
|
||||
h1 { font-size: 180%; font-weight: medium; margin-top: 0.28em; margin-bottom: 0.05em; color: Highlight }
|
||||
h2 { font-size: 140%; font-weight: bold; margin-top: 0.22em; margin-bottom: 3; color: Highlight }
|
||||
h3 { font-size: 110%; font-weight: bold; margin-top: 0.18em; margin-bottom: 3 }
|
||||
h4 { font-size: 100%; font-weight: bold; margin-top: 0.2em; margin-bottom: 3; font-style: italic }
|
||||
p { margin-top: 1.0em; margin-bottom: 1.0em }
|
||||
pre { margin-left: 6; font-size: 90% }
|
||||
a:link { color: #0000FF }
|
||||
a:hover { color: #000080 }
|
||||
a:visited { text-decoration: underline }
|
||||
ul { margin-top: 0;
|
||||
margin-bottom: 1.0em;
|
||||
margin-left : 1.0em;
|
||||
padding-left: 0;
|
||||
}
|
||||
li { margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
padding-left: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
li p { margin-top: 0; margin-bottom: 0 }
|
||||
ol { margin-top: 0;
|
||||
margin-bottom: 10;
|
||||
padding-left: 0;
|
||||
margin-left: 1.4em }
|
||||
dl { margin-top: 0; margin-bottom: 10 }
|
||||
dt { margin-top: 0; margin-bottom: 0; font-weight: bold }
|
||||
dd { margin-top: 0; margin-bottom: 0 }
|
||||
strong { font-weight: bold}
|
||||
em { font-style: italic}
|
||||
var { font-style: italic}
|
||||
div.revision { border-left-style: solid; border-left-width: thin;
|
||||
border-left-color: #7B68EE; padding-left:5 }
|
||||
th { font-weight: bold }
|
||||
|
||||
.figure-contents .mediaobject img {
|
||||
width: 100%;
|
||||
heigth: auto;
|
||||
}
|
108
doc/com.minres.scviewer.doc/src/docbkx/css/style.css
Normal file
108
doc/com.minres.scviewer.doc/src/docbkx/css/style.css
Normal file
@ -0,0 +1,108 @@
|
||||
P.Code {
|
||||
display: block;
|
||||
text-align: left;
|
||||
text-indent: 0.00pt;
|
||||
margin-top: 0.000000pt;
|
||||
margin-bottom: 0.000000pt;
|
||||
margin-right: 0.000000pt;
|
||||
margin-left: 15pt;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
color: #4444CC;
|
||||
text-decoration: none;
|
||||
vertical-align: baseline;
|
||||
text-transform: none;
|
||||
font-family: "Courier New", Courier, monospace;
|
||||
}
|
||||
H6.CaptionFigColumn {
|
||||
display: block;
|
||||
text-align: left;
|
||||
text-indent: 0.000000pt;
|
||||
margin-top: 3.000000pt;
|
||||
margin-bottom: 11.000000pt;
|
||||
margin-right: 0.000000pt;
|
||||
margin-left: 0.000000pt;
|
||||
font-size: 75%;
|
||||
font-weight: bold;
|
||||
font-style: Italic;
|
||||
color: #000000;
|
||||
text-decoration: none;
|
||||
vertical-align: baseline;
|
||||
text-transform: none;
|
||||
}
|
||||
P.Note {
|
||||
display: block;
|
||||
text-align: left;
|
||||
text-indent: 0pt;
|
||||
margin-top: 19.500000pt;
|
||||
margin-bottom: 19.500000pt;
|
||||
margin-right: 0.000000pt;
|
||||
margin-left: 30pt;
|
||||
font-size: 110%;
|
||||
font-weight: normal;
|
||||
font-style: Italic;
|
||||
color: #000000;
|
||||
text-decoration: none;
|
||||
vertical-align: baseline;
|
||||
text-transform: none;
|
||||
}
|
||||
EM.UILabel {
|
||||
font-weight: Bold;
|
||||
font-style: normal;
|
||||
text-decoration: none;
|
||||
vertical-align: baseline;
|
||||
text-transform: none;
|
||||
}
|
||||
EM.CodeName {
|
||||
font-weight: Bold;
|
||||
font-style: normal;
|
||||
text-decoration: none;
|
||||
vertical-align: baseline;
|
||||
text-transform: none;
|
||||
font-family: "Courier New", Courier, monospace;
|
||||
}
|
||||
UL.NavList {
|
||||
margin-left: 1.5em;
|
||||
padding-left: 0px;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
body, html { border: 0px }
|
||||
|
||||
|
||||
/* following font face declarations need to be removed for DBCS */
|
||||
|
||||
body, h1, h2, h3, h4, h5, h6, p, table, td, caption, th, ul, ol, dl, li, dd, dt {font-family: Arial, Helvetica, sans-serif; color: #000000}
|
||||
pre, code { font-family: "Courier New", Courier, monospace;}
|
||||
|
||||
/* end font face declarations */
|
||||
|
||||
@media print {
|
||||
html { font-size: 12pt }
|
||||
}
|
||||
|
||||
body { font-size: 83%; background: #FFFFFF; margin-bottom: 1em }
|
||||
h1 { font-size: 180%; margin-top: 5px; margin-bottom: 1px }
|
||||
h2 { font-size: 140%; margin-top: 25px; margin-bottom: 3px }
|
||||
h3 { font-size: 110%; margin-top: 20px; margin-bottom: 3px }
|
||||
h4 { font-size: 100%; margin-top: 20px; margin-bottom: 3px; font-style: italic }
|
||||
p { margin-top: 10px; margin-bottom: 10px }
|
||||
pre { font-size: 93%; margin-left: 6; color: #4444CC }
|
||||
code { font-size: 93%; }
|
||||
table { font-size: 100% } /* needed for quirks mode */
|
||||
a:link { color: #0000FF }
|
||||
a:hover { color: #000080 }
|
||||
a:visited { text-decoration: underline }
|
||||
ul { margin-top: 10px; margin-bottom: 10px; }
|
||||
li { margin-top: 5px; margin-bottom: 5px; }
|
||||
li p { margin-top: 5px; margin-bottom: 5px; }
|
||||
ol { margin-top: 10px; margin-bottom: 10px; }
|
||||
dl { margin-top: 10px; margin-bottom: 10px; }
|
||||
dt { margin-top: 5px; margin-bottom: 5px; font-weight: bold; }
|
||||
dd { margin-top: 5px; margin-bottom: 5px; }
|
||||
strong { font-weight: bold}
|
||||
em { font-style: italic}
|
||||
var { font-style: italic}
|
||||
div.revision { border-left-style: solid; border-left-width: thin;
|
||||
border-left-color: #7B68EE; padding-left:5 }
|
||||
th { font-weight: bold }
|
1
doc/com.minres.scviewer.doc/src/docbkx/images/.gitignore
vendored
Normal file
1
doc/com.minres.scviewer.doc/src/docbkx/images/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/*.png
|
@ -27,12 +27,12 @@ http://www.eclipse.org/legal/epl-v10.html
|
||||
</url>
|
||||
|
||||
<requires>
|
||||
<import plugin="org.codehaus.groovy" version="2.5.8" match="greaterOrEqual"/>
|
||||
<import plugin="org.eclipse.osgi.services" version="3.4.0" match="greaterOrEqual"/>
|
||||
<import plugin="com.google.guava" version="15.0.0" match="greaterOrEqual"/>
|
||||
<import plugin="org.eclipse.osgi"/>
|
||||
<import plugin="com.minres.scviewer.database" version="1.0.0" match="greaterOrEqual"/>
|
||||
<import plugin="org.eclipse.core.runtime"/>
|
||||
<import feature="org.eclipse.collections.feature" version="10.4.0.v20200820-2049"/>
|
||||
</requires>
|
||||
|
||||
<plugin
|
||||
@ -70,4 +70,11 @@ http://www.eclipse.org/legal/epl-v10.html
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="com.minres.scviewer.database.ftr"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
</feature>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.minres.scviewer</groupId>
|
||||
<artifactId>com.minres.scviewer.parent</artifactId>
|
||||
<version>2.12.1</version>
|
||||
<version>2.17.1</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<version>3.0.0-SNAPSHOT</version>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.minres.scviewer</groupId>
|
||||
<artifactId>com.minres.scviewer.parent</artifactId>
|
||||
<version>2.12.1</version>
|
||||
<version>2.17.1</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<version>1.1.0-SNAPSHOT</version>
|
||||
|
1
features/com.minres.scviewer.e4.help.feature/.gitignore
vendored
Normal file
1
features/com.minres.scviewer.e4.help.feature/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target/
|
17
features/com.minres.scviewer.e4.help.feature/.project
Normal file
17
features/com.minres.scviewer.e4.help.feature/.project
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.minres.scviewer.e4.help.feature</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.FeatureBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.FeatureNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
@ -0,0 +1 @@
|
||||
bin.includes = feature.xml
|
207
features/com.minres.scviewer.e4.help.feature/feature.xml
Normal file
207
features/com.minres.scviewer.e4.help.feature/feature.xml
Normal file
@ -0,0 +1,207 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<feature
|
||||
id="com.minres.scviewer.e4.help.feature"
|
||||
label="Feature"
|
||||
version="1.0.0.qualifier"
|
||||
provider-name="MINRES Technologies GmbH">
|
||||
|
||||
<description url="http://www.example.com/description">
|
||||
[Enter Feature Description here.]
|
||||
</description>
|
||||
|
||||
<copyright url="http://www.example.com/copyright">
|
||||
[Enter Copyright Description here.]
|
||||
</copyright>
|
||||
|
||||
<license url="http://www.example.com/license">
|
||||
[Enter License Description here.]
|
||||
</license>
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.help"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.help.webapp"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.help.base"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.apache.lucene.core"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.apache.lucene.analyzers-common"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.apache.lucene.analyzers-smartcn"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.core.net"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.equinox.security"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.equinox.security.linux.x86_64"
|
||||
os="linux"
|
||||
arch="x86_64"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
fragment="true"/>
|
||||
|
||||
<plugin
|
||||
id="javax.el"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="javax.servlet"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="javax.servlet.jsp"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.equinox.http.jetty"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.equinox.http.registry"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.equinox.http.servlet"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.equinox.jsp.jasper"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.equinox.jsp.jasper.registry"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.apache.jasper.glassfish"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.jetty.http"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.jetty.io"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.jetty.security"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.jetty.server"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.jetty.servlet"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.jetty.util"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="com.minres.scviewer.e4.application.help"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.equinox.security.win32.x86_64"
|
||||
os="win32"
|
||||
arch="x86_64"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
fragment="true"
|
||||
unpack="false"/>
|
||||
|
||||
</feature>
|
12
features/com.minres.scviewer.e4.help.feature/pom.xml
Normal file
12
features/com.minres.scviewer.e4.help.feature/pom.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>com.minres.scviewer.e4.help.feature</artifactId>
|
||||
<packaging>eclipse-feature</packaging>
|
||||
<parent>
|
||||
<groupId>com.minres.scviewer</groupId>
|
||||
<artifactId>com.minres.scviewer.parent</artifactId>
|
||||
<version>2.17.1</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</project>
|
@ -29,6 +29,10 @@
|
||||
id="org.eclipse.emf.common"
|
||||
version="0.0.0"/>
|
||||
|
||||
<includes
|
||||
id="org.eclipse.collections.feature"
|
||||
version="0.0.0"/>
|
||||
|
||||
<requires>
|
||||
<import plugin="org.eclipse.core.expressions" version="3.2.0" match="compatible"/>
|
||||
<import plugin="org.eclipse.core.filesystem" version="1.3.0" match="compatible"/>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.minres.scviewer</groupId>
|
||||
<artifactId>com.minres.scviewer.parent</artifactId>
|
||||
<version>2.12.1</version>
|
||||
<version>2.17.1</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.minres.scviewer</groupId>
|
||||
<artifactId>com.minres.scviewer.parent</artifactId>
|
||||
<version>2.12.1</version>
|
||||
<version>2.17.1</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<version>1.1.0-SNAPSHOT</version>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.minres.scviewer</groupId>
|
||||
<artifactId>com.minres.scviewer.parent</artifactId>
|
||||
<version>2.12.1</version>
|
||||
<version>2.17.1</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<version>1.1.0-SNAPSHOT</version>
|
||||
|
11
plugins/com.minres.scviewer.database.ftr/.classpath
Normal file
11
plugins/com.minres.scviewer.database.ftr/.classpath
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
|
||||
<attributes>
|
||||
<attribute name="module" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
3
plugins/com.minres.scviewer.database.ftr/.gitignore
vendored
Normal file
3
plugins/com.minres.scviewer.database.ftr/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/bin
|
||||
/target/
|
||||
/.settings/
|
39
plugins/com.minres.scviewer.database.ftr/.project
Normal file
39
plugins/com.minres.scviewer.database.ftr/.project
Normal file
@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.minres.scviewer.database.ftr</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ds.core.builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
@ -0,0 +1,18 @@
|
||||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: CBOR transaction database
|
||||
Bundle-SymbolicName: com.minres.scviewer.database.ftr
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Vendor: MINRES Technologies GmbH
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-11
|
||||
Import-Package: org.osgi.framework;version="1.3.0",
|
||||
org.slf4j;version="1.7.2"
|
||||
Require-Bundle: com.minres.scviewer.database,
|
||||
org.eclipse.osgi.services;bundle-version="3.4.0",
|
||||
com.google.guava;bundle-version="15.0.0",
|
||||
org.eclipse.collections;bundle-version="10.4.0",
|
||||
org.apache.commons.compress;bundle-version="1.20.0"
|
||||
Service-Component: OSGI-INF/component.xml
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Automatic-Module-Name: com.minres.scviewer.database.ftr
|
||||
Bundle-ClassPath: .
|
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="FtrDbLoaderFactory">
|
||||
<implementation class="com.minres.scviewer.database.ftr.FtrDbLoaderFactory"/>
|
||||
<service>
|
||||
<provide interface="com.minres.scviewer.database.IWaveformDbLoaderFactory"/>
|
||||
</service>
|
||||
</scr:component>
|
14
plugins/com.minres.scviewer.database.ftr/build.properties
Normal file
14
plugins/com.minres.scviewer.database.ftr/build.properties
Normal file
@ -0,0 +1,14 @@
|
||||
###############################################################################
|
||||
# Copyright (c) 2014, 2015-2021 MINRES Technologies GmbH and others.
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
#
|
||||
# Contributors:
|
||||
# MINRES Technologies GmbH - initial API and implementation
|
||||
###############################################################################
|
||||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
OSGI-INF/
|
||||
source.. = src/
|
14
plugins/com.minres.scviewer.database.ftr/pom.xml
Normal file
14
plugins/com.minres.scviewer.database.ftr/pom.xml
Normal file
@ -0,0 +1,14 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>com.minres.scviewer.database.ftr</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<parent>
|
||||
<groupId>com.minres.scviewer</groupId>
|
||||
<artifactId>com.minres.scviewer.parent</artifactId>
|
||||
<version>2.17.1</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
|
||||
</project>
|
@ -0,0 +1,189 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 MINRES Technologies GmbH
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IT Just working - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.minres.scviewer.database.ftr;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import com.minres.scviewer.database.EventEntry;
|
||||
import com.minres.scviewer.database.EventList;
|
||||
import com.minres.scviewer.database.HierNode;
|
||||
import com.minres.scviewer.database.IEvent;
|
||||
import com.minres.scviewer.database.IEventList;
|
||||
import com.minres.scviewer.database.IWaveform;
|
||||
import com.minres.scviewer.database.WaveformType;
|
||||
import com.minres.scviewer.database.tx.ITx;
|
||||
import com.minres.scviewer.database.tx.ITxEvent;
|
||||
|
||||
/**
|
||||
* The Class AbstractTxStream.
|
||||
*/
|
||||
abstract class AbstractTxStream extends HierNode implements IWaveform {
|
||||
|
||||
private final String fullName;
|
||||
|
||||
/** The id. */
|
||||
private Long id;
|
||||
|
||||
/** The loader. */
|
||||
protected FtrDbLoader loader;
|
||||
|
||||
/** The events. */
|
||||
IEventList events = new EventList();
|
||||
|
||||
/** The max concurrency. */
|
||||
private int rowCount = -1;
|
||||
|
||||
/**
|
||||
* Instantiates a new abstract tx stream.
|
||||
*
|
||||
* @param loader the loader
|
||||
* @param id the id
|
||||
* @param name the name
|
||||
*/
|
||||
protected AbstractTxStream(FtrDbLoader loader, Long id, String name) {
|
||||
super(name);
|
||||
fullName=name;
|
||||
this.loader = loader;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the full hierarchical name.
|
||||
*
|
||||
* @return the full name
|
||||
*/
|
||||
@Override
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
/**
|
||||
* Adds the event.
|
||||
*
|
||||
* @param evt the evt
|
||||
*/
|
||||
public void addEvent(ITxEvent evt) {
|
||||
events.put(evt.getTime(), evt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the events.
|
||||
*
|
||||
* @return the events
|
||||
*/
|
||||
@Override
|
||||
public IEventList getEvents() {
|
||||
return events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the events at time.
|
||||
*
|
||||
* @param time the time
|
||||
* @return the events at time
|
||||
*/
|
||||
@Override
|
||||
public IEvent[] getEventsAtTime(long time) {
|
||||
return events.get(time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the events before time.
|
||||
*
|
||||
* @param time the time
|
||||
* @return the events before time
|
||||
*/
|
||||
@Override
|
||||
public IEvent[] getEventsBeforeTime(long time) {
|
||||
EventEntry e = events.floorEntry(time);
|
||||
if (e == null)
|
||||
return new IEvent[] {};
|
||||
else
|
||||
return events.floorEntry(time).events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type.
|
||||
*
|
||||
* @return the type
|
||||
*/
|
||||
@Override
|
||||
public WaveformType getType() {
|
||||
return WaveformType.TRANSACTION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id.
|
||||
*
|
||||
* @return the id
|
||||
*/
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the width.
|
||||
*
|
||||
* @return the width
|
||||
*/
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
if (rowCount<0)
|
||||
calculateConcurrency();
|
||||
return rowCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate concurrency.
|
||||
*/
|
||||
void calculateConcurrency() {
|
||||
if (rowCount>=0)
|
||||
return;
|
||||
ArrayList<Long> rowEndTime = new ArrayList<>();
|
||||
HashMap<Long, Integer> rowByTxId = new HashMap<>();
|
||||
for(EventEntry entry: events) {
|
||||
for(IEvent evt:entry.events) {
|
||||
TxEvent txEvt = (TxEvent) evt;
|
||||
ITx tx = txEvt.getTransaction();
|
||||
int rowIdx = 0;
|
||||
switch(evt.getKind()) {
|
||||
case END: //TODO: might throw NPE in concurrent execution
|
||||
Long txId = txEvt.getTransaction().getId();
|
||||
txEvt.setConcurrencyIndex(rowByTxId.get(txId));
|
||||
rowByTxId.remove(txId);
|
||||
break;
|
||||
case SINGLE:
|
||||
for (; rowIdx < rowEndTime.size() && rowEndTime.get(rowIdx)>tx.getBeginTime(); rowIdx++);
|
||||
if (rowEndTime.size() <= rowIdx)
|
||||
rowEndTime.add(tx.getEndTime());
|
||||
else
|
||||
rowEndTime.set(rowIdx, tx.getEndTime());
|
||||
((TxEvent) evt).setConcurrencyIndex(rowIdx);
|
||||
break;
|
||||
case BEGIN:
|
||||
for (; rowIdx < rowEndTime.size() && rowEndTime.get(rowIdx)>tx.getBeginTime(); rowIdx++);
|
||||
if (rowEndTime.size() <= rowIdx)
|
||||
rowEndTime.add(tx.getEndTime());
|
||||
else
|
||||
rowEndTime.set(rowIdx, tx.getEndTime());
|
||||
((TxEvent) evt).setConcurrencyIndex(rowIdx);
|
||||
rowByTxId.put(tx.getId(), rowIdx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
rowCount=rowEndTime.size()>0?rowEndTime.size():1;
|
||||
//getChildNodes().parallelStream().forEach(c -> ((TxGenerator)c).calculateConcurrency());
|
||||
getChildNodes().stream().forEach(c -> ((TxGenerator)c).calculateConcurrency());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,525 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 MINRES Technologies GmbH
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IT Just working - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.minres.scviewer.database.ftr;
|
||||
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.compress.compressors.lz4.BlockLZ4CompressorInputStream;
|
||||
import org.eclipse.collections.impl.map.mutable.UnifiedMap;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.minres.scviewer.database.AssociationType;
|
||||
import com.minres.scviewer.database.DataType;
|
||||
import com.minres.scviewer.database.EventKind;
|
||||
import com.minres.scviewer.database.IWaveform;
|
||||
import com.minres.scviewer.database.IWaveformDb;
|
||||
import com.minres.scviewer.database.IWaveformDbLoader;
|
||||
import com.minres.scviewer.database.InputFormatException;
|
||||
import com.minres.scviewer.database.RelationType;
|
||||
import com.minres.scviewer.database.RelationTypeFactory;
|
||||
import com.minres.scviewer.database.tx.ITx;
|
||||
import com.minres.scviewer.database.tx.ITxAttribute;
|
||||
|
||||
import jacob.CborDecoder;
|
||||
import jacob.CborType;
|
||||
|
||||
/**
|
||||
* The Class TextDbLoader.
|
||||
*/
|
||||
public class FtrDbLoader implements IWaveformDbLoader {
|
||||
|
||||
enum FileType { NONE, PLAIN, GZIP, LZ4};
|
||||
|
||||
/** The max time. */
|
||||
private Long maxTime = 0L;
|
||||
|
||||
ArrayList<String> strDict = new ArrayList<>();
|
||||
|
||||
|
||||
/** The attr values. */
|
||||
final List<String> attrValues = new ArrayList<>();
|
||||
|
||||
/** The relation types. */
|
||||
final Map<String, RelationType> relationTypes = UnifiedMap.newMap();
|
||||
|
||||
/** The tx streams. */
|
||||
final Map<Long, TxStream> txStreams = UnifiedMap.newMap();
|
||||
|
||||
/** The tx generators. */
|
||||
final Map<Long, TxGenerator> txGenerators = UnifiedMap.newMap();
|
||||
|
||||
/** The transactions. */
|
||||
final Map<Long, FtrTx> transactions = UnifiedMap.newMap();
|
||||
|
||||
/** The attribute types. */
|
||||
final Map<String, TxAttributeType> attributeTypes = UnifiedMap.newMap();
|
||||
|
||||
/** The relations in. */
|
||||
final HashMultimap<Long, FtrRelation> relationsIn = HashMultimap.create();
|
||||
|
||||
/** The relations out. */
|
||||
final HashMultimap<Long, FtrRelation> relationsOut = HashMultimap.create();
|
||||
|
||||
/** The tx cache. */
|
||||
final Map<Long, Tx> txCache = UnifiedMap.newMap();
|
||||
|
||||
/** The threads. */
|
||||
List<Thread> threads = new ArrayList<>();
|
||||
|
||||
File file;
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(FtrDbLoader.class);
|
||||
|
||||
/** The pcs. */
|
||||
protected PropertyChangeSupport pcs = new PropertyChangeSupport(this);
|
||||
|
||||
long time_scale_factor = 1000l;
|
||||
|
||||
/**
|
||||
* Adds the property change listener.
|
||||
*
|
||||
* @param l the l
|
||||
*/
|
||||
@Override
|
||||
public void addPropertyChangeListener(PropertyChangeListener l) {
|
||||
pcs.addPropertyChangeListener(l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the property change listener.
|
||||
*
|
||||
* @param l the l
|
||||
*/
|
||||
@Override
|
||||
public void removePropertyChangeListener(PropertyChangeListener l) {
|
||||
pcs.removePropertyChangeListener(l);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the max time.
|
||||
*
|
||||
* @return the max time
|
||||
*/
|
||||
@Override
|
||||
public long getMaxTime() {
|
||||
return maxTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the transaction.
|
||||
*
|
||||
* @param txId the tx id
|
||||
* @return the transaction
|
||||
*/
|
||||
public ITx getTransaction(long txId) {
|
||||
if (txCache.containsKey(txId))
|
||||
return txCache.get(txId);
|
||||
if(transactions.containsKey(txId)) {
|
||||
Tx tx = new Tx(this, transactions.get(txId));
|
||||
txCache.put(txId, tx);
|
||||
return tx;
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
public FtrTx getScvTx(long id) {
|
||||
if(transactions.containsKey(id))
|
||||
return transactions.get(id);
|
||||
else
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the all waves.
|
||||
*
|
||||
* @return the all waves
|
||||
*/
|
||||
@Override
|
||||
public Collection<IWaveform> getAllWaves() {
|
||||
ArrayList<IWaveform> ret = new ArrayList<>(txStreams.values());
|
||||
ret.addAll(txGenerators.values());
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the all relation types.
|
||||
*
|
||||
* @return the all relation types
|
||||
*/
|
||||
public Collection<RelationType> getAllRelationTypes() {
|
||||
return relationTypes.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load.
|
||||
*
|
||||
* @param db the db
|
||||
* @param file the file
|
||||
* @return true, if successful
|
||||
* @throws InputFormatException the input format exception
|
||||
*/
|
||||
@Override
|
||||
public void load(IWaveformDb db, File file) throws InputFormatException {
|
||||
dispose();
|
||||
this.file=file;
|
||||
try(FileInputStream fis = new FileInputStream(file)) {
|
||||
new CborDbParser(this, fis);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error parsing file "+file.getName(), e);
|
||||
transactions.clear();
|
||||
throw new InputFormatException(e.toString());
|
||||
}
|
||||
txStreams.values().parallelStream().forEach(TxStream::calculateConcurrency);
|
||||
}
|
||||
|
||||
public List<? extends byte[]> getChunksAtOffsets(ArrayList<Long> fileOffsets) throws InputFormatException {
|
||||
List<byte[]> ret = new ArrayList<>();
|
||||
try(FileInputStream fis = new FileInputStream(file)) {
|
||||
FileChannel fc = fis.getChannel();
|
||||
for (Long offset : fileOffsets) {
|
||||
if(offset>=0) {
|
||||
fc.position(offset);
|
||||
CborDecoder parser = new CborDecoder(fis);
|
||||
ret.add(parser.readByteString());
|
||||
} else {
|
||||
fc.position(-offset);
|
||||
CborDecoder parser = new CborDecoder(fis);
|
||||
BlockLZ4CompressorInputStream decomp = new BlockLZ4CompressorInputStream(new ByteArrayInputStream(parser.readByteString()));
|
||||
ret.add(decomp.readAllBytes());
|
||||
decomp.close();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error parsing file "+file.getName(), e);
|
||||
transactions.clear();
|
||||
throw new InputFormatException(e.toString());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<? extends ITxAttribute> parseAtrributes(byte[] chunk, long blockOffset) {
|
||||
List<ITxAttribute> ret = new ArrayList<>();
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(chunk);
|
||||
bais.skip(blockOffset);
|
||||
CborDecoder cborDecoder = new CborDecoder(bais);
|
||||
try {
|
||||
long tx_size = cborDecoder.readArrayLength();
|
||||
for(long i = 0; i<tx_size; ++i) {
|
||||
long tag = cborDecoder.readTag();
|
||||
switch((int)tag) {
|
||||
case 6: // id/generator/start/end
|
||||
long len = cborDecoder.readArrayLength();
|
||||
assert(len==4);
|
||||
cborDecoder.readInt();
|
||||
cborDecoder.readInt();
|
||||
cborDecoder.readInt();
|
||||
cborDecoder.readInt();
|
||||
break;
|
||||
default: { // skip over 7:begin attr, 8:record attr, 9:end attr
|
||||
long sz = cborDecoder.readArrayLength();
|
||||
assert(sz==3);
|
||||
long name_id = cborDecoder.readInt();
|
||||
long type_id = cborDecoder.readInt();
|
||||
String attrName = strDict.get((int)name_id);
|
||||
if(!attributeTypes.containsKey(attrName)) {
|
||||
attributeTypes.put(attrName, new TxAttributeType(attrName, DataType.values()[(int)type_id], AssociationType.values()[(int)tag-7]));
|
||||
}
|
||||
TxAttributeType attrType = attributeTypes.get(attrName);
|
||||
switch((int)type_id) {
|
||||
case 0: // BOOLEAN
|
||||
ITxAttribute b = new TxAttribute(attrType, cborDecoder.readInt()>0?"True":"False");
|
||||
ret.add(b);
|
||||
break;
|
||||
case 2: // INTEGER
|
||||
case 3: // UNSIGNED
|
||||
ITxAttribute a = new TxAttribute(attrType, String.valueOf(cborDecoder.readInt()));
|
||||
ret.add(a);
|
||||
break;
|
||||
case 4: // FLOATING_POINT_NUMBER
|
||||
case 7: // FIXED_POINT_INTEGER
|
||||
case 8: // UNSIGNED_FIXED_POINT_INTEGER
|
||||
ITxAttribute v = new TxAttribute(attrType, String.valueOf(cborDecoder.readFloat()));
|
||||
ret.add(v);
|
||||
break;
|
||||
case 1: // ENUMERATION
|
||||
case 5: // BIT_VECTOR
|
||||
case 6: // LOGIC_VECTOR
|
||||
case 12: // STRING
|
||||
ITxAttribute s = new TxAttribute(attrType, strDict.get((int)cborDecoder.readInt()));
|
||||
ret.add(s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOG.error("Error parsing file "+file.getName(), e);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispose.
|
||||
*/
|
||||
@Override
|
||||
public void dispose() {
|
||||
attrValues.clear();
|
||||
relationTypes.clear();
|
||||
txStreams.clear();
|
||||
txGenerators.clear();
|
||||
transactions.clear();
|
||||
attributeTypes.clear();
|
||||
relationsIn.clear();
|
||||
relationsOut.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* The Class TextDbParser.
|
||||
*/
|
||||
static class CborDbParser extends CborDecoder {
|
||||
|
||||
static final private CborType break_type = CborType.valueOf(0xff);
|
||||
|
||||
/** The loader. */
|
||||
final FtrDbLoader loader;
|
||||
|
||||
/**
|
||||
* Instantiates a new text db parser.
|
||||
*
|
||||
* @param loader the loader
|
||||
*/
|
||||
public CborDbParser(FtrDbLoader loader, FileInputStream inputStream) {
|
||||
super(inputStream);
|
||||
this.loader = loader;
|
||||
try {
|
||||
long cbor_tag = readTag();
|
||||
assert(cbor_tag == 55799);
|
||||
long array_len = readArrayLength();
|
||||
assert(array_len==-1);
|
||||
CborType next = peekType();
|
||||
while(next != null && !break_type.isEqualType(next)) {
|
||||
long tag = readTag();
|
||||
switch((int)tag) {
|
||||
<<<<<<< HEAD
|
||||
case 6: // info
|
||||
=======
|
||||
case 6: { // info
|
||||
>>>>>>> refs/heads/release/2.17.1
|
||||
CborDecoder cbd = new CborDecoder(new ByteArrayInputStream(readByteString()));
|
||||
long sz = cbd.readArrayLength();
|
||||
assert(sz==3);
|
||||
long time_numerator=cbd.readInt();
|
||||
long time_denominator=cbd.readInt();
|
||||
loader.time_scale_factor = 1000000000000000l*time_numerator/time_denominator;
|
||||
long epoch_tag = cbd.readTag();
|
||||
assert(epoch_tag==1);
|
||||
cbd.readInt(); // epoch
|
||||
break;
|
||||
}
|
||||
case 8: { // dictionary uncompressed
|
||||
parseDict(new CborDecoder(new ByteArrayInputStream(readByteString())));
|
||||
break;
|
||||
}
|
||||
case 9: { // dictionary compressed
|
||||
long sz = readArrayLength();
|
||||
assert(sz==2);
|
||||
readInt(); // uncompressed size
|
||||
parseDict(new CborDecoder(new BlockLZ4CompressorInputStream(new ByteArrayInputStream(readByteString()))));
|
||||
break;
|
||||
}
|
||||
case 10: { // directory uncompressed
|
||||
parseDir(new CborDecoder(new ByteArrayInputStream(readByteString())));
|
||||
break;
|
||||
}
|
||||
case 11: { // directory compressed
|
||||
long sz = readArrayLength();
|
||||
assert(sz==2);
|
||||
readInt(); // uncompressed size
|
||||
parseDir(new CborDecoder(new BlockLZ4CompressorInputStream(new ByteArrayInputStream(readByteString()))));
|
||||
break;
|
||||
}
|
||||
case 12: { //tx chunk uncompressed
|
||||
long len = readArrayLength();
|
||||
assert(len==2);
|
||||
long stream_id = readInt();
|
||||
TxStream txStream = loader.txStreams.get(stream_id);
|
||||
txStream.fileOffsets.add(inputStream.getChannel().position());
|
||||
parseTx(txStream, txStream.fileOffsets.size()-1, readByteString());
|
||||
break;
|
||||
}
|
||||
case 13: { //tx chunk compressed
|
||||
long len = readArrayLength();
|
||||
assert(len==3);
|
||||
long stream_id = readInt();
|
||||
readInt(); // uncompressed size
|
||||
TxStream txStream = loader.txStreams.get(stream_id);
|
||||
txStream.fileOffsets.add(0-inputStream.getChannel().position());
|
||||
BlockLZ4CompressorInputStream decomp = new BlockLZ4CompressorInputStream(new ByteArrayInputStream(readByteString()));
|
||||
parseTx(txStream, txStream.fileOffsets.size()-1, decomp.readAllBytes());
|
||||
decomp.close();
|
||||
break;
|
||||
}
|
||||
case 14: { // relations uncompressed
|
||||
parseRel(new CborDecoder(new ByteArrayInputStream(readByteString())));
|
||||
break;
|
||||
}
|
||||
case 15: { // relations uncompressed
|
||||
long sz = readArrayLength();
|
||||
assert(sz==2);
|
||||
readInt(); // uncompressed size
|
||||
parseRel(new CborDecoder(new BlockLZ4CompressorInputStream(new ByteArrayInputStream(readByteString()))));
|
||||
break;
|
||||
}
|
||||
}
|
||||
next = peekType();
|
||||
}
|
||||
} catch(IOException e) {
|
||||
LOG.error("Error parsing file input stream", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void parseDict(CborDecoder cborDecoder) throws IOException {
|
||||
long size = cborDecoder.readMapLength();
|
||||
ArrayList<String> lst = new ArrayList<>((int)size);
|
||||
for(long i = 0; i<size; ++i) {
|
||||
long idx = cborDecoder.readInt();
|
||||
assert(idx==loader.strDict.size()+1);
|
||||
lst.add(cborDecoder.readTextString());
|
||||
}
|
||||
loader.strDict.addAll(lst);
|
||||
}
|
||||
|
||||
private void parseDir(CborDecoder cborDecoder) throws IOException {
|
||||
long size = cborDecoder.readArrayLength();
|
||||
if(size<0) {
|
||||
CborType next = cborDecoder.peekType();
|
||||
while(next != null && !break_type.isEqualType(next)) {
|
||||
parseDictEntry(cborDecoder);
|
||||
next = cborDecoder.peekType();
|
||||
}
|
||||
} else
|
||||
for(long i = 0; i<size; ++i) {
|
||||
parseDictEntry(cborDecoder);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void parseDictEntry(CborDecoder cborDecoder) throws IOException {
|
||||
long id = cborDecoder.readTag();
|
||||
if(id==16) { // a stream
|
||||
long len = cborDecoder.readArrayLength();
|
||||
assert(len==3);
|
||||
long stream_id = cborDecoder.readInt();
|
||||
long name_id = cborDecoder.readInt();
|
||||
long kind_id = cborDecoder.readInt();
|
||||
add(stream_id, new TxStream(loader, stream_id, loader.strDict.get((int)name_id), loader.strDict.get((int)kind_id)));
|
||||
} else if(id==17) { // a generator
|
||||
long len = cborDecoder.readArrayLength();
|
||||
assert(len==3);
|
||||
long gen_id = cborDecoder.readInt();
|
||||
long name_id = cborDecoder.readInt();
|
||||
long stream_id = cborDecoder.readInt();
|
||||
add(gen_id, new TxGenerator(loader, gen_id, loader.strDict.get((int)name_id), loader.txStreams.get(stream_id)));
|
||||
} else {
|
||||
throw new IOException("Illegal tage ncountered: "+id);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseTx(TxStream txStream, long blockId, byte[] chunk) throws IOException {
|
||||
CborDecoder cborDecoder = new CborDecoder(new ByteArrayInputStream(chunk));
|
||||
long size = cborDecoder.readArrayLength();
|
||||
assert(size==-1);
|
||||
CborType next = cborDecoder.peekType();
|
||||
while(next != null && !break_type.isEqualType(next)) {
|
||||
long blockOffset = cborDecoder.getPos();
|
||||
long tx_size = cborDecoder.readArrayLength();
|
||||
for(long i = 0; i<tx_size; ++i) {
|
||||
long tag = cborDecoder.readTag();
|
||||
switch((int)tag) {
|
||||
case 6: // id/generator/start/end
|
||||
long len = cborDecoder.readArrayLength();
|
||||
assert(len==4);
|
||||
long txId = cborDecoder.readInt();
|
||||
long genId = cborDecoder.readInt();
|
||||
long startTime = cborDecoder.readInt()*loader.time_scale_factor;
|
||||
long endTime = cborDecoder.readInt()*loader.time_scale_factor;
|
||||
TxGenerator gen = loader.txGenerators.get(genId);
|
||||
FtrTx scvTx = new FtrTx(txId, gen.stream.getId(), genId, startTime, endTime, blockId, blockOffset);
|
||||
loader.maxTime = loader.maxTime > scvTx.endTime ? loader.maxTime : scvTx.endTime;
|
||||
loader.transactions.put(txId, scvTx);
|
||||
TxStream stream = loader.txStreams.get(gen.stream.getId());
|
||||
if (scvTx.beginTime == scvTx.endTime) {
|
||||
stream.addEvent(new TxEvent(loader, EventKind.SINGLE, txId, scvTx.beginTime));
|
||||
gen.addEvent(new TxEvent(loader, EventKind.SINGLE, txId, scvTx.beginTime));
|
||||
} else {
|
||||
stream.addEvent(new TxEvent(loader, EventKind.BEGIN, txId, scvTx.beginTime));
|
||||
gen.addEvent(new TxEvent(loader, EventKind.BEGIN, txId, scvTx.beginTime));
|
||||
stream.addEvent(new TxEvent(loader, EventKind.END, txId, scvTx.endTime));
|
||||
gen.addEvent(new TxEvent(loader, EventKind.END, txId, scvTx.endTime));
|
||||
}
|
||||
break;
|
||||
default: { // skip over 7:begin attr, 8:record attr, 9:end attr
|
||||
long sz = cborDecoder.readArrayLength();
|
||||
assert(sz==3);
|
||||
for(long j = 0; j<sz; ++j)
|
||||
cborDecoder.readInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
next = cborDecoder.peekType();
|
||||
}
|
||||
}
|
||||
|
||||
private void parseRel(CborDecoder cborDecoder) throws IOException {
|
||||
long size = cborDecoder.readArrayLength();
|
||||
assert(size==-1);
|
||||
CborType next = cborDecoder.peekType();
|
||||
while(next != null && !break_type.isEqualType(next)) {
|
||||
long sz = cborDecoder.readArrayLength();
|
||||
assert(sz==3);
|
||||
long type_id = cborDecoder.readInt();
|
||||
long from_id = cborDecoder.readInt();
|
||||
long to_id = cborDecoder.readInt();
|
||||
String rel_name = loader.strDict.get((int)type_id);
|
||||
FtrRelation ftrRel = new FtrRelation(loader.relationTypes.getOrDefault(rel_name, RelationTypeFactory.create(rel_name)), from_id, to_id);
|
||||
loader.relationsOut.put(from_id, ftrRel);
|
||||
loader.relationsIn.put(to_id, ftrRel);
|
||||
next = cborDecoder.peekType();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void add(Long id, TxStream stream) {
|
||||
loader.txStreams.put(id, stream);
|
||||
loader.pcs.firePropertyChange(IWaveformDbLoader.STREAM_ADDED, null, stream);
|
||||
}
|
||||
|
||||
private void add(Long id, TxGenerator generator) {
|
||||
loader.txGenerators.put(id, generator);
|
||||
loader.pcs.firePropertyChange(IWaveformDbLoader.GENERATOR_ADDED, null, generator);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 MINRES Technologies GmbH
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IT Just working - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.minres.scviewer.database.ftr;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import com.minres.scviewer.database.IWaveformDbLoader;
|
||||
import com.minres.scviewer.database.IWaveformDbLoaderFactory;
|
||||
|
||||
/**
|
||||
* The Class TextDbLoader.
|
||||
*/
|
||||
public class FtrDbLoaderFactory implements IWaveformDbLoaderFactory {
|
||||
|
||||
public static byte[] hexStringToByteArray(String s) {
|
||||
int len = s.length();
|
||||
byte[] data = new byte[len / 2];
|
||||
for (int i = 0; i < len; i += 2) {
|
||||
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
|
||||
+ Character.digit(s.charAt(i+1), 16));
|
||||
}
|
||||
return data;
|
||||
}
|
||||
/** The Constant x. */
|
||||
static final byte[] x = hexStringToByteArray("d9d9f79f");
|
||||
|
||||
/**
|
||||
* Can load.
|
||||
*
|
||||
* @param inputFile the input file
|
||||
* @return true, if successful
|
||||
*/
|
||||
@Override
|
||||
public boolean canLoad(File inputFile) {
|
||||
try (InputStream is = new FileInputStream(inputFile)) {
|
||||
byte[] buffer = new byte[x.length];
|
||||
int readCnt = is.read(buffer, 0, x.length);
|
||||
if (readCnt == x.length) {
|
||||
for (int i = 0; i < x.length; i++)
|
||||
if (buffer[i] != x[i]) return false;
|
||||
}
|
||||
return true;
|
||||
} catch (IOException e) {}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IWaveformDbLoader getLoader() {
|
||||
return new FtrDbLoader();
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 MINRES Technologies GmbH
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IT Just working - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.minres.scviewer.database.ftr;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.minres.scviewer.database.RelationType;
|
||||
|
||||
/**
|
||||
* The Class ScvRelation.
|
||||
*/
|
||||
class FtrRelation implements Serializable {
|
||||
|
||||
/** The Constant serialVersionUID. */
|
||||
private static final long serialVersionUID = -347668857680574140L;
|
||||
|
||||
/** The source. */
|
||||
final long source;
|
||||
|
||||
/** The target. */
|
||||
final long target;
|
||||
|
||||
/** The relation type. */
|
||||
final RelationType relationType;
|
||||
|
||||
/**
|
||||
* Instantiates a new scv relation.
|
||||
*
|
||||
* @param relationType the relation type
|
||||
* @param source the source
|
||||
* @param target the target
|
||||
*/
|
||||
public FtrRelation(RelationType relationType, long source, long target) {
|
||||
this.source = source;
|
||||
this.target = target;
|
||||
this.relationType = relationType;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 MINRES Technologies GmbH
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IT Just working - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.minres.scviewer.database.ftr;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.minres.scviewer.database.InputFormatException;
|
||||
import com.minres.scviewer.database.tx.ITxAttribute;
|
||||
|
||||
/**
|
||||
* The Class ScvTx.
|
||||
*/
|
||||
class FtrTx implements Serializable {
|
||||
|
||||
/** The Constant serialVersionUID. */
|
||||
private static final long serialVersionUID = -855200240003328221L;
|
||||
|
||||
/** The id. */
|
||||
final long id;
|
||||
|
||||
/** The generator id. */
|
||||
final long generatorId;
|
||||
|
||||
/** The stream id. */
|
||||
final long streamId;
|
||||
|
||||
/** The begin time. */
|
||||
long beginTime;
|
||||
|
||||
/** The end time. */
|
||||
long endTime;
|
||||
|
||||
/** The attributes. */
|
||||
final List<ITxAttribute> attributes = new ArrayList<>();
|
||||
|
||||
final long blockId;
|
||||
|
||||
final long blockOffset;
|
||||
|
||||
/**
|
||||
* Instantiates a new scv tx.
|
||||
*
|
||||
* @param id the id
|
||||
* @param streamId the stream id
|
||||
* @param generatorId the generator id
|
||||
* @param begin the begin
|
||||
*/
|
||||
FtrTx(long id, long streamId, long generatorId, long begin, long end, long blockId, long blockOffset) {
|
||||
this.id = id;
|
||||
this.streamId = streamId;
|
||||
this.generatorId = generatorId;
|
||||
this.beginTime = begin;
|
||||
this.endTime = end;
|
||||
this.blockId=blockId;
|
||||
this.blockOffset=blockOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id.
|
||||
*
|
||||
* @return the id
|
||||
*/
|
||||
Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public List<ITxAttribute> getAttributes(FtrDbLoader loader) {
|
||||
if(attributes.size()==0)
|
||||
try {
|
||||
TxStream stream = loader.txStreams.get(streamId);
|
||||
byte[] chunk = stream.getChunks().get((int)blockId);
|
||||
attributes.addAll(loader.parseAtrributes(chunk, blockOffset));
|
||||
} catch (InputFormatException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return attributes;
|
||||
}
|
||||
}
|
@ -0,0 +1,232 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2012 IT Just working.
|
||||
* Copyright (c) 2020 MINRES Technologies GmbH
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IT Just working - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.minres.scviewer.database.ftr;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.minres.scviewer.database.IWaveform;
|
||||
import com.minres.scviewer.database.tx.ITx;
|
||||
import com.minres.scviewer.database.tx.ITxAttribute;
|
||||
import com.minres.scviewer.database.tx.ITxRelation;
|
||||
|
||||
/**
|
||||
* The Class Tx.
|
||||
*/
|
||||
class Tx implements ITx {
|
||||
|
||||
/** The loader. */
|
||||
private final FtrDbLoader loader;
|
||||
|
||||
private FtrTx scvTx =null;
|
||||
|
||||
/** The id. */
|
||||
private final long id;
|
||||
|
||||
private final long generatorId;
|
||||
|
||||
private final long streamId;
|
||||
|
||||
/** The begin time. */
|
||||
long beginTime = -1;
|
||||
|
||||
/** The end time. */
|
||||
long endTime = -1;
|
||||
|
||||
/**
|
||||
* Instantiates a new tx.
|
||||
*
|
||||
* @param loader the loader
|
||||
* @param scvTx the scv tx
|
||||
*/
|
||||
public Tx(FtrDbLoader loader, FtrTx scvTx) {
|
||||
this.loader = loader;
|
||||
id = scvTx.id;
|
||||
this.scvTx=scvTx;
|
||||
generatorId=scvTx.generatorId;
|
||||
streamId=scvTx.streamId;
|
||||
beginTime=scvTx.beginTime;
|
||||
endTime=scvTx.endTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new tx.
|
||||
*
|
||||
* @param loader the loader
|
||||
* @param txId the tx id
|
||||
*/
|
||||
public Tx(FtrDbLoader loader, long id, long generatorId, long streamId) {
|
||||
this.loader = loader;
|
||||
this.id = id;
|
||||
this.generatorId=generatorId;
|
||||
this.streamId = streamId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the incoming relations.
|
||||
*
|
||||
* @return the incoming relations
|
||||
*/
|
||||
@Override
|
||||
public Collection<ITxRelation> getIncomingRelations() {
|
||||
Set<FtrRelation> rels = loader.relationsIn.get(id);
|
||||
return rels.stream().map(rel -> new TxRelation(loader, rel)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the outgoing relations.
|
||||
*
|
||||
* @return the outgoing relations
|
||||
*/
|
||||
@Override
|
||||
public Collection<ITxRelation> getOutgoingRelations() {
|
||||
Set<FtrRelation> rels = loader.relationsOut.get(id);
|
||||
return rels.stream().map(rel -> new TxRelation(loader, rel)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare to.
|
||||
*
|
||||
* @param o the o
|
||||
* @return the int
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(ITx o) {
|
||||
int res = Long.compare(getBeginTime(), o.getBeginTime());
|
||||
if (res != 0)
|
||||
return res;
|
||||
else
|
||||
return Long.compare(getId(), o.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Equals.
|
||||
*
|
||||
* @param obj the obj
|
||||
* @return true, if successful
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
return this.getScvTx().equals(((Tx) obj).getScvTx());
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash code.
|
||||
*
|
||||
* @return the int
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getScvTx().hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* To string.
|
||||
*
|
||||
* @return the string
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "tx#" + getId() + "[" + getBeginTime() / 1000000 + "ns - " + getEndTime() / 1000000 + "ns]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id.
|
||||
*
|
||||
* @return the id
|
||||
*/
|
||||
@Override
|
||||
public long getId() {
|
||||
return getScvTx().id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the stream.
|
||||
*
|
||||
* @return the stream
|
||||
*/
|
||||
@Override
|
||||
public IWaveform getStream() {
|
||||
return loader.txStreams.get(streamId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the generator.
|
||||
*
|
||||
* @return the generator
|
||||
*/
|
||||
@Override
|
||||
public IWaveform getGenerator() {
|
||||
return loader.txGenerators.get(generatorId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the begin time.
|
||||
*
|
||||
* @return the begin time
|
||||
*/
|
||||
@Override
|
||||
public long getBeginTime() {
|
||||
if (beginTime < 0) {
|
||||
FtrTx tx = scvTx==null?loader.getScvTx(id):getScvTx();
|
||||
beginTime = tx.beginTime;
|
||||
endTime = tx.endTime;
|
||||
}
|
||||
return beginTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the end time.
|
||||
*
|
||||
* @return the end time
|
||||
*/
|
||||
@Override
|
||||
public long getEndTime() {
|
||||
if (endTime < 0) {
|
||||
FtrTx tx = scvTx==null?loader.getScvTx(id):getScvTx();
|
||||
beginTime = tx.beginTime;
|
||||
endTime = tx.endTime;
|
||||
}
|
||||
return endTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the end time.
|
||||
*
|
||||
* @param time the new end time
|
||||
*/
|
||||
void setEndTime(Long time) {
|
||||
getScvTx().endTime = time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the attributes.
|
||||
*
|
||||
* @return the attributes
|
||||
*/
|
||||
@Override
|
||||
public List<ITxAttribute> getAttributes() {
|
||||
return getScvTx().getAttributes(loader);
|
||||
}
|
||||
|
||||
private FtrTx getScvTx() {
|
||||
if(scvTx==null)
|
||||
scvTx=loader.getScvTx(id);
|
||||
return scvTx;
|
||||
}
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 MINRES Technologies GmbH
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IT Just working - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.minres.scviewer.database.ftr;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.minres.scviewer.database.AssociationType;
|
||||
import com.minres.scviewer.database.DataType;
|
||||
import com.minres.scviewer.database.tx.ITxAttribute;
|
||||
|
||||
/**
|
||||
* The Class TxAttribute.
|
||||
*/
|
||||
public class TxAttribute implements ITxAttribute, Serializable {
|
||||
|
||||
/** The Constant serialVersionUID. */
|
||||
private static final long serialVersionUID = 4767726016651807152L;
|
||||
|
||||
/** The attribute type. */
|
||||
private final TxAttributeType attributeType;
|
||||
|
||||
/** The value. */
|
||||
private final String value;
|
||||
|
||||
/**
|
||||
* Instantiates a new tx attribute.
|
||||
*
|
||||
* @param type the type
|
||||
* @param value the value
|
||||
*/
|
||||
TxAttribute(TxAttributeType type, String value) {
|
||||
this.attributeType = type;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name.
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return attributeType.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type.
|
||||
*
|
||||
* @return the type
|
||||
*/
|
||||
@Override
|
||||
public AssociationType getType() {
|
||||
return attributeType.getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the data type.
|
||||
*
|
||||
* @return the data type
|
||||
*/
|
||||
@Override
|
||||
public DataType getDataType() {
|
||||
return attributeType.getDataType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value.
|
||||
*
|
||||
* @return the value
|
||||
*/
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 MINRES Technologies GmbH
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IT Just working - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.minres.scviewer.database.ftr;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.minres.scviewer.database.AssociationType;
|
||||
import com.minres.scviewer.database.DataType;
|
||||
import com.minres.scviewer.database.tx.ITxAttributeType;
|
||||
|
||||
/**
|
||||
* The Class TxAttributeType.
|
||||
*/
|
||||
class TxAttributeType implements ITxAttributeType, Serializable {
|
||||
|
||||
/** The Constant serialVersionUID. */
|
||||
private static final long serialVersionUID = 7159721937208946828L;
|
||||
|
||||
/** The name. */
|
||||
private String name;
|
||||
|
||||
/** The data type. */
|
||||
private DataType dataType;
|
||||
|
||||
/** The type. */
|
||||
private AssociationType type;
|
||||
|
||||
/**
|
||||
* Instantiates a new tx attribute type.
|
||||
*
|
||||
* @param name the name
|
||||
* @param dataType the data type
|
||||
* @param type the type
|
||||
*/
|
||||
TxAttributeType(String name, DataType dataType, AssociationType type) {
|
||||
this.name = name;
|
||||
this.dataType = dataType;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name.
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the data type.
|
||||
*
|
||||
* @return the data type
|
||||
*/
|
||||
@Override
|
||||
public DataType getDataType() {
|
||||
return dataType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type.
|
||||
*
|
||||
* @return the type
|
||||
*/
|
||||
@Override
|
||||
public AssociationType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name + ":" + dataType.name() + "@" + type.name();
|
||||
}
|
||||
}
|
@ -0,0 +1,120 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 MINRES Technologies GmbH
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IT Just working - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.minres.scviewer.database.ftr;
|
||||
|
||||
import com.minres.scviewer.database.EventKind;
|
||||
import com.minres.scviewer.database.WaveformType;
|
||||
import com.minres.scviewer.database.tx.ITx;
|
||||
import com.minres.scviewer.database.tx.ITxEvent;
|
||||
|
||||
/**
|
||||
* The Class TxEvent.
|
||||
*/
|
||||
class TxEvent implements ITxEvent {
|
||||
|
||||
/** The loader. */
|
||||
final FtrDbLoader loader;
|
||||
|
||||
/** The kind. */
|
||||
final EventKind kind;
|
||||
|
||||
/** The transaction. */
|
||||
final long transaction;
|
||||
|
||||
/** The time. */
|
||||
final long time;
|
||||
|
||||
private int concurrencyIdx=-1;
|
||||
/**
|
||||
* Instantiates a new tx event.
|
||||
*
|
||||
* @param loader the loader
|
||||
* @param kind the kind
|
||||
* @param transaction the transaction
|
||||
* @param time the time
|
||||
*/
|
||||
TxEvent(FtrDbLoader loader, EventKind kind, Long transaction, Long time) {
|
||||
this.loader = loader;
|
||||
this.kind = kind;
|
||||
this.transaction = transaction;
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate.
|
||||
*
|
||||
* @return the i tx event
|
||||
* @throws CloneNotSupportedException the clone not supported exception
|
||||
*/
|
||||
@Override
|
||||
public ITxEvent duplicate() throws CloneNotSupportedException {
|
||||
return new TxEvent(loader, kind, transaction, time);
|
||||
}
|
||||
|
||||
/**
|
||||
* To string.
|
||||
*
|
||||
* @return the string
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return kind.toString() + "@" + time + " of tx #" + transaction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type.
|
||||
*
|
||||
* @return the type
|
||||
*/
|
||||
@Override
|
||||
public WaveformType getType() {
|
||||
return WaveformType.TRANSACTION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the kind.
|
||||
*
|
||||
* @return the kind
|
||||
*/
|
||||
@Override
|
||||
public EventKind getKind() {
|
||||
return kind;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the time.
|
||||
*
|
||||
* @return the time
|
||||
*/
|
||||
@Override
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the transaction.
|
||||
*
|
||||
* @return the transaction
|
||||
*/
|
||||
@Override
|
||||
public ITx getTransaction() {
|
||||
return loader.getTransaction(transaction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowIndex() {
|
||||
return concurrencyIdx;
|
||||
}
|
||||
|
||||
public void setConcurrencyIndex(int idx) {
|
||||
concurrencyIdx=idx;
|
||||
}
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 MINRES Technologies GmbH
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IT Just working - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.minres.scviewer.database.ftr;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.minres.scviewer.database.IWaveform;
|
||||
|
||||
/**
|
||||
* The Class TxGenerator.
|
||||
*/
|
||||
class TxGenerator extends AbstractTxStream {
|
||||
|
||||
/** The stream. */
|
||||
TxStream stream;
|
||||
|
||||
/** The begin attrs. */
|
||||
List<TxAttributeType> beginAttrs = new ArrayList<>();
|
||||
|
||||
/** The end attrs. */
|
||||
List<TxAttributeType> endAttrs = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Instantiates a new tx generator.
|
||||
*
|
||||
* @param loader the loader
|
||||
* @param id the id
|
||||
* @param name the name
|
||||
* @param stream the stream
|
||||
*/
|
||||
TxGenerator(FtrDbLoader loader, Long id, String name, TxStream stream) {
|
||||
super(loader, id, name);
|
||||
this.stream = stream;
|
||||
stream.addChild(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if is same.
|
||||
*
|
||||
* @param other the other
|
||||
* @return true, if is same
|
||||
*/
|
||||
@Override
|
||||
public boolean isSame(IWaveform other) {
|
||||
return (other instanceof TxGenerator && this.getId()==other.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the begin attrs.
|
||||
*
|
||||
* @return the begin attrs
|
||||
*/
|
||||
public List<TxAttributeType> getBeginAttrs() {
|
||||
return beginAttrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the end attrs.
|
||||
*
|
||||
* @return the end attrs
|
||||
*/
|
||||
public List<TxAttributeType> getEndAttrs() {
|
||||
return endAttrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the kind.
|
||||
*
|
||||
* @return the kind
|
||||
*/
|
||||
@Override
|
||||
public String getKind() {
|
||||
return stream.getKind();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the full hierarchical name.
|
||||
*
|
||||
* @return the full name
|
||||
*/
|
||||
@Override
|
||||
public String getFullName() {
|
||||
return ((AbstractTxStream)parent).getFullName()+"."+name;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 MINRES Technologies GmbH
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IT Just working - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.minres.scviewer.database.ftr;
|
||||
|
||||
import com.minres.scviewer.database.RelationType;
|
||||
import com.minres.scviewer.database.tx.ITx;
|
||||
import com.minres.scviewer.database.tx.ITxRelation;
|
||||
|
||||
/**
|
||||
* The Class TxRelation.
|
||||
*/
|
||||
class TxRelation implements ITxRelation {
|
||||
|
||||
/** The loader. */
|
||||
final FtrDbLoader loader;
|
||||
|
||||
/** The scv relation. */
|
||||
final FtrRelation scvRelation;
|
||||
|
||||
/**
|
||||
* Instantiates a new tx relation.
|
||||
*
|
||||
* @param loader the loader
|
||||
* @param scvRelation the scv relation
|
||||
*/
|
||||
public TxRelation(FtrDbLoader loader, FtrRelation scvRelation) {
|
||||
this.loader = loader;
|
||||
this.scvRelation = scvRelation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the relation type.
|
||||
*
|
||||
* @return the relation type
|
||||
*/
|
||||
@Override
|
||||
public RelationType getRelationType() {
|
||||
return scvRelation.relationType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the source.
|
||||
*
|
||||
* @return the source
|
||||
*/
|
||||
@Override
|
||||
public ITx getSource() {
|
||||
return loader.getTransaction(scvRelation.source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the target.
|
||||
*
|
||||
* @return the target
|
||||
*/
|
||||
@Override
|
||||
public ITx getTarget() {
|
||||
return loader.getTransaction(scvRelation.target);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2023 MINRES Technologies GmbH
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IT Just working - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.minres.scviewer.database.ftr;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.minres.scviewer.database.IWaveform;
|
||||
import com.minres.scviewer.database.InputFormatException;
|
||||
|
||||
/**
|
||||
* The Class TxStream.
|
||||
*/
|
||||
class TxStream extends AbstractTxStream {
|
||||
|
||||
/** The kind. */
|
||||
final String kind;
|
||||
|
||||
final ArrayList<Long> fileOffsets = new ArrayList<>();
|
||||
|
||||
final ArrayList<byte[]> chunks = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Instantiates a new tx stream.
|
||||
*
|
||||
* @param loader the loader
|
||||
* @param id the id
|
||||
* @param name the name
|
||||
* @param kind the kind
|
||||
*/
|
||||
TxStream(FtrDbLoader loader, Long id, String name, String kind) {
|
||||
super(loader, id, name);
|
||||
this.kind = kind;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if is same.
|
||||
*
|
||||
* @param other the other
|
||||
* @return true, if is same
|
||||
*/
|
||||
@Override
|
||||
public boolean isSame(IWaveform other) {
|
||||
return (other instanceof TxStream && this.getId() == other.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the kind.
|
||||
*
|
||||
* @return the kind
|
||||
*/
|
||||
@Override
|
||||
public String getKind() {
|
||||
return kind;
|
||||
}
|
||||
|
||||
public List<byte[]> getChunks() throws InputFormatException {
|
||||
if(chunks.size()==0) {
|
||||
chunks.addAll(loader.getChunksAtOffsets(fileOffsets));
|
||||
}
|
||||
return chunks;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* JACOB - CBOR implementation in Java.
|
||||
*
|
||||
* (C) Copyright - 2013 - J.W. Janssen <j.w.janssen@lxtreme.nl>
|
||||
*
|
||||
* Licensed under Apache License v2.0.
|
||||
*/
|
||||
package jacob;
|
||||
|
||||
/**
|
||||
* Constant values used by the CBOR format.
|
||||
*/
|
||||
public interface CborConstants {
|
||||
/** Major type 0: unsigned integers. */
|
||||
int TYPE_UNSIGNED_INTEGER = 0x00;
|
||||
/** Major type 1: negative integers. */
|
||||
int TYPE_NEGATIVE_INTEGER = 0x01;
|
||||
/** Major type 2: byte string. */
|
||||
int TYPE_BYTE_STRING = 0x02;
|
||||
/** Major type 3: text/UTF8 string. */
|
||||
int TYPE_TEXT_STRING = 0x03;
|
||||
/** Major type 4: array of items. */
|
||||
int TYPE_ARRAY = 0x04;
|
||||
/** Major type 5: map of pairs. */
|
||||
int TYPE_MAP = 0x05;
|
||||
/** Major type 6: semantic tags. */
|
||||
int TYPE_TAG = 0x06;
|
||||
/** Major type 7: floating point, simple data types. */
|
||||
int TYPE_FLOAT_SIMPLE = 0x07;
|
||||
|
||||
/** Denotes a one-byte value (uint8). */
|
||||
int ONE_BYTE = 0x18;
|
||||
/** Denotes a two-byte value (uint16). */
|
||||
int TWO_BYTES = 0x19;
|
||||
/** Denotes a four-byte value (uint32). */
|
||||
int FOUR_BYTES = 0x1a;
|
||||
/** Denotes a eight-byte value (uint64). */
|
||||
int EIGHT_BYTES = 0x1b;
|
||||
|
||||
/** The CBOR-encoded boolean <code>false</code> value (encoded as "simple value": {@link #MT_SIMPLE}). */
|
||||
int FALSE = 0x14;
|
||||
/** The CBOR-encoded boolean <code>true</code> value (encoded as "simple value": {@link #MT_SIMPLE}). */
|
||||
int TRUE = 0x15;
|
||||
/** The CBOR-encoded <code>null</code> value (encoded as "simple value": {@link #MT_SIMPLE}). */
|
||||
int NULL = 0x16;
|
||||
/** The CBOR-encoded "undefined" value (encoded as "simple value": {@link #MT_SIMPLE}). */
|
||||
int UNDEFINED = 0x17;
|
||||
/** Denotes a half-precision float (two-byte IEEE 754, see {@link #MT_FLOAT}). */
|
||||
int HALF_PRECISION_FLOAT = 0x19;
|
||||
/** Denotes a single-precision float (four-byte IEEE 754, see {@link #MT_FLOAT}). */
|
||||
int SINGLE_PRECISION_FLOAT = 0x1a;
|
||||
/** Denotes a double-precision float (eight-byte IEEE 754, see {@link #MT_FLOAT}). */
|
||||
int DOUBLE_PRECISION_FLOAT = 0x1b;
|
||||
/** The CBOR-encoded "break" stop code for unlimited arrays/maps. */
|
||||
int BREAK = 0x1f;
|
||||
|
||||
/** Semantic tag value describing date/time values in the standard format (UTF8 string, RFC3339). */
|
||||
int TAG_STANDARD_DATE_TIME = 0;
|
||||
/** Semantic tag value describing date/time values as Epoch timestamp (numeric, RFC3339). */
|
||||
int TAG_EPOCH_DATE_TIME = 1;
|
||||
/** Semantic tag value describing a positive big integer value (byte string). */
|
||||
int TAG_POSITIVE_BIGINT = 2;
|
||||
/** Semantic tag value describing a negative big integer value (byte string). */
|
||||
int TAG_NEGATIVE_BIGINT = 3;
|
||||
/** Semantic tag value describing a decimal fraction value (two-element array, base 10). */
|
||||
int TAG_DECIMAL_FRACTION = 4;
|
||||
/** Semantic tag value describing a big decimal value (two-element array, base 2). */
|
||||
int TAG_BIGDECIMAL = 5;
|
||||
/** Semantic tag value describing an expected conversion to base64url encoding. */
|
||||
int TAG_EXPECTED_BASE64_URL_ENCODED = 21;
|
||||
/** Semantic tag value describing an expected conversion to base64 encoding. */
|
||||
int TAG_EXPECTED_BASE64_ENCODED = 22;
|
||||
/** Semantic tag value describing an expected conversion to base16 encoding. */
|
||||
int TAG_EXPECTED_BASE16_ENCODED = 23;
|
||||
/** Semantic tag value describing an encoded CBOR data item (byte string). */
|
||||
int TAG_CBOR_ENCODED = 24;
|
||||
/** Semantic tag value describing an URL (UTF8 string). */
|
||||
int TAG_URI = 32;
|
||||
/** Semantic tag value describing a base64url encoded string (UTF8 string). */
|
||||
int TAG_BASE64_URL_ENCODED = 33;
|
||||
/** Semantic tag value describing a base64 encoded string (UTF8 string). */
|
||||
int TAG_BASE64_ENCODED = 34;
|
||||
/** Semantic tag value describing a regular expression string (UTF8 string, PCRE). */
|
||||
int TAG_REGEXP = 35;
|
||||
/** Semantic tag value describing a MIME message (UTF8 string, RFC2045). */
|
||||
int TAG_MIME_MESSAGE = 36;
|
||||
/** Semantic tag value describing CBOR content. */
|
||||
int TAG_CBOR_MARKER = 55799;
|
||||
}
|
@ -0,0 +1,515 @@
|
||||
/*
|
||||
* JACOB - CBOR implementation in Java.
|
||||
*
|
||||
* (C) Copyright - 2013 - J.W. Janssen <j.w.janssen@lxtreme.nl>
|
||||
*/
|
||||
package jacob;
|
||||
|
||||
import static jacob.CborConstants.*;
|
||||
import static jacob.CborType.*;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PushbackInputStream;
|
||||
|
||||
/**
|
||||
* Provides a decoder capable of handling CBOR encoded data from a {@link InputStream}.
|
||||
*/
|
||||
public class CborDecoder {
|
||||
protected final PushbackInputStream m_is;
|
||||
|
||||
protected final int total_avail;
|
||||
|
||||
static int getAvailableBytes(PushbackInputStream is) {
|
||||
try {
|
||||
return is.available();
|
||||
} catch (IOException e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Creates a new {@link CborDecoder} instance.
|
||||
*
|
||||
* @param is the actual input stream to read the CBOR-encoded data from, cannot be <code>null</code>.
|
||||
*/
|
||||
public CborDecoder(InputStream is) {
|
||||
if (is == null) {
|
||||
throw new IllegalArgumentException("InputStream cannot be null!");
|
||||
}
|
||||
m_is = (is instanceof PushbackInputStream) ? (PushbackInputStream) is : new PushbackInputStream(is);
|
||||
total_avail = getAvailableBytes(m_is);
|
||||
}
|
||||
|
||||
private static void fail(String msg, Object... args) throws IOException {
|
||||
throw new IOException(String.format(msg, args));
|
||||
}
|
||||
|
||||
private static String lengthToString(int len) {
|
||||
return (len < 0) ? "no payload" : (len == ONE_BYTE) ? "one byte" : (len == TWO_BYTES) ? "two bytes"
|
||||
: (len == FOUR_BYTES) ? "four bytes" : (len == EIGHT_BYTES) ? "eight bytes" : "(unknown)";
|
||||
}
|
||||
|
||||
public long getPos() {
|
||||
try {
|
||||
return total_avail-m_is.available();
|
||||
} catch (IOException e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Peeks in the input stream for the upcoming type.
|
||||
*
|
||||
* @return the upcoming type in the stream, or <code>null</code> in case of an end-of-stream.
|
||||
* @throws IOException in case of I/O problems reading the CBOR-type from the underlying input stream.
|
||||
*/
|
||||
public CborType peekType() throws IOException {
|
||||
int p = m_is.read();
|
||||
if (p < 0) {
|
||||
// EOF, nothing to peek at...
|
||||
return null;
|
||||
}
|
||||
m_is.unread(p);
|
||||
return valueOf(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prolog to reading an array value in CBOR format.
|
||||
*
|
||||
* @return the number of elements in the array to read, or <tt>-1</tt> in case of infinite-length arrays.
|
||||
* @throws IOException in case of I/O problems reading the CBOR-encoded value from the underlying input stream.
|
||||
*/
|
||||
public long readArrayLength() throws IOException {
|
||||
return readMajorTypeWithSize(TYPE_ARRAY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a boolean value in CBOR format.
|
||||
*
|
||||
* @return the read boolean.
|
||||
* @throws IOException in case of I/O problems reading the CBOR-encoded value from the underlying input stream.
|
||||
*/
|
||||
public boolean readBoolean() throws IOException {
|
||||
int b = readMajorType(TYPE_FLOAT_SIMPLE);
|
||||
if (b != FALSE && b != TRUE) {
|
||||
fail("Unexpected boolean value: %d!", b);
|
||||
}
|
||||
return b == TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a "break"/stop value in CBOR format.
|
||||
*
|
||||
* @return always <code>null</code>.
|
||||
* @throws IOException in case of I/O problems reading the CBOR-encoded value from the underlying input stream.
|
||||
*/
|
||||
public Object readBreak() throws IOException {
|
||||
readMajorTypeExact(TYPE_FLOAT_SIMPLE, BREAK);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a byte string value in CBOR format.
|
||||
*
|
||||
* @return the read byte string, never <code>null</code>. In case the encoded string has a length of <tt>0</tt>, an empty string is returned.
|
||||
* @throws IOException in case of I/O problems reading the CBOR-encoded value from the underlying input stream.
|
||||
*/
|
||||
public byte[] readByteString() throws IOException {
|
||||
long len = readMajorTypeWithSize(TYPE_BYTE_STRING);
|
||||
if (len < 0) {
|
||||
fail("Infinite-length byte strings not supported!");
|
||||
}
|
||||
if (len > Integer.MAX_VALUE) {
|
||||
fail("String length too long!");
|
||||
}
|
||||
return readFully(new byte[(int) len]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prolog to reading a byte string value in CBOR format.
|
||||
*
|
||||
* @return the number of bytes in the string to read, or <tt>-1</tt> in case of infinite-length strings.
|
||||
* @throws IOException in case of I/O problems reading the CBOR-encoded value from the underlying input stream.
|
||||
*/
|
||||
public long readByteStringLength() throws IOException {
|
||||
return readMajorTypeWithSize(TYPE_BYTE_STRING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a double-precision float value in CBOR format.
|
||||
*
|
||||
* @return the read double value, values from {@link Float#MIN_VALUE} to {@link Float#MAX_VALUE} are supported.
|
||||
* @throws IOException in case of I/O problems reading the CBOR-encoded value from the underlying input stream.
|
||||
*/
|
||||
public double readDouble() throws IOException {
|
||||
readMajorTypeExact(TYPE_FLOAT_SIMPLE, DOUBLE_PRECISION_FLOAT);
|
||||
|
||||
return Double.longBitsToDouble(readUInt64());
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a single-precision float value in CBOR format.
|
||||
*
|
||||
* @return the read float value, values from {@link Float#MIN_VALUE} to {@link Float#MAX_VALUE} are supported.
|
||||
* @throws IOException in case of I/O problems reading the CBOR-encoded value from the underlying input stream.
|
||||
*/
|
||||
public float readFloat() throws IOException {
|
||||
readMajorTypeExact(TYPE_FLOAT_SIMPLE, SINGLE_PRECISION_FLOAT);
|
||||
|
||||
return Float.intBitsToFloat((int) readUInt32());
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a half-precision float value in CBOR format.
|
||||
*
|
||||
* @return the read half-precision float value, values from {@link Float#MIN_VALUE} to {@link Float#MAX_VALUE} are supported.
|
||||
* @throws IOException in case of I/O problems reading the CBOR-encoded value from the underlying input stream.
|
||||
*/
|
||||
public double readHalfPrecisionFloat() throws IOException {
|
||||
readMajorTypeExact(TYPE_FLOAT_SIMPLE, HALF_PRECISION_FLOAT);
|
||||
|
||||
int half = readUInt16();
|
||||
int exp = (half >> 10) & 0x1f;
|
||||
int mant = half & 0x3ff;
|
||||
|
||||
double val;
|
||||
if (exp == 0) {
|
||||
val = mant * Math.pow(2, -24);
|
||||
} else if (exp != 31) {
|
||||
val = (mant + 1024) * Math.pow(2, exp - 25);
|
||||
} else if (mant != 0) {
|
||||
val = Double.NaN;
|
||||
} else {
|
||||
val = Double.POSITIVE_INFINITY;
|
||||
}
|
||||
|
||||
return ((half & 0x8000) == 0) ? val : -val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a signed or unsigned integer value in CBOR format.
|
||||
*
|
||||
* @return the read integer value, values from {@link Long#MIN_VALUE} to {@link Long#MAX_VALUE} are supported.
|
||||
* @throws IOException in case of I/O problems reading the CBOR-encoded value from the underlying input stream.
|
||||
*/
|
||||
public long readInt() throws IOException {
|
||||
int ib = m_is.read();
|
||||
|
||||
// in case of negative integers, extends the sign to all bits; otherwise zero...
|
||||
long ui = expectIntegerType(ib);
|
||||
// in case of negative integers does a ones complement
|
||||
return ui ^ readUInt(ib & 0x1f, false /* breakAllowed */);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a signed or unsigned 16-bit integer value in CBOR format.
|
||||
*
|
||||
* @read the small integer value, values from <tt>[-65536..65535]</tt> are supported.
|
||||
* @throws IOException in case of I/O problems reading the CBOR-encoded value from the underlying output stream.
|
||||
*/
|
||||
public int readInt16() throws IOException {
|
||||
int ib = m_is.read();
|
||||
|
||||
// in case of negative integers, extends the sign to all bits; otherwise zero...
|
||||
long ui = expectIntegerType(ib);
|
||||
// in case of negative integers does a ones complement
|
||||
return (int) (ui ^ readUIntExact(TWO_BYTES, ib & 0x1f));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a signed or unsigned 32-bit integer value in CBOR format.
|
||||
*
|
||||
* @read the small integer value, values in the range <tt>[-4294967296..4294967295]</tt> are supported.
|
||||
* @throws IOException in case of I/O problems reading the CBOR-encoded value from the underlying output stream.
|
||||
*/
|
||||
public long readInt32() throws IOException {
|
||||
int ib = m_is.read();
|
||||
|
||||
// in case of negative integers, extends the sign to all bits; otherwise zero...
|
||||
long ui = expectIntegerType(ib);
|
||||
// in case of negative integers does a ones complement
|
||||
return ui ^ readUIntExact(FOUR_BYTES, ib & 0x1f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a signed or unsigned 64-bit integer value in CBOR format.
|
||||
*
|
||||
* @read the small integer value, values from {@link Long#MIN_VALUE} to {@link Long#MAX_VALUE} are supported.
|
||||
* @throws IOException in case of I/O problems reading the CBOR-encoded value from the underlying output stream.
|
||||
*/
|
||||
public long readInt64() throws IOException {
|
||||
int ib = m_is.read();
|
||||
|
||||
// in case of negative integers, extends the sign to all bits; otherwise zero...
|
||||
long ui = expectIntegerType(ib);
|
||||
// in case of negative integers does a ones complement
|
||||
return ui ^ readUIntExact(EIGHT_BYTES, ib & 0x1f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a signed or unsigned 8-bit integer value in CBOR format.
|
||||
*
|
||||
* @read the small integer value, values in the range <tt>[-256..255]</tt> are supported.
|
||||
* @throws IOException in case of I/O problems reading the CBOR-encoded value from the underlying output stream.
|
||||
*/
|
||||
public int readInt8() throws IOException {
|
||||
int ib = m_is.read();
|
||||
|
||||
// in case of negative integers, extends the sign to all bits; otherwise zero...
|
||||
long ui = expectIntegerType(ib);
|
||||
// in case of negative integers does a ones complement
|
||||
return (int) (ui ^ readUIntExact(ONE_BYTE, ib & 0x1f));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prolog to reading a map of key-value pairs in CBOR format.
|
||||
*
|
||||
* @return the number of entries in the map, >= 0.
|
||||
* @throws IOException in case of I/O problems reading the CBOR-encoded value from the underlying input stream.
|
||||
*/
|
||||
public long readMapLength() throws IOException {
|
||||
return readMajorTypeWithSize(TYPE_MAP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a <code>null</code>-value in CBOR format.
|
||||
*
|
||||
* @return always <code>null</code>.
|
||||
* @throws IOException in case of I/O problems reading the CBOR-encoded value from the underlying input stream.
|
||||
*/
|
||||
public Object readNull() throws IOException {
|
||||
readMajorTypeExact(TYPE_FLOAT_SIMPLE, NULL);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a single byte value in CBOR format.
|
||||
*
|
||||
* @return the read byte value.
|
||||
* @throws IOException in case of I/O problems reading the CBOR-encoded value from the underlying input stream.
|
||||
*/
|
||||
public byte readSimpleValue() throws IOException {
|
||||
readMajorTypeExact(TYPE_FLOAT_SIMPLE, ONE_BYTE);
|
||||
return (byte) readUInt8();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a signed or unsigned small (<= 23) integer value in CBOR format.
|
||||
*
|
||||
* @read the small integer value, values in the range <tt>[-24..23]</tt> are supported.
|
||||
* @throws IOException in case of I/O problems reading the CBOR-encoded value from the underlying output stream.
|
||||
*/
|
||||
public int readSmallInt() throws IOException {
|
||||
int ib = m_is.read();
|
||||
|
||||
// in case of negative integers, extends the sign to all bits; otherwise zero...
|
||||
long ui = expectIntegerType(ib);
|
||||
// in case of negative integers does a ones complement
|
||||
return (int) (ui ^ readUIntExact(-1, ib & 0x1f));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a semantic tag value in CBOR format.
|
||||
*
|
||||
* @return the read tag value.
|
||||
* @throws IOException in case of I/O problems reading the CBOR-encoded value from the underlying input stream.
|
||||
*/
|
||||
public long readTag() throws IOException {
|
||||
return readUInt(readMajorType(TYPE_TAG), false /* breakAllowed */);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an UTF-8 encoded string value in CBOR format.
|
||||
*
|
||||
* @return the read UTF-8 encoded string, never <code>null</code>. In case the encoded string has a length of <tt>0</tt>, an empty string is returned.
|
||||
* @throws IOException in case of I/O problems reading the CBOR-encoded value from the underlying input stream.
|
||||
*/
|
||||
public String readTextString() throws IOException {
|
||||
long len = readMajorTypeWithSize(TYPE_TEXT_STRING);
|
||||
if (len < 0) {
|
||||
fail("Infinite-length text strings not supported!");
|
||||
}
|
||||
if (len > Integer.MAX_VALUE) {
|
||||
fail("String length too long!");
|
||||
}
|
||||
return new String(readFully(new byte[(int) len]), "UTF-8");
|
||||
}
|
||||
|
||||
/**
|
||||
* Prolog to reading an UTF-8 encoded string value in CBOR format.
|
||||
*
|
||||
* @return the length of the string to read, or <tt>-1</tt> in case of infinite-length strings.
|
||||
* @throws IOException in case of I/O problems reading the CBOR-encoded value from the underlying input stream.
|
||||
*/
|
||||
public long readTextStringLength() throws IOException {
|
||||
return readMajorTypeWithSize(TYPE_TEXT_STRING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an undefined value in CBOR format.
|
||||
*
|
||||
* @return always <code>null</code>.
|
||||
* @throws IOException in case of I/O problems reading the CBOR-encoded value from the underlying input stream.
|
||||
*/
|
||||
public Object readUndefined() throws IOException {
|
||||
readMajorTypeExact(TYPE_FLOAT_SIMPLE, UNDEFINED);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next major type from the underlying input stream, and verifies whether it matches the given expectation.
|
||||
*
|
||||
* @param majorType the expected major type, cannot be <code>null</code> (unchecked).
|
||||
* @return either <tt>-1</tt> if the major type was an signed integer, or <tt>0</tt> otherwise.
|
||||
* @throws IOException in case of I/O problems reading the CBOR-encoded value from the underlying input stream.
|
||||
*/
|
||||
protected long expectIntegerType(int ib) throws IOException {
|
||||
int majorType = ((ib & 0xFF) >>> 5);
|
||||
if ((majorType != TYPE_UNSIGNED_INTEGER) && (majorType != TYPE_NEGATIVE_INTEGER)) {
|
||||
fail("Unexpected type: %s, expected type %s or %s!", getName(majorType), getName(TYPE_UNSIGNED_INTEGER),
|
||||
getName(TYPE_NEGATIVE_INTEGER));
|
||||
}
|
||||
return -majorType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next major type from the underlying input stream, and verifies whether it matches the given expectation.
|
||||
*
|
||||
* @param majorType the expected major type, cannot be <code>null</code> (unchecked).
|
||||
* @return the read subtype, or payload, of the read major type.
|
||||
* @throws IOException in case of I/O problems reading the CBOR-encoded value from the underlying input stream.
|
||||
*/
|
||||
protected int readMajorType(int majorType) throws IOException {
|
||||
int ib = m_is.read();
|
||||
if (majorType != ((ib >>> 5) & 0x07)) {
|
||||
fail("Unexpected type: %s, expected: %s!", getName(ib), getName(majorType));
|
||||
}
|
||||
return ib & 0x1F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next major type from the underlying input stream, and verifies whether it matches the given expectations.
|
||||
*
|
||||
* @param majorType the expected major type, cannot be <code>null</code> (unchecked);
|
||||
* @param subtype the expected subtype.
|
||||
* @throws IOException in case of I/O problems reading the CBOR-encoded value from the underlying input stream.
|
||||
*/
|
||||
protected void readMajorTypeExact(int majorType, int subtype) throws IOException {
|
||||
int st = readMajorType(majorType);
|
||||
if ((st ^ subtype) != 0) {
|
||||
fail("Unexpected subtype: %d, expected: %d!", st, subtype);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next major type from the underlying input stream, verifies whether it matches the given expectation, and decodes the payload into a size.
|
||||
*
|
||||
* @param majorType the expected major type, cannot be <code>null</code> (unchecked).
|
||||
* @return the number of succeeding bytes, >= 0, or <tt>-1</tt> if an infinite-length type is read.
|
||||
* @throws IOException in case of I/O problems reading the CBOR-encoded value from the underlying input stream.
|
||||
*/
|
||||
protected long readMajorTypeWithSize(int majorType) throws IOException {
|
||||
return readUInt(readMajorType(majorType), true /* breakAllowed */);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an unsigned integer with a given length-indicator.
|
||||
*
|
||||
* @param length the length indicator to use;
|
||||
* @return the read unsigned integer, as long value.
|
||||
* @throws IOException in case of I/O problems reading the unsigned integer from the underlying input stream.
|
||||
*/
|
||||
protected long readUInt(int length, boolean breakAllowed) throws IOException {
|
||||
long result = -1;
|
||||
if (length < ONE_BYTE) {
|
||||
result = length;
|
||||
} else if (length == ONE_BYTE) {
|
||||
result = readUInt8();
|
||||
} else if (length == TWO_BYTES) {
|
||||
result = readUInt16();
|
||||
} else if (length == FOUR_BYTES) {
|
||||
result = readUInt32();
|
||||
} else if (length == EIGHT_BYTES) {
|
||||
result = readUInt64();
|
||||
} else if (breakAllowed && length == BREAK) {
|
||||
return -1;
|
||||
}
|
||||
if (result < 0) {
|
||||
fail("Not well-formed CBOR integer found, invalid length: %d!", result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an unsigned 16-bit integer value
|
||||
*
|
||||
* @return value the read value, values from {@link Long#MIN_VALUE} to {@link Long#MAX_VALUE} are supported.
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
protected int readUInt16() throws IOException {
|
||||
byte[] buf = readFully(new byte[2]);
|
||||
return (buf[0] & 0xFF) << 8 | (buf[1] & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an unsigned 32-bit integer value
|
||||
*
|
||||
* @return value the read value, values from {@link Long#MIN_VALUE} to {@link Long#MAX_VALUE} are supported.
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
protected long readUInt32() throws IOException {
|
||||
byte[] buf = readFully(new byte[4]);
|
||||
return ((buf[0] & 0xFF) << 24 | (buf[1] & 0xFF) << 16 | (buf[2] & 0xFF) << 8 | (buf[3] & 0xFF)) & 0xffffffffL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an unsigned 64-bit integer value
|
||||
*
|
||||
* @return value the read value, values from {@link Long#MIN_VALUE} to {@link Long#MAX_VALUE} are supported.
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
protected long readUInt64() throws IOException {
|
||||
byte[] buf = readFully(new byte[8]);
|
||||
return (buf[0] & 0xFFL) << 56 | (buf[1] & 0xFFL) << 48 | (buf[2] & 0xFFL) << 40 | (buf[3] & 0xFFL) << 32 | //
|
||||
(buf[4] & 0xFFL) << 24 | (buf[5] & 0xFFL) << 16 | (buf[6] & 0xFFL) << 8 | (buf[7] & 0xFFL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an unsigned 8-bit integer value
|
||||
*
|
||||
* @return value the read value, values from {@link Long#MIN_VALUE} to {@link Long#MAX_VALUE} are supported.
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
protected int readUInt8() throws IOException {
|
||||
return m_is.read() & 0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an unsigned integer with a given length-indicator.
|
||||
*
|
||||
* @param length the length indicator to use;
|
||||
* @return the read unsigned integer, as long value.
|
||||
* @throws IOException in case of I/O problems reading the unsigned integer from the underlying input stream.
|
||||
*/
|
||||
protected long readUIntExact(int expectedLength, int length) throws IOException {
|
||||
if (((expectedLength == -1) && (length >= ONE_BYTE)) || ((expectedLength >= 0) && (length != expectedLength))) {
|
||||
fail("Unexpected payload/length! Expected %s, but got %s.", lengthToString(expectedLength),
|
||||
lengthToString(length));
|
||||
}
|
||||
return readUInt(length, false /* breakAllowed */);
|
||||
}
|
||||
|
||||
private byte[] readFully(byte[] buf) throws IOException {
|
||||
int len = buf.length;
|
||||
int n = 0, off = 0;
|
||||
while (n < len) {
|
||||
int count = m_is.read(buf, off + n, len - n);
|
||||
if (count < 0) {
|
||||
throw new EOFException();
|
||||
}
|
||||
n += count;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
}
|
@ -0,0 +1,488 @@
|
||||
/*
|
||||
* JACOB - CBOR implementation in Java.
|
||||
*
|
||||
* (C) Copyright - 2013 - J.W. Janssen <j.w.janssen@lxtreme.nl>
|
||||
*
|
||||
* Licensed under Apache License v2.0.
|
||||
*/
|
||||
package jacob;
|
||||
|
||||
import static jacob.CborConstants.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Provides an encoder capable of encoding data into CBOR format to a given {@link OutputStream}.
|
||||
*/
|
||||
public class CborEncoder {
|
||||
private static final int NEG_INT_MASK = TYPE_NEGATIVE_INTEGER << 5;
|
||||
|
||||
private final OutputStream m_os;
|
||||
|
||||
/**
|
||||
* Creates a new {@link CborEncoder} instance.
|
||||
*
|
||||
* @param os the actual output stream to write the CBOR-encoded data to, cannot be <code>null</code>.
|
||||
*/
|
||||
public CborEncoder(OutputStream os) {
|
||||
if (os == null) {
|
||||
throw new IllegalArgumentException("OutputStream cannot be null!");
|
||||
}
|
||||
m_os = os;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interprets a given float-value as a half-precision float value and
|
||||
* converts it to its raw integer form, as defined in IEEE 754.
|
||||
* <p>
|
||||
* Taken from: <a href="http://stackoverflow.com/a/6162687/229140">this Stack Overflow answer</a>.
|
||||
* </p>
|
||||
*
|
||||
* @param fval the value to convert.
|
||||
* @return the raw integer representation of the given float value.
|
||||
*/
|
||||
static int halfPrecisionToRawIntBits(float fval) {
|
||||
int fbits = Float.floatToIntBits(fval);
|
||||
int sign = (fbits >>> 16) & 0x8000;
|
||||
int val = (fbits & 0x7fffffff) + 0x1000;
|
||||
|
||||
// might be or become NaN/Inf
|
||||
if (val >= 0x47800000) {
|
||||
if ((fbits & 0x7fffffff) >= 0x47800000) { // is or must become NaN/Inf
|
||||
if (val < 0x7f800000) {
|
||||
// was value but too large, make it +/-Inf
|
||||
return sign | 0x7c00;
|
||||
}
|
||||
return sign | 0x7c00 | (fbits & 0x007fffff) >>> 13; // keep NaN (and Inf) bits
|
||||
}
|
||||
return sign | 0x7bff; // unrounded not quite Inf
|
||||
}
|
||||
if (val >= 0x38800000) {
|
||||
// remains normalized value
|
||||
return sign | val - 0x38000000 >>> 13; // exp - 127 + 15
|
||||
}
|
||||
if (val < 0x33000000) {
|
||||
// too small for subnormal
|
||||
return sign; // becomes +/-0
|
||||
}
|
||||
|
||||
val = (fbits & 0x7fffffff) >>> 23;
|
||||
// add subnormal bit, round depending on cut off and div by 2^(1-(exp-127+15)) and >> 13 | exp=0
|
||||
return sign | ((fbits & 0x7fffff | 0x800000) + (0x800000 >>> val - 102) >>> 126 - val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the start of an indefinite-length array.
|
||||
* <p>
|
||||
* After calling this method, one is expected to write the given number of array elements, which can be of any type. No length checks are performed.<br/>
|
||||
* After all array elements are written, one should write a single break value to end the array, see {@link #writeBreak()}.
|
||||
* </p>
|
||||
*
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
public void writeArrayStart() throws IOException {
|
||||
writeSimpleType(TYPE_ARRAY, BREAK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the start of a definite-length array.
|
||||
* <p>
|
||||
* After calling this method, one is expected to write the given number of array elements, which can be of any type. No length checks are performed.
|
||||
* </p>
|
||||
*
|
||||
* @param length the number of array elements to write, should >= 0.
|
||||
* @throws IllegalArgumentException in case the given length was negative;
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
public void writeArrayStart(int length) throws IOException {
|
||||
if (length < 0) {
|
||||
throw new IllegalArgumentException("Invalid array-length!");
|
||||
}
|
||||
writeType(TYPE_ARRAY, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a boolean value in canonical CBOR format.
|
||||
*
|
||||
* @param value the boolean to write.
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
public void writeBoolean(boolean value) throws IOException {
|
||||
writeSimpleType(TYPE_FLOAT_SIMPLE, value ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a "break" stop-value in canonical CBOR format.
|
||||
*
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
public void writeBreak() throws IOException {
|
||||
writeSimpleType(TYPE_FLOAT_SIMPLE, BREAK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a byte string in canonical CBOR-format.
|
||||
*
|
||||
* @param value the byte string to write, can be <code>null</code> in which case a byte-string of length <tt>0</tt> is written.
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
public void writeByteString(byte[] bytes) throws IOException {
|
||||
writeString(TYPE_BYTE_STRING, bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the start of an indefinite-length byte string.
|
||||
* <p>
|
||||
* After calling this method, one is expected to write the given number of string parts. No length checks are performed.<br/>
|
||||
* After all string parts are written, one should write a single break value to end the string, see {@link #writeBreak()}.
|
||||
* </p>
|
||||
*
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
public void writeByteStringStart() throws IOException {
|
||||
writeSimpleType(TYPE_BYTE_STRING, BREAK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a double-precision float value in canonical CBOR format.
|
||||
*
|
||||
* @param value the value to write, values from {@link Double#MIN_VALUE} to {@link Double#MAX_VALUE} are supported.
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
public void writeDouble(double value) throws IOException {
|
||||
writeUInt64(TYPE_FLOAT_SIMPLE << 5, Double.doubleToRawLongBits(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a single-precision float value in canonical CBOR format.
|
||||
*
|
||||
* @param value the value to write, values from {@link Float#MIN_VALUE} to {@link Float#MAX_VALUE} are supported.
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
public void writeFloat(float value) throws IOException {
|
||||
writeUInt32(TYPE_FLOAT_SIMPLE << 5, Float.floatToRawIntBits(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a half-precision float value in canonical CBOR format.
|
||||
*
|
||||
* @param value the value to write, values from {@link Float#MIN_VALUE} to {@link Float#MAX_VALUE} are supported.
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
public void writeHalfPrecisionFloat(float value) throws IOException {
|
||||
writeUInt16(TYPE_FLOAT_SIMPLE << 5, halfPrecisionToRawIntBits(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a signed or unsigned integer value in canonical CBOR format, that is, tries to encode it in a little bytes as possible..
|
||||
*
|
||||
* @param value the value to write, values from {@link Long#MIN_VALUE} to {@link Long#MAX_VALUE} are supported.
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
public void writeInt(long value) throws IOException {
|
||||
// extends the sign over all bits...
|
||||
long sign = value >> 63;
|
||||
// in case value is negative, this bit should be set...
|
||||
int mt = (int) (sign & NEG_INT_MASK);
|
||||
// complement negative value...
|
||||
value = (sign ^ value);
|
||||
|
||||
writeUInt(mt, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a signed or unsigned 16-bit integer value in CBOR format.
|
||||
*
|
||||
* @param value the value to write, values from <tt>[-65536..65535]</tt> are supported.
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
public void writeInt16(int value) throws IOException {
|
||||
// extends the sign over all bits...
|
||||
int sign = value >> 31;
|
||||
// in case value is negative, this bit should be set...
|
||||
int mt = (int) (sign & NEG_INT_MASK);
|
||||
// complement negative value...
|
||||
writeUInt16(mt, (sign ^ value) & 0xffff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a signed or unsigned 32-bit integer value in CBOR format.
|
||||
*
|
||||
* @param value the value to write, values in the range <tt>[-4294967296..4294967295]</tt> are supported.
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
public void writeInt32(long value) throws IOException {
|
||||
// extends the sign over all bits...
|
||||
long sign = value >> 63;
|
||||
// in case value is negative, this bit should be set...
|
||||
int mt = (int) (sign & NEG_INT_MASK);
|
||||
// complement negative value...
|
||||
writeUInt32(mt, (int) ((sign ^ value) & 0xffffffffL));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a signed or unsigned 64-bit integer value in CBOR format.
|
||||
*
|
||||
* @param value the value to write, values from {@link Long#MIN_VALUE} to {@link Long#MAX_VALUE} are supported.
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
public void writeInt64(long value) throws IOException {
|
||||
// extends the sign over all bits...
|
||||
long sign = value >> 63;
|
||||
// in case value is negative, this bit should be set...
|
||||
int mt = (int) (sign & NEG_INT_MASK);
|
||||
// complement negative value...
|
||||
writeUInt64(mt, sign ^ value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a signed or unsigned 8-bit integer value in CBOR format.
|
||||
*
|
||||
* @param value the value to write, values in the range <tt>[-256..255]</tt> are supported.
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
public void writeInt8(int value) throws IOException {
|
||||
// extends the sign over all bits...
|
||||
int sign = value >> 31;
|
||||
// in case value is negative, this bit should be set...
|
||||
int mt = (int) (sign & NEG_INT_MASK);
|
||||
// complement negative value...
|
||||
writeUInt8(mt, (sign ^ value) & 0xff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the start of an indefinite-length map.
|
||||
* <p>
|
||||
* After calling this method, one is expected to write any number of map entries, as separate key and value. Keys and values can both be of any type. No length checks are performed.<br/>
|
||||
* After all map entries are written, one should write a single break value to end the map, see {@link #writeBreak()}.
|
||||
* </p>
|
||||
*
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
public void writeMapStart() throws IOException {
|
||||
writeSimpleType(TYPE_MAP, BREAK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the start of a finite-length map.
|
||||
* <p>
|
||||
* After calling this method, one is expected to write any number of map entries, as separate key and value. Keys and values can both be of any type. No length checks are performed.
|
||||
* </p>
|
||||
*
|
||||
* @param length the number of map entries to write, should >= 0.
|
||||
* @throws IllegalArgumentException in case the given length was negative;
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
public void writeMapStart(int length) throws IOException {
|
||||
if (length < 0) {
|
||||
throw new IllegalArgumentException("Invalid length of map!");
|
||||
}
|
||||
writeType(TYPE_MAP, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>null</code> value in canonical CBOR format.
|
||||
*
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
public void writeNull() throws IOException {
|
||||
writeSimpleType(TYPE_FLOAT_SIMPLE, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a simple value, i.e., an "atom" or "constant" value in canonical CBOR format.
|
||||
*
|
||||
* @param value the (unsigned byte) value to write, values from <tt>32</tt> to <tt>255</tt> are supported (though not enforced).
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
public void writeSimpleValue(byte simpleValue) throws IOException {
|
||||
// convert to unsigned value...
|
||||
int value = (simpleValue & 0xff);
|
||||
writeType(TYPE_FLOAT_SIMPLE, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a signed or unsigned small (<= 23) integer value in CBOR format.
|
||||
*
|
||||
* @param value the value to write, values in the range <tt>[-24..23]</tt> are supported.
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
public void writeSmallInt(int value) throws IOException {
|
||||
// extends the sign over all bits...
|
||||
int sign = value >> 31;
|
||||
// in case value is negative, this bit should be set...
|
||||
int mt = (int) (sign & NEG_INT_MASK);
|
||||
// complement negative value...
|
||||
value = Math.min(0x17, (sign ^ value));
|
||||
|
||||
m_os.write((int) (mt | value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a semantic tag in canonical CBOR format.
|
||||
*
|
||||
* @param tag the tag to write, should >= 0.
|
||||
* @throws IllegalArgumentException in case the given tag was negative;
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
public void writeTag(long tag) throws IOException {
|
||||
if (tag < 0) {
|
||||
throw new IllegalArgumentException("Invalid tag specification, cannot be negative!");
|
||||
}
|
||||
writeType(TYPE_TAG, tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an UTF-8 string in canonical CBOR-format.
|
||||
* <p>
|
||||
* Note that this method is <em>platform</em> specific, as the given string value will be encoded in a byte array
|
||||
* using the <em>platform</em> encoding! This means that the encoding must be standardized and known.
|
||||
* </p>
|
||||
*
|
||||
* @param value the UTF-8 string to write, can be <code>null</code> in which case an UTF-8 string of length <tt>0</tt> is written.
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
public void writeTextString(String value) throws IOException {
|
||||
writeString(TYPE_TEXT_STRING, value == null ? null : value.getBytes("UTF-8"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the start of an indefinite-length UTF-8 string.
|
||||
* <p>
|
||||
* After calling this method, one is expected to write the given number of string parts. No length checks are performed.<br/>
|
||||
* After all string parts are written, one should write a single break value to end the string, see {@link #writeBreak()}.
|
||||
* </p>
|
||||
*
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
public void writeTextStringStart() throws IOException {
|
||||
writeSimpleType(TYPE_TEXT_STRING, BREAK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an "undefined" value in canonical CBOR format.
|
||||
*
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
public void writeUndefined() throws IOException {
|
||||
writeSimpleType(TYPE_FLOAT_SIMPLE, UNDEFINED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes and writes the major type and value as a simple type.
|
||||
*
|
||||
* @param majorType the major type of the value to write, denotes what semantics the written value has;
|
||||
* @param value the value to write, values from [0..31] are supported.
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
protected void writeSimpleType(int majorType, int value) throws IOException {
|
||||
m_os.write((majorType << 5) | (value & 0x1f));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a byte string in canonical CBOR-format.
|
||||
*
|
||||
* @param majorType the major type of the string, should be either 0x40 or 0x60;
|
||||
* @param value the byte string to write, can be <code>null</code> in which case a byte-string of length <tt>0</tt> is written.
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
protected void writeString(int majorType, byte[] bytes) throws IOException {
|
||||
int len = (bytes == null) ? 0 : bytes.length;
|
||||
writeType(majorType, len);
|
||||
for (int i = 0; i < len; i++) {
|
||||
m_os.write(bytes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes and writes the major type indicator with a given payload (length).
|
||||
*
|
||||
* @param majorType the major type of the value to write, denotes what semantics the written value has;
|
||||
* @param value the value to write, values from {@link Long#MIN_VALUE} to {@link Long#MAX_VALUE} are supported.
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
protected void writeType(int majorType, long value) throws IOException {
|
||||
writeUInt((majorType << 5), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes and writes an unsigned integer value, that is, tries to encode it in a little bytes as possible.
|
||||
*
|
||||
* @param mt the major type of the value to write, denotes what semantics the written value has;
|
||||
* @param value the value to write, values from {@link Long#MIN_VALUE} to {@link Long#MAX_VALUE} are supported.
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
protected void writeUInt(int mt, long value) throws IOException {
|
||||
if (value < 0x18L) {
|
||||
m_os.write((int) (mt | value));
|
||||
} else if (value < 0x100L) {
|
||||
writeUInt8(mt, (int) value);
|
||||
} else if (value < 0x10000L) {
|
||||
writeUInt16(mt, (int) value);
|
||||
} else if (value < 0x100000000L) {
|
||||
writeUInt32(mt, (int) value);
|
||||
} else {
|
||||
writeUInt64(mt, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes and writes an unsigned 16-bit integer value
|
||||
*
|
||||
* @param mt the major type of the value to write, denotes what semantics the written value has;
|
||||
* @param value the value to write, values from {@link Long#MIN_VALUE} to {@link Long#MAX_VALUE} are supported.
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
protected void writeUInt16(int mt, int value) throws IOException {
|
||||
m_os.write(mt | TWO_BYTES);
|
||||
m_os.write(value >> 8);
|
||||
m_os.write(value & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes and writes an unsigned 32-bit integer value
|
||||
*
|
||||
* @param mt the major type of the value to write, denotes what semantics the written value has;
|
||||
* @param value the value to write, values from {@link Long#MIN_VALUE} to {@link Long#MAX_VALUE} are supported.
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
protected void writeUInt32(int mt, int value) throws IOException {
|
||||
m_os.write(mt | FOUR_BYTES);
|
||||
m_os.write(value >> 24);
|
||||
m_os.write(value >> 16);
|
||||
m_os.write(value >> 8);
|
||||
m_os.write(value & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes and writes an unsigned 64-bit integer value
|
||||
*
|
||||
* @param mt the major type of the value to write, denotes what semantics the written value has;
|
||||
* @param value the value to write, values from {@link Long#MIN_VALUE} to {@link Long#MAX_VALUE} are supported.
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
protected void writeUInt64(int mt, long value) throws IOException {
|
||||
m_os.write(mt | EIGHT_BYTES);
|
||||
m_os.write((int) (value >> 56));
|
||||
m_os.write((int) (value >> 48));
|
||||
m_os.write((int) (value >> 40));
|
||||
m_os.write((int) (value >> 32));
|
||||
m_os.write((int) (value >> 24));
|
||||
m_os.write((int) (value >> 16));
|
||||
m_os.write((int) (value >> 8));
|
||||
m_os.write((int) (value & 0xFF));
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes and writes an unsigned 8-bit integer value
|
||||
*
|
||||
* @param mt the major type of the value to write, denotes what semantics the written value has;
|
||||
* @param value the value to write, values from {@link Long#MIN_VALUE} to {@link Long#MAX_VALUE} are supported.
|
||||
* @throws IOException in case of I/O problems writing the CBOR-encoded value to the underlying output stream.
|
||||
*/
|
||||
protected void writeUInt8(int mt, int value) throws IOException {
|
||||
m_os.write(mt | ONE_BYTE);
|
||||
m_os.write(value & 0xFF);
|
||||
}
|
||||
}
|
142
plugins/com.minres.scviewer.database.ftr/src/jacob/CborType.java
Normal file
142
plugins/com.minres.scviewer.database.ftr/src/jacob/CborType.java
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* JACOB - CBOR implementation in Java.
|
||||
*
|
||||
* (C) Copyright - 2013 - J.W. Janssen <j.w.janssen@lxtreme.nl>
|
||||
*
|
||||
* Licensed under Apache License v2.0.
|
||||
*/
|
||||
package jacob;
|
||||
|
||||
import static jacob.CborConstants.*;
|
||||
|
||||
/**
|
||||
* Represents the various major types in CBOR, along with their .
|
||||
* <p>
|
||||
* The major type is encoded in the upper three bits of each initial byte. The lower 5 bytes represent any additional information.
|
||||
* </p>
|
||||
*/
|
||||
public class CborType {
|
||||
private final int m_major;
|
||||
private final int m_additional;
|
||||
|
||||
private CborType(int major, int additional) {
|
||||
m_major = major;
|
||||
m_additional = additional;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a descriptive string for the given major type.
|
||||
*
|
||||
* @param mt the major type to return as string, values from [0..7] are supported.
|
||||
* @return the name of the given major type, as String, never <code>null</code>.
|
||||
* @throws IllegalArgumentException in case the given major type is not supported.
|
||||
*/
|
||||
public static String getName(int mt) {
|
||||
switch (mt) {
|
||||
case TYPE_ARRAY:
|
||||
return "array";
|
||||
case TYPE_BYTE_STRING:
|
||||
return "byte string";
|
||||
case TYPE_FLOAT_SIMPLE:
|
||||
return "float/simple value";
|
||||
case TYPE_MAP:
|
||||
return "map";
|
||||
case TYPE_NEGATIVE_INTEGER:
|
||||
return "negative integer";
|
||||
case TYPE_TAG:
|
||||
return "tag";
|
||||
case TYPE_TEXT_STRING:
|
||||
return "text string";
|
||||
case TYPE_UNSIGNED_INTEGER:
|
||||
return "unsigned integer";
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid major type: " + mt);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes a given byte value to a {@link CborType} value.
|
||||
*
|
||||
* @param i the input byte (8-bit) to decode into a {@link CborType} instance.
|
||||
* @return a {@link CborType} instance, never <code>null</code>.
|
||||
*/
|
||||
public static CborType valueOf(int i) {
|
||||
return new CborType((i & 0xff) >>> 5, i & 0x1f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CborType other = (CborType) obj;
|
||||
return (m_major == other.m_major) && (m_additional == other.m_additional);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the additional information of this type, as integer value from [0..31].
|
||||
*/
|
||||
public int getAdditionalInfo() {
|
||||
return m_additional;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the major type, as integer value from [0..7].
|
||||
*/
|
||||
public int getMajorType() {
|
||||
return m_major;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + m_additional;
|
||||
result = prime * result + m_major;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if this type allows for an infinite-length payload,
|
||||
* <code>false</code> if only definite-length payloads are allowed.
|
||||
*/
|
||||
public boolean isBreakAllowed() {
|
||||
return m_major == TYPE_ARRAY || m_major == TYPE_BYTE_STRING || m_major == TYPE_MAP
|
||||
|| m_major == TYPE_TEXT_STRING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the major type of a given {@link CborType} equals the major type of this {@link CborType}.
|
||||
*
|
||||
* @param other the {@link CborType} to compare against, cannot be <code>null</code>.
|
||||
* @return <code>true</code> if the given {@link CborType} is of the same major type as this {@link CborType}, <code>false</code> otherwise.
|
||||
* @throws IllegalArgumentException in case the given argument was <code>null</code>.
|
||||
*/
|
||||
public boolean isEqualType(CborType other) {
|
||||
if (other == null) {
|
||||
throw new IllegalArgumentException("Parameter cannot be null!");
|
||||
}
|
||||
return m_major == other.m_major;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the major type of a given byte value (representing an encoded {@link CborType}) equals the major type of this {@link CborType}.
|
||||
*
|
||||
* @param encoded the encoded CBOR type to compare.
|
||||
* @return <code>true</code> if the given byte value represents the same major type as this {@link CborType}, <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean isEqualType(int encoded) {
|
||||
return m_major == ((encoded & 0xff) >>> 5);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(getName(m_major)).append('(').append(m_additional).append(')');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
version 1.0
|
@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.minres.scviewer</groupId>
|
||||
<artifactId>com.minres.scviewer.parent</artifactId>
|
||||
<version>2.12.1</version>
|
||||
<version>2.17.1</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
|
@ -14,12 +14,13 @@ import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.NavigableMap;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import com.minres.scviewer.database.EventEntry;
|
||||
import com.minres.scviewer.database.EventKind;
|
||||
import com.minres.scviewer.database.HierNode;
|
||||
import com.minres.scviewer.database.IEvent;
|
||||
import com.minres.scviewer.database.IEventList;
|
||||
import com.minres.scviewer.database.EventList;
|
||||
import com.minres.scviewer.database.IWaveform;
|
||||
import com.minres.scviewer.database.RelationType;
|
||||
import com.minres.scviewer.database.RelationTypeFactory;
|
||||
@ -35,7 +36,7 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
|
||||
|
||||
private Integer maxConcurrency;
|
||||
|
||||
private TreeMap<Long, IEvent[]> events;
|
||||
private IEventList events;
|
||||
|
||||
private List<RelationType> usedRelationsList;
|
||||
|
||||
@ -71,9 +72,9 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
|
||||
}
|
||||
|
||||
@Override
|
||||
public NavigableMap<Long, IEvent[]> getEvents(){
|
||||
public IEventList getEvents(){
|
||||
if(events==null){
|
||||
events=new TreeMap<>();
|
||||
events=new EventList();
|
||||
for(Entry<Integer, ITx> entry:getTransactions().entrySet()){
|
||||
putEvent(new TxEvent(EventKind.BEGIN, entry.getValue()));
|
||||
putEvent(new TxEvent(EventKind.END, entry.getValue()));
|
||||
@ -83,22 +84,13 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
|
||||
}
|
||||
|
||||
private void putEvent(TxEvent ev){
|
||||
Long time = ev.getTime();
|
||||
if(events.containsKey(time)) {
|
||||
IEvent[] oldV = events.get(time);
|
||||
IEvent[] newV = new IEvent[oldV.length+1];
|
||||
System.arraycopy(oldV, 0, newV, 0, oldV.length);
|
||||
newV[oldV.length]=ev;
|
||||
events.put(time, newV);
|
||||
} else {
|
||||
events.put(time, new IEvent[] {ev});
|
||||
}
|
||||
events.put(ev.getTime(), ev);
|
||||
}
|
||||
|
||||
protected abstract Map<Integer, ITx> getTransactions();
|
||||
|
||||
@Override
|
||||
public IEvent[] getEventsAtTime(Long time) {
|
||||
public IEvent[] getEventsAtTime(long time) {
|
||||
return getEvents().get(time);
|
||||
}
|
||||
|
||||
@ -113,12 +105,12 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IEvent[] getEventsBeforeTime(Long time) {
|
||||
Entry<Long, IEvent[]> e = events.floorEntry(time);
|
||||
public IEvent[] getEventsBeforeTime(long time) {
|
||||
EventEntry e = events.floorEntry(time);
|
||||
if(e==null)
|
||||
return new IEvent[]{};
|
||||
else
|
||||
return events.floorEntry(time).getValue();
|
||||
return events.floorEntry(time).events;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -14,8 +14,6 @@ import java.beans.IntrospectionException;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
@ -42,13 +40,11 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
|
||||
|
||||
private ScvSimProps scvSimProps;
|
||||
|
||||
private static final byte[] x = "SQLite format 3".getBytes();
|
||||
|
||||
/** The pcs. */
|
||||
protected PropertyChangeSupport pcs = new PropertyChangeSupport(this);
|
||||
|
||||
@Override
|
||||
public Long getMaxTime() {
|
||||
public long getMaxTime() {
|
||||
SQLiteDatabaseSelectHandler<ScvTxEvent> handler = new SQLiteDatabaseSelectHandler<>(ScvTxEvent.class,
|
||||
database, "time = (SELECT MAX(time) FROM ScvTxEvent)");
|
||||
try {
|
||||
@ -78,24 +74,24 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
|
||||
return streams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canLoad(File inputFile) {
|
||||
if (!inputFile.isDirectory() && inputFile.exists()) {
|
||||
try(InputStream stream = new FileInputStream(inputFile)){
|
||||
byte[] buffer = new byte[x.length];
|
||||
int readCnt = stream.read(buffer, 0, x.length);
|
||||
if (readCnt == x.length) {
|
||||
for (int i = 0; i < x.length; i++)
|
||||
if (buffer[i] != x[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// @Override
|
||||
// public boolean canLoad(File inputFile) {
|
||||
// if (!inputFile.isDirectory() && inputFile.exists()) {
|
||||
// try(InputStream stream = new FileInputStream(inputFile)){
|
||||
// byte[] buffer = new byte[x.length];
|
||||
// int readCnt = stream.read(buffer, 0, x.length);
|
||||
// if (readCnt == x.length) {
|
||||
// for (int i = 0; i < x.length; i++)
|
||||
// if (buffer[i] != x[i])
|
||||
// return false;
|
||||
// }
|
||||
// return true;
|
||||
// } catch (Exception e) {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void load(IWaveformDb db, File file) throws InputFormatException {
|
||||
|
@ -37,8 +37,8 @@ public class Tx implements ITx {
|
||||
private TxGenerator trGenerator;
|
||||
private ScvTx scvTx;
|
||||
private List<ITxAttribute> attributes;
|
||||
private Long begin;
|
||||
private Long end;
|
||||
private long begin=-1;
|
||||
private long end=-1;
|
||||
private List<ITxRelation> incoming;
|
||||
private List<ITxRelation> outgoing;
|
||||
|
||||
@ -50,7 +50,7 @@ public class Tx implements ITx {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getId() {
|
||||
public long getId() {
|
||||
return (long) scvTx.getId();
|
||||
}
|
||||
|
||||
@ -69,8 +69,8 @@ public class Tx implements ITx {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getBeginTime() {
|
||||
if(begin==null){
|
||||
public long getBeginTime() {
|
||||
if(begin<0){
|
||||
SQLiteDatabaseSelectHandler<ScvTxEvent> handler = new SQLiteDatabaseSelectHandler<>(ScvTxEvent.class,
|
||||
database, "tx="+scvTx.getId()+" AND type="+ AssociationType.BEGIN.ordinal());
|
||||
try {
|
||||
@ -85,8 +85,8 @@ public class Tx implements ITx {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getEndTime() {
|
||||
if(end==null){
|
||||
public long getEndTime() {
|
||||
if(end<0){
|
||||
SQLiteDatabaseSelectHandler<ScvTxEvent> handler = new SQLiteDatabaseSelectHandler<>(ScvTxEvent.class,
|
||||
database, "tx="+scvTx.getId()+" AND type="+ AssociationType.END.ordinal());
|
||||
try {
|
||||
@ -178,11 +178,11 @@ public class Tx implements ITx {
|
||||
|
||||
@Override
|
||||
public int compareTo(ITx o) {
|
||||
int res = this.getBeginTime().compareTo(o.getBeginTime());
|
||||
int res = Long.compare(this.getBeginTime(), o.getBeginTime());
|
||||
if(res!=0)
|
||||
return res;
|
||||
else
|
||||
return this.getId().compareTo(o.getId());
|
||||
return Long.compare(this.getId(), o.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -28,7 +28,7 @@ public class TxEvent implements ITxEvent {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getTime() {
|
||||
public long getTime() {
|
||||
return type==EventKind.BEGIN?tx.getBeginTime():tx.getEndTime();
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ public class TxGenerator extends AbstractTxStream {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getId() {
|
||||
public long getId() {
|
||||
return (long) scvGenerator.getId();
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@ public class TxGenerator extends AbstractTxStream {
|
||||
|
||||
@Override
|
||||
public boolean isSame(IWaveform other) {
|
||||
return(other instanceof TxGenerator && this.getId().equals(other.getId()));
|
||||
return(other instanceof TxGenerator && this.getId() == other.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -49,7 +49,7 @@ public class TxStream extends AbstractTxStream {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getId() {
|
||||
public long getId() {
|
||||
return (long) scvStream.getId();
|
||||
}
|
||||
|
||||
@ -89,13 +89,13 @@ public class TxStream extends AbstractTxStream {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IEvent[] getEventsAtTime(Long time) {
|
||||
public IEvent[] getEventsAtTime(long time) {
|
||||
return getEvents().get(time);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSame(IWaveform other) {
|
||||
return(other instanceof TxStream && this.getId().equals(other.getId()));
|
||||
return(other instanceof TxStream && this.getId() == other.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2,12 +2,12 @@
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src/"/>
|
||||
<classpathentry exported="true" kind="lib" path="lib/mapdb-3.0.7.jar" sourcepath="lib/mapdb-3.0.7-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:platform:/resource/com.minres.scviewer.database.text/lib/mapdb-3.0.7-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry exported="true" kind="lib" path="lib/kotlin-stdlib-1.2.42.jar"/>
|
||||
<classpathentry exported="true" kind="lib" path="lib/lz4-1.3.0.jar"/>
|
||||
<classpathentry exported="true" kind="lib" path="lib/elsa-3.0.0-M5.jar"/>
|
||||
|
@ -2,14 +2,15 @@ Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Textual transaction database
|
||||
Bundle-SymbolicName: com.minres.scviewer.database.text
|
||||
Bundle-Version: 3.0.0.qualifier
|
||||
Bundle-Version: 4.0.1.qualifier
|
||||
Bundle-Vendor: MINRES Technologies GmbH
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-11
|
||||
Import-Package: org.osgi.framework;version="1.3.0"
|
||||
Require-Bundle: com.minres.scviewer.database,
|
||||
org.eclipse.osgi.services;bundle-version="3.4.0",
|
||||
com.google.guava;bundle-version="15.0.0",
|
||||
org.eclipse.collections;bundle-version="10.4.0"
|
||||
org.eclipse.collections;bundle-version="10.4.0",
|
||||
org.apache.commons.compress;bundle-version="1.20.0"
|
||||
Service-Component: OSGI-INF/component.xml
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Automatic-Module-Name: com.minres.scviewer.database.text
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="TextDbLoader">
|
||||
<implementation class="com.minres.scviewer.database.text.TextDbLoader"/>
|
||||
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="TextDbLoaderFactory">
|
||||
<implementation class="com.minres.scviewer.database.text.TextDbLoaderFactory"/>
|
||||
<service>
|
||||
<provide interface="com.minres.scviewer.database.IWaveformDbLoader"/>
|
||||
<provide interface="com.minres.scviewer.database.IWaveformDbLoaderFactory"/>
|
||||
</service>
|
||||
</scr:component>
|
||||
|
@ -2,11 +2,11 @@
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>com.minres.scviewer.database.text</artifactId>
|
||||
<version>3.0.0-SNAPSHOT</version>
|
||||
<version>4.0.1-SNAPSHOT</version>
|
||||
<parent>
|
||||
<groupId>com.minres.scviewer</groupId>
|
||||
<artifactId>com.minres.scviewer.parent</artifactId>
|
||||
<version>2.12.1</version>
|
||||
<version>2.17.1</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
|
@ -12,14 +12,13 @@
|
||||
package com.minres.scviewer.database.text;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.NavigableMap;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import com.minres.scviewer.database.EventEntry;
|
||||
import com.minres.scviewer.database.EventList;
|
||||
import com.minres.scviewer.database.HierNode;
|
||||
import com.minres.scviewer.database.IEvent;
|
||||
import com.minres.scviewer.database.IEventList;
|
||||
import com.minres.scviewer.database.IWaveform;
|
||||
import com.minres.scviewer.database.WaveformType;
|
||||
import com.minres.scviewer.database.tx.ITx;
|
||||
@ -30,6 +29,8 @@ import com.minres.scviewer.database.tx.ITxEvent;
|
||||
*/
|
||||
abstract class AbstractTxStream extends HierNode implements IWaveform {
|
||||
|
||||
private final String fullName;
|
||||
|
||||
/** The id. */
|
||||
private Long id;
|
||||
|
||||
@ -37,7 +38,7 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
|
||||
protected TextDbLoader loader;
|
||||
|
||||
/** The events. */
|
||||
TreeMap<Long, IEvent[]> events = new TreeMap<>();
|
||||
IEventList events = new EventList();
|
||||
|
||||
/** The max concurrency. */
|
||||
private int rowCount = -1;
|
||||
@ -51,24 +52,27 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
|
||||
*/
|
||||
protected AbstractTxStream(TextDbLoader loader, Long id, String name) {
|
||||
super(name);
|
||||
fullName=name;
|
||||
this.loader = loader;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the full hierarchical name.
|
||||
*
|
||||
* @return the full name
|
||||
*/
|
||||
@Override
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
/**
|
||||
* Adds the event.
|
||||
*
|
||||
* @param evt the evt
|
||||
*/
|
||||
public void addEvent(ITxEvent evt) {
|
||||
if (!events.containsKey(evt.getTime()))
|
||||
events.put(evt.getTime(), new IEvent[] { evt });
|
||||
else {
|
||||
IEvent[] evts = events.get(evt.getTime());
|
||||
IEvent[] newEvts = Arrays.copyOf(evts, evts.length + 1);
|
||||
newEvts[evts.length] = evt;
|
||||
events.put(evt.getTime(), newEvts);
|
||||
}
|
||||
events.put(evt.getTime(), evt);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -77,7 +81,7 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
|
||||
* @return the events
|
||||
*/
|
||||
@Override
|
||||
public NavigableMap<Long, IEvent[]> getEvents() {
|
||||
public IEventList getEvents() {
|
||||
return events;
|
||||
}
|
||||
|
||||
@ -88,7 +92,7 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
|
||||
* @return the events at time
|
||||
*/
|
||||
@Override
|
||||
public IEvent[] getEventsAtTime(Long time) {
|
||||
public IEvent[] getEventsAtTime(long time) {
|
||||
return events.get(time);
|
||||
}
|
||||
|
||||
@ -99,12 +103,12 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
|
||||
* @return the events before time
|
||||
*/
|
||||
@Override
|
||||
public IEvent[] getEventsBeforeTime(Long time) {
|
||||
Entry<Long, IEvent[]> e = events.floorEntry(time);
|
||||
public IEvent[] getEventsBeforeTime(long time) {
|
||||
EventEntry e = events.floorEntry(time);
|
||||
if (e == null)
|
||||
return new IEvent[] {};
|
||||
else
|
||||
return events.floorEntry(time).getValue();
|
||||
return events.floorEntry(time).events;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -123,7 +127,7 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
|
||||
* @return the id
|
||||
*/
|
||||
@Override
|
||||
public Long getId() {
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@ -147,8 +151,8 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
|
||||
return;
|
||||
ArrayList<Long> rowEndTime = new ArrayList<>();
|
||||
HashMap<Long, Integer> rowByTxId = new HashMap<>();
|
||||
for(Entry<Long, IEvent[]> entry: events.entrySet()) {
|
||||
for(IEvent evt:entry.getValue()) {
|
||||
for(EventEntry entry: events) {
|
||||
for(IEvent evt:entry.events) {
|
||||
TxEvent txEvt = (TxEvent) evt;
|
||||
ITx tx = txEvt.getTransaction();
|
||||
int rowIdx = 0;
|
||||
@ -179,7 +183,7 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
|
||||
}
|
||||
}
|
||||
rowCount=rowEndTime.size()>0?rowEndTime.size():1;
|
||||
getChildNodes().parallelStream().forEach(c -> ((TxGenerator)c).calculateConcurrency());
|
||||
//getChildNodes().parallelStream().forEach(c -> ((TxGenerator)c).calculateConcurrency());
|
||||
getChildNodes().stream().forEach(c -> ((TxGenerator)c).calculateConcurrency());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ package com.minres.scviewer.database.text;
|
||||
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
@ -33,6 +34,7 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
import org.apache.commons.compress.compressors.lz4.FramedLZ4CompressorInputStream;
|
||||
import org.eclipse.collections.impl.map.mutable.UnifiedMap;
|
||||
import org.mapdb.DB;
|
||||
import org.mapdb.DBMaker;
|
||||
@ -56,13 +58,15 @@ import com.minres.scviewer.database.tx.ITx;
|
||||
*/
|
||||
public class TextDbLoader implements IWaveformDbLoader {
|
||||
|
||||
enum FileType { NONE, PLAIN, GZIP, LZ4};
|
||||
|
||||
/** the file size limit of a zipped txlog where the loader starts to use a file mapped database */
|
||||
private static final long MEMMAP_LIMIT=256l*1024l*1024l;
|
||||
|
||||
|
||||
private static final long MAPDB_INITIAL_ALLOC = 512l*1024l*1024l;
|
||||
|
||||
|
||||
private static final long MAPDB_INCREMENTAL_ALLOC = 128l*1024l*1024l;
|
||||
|
||||
|
||||
/** The max time. */
|
||||
private Long maxTime = 0L;
|
||||
|
||||
@ -131,7 +135,7 @@ public class TextDbLoader implements IWaveformDbLoader {
|
||||
* @return the max time
|
||||
*/
|
||||
@Override
|
||||
public Long getMaxTime() {
|
||||
public long getMaxTime() {
|
||||
return maxTime;
|
||||
}
|
||||
|
||||
@ -167,7 +171,9 @@ public class TextDbLoader implements IWaveformDbLoader {
|
||||
*/
|
||||
@Override
|
||||
public Collection<IWaveform> getAllWaves() {
|
||||
return new ArrayList<>(txStreams.values());
|
||||
ArrayList<IWaveform> ret = new ArrayList<>(txStreams.values());
|
||||
ret.addAll(txGenerators.values());
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -179,45 +185,30 @@ public class TextDbLoader implements IWaveformDbLoader {
|
||||
return relationTypes.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Can load.
|
||||
*
|
||||
* @param inputFile the input file
|
||||
* @return true, if successful
|
||||
*/
|
||||
@Override
|
||||
public boolean canLoad(File inputFile) {
|
||||
if (!inputFile.isDirectory() && inputFile.exists()) {
|
||||
boolean gzipped = isGzipped(inputFile);
|
||||
try(InputStream stream = gzipped ? new GZIPInputStream(new FileInputStream(inputFile)) : new FileInputStream(inputFile)){
|
||||
byte[] buffer = new byte[x.length];
|
||||
int readCnt = stream.read(buffer, 0, x.length);
|
||||
if (readCnt == x.length) {
|
||||
for (int i = 0; i < x.length; i++)
|
||||
if (buffer[i] != x[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if is gzipped.
|
||||
*
|
||||
* @param f the f
|
||||
* @return true, if is gzipped
|
||||
*/
|
||||
private static boolean isGzipped(File f) {
|
||||
static FileType getFileType(File f) {
|
||||
try (InputStream is = new FileInputStream(f)) {
|
||||
byte[] signature = new byte[2];
|
||||
byte[] signature = new byte[4];
|
||||
int nread = is.read(signature); // read the gzip signature
|
||||
return nread == 2 && signature[0] == (byte) 0x1f && signature[1] == (byte) 0x8b;
|
||||
if(nread >= 2 &&
|
||||
signature[0] == (byte) 0x1f &&
|
||||
signature[1] == (byte) 0x8b)
|
||||
return FileType.GZIP;
|
||||
else if(nread>=4 &&
|
||||
signature[0] == (byte) 0x04 &&
|
||||
signature[1] == (byte) 0x22 &&
|
||||
signature[2] == (byte) 0x4d &&
|
||||
signature[3] == (byte) 0x18)
|
||||
return FileType.LZ4;
|
||||
else
|
||||
return FileType.PLAIN;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
return FileType.NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -233,8 +224,8 @@ public class TextDbLoader implements IWaveformDbLoader {
|
||||
@Override
|
||||
public void load(IWaveformDb db, File file) throws InputFormatException {
|
||||
dispose();
|
||||
boolean gzipped = isGzipped(file);
|
||||
if (file.length() < MEMMAP_LIMIT * (gzipped ? 1 : 10)
|
||||
FileType fType = getFileType(file);
|
||||
if (file.length() < MEMMAP_LIMIT * (fType!=FileType.PLAIN ? 1 : 10)
|
||||
|| "memory".equals(System.getProperty("ScvBackingDB", "file")))
|
||||
mapDb = DBMaker.memoryDirectDB().make();
|
||||
else {
|
||||
@ -252,13 +243,15 @@ public class TextDbLoader implements IWaveformDbLoader {
|
||||
}
|
||||
TextDbParser parser = new TextDbParser(this);
|
||||
try {
|
||||
|
||||
|
||||
parser.txSink = mapDb.hashMap("transactions", Serializer.LONG, Serializer.JAVA).create();
|
||||
parser.parseInput(gzipped ? new GZIPInputStream(new FileInputStream(file)) : new FileInputStream(file));
|
||||
transactions = parser.txSink;
|
||||
InputStream is = new BufferedInputStream(new FileInputStream(file));
|
||||
parser.parseInput(fType==FileType.GZIP ? new GZIPInputStream(is) : fType==FileType.LZ4? new FramedLZ4CompressorInputStream(is) : is);
|
||||
} catch (IllegalArgumentException | ArrayIndexOutOfBoundsException e) {
|
||||
} catch (Exception e) {
|
||||
throw new InputFormatException(e.toString());
|
||||
} finally {
|
||||
transactions = parser.txSink;
|
||||
}
|
||||
txStreams.values().parallelStream().forEach(TxStream::calculateConcurrency);
|
||||
}
|
||||
@ -338,20 +331,22 @@ public class TextDbLoader implements IWaveformDbLoader {
|
||||
* @throws IOException Signals that an I/O exception has occurred.
|
||||
* @throws InputFormatException Signals that the input format is wrong
|
||||
*/
|
||||
void parseInput(InputStream inputStream) throws IOException, InputFormatException {
|
||||
reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
String curLine = reader.readLine();
|
||||
String nextLine = null;
|
||||
while ((nextLine = reader.readLine()) != null && curLine != null) {
|
||||
curLine = parseLine(curLine, nextLine);
|
||||
}
|
||||
if (curLine != null)
|
||||
parseLine(curLine, nextLine);
|
||||
for(Entry<Long, ScvTx> e: transactionById.entrySet()) {
|
||||
ScvTx scvTx = e.getValue();
|
||||
scvTx.endTime=loader.maxTime;
|
||||
txSink.put(e.getKey(), scvTx);
|
||||
}
|
||||
void parseInput(InputStream inputStream) throws InputFormatException {
|
||||
try {
|
||||
reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
String curLine = reader.readLine();
|
||||
String nextLine = null;
|
||||
while ((nextLine = reader.readLine()) != null && curLine != null) {
|
||||
curLine = parseLine(curLine, nextLine, false);
|
||||
}
|
||||
if (curLine != null)
|
||||
parseLine(curLine, nextLine, true);
|
||||
for(Entry<Long, ScvTx> e: transactionById.entrySet()) {
|
||||
ScvTx scvTx = e.getValue();
|
||||
scvTx.endTime=loader.maxTime;
|
||||
txSink.put(e.getKey(), scvTx);
|
||||
}
|
||||
} catch(IOException e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -383,81 +378,87 @@ public class TextDbLoader implements IWaveformDbLoader {
|
||||
* @throws IOException Signals that an I/O exception has occurred.
|
||||
* @throws InputFormatException Signals that the input format is wrong
|
||||
*/
|
||||
private String parseLine(String curLine, String nextLine) throws IOException, InputFormatException {
|
||||
String[] tokens = curLine.split("\\s+");
|
||||
if ("tx_record_attribute".equals(tokens[0])) {
|
||||
Long id = Long.parseLong(tokens[1]);
|
||||
String name = tokens[2].substring(1, tokens[2].length()-1);
|
||||
DataType type = DataType.valueOf(tokens[3]);
|
||||
String remaining = tokens.length > 5 ? String.join(" ", Arrays.copyOfRange(tokens, 5, tokens.length)) : "";
|
||||
TxAttributeType attrType = getAttrType(name, type, AssociationType.RECORD);
|
||||
transactionById.get(id).attributes.add(new TxAttribute(attrType, getAttrString(attrType, remaining)));
|
||||
} else if ("tx_begin".equals(tokens[0])) {
|
||||
Long id = Long.parseLong(tokens[1]);
|
||||
Long genId = Long.parseLong(tokens[2]);
|
||||
TxGenerator gen = loader.txGenerators.get(genId);
|
||||
ScvTx scvTx = new ScvTx(id, gen.stream.getId(), genId,
|
||||
Long.parseLong(tokens[3]) * stringToScale(tokens[4]));
|
||||
loader.maxTime = loader.maxTime > scvTx.beginTime ? loader.maxTime : scvTx.beginTime;
|
||||
if (nextLine != null && nextLine.charAt(0) == 'a') {
|
||||
int idx = 0;
|
||||
while (nextLine != null && nextLine.charAt(0) == 'a') {
|
||||
String[] attrTokens = nextLine.split("\\s+");
|
||||
TxAttributeType attrType = gen.beginAttrs.get(idx);
|
||||
TxAttribute attr = new TxAttribute(attrType, getAttrString(attrType, attrTokens[1]));
|
||||
scvTx.attributes.add(attr);
|
||||
idx++;
|
||||
nextLine = reader.readLine();
|
||||
private String parseLine(String curLine, String nextLine, boolean last) throws IOException, InputFormatException {
|
||||
if(curLine.charAt(0)=='t') {
|
||||
String[] tokens = curLine.split(" ");
|
||||
//if ("tx_record_attribute".equals(tokens[0]) && tokens.length>4) {
|
||||
if (curLine.charAt(5)=='c' && tokens.length>4) {
|
||||
Long id = Long.parseLong(tokens[1]);
|
||||
String name = tokens[2].substring(1, tokens[2].length()-1);
|
||||
DataType type = DataType.valueOf(tokens[3]);
|
||||
String remaining = tokens.length > 5 ? String.join(" ", Arrays.copyOfRange(tokens, 5, tokens.length)) : "";
|
||||
TxAttributeType attrType = getAttrType(name, type, AssociationType.RECORD);
|
||||
transactionById.get(id).attributes.add(new TxAttribute(attrType, getAttrString(attrType, remaining)));
|
||||
//} else if ("tx_begin".equals(tokens[0]) && tokens.length>4) {
|
||||
} else if (curLine.charAt(3)=='b' && tokens.length>4) {
|
||||
Long id = Long.parseLong(tokens[1]);
|
||||
Long genId = Long.parseLong(tokens[2]);
|
||||
TxGenerator gen = loader.txGenerators.get(genId);
|
||||
ScvTx scvTx = new ScvTx(id, gen.stream.getId(), genId,
|
||||
Long.parseLong(tokens[3]) * stringToScale(tokens[4]));
|
||||
loader.maxTime = loader.maxTime > scvTx.beginTime ? loader.maxTime : scvTx.beginTime;
|
||||
if (nextLine != null && nextLine.charAt(0) == 'a') {
|
||||
int idx = 0;
|
||||
while (nextLine != null && nextLine.charAt(0) == 'a') {
|
||||
String[] attrTokens = nextLine.split("\\s+");
|
||||
TxAttributeType attrType = gen.beginAttrs.get(idx);
|
||||
TxAttribute attr = new TxAttribute(attrType, getAttrString(attrType, attrTokens[1]));
|
||||
scvTx.attributes.add(attr);
|
||||
idx++;
|
||||
nextLine = reader.readLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
transactionById.put(id, scvTx);
|
||||
} else if ("tx_end".equals(tokens[0])) {
|
||||
Long id = Long.parseLong(tokens[1]);
|
||||
ScvTx scvTx = transactionById.get(id);
|
||||
assert Long.parseLong(tokens[2]) == scvTx.generatorId;
|
||||
scvTx.endTime = Long.parseLong(tokens[3]) * stringToScale(tokens[4]);
|
||||
loader.maxTime = loader.maxTime > scvTx.endTime ? loader.maxTime : scvTx.endTime;
|
||||
TxGenerator gen = loader.txGenerators.get(scvTx.generatorId);
|
||||
TxStream stream = loader.txStreams.get(gen.stream.getId());
|
||||
if (scvTx.beginTime == scvTx.endTime) {
|
||||
stream.addEvent(new TxEvent(loader, EventKind.SINGLE, id, scvTx.beginTime));
|
||||
gen.addEvent(new TxEvent(loader, EventKind.SINGLE, id, scvTx.beginTime));
|
||||
} else {
|
||||
stream.addEvent(new TxEvent(loader, EventKind.BEGIN, id, scvTx.beginTime));
|
||||
gen.addEvent(new TxEvent(loader, EventKind.BEGIN, id, scvTx.beginTime));
|
||||
stream.addEvent(new TxEvent(loader, EventKind.END, id, scvTx.endTime));
|
||||
gen.addEvent(new TxEvent(loader, EventKind.END, id, scvTx.endTime));
|
||||
}
|
||||
if (nextLine != null && nextLine.charAt(0) == 'a') {
|
||||
int idx = 0;
|
||||
while (nextLine != null && nextLine.charAt(0) == 'a') {
|
||||
String[] attrTokens = nextLine.split("\\s+");
|
||||
TxAttributeType attrType = gen.endAttrs.get(idx);
|
||||
TxAttribute attr = new TxAttribute(attrType, getAttrString(attrType, attrTokens[1]));
|
||||
scvTx.attributes.add(attr);
|
||||
idx++;
|
||||
nextLine = reader.readLine();
|
||||
transactionById.put(id, scvTx);
|
||||
//} else if ("tx_end".equals(tokens[0]) && tokens.length>4) {
|
||||
} else if (curLine.charAt(3)=='e' && tokens.length>4) {
|
||||
Long id = Long.parseLong(tokens[1]);
|
||||
ScvTx scvTx = transactionById.get(id);
|
||||
assert Long.parseLong(tokens[2]) == scvTx.generatorId;
|
||||
scvTx.endTime = Long.parseLong(tokens[3]) * stringToScale(tokens[4]);
|
||||
loader.maxTime = loader.maxTime > scvTx.endTime ? loader.maxTime : scvTx.endTime;
|
||||
TxGenerator gen = loader.txGenerators.get(scvTx.generatorId);
|
||||
TxStream stream = loader.txStreams.get(gen.stream.getId());
|
||||
if (scvTx.beginTime == scvTx.endTime) {
|
||||
stream.addEvent(new TxEvent(loader, EventKind.SINGLE, id, scvTx.beginTime));
|
||||
gen.addEvent(new TxEvent(loader, EventKind.SINGLE, id, scvTx.beginTime));
|
||||
} else {
|
||||
stream.addEvent(new TxEvent(loader, EventKind.BEGIN, id, scvTx.beginTime));
|
||||
gen.addEvent(new TxEvent(loader, EventKind.BEGIN, id, scvTx.beginTime));
|
||||
stream.addEvent(new TxEvent(loader, EventKind.END, id, scvTx.endTime));
|
||||
gen.addEvent(new TxEvent(loader, EventKind.END, id, scvTx.endTime));
|
||||
}
|
||||
if (nextLine != null && nextLine.charAt(0) == 'a') {
|
||||
int idx = 0;
|
||||
while (nextLine != null && nextLine.charAt(0) == 'a') {
|
||||
String[] attrTokens = nextLine.split("\\s+");
|
||||
TxAttributeType attrType = gen.endAttrs.get(idx);
|
||||
TxAttribute attr = new TxAttribute(attrType, getAttrString(attrType, attrTokens[1]));
|
||||
scvTx.attributes.add(attr);
|
||||
idx++;
|
||||
nextLine = reader.readLine();
|
||||
}
|
||||
}
|
||||
txSink.put(scvTx.getId(), scvTx);
|
||||
transactionById.remove(id);
|
||||
//} else if ("tx_relation".equals(tokens[0]) && tokens.length>3) {
|
||||
} else if (curLine.charAt(5)=='l' && tokens.length>3) {
|
||||
Long tr2 = Long.parseLong(tokens[2]);
|
||||
Long tr1 = Long.parseLong(tokens[3]);
|
||||
String relType = tokens[1].substring(1, tokens[1].length() - 1);
|
||||
if (!loader.relationTypes.containsKey(relType))
|
||||
loader.relationTypes.put(relType, RelationTypeFactory.create(relType));
|
||||
ScvRelation rel = new ScvRelation(loader.relationTypes.get(relType), tr1, tr2);
|
||||
loader.relationsOut.put(tr1, rel);
|
||||
loader.relationsIn.put(tr2, rel);
|
||||
}
|
||||
txSink.put(scvTx.getId(), scvTx);
|
||||
transactionById.remove(id);
|
||||
} else if ("tx_relation".equals(tokens[0])) {
|
||||
Long tr2 = Long.parseLong(tokens[2]);
|
||||
Long tr1 = Long.parseLong(tokens[3]);
|
||||
String relType = tokens[1].substring(1, tokens[1].length() - 1);
|
||||
if (!loader.relationTypes.containsKey(relType))
|
||||
loader.relationTypes.put(relType, RelationTypeFactory.create(relType));
|
||||
ScvRelation rel = new ScvRelation(loader.relationTypes.get(relType), tr1, tr2);
|
||||
loader.relationsOut.put(tr1, rel);
|
||||
loader.relationsIn.put(tr2, rel);
|
||||
} else if ("scv_tr_stream".equals(tokens[0])) {
|
||||
} else if (curLine.length()>13 && "scv_tr_stream".equals(curLine.substring(0, 13))) {
|
||||
Matcher matcher = scv_tr_stream.matcher(curLine);
|
||||
if (matcher.matches()) {
|
||||
Long id = Long.parseLong(matcher.group(1));
|
||||
TxStream stream = new TxStream(loader, id, matcher.group(2), matcher.group(3));
|
||||
add(id, stream);
|
||||
}
|
||||
} else if ("scv_tr_generator".equals(tokens[0])) {
|
||||
} else if (curLine.length()>16 && "scv_tr_generator".equals(curLine.substring(0, 16))) {
|
||||
Matcher matcher = scv_tr_generator.matcher(curLine);
|
||||
if ((matcher.matches())) {
|
||||
Long id = Long.parseLong(matcher.group(1));
|
||||
@ -465,23 +466,23 @@ public class TextDbLoader implements IWaveformDbLoader {
|
||||
generator = new TxGenerator(loader, id, matcher.group(2), stream);
|
||||
add(id, generator);
|
||||
}
|
||||
} else if ("begin_attribute".equals(tokens[0])) {
|
||||
} else if (curLine.length()>15 && "begin_attribute".equals(curLine.substring(0, 15))) {
|
||||
Matcher matcher = begin_attribute.matcher(curLine);
|
||||
if ((matcher.matches())) {
|
||||
TxAttributeType attrType = getAttrType(matcher.group(2), DataType.valueOf(matcher.group(3)),
|
||||
AssociationType.BEGIN);
|
||||
generator.beginAttrs.add(attrType);
|
||||
}
|
||||
} else if ("end_attribute".equals(tokens[0])) {
|
||||
} else if (curLine.length()>13 && "end_attribute".equals(curLine.substring(0, 13))) {
|
||||
Matcher matcher = end_attribute.matcher(curLine);
|
||||
if ((matcher.matches())) {
|
||||
TxAttributeType attrType = getAttrType(matcher.group(2), DataType.valueOf(matcher.group(3)),
|
||||
AssociationType.END);
|
||||
generator.endAttrs.add(attrType);
|
||||
}
|
||||
} else if (")".equals(tokens[0])) {
|
||||
} else if (curLine.charAt(0) == ')') {
|
||||
generator = null;
|
||||
} else
|
||||
} else if(!last)
|
||||
throw new InputFormatException("Don't know what to do with: '" + curLine + "'");
|
||||
return nextLine;
|
||||
}
|
||||
|
@ -0,0 +1,60 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2012 IT Just working.
|
||||
* Copyright (c) 2020 MINRES Technologies GmbH
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IT Just working - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.minres.scviewer.database.text;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
import org.apache.commons.compress.compressors.lz4.FramedLZ4CompressorInputStream;
|
||||
|
||||
import com.minres.scviewer.database.IWaveformDbLoader;
|
||||
import com.minres.scviewer.database.IWaveformDbLoaderFactory;
|
||||
import com.minres.scviewer.database.text.TextDbLoader.FileType;
|
||||
|
||||
/**
|
||||
* The Class TextDbLoader.
|
||||
*/
|
||||
public class TextDbLoaderFactory implements IWaveformDbLoaderFactory {
|
||||
|
||||
/** The Constant x. */
|
||||
static final byte[] x = "scv_tr_stream".getBytes();
|
||||
|
||||
/**
|
||||
* Can load.
|
||||
*
|
||||
* @param inputFile the input file
|
||||
* @return true, if successful
|
||||
*/
|
||||
@Override
|
||||
public boolean canLoad(File inputFile) {
|
||||
FileType fType = TextDbLoader.getFileType(inputFile);
|
||||
try (InputStream is = new FileInputStream(inputFile)) {
|
||||
InputStream plainIs = fType==FileType.GZIP ? new GZIPInputStream(is) : fType==FileType.LZ4? new FramedLZ4CompressorInputStream(is) : is;
|
||||
byte[] buffer = new byte[x.length];
|
||||
int readCnt = plainIs.read(buffer, 0, x.length);
|
||||
if (readCnt == x.length) {
|
||||
for (int i = 0; i < x.length; i++)
|
||||
if (buffer[i] != x[i]) return false;
|
||||
}
|
||||
return true;
|
||||
} catch (IOException e) {}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IWaveformDbLoader getLoader() {
|
||||
return new TextDbLoader();
|
||||
}
|
||||
}
|
@ -102,11 +102,11 @@ class Tx implements ITx {
|
||||
*/
|
||||
@Override
|
||||
public int compareTo(ITx o) {
|
||||
int res = getBeginTime().compareTo(o.getBeginTime());
|
||||
int res = Long.compare(getBeginTime(), o.getBeginTime());
|
||||
if (res != 0)
|
||||
return res;
|
||||
else
|
||||
return getId().compareTo(o.getId());
|
||||
return Long.compare(getId(), o.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -150,7 +150,7 @@ class Tx implements ITx {
|
||||
* @return the id
|
||||
*/
|
||||
@Override
|
||||
public Long getId() {
|
||||
public long getId() {
|
||||
return getScvTx().id;
|
||||
}
|
||||
|
||||
@ -180,7 +180,7 @@ class Tx implements ITx {
|
||||
* @return the begin time
|
||||
*/
|
||||
@Override
|
||||
public Long getBeginTime() {
|
||||
public long getBeginTime() {
|
||||
if (beginTime < 0) {
|
||||
ScvTx tx = scvTx==null?loader.getScvTx(id):getScvTx();
|
||||
beginTime = tx.beginTime;
|
||||
@ -195,7 +195,7 @@ class Tx implements ITx {
|
||||
* @return the end time
|
||||
*/
|
||||
@Override
|
||||
public Long getEndTime() {
|
||||
public long getEndTime() {
|
||||
if (endTime < 0) {
|
||||
ScvTx tx = scvTx==null?loader.getScvTx(id):getScvTx();
|
||||
beginTime = tx.beginTime;
|
||||
|
@ -95,7 +95,7 @@ class TxEvent implements ITxEvent {
|
||||
* @return the time
|
||||
*/
|
||||
@Override
|
||||
public Long getTime() {
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ class TxGenerator extends AbstractTxStream {
|
||||
*/
|
||||
@Override
|
||||
public boolean isSame(IWaveform other) {
|
||||
return (other instanceof TxGenerator && this.getId().equals(other.getId()));
|
||||
return (other instanceof TxGenerator && this.getId()==other.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -82,5 +82,15 @@ class TxGenerator extends AbstractTxStream {
|
||||
public String getKind() {
|
||||
return stream.getKind();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the full hierarchical name.
|
||||
*
|
||||
* @return the full name
|
||||
*/
|
||||
@Override
|
||||
public String getFullName() {
|
||||
return ((AbstractTxStream)parent).getFullName()+"."+name;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ class TxStream extends AbstractTxStream {
|
||||
*/
|
||||
@Override
|
||||
public boolean isSame(IWaveform other) {
|
||||
return (other instanceof TxStream && this.getId().equals(other.getId()));
|
||||
return (other instanceof TxStream && this.getId() == other.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: SWT database widget
|
||||
Bundle-SymbolicName: com.minres.scviewer.database.ui.swt
|
||||
Bundle-Version: 3.0.0.qualifier
|
||||
Bundle-Version: 4.0.0.qualifier
|
||||
Bundle-Vendor: MINRES Technologies GmbH
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-11
|
||||
Require-Bundle: org.eclipse.swt;bundle-version="3.103.1",
|
||||
|
@ -5,8 +5,8 @@
|
||||
<parent>
|
||||
<groupId>com.minres.scviewer</groupId>
|
||||
<artifactId>com.minres.scviewer.parent</artifactId>
|
||||
<version>2.12.1</version>
|
||||
<version>2.17.1</version>
|
||||
<relativePath>../..</relativePath>
|
||||
</parent>
|
||||
<version>3.0.0-SNAPSHOT</version>
|
||||
<version>4.0.0-SNAPSHOT</version>
|
||||
</project>
|
||||
|
@ -27,10 +27,14 @@ import com.minres.scviewer.database.tx.ITx;
|
||||
|
||||
public interface IWaveformView extends PropertyChangeListener, ISelectionProvider{
|
||||
|
||||
String CURSOR_PROPERTY = "cursor_time";
|
||||
static final String CURSOR_PROPERTY = "cursor_time";
|
||||
|
||||
String MARKER_PROPERTY = "marker_time";
|
||||
static final String MARKER_PROPERTY = "marker_time";
|
||||
|
||||
static final int CURSOR_POS = 0;
|
||||
|
||||
static final int MARKER_POS = 1;
|
||||
|
||||
public static final RelationType NEXT_PREV_IN_STREAM = RelationTypeFactory.create("Prev/Next in stream");
|
||||
|
||||
public void addSelectionChangedListener(ISelectionChangedListener listener);
|
||||
@ -75,23 +79,17 @@ public interface IWaveformView extends PropertyChangeListener, ISelectionProvide
|
||||
|
||||
public void setHighliteRelation(RelationType relationType);
|
||||
|
||||
public long getMaxTime();
|
||||
|
||||
public void setMaxTime(long maxTime);
|
||||
|
||||
public void setZoomLevel(int scale);
|
||||
|
||||
public int getZoomLevel();
|
||||
|
||||
public void setCursorTime(long time);
|
||||
|
||||
public void setMarkerTime(long time, int index);
|
||||
public void setMarkerTime(int marker, long time);
|
||||
|
||||
public long getCursorTime();
|
||||
|
||||
public int getSelectedMarkerId();
|
||||
public int getSelectedMarker();
|
||||
|
||||
public long getMarkerTime(int index);
|
||||
public long getMarkerTime(int marker);
|
||||
|
||||
public void addPropertyChangeListener(PropertyChangeListener listener);
|
||||
|
||||
@ -101,21 +99,18 @@ public interface IWaveformView extends PropertyChangeListener, ISelectionProvide
|
||||
|
||||
public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener);
|
||||
|
||||
public String getScaledTime(long time);
|
||||
|
||||
public String[] getZoomLevels();
|
||||
|
||||
public List<ICursor> getCursorList();
|
||||
|
||||
public long getBaselineTime();
|
||||
|
||||
public void setBaselineTime(Long scale);
|
||||
|
||||
public void scrollHorizontal(int percent);
|
||||
|
||||
public void scrollTo(int pos);
|
||||
|
||||
public void addDisposeListener( DisposeListener listener );
|
||||
|
||||
public void deleteSelectedTracks();
|
||||
|
||||
public TrackEntry addWaveform(IWaveform waveform, int pos);
|
||||
|
||||
public IWaveformZoom getWaveformZoom();
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package com.minres.scviewer.database.ui;
|
||||
|
||||
public interface IWaveformZoom {
|
||||
|
||||
long getMaxVisibleTime();
|
||||
|
||||
long getMinVisibleTime();
|
||||
|
||||
void setMinVisibleTime(long scale);
|
||||
|
||||
long getMaxTime();
|
||||
|
||||
long getScale();
|
||||
|
||||
void setScale(long factor);
|
||||
|
||||
void setVisibleRange(long startTime, long endTime);
|
||||
|
||||
void centerAt(long time);
|
||||
|
||||
void zoom(ZoomKind kind);
|
||||
|
||||
String timeToString(long time);
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
package com.minres.scviewer.database.ui;
|
||||
|
||||
public enum ZoomKind {IN, OUT, FIT, FULL}
|
@ -1,14 +1,49 @@
|
||||
package com.minres.scviewer.database.ui.swt;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
public class Constants {
|
||||
|
||||
public static final String[] UNIT_STRING={"fs", "ps", "ns", "us", "ms"};//, "s"};
|
||||
|
||||
public static final int[] UNIT_MULTIPLIER={1, 3, 10, 30, 100, 300};
|
||||
public static final String[] UNIT_STRING={"fs", "ps", "ns", "us", "ms", "s"};
|
||||
public static final long[] UNIT_MULTIPLIER={1l, 1000l, 1000l*1000, 1000l*1000*1000, 1000l*1000*1000*1000, 1000l*1000*1000*1000*1000 };
|
||||
|
||||
//public static final int[] UNIT_MULTIPLIER={1, 3, 10, 30, 100, 300};
|
||||
public static final long[] SCALE_MULTIPLIER={1, 2, 5, 10, 20, 50, 100, 200, 500};
|
||||
|
||||
public static final String CONTENT_PROVIDER_TAG = "TOOLTIP_CONTENT_PROVIDER";
|
||||
public static final String HELP_PROVIDER_TAG = "TOOLTIP_HELP_PROVIDER";
|
||||
|
||||
public static final DecimalFormat TIME_FORMAT_FS = new DecimalFormat("#");
|
||||
public static final DecimalFormat TIME_FORMAT_PS = new DecimalFormat("#");
|
||||
public static final DecimalFormat TIME_FORMAT_NS = new DecimalFormat("#.0##");
|
||||
public static final DecimalFormat TIME_FORMAT_UMS = new DecimalFormat("#.0#####");
|
||||
public static final long[] POWERS_OF_TEN = {
|
||||
1L,
|
||||
10L,
|
||||
100L,
|
||||
1_000L,
|
||||
10_000L,
|
||||
100_000L,
|
||||
1_000_000L,
|
||||
10_000_000L,
|
||||
100_000_000L,
|
||||
1_000_000_000L,
|
||||
10_000_000_000L,
|
||||
100_000_000_000L,
|
||||
1_000_000_000_000L,
|
||||
10_000_000_000_000L,
|
||||
100_000_000_000_000L,
|
||||
1_000_000_000_000_000L};
|
||||
|
||||
public static DecimalFormat getTimeFormatForLevel(int idx) {
|
||||
switch(idx) {
|
||||
case 0: return TIME_FORMAT_FS;
|
||||
case 1: return TIME_FORMAT_PS;
|
||||
case 2: return TIME_FORMAT_NS;
|
||||
default:
|
||||
return TIME_FORMAT_UMS;
|
||||
}
|
||||
}
|
||||
private Constants() {}
|
||||
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ package com.minres.scviewer.database.ui.swt;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Plugin;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.wb.swt.SWTResourceManager;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
public class DatabaseUiPlugin extends Plugin {
|
||||
@ -24,6 +25,7 @@ public class DatabaseUiPlugin extends Plugin {
|
||||
|
||||
@Override
|
||||
public void stop(BundleContext context) throws Exception {
|
||||
SWTResourceManager.dispose();
|
||||
getLog().log(new Status(IStatus.OK, "org.eclipse.e4.core", "Stopping org.eclipse.e4.core bundle..."));
|
||||
}
|
||||
}
|
@ -24,7 +24,6 @@ import org.eclipse.swt.graphics.Rectangle;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
|
||||
import com.minres.scviewer.database.IEvent;
|
||||
import com.minres.scviewer.database.IHierNode;
|
||||
import com.minres.scviewer.database.IWaveform;
|
||||
import com.minres.scviewer.database.RelationType;
|
||||
import com.minres.scviewer.database.tx.ITx;
|
||||
@ -76,14 +75,14 @@ public class ArrowPainter implements IPainter {
|
||||
this.tx = newTx;
|
||||
iRect = new LinkedList<>();
|
||||
oRect = new LinkedList<>();
|
||||
scaleFactor = waveCanvas.getScaleFactor();
|
||||
scaleFactor = waveCanvas.getScale();
|
||||
if (tx != null) {
|
||||
calculateGeometries();
|
||||
}
|
||||
}
|
||||
|
||||
private int getConcurrencyIndex(ITx tx) {
|
||||
IEvent[] eventList = tx.getStream().getEvents().floorEntry(tx.getBeginTime()).getValue();
|
||||
IEvent[] eventList = tx.getStream().getEventsBeforeTime(tx.getBeginTime());
|
||||
Optional<Integer> res = Arrays.stream(eventList).map(e -> ((ITxEvent)e).getRowIndex()).findFirst();
|
||||
return res.isPresent()? res.get():0;
|
||||
}
|
||||
@ -110,48 +109,23 @@ public class ArrowPainter implements IPainter {
|
||||
protected void deriveGeom(Collection<ITxRelation> relations, List<LinkEntry> res, boolean useTarget) {
|
||||
for (ITxRelation iTxRelation : relations) {
|
||||
ITx otherTx = useTarget ? iTxRelation.getTarget() : iTxRelation.getSource();
|
||||
Rectangle bb = createLinkEntry(otherTx, otherTx.getStream());
|
||||
if(bb!=null){
|
||||
res.add(new LinkEntry(bb, iTxRelation.getRelationType()));
|
||||
return;
|
||||
} else {
|
||||
for(IHierNode gen:otherTx.getStream().getChildNodes()) {
|
||||
if(gen instanceof IWaveform) {
|
||||
bb = createLinkEntry(otherTx, (IWaveform) gen);
|
||||
if(bb!=null){
|
||||
res.add(new LinkEntry(bb, iTxRelation.getRelationType()));
|
||||
return;
|
||||
}
|
||||
for(IWaveform iWaveform: new IWaveform[]{otherTx.getStream(), otherTx.getGenerator()}) {
|
||||
if (waveCanvas.wave2painterMap.containsKey(iWaveform)) {
|
||||
IWaveformPainter painter = waveCanvas.wave2painterMap.get(iWaveform);
|
||||
if(painter!=null) {
|
||||
int height = waveCanvas.styleProvider.getTrackHeight();
|
||||
Rectangle bb = new Rectangle(
|
||||
(int) (otherTx.getBeginTime() / scaleFactor),
|
||||
waveCanvas.rulerHeight + painter.getVerticalOffset() + height * getConcurrencyIndex(otherTx),
|
||||
(int) ((otherTx.getEndTime() - otherTx.getBeginTime()) / scaleFactor),
|
||||
height);
|
||||
res.add(new LinkEntry(bb, iTxRelation.getRelationType()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Rectangle createLinkEntry(ITx otherTx, IWaveform iWaveform) {
|
||||
if (waveCanvas.wave2painterMap.containsKey(iWaveform)) {
|
||||
IWaveformPainter painter = waveCanvas.wave2painterMap.get(otherTx.getStream());
|
||||
if(painter==null) {
|
||||
for(IHierNode gen:otherTx.getStream().getChildNodes()) {
|
||||
if(gen instanceof IWaveform) {
|
||||
painter = waveCanvas.wave2painterMap.get(gen);
|
||||
if(painter!=null)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(painter!=null) {
|
||||
int height = waveCanvas.styleProvider.getTrackHeight();
|
||||
return new Rectangle(
|
||||
(int) (otherTx.getBeginTime() / scaleFactor),
|
||||
waveCanvas.rulerHeight + painter.getVerticalOffset() + height * getConcurrencyIndex(otherTx),
|
||||
(int) ((otherTx.getEndTime() - otherTx.getBeginTime()) / scaleFactor),
|
||||
height);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintArea(Projection proj, Rectangle clientRect) {
|
||||
yCtrlOffset = waveCanvas.styleProvider.getTrackHeight()/2;
|
||||
@ -159,7 +133,7 @@ public class ArrowPainter implements IPainter {
|
||||
Color highliteColor = waveCanvas.styleProvider.getColor(WaveformColors.REL_ARROW_HIGHLITE);
|
||||
|
||||
if(tx==null) return;
|
||||
scaleFactor = waveCanvas.getScaleFactor();
|
||||
scaleFactor = waveCanvas.getScale();
|
||||
if(calculateGeometries())
|
||||
return;
|
||||
int correctionValue = (int)(selectionOffset);
|
||||
|
@ -65,7 +65,7 @@ public class CursorPainter implements IPainter, ICursor {
|
||||
Rectangle area = proj.unProject(clientRect);
|
||||
if(!waveCanvas.painterList.isEmpty()){
|
||||
|
||||
long scaleFactor=waveCanvas.getScaleFactor();
|
||||
long scaleFactor=waveCanvas.getScale();
|
||||
long beginPos = area.x;
|
||||
|
||||
maxPosX = area.x + area.width;
|
||||
@ -83,8 +83,7 @@ public class CursorPainter implements IPainter, ICursor {
|
||||
proj.drawLine(x, top, x, area.y+area.height);
|
||||
proj.setBackground(drawColor);
|
||||
proj.setForeground(textColor);
|
||||
double dTime=time;
|
||||
proj.drawText((dTime/waveCanvas.getScaleFactorPow10())+waveCanvas.getUnitStr(), x+1, top);
|
||||
proj.drawText(waveCanvas.timeToString(time), x+1, top);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user