Compare commits

..

96 Commits

Author SHA1 Message Date
97d6062c3f Merge branch 'release/2.19.4' 2024-02-11 12:59:13 +01:00
92428a3859 update version numbers 2024-02-11 12:58:44 +01:00
5f244dc03a fixes an multiple-load issue leading to NPE when adding empty generator
streams
2024-02-11 12:35:10 +01:00
64cc09d207 updates plugin settings to conform with Eclipse 2023-12 2024-02-11 12:34:12 +01:00
7af8b73bdd Merge branch 'release/2.19.3' 2024-01-27 15:11:44 +01:00
61bc407fb3 updates version numbers 2024-01-27 15:05:04 +01:00
f6a3da013e fixes some drawing and state restore issues 2024-01-27 14:58:55 +01:00
c4fafae029 fixes a missing increment statement 2024-01-27 14:57:15 +01:00
819e549d87 Merge branch 'release/2.19.1' 2024-01-24 06:31:00 +01:00
e472a092c3 updates version numbers 2024-01-23 17:51:02 +01:00
523c266e8d fixes locking issue preventing reload 2024-01-23 17:50:43 +01:00
db640808f2 updates packaged java version 2023-09-14 16:29:02 +02:00
09a55f1513 fixes some naming for the update site 2023-08-15 13:44:23 +02:00
088500afff update update site address 2023-08-11 14:02:49 +02:00
917a51ced7 Merge branch 'release/2.19.0' 2023-08-11 13:28:01 +02:00
c27354070c updates version numbers 2023-08-11 13:26:42 +02:00
9ca573efdb Merge branch 'release/2.19' 2023-08-11 13:15:51 +02:00
299c10363a Merge branch 'release/2.19' 2023-08-11 12:35:34 +02:00
36fdc68051 updates version and eclipse rcp version 2023-08-11 12:34:54 +02:00
53576f5e1b fixes load issue when using partial txlog files 2023-08-11 11:40:21 +02:00
abb8b45cd8 changes font handling for MultiBitStencil 2023-06-27 21:20:08 +02:00
e557e2c8d4 Merge branch 'develop' 2023-06-27 19:42:35 +02:00
aaf8a9e5d0 fixes bitvector conversion to hex number 2023-06-27 19:42:06 +02:00
c9a94334c4 fixes packaging to work without JS 2023-06-27 18:49:45 +02:00
8e7e977ac5 Merge branch 'develop' 2023-06-27 17:36:37 +02:00
24a362c277 adds some more test data 2023-06-27 17:33:10 +02:00
aa4659f8ef adds some more cleanup 2023-06-27 17:00:19 +02:00
81f37d4740 puts some cleanup 2023-06-27 16:56:03 +02:00
69c82ac9a8 adds some more test files 2023-06-27 16:29:26 +02:00
95c04c2240 updates images 2023-06-27 16:19:14 +02:00
be87792dad uadds and pdates some graphics and menu items 2023-06-27 16:01:13 +02:00
d1808ec1cf updates README.md 2023-06-27 10:39:36 +02:00
1a86104b19 fixes alignment issue in waveform canvas 2023-03-19 17:09:13 +01:00
dc4798b8ba implements visual improvements 2023-03-19 17:02:00 +01:00
3890a87a8c adds rendering of hierarchy indicator 2023-03-19 11:29:16 +01:00
d657843541 improves bit vector rendering 2023-03-19 11:28:44 +01:00
361a18b38e changes value representation in waves 2023-03-19 11:23:25 +01:00
354c4a4390 fixes signed/unsigned conversion for large integer sizes 2023-03-18 18:29:34 +01:00
65461ccc48 fixes unit test 2023-03-18 12:47:43 +01:00
654cf3f9e5 fixes visual handling of Tx not yet being loaded 2023-03-18 12:20:29 +01:00
6f2f5a388c fixes deferred loading of Tx when being referenced 2023-03-18 12:18:20 +01:00
f9d38b5091 adapts to extended database format 2023-03-18 10:13:10 +01:00
ba83c585f0 fixes missing block increment which prevents loading large dbs 2023-03-18 10:12:27 +01:00
14425b9102 fixes FST timescale calculation 2023-03-15 16:53:40 +01:00
1b7d4c3ed6 fixes FTR to delay tx chunk reading 2023-03-04 15:33:19 +01:00
b391d19303 updates time scale handling 2023-03-04 12:33:22 +01:00
bf38ccd6db updates test cases 2023-03-04 11:54:18 +01:00
567d62cea1 Merge branch 'develop' into feature/waveform_groups 2023-03-01 20:00:41 +01:00
6769513e2d fixes database reopening problem due to locking 2023-03-01 12:53:34 +01:00
f64a1baf02 rename BLANK to EMPY, enhances separator render, fixes menu selection 2023-03-01 09:21:11 +01:00
9be9671d3a adds configurable label to separator 2023-02-28 23:05:39 +01:00
c39ca8884a renames blank to separator 2023-02-28 13:23:42 +01:00
5670977d52 fixes color handling 2023-02-28 12:12:47 +01:00
463dad60b9 fixes color preferences handling 2023-02-28 12:03:34 +01:00
8a54ed3f6c Merge branch 'develop' into feature/waveform_groups 2023-02-28 11:30:12 +01:00
74f30e921f fixes imports 2023-02-28 11:29:28 +01:00
dbae0f1666 Merge branch 'develop' into feature/waveform_groups 2023-02-28 11:27:51 +01:00
52232bb0db adds blank entry for waveform viewer 2023-02-28 11:23:38 +01:00
6dfe6c8e2b adds blank entry for waveform viewer 2023-02-28 07:50:10 +01:00
a18f72c43f updates and cleans messages 2023-02-28 07:22:42 +01:00
ec471348f6 adds binary render option 2023-02-28 07:06:48 +01:00
b268b4b677 updates gitignore 2023-02-27 20:31:22 +01:00
da2cd03606 updates version numbers, fixes missing pom.xml 2023-02-27 20:29:41 +01:00
c45d7b5024 add windows fst library 2023-02-27 19:50:18 +01:00
1efb574a98 fixes missing dispose of resources 2023-02-27 15:56:15 +01:00
0105621be3 adds UI support and fixes a reading issue 2023-02-27 15:16:55 +01:00
e44e4d0a05 adds working FST reader implementation 2023-02-27 13:09:38 +01:00
299f76323f cleans interfaces up 2023-02-27 13:07:10 +01:00
bba4349e1e adds skeleton of FST plugin 2023-02-26 10:53:39 +01:00
85d9c92f21 fixes a tree display issue in transaction details view 2023-02-24 11:28:40 +01:00
cf663bcae5 Merge branch 'release/2.17.3' 2023-02-24 09:15:23 +01:00
2885cb9602 Merge branch 'release/2.17.3' into develop 2023-02-24 09:15:23 +01:00
31e79e453c updates version number 2023-02-24 09:15:10 +01:00
23a2f8d6c8 fixes data type numbering 2023-02-24 08:31:53 +01:00
ceaf52bfa1 fixes some divide by zero exception while drawing 2023-02-23 21:10:57 +01:00
7a98eda464 Merge branch 'release/2.17.2' 2023-02-23 15:51:49 +01:00
c8e587c1ea updates version numbers 2023-02-23 15:50:47 +01:00
d95683a146 fixes FTR reading and makes it more robust 2023-02-23 13:33:32 +01:00
07062d5618 updates target platform to 2022-12 2023-02-22 08:29:50 +01:00
e0b710efc4 sets target execution environment for launch configs 2023-02-22 07:56:28 +01:00
e0f174173c Merge branch 'release/2.17.1' 2023-02-22 07:47:27 +01:00
12a7c701e3 cleans imports and other warnings 2023-02-22 07:45:22 +01:00
cb259503cb Merge branch 'release/2.17.1' into develop 2023-02-22 07:30:43 +01:00
8aca26e499 Merge branch 'release/2.17.1' 2023-02-22 07:30:06 +01:00
ebf3f920bf updates version numbers 2023-02-22 07:29:26 +01:00
3b57ec029b adds support for compressed FTR 2023-02-22 07:24:02 +01:00
01c9b7f1c2 adds support for FTR chunk type 0 2023-02-22 06:14:17 +01:00
a737f5588d fixes entries in product definition 2023-02-21 20:03:59 +01:00
f7f512a5f3 Merge branch 'release/2.17.0' 2023-02-21 19:57:07 +01:00
8f838a96b7 Merge branch 'release/2.17.0' into develop 2023-02-21 19:57:07 +01:00
4d49e3b53f updates version numbers 2023-02-21 19:56:55 +01:00
b809042189 fixes removing traces 2023-02-21 19:24:13 +01:00
0e705ce0e9 adds initial version of FTR reader 2023-02-21 17:59:11 +01:00
25064f9744 externalizes strings 2022-09-30 15:29:16 +02:00
31fd54c6be adds update functionality for SCViewer 2022-09-30 14:23:54 +02:00
a1094ff870 Merge branch 'release/2.16.1' into develop 2022-06-12 20:58:31 +02:00
205 changed files with 16845 additions and 397346 deletions

1
.gitignore vendored
View File

@ -10,3 +10,4 @@ copyrightLog.txt
/workspace
?*.launch
/.settings/
.tycho-consumer-pom.xml

View File

@ -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,11 @@
<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_SHOW_CODEDETAILS_IN_EXCEPTION_MESSAGES" value="true"/>
<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.debug.ui.launcher.StandardVMType/JavaSE-17/"/>
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${project_loc:com.minres.scviewer.parent}"/>
</launchConfiguration>

View File

@ -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"/>
@ -8,12 +9,15 @@
<listAttribute key="M2_PROPERTIES"/>
<stringAttribute key="M2_RUNTIME" value="EMBEDDED"/>
<booleanAttribute key="M2_SKIP_TESTS" value="false"/>
<intAttribute key="M2_THREADS" value="1"/>
<intAttribute key="M2_THREADS" value="4"/>
<booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/>
<stringAttribute key="M2_USER_SETTINGS" value=""/>
<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="true"/>
<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_SHOW_CODEDETAILS_IN_EXCEPTION_MESSAGES" value="true"/>
<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.debug.ui.launcher.StandardVMType/JavaSE-17/"/>
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${project_loc:com.minres.scviewer.parent}"/>
</launchConfiguration>

View File

@ -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,11 @@
<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_SHOW_CODEDETAILS_IN_EXCEPTION_MESSAGES" value="true"/>
<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.debug.ui.launcher.StandardVMType/JavaSE-17/"/>
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${project_loc:com.minres.scviewer.parent}"/>
</launchConfiguration>

View File

@ -1,12 +1,8 @@
SCViewer
========
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.
> If you encounter issue when running on Linux please try running as `SWT_GTK3=0 scviewer` as there exist issues wiht GTK3.
SCViewer is composed of a set of eclipse plugins to display VCD (e.g. created by SystemC VCD trace) and transaction streams. Those streams can be
created by the SystemC Verification Library (SCV, For further description of the SCV please refer to https://www.accellera.org/activities/working-groups/systemc-verification) or by the **L**ight**w**eight **T**ranasaction **R**ecording for SystemC ( [LWTR4SC](https://github.com/Minres/LWTR4SC) ).
The viewer has the following features
- support of VCD files (compressed and uncompressed)
@ -18,6 +14,8 @@ The viewer has the following features
- sqlite based
- visualization of transaction relations
> If you encounter issue when running on Linux please try running as `SWT_GTK3=0 scviewer` as there exist issues wiht GTK3.
To build the plugins the Eclipse SDK or PDE can be used.
Key Shortcuts

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8

View File

@ -7,7 +7,7 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.16.1</version>
<version>2.19.4</version>
<relativePath>../..</relativePath>
</parent>

View File

@ -70,4 +70,19 @@ 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"/>
<plugin
id="com.minres.scviewer.database.fst"
os="linux,win32"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
</feature>

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.16.1</version>
<version>2.19.4</version>
<relativePath>../..</relativePath>
</parent>
<version>3.0.0-SNAPSHOT</version>

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.16.1</version>
<version>2.19.4</version>
<relativePath>../..</relativePath>
</parent>
<version>1.1.0-SNAPSHOT</version>

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8

View File

@ -66,22 +66,6 @@
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"
@ -89,20 +73,6 @@
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"

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.16.1</version>
<version>2.19.4</version>
<relativePath>../..</relativePath>
</parent>
<version>1.0.0-SNAPSHOT</version>

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.16.1</version>
<version>2.19.4</version>
<relativePath>../..</relativePath>
</parent>
<version>1.0.0-SNAPSHOT</version>

View File

@ -2,7 +2,7 @@
<feature
id="com.minres.scviewer.feature"
label="%featureName"
version="1.1.0.qualifier"
version="2.19.4"
provider-name="%providerName">
<description>
@ -46,22 +46,14 @@ http://www.eclipse.org/legal/epl-v10.html
<plugin
id="org.junit"
download-size="0"
install-size="0"
version="0.0.0"/>
<plugin
id="org.hamcrest.core"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
version="0.0.0"/>
<plugin
id="com.minres.scviewer.ui"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
version="0.0.0"/>
</feature>

View File

@ -5,8 +5,7 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.16.1</version>
<version>2.19.4</version>
<relativePath>../..</relativePath>
</parent>
<version>1.1.0-SNAPSHOT</version>
</project>

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.16.1</version>
<version>2.19.4</version>
<relativePath>../..</relativePath>
</parent>
<version>1.1.0-SNAPSHOT</version>

View File

@ -0,0 +1,17 @@
<?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-17">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="lib" path="lib/jna-5.13.0.jar" sourcepath="lib/jna-5.13.0-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:platform:/resource/com.minres.scviewer.database.fst/lib/jna-5.13.0-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="lib/jna-jpms-5.13.0.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -0,0 +1,3 @@
/bin/
/.settings/
/target/

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.minres.scviewer.database.fst</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>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,17 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: FST signal database
Bundle-SymbolicName: com.minres.scviewer.database.fst
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: MINRES Technologies GmbH
Bundle-RequiredExecutionEnvironment: JavaSE-17
Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0",
org.eclipse.osgi.services;bundle-version="3.4.0",
com.google.guava;bundle-version="15.0.0"
Service-Component: OSGI-INF/component.xml
Bundle-ActivationPolicy: lazy
Bundle-ClassPath: lib/jna-5.13.0.jar,
lib/jna-jpms-5.13.0.jar,
.
Automatic-Module-Name: com.minres.scviewer.database.fst
Import-Package: org.osgi.framework;version="1.10.0"

View File

@ -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="FstDbLoaderFactory">
<implementation class="com.minres.scviewer.database.fst.FstDbLoaderFactory"/>
<service>
<provide interface="com.minres.scviewer.database.IWaveformDbLoaderFactory"/>
</service>
</scr:component>

View File

@ -0,0 +1,9 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
lib/jna-5.13.0.jar,\
lib/jna-jpms-5.13.0.jar,\
linux-x86-64/,\
win32-x86-64/,\
OSGI-INF/

View File

@ -0,0 +1 @@
/build/

View File

@ -0,0 +1,35 @@
cmake_minimum_required (VERSION 3.0)
project (fstlib VERSION 1.0.0)
set(BUILD_SHARED_LIBS ON)
#find_package(ZLIB REQUIRED)
include(FetchContent)
FetchContent_Declare(
zlib
URL https://www.zlib.net/zlib-1.2.13.tar.gz
https://www.zlib.net/fossils/zlib-1.2.13.tar.gz
https://github.com/madler/zlib/releases/download/v1.2.13/zlib-1.2.13.tar.gz
URL_HASH MD5=9b8aa094c4e5765dabf4da391f00d15c
)
FetchContent_Populate(zlib)
add_subdirectory(${zlib_SOURCE_DIR} ${zlib_BINARY_DIR} EXCLUDE_FROM_ALL)
add_library(ZLIB::ZLIB ALIAS zlibstatic)
target_include_directories(zlibstatic INTERFACE ${zlib_BINARY_DIR} ${zlib_SOURCE_DIR})
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
add_library(fstapi fstapi.c lz4.c fastlz.c fst_helper.c)
#target_include_directories(fstapi PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${ZLIB_INCLUDE_DIRS})
target_link_libraries(fstapi PRIVATE zlibstatic)
# hack to avoid creating dummy config.h
target_compile_definitions(fstapi PRIVATE -DFST_CONFIG_INCLUDE="fstapi.h")
if(MSVC)
# define __MINGW32__ to minimize changes to upstream
target_compile_definitions(fstapi PRIVATE __MINGW32__ _CRT_SECURE_NO_WARNINGS FST_DO_MISALIGNED_OPS)
target_compile_options(fstapi PRIVATE /wd4244 /wd4267 /wd4146 /wd4996)
endif()
install(TARGETS fstapi
LIBRARY DESTINATION .
RUNTIME DESTINATION .)

View File

@ -0,0 +1,130 @@
See fstapi.h for the values for the FST_BL_XXX enums.
===========================================================================
compressed wrapper (typically over whole file)
uint8_t FST_BL_ZWRAPPER
uint64_t section length
uint64_t length of uncompressed data
[zlib compressed data]
===========================================================================
header block
uint8_t FST_BL_HDR
uint64_t section length
uint64_t start time
uint64_t end time
double endian test for "e"
uint64_t memory used by writer
uint64_t scope creation count
uint64_t var creation count
uint64_t max var idcode
uint64_t vc section count
int8_t timescale exponent
[128 bytes] version
[128 bytes] date
===========================================================================
geometry block
uint8_t FST_BL_GEOM
uint64_t section length
uint64_t length of uncompressed geometry data
uint64_t maxhandle
[compressed data]
(length of compressed data is section length - 24)
===========================================================================
hierarchy block
uint8_t FST_BL_HIER
uint64_t section length
uint64_t length of uncompressed hier data
[zlib compressed data]
or
uint8_t FST_BL_HIER_LZ4
uint64_t section length
uint64_t length of uncompressed hier data
[lz4 compressed data]
uint8_t FST_BL_HIER_LZ4DUO
uint64_t section length
uint64_t length of uncompressed hier data
varint length of hier data compressed once with lz4
[lz4 double compressed data]
===========================================================================
dumpon/off block
uint8_t FST_BL_BLACKOUT
uint64_t section length
varint num blackouts (section below is repeated this # times)
[
uint8_t on/off (nonzero = on)
varint delta time
]
===========================================================================
1..n value change blocks:
// header
uint8_t FST_BL_VCDATA (or FST_BL_VCDATA_DYN_ALIAS)
uint64_t section length
uint64_t begin time of section
uint64_t end time of section
uint64_t amount of buffer memory required in reader for full vc traversal
varint maxvalpos (length of uncompressed data)
varint length of compressed data
varint maxhandle associated with this checkpoint data
[compressed data]
---
// value changes
varint maxhandle associated with the value change data
uint8_t pack type ('F' is fastlz, '4' is lz4,
others ['Z'/'!'] are zlib)
varint chain 0 compressed data length (0 = uncompressed)
[compressed data]
...
varint chain n compressed data length (0 = uncompressed)
[compressed data]
---
// index: chain pointer table (from 0..maxhandle-1)
varint if &1 == 1, this is <<1 literal delta
if &1 == 0, this is <<1 RLE count of zeros
if == 0, next varint is handle of prev chain to use,
bit only if FST_BL_VCDATA_DYN_ALIAS or
later VCDATA format
---
uint64_t index length (subtract from here to get index position)
---
[compressed data for time section]
uint64_t uncompressed data length in bytes
uint64_t compressed data length in bytes
uint64_t number of time items
// end of section
===========================================================================

View File

@ -0,0 +1,2 @@
cmake -B build -S . -DCMAKE_INSTALL_PREFIX=../../win32-x86-64
cmake --build build --target install --config Release

View File

@ -0,0 +1,2 @@
cmake -B build -S . -DCMAKE_INSTALL_PREFIX=../../linux-x86-64 -DCMAKE_BUILD_TYPE=Release
cmake --build build --target install

View File

@ -0,0 +1,549 @@
/*
FastLZ - lightning-fast lossless compression library
Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
Copyright (C) 2005 Ariya Hidayat (ariya@kde.org)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
SPDX-License-Identifier: MIT
*/
#include "fastlz.h"
#if !defined(FASTLZ__COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR)
/*
* Always check for bound when decompressing.
* Generally it is best to leave it defined.
*/
#define FASTLZ_SAFE
/*
* Give hints to the compiler for branch prediction optimization.
*/
#if defined(__GNUC__) && (__GNUC__ > 2)
#define FASTLZ_EXPECT_CONDITIONAL(c) (__builtin_expect((c), 1))
#define FASTLZ_UNEXPECT_CONDITIONAL(c) (__builtin_expect((c), 0))
#else
#define FASTLZ_EXPECT_CONDITIONAL(c) (c)
#define FASTLZ_UNEXPECT_CONDITIONAL(c) (c)
#endif
/*
* Use inlined functions for supported systems.
*/
#if defined(__GNUC__) || defined(__DMC__) || defined(__POCC__) || defined(__WATCOMC__) || defined(__SUNPRO_C)
#define FASTLZ_INLINE inline
#elif defined(__BORLANDC__) || defined(_MSC_VER) || defined(__LCC__)
#define FASTLZ_INLINE __inline
#else
#define FASTLZ_INLINE
#endif
/*
* Prevent accessing more than 8-bit at once, except on x86 architectures.
*/
#if !defined(FASTLZ_STRICT_ALIGN)
#define FASTLZ_STRICT_ALIGN
#if defined(__i386__) || defined(__386) /* GNU C, Sun Studio */
#undef FASTLZ_STRICT_ALIGN
#elif defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(__amd64) /* GNU C */
#undef FASTLZ_STRICT_ALIGN
#elif defined(_M_IX86) /* Intel, MSVC */
#undef FASTLZ_STRICT_ALIGN
#elif defined(__386)
#undef FASTLZ_STRICT_ALIGN
#elif defined(_X86_) /* MinGW */
#undef FASTLZ_STRICT_ALIGN
#elif defined(__I86__) /* Digital Mars */
#undef FASTLZ_STRICT_ALIGN
#endif
#endif
/* prototypes */
int fastlz_compress(const void* input, int length, void* output);
int fastlz_compress_level(int level, const void* input, int length, void* output);
int fastlz_decompress(const void* input, int length, void* output, int maxout);
#define MAX_COPY 32
#define MAX_LEN 264 /* 256 + 8 */
#define MAX_DISTANCE 8192
#if !defined(FASTLZ_STRICT_ALIGN)
#define FASTLZ_READU16(p) *((const flzuint16*)(p))
#else
#define FASTLZ_READU16(p) ((p)[0] | (p)[1]<<8)
#endif
#define HASH_LOG 13
#define HASH_SIZE (1<< HASH_LOG)
#define HASH_MASK (HASH_SIZE-1)
#define HASH_FUNCTION(v,p) { v = FASTLZ_READU16(p); v ^= FASTLZ_READU16(p+1)^(v>>(16-HASH_LOG));v &= HASH_MASK; }
#undef FASTLZ_LEVEL
#define FASTLZ_LEVEL 1
#undef FASTLZ_COMPRESSOR
#undef FASTLZ_DECOMPRESSOR
#define FASTLZ_COMPRESSOR fastlz1_compress
#define FASTLZ_DECOMPRESSOR fastlz1_decompress
static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output);
static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout);
#include "fastlz.c"
#undef FASTLZ_LEVEL
#define FASTLZ_LEVEL 2
#undef MAX_DISTANCE
#define MAX_DISTANCE 8191
#define MAX_FARDISTANCE (65535+MAX_DISTANCE-1)
#undef FASTLZ_COMPRESSOR
#undef FASTLZ_DECOMPRESSOR
#define FASTLZ_COMPRESSOR fastlz2_compress
#define FASTLZ_DECOMPRESSOR fastlz2_decompress
static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output);
static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout);
#include "fastlz.c"
int fastlz_compress(const void* input, int length, void* output)
{
/* for short block, choose fastlz1 */
if(length < 65536)
return fastlz1_compress(input, length, output);
/* else... */
return fastlz2_compress(input, length, output);
}
int fastlz_decompress(const void* input, int length, void* output, int maxout)
{
/* magic identifier for compression level */
int level = ((*(const flzuint8*)input) >> 5) + 1;
if(level == 1)
return fastlz1_decompress(input, length, output, maxout);
if(level == 2)
return fastlz2_decompress(input, length, output, maxout);
/* unknown level, trigger error */
return 0;
}
int fastlz_compress_level(int level, const void* input, int length, void* output)
{
if(level == 1)
return fastlz1_compress(input, length, output);
if(level == 2)
return fastlz2_compress(input, length, output);
return 0;
}
#else /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */
static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output)
{
const flzuint8* ip = (const flzuint8*) input;
const flzuint8* ip_bound = ip + length - 2;
const flzuint8* ip_limit = ip + length - 12;
flzuint8* op = (flzuint8*) output;
const flzuint8* htab[HASH_SIZE];
const flzuint8** hslot;
flzuint32 hval;
flzuint32 copy;
/* sanity check */
if(FASTLZ_UNEXPECT_CONDITIONAL(length < 4))
{
if(length)
{
/* create literal copy only */
*op++ = length-1;
ip_bound++;
while(ip <= ip_bound)
*op++ = *ip++;
return length+1;
}
else
return 0;
}
/* initializes hash table */
for (hslot = htab; hslot < htab + HASH_SIZE; hslot++)
*hslot = ip;
/* we start with literal copy */
copy = 2;
*op++ = MAX_COPY-1;
*op++ = *ip++;
*op++ = *ip++;
/* main loop */
while(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit))
{
const flzuint8* ref;
flzuint32 distance;
/* minimum match length */
flzuint32 len = 3;
/* comparison starting-point */
const flzuint8* anchor = ip;
/* check for a run */
#if FASTLZ_LEVEL==2
if(ip[0] == ip[-1] && FASTLZ_READU16(ip-1)==FASTLZ_READU16(ip+1))
{
distance = 1;
/* ip += 3; */ /* scan-build, never used */
ref = anchor - 1 + 3;
goto match;
}
#endif
/* find potential match */
HASH_FUNCTION(hval,ip);
hslot = htab + hval;
ref = htab[hval];
/* calculate distance to the match */
distance = anchor - ref;
/* update hash table */
*hslot = anchor;
/* is this a match? check the first 3 bytes */
if(distance==0 ||
#if FASTLZ_LEVEL==1
(distance >= MAX_DISTANCE) ||
#else
(distance >= MAX_FARDISTANCE) ||
#endif
*ref++ != *ip++ || *ref++!=*ip++ || *ref++!=*ip++)
goto literal;
#if FASTLZ_LEVEL==2
/* far, needs at least 5-byte match */
if(distance >= MAX_DISTANCE)
{
if(*ip++ != *ref++ || *ip++!= *ref++)
goto literal;
len += 2;
}
match:
#endif
/* last matched byte */
ip = anchor + len;
/* distance is biased */
distance--;
if(!distance)
{
/* zero distance means a run */
flzuint8 x = ip[-1];
while(ip < ip_bound)
if(*ref++ != x) break; else ip++;
}
else
for(;;)
{
/* safe because the outer check against ip limit */
if(*ref++ != *ip++) break;
if(*ref++ != *ip++) break;
if(*ref++ != *ip++) break;
if(*ref++ != *ip++) break;
if(*ref++ != *ip++) break;
if(*ref++ != *ip++) break;
if(*ref++ != *ip++) break;
if(*ref++ != *ip++) break;
while(ip < ip_bound)
if(*ref++ != *ip++) break;
break;
}
/* if we have copied something, adjust the copy count */
if(copy)
/* copy is biased, '0' means 1 byte copy */
*(op-copy-1) = copy-1;
else
/* back, to overwrite the copy count */
op--;
/* reset literal counter */
copy = 0;
/* length is biased, '1' means a match of 3 bytes */
ip -= 3;
len = ip - anchor;
/* encode the match */
#if FASTLZ_LEVEL==2
if(distance < MAX_DISTANCE)
{
if(len < 7)
{
*op++ = (len << 5) + (distance >> 8);
*op++ = (distance & 255);
}
else
{
*op++ = (7 << 5) + (distance >> 8);
for(len-=7; len >= 255; len-= 255)
*op++ = 255;
*op++ = len;
*op++ = (distance & 255);
}
}
else
{
/* far away, but not yet in the another galaxy... */
if(len < 7)
{
distance -= MAX_DISTANCE;
*op++ = (len << 5) + 31;
*op++ = 255;
*op++ = distance >> 8;
*op++ = distance & 255;
}
else
{
distance -= MAX_DISTANCE;
*op++ = (7 << 5) + 31;
for(len-=7; len >= 255; len-= 255)
*op++ = 255;
*op++ = len;
*op++ = 255;
*op++ = distance >> 8;
*op++ = distance & 255;
}
}
#else
if(FASTLZ_UNEXPECT_CONDITIONAL(len > MAX_LEN-2))
while(len > MAX_LEN-2)
{
*op++ = (7 << 5) + (distance >> 8);
*op++ = MAX_LEN - 2 - 7 -2;
*op++ = (distance & 255);
len -= MAX_LEN-2;
}
if(len < 7)
{
*op++ = (len << 5) + (distance >> 8);
*op++ = (distance & 255);
}
else
{
*op++ = (7 << 5) + (distance >> 8);
*op++ = len - 7;
*op++ = (distance & 255);
}
#endif
/* update the hash at match boundary */
HASH_FUNCTION(hval,ip);
htab[hval] = ip++;
HASH_FUNCTION(hval,ip);
htab[hval] = ip++;
/* assuming literal copy */
*op++ = MAX_COPY-1;
continue;
literal:
*op++ = *anchor++;
ip = anchor;
copy++;
if(FASTLZ_UNEXPECT_CONDITIONAL(copy == MAX_COPY))
{
copy = 0;
*op++ = MAX_COPY-1;
}
}
/* left-over as literal copy */
ip_bound++;
while(ip <= ip_bound)
{
*op++ = *ip++;
copy++;
if(copy == MAX_COPY)
{
copy = 0;
*op++ = MAX_COPY-1;
}
}
/* if we have copied something, adjust the copy length */
if(copy)
*(op-copy-1) = copy-1;
else
op--;
#if FASTLZ_LEVEL==2
/* marker for fastlz2 */
*(flzuint8*)output |= (1 << 5);
#endif
return op - (flzuint8*)output;
}
static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout)
{
const flzuint8* ip = (const flzuint8*) input;
const flzuint8* ip_limit = ip + length;
flzuint8* op = (flzuint8*) output;
flzuint8* op_limit = op + maxout;
flzuint32 ctrl = (*ip++) & 31;
int loop = 1;
do
{
const flzuint8* ref = op;
flzuint32 len = ctrl >> 5;
flzuint32 ofs = (ctrl & 31) << 8;
if(ctrl >= 32)
{
#if FASTLZ_LEVEL==2
flzuint8 code;
#endif
len--;
ref -= ofs;
if (len == 7-1)
#if FASTLZ_LEVEL==1
len += *ip++;
ref -= *ip++;
#else
do
{
code = *ip++;
len += code;
} while (code==255);
code = *ip++;
ref -= code;
/* match from 16-bit distance */
if(FASTLZ_UNEXPECT_CONDITIONAL(code==255))
if(FASTLZ_EXPECT_CONDITIONAL(ofs==(31 << 8)))
{
ofs = (*ip++) << 8;
ofs += *ip++;
ref = op - ofs - MAX_DISTANCE;
}
#endif
#ifdef FASTLZ_SAFE
if (FASTLZ_UNEXPECT_CONDITIONAL(op + len + 3 > op_limit))
return 0;
if (FASTLZ_UNEXPECT_CONDITIONAL(ref-1 < (flzuint8 *)output))
return 0;
#endif
if(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit))
ctrl = *ip++;
else
loop = 0;
if(ref == op)
{
/* optimize copy for a run */
flzuint8 b = ref[-1];
*op++ = b;
*op++ = b;
*op++ = b;
for(; len; --len)
*op++ = b;
}
else
{
#if !defined(FASTLZ_STRICT_ALIGN)
const flzuint16* p;
flzuint16* q;
#endif
/* copy from reference */
ref--;
*op++ = *ref++;
*op++ = *ref++;
*op++ = *ref++;
#if !defined(FASTLZ_STRICT_ALIGN)
/* copy a byte, so that now it's word aligned */
if(len & 1)
{
*op++ = *ref++;
len--;
}
/* copy 16-bit at once */
q = (flzuint16*) op;
op += len;
p = (const flzuint16*) ref;
for(len>>=1; len > 4; len-=4)
{
*q++ = *p++;
*q++ = *p++;
*q++ = *p++;
*q++ = *p++;
}
for(; len; --len)
*q++ = *p++;
#else
for(; len; --len)
*op++ = *ref++;
#endif
}
}
else
{
ctrl++;
#ifdef FASTLZ_SAFE
if (FASTLZ_UNEXPECT_CONDITIONAL(op + ctrl > op_limit))
return 0;
if (FASTLZ_UNEXPECT_CONDITIONAL(ip + ctrl > ip_limit))
return 0;
#endif
*op++ = *ip++;
for(--ctrl; ctrl; ctrl--)
*op++ = *ip++;
loop = FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit);
if(loop)
ctrl = *ip++;
}
}
while(FASTLZ_EXPECT_CONDITIONAL(loop));
return op - (flzuint8*)output;
}
#endif /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */

View File

@ -0,0 +1,109 @@
/*
FastLZ - lightning-fast lossless compression library
Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
Copyright (C) 2005 Ariya Hidayat (ariya@kde.org)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
SPDX-License-Identifier: MIT
*/
#ifndef FASTLZ_H
#define FASTLZ_H
#include <inttypes.h>
#define flzuint8 uint8_t
#define flzuint16 uint16_t
#define flzuint32 uint32_t
#define FASTLZ_VERSION 0x000100
#define FASTLZ_VERSION_MAJOR 0
#define FASTLZ_VERSION_MINOR 0
#define FASTLZ_VERSION_REVISION 0
#define FASTLZ_VERSION_STRING "0.1.0"
#if defined (__cplusplus)
extern "C" {
#endif
/**
Compress a block of data in the input buffer and returns the size of
compressed block. The size of input buffer is specified by length. The
minimum input buffer size is 16.
The output buffer must be at least 5% larger than the input buffer
and can not be smaller than 66 bytes.
If the input is not compressible, the return value might be larger than
length (input buffer size).
The input buffer and the output buffer can not overlap.
*/
int fastlz_compress(const void* input, int length, void* output);
/**
Decompress a block of compressed data and returns the size of the
decompressed block. If error occurs, e.g. the compressed data is
corrupted or the output buffer is not large enough, then 0 (zero)
will be returned instead.
The input buffer and the output buffer can not overlap.
Decompression is memory safe and guaranteed not to write the output buffer
more than what is specified in maxout.
*/
int fastlz_decompress(const void* input, int length, void* output, int maxout);
/**
Compress a block of data in the input buffer and returns the size of
compressed block. The size of input buffer is specified by length. The
minimum input buffer size is 16.
The output buffer must be at least 5% larger than the input buffer
and can not be smaller than 66 bytes.
If the input is not compressible, the return value might be larger than
length (input buffer size).
The input buffer and the output buffer can not overlap.
Compression level can be specified in parameter level. At the moment,
only level 1 and level 2 are supported.
Level 1 is the fastest compression and generally useful for short data.
Level 2 is slightly slower but it gives better compression ratio.
Note that the compressed data, regardless of the level, can always be
decompressed using the function fastlz_decompress above.
*/
int fastlz_compress_level(int level, const void* input, int length, void* output);
#if defined (__cplusplus)
}
#endif
#endif /* FASTLZ_H */

View File

@ -0,0 +1,31 @@
#include "fstapi.h"
int getHierType(struct fstHier * hier){
return hier->htyp;
}
void getHierScope(struct fstHier* h, struct fstHierScope* scope){
if(h->htyp==FST_HT_SCOPE)
*scope=h->u.scope;
}
void getHierVar(struct fstHier* h, struct fstHierVar* var){
if(h->htyp==FST_HT_VAR)
*var=h->u.var;
}
void getHierAttr(struct fstHier* h, struct fstHierAttr* attr){
if(h->htyp==FST_HT_ATTRBEGIN)
*attr=h->u.attr;
}
typedef void (*value_change_callback)(uint64_t time, fstHandle facidx, const char *value);
static void forward_cb(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value) {
//fprintf(stderr, "val: %s @ %ld\n", value, time);
((value_change_callback)user_callback_data_pointer)(time, facidx, value);
}
void iterateValueChanges(void* ctx, value_change_callback vcc) {
fstReaderIterBlocks(ctx, forward_cb, vcc, NULL);
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2009-2018 Tony Bybell.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* SPDX-License-Identifier: MIT
*/
#ifndef WIN_UNISTD_H
#define WIN_UNISTD_H
#include <stdlib.h>
#ifdef _WIN64
#include <io.h>
#else
#include <sys/io.h>
#endif
#include <process.h>
#define ftruncate _chsize_s
#define unlink _unlink
#define fileno _fileno
#define lseek _lseeki64
#ifdef _WIN64
#define ssize_t __int64
#define SSIZE_MAX 9223372036854775807i64
#else
#define ssize_t long
#define SSIZE_MAX 2147483647L
#endif
#include "stdint.h"
#endif //WIN_UNISTD_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,466 @@
/*
* Copyright (c) 2009-2018 Tony Bybell.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* SPDX-License-Identifier: MIT
*/
#ifndef FST_API_H
#define FST_API_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <zlib.h>
#include <inttypes.h>
#if defined(_MSC_VER)
#include "fst_win_unistd.h"
#else
#include <unistd.h>
#endif
#include <time.h>
#define FST_RDLOAD "FSTLOAD | "
typedef uint32_t fstHandle;
typedef uint32_t fstEnumHandle;
enum fstWriterPackType {
FST_WR_PT_ZLIB = 0,
FST_WR_PT_FASTLZ = 1,
FST_WR_PT_LZ4 = 2
};
enum fstFileType {
FST_FT_MIN = 0,
FST_FT_VERILOG = 0,
FST_FT_VHDL = 1,
FST_FT_VERILOG_VHDL = 2,
FST_FT_MAX = 2
};
enum fstBlockType {
FST_BL_HDR = 0,
FST_BL_VCDATA = 1,
FST_BL_BLACKOUT = 2,
FST_BL_GEOM = 3,
FST_BL_HIER = 4,
FST_BL_VCDATA_DYN_ALIAS = 5,
FST_BL_HIER_LZ4 = 6,
FST_BL_HIER_LZ4DUO = 7,
FST_BL_VCDATA_DYN_ALIAS2 = 8,
FST_BL_ZWRAPPER = 254, /* indicates that whole trace is gz wrapped */
FST_BL_SKIP = 255 /* used while block is being written */
};
enum fstScopeType {
FST_ST_MIN = 0,
FST_ST_VCD_MODULE = 0,
FST_ST_VCD_TASK = 1,
FST_ST_VCD_FUNCTION = 2,
FST_ST_VCD_BEGIN = 3,
FST_ST_VCD_FORK = 4,
FST_ST_VCD_GENERATE = 5,
FST_ST_VCD_STRUCT = 6,
FST_ST_VCD_UNION = 7,
FST_ST_VCD_CLASS = 8,
FST_ST_VCD_INTERFACE = 9,
FST_ST_VCD_PACKAGE = 10,
FST_ST_VCD_PROGRAM = 11,
FST_ST_VHDL_ARCHITECTURE = 12,
FST_ST_VHDL_PROCEDURE = 13,
FST_ST_VHDL_FUNCTION = 14,
FST_ST_VHDL_RECORD = 15,
FST_ST_VHDL_PROCESS = 16,
FST_ST_VHDL_BLOCK = 17,
FST_ST_VHDL_FOR_GENERATE = 18,
FST_ST_VHDL_IF_GENERATE = 19,
FST_ST_VHDL_GENERATE = 20,
FST_ST_VHDL_PACKAGE = 21,
FST_ST_MAX = 21,
FST_ST_GEN_ATTRBEGIN = 252,
FST_ST_GEN_ATTREND = 253,
FST_ST_VCD_SCOPE = 254,
FST_ST_VCD_UPSCOPE = 255
};
enum fstVarType {
FST_VT_MIN = 0, /* start of vartypes */
FST_VT_VCD_EVENT = 0,
FST_VT_VCD_INTEGER = 1,
FST_VT_VCD_PARAMETER = 2,
FST_VT_VCD_REAL = 3,
FST_VT_VCD_REAL_PARAMETER = 4,
FST_VT_VCD_REG = 5,
FST_VT_VCD_SUPPLY0 = 6,
FST_VT_VCD_SUPPLY1 = 7,
FST_VT_VCD_TIME = 8,
FST_VT_VCD_TRI = 9,
FST_VT_VCD_TRIAND = 10,
FST_VT_VCD_TRIOR = 11,
FST_VT_VCD_TRIREG = 12,
FST_VT_VCD_TRI0 = 13,
FST_VT_VCD_TRI1 = 14,
FST_VT_VCD_WAND = 15,
FST_VT_VCD_WIRE = 16,
FST_VT_VCD_WOR = 17,
FST_VT_VCD_PORT = 18,
FST_VT_VCD_SPARRAY = 19, /* used to define the rownum (index) port for a sparse array */
FST_VT_VCD_REALTIME = 20,
FST_VT_GEN_STRING = 21, /* generic string type (max len is defined dynamically via fstWriterEmitVariableLengthValueChange) */
FST_VT_SV_BIT = 22,
FST_VT_SV_LOGIC = 23,
FST_VT_SV_INT = 24, /* declare as size = 32 */
FST_VT_SV_SHORTINT = 25, /* declare as size = 16 */
FST_VT_SV_LONGINT = 26, /* declare as size = 64 */
FST_VT_SV_BYTE = 27, /* declare as size = 8 */
FST_VT_SV_ENUM = 28, /* declare as appropriate type range */
FST_VT_SV_SHORTREAL = 29, /* declare and emit same as FST_VT_VCD_REAL (needs to be emitted as double, not a float) */
FST_VT_MAX = 29 /* end of vartypes */
};
enum fstVarDir {
FST_VD_MIN = 0,
FST_VD_IMPLICIT = 0,
FST_VD_INPUT = 1,
FST_VD_OUTPUT = 2,
FST_VD_INOUT = 3,
FST_VD_BUFFER = 4,
FST_VD_LINKAGE = 5,
FST_VD_MAX = 5
};
enum fstHierType {
FST_HT_MIN = 0,
FST_HT_SCOPE = 0,
FST_HT_UPSCOPE = 1,
FST_HT_VAR = 2,
FST_HT_ATTRBEGIN = 3,
FST_HT_ATTREND = 4,
/* FST_HT_TREEBEGIN and FST_HT_TREEEND are not yet used by FST but are currently used when fstHier bridges other formats */
FST_HT_TREEBEGIN = 5,
FST_HT_TREEEND = 6,
FST_HT_MAX = 6
};
enum fstAttrType {
FST_AT_MIN = 0,
FST_AT_MISC = 0, /* self-contained: does not need matching FST_HT_ATTREND */
FST_AT_ARRAY = 1,
FST_AT_ENUM = 2,
FST_AT_PACK = 3,
FST_AT_MAX = 3
};
enum fstMiscType {
FST_MT_MIN = 0,
FST_MT_COMMENT = 0, /* use fstWriterSetComment() to emit */
FST_MT_ENVVAR = 1, /* use fstWriterSetEnvVar() to emit */
FST_MT_SUPVAR = 2, /* use fstWriterCreateVar2() to emit */
FST_MT_PATHNAME = 3, /* reserved for fstWriterSetSourceStem() string -> number management */
FST_MT_SOURCESTEM = 4, /* use fstWriterSetSourceStem() to emit */
FST_MT_SOURCEISTEM = 5, /* use fstWriterSetSourceInstantiationStem() to emit */
FST_MT_VALUELIST = 6, /* use fstWriterSetValueList() to emit, followed by fstWriterCreateVar*() */
FST_MT_ENUMTABLE = 7, /* use fstWriterCreateEnumTable() and fstWriterEmitEnumTableRef() to emit */
FST_MT_UNKNOWN = 8,
FST_MT_MAX = 8
};
enum fstArrayType {
FST_AR_MIN = 0,
FST_AR_NONE = 0,
FST_AR_UNPACKED = 1,
FST_AR_PACKED = 2,
FST_AR_SPARSE = 3,
FST_AR_MAX = 3
};
enum fstEnumValueType {
FST_EV_SV_INTEGER = 0,
FST_EV_SV_BIT = 1,
FST_EV_SV_LOGIC = 2,
FST_EV_SV_INT = 3,
FST_EV_SV_SHORTINT = 4,
FST_EV_SV_LONGINT = 5,
FST_EV_SV_BYTE = 6,
FST_EV_SV_UNSIGNED_INTEGER = 7,
FST_EV_SV_UNSIGNED_BIT = 8,
FST_EV_SV_UNSIGNED_LOGIC = 9,
FST_EV_SV_UNSIGNED_INT = 10,
FST_EV_SV_UNSIGNED_SHORTINT = 11,
FST_EV_SV_UNSIGNED_LONGINT = 12,
FST_EV_SV_UNSIGNED_BYTE = 13,
FST_EV_REG = 14,
FST_EV_TIME = 15,
FST_EV_MAX = 15
};
enum fstPackType {
FST_PT_NONE = 0,
FST_PT_UNPACKED = 1,
FST_PT_PACKED = 2,
FST_PT_TAGGED_PACKED = 3,
FST_PT_MAX = 3
};
enum fstSupplementalVarType {
FST_SVT_MIN = 0,
FST_SVT_NONE = 0,
FST_SVT_VHDL_SIGNAL = 1,
FST_SVT_VHDL_VARIABLE = 2,
FST_SVT_VHDL_CONSTANT = 3,
FST_SVT_VHDL_FILE = 4,
FST_SVT_VHDL_MEMORY = 5,
FST_SVT_MAX = 5
};
enum fstSupplementalDataType {
FST_SDT_MIN = 0,
FST_SDT_NONE = 0,
FST_SDT_VHDL_BOOLEAN = 1,
FST_SDT_VHDL_BIT = 2,
FST_SDT_VHDL_BIT_VECTOR = 3,
FST_SDT_VHDL_STD_ULOGIC = 4,
FST_SDT_VHDL_STD_ULOGIC_VECTOR = 5,
FST_SDT_VHDL_STD_LOGIC = 6,
FST_SDT_VHDL_STD_LOGIC_VECTOR = 7,
FST_SDT_VHDL_UNSIGNED = 8,
FST_SDT_VHDL_SIGNED = 9,
FST_SDT_VHDL_INTEGER = 10,
FST_SDT_VHDL_REAL = 11,
FST_SDT_VHDL_NATURAL = 12,
FST_SDT_VHDL_POSITIVE = 13,
FST_SDT_VHDL_TIME = 14,
FST_SDT_VHDL_CHARACTER = 15,
FST_SDT_VHDL_STRING = 16,
FST_SDT_MAX = 16,
FST_SDT_SVT_SHIFT_COUNT = 10, /* FST_SVT_* is ORed in by fstWriterCreateVar2() to the left after shifting FST_SDT_SVT_SHIFT_COUNT */
FST_SDT_ABS_MAX = ((1<<(FST_SDT_SVT_SHIFT_COUNT))-1)
};
struct fstHier
{
unsigned char htyp;
union {
/* if htyp == FST_HT_SCOPE */
struct fstHierScope {
unsigned char typ; /* FST_ST_MIN ... FST_ST_MAX */
const char *name;
const char *component;
uint32_t name_length; /* strlen(u.scope.name) */
uint32_t component_length; /* strlen(u.scope.component) */
} scope;
/* if htyp == FST_HT_VAR */
struct fstHierVar {
unsigned char typ; /* FST_VT_MIN ... FST_VT_MAX */
unsigned char direction; /* FST_VD_MIN ... FST_VD_MAX */
unsigned char svt_workspace; /* zeroed out by FST reader, for client code use */
unsigned char sdt_workspace; /* zeroed out by FST reader, for client code use */
unsigned int sxt_workspace; /* zeroed out by FST reader, for client code use */
const char *name;
uint32_t length;
fstHandle handle;
uint32_t name_length; /* strlen(u.var.name) */
unsigned is_alias : 1;
} var;
/* if htyp == FST_HT_ATTRBEGIN */
struct fstHierAttr {
unsigned char typ; /* FST_AT_MIN ... FST_AT_MAX */
unsigned char subtype; /* from fstMiscType, fstArrayType, fstEnumValueType, fstPackType */
const char *name;
uint64_t arg; /* number of array elements, struct members, or some other payload (possibly ignored) */
uint64_t arg_from_name; /* for when name is overloaded as a variable-length integer (FST_AT_MISC + FST_MT_SOURCESTEM) */
uint32_t name_length; /* strlen(u.attr.name) */
} attr;
} u;
};
struct fstETab
{
char *name;
uint32_t elem_count;
char **literal_arr;
char **val_arr;
};
/*
* writer functions
*/
void fstWriterClose(void *ctx);
void * fstWriterCreate(const char *nam, int use_compressed_hier);
fstEnumHandle fstWriterCreateEnumTable(void *ctx, const char *name, uint32_t elem_count, unsigned int min_valbits, const char **literal_arr, const char **val_arr);
/* used for Verilog/SV */
fstHandle fstWriterCreateVar(void *ctx, enum fstVarType vt, enum fstVarDir vd,
uint32_t len, const char *nam, fstHandle aliasHandle);
/* future expansion for VHDL and other languages. The variable type, data type, etc map onto
the current Verilog/SV one. The "type" string is optional for a more verbose or custom description */
fstHandle fstWriterCreateVar2(void *ctx, enum fstVarType vt, enum fstVarDir vd,
uint32_t len, const char *nam, fstHandle aliasHandle,
const char *type, enum fstSupplementalVarType svt, enum fstSupplementalDataType sdt);
void fstWriterEmitDumpActive(void *ctx, int enable);
void fstWriterEmitEnumTableRef(void *ctx, fstEnumHandle handle);
void fstWriterEmitValueChange(void *ctx, fstHandle handle, const void *val);
void fstWriterEmitValueChange32(void *ctx, fstHandle handle,
uint32_t bits, uint32_t val);
void fstWriterEmitValueChange64(void *ctx, fstHandle handle,
uint32_t bits, uint64_t val);
void fstWriterEmitValueChangeVec32(void *ctx, fstHandle handle,
uint32_t bits, const uint32_t *val);
void fstWriterEmitValueChangeVec64(void *ctx, fstHandle handle,
uint32_t bits, const uint64_t *val);
void fstWriterEmitVariableLengthValueChange(void *ctx, fstHandle handle, const void *val, uint32_t len);
void fstWriterEmitTimeChange(void *ctx, uint64_t tim);
void fstWriterFlushContext(void *ctx);
int fstWriterGetDumpSizeLimitReached(void *ctx);
int fstWriterGetFseekFailed(void *ctx);
void fstWriterSetAttrBegin(void *ctx, enum fstAttrType attrtype, int subtype,
const char *attrname, uint64_t arg);
void fstWriterSetAttrEnd(void *ctx);
void fstWriterSetComment(void *ctx, const char *comm);
void fstWriterSetDate(void *ctx, const char *dat);
void fstWriterSetDumpSizeLimit(void *ctx, uint64_t numbytes);
void fstWriterSetEnvVar(void *ctx, const char *envvar);
void fstWriterSetFileType(void *ctx, enum fstFileType filetype);
void fstWriterSetPackType(void *ctx, enum fstWriterPackType typ);
void fstWriterSetParallelMode(void *ctx, int enable);
void fstWriterSetRepackOnClose(void *ctx, int enable); /* type = 0 (none), 1 (libz) */
void fstWriterSetScope(void *ctx, enum fstScopeType scopetype,
const char *scopename, const char *scopecomp);
void fstWriterSetSourceInstantiationStem(void *ctx, const char *path, unsigned int line, unsigned int use_realpath);
void fstWriterSetSourceStem(void *ctx, const char *path, unsigned int line, unsigned int use_realpath);
void fstWriterSetTimescale(void *ctx, int ts);
void fstWriterSetTimescaleFromString(void *ctx, const char *s);
void fstWriterSetTimezero(void *ctx, int64_t tim);
void fstWriterSetUpscope(void *ctx);
void fstWriterSetValueList(void *ctx, const char *vl);
void fstWriterSetVersion(void *ctx, const char *vers);
/*
* reader functions
*/
void fstReaderClose(void *ctx);
void fstReaderClrFacProcessMask(void *ctx, fstHandle facidx);
void fstReaderClrFacProcessMaskAll(void *ctx);
uint64_t fstReaderGetAliasCount(void *ctx);
const char * fstReaderGetCurrentFlatScope(void *ctx);
void * fstReaderGetCurrentScopeUserInfo(void *ctx);
int fstReaderGetCurrentScopeLen(void *ctx);
const char * fstReaderGetDateString(void *ctx);
int fstReaderGetDoubleEndianMatchState(void *ctx);
uint64_t fstReaderGetDumpActivityChangeTime(void *ctx, uint32_t idx);
unsigned char fstReaderGetDumpActivityChangeValue(void *ctx, uint32_t idx);
uint64_t fstReaderGetEndTime(void *ctx);
int fstReaderGetFacProcessMask(void *ctx, fstHandle facidx);
int fstReaderGetFileType(void *ctx);
int fstReaderGetFseekFailed(void *ctx);
fstHandle fstReaderGetMaxHandle(void *ctx);
uint64_t fstReaderGetMemoryUsedByWriter(void *ctx);
uint32_t fstReaderGetNumberDumpActivityChanges(void *ctx);
uint64_t fstReaderGetScopeCount(void *ctx);
uint64_t fstReaderGetStartTime(void *ctx);
signed char fstReaderGetTimescale(void *ctx);
int64_t fstReaderGetTimezero(void *ctx);
uint64_t fstReaderGetValueChangeSectionCount(void *ctx);
char * fstReaderGetValueFromHandleAtTime(void *ctx, uint64_t tim, fstHandle facidx, char *buf);
uint64_t fstReaderGetVarCount(void *ctx);
const char * fstReaderGetVersionString(void *ctx);
struct fstHier *fstReaderIterateHier(void *ctx);
int fstReaderIterateHierRewind(void *ctx);
int fstReaderIterBlocks(void *ctx,
void (*value_change_callback)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value),
void *user_callback_data_pointer, FILE *vcdhandle);
int fstReaderIterBlocks2(void *ctx,
void (*value_change_callback)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value),
void (*value_change_callback_varlen)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value, uint32_t len),
void *user_callback_data_pointer, FILE *vcdhandle);
void fstReaderIterBlocksSetNativeDoublesOnCallback(void *ctx, int enable);
void * fstReaderOpen(const char *nam);
void * fstReaderOpenForUtilitiesOnly(void);
const char * fstReaderPopScope(void *ctx);
int fstReaderProcessHier(void *ctx, FILE *vcdhandle);
const char * fstReaderPushScope(void *ctx, const char *nam, void *user_info);
void fstReaderResetScope(void *ctx);
void fstReaderSetFacProcessMask(void *ctx, fstHandle facidx);
void fstReaderSetFacProcessMaskAll(void *ctx);
void fstReaderSetLimitTimeRange(void *ctx, uint64_t start_time, uint64_t end_time);
void fstReaderSetUnlimitedTimeRange(void *ctx);
void fstReaderSetVcdExtensions(void *ctx, int enable);
/*
* utility functions
*/
int fstUtilityBinToEscConvertedLen(const unsigned char *s, int len); /* used for mallocs for fstUtilityBinToEsc() */
int fstUtilityBinToEsc(unsigned char *d, const unsigned char *s, int len);
int fstUtilityEscToBin(unsigned char *d, unsigned char *s, int len);
struct fstETab *fstUtilityExtractEnumTableFromString(const char *s);
void fstUtilityFreeEnumTable(struct fstETab *etab); /* must use to free fstETab properly */
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,362 @@
/*
LZ4 - Fast LZ compression algorithm
Header File
Copyright (C) 2011-2015, Yann Collet.
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
SPDX-License-Identifier: BSD-2-Clause
You can contact the author at :
- LZ4 source repository : https://github.com/Cyan4973/lz4
- LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
*/
#pragma once
#if defined (__cplusplus)
extern "C" {
#endif
/*
* lz4.h provides block compression functions, and gives full buffer control to programmer.
* If you need to generate inter-operable compressed data (respecting LZ4 frame specification),
* and can let the library handle its own memory, please use lz4frame.h instead.
*/
/**************************************
* Version
**************************************/
#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */
#define LZ4_VERSION_MINOR 7 /* for new (non-breaking) interface capabilities */
#define LZ4_VERSION_RELEASE 1 /* for tweaks, bug-fixes, or development */
#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE)
int LZ4_versionNumber (void);
/**************************************
* Tuning parameter
**************************************/
/*
* LZ4_MEMORY_USAGE :
* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)
* Increasing memory usage improves compression ratio
* Reduced memory usage can improve speed, due to cache effect
* Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache
*/
#define LZ4_MEMORY_USAGE 14
/**************************************
* Simple Functions
**************************************/
int LZ4_compress_default(const char* source, char* dest, int sourceSize, int maxDestSize);
int LZ4_decompress_safe (const char* source, char* dest, int compressedSize, int maxDecompressedSize);
/*
LZ4_compress_default() :
Compresses 'sourceSize' bytes from buffer 'source'
into already allocated 'dest' buffer of size 'maxDestSize'.
Compression is guaranteed to succeed if 'maxDestSize' >= LZ4_compressBound(sourceSize).
It also runs faster, so it's a recommended setting.
If the function cannot compress 'source' into a more limited 'dest' budget,
compression stops *immediately*, and the function result is zero.
As a consequence, 'dest' content is not valid.
This function never writes outside 'dest' buffer, nor read outside 'source' buffer.
sourceSize : Max supported value is LZ4_MAX_INPUT_VALUE
maxDestSize : full or partial size of buffer 'dest' (which must be already allocated)
return : the number of bytes written into buffer 'dest' (necessarily <= maxOutputSize)
or 0 if compression fails
LZ4_decompress_safe() :
compressedSize : is the precise full size of the compressed block.
maxDecompressedSize : is the size of destination buffer, which must be already allocated.
return : the number of bytes decompressed into destination buffer (necessarily <= maxDecompressedSize)
If destination buffer is not large enough, decoding will stop and output an error code (<0).
If the source stream is detected malformed, the function will stop decoding and return a negative result.
This function is protected against buffer overflow exploits, including malicious data packets.
It never writes outside output buffer, nor reads outside input buffer.
*/
/**************************************
* Advanced Functions
**************************************/
#define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */
#define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16)
/*
LZ4_compressBound() :
Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible)
This function is primarily useful for memory allocation purposes (destination buffer size).
Macro LZ4_COMPRESSBOUND() is also provided for compilation-time evaluation (stack memory allocation for example).
Note that LZ4_compress_default() compress faster when dest buffer size is >= LZ4_compressBound(srcSize)
inputSize : max supported value is LZ4_MAX_INPUT_SIZE
return : maximum output size in a "worst case" scenario
or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE)
*/
int LZ4_compressBound(int inputSize);
/*
LZ4_compress_fast() :
Same as LZ4_compress_default(), but allows to select an "acceleration" factor.
The larger the acceleration value, the faster the algorithm, but also the lesser the compression.
It's a trade-off. It can be fine tuned, with each successive value providing roughly +~3% to speed.
An acceleration value of "1" is the same as regular LZ4_compress_default()
Values <= 0 will be replaced by ACCELERATION_DEFAULT (see lz4.c), which is 1.
*/
int LZ4_compress_fast (const char* source, char* dest, int sourceSize, int maxDestSize, int acceleration);
/*
LZ4_compress_fast_extState() :
Same compression function, just using an externally allocated memory space to store compression state.
Use LZ4_sizeofState() to know how much memory must be allocated,
and allocate it on 8-bytes boundaries (using malloc() typically).
Then, provide it as 'void* state' to compression function.
*/
int LZ4_sizeofState(void);
int LZ4_compress_fast_extState (void* state, const char* source, char* dest, int inputSize, int maxDestSize, int acceleration);
/*
LZ4_compress_destSize() :
Reverse the logic, by compressing as much data as possible from 'source' buffer
into already allocated buffer 'dest' of size 'targetDestSize'.
This function either compresses the entire 'source' content into 'dest' if it's large enough,
or fill 'dest' buffer completely with as much data as possible from 'source'.
*sourceSizePtr : will be modified to indicate how many bytes where read from 'source' to fill 'dest'.
New value is necessarily <= old value.
return : Nb bytes written into 'dest' (necessarily <= targetDestSize)
or 0 if compression fails
*/
int LZ4_compress_destSize (const char* source, char* dest, int* sourceSizePtr, int targetDestSize);
/*
LZ4_decompress_fast() :
originalSize : is the original and therefore uncompressed size
return : the number of bytes read from the source buffer (in other words, the compressed size)
If the source stream is detected malformed, the function will stop decoding and return a negative result.
Destination buffer must be already allocated. Its size must be a minimum of 'originalSize' bytes.
note : This function fully respect memory boundaries for properly formed compressed data.
It is a bit faster than LZ4_decompress_safe().
However, it does not provide any protection against intentionally modified data stream (malicious input).
Use this function in trusted environment only (data to decode comes from a trusted source).
*/
int LZ4_decompress_fast (const char* source, char* dest, int originalSize);
/*
LZ4_decompress_safe_partial() :
This function decompress a compressed block of size 'compressedSize' at position 'source'
into destination buffer 'dest' of size 'maxDecompressedSize'.
The function tries to stop decompressing operation as soon as 'targetOutputSize' has been reached,
reducing decompression time.
return : the number of bytes decoded in the destination buffer (necessarily <= maxDecompressedSize)
Note : this number can be < 'targetOutputSize' should the compressed block to decode be smaller.
Always control how many bytes were decoded.
If the source stream is detected malformed, the function will stop decoding and return a negative result.
This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets
*/
int LZ4_decompress_safe_partial (const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize);
/***********************************************
* Streaming Compression Functions
***********************************************/
#define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4)
#define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(long long))
/*
* LZ4_stream_t
* information structure to track an LZ4 stream.
* important : init this structure content before first use !
* note : only allocated directly the structure if you are statically linking LZ4
* If you are using liblz4 as a DLL, please use below construction methods instead.
*/
typedef struct { long long table[LZ4_STREAMSIZE_U64]; } LZ4_stream_t;
/*
* LZ4_resetStream
* Use this function to init an allocated LZ4_stream_t structure
*/
void LZ4_resetStream (LZ4_stream_t* streamPtr);
/*
* LZ4_createStream will allocate and initialize an LZ4_stream_t structure
* LZ4_freeStream releases its memory.
* In the context of a DLL (liblz4), please use these methods rather than the static struct.
* They are more future proof, in case of a change of LZ4_stream_t size.
*/
LZ4_stream_t* LZ4_createStream(void);
int LZ4_freeStream (LZ4_stream_t* streamPtr);
/*
* LZ4_loadDict
* Use this function to load a static dictionary into LZ4_stream.
* Any previous data will be forgotten, only 'dictionary' will remain in memory.
* Loading a size of 0 is allowed.
* Return : dictionary size, in bytes (necessarily <= 64 KB)
*/
int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize);
/*
* LZ4_compress_fast_continue
* Compress buffer content 'src', using data from previously compressed blocks as dictionary to improve compression ratio.
* Important : Previous data blocks are assumed to still be present and unmodified !
* 'dst' buffer must be already allocated.
* If maxDstSize >= LZ4_compressBound(srcSize), compression is guaranteed to succeed, and runs faster.
* If not, and if compressed data cannot fit into 'dst' buffer size, compression stops, and function returns a zero.
*/
int LZ4_compress_fast_continue (LZ4_stream_t* streamPtr, const char* src, char* dst, int srcSize, int maxDstSize, int acceleration);
/*
* LZ4_saveDict
* If previously compressed data block is not guaranteed to remain available at its memory location
* save it into a safer place (char* safeBuffer)
* Note : you don't need to call LZ4_loadDict() afterwards,
* dictionary is immediately usable, you can therefore call LZ4_compress_fast_continue()
* Return : saved dictionary size in bytes (necessarily <= dictSize), or 0 if error
*/
int LZ4_saveDict (LZ4_stream_t* streamPtr, char* safeBuffer, int dictSize);
/************************************************
* Streaming Decompression Functions
************************************************/
#define LZ4_STREAMDECODESIZE_U64 4
#define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long))
typedef struct { unsigned long long table[LZ4_STREAMDECODESIZE_U64]; } LZ4_streamDecode_t;
/*
* LZ4_streamDecode_t
* information structure to track an LZ4 stream.
* init this structure content using LZ4_setStreamDecode or memset() before first use !
*
* In the context of a DLL (liblz4) please prefer usage of construction methods below.
* They are more future proof, in case of a change of LZ4_streamDecode_t size in the future.
* LZ4_createStreamDecode will allocate and initialize an LZ4_streamDecode_t structure
* LZ4_freeStreamDecode releases its memory.
*/
LZ4_streamDecode_t* LZ4_createStreamDecode(void);
int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream);
/*
* LZ4_setStreamDecode
* Use this function to instruct where to find the dictionary.
* Setting a size of 0 is allowed (same effect as reset).
* Return : 1 if OK, 0 if error
*/
int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize);
/*
*_continue() :
These decoding functions allow decompression of multiple blocks in "streaming" mode.
Previously decoded blocks *must* remain available at the memory position where they were decoded (up to 64 KB)
In the case of a ring buffers, decoding buffer must be either :
- Exactly same size as encoding buffer, with same update rule (block boundaries at same positions)
In which case, the decoding & encoding ring buffer can have any size, including very small ones ( < 64 KB).
- Larger than encoding buffer, by a minimum of maxBlockSize more bytes.
maxBlockSize is implementation dependent. It's the maximum size you intend to compress into a single block.
In which case, encoding and decoding buffers do not need to be synchronized,
and encoding ring buffer can have any size, including small ones ( < 64 KB).
- _At least_ 64 KB + 8 bytes + maxBlockSize.
In which case, encoding and decoding buffers do not need to be synchronized,
and encoding ring buffer can have any size, including larger than decoding buffer.
Whenever these conditions are not possible, save the last 64KB of decoded data into a safe buffer,
and indicate where it is saved using LZ4_setStreamDecode()
*/
int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxDecompressedSize);
int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize);
/*
Advanced decoding functions :
*_usingDict() :
These decoding functions work the same as
a combination of LZ4_setStreamDecode() followed by LZ4_decompress_x_continue()
They are stand-alone. They don't need nor update an LZ4_streamDecode_t structure.
*/
int LZ4_decompress_safe_usingDict (const char* source, char* dest, int compressedSize, int maxDecompressedSize, const char* dictStart, int dictSize);
int LZ4_decompress_fast_usingDict (const char* source, char* dest, int originalSize, const char* dictStart, int dictSize);
/**************************************
* Obsolete Functions
**************************************/
/* Deprecate Warnings */
/* Should these warnings messages be a problem,
it is generally possible to disable them,
with -Wno-deprecated-declarations for gcc
or _CRT_SECURE_NO_WARNINGS in Visual for example.
You can also define LZ4_DEPRECATE_WARNING_DEFBLOCK. */
#ifndef LZ4_DEPRECATE_WARNING_DEFBLOCK
# define LZ4_DEPRECATE_WARNING_DEFBLOCK
# define LZ4_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
# if (LZ4_GCC_VERSION >= 405) || defined(__clang__)
# define LZ4_DEPRECATED(message) __attribute__((deprecated(message)))
# elif (LZ4_GCC_VERSION >= 301)
# define LZ4_DEPRECATED(message) __attribute__((deprecated))
# elif defined(_MSC_VER)
# define LZ4_DEPRECATED(message) __declspec(deprecated(message))
# else
# pragma message("WARNING: You need to implement LZ4_DEPRECATED for this compiler")
# define LZ4_DEPRECATED(message)
# endif
#endif /* LZ4_DEPRECATE_WARNING_DEFBLOCK */
/* Obsolete compression functions */
/* These functions are planned to start generate warnings by r131 approximately */
int LZ4_compress (const char* source, char* dest, int sourceSize);
int LZ4_compress_limitedOutput (const char* source, char* dest, int sourceSize, int maxOutputSize);
int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize);
int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize);
int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize);
int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize);
/* Obsolete decompression functions */
/* These function names are completely deprecated and must no longer be used.
They are only provided here for compatibility with older programs.
- LZ4_uncompress is the same as LZ4_decompress_fast
- LZ4_uncompress_unknownOutputSize is the same as LZ4_decompress_safe
These function prototypes are now disabled; uncomment them only if you really need them.
It is highly recommended to stop using these prototypes and migrate to maintained ones */
/* int LZ4_uncompress (const char* source, char* dest, int outputSize); */
/* int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize); */
/* Obsolete streaming functions; use new streaming interface whenever possible */
LZ4_DEPRECATED("use LZ4_createStream() instead") void* LZ4_create (char* inputBuffer);
LZ4_DEPRECATED("use LZ4_createStream() instead") int LZ4_sizeofStreamState(void);
LZ4_DEPRECATED("use LZ4_resetStream() instead") int LZ4_resetStreamState(void* state, char* inputBuffer);
LZ4_DEPRECATED("use LZ4_saveDict() instead") char* LZ4_slideInputBuffer (void* state);
/* Obsolete streaming decoding functions */
LZ4_DEPRECATED("use LZ4_decompress_safe_usingDict() instead") int LZ4_decompress_safe_withPrefix64k (const char* src, char* dst, int compressedSize, int maxDstSize);
LZ4_DEPRECATED("use LZ4_decompress_fast_usingDict() instead") int LZ4_decompress_fast_withPrefix64k (const char* src, char* dst, int originalSize);
#if defined (__cplusplus)
}
#endif

View 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.fst</artifactId>
<version>1.0.0-SNAPSHOT</version>
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.19.4</version>
<relativePath>../..</relativePath>
</parent>
<packaging>eclipse-plugin</packaging>
</project>

View File

@ -0,0 +1,190 @@
/*******************************************************************************
* Copyright (c) 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
*******************************************************************************/
package com.minres.scviewer.database.fst;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.File;
import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Vector;
import com.google.common.collect.Iterables;
import com.minres.scviewer.database.BitVector;
import com.minres.scviewer.database.DoubleVal;
import com.minres.scviewer.database.EventList;
import com.minres.scviewer.database.IEventList;
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;
/**
* The Class VCDDb.
*/
public class FstDbLoader implements IWaveformDbLoader, IFstDatabaseBuilder {
/** The module stack. */
private ArrayDeque<String> moduleStack;
/** The signals. */
private List<IWaveform> signals;
FstFileParser parser;
/** The max time. */
private long maxTime;
private long timeScaleFactor;
/** The pcs. */
protected PropertyChangeSupport pcs = new PropertyChangeSupport(this);
static long calculateTimescaleMultipierPower(long time_scale){
long answer = 1;
if(time_scale<=0){
return answer;
} else{
for(int i = 1; i<= time_scale; i++)
answer *= 10;
return answer;
}
}
/* (non-Javadoc)
* @see com.minres.scviewer.database.ITrDb#load(java.io.File)
*/
@Override
public void load(File file) throws InputFormatException {
dispose();
this.maxTime=0;
boolean res = false;
signals = new Vector<>();
moduleStack= new ArrayDeque<>();
parser = new FstFileParser(file);
res = parser.open(this);
moduleStack=null;
if(!res)
throw new InputFormatException("Could not parse VCD file");
// calculate max time of this database
pcs.firePropertyChange(IWaveformDbLoader.LOADING_FINISHED, null, null);
}
public void dispose() {
if(parser!=null) {
parser.close();
parser=null;
}
moduleStack=null;
signals=null;
}
/* (non-Javadoc)
* @see com.minres.scviewer.database.ITrDb#getMaxTime()
*/
@Override
public long getMaxTime() {
return maxTime;
}
/* (non-Javadoc)
* @see com.minres.scviewer.database.ITrDb#getAllWaves()
*/
@Override
public Collection<IWaveform> getAllWaves() {
return signals;
}
/* (non-Javadoc)
* @see com.minres.scviewer.database.vcd.ITraceBuilder#enterModule(java.lang.String)
*/
@Override
public void enterModule(String tokenString) {
if(moduleStack.isEmpty()) {
if("SystemC".compareTo(tokenString)!=0)
moduleStack.push(tokenString);
} else
moduleStack.push(moduleStack.peek()+"."+tokenString);
}
/* (non-Javadoc)
* @see com.minres.scviewer.database.vcd.ITraceBuilder#exitModule()
*/
@Override
public void exitModule() {
if(!moduleStack.isEmpty()) moduleStack.pop();
}
/* (non-Javadoc)
* @see com.minres.scviewer.database.vcd.ITraceBuilder#newNet(java.lang.String, int, int)
*/
@Override
public void newNet(String name, int handle, int width, int direction, boolean alias) {
String netName = moduleStack.isEmpty()? name: moduleStack.peek()+"."+name;
IWaveform signal = width==0?
new FstSignal<DoubleVal>(this, handle, netName, width, direction):
new FstSignal<BitVector>(this, handle, netName, direction, width);
signals.add(signal);
pcs.firePropertyChange(IWaveformDbLoader.SIGNAL_ADDED, null, Iterables.getLast(signals));
}
/* (non-Javadoc)
* @see com.minres.scviewer.database.vcd.ITraceBuilder#getNetWidth(int)
*/
@Override
public int getNetWidth(int intValue) {
FstSignal<?> signal = (FstSignal<?>) signals.get(intValue);
return signal.getRowCount();
}
public void setMaxTime(long maxTime, int timeScale) {
if(timeScale>0) timeScale=-timeScale;
long eff_time_scale=timeScale-IWaveformDb.databaseTimeScale;
this.timeScaleFactor = calculateTimescaleMultipierPower(eff_time_scale);
this.maxTime = maxTime*timeScaleFactor;
}
/* (non-Javadoc)
* @see com.minres.scviewer.database.IWaveformDbLoader#getAllRelationTypes()
*/
@Override
public Collection<RelationType> getAllRelationTypes(){
return Collections.emptyList();
}
/**
* 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);
}
public void getEvents(int id, int width, IEventList values) {
if(values instanceof EventList)
parser.getValueChanges(id, width, timeScaleFactor, (EventList) values);
}
}

View File

@ -0,0 +1,42 @@
/*******************************************************************************
* Copyright (c) 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
*******************************************************************************/
package com.minres.scviewer.database.fst;
import java.io.File;
import com.minres.scviewer.database.IWaveformDbLoader;
import com.minres.scviewer.database.IWaveformDbLoaderFactory;
/**
* The Class VCDDb.
*/
public class FstDbLoaderFactory implements IWaveformDbLoaderFactory {
/**
* Can load.
*
* @param inputFile the input file
* @return true, if successful
*/
@Override
public boolean canLoad(File inputFile) {
if(!inputFile.isDirectory() || inputFile.exists()) {
String name = inputFile.getName();
return name.endsWith(".fst");
}
return false;
}
@Override
public IWaveformDbLoader getLoader() {
return new FstDbLoader();
}
}

View File

@ -0,0 +1,93 @@
/*******************************************************************************
* Copyright (c) 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
*******************************************************************************/
package com.minres.scviewer.database.fst;
import java.io.File;
import com.minres.scviewer.database.BitVector;
import com.minres.scviewer.database.EventList;
import com.minres.scviewer.database.fst.FstLibrary.HierAttr;
import com.minres.scviewer.database.fst.FstLibrary.HierScope;
import com.minres.scviewer.database.fst.FstLibrary.HierType;
import com.minres.scviewer.database.fst.FstLibrary.HierVar;
import com.minres.scviewer.database.fst.FstLibrary.ValueChangeCallback;
import com.sun.jna.Pointer;
class FstFileParser {
long currentTime;
final File file;
Pointer fst;
public FstFileParser(File file) {
this.file=file;
}
public boolean open(IFstDatabaseBuilder builder) {
fst = FstLibrary.fstReaderOpen(file.getAbsolutePath());
if(!fst.equals(Pointer.NULL)) {
// String version = FstLibrary.fstReaderGetVersionString(fst);
long endTime = FstLibrary.fstReaderGetEndTime(fst);
byte timeScale = FstLibrary.fstReaderGetTimescale(fst);
builder.setMaxTime(endTime, -timeScale);
FstLibrary.fstReaderIterateHierRewind(fst);
Pointer p = FstLibrary.fstReaderIterateHier(fst);
while(p!=null && !p.equals(Pointer.NULL)) {
int hierType = FstLibrary.getHierType(p);
HierType type = HierType.values()[hierType];
switch(type) {
case HT_SCOPE:
HierScope scope = new HierScope();
FstLibrary.getHierScope(p, scope);
builder.enterModule(scope.name);
break;
case HT_UPSCOPE:
builder.exitModule();
break;
case HT_VAR:
HierVar v = new HierVar();
FstLibrary.getHierVar(p, v);
builder.newNet(v.name, v.handle, v.length, v.direction, v.is_alias!=0);
break;
case HT_ATTRBEGIN:
HierAttr attr = new HierAttr();
FstLibrary.getHierAttr(p, attr);
break;
case HT_ATTREND:
break;
case HT_TREEBEGIN:
break;
case HT_TREEEND:
break;
default:
break;
}
p = FstLibrary.fstReaderIterateHier(fst);
}
return true;
} else
return false;
}
public void getValueChanges(final int id, final int width, long timeScale, final EventList values) {
FstLibrary.fstReaderClrFacProcessMaskAll(fst);
FstLibrary.fstReaderSetFacProcessMask(fst, id);
FstLibrary.iterateValueChanges(fst, new ValueChangeCallback() {
@Override
public void callback(long time, int facidx, String value) {
values.put(time*timeScale, BitVector.fromString(width, value));
}
});
}
public void close() {
FstLibrary.fstReaderClose(fst);
}
}

View File

@ -0,0 +1,224 @@
package com.minres.scviewer.database.fst;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.Structure.FieldOrder;
import com.sun.jna.Callback;
public class FstLibrary {
public static enum ScopeType {
MIN(0),
VCD_MODULE(0),
VCD_TASK(1),
VCD_FUNCTION(2),
VCD_BEGIN(3),
VCD_FORK(4),
VCD_GENERATE(5),
VCD_STRUCT(6),
VCD_UNION(7),
VCD_CLASS(8),
VCD_INTERFACE(9),
VCD_PACKAGE(10),
VCD_PROGRAM(11),
VHDL_ARCHITECTURE(12),
VHDL_PROCEDURE(13),
VHDL_FUNCTION(14),
VHDL_RECORD(15),
VHDL_PROCESS(16),
VHDL_BLOCK(17),
VHDL_FOR_GENERATE(18),
VHDL_IF_GENERATE(19),
VHDL_GENERATE(20),
VHDL_PACKAGE(21),
MAX(21),
ST_GEN_ATTRBEGIN(252),
ST_GEN_ATTREND(253),
ST_VCD_SCOPE(254),
ST_VCD_UPSCOPE(255);
public final int label;
private ScopeType(int label) {
this.label = label;
}
};
public static enum HierType {
HT_SCOPE(0),
HT_UPSCOPE(1),
HT_VAR(2),
HT_ATTRBEGIN(3),
HT_ATTREND(4),
HT_TREEBEGIN(5),
HT_TREEEND(6);
public final int type;
private HierType(int type) {
this.type = type;
}
};
public static enum VarType {
FST_VT_VCD_EVENT (0),
FST_VT_VCD_INTEGER (1),
FST_VT_VCD_PARAMETER (2),
FST_VT_VCD_REAL (3),
FST_VT_VCD_REAL_PARAMETER (4),
FST_VT_VCD_REG (5),
FST_VT_VCD_SUPPLY0 (6),
FST_VT_VCD_SUPPLY1 (7),
FST_VT_VCD_TIME (8),
FST_VT_VCD_TRI (9),
FST_VT_VCD_TRIAND (10),
FST_VT_VCD_TRIOR (11),
FST_VT_VCD_TRIREG (12),
FST_VT_VCD_TRI0 (13),
FST_VT_VCD_TRI1 (14),
FST_VT_VCD_WAND (15),
FST_VT_VCD_WIRE (16),
FST_VT_VCD_WOR (17),
FST_VT_VCD_PORT (18),
FST_VT_VCD_SPARRAY (19), /* used to define the rownum (index) port for a sparse array */
FST_VT_VCD_REALTIME (20),
FST_VT_GEN_STRING (21), /* generic string type (max len is defined dynamically via fstWriterEmitVariableLengthValueChange) */
FST_VT_SV_BIT (22),
FST_VT_SV_LOGIC (23),
FST_VT_SV_INT (24), /* declare as size = 32 */
FST_VT_SV_SHORTINT (25), /* declare as size = 16 */
FST_VT_SV_LONGINT (26), /* declare as size = 64 */
FST_VT_SV_BYTE (27), /* declare as size = 8 */
FST_VT_SV_ENUM (28), /* declare as appropriate type range */
FST_VT_SV_SHORTREAL (29); /* declare and emit same as FST_VT_VCD_REAL (needs to be emitted as double, not a float) */
public final int varType;
private VarType(int varType) {
this.varType = varType;
}
};
public static enum VarDir {
FST_VD_IMPLICIT (0),
FST_VD_INPUT (1),
FST_VD_OUTPUT (2),
FST_VD_INOUT (3),
FST_VD_BUFFER (4),
FST_VD_LINKAGE (5);
public final int varDir;
private VarDir(int varDir) {
this.varDir = varDir;
}
};
public static enum AttrType {
FST_AT_MISC ( 0), /* self-contained: does not need matching FST_HT_ATTREND */
FST_AT_ARRAY ( 1),
FST_AT_ENUM ( 2),
FST_AT_PACK ( 3);
public final int attrType;
private AttrType(int attrType) {
this.attrType = attrType;
}
};
@FieldOrder({"type","name","component", "name_length", "component_length"})
public static class HierScope extends Structure {
public byte type; /* FST_ST_MIN ... FST_ST_MAX */
public String name;
public String component;
public int name_length; /* strlen(u.scope.name) */
public int component_length; /* strlen(u.scope.component) */
};
@FieldOrder({"type","direction","svt_workspace", "sdt_workspace", "sxt_workspace", "name","length","handle","name_length", "is_alias"})
public static class HierVar extends Structure {
public byte type; /* FST_VT_MIN ... FST_VT_MAX */
public byte direction; /* FST_VD_MIN ... FST_VD_MAX */
public byte svt_workspace; /* zeroed out by FST reader, for client code use */
public byte sdt_workspace; /* zeroed out by FST reader, for client code use */
public int sxt_workspace; /* zeroed out by FST reader, for client code use */
public String name;
public int length;
public int handle; /*fstHandle*/
public int name_length; /* strlen(u.var.name) */
public int is_alias;
};
@FieldOrder({"type","subtype","name", "arg", "arg_from_name", "name_length"})
public static class HierAttr extends Structure {
public byte type; /* FST_AT_MIN ... FST_AT_MAX */
public byte subtype; /* from fstMiscType, fstArrayType, fstEnumValueType, fstPackType */
public String name;
public long arg; /* number of array elements, struct members, or some other payload (possibly ignored) */
public long arg_from_name; /* for when name is overloaded as a variable-length integer (FST_AT_MISC + FST_MT_SOURCESTEM) */
public long name_length; /* strlen(u.attr.name) */
};
public static native Pointer fstReaderOpen(String name);
public static native Pointer fstReaderOpenForUtilitiesOnly();
public static native void fstReaderClose(Pointer ctx);
public static native String fstReaderGetVersionString(Pointer ctx);
public static native String fstReaderGetDateString(Pointer ctx);
public static native int fstReaderGetFileType(Pointer ctx);
public static native long fstReaderGetVarCount(Pointer ctx);
public static native long fstReaderGetScopeCount(Pointer ctx);
public static native long fstReaderGetAliasCount(Pointer ctx);
public static native long fstReaderGetValueChangeSectionCount(Pointer ctx);
public static native long fstReaderGetStartTime(Pointer ctx);
public static native long fstReaderGetEndTime(Pointer ctx);
public static native byte fstReaderGetTimescale(Pointer ctx);
public static native long fstReaderGetTimezero(Pointer ctx);
public static native int fstReaderGetMaxHandle(Pointer ctx);
public static native void fstReaderResetScope(Pointer ctx);
public static native String fstReaderPushScope(Pointer ctx, String nam, Pointer user_info);
public static native String fstReaderPopScope(Pointer ctx);
public static native int fstReaderGetCurrentScopeLen(Pointer ctx);
public static native String fstReaderGetCurrentFlatScope(Pointer ctx);
public static native int fstReaderGetNumberDumpActivityChanges(Pointer ctx);
public static native long fstReaderGetDumpActivityChangeTime(Pointer ctx, int idx);
public static native byte fstReaderGetDumpActivityChangeValue(Pointer ctx, int idx);
public static native int fstReaderIterateHierRewind(Pointer ctx);
public static native Pointer fstReaderIterateHier(Pointer ctx);
public static native int getHierType(Pointer hier);
public static native void getHierScope(Pointer hier, HierScope scope);
public static native void getHierVar(Pointer hier, HierVar scope);
public static native void getHierAttr(Pointer hier, HierAttr scope);
public static native int fstReaderGetFacProcessMask(Pointer ctx, int facidx);
public static native void fstReaderSetFacProcessMask(Pointer ctx, int facidx);
public static native void fstReaderClrFacProcessMask(Pointer ctx, int facidx);
public static native void fstReaderSetFacProcessMaskAll(Pointer ctx);
public static native void fstReaderClrFacProcessMaskAll(Pointer ctx);
public interface ValueChangeCallback extends Callback {
void callback(long time, int facidx, String value);
}
public static native void iterateValueChanges(Pointer ctx, ValueChangeCallback vcc);
/* untranslated functions:
int fstReaderIterBlocks(Pointer ctx, ValueChangeCallback vcc, Pointer user_callback_data_pointer, Pointer vcdhandle);
Pointer fstReaderGetCurrentScopeUserInfo(Pointer ctx);
int fstReaderGetDoubleEndianMatchState(Pointer ctx);
int fstReaderGetFseekFailed(Pointer ctx);
long fstReaderGetMemoryUsedByWriter(Pointer ctx);
String fstReaderGetValueFromHandleAtTime(Pointer ctx, long tim, fstHandle facidx, Stringbuf);
int fstReaderIterBlocks2(Pointer ctx,
void (*value_change_callback)(Pointer user_callback_data_pointer, long time, fstHandle facidx, const unsigned Stringvalue),
void (*value_change_callback_varlen)(Pointer user_callback_data_pointer, long time, fstHandle facidx, const unsigned Stringvalue, int len),
Pointer user_callback_data_pointer, FILE *vcdhandle);
void fstReaderIterBlocksSetNativeDoublesOnCallback(Pointer ctx, int enable);
int fstReaderProcessHier(Pointer ctx, FILE *vcdhandle);
void fstReaderSetLimitTimeRange(Pointer ctx, long start_time, long end_time);
void fstReaderSetUnlimitedTimeRange(Pointer ctx);
void fstReaderSetVcdExtensions(Pointer ctx, int enable);
*/
static {
// System.setProperty("jna.debug_load", "true");
Native.register("fstapi");
}
}

View File

@ -0,0 +1,131 @@
/*******************************************************************************
* Copyright (c) 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
*******************************************************************************/
package com.minres.scviewer.database.fst;
import com.minres.scviewer.database.DirectionType;
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;
public class FstSignal<T extends IEvent> extends HierNode implements IWaveform {
private final FstDbLoader loader;
private final int direction;
private final int id;
private final String fullName;
private final int width;
private final IEventList values;
public FstSignal(FstDbLoader loader, String name) {
this(loader, 0, name, 0, 1);
}
public FstSignal(FstDbLoader loader, int id, String name) {
this(loader, id,name, 0,1);
}
public FstSignal(FstDbLoader loader, int id, String name, int direction, int width) {
super(name);
fullName=name;
this.loader=loader;
this.id=id;
this.direction = direction;
this.width=width;
this.values=new EventList();
}
public FstSignal(FstSignal<T> o, int id, String name) {
super(name);
fullName=name;
this.loader=o.loader;
this.id=id;
this.direction = 0;
this.width=o.width;
this.values=o.values;
}
@Override
public String getFullName() {
return fullName;
}
@Override
public long getId() {
return id;
}
@Override
public IEventList getEvents() {
if(values.size()==0)
loader.getEvents(id, width, values);
return values;
}
@Override
public IEvent[] getEventsAtTime(long time) {
return getEvents().get(time);
}
@Override
public IEvent[] getEventsBeforeTime(long time) {
EventEntry e = getEvents().floorEntry(time);
if(e==null)
return new IEvent[] {};
else
return getEvents().floorEntry(time).events;
}
@Override
public boolean isSame(IWaveform other) {
return( other instanceof FstSignal<?> && this.getId() == other.getId());
}
@Override
public WaveformType getType() {
return WaveformType.SIGNAL;
}
@Override
public int getRowCount() {
return 1;
}
@Override
public int getWidth() {
return width;
}
@Override
public String getKind() {
return "signal";
}
@Override
public DirectionType getDirection() {
switch(direction) {
case 1: return DirectionType.INPUT;
case 2: return DirectionType.OUTPUT;
case 3: return DirectionType.INOUT;
case 4: return DirectionType.BUFFER;
case 5: return DirectionType.LINKAGE;
}
return DirectionType.IMPLICIT;
}
}

View File

@ -0,0 +1,49 @@
/*******************************************************************************
* Copyright (c) 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
*******************************************************************************/
package com.minres.scviewer.database.fst;
/**
* The Interface IVCDDatabaseBuilder. It allows to add VCD events into the database
*/
public interface IFstDatabaseBuilder {
/**
* Enter module.
*
* @param tokenString the token string
*/
public void enterModule(String tokenString);
/**
* Exit module.
*/
public void exitModule();
/**
* New net.
*
* @param netName the net name
* @param i the index of the net, -1 if a new one, otherwise the id if the referenced
* @param width the width, -1 equals real, 0... is a bit vector
* @return the net id
*/
public void newNet(String netName, int handle, int width, int direction, boolean alias) ;
/**
* Gets the net width.
*
* @param intValue the net id
* @return the net width, -1 means a real-valued net
*/
public int getNetWidth(int netId);
public void setMaxTime(long time, int timeScale);
}

View 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-17">
<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>

View File

@ -0,0 +1,3 @@
/bin
/target/
/.settings/

View 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>

View File

@ -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.2.qualifier
Bundle-Vendor: MINRES Technologies GmbH
Bundle-RequiredExecutionEnvironment: JavaSE-17
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: .

View File

@ -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>

View 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/

View 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.2-SNAPSHOT</version>
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.19.4</version>
<relativePath>../..</relativePath>
</parent>
<packaging>eclipse-plugin</packaging>
</project>

View File

@ -0,0 +1,182 @@
/*******************************************************************************
* 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. */
protected 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 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;
}
@Override
public int getWidth() {
return 0;
}
/**
* Calculate concurrency.
*/
void calculateConcurrency() {
if (rowCount>=0)
return;
ArrayList<Long> rowEndTime = new ArrayList<>();
HashMap<Long, Integer> rowByTxId = new HashMap<>();
for(EventEntry entry: getEvents()) {
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());
}
}

View File

@ -0,0 +1,553 @@
/*******************************************************************************
* 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.nio.channels.FileLock;
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 {
static final private CborType break_type = CborType.valueOf(0xff);
/** The max time. */
private long maxTime = 0L;
ArrayList<String> strDict = new ArrayList<>();
FileInputStream fis = null;
FileLock lock = null;
/** 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 or null if the transaction is not available
*/
public synchronized 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 {
return null;
}
}
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(File file) throws InputFormatException {
this.file=file;
try {
fis = new FileInputStream(file);
FileChannel channel = fis.getChannel();
lock=channel.lock(0, Long.MAX_VALUE, true);
parseInput(new CborDecoder(fis), channel);
} catch (IOException e) {
LOG.warn("Problem parsing file "+file.getName()+": " , e);
} catch (Exception e) {
LOG.error("Error parsing file "+file.getName()+ ": ", e);
transactions.clear();
throw new InputFormatException(e.toString());
}
}
public synchronized List<? extends byte[]> getChunksAtOffsets(ArrayList<Long> fileOffsets) throws InputFormatException {
List<byte[]> ret = new ArrayList<>();
try {
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;
}
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();
long txId = 0;
long genId = 0;
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);
txId = cborDecoder.readInt();
genId = cborDecoder.readInt();
long startTime = cborDecoder.readInt()*time_scale_factor;
long endTime = cborDecoder.readInt()*time_scale_factor;
TxGenerator gen = txGenerators.get(genId);
TxStream stream = gen.stream;
FtrTx scvTx = new FtrTx(txId, stream.getId(), genId, startTime, endTime, blockId, blockOffset);
updateTransactions(txId, scvTx);
if (scvTx.beginTime == scvTx.endTime) {
stream.addEvent(new TxEvent(this, EventKind.SINGLE, txId, scvTx.beginTime));
gen.addEvent(new TxEvent(this, EventKind.SINGLE, txId, scvTx.beginTime));
} else {
stream.addEvent(new TxEvent(this, EventKind.BEGIN, txId, scvTx.beginTime));
gen.addEvent(new TxEvent(this, EventKind.BEGIN, txId, scvTx.beginTime));
stream.addEvent(new TxEvent(this, EventKind.END, txId, scvTx.endTime));
gen.addEvent(new TxEvent(this, 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);
cborDecoder.readInt();
long type_id = cborDecoder.readInt();
switch(DataType.values()[(int)type_id]) {
case BOOLEAN:
cborDecoder.readBoolean();
break;
case FLOATING_POINT_NUMBER: // FLOATING_POINT_NUMBER
case FIXED_POINT_INTEGER: // FIXED_POINT_INTEGER
case UNSIGNED_FIXED_POINT_INTEGER: // UNSIGNED_FIXED_POINT_INTEGER
cborDecoder.readFloat();
break;
case NONE: // UNSIGNED_FIXED_POINT_INTEGER
LOG.warn("Unsupported data type: "+type_id);
break;
default:
cborDecoder.readInt();
}
}
}
}
next = cborDecoder.peekType();
}
}
private synchronized void updateTransactions(long txId, FtrTx scvTx) {
maxTime = maxTime > scvTx.endTime ? maxTime : scvTx.endTime;
transactions.put(txId, scvTx);
}
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(); //txid
cborDecoder.readInt(); // genId
cborDecoder.readInt(); // startTime
cborDecoder.readInt(); // endTime
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();
DataType type = DataType.values()[(int)type_id];
String attrName = strDict.get((int)name_id);
TxAttributeType attrType = getOrAddAttributeType(tag, type, attrName);
switch(type) {
case BOOLEAN:
ITxAttribute b = new TxAttribute(attrType, cborDecoder.readBoolean()?"True":"False");
ret.add(b);
break;
case INTEGER:
case UNSIGNED:
case POINTER:
case TIME:
ITxAttribute a = new TxAttribute(attrType, String.valueOf(cborDecoder.readInt()));
ret.add(a);
break;
case FLOATING_POINT_NUMBER:
case FIXED_POINT_INTEGER:
case UNSIGNED_FIXED_POINT_INTEGER:
ITxAttribute v = new TxAttribute(attrType, String.valueOf(cborDecoder.readFloat()));
ret.add(v);
break;
case ENUMERATION:
case BIT_VECTOR:
case LOGIC_VECTOR:
case STRING:
ITxAttribute s = new TxAttribute(attrType, strDict.get((int)cborDecoder.readInt()));
ret.add(s);
break;
default:
LOG.warn("Unsupported data type: "+type_id);
}
}
}
}
} catch (IOException e) {
LOG.error("Error parsing file "+file.getName(), e);
}
return ret;
}
private synchronized TxAttributeType getOrAddAttributeType(long tag, DataType type, String attrName) {
if(!attributeTypes.containsKey(attrName)) {
attributeTypes.put(attrName, new TxAttributeType(attrName, type, AssociationType.values()[(int)tag-7]));
}
TxAttributeType attrType = attributeTypes.get(attrName);
return attrType;
}
/**
* Dispose.
*/
@Override
public void dispose() {
try {
if(lock!=null) lock.close();
lock=null;
if(fis!=null) fis.close();
fis=null;
} catch (IOException e) { }
attrValues.clear();
relationTypes.clear();
txStreams.clear();
txGenerators.clear();
transactions.clear();
attributeTypes.clear();
relationsIn.clear();
relationsOut.clear();
}
static long calculateTimescaleMultipierPower(long power){
long answer = 1;
if(power<=0){
return answer;
} else{
for(int i = 1; i<= power; i++)
answer *= 10;
return answer;
}
}
public void parseInput(CborDecoder cborDecoder, FileChannel channel) {
try {
long cbor_tag = cborDecoder.readTag();
assert(cbor_tag == 55799);
long array_len = cborDecoder.readArrayLength();
assert(array_len==-1);
CborType next = cborDecoder.peekType();
while(next != null && !break_type.isEqualType(next)) {
long tag = cborDecoder.readTag();
switch((int)tag) {
case 6: { // info
CborDecoder cbd = new CborDecoder(new ByteArrayInputStream(cborDecoder.readByteString()));
long sz = cbd.readArrayLength();
assert(sz==2);
long time_scale=cbd.readInt();
long eff_time_scale=time_scale-IWaveformDb.databaseTimeScale;
time_scale_factor = calculateTimescaleMultipierPower(eff_time_scale);
long epoch_tag = cbd.readTag();
assert(epoch_tag==1);
cbd.readInt(); // epoch
break;
}
case 8: { // dictionary uncompressed
parseDict(new CborDecoder(new ByteArrayInputStream(cborDecoder.readByteString())));
break;
}
case 9: { // dictionary compressed
long sz = cborDecoder.readArrayLength();
assert(sz==2);
cborDecoder.readInt(); // uncompressed size
parseDict(new CborDecoder(new BlockLZ4CompressorInputStream(new ByteArrayInputStream(cborDecoder.readByteString()))));
break;
}
case 10: { // directory uncompressed
parseDir(new CborDecoder(new ByteArrayInputStream(cborDecoder.readByteString())));
break;
}
case 11: { // directory compressed
long sz = cborDecoder.readArrayLength();
assert(sz==2);
cborDecoder.readInt(); // uncompressed size
parseDir(new CborDecoder(new BlockLZ4CompressorInputStream(new ByteArrayInputStream(cborDecoder.readByteString()))));
break;
}
case 12: { //tx chunk uncompressed
long len = cborDecoder.readArrayLength();
assert(len==4);
long stream_id = cborDecoder.readInt();
cborDecoder.readInt(); // start time of block
long end_time = cborDecoder.readInt()*time_scale_factor;
maxTime = end_time>maxTime?end_time:maxTime;
txStreams.get(stream_id).fileOffsets.add(channel.position());
cborDecoder.readByteString();
break;
}
case 13: { //tx chunk compressed
long len = cborDecoder.readArrayLength();
assert(len==5);
long stream_id = cborDecoder.readInt();
cborDecoder.readInt(); // start time of block
long end_time = cborDecoder.readInt()*time_scale_factor;
cborDecoder.readInt(); // uncompressed size
maxTime = end_time>maxTime?end_time:maxTime;
txStreams.get(stream_id).fileOffsets.add(0-channel.position());
cborDecoder.readByteString();
break;
}
case 14: { // relations uncompressed
parseRel(new CborDecoder(new ByteArrayInputStream(cborDecoder.readByteString())));
break;
}
case 15: { // relations uncompressed
long sz = cborDecoder.readArrayLength();
assert(sz==2);
cborDecoder.readInt(); // uncompressed size
parseRel(new CborDecoder(new BlockLZ4CompressorInputStream(new ByteArrayInputStream(cborDecoder.readByteString()))));
break;
}
}
next = cborDecoder.peekType();
}
} catch(IOException e) {
long pos = 0;
try {pos=channel.position(); } catch (Exception ee) {}
LOG.error("Error parsing file input stream at position" + pos, 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==strDict.size()+lst.size());
lst.add(cborDecoder.readTextString());
}
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(this, stream_id, strDict.get((int)name_id), 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();
if(txStreams.containsKey(stream_id))
add(gen_id, new TxGenerator(this, gen_id, strDict.get((int)name_id), txStreams.get(stream_id)));
} else {
throw new IOException("Illegal tage ncountered: "+id);
}
}
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==5 || sz==3);
long type_id = cborDecoder.readInt();
long from_id = cborDecoder.readInt();
long to_id = cborDecoder.readInt();
long from_fiber = sz>3?cborDecoder.readInt():-1;
long to_fiber = sz>3?cborDecoder.readInt():-1;
String rel_name = strDict.get((int)type_id);
FtrRelation ftrRel = new FtrRelation(relationTypes.getOrDefault(rel_name, RelationTypeFactory.create(rel_name)), from_id, to_id, from_fiber, to_fiber);
relationsOut.put(from_id, ftrRel);
relationsIn.put(to_id, ftrRel);
next = cborDecoder.peekType();
}
}
private void add(Long id, TxStream stream) {
txStreams.put(id, stream);
pcs.firePropertyChange(IWaveformDbLoader.STREAM_ADDED, null, stream);
}
private void add(Long id, TxGenerator generator) {
txGenerators.put(id, generator);
pcs.firePropertyChange(IWaveformDbLoader.GENERATOR_ADDED, null, generator);
}
}

View File

@ -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();
}
}

View File

@ -0,0 +1,55 @@
/*******************************************************************************
* 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 source. */
final long source_fiber;
/** The target. */
final long target_fiber;
/** 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, long source_fiber, long target_fiber) {
this.source = source;
this.target = target;
this.source_fiber = source_fiber;
this.target_fiber = target_fiber;
this.relationType = relationType;
}
}

View File

@ -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 {
final TxStream stream = loader.txStreams.get(streamId);
final 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;
}
}

View File

@ -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;
}
}

View File

@ -0,0 +1,88 @@
/*******************************************************************************
* 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;
}
@Override
public String toString() {
return "FtxAttr: " + attributeType.toString() + "=" + value;
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -0,0 +1,127 @@
/*******************************************************************************
* 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.IOException;
import java.util.ArrayList;
import java.util.List;
import com.minres.scviewer.database.DirectionType;
import com.minres.scviewer.database.IEventList;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.InputFormatException;
/**
* 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 events.
*
* @return the events
*/
@Override
public IEventList getEvents() {
if(stream.events.size()==0) {
try {
List<byte[]> chunks = stream.getChunks();
int blockid = 0;
for (byte[] bs : chunks) {
loader.parseTx(stream, blockid++, bs);
}
} catch (InputFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return events;
}
/**
* 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;
}
@Override
public DirectionType getDirection() {
return DirectionType.IMPLICIT;
}
}

View File

@ -0,0 +1,152 @@
/*******************************************************************************
* 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.Collection;
import java.util.List;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.RelationType;
import com.minres.scviewer.database.tx.ITx;
import com.minres.scviewer.database.tx.ITxAttribute;
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() {
ITx tx = loader.getTransaction(scvRelation.source);
if(tx!=null) return tx;
return new TxFacade(scvRelation.source_fiber, scvRelation.source);
}
/**
* Gets the target.
*
* @return the target
*/
@Override
public ITx getTarget() {
ITx tx = loader.getTransaction(scvRelation.target);
if(tx!=null) return tx;
return new TxFacade(scvRelation.target_fiber, scvRelation.target);
}
private class TxFacade implements ITx {
final long fiberId;
final long txId;
ITx tx = null;
public TxFacade(long fiberId, long txId) {
this.fiberId = fiberId;
this.txId=txId;
}
@Override
public int compareTo(ITx o) {
return tx==null?-1:tx.compareTo(o);
}
@Override
public long getId() {
return txId;
}
@Override
public IWaveform getStream() {
if(tx==null) {
TxStream fiber = loader.txStreams.get(fiberId);
fiber.loadStream();
tx = loader.getTransaction(txId);
return loader.txStreams.get(fiberId);
} else
return tx.getStream();
}
@Override
public IWaveform getGenerator() {
if(tx==null) {
loader.txStreams.get(fiberId).loadStream();
tx = loader.getTransaction(txId);
}
return tx.getGenerator();
}
@Override
public long getBeginTime() {
return tx==null?-1:tx.getBeginTime();
}
@Override
public long getEndTime() {
return tx==null?-1:tx.getBeginTime();
}
@Override
public List<ITxAttribute> getAttributes() {
return tx==null?new ArrayList<>():tx.getAttributes();
}
@Override
public Collection<ITxRelation> getIncomingRelations() {
return tx==null?new ArrayList<>():tx.getIncomingRelations();
}
@Override
public Collection<ITxRelation> getOutgoingRelations() {
return tx==null?new ArrayList<>():tx.getOutgoingRelations();
}
@Override
public String toString() {
return tx==null?("tx#" + getId() + "[not available]"):tx.toString();
}
}
}

View File

@ -0,0 +1,104 @@
/*******************************************************************************
* 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.IOException;
import java.util.ArrayList;
import java.util.List;
import com.minres.scviewer.database.DirectionType;
import com.minres.scviewer.database.IEventList;
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;
}
public void loadStream() {
try {
List<byte[]> chunks = getChunks();
int blockid = 0;
for (byte[] bs : chunks) {
loader.parseTx(this, blockid, bs);
blockid++;
}
} catch (InputFormatException e) {
} catch (IOException e) {
}
}
/**
* Gets the events.
*
* @return the events
*/
@Override
public IEventList getEvents() {
if(events.size()==0) {
loadStream();
}
return events;
}
@Override
public DirectionType getDirection() {
return DirectionType.IMPLICIT;
}
}

View File

@ -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;
}

View File

@ -0,0 +1,516 @@
/*
* 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 (&lt;= 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, &gt;= 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;
}
// unsigned values larger than long.MAX are shown as negative values
// 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;
}
}

View File

@ -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 &gt;= 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 &gt;= 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 (&lt;= 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 &gt;= 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);
}
}

View 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();
}
}

View File

@ -0,0 +1 @@
version 1.0

View File

@ -1,8 +1,22 @@
<?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"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" output="target/classes" path="src">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry exported="true" kind="lib" path="sqlite-jdbc-3.8.7.jar"/>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@ -4,7 +4,7 @@ Bundle-Name: SQLite transaction database
Bundle-SymbolicName: com.minres.scviewer.database.sqlite
Bundle-Version: 1.1.0.qualifier
Bundle-Vendor: MINRES Technologies GmbH
Bundle-RequiredExecutionEnvironment: JavaSE-11
Bundle-RequiredExecutionEnvironment: JavaSE-17
Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0"
Bundle-ClassPath: .,sqlite-jdbc-3.8.7.jar
Service-Component: OSGI-INF/component.xml

View File

@ -4,7 +4,7 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.16.1</version>
<version>2.19.4</version>
<relativePath>../..</relativePath>
</parent>
<packaging>eclipse-plugin</packaging>

View File

@ -71,6 +71,11 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
return maxConcurrency;
}
@Override
public int getWidth() {
return 0;
}
@Override
public IEventList getEvents(){
if(events==null){

View File

@ -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;
@ -23,7 +21,6 @@ import java.util.Collection;
import java.util.List;
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;
@ -42,8 +39,6 @@ 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);
@ -98,8 +93,8 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
// }
@Override
public void load(IWaveformDb db, File file) throws InputFormatException {
database=new SQLiteDatabase(file.getAbsolutePath(), db);
public void load(File file) throws InputFormatException {
database=new SQLiteDatabase(file.getAbsolutePath());
database.setData("TIMERESOLUTION", 1L);
SQLiteDatabaseSelectHandler<ScvSimProps> handler = new SQLiteDatabaseSelectHandler<>(ScvSimProps.class, database);
try {

View File

@ -32,7 +32,18 @@ public class TxAttribute implements ITxAttribute{
@Override
public DataType getDataType() {
return DataType.values()[scvAttribute.getData_type()];
int dt = scvAttribute.getData_type();
switch(dt) {
case 12:
return DataType.STRING;
case 10:
return DataType.POINTER;
default:
if(dt<9)
return DataType.values()[dt];
else
return DataType.NONE;
}
}
@Override

View File

@ -16,6 +16,7 @@ import java.sql.SQLException;
import java.util.Map;
import java.util.TreeMap;
import com.minres.scviewer.database.DirectionType;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.sqlite.db.IDatabase;
import com.minres.scviewer.database.sqlite.db.SQLiteDatabaseSelectHandler;
@ -76,4 +77,8 @@ public class TxGenerator extends AbstractTxStream {
return transactions;
}
@Override
public DirectionType getDirection() {
return DirectionType.IMPLICIT;
}
}

View File

@ -18,6 +18,7 @@ import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import com.minres.scviewer.database.DirectionType;
import com.minres.scviewer.database.IEvent;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.sqlite.db.IDatabase;
@ -102,4 +103,9 @@ public class TxStream extends AbstractTxStream {
public String getKind() {
return scvStream.getKind();
}
@Override
public DirectionType getDirection() {
return DirectionType.IMPLICIT;
}
}

View File

@ -26,8 +26,6 @@ public class SQLiteDatabase implements IDatabase {
protected String dbFileName;
protected IWaveformDb waveformDb;
protected HashMap<String, Object> props;
static {
@ -43,10 +41,9 @@ public class SQLiteDatabase implements IDatabase {
}
}
public SQLiteDatabase(String dbFileName, IWaveformDb waveformDb) {
public SQLiteDatabase(String dbFileName) {
super();
this.dbFileName = dbFileName;
this.waveformDb = waveformDb;
props = new HashMap<String, Object>();
}
@ -96,7 +93,7 @@ public class SQLiteDatabase implements IDatabase {
@Override
public IWaveformDb getWaveformDb() {
return waveformDb;
return null;
}
}

View File

@ -1,8 +1,17 @@
<?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"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src/"/>
<classpathentry kind="src" output="target/classes" path="src">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<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!/"/>
@ -11,5 +20,10 @@
<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"/>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@ -4,7 +4,7 @@ Bundle-Name: Textual transaction database
Bundle-SymbolicName: com.minres.scviewer.database.text
Bundle-Version: 4.0.1.qualifier
Bundle-Vendor: MINRES Technologies GmbH
Bundle-RequiredExecutionEnvironment: JavaSE-11
Bundle-RequiredExecutionEnvironment: JavaSE-17
Import-Package: org.osgi.framework;version="1.3.0"
Require-Bundle: com.minres.scviewer.database,
org.eclipse.osgi.services;bundle-version="3.4.0",

View File

@ -6,7 +6,7 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.16.1</version>
<version>2.19.4</version>
<relativePath>../..</relativePath>
</parent>
<packaging>eclipse-plugin</packaging>

View File

@ -143,6 +143,10 @@ abstract class AbstractTxStream extends HierNode implements IWaveform {
return rowCount;
}
@Override
public int getWidth() {
return 0;
}
/**
* Calculate concurrency.
*/
@ -183,7 +187,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());
}
}

View File

@ -46,7 +46,6 @@ 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;
@ -222,7 +221,7 @@ public class TextDbLoader implements IWaveformDbLoader {
*/
@SuppressWarnings("unchecked")
@Override
public void load(IWaveformDb db, File file) throws InputFormatException {
public void load(File file) throws InputFormatException {
dispose();
FileType fType = getFileType(file);
if (file.length() < MEMMAP_LIMIT * (fType!=FileType.PLAIN ? 1 : 10)
@ -247,7 +246,7 @@ public class TextDbLoader implements IWaveformDbLoader {
parser.txSink = mapDb.hashMap("transactions", Serializer.LONG, Serializer.JAVA).create();
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 (IllegalArgumentException | IndexOutOfBoundsException e) {
} catch (Exception e) {
throw new InputFormatException(e.toString());
} finally {
@ -382,7 +381,7 @@ public class TextDbLoader implements IWaveformDbLoader {
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) {
if (curLine.length()>5 && 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]);
@ -520,6 +519,7 @@ public class TextDbLoader implements IWaveformDbLoader {
* @return the long
*/
private long stringToScale(String scale) {
// TODO: scale to IWaveformDb.databaseTimeScale
String cmp = scale.trim();
if ("fs".equals(cmp))
return 1L;

View File

@ -11,7 +11,6 @@
*******************************************************************************/
package com.minres.scviewer.database.text;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@ -32,22 +31,6 @@ public class TextDbLoaderFactory implements IWaveformDbLoaderFactory {
/** The Constant x. */
static final byte[] x = "scv_tr_stream".getBytes();
/**
* Checks if f is gzipped.
*
* @param f the f
* @return true, if is gzipped
*/
private static boolean isGzipped(File f) {
try (InputStream is = new FileInputStream(f)) {
byte[] signature = new byte[2];
int nread = is.read(signature); // read the gzip signature
return nread == 2 && signature[0] == (byte) 0x1f && signature[1] == (byte) 0x8b;
} catch (IOException e) {
return false;
}
}
/**
* Can load.
*

View File

@ -14,6 +14,7 @@ package com.minres.scviewer.database.text;
import java.util.ArrayList;
import java.util.List;
import com.minres.scviewer.database.DirectionType;
import com.minres.scviewer.database.IWaveform;
/**
@ -93,4 +94,8 @@ class TxGenerator extends AbstractTxStream {
return ((AbstractTxStream)parent).getFullName()+"."+name;
}
@Override
public DirectionType getDirection() {
return DirectionType.IMPLICIT;
}
}

View File

@ -11,6 +11,7 @@
*******************************************************************************/
package com.minres.scviewer.database.text;
import com.minres.scviewer.database.DirectionType;
import com.minres.scviewer.database.IWaveform;
/**
@ -55,4 +56,8 @@ class TxStream extends AbstractTxStream {
return kind;
}
@Override
public DirectionType getDirection() {
return DirectionType.IMPLICIT;
}
}

View File

@ -1,7 +1,21 @@
<?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"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" output="target/classes" path="src">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@ -4,7 +4,7 @@ Bundle-Name: SWT database widget
Bundle-SymbolicName: com.minres.scviewer.database.ui.swt
Bundle-Version: 4.0.0.qualifier
Bundle-Vendor: MINRES Technologies GmbH
Bundle-RequiredExecutionEnvironment: JavaSE-11
Bundle-RequiredExecutionEnvironment: JavaSE-17
Require-Bundle: org.eclipse.swt;bundle-version="3.103.1",
com.minres.scviewer.database;bundle-version="1.0.0",
com.google.guava;bundle-version="15.0.0",

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.16.1</version>
<version>2.19.4</version>
<relativePath>../..</relativePath>
</parent>
<version>4.0.0-SNAPSHOT</version>

View File

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2015-2021 MINRES Technologies GmbH and others.
* Copyright (c) 2015-2023 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
@ -12,8 +12,8 @@ package com.minres.scviewer.database.ui;
public interface ICursor {
public long getTime();
long getTime();
public void setTime(long time);
void setTime(long time);
}

View File

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2015-2021 MINRES Technologies GmbH and others.
* Copyright (c) 2015-2023 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
@ -35,82 +35,86 @@ public interface IWaveformView extends PropertyChangeListener, ISelectionProvide
static final int MARKER_POS = 1;
public static final RelationType NEXT_PREV_IN_STREAM = RelationTypeFactory.create("Prev/Next in stream");
static final RelationType NEXT_PREV_IN_STREAM = RelationTypeFactory.create("Prev/Next in stream");
public void addSelectionChangedListener(ISelectionChangedListener listener);
void addSelectionChangedListener(ISelectionChangedListener listener);
public void removeSelectionChangedListener(ISelectionChangedListener listener);
void removeSelectionChangedListener(ISelectionChangedListener listener);
public void setStyleProvider(IWaveformStyleProvider styleProvider);
void setStyleProvider(IWaveformStyleProvider styleProvider);
public void update();
void update();
public Control getControl();
Control getControl();
public Control getNameControl();
Control getNameControl();
public Control getValueControl();
Control getValueControl();
public Control getWaveformControl();
Control getWaveformControl();
public ISelection getSelection();
ISelection getSelection();
public void setSelection(ISelection selection);
void setSelection(ISelection selection);
public void setSelection(ISelection selection, boolean showIfNeeded);
void setSelection(ISelection selection, boolean showIfNeeded);
public void addToSelection(ISelection selection, boolean showIfNeeded);
void addToSelection(ISelection selection, boolean showIfNeeded);
public void moveSelection(GotoDirection direction);
void moveSelection(GotoDirection direction);
public void moveSelection(GotoDirection direction, RelationType relationType);
void moveSelection(GotoDirection direction, RelationType relationType);
public void moveCursor(GotoDirection direction);
void moveCursor(GotoDirection direction);
public List<TrackEntry> getStreamList();
List<TrackEntry> getStreamList();
public TrackEntry getEntryFor(ITx source);
TrackEntry getEntryFor(ITx source);
public TrackEntry getEntryFor(IWaveform source);
TrackEntry getEntryFor(IWaveform source);
public List<Object> getElementsAt(Point pt);
List<Object> getElementsAt(Point pt);
public void moveSelectedTrack(int i);
void moveSelectedTrack(int i);
public void setHighliteRelation(RelationType relationType);
void setHighliteRelation(RelationType relationType);
public void setMaxTime(long maxTime);
void setMaxTime(long maxTime);
public void setCursorTime(long time);
void setCursorTime(long time);
public void setMarkerTime(int marker, long time);
void setMarkerTime(int marker, long time);
public long getCursorTime();
long getCursorTime();
public int getSelectedMarker();
int getSelectedMarker();
public long getMarkerTime(int marker);
long getMarkerTime(int marker);
public void addPropertyChangeListener(PropertyChangeListener listener);
void addPropertyChangeListener(PropertyChangeListener listener);
public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener);
void addPropertyChangeListener(String propertyName, PropertyChangeListener listener);
public void removePropertyChangeListener(PropertyChangeListener listener);
void removePropertyChangeListener(PropertyChangeListener listener);
public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener);
void removePropertyChangeListener(String propertyName, PropertyChangeListener listener);
public List<ICursor> getCursorList();
List<ICursor> getCursorList();
public void scrollHorizontal(int percent);
void scrollHorizontal(int percent);
public void scrollTo(int pos);
void scrollTo(int pos);
public void addDisposeListener( DisposeListener listener );
void addDisposeListener( DisposeListener listener );
public void deleteSelectedTracks();
void addEventListner(IWaveformviewEventListener listener);
public TrackEntry addWaveform(IWaveform waveform, int pos);
void removeEventListner(IWaveformviewEventListener listener);
public IWaveformZoom getWaveformZoom();
void deleteSelectedTracks();
TrackEntry addWaveform(IWaveform waveform, int pos);
IWaveformZoom getWaveformZoom();
}

View File

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2015-2021 MINRES Technologies GmbH and others.
* Copyright (c) 2015-2023 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
@ -13,7 +13,7 @@ package com.minres.scviewer.database.ui;
import org.eclipse.swt.widgets.Composite;
public interface IWaveformViewFactory {
public IWaveformView createPanel(Composite parent);
IWaveformView createPanel(Composite parent);
public IWaveformView createPanel(Composite parent, IWaveformStyleProvider styleProvider);
IWaveformView createPanel(Composite parent, IWaveformStyleProvider styleProvider);
}

View File

@ -0,0 +1,16 @@
/*******************************************************************************
* Copyright (c) 2015-2023 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
*******************************************************************************/
package com.minres.scviewer.database.ui;
public interface IWaveformviewEventListener {
void onTrackEntryDoubleClickEvent (TrackEntry trackEntry);
}

Some files were not shown because too many files have changed in this diff Show More