Compare commits

...

167 Commits

Author SHA1 Message Date
f1abc645c3 Merge branch 'hotfix/#27_truncated_input' 2020-03-11 07:37:21 +01:00
2c8b7129e9 add fix for #27 'parser doesn't handle truncated input files' 2020-03-11 07:37:14 +01:00
8f76d816f1 Merge branch 'hotfix/#26_incomplete_regex_throws_exception' 2020-03-11 07:35:42 +01:00
594a71a9ba add try-catch to filter application 2020-03-11 07:35:31 +01:00
97443c6cd8 Merge branch 'release/2.1.4' 2020-03-09 18:02:19 +01:00
c3486eb6c8 Updated version numbers 2020-03-09 18:00:15 +01:00
8a286a8eac Merge branch 'release/2.1.4' 2020-03-09 17:58:47 +01:00
e4329213fa Fixed missing version number 2020-03-09 17:55:50 +01:00
857bbe17d7 Merge branch 'release/2.1.3' 2020-03-09 17:55:05 +01:00
091cb1cf7f Fixed missing version number 2020-03-09 17:53:35 +01:00
0623b8de4a Fixed #25 - TransactionDetails vanish when setting filter for streamlist 2020-02-28 21:19:40 +01:00
8b55548cca Fixed #16 - Setting and deleting filter removes properties 2020-02-17 19:43:27 +01:00
a0a4ea1f53 Merge branch 'release/2.1.3'
Conflicts:
	com.minres.scviewer.e4.application/META-INF/MANIFEST.MF
2020-02-10 07:04:54 +01:00
e034d1faad Updated version numbers 2020-02-10 07:03:24 +01:00
68660d0892 Merge branch 'release/2.1.2' 2020-02-10 06:50:07 +01:00
a0f0b55045 Updated application bundle version number 2020-02-10 06:46:55 +01:00
3d20b6961e Updated groovy compiler level 2020-02-10 02:25:40 +01:00
ca02c92a18 Fixed #23 - Fix sync of properties 2020-02-03 21:30:44 +01:00
347dbf134b removed javax.xml.bind dependency 2020-01-28 23:23:15 +01:00
44ac32359f Fixed #19 - Fixed sync of streamlist 2020-01-27 20:37:53 +01:00
48c7d81b8a Merge branch 'develop' of VP-Tools/SCViewer into master 2020-01-13 12:26:56 +00:00
e945a3acbe Fixed NP and updated build infrastructure and target platform 2020-01-13 12:26:56 +00:00
145dfbd74d Fixed NP and updated build infrastructure and target platform 2020-01-13 12:26:56 +00:00
b7646dc29e Extended data type for text database 2020-01-13 12:26:56 +00:00
475181c8df Fixed #21 - IllegalStateException when closing SCViewer 2020-01-13 12:26:56 +00:00
3d043ce1b7 Fixed #20 - NPE gets caught when opening a damaged file and info popup
is shown
2020-01-13 12:26:56 +00:00
7e2869b7ee Fixed # 18 - Fixed tree view and stream list after last tab is closed 2020-01-13 12:26:56 +00:00
51d9d7e25c Fixed NP and updated build infrastructure and target platform 2020-01-13 13:17:27 +01:00
ed665ac032 Fixed NP and updated build infrastructure and target platform 2020-01-13 13:14:34 +01:00
689d7874f4 Extended data type for text database 2020-01-07 12:43:39 +01:00
c7c1f97b0c Fixed #21 - IllegalStateException when closing SCViewer 2019-12-18 17:16:20 +01:00
7b2db09585 Fixed #20 - NPE gets caught when opening a damaged file and info popup
is shown
2019-12-03 22:19:56 +01:00
52f3f7b348 Fixed # 18 - Fixed tree view and stream list after last tab is closed 2019-11-25 17:46:28 +01:00
429ea37080 Merge branch 'release/2.1.2' 2019-09-11 13:08:52 +02:00
04f011e82f Fixed array out of bounds error 2019-09-11 13:05:26 +02:00
3a6ed3ce7e Fixed 'Save Settings' #4 2019-09-04 20:50:34 +02:00
79eb8073d8 Merge branch 'release/2.1.1' 2019-07-08 18:44:47 +02:00
4ea841cc7b Fixed Part Stack issue and updated About Dialog 2019-07-08 18:38:53 +02:00
6bf642d2af Merge branch 'release/2.1.0' 2019-06-30 11:54:10 +02:00
15c24f0925 Fixed #15 - no more ArrayOutOfBounds exception when deleting last stream 2019-06-25 22:21:10 +02:00
4d4a6579c6 Fixed #13 - added transaction colors 2019-06-09 21:49:45 +02:00
b648dccfd8 Fixed NPE in case of detached waveform 2019-04-11 06:24:47 +00:00
f9425834a3 Merge branch 'develop' of https://eyck@git.minres.com/VP/SCViewer.git into develop 2019-04-11 06:09:46 +00:00
e0d00e6402 Settings update 2019-04-11 06:09:35 +00:00
b1b7517759 Merge branch 'release/2.0.5' into develop 2019-03-19 19:15:28 +01:00
a5b9c28007 Merge branch 'release/2.0.5' 2019-03-19 19:15:27 +01:00
b5e408595b Updated version numbers 2019-03-19 19:14:39 +01:00
f15930682e Merge branch 'develop' of https://git.minres.com/VP/SCViewer.git into develop 2019-03-19 18:46:56 +01:00
f8765518bc Fixed #10 -all status bar parts now visible after starting program 2019-03-18 17:17:18 +01:00
73e952faea Fixed #11 - No more display problems in waveforms when zooming in and
scrolling
2019-03-18 17:17:17 +01:00
111383bcba Merge branch 'release/2.0.4' into develop 2019-03-15 08:53:16 +01:00
244f005ae6 Merge branch 'release/2.0.4' 2019-03-15 08:53:15 +01:00
701733e69d Updated version numbers and display in about dialog 2019-03-15 08:50:12 +01:00
6b4a9c1e14 Fixed handling of TransactionDetails view state 2019-03-15 07:31:13 +00:00
3abbc3e0e2 Merge branch 'master' into develop 2019-03-14 21:29:23 +01:00
2a7b713ef2 Merge branch 'release/2.0.3' 2019-03-14 21:26:55 +01:00
593571ce10 Merge branch 'hotfix/selction_bug' into develop 2019-03-14 21:23:59 +01:00
979261432a Merge branch 'hotfix/selction_bug' 2019-03-14 21:23:58 +01:00
e25f56a8a9 Fixed NPE 2019-03-14 21:23:39 +01:00
e8788e6ce0 Merge branch 'master' into develop 2019-03-14 21:14:26 +01:00
8a8691a889 Merge branch 'release/2.0.2' 2019-03-14 21:11:51 +01:00
de15b84bef Merge branch 'feature/keep_properties_scroll' into develop 2019-03-14 20:51:31 +01:00
b78d8bea45 Fixed format detection bug and adapted VCD loader to Arteris specifics 2019-03-14 20:51:02 +01:00
a49842a119 Added logic to keep the same element revealed in transaction details
view
2019-03-14 19:28:38 +01:00
dbe5d603ed Fixed EOFException so that partial gzip files get loaded 2019-03-14 19:27:58 +01:00
cde1835c74 Merge branch 'develop' of https://eyck@git.minres.com/VP/SCViewer.git into develop 2018-11-06 12:36:40 +01:00
b332eca891 Fixed about dialog handling 2018-11-06 12:36:25 +01:00
75efd69b77 Merge branch 'master' of https://github.com/Minres/SCViewer 2018-11-06 12:33:34 +01:00
960610bab2 Fixed about dialog handling 2018-11-06 12:28:45 +01:00
98029f8c7a Merge branch 'master' of https://eyck@git.minres.com/VP/SCViewer.git 2018-11-06 12:08:42 +01:00
9c09cf5f40 Merge branch 'release/2.0.0' into develop 2018-11-06 12:07:37 +01:00
113d65cfc4 Merge branch 'release/2.0.0' 2018-11-06 12:07:35 +01:00
22e7bb04f0 Updated documentation 2018-11-06 12:07:23 +01:00
d8c5b7d9c3 Merge branch 'develop' of https://git.minres.com/VP/SCViewer into
develop

# Conflicts:
#	com.minres.scviewer.e4.application/src/com/minres/scviewer/e4/application/parts/WaveformViewer.java
2018-11-06 08:35:00 +01:00
2e7ae5309f Merge branch 'feature/MapDB-backing' into develop 2018-11-06 08:32:12 +01:00
f81e830e93 Updated UI to reflect database changes esp. in VCD 2018-11-06 08:26:39 +01:00
47a285bf6d Added MapDB backing store for Text based Transactions, cleanup of
imports etc.
2018-11-06 08:24:26 +01:00
c080773878 Removed jdbm files and added MapDB 3.0.7 jar files 2018-11-05 18:33:51 +01:00
bcf4e1a274 Adapted application to data model changes 2018-11-05 18:23:17 +01:00
93fd192782 Refactored database data model to improve speed and reduce memory
consumption
2018-11-05 18:22:28 +01:00
e687eef42c Fixed Tx properties 2018-11-05 18:16:59 +01:00
2a709113fe Uodated tests to run on LevelDB backed transaction db 2018-11-03 17:49:40 +01:00
8d7acdb9cb Added LevelDB transaction db reader 2018-11-03 17:48:36 +01:00
77684d828c Merge branch 'master' of https://git.minres.com/VP/SCViewer 2018-10-15 22:31:22 +02:00
9f902057ba Merge branch 'release/2.0.1' 2018-10-15 22:30:02 +02:00
42660c7a2e Fixed some warnings 2018-10-15 22:01:44 +02:00
97a806f9d9 Changed selection handling and fixed keycode handling 2018-10-15 21:55:35 +02:00
60185fbaee Version inconsitency fixes 2018-10-15 10:09:51 +02:00
5411a405d4 Merge branch 'master' of https://github.com/Minres/SCViewer 2018-10-15 09:32:43 +02:00
694dad1cf5 Merge branch 'develop' 2018-10-15 09:17:44 +02:00
5fb9a7dcdf Merge branch 'master' of https://git.minres.com/VP/SCViewer 2018-10-15 09:15:04 +02:00
3faa7205ae Merge branch 'release/2.0' into develop 2018-10-15 09:13:55 +02:00
3cbe5d56d9 Merge branch 'release/2.0' 2018-10-15 09:13:54 +02:00
5745ab4f2c Fixed cli options and NaN handling in VCD loader 2018-10-15 09:13:41 +02:00
4a17108ccc Moved commonly used constants to own class 2018-10-15 09:10:10 +02:00
408138c27c Merge branch 'develop' of https://git.minres.com/VP/SCViewer into develop 2018-10-15 07:50:31 +02:00
3211db8743 Merge branch 'release/2.0' 2018-10-14 21:29:23 +02:00
0c81988d8c Merge branch 'release/2.0' into develop 2018-10-14 21:29:23 +02:00
0107c423a3 Fixed warnings in Java files and MANIFESTS.MF, updated version numbers 2018-10-14 21:29:09 +02:00
5d41816eb6 Merge branch 'feature/add-keyboard-navigation' into develop 2018-10-14 20:44:41 +02:00
e41b7e25ed Updated reading/writing of scview files, added command line argument to
load config file
2018-10-14 20:44:17 +02:00
dba8b2731d Added keyboard navigation to scroll, move selection, move selected and
zoom
2018-10-14 17:30:37 +02:00
048fa93b53 Merge branch 'feature/Extend-waveform-configurability' into develop 2018-10-14 08:59:37 +02:00
6cc5597c25 Added handler and configurability of wavefrom view 2018-10-14 08:59:17 +02:00
694423be3b [WIP] extended application to configure waveform display 2018-10-11 15:23:07 +02:00
0634b9cfd5 Merge branch 'develop' of https://git.minres.com/VP/SCViewer.git into
develop

Conflicts:
	com.minres.scviewer.database.test/inputs/simple_system.vcd
	com.minres.scviewer.database.test/src/com/minres/scviewer/database/test/DatabaseServicesTest.java
	com.minres.scviewer.database.text/.settings/org.eclipse.jdt.groovy.core.prefs
	com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/SignalPainter.java
	com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/WaveformCanvas.java
	com.minres.scviewer.database.ui.swt/src/com/minres/scviewer/database/swt/internal/WaveformViewer.java
	com.minres.scviewer.database.ui/src/com/minres/scviewer/database/ui/WaveformColors.java
	com.minres.scviewer.database.vcd/src/com/minres/scviewer/database/vcd/VCDDbLoader.java
	com.minres.scviewer.database.vcd/src/com/minres/scviewer/database/vcd/VCDFileParser.java
	com.minres.scviewer.e4.application/plugin.xml
	com.minres.scviewer.e4.product/scviewer.product
	com.minres.scviewer.target/neon.target
	com.minres.scviewer.target/photon.target
	com.minres.scviewer.ui/.settings/org.eclipse.jdt.groovy.core.prefs
2018-10-11 15:22:10 +02:00
c4b16338a8 Merge branch 'feature/real_signal_support' into develop 2018-10-11 14:53:07 +02:00
bda2a84532 Fixed #6 Implement right-click menue for signal names 2018-10-11 14:48:36 +02:00
9d4c951e7f Added support for real valued signals in waveform UI 2018-10-11 14:44:41 +02:00
8a89b21d34 Added database support to read real valued signals 2018-10-11 11:23:28 +02:00
e02df858fa Merge branch 'develop' of https://git.minres.com/VP/SCViewer into develop 2018-09-26 21:25:23 +02:00
0fbe22e2e0 Fixed NPE when concurrencyLevel is 0 2018-09-26 21:25:02 +02:00
021c2bceff Fixed ZoomFit and encoding issue 2018-09-17 17:06:57 +02:00
9862c14040 Additional files missing in the last commit 2018-09-17 16:38:27 +02:00
23131e7527 Fixed ZoomFit 2018-09-17 16:38:26 +02:00
0833bca1bd Fixed VCD parsing error 2018-09-17 16:38:25 +02:00
1cf00ec882 Updated to Photon platform 2018-09-17 16:38:24 +02:00
6c0bbd5f1f Added hierarchical VCD File 2018-09-17 16:32:07 +02:00
f13b091664 Update README.md 2018-09-17 16:26:49 +02:00
dff41eceb2 Updated version numbers 2018-09-17 16:26:49 +02:00
d267e64907 Fixed parsing bug 2018-09-17 16:26:49 +02:00
792dcd55f3 Fixed rendering of integral transaction attributes and updated version
numbers
2018-09-17 16:26:48 +02:00
2b33ea0c85 Fixed drawing issue for very long transactions 2018-08-27 23:46:06 +02:00
f69a6f2e89 Removed jdbm 2018-08-27 23:16:54 +02:00
0f133a3df6 Added UI support for real value signals 2018-08-27 23:13:19 +02:00
549c522bf7 Added support for real value signals 2018-08-27 16:19:59 +02:00
2f11d8ed7b Fixed VCD parsing error 2018-07-16 13:17:58 +02:00
7dd0a24df6 Updated to Photon platform 2018-07-16 13:17:43 +02:00
a052fe2324 Added hierarchical VCD File 2018-07-14 11:42:55 +02:00
4fc24453ae Merge branch 'develop'
* develop:
  Update README.md
2018-04-05 23:10:31 +02:00
b468fba441 Update README.md 2018-04-05 23:04:12 +02:00
f80021059e Update README.md 2017-11-01 19:02:01 +01:00
7c0822b4d2 Merge pull request #4 from Minres/develop
Develop
2017-10-14 19:06:53 +00:00
cdde384ed3 Updated version numbers 2017-10-14 20:59:30 +02:00
fce1bdb1e7 Fixed parsing bug 2017-10-14 20:46:22 +02:00
b68a7d3259 Merge pull request #3 from Minres/develop
Changes for 1.2.1 version
2017-10-13 08:03:11 +00:00
44b13c105d Fixed rendering of integral transaction attributes and updated version
numbers
2017-10-13 09:36:44 +02:00
ed0558afdf Fixed compiler warnings and moved execution environment to Java 1.8 2017-01-23 23:25:28 +01:00
d0be3b0ca2 Externalized strings 2017-01-23 23:07:29 +01:00
a052c6aa3b Enabled test 2017-01-23 22:26:05 +01:00
8a30ba8dea Fixed target platform setting for tests 2017-01-23 22:18:59 +01:00
0a7972c54d Merge pull request #2 from Minres/develop
Merge in latest changes
2017-01-23 20:44:18 +00:00
b1890eb5e1 Updated License information and fixed pom warning 2017-01-23 21:41:48 +01:00
1aaf5c837e Added support for gzipped txlog files and org.apache.jdbm as backing
store
2017-01-23 21:23:43 +01:00
c8a213e985 Fixed windows icons, adjusted version numbers 2017-01-22 15:14:03 +01:00
5f82700290 Updated to Neon platform 2017-01-22 14:05:42 +01:00
40a0137dfd Fixed compile warnings and performance bottlenecks in drawing 2017-01-22 10:28:49 +01:00
4ec9a928b9 Merge pull request #1 from Minres/master
Create LICENSE
2016-12-15 13:16:50 +01:00
c82c41bbf0 Create LICENSE 2016-10-20 07:08:35 +02:00
79c49e6f1d Removed SCV code 2016-10-08 21:53:07 +02:00
96d628d322 Updated version numbers 2015-12-02 20:35:03 +01:00
b4d81d96b8 Cleanup of project structure 2015-12-02 20:29:17 +01:00
08fdc18290 Merge pull request #7 from eyck/develop
Develop
2015-12-01 21:13:38 +01:00
5c784af74f 6: Add Load/Save state functionality
Task-Url: https://github.com/eyck/txviewer/issues/issue/6
2015-11-30 22:55:03 +01:00
ff4cb91aed 6: Add Load/Save state functionality
Task-Url: https://github.com/eyck/txviewer/issues/issue/6
2015-11-30 22:16:29 +01:00
31ed3e4858 5: DesignBrowser should indicate loading of database
Task-Url: https://github.com/eyck/txviewer/issues/issue/5
2015-11-22 16:38:00 +01:00
0007ab9322 4: It shoudl be possible to start SCViewer several times in parallel
Task-Url: https://github.com/eyck/txviewer/issues/issue/4
2015-11-22 14:29:55 +01:00
f723a770c7 - small refactoring of part class names
- tried to improve Javadoc
2015-11-22 12:47:07 +01:00
af1b3d00dc Changed AboutDialog to be a ApplicationModel element 2015-11-22 12:17:17 +01:00
316647031a 2: Reload dialog opens while dialog is open
Task-Url: https://github.com/eyck/txviewer/issues/issue/2
2015-11-22 12:14:27 +01:00
929cf21ff8 3: Zoom in/out should try its best to keep cursor at the same position
Task-Url: https://github.com/eyck/txviewer/issues/issue/3
2015-11-22 12:07:50 +01:00
6ff48cac7a Merge branch 'develop' of https://github.com/eyck/txviewer into develop 2015-11-21 19:04:15 +01:00
b083094cc8 Added tlm3 recording sockets 2015-11-21 19:03:50 +01:00
8180a0e5d7 Merge branch 'master' of https://github.com/eyck/txviewer 2015-11-16 13:30:40 +01:00
5a39bab52e Fixed about message 2015-11-16 13:28:44 +01:00
02ba74ae16 Merge pull request #1 from eyck/develop
Fixed about message
2015-11-16 10:51:39 +01:00
c02f8a6520 Fixed about message 2015-11-16 10:51:05 +01:00
217 changed files with 412403 additions and 162411 deletions

5
.gitignore vendored
View File

@ -3,3 +3,8 @@
/.recommenders/
/RemoteSystemsTempFiles/
/*.zip
SCViewer initiator_target.launch
SCViewer.xcf
SCViewer_1.png
*.launch
copyrightLog.txt

203
LICENSE Normal file
View File

@ -0,0 +1,203 @@
Eclipse Public License - v 1.0
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
1. DEFINITIONS
"Contribution" means:
a) in the case of the initial Contributor, the initial code and documentation
distributed under this Agreement, and
b) in the case of each subsequent Contributor:
i) changes to the Program, and
ii) additions to the Program;
where such changes and/or additions to the Program originate from and are
distributed by that particular Contributor. A Contribution 'originates'
from a Contributor if it was added to the Program by such Contributor
itself or anyone acting on such Contributor's behalf. Contributions do not
include additions to the Program which: (i) are separate modules of
software distributed in conjunction with the Program under their own
license agreement, and (ii) are not derivative works of the Program.
"Contributor" means any person or entity that distributes the Program.
"Licensed Patents" mean patent claims licensable by a Contributor which are
necessarily infringed by the use or sale of its Contribution alone or when
combined with the Program.
"Program" means the Contributions distributed in accordance with this
Agreement.
"Recipient" means anyone who receives the Program under this Agreement,
including all Contributors.
2. GRANT OF RIGHTS
a) Subject to the terms of this Agreement, each Contributor hereby grants
Recipient a non-exclusive, worldwide, royalty-free copyright license to
reproduce, prepare derivative works of, publicly display, publicly
perform, distribute and sublicense the Contribution of such Contributor,
if any, and such derivative works, in source code and object code form.
b) Subject to the terms of this Agreement, each Contributor hereby grants
Recipient a non-exclusive, worldwide, royalty-free patent license under
Licensed Patents to make, use, sell, offer to sell, import and otherwise
transfer the Contribution of such Contributor, if any, in source code and
object code form. This patent license shall apply to the combination of
the Contribution and the Program if, at the time the Contribution is
added by the Contributor, such addition of the Contribution causes such
combination to be covered by the Licensed Patents. The patent license
shall not apply to any other combinations which include the Contribution.
No hardware per se is licensed hereunder.
c) Recipient understands that although each Contributor grants the licenses
to its Contributions set forth herein, no assurances are provided by any
Contributor that the Program does not infringe the patent or other
intellectual property rights of any other entity. Each Contributor
disclaims any liability to Recipient for claims brought by any other
entity based on infringement of intellectual property rights or
otherwise. As a condition to exercising the rights and licenses granted
hereunder, each Recipient hereby assumes sole responsibility to secure
any other intellectual property rights needed, if any. For example, if a
third party patent license is required to allow Recipient to distribute
the Program, it is Recipient's responsibility to acquire that license
before distributing the Program.
d) Each Contributor represents that to its knowledge it has sufficient
copyright rights in its Contribution, if any, to grant the copyright
license set forth in this Agreement.
3. REQUIREMENTS
A Contributor may choose to distribute the Program in object code form under
its own license agreement, provided that:
a) it complies with the terms and conditions of this Agreement; and
b) its license agreement:
i) effectively disclaims on behalf of all Contributors all warranties
and conditions, express and implied, including warranties or
conditions of title and non-infringement, and implied warranties or
conditions of merchantability and fitness for a particular purpose;
ii) effectively excludes on behalf of all Contributors all liability for
damages, including direct, indirect, special, incidental and
consequential damages, such as lost profits;
iii) states that any provisions which differ from this Agreement are
offered by that Contributor alone and not by any other party; and
iv) states that source code for the Program is available from such
Contributor, and informs licensees how to obtain it in a reasonable
manner on or through a medium customarily used for software exchange.
When the Program is made available in source code form:
a) it must be made available under this Agreement; and
b) a copy of this Agreement must be included with each copy of the Program.
Contributors may not remove or alter any copyright notices contained
within the Program.
Each Contributor must identify itself as the originator of its Contribution,
if
any, in a manner that reasonably allows subsequent Recipients to identify the
originator of the Contribution.
4. COMMERCIAL DISTRIBUTION
Commercial distributors of software may accept certain responsibilities with
respect to end users, business partners and the like. While this license is
intended to facilitate the commercial use of the Program, the Contributor who
includes the Program in a commercial product offering should do so in a manner
which does not create potential liability for other Contributors. Therefore,
if a Contributor includes the Program in a commercial product offering, such
Contributor ("Commercial Contributor") hereby agrees to defend and indemnify
every other Contributor ("Indemnified Contributor") against any losses,
damages and costs (collectively "Losses") arising from claims, lawsuits and
other legal actions brought by a third party against the Indemnified
Contributor to the extent caused by the acts or omissions of such Commercial
Contributor in connection with its distribution of the Program in a commercial
product offering. The obligations in this section do not apply to any claims
or Losses relating to any actual or alleged intellectual property
infringement. In order to qualify, an Indemnified Contributor must:
a) promptly notify the Commercial Contributor in writing of such claim, and
b) allow the Commercial Contributor to control, and cooperate with the
Commercial Contributor in, the defense and any related settlement
negotiations. The Indemnified Contributor may participate in any such claim at
its own expense.
For example, a Contributor might include the Program in a commercial product
offering, Product X. That Contributor is then a Commercial Contributor. If
that Commercial Contributor then makes performance claims, or offers
warranties related to Product X, those performance claims and warranties are
such Commercial Contributor's responsibility alone. Under this section, the
Commercial Contributor would have to defend claims against the other
Contributors related to those performance claims and warranties, and if a
court requires any other Contributor to pay any damages as a result, the
Commercial Contributor must pay those damages.
5. NO WARRANTY
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE,
NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each
Recipient is solely responsible for determining the appropriateness of using
and distributing the Program and assumes all risks associated with its
exercise of rights under this Agreement , including but not limited to the
risks and costs of program errors, compliance with applicable laws, damage to
or loss of data, programs or equipment, and unavailability or interruption of
operations.
6. DISCLAIMER OF LIABILITY
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE
EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGES.
7. GENERAL
If any provision of this Agreement is invalid or unenforceable under
applicable law, it shall not affect the validity or enforceability of the
remainder of the terms of this Agreement, and without further action by the
parties hereto, such provision shall be reformed to the minimum extent
necessary to make such provision valid and enforceable.
If Recipient institutes patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Program itself
(excluding combinations of the Program with other software or hardware)
infringes such Recipient's patent(s), then such Recipient's rights granted
under Section 2(b) shall terminate as of the date such litigation is filed.
All Recipient's rights under this Agreement shall terminate if it fails to
comply with any of the material terms or conditions of this Agreement and does
not cure such failure in a reasonable period of time after becoming aware of
such noncompliance. If all Recipient's rights under this Agreement terminate,
Recipient agrees to cease use and distribution of the Program as soon as
reasonably practicable. However, Recipient's obligations under this Agreement
and any licenses granted by Recipient relating to the Program shall continue
and survive.
Everyone is permitted to copy and distribute copies of this Agreement, but in
order to avoid inconsistency the Agreement is copyrighted and may only be
modified in the following manner. The Agreement Steward reserves the right to
publish new versions (including revisions) of this Agreement from time to
time. No one other than the Agreement Steward has the right to modify this
Agreement. The Eclipse Foundation is the initial Agreement Steward. The
Eclipse Foundation may assign the responsibility to serve as the Agreement
Steward to a suitable separate entity. Each new version of the Agreement will
be given a distinguishing version number. The Program (including
Contributions) may always be distributed subject to the version of the
Agreement under which it was received. In addition, after a new version of the
Agreement is published, Contributor may elect to distribute the Program
(including its Contributions) under the new version. Except as expressly
stated in Sections 2(a) and 2(b) above, Recipient receives no rights or
licenses to the intellectual property of any Contributor under this Agreement,
whether expressly, by implication, estoppel or otherwise. All rights in the
Program not expressly granted under this Agreement are reserved.
This Agreement is governed by the laws of the State of New York and the
intellectual property laws of the United States of America. No party to this
Agreement will bring a legal action under this Agreement more than one year
after the cause of action arose. Each party waives its rights to a jury trial in
any resulting litigation.

View File

@ -6,34 +6,26 @@ created by the SystemC VCD trace implementation and the SystemC Verification Lib
For further description of the SCV please refer to
http://www.accellera.org/activities/committees/systemc-verification.
The viewer is in early alpha stage and not yet ready for production use!
> If you encounter issue when running on Linux please try running as `SWT_GTK3=0 scviewer` as there exist issues wiht GTK3.
The viewer has the following features
- support of VCD files (compressed and uncompressed)
- real numbers
- showing vectors and real numbers as analog (step-wise & continuous)
- various value representations of bit vectors
- support of SCV transaction recordings in various formats
- text log files (compressed and uncompressed)
- sqlite based
- visualization of transaction relations
The plugins are structured as follows:
- com.minres.scviewer.database
the interface defining the API to access the database and the implementation for VCD
- com.minres.scviewer.database.text
an implementation of the API to read the text files generated by the SCV
sc_tr_text database
- com.minres.scviewer.database.sqlite
an implementation of the API to read the files generated by implementation in the
sc_tr_sqlite project using a SQLite based database
- com.minres.scviewer.database.test
a some JUnit tests of the 3 back ends
- com.minres.scviewer.ui
the viewer it self to diplay the transactions and associated views like the
outline of the DB and the properties of the transaction
- com.minres.scviewer.feature
the feature combining the plugins above into a somhow usable form
- scv_tr_sqlite
a C++ project containing the SQLite based SCV database implementation. A simple
example (scv_tr_recording_example.cpp) for testig purposes is provided.
To build the plugins the Eclipse SDK or PDE can be used. In both cases the Groovy
eclipse plugin (http://groovy.codehaus.org/Eclipse+Plugin or Market) has to be
installed.
TODO
====
- refactor the graphical viewer (again)
- add more tests
- additional analysis means
- move to feature based product to allow automatic updates
- improve graphics
- catch-up e3 plugin to functionality of e4 product
- add calculated traces

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry exported="true" kind="lib" path="json-20180813.jar" sourcepath="json-20180813-sources.jar"/>
<classpathentry exported="true" kind="lib" path="leveldb-0.11-SNAPSHOT-uber.jar" sourcepath="leveldb-0.11-SNAPSHOT-sources.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -0,0 +1,4 @@
/json-20180813-sources.jar
/leveldb-0.11-SNAPSHOT-sources.jar
/bin/
/target/

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.minres.scviewer.database.leveldb</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,7 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.8

View File

@ -0,0 +1,4 @@
eclipse.preferences.version=1
pluginProject.equinox=false
pluginProject.extensions=false
resolve.requirebundle=false

View File

@ -0,0 +1,5 @@
eclipse.preferences.version=1
enabled=true
path=OSGI-INF
validationErrorLevel=error
validationErrorLevel.missingImplicitUnbindMethod=error

View File

@ -0,0 +1,18 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Leveldb
Bundle-SymbolicName: com.minres.scviewer.database.leveldb
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: MINRES Technologies GmbH
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: org.osgi.framework;version="1.3.0"
Automatic-Module-Name: com.minres.scviewer.database.leveldb
Service-Component: OSGI-INF/*.xml
Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0",
org.eclipse.equinox.util;bundle-version="1.0.500",
org.eclipse.equinox.ds;bundle-version="1.4.200",
org.eclipse.osgi.services;bundle-version="3.4.0"
Bundle-ActivationPolicy: lazy
Bundle-ClassPath: leveldb-0.11-SNAPSHOT-uber.jar,
.,
json-20180813.jar

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="LevelDbLoader">
<implementation class="com.minres.scviewer.database.leveldb.LevelDBLoader"/>
<service>
<provide interface="com.minres.scviewer.database.IWaveformDbLoader"/>
</service>
</scr:component>

View File

@ -0,0 +1,7 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
OSGI-INF/,\
leveldb-0.11-SNAPSHOT-uber.jar,\
json-20180813.jar

Binary file not shown.

View File

@ -0,0 +1,13 @@
<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.leveldb</artifactId>
<version>1.0.0-SNAPSHOT</version>
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>2.0.0-SNAPSHOT</version>
<relativePath>../com.minres.scviewer.parent</relativePath>
</parent>
<packaging>eclipse-plugin</packaging>
</project>

View File

@ -0,0 +1,87 @@
package com.minres.scviewer.database.leveldb;
import static java.nio.charset.StandardCharsets.UTF_8;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map.Entry;
import org.iq80.leveldb.Options;
import org.iq80.leveldb.impl.SeekingIterator;
import org.json.JSONObject;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.IWaveformDb;
import com.minres.scviewer.database.IWaveformDbLoader;
import com.minres.scviewer.database.RelationType;
public class LevelDBLoader implements IWaveformDbLoader {
static byte[] toByteArray(String value) {
return value.getBytes(UTF_8);
}
private TxDBWrapper levelDb;
private IWaveformDb db;
private Long maxTime=null;
private List<RelationType> usedRelationsList = new ArrayList<>();
@Override
public boolean load(IWaveformDb db, File inp) throws Exception {
try {
this.db=db;
levelDb = new TxDBWrapper(new Options(), inp);
JSONObject configVal = new JSONObject(levelDb.get("__config"));
if(!configVal.isEmpty())
levelDb.setTimeResolution(configVal.getLong("resolution"));
} catch(Exception e) {
return false;
}
return true;
}
@Override
public Long getMaxTime() {
if(maxTime==null) {
SeekingIterator<String, String> it = levelDb.iterator();
it.seek("st~");
Entry<String, String> val = null;
while(it.hasNext()) {
Entry<String, String> v = it.next();
if(!v.getKey().startsWith("st~")) continue;
val=v;
}
if(val==null)
maxTime = 0L;
else {
String[] token = val.getKey().split("~");
maxTime = Long.parseLong(token[2], 16)*levelDb.getTimeResolution();
}
}
return maxTime;
}
@Override
public List<IWaveform> getAllWaves() {
List<IWaveform> streams=new ArrayList<IWaveform>();
SeekingIterator<String, String> it = levelDb.iterator();
it.seek("s~");
while(it.hasNext()) {
Entry<String, String> val = it.next();
if(!val.getKey().startsWith("s~")) break;
TxStream stream = new TxStream(levelDb, db, new JSONObject(val.getValue()));
stream.setRelationTypeList(usedRelationsList);
streams.add(stream);
}
return streams;
}
@Override
public Collection<RelationType> getAllRelationTypes() {
// return Collections.emptyList();
return usedRelationsList;
}
}

View File

@ -0,0 +1,51 @@
package com.minres.scviewer.database.leveldb;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.iq80.leveldb.shaded.guava.collect.Maps.immutableEntry;
import java.util.Map.Entry;
import org.iq80.leveldb.DBIterator;
import org.iq80.leveldb.impl.SeekingIterator;
class StringDbIterator implements SeekingIterator<String, String> {
private final DBIterator iterator;
StringDbIterator(DBIterator iterator) {
this.iterator = iterator;
}
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public void seekToFirst() {
iterator.seekToFirst();
}
@Override
public void seek(String targetKey) {
iterator.seek(targetKey.getBytes(UTF_8));
}
@Override
public Entry<String, String> peek() {
return adapt(iterator.peekNext());
}
@Override
public Entry<String, String> next() {
return adapt(iterator.next());
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
private Entry<String, String> adapt(Entry<byte[], byte[]> next) {
return immutableEntry(new String(next.getKey(), UTF_8), new String(next.getValue(), UTF_8));
}
}

View File

@ -0,0 +1,172 @@
/*******************************************************************************
* Copyright (c) 2015 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.leveldb;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.iq80.leveldb.impl.SeekingIterator;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.minres.scviewer.database.ITx;
import com.minres.scviewer.database.ITxAttribute;
import com.minres.scviewer.database.ITxEvent;
import com.minres.scviewer.database.ITxGenerator;
import com.minres.scviewer.database.ITxRelation;
import com.minres.scviewer.database.ITxStream;
public class Tx implements ITx {
private TxDBWrapper levelDb;
private TxStream trStream;
private TxGenerator trGenerator;
private long id;
private long start_time=0;
private long end_time=0;
private int concurency_index;
private boolean initialized=false;
private List<ITxAttribute> attributes;
private List<ITxRelation> incoming, outgoing;
public Tx(TxDBWrapper levelDb, TxStream trStream, TxGenerator trGenerator, long id) {
this.levelDb=levelDb;
this.trStream=trStream;
this.trGenerator=trGenerator;
this.id=id;
}
@Override
public Long getId() {
return id;
}
@Override
public ITxStream<ITxEvent> getStream() {
return trStream;
}
@Override
public ITxGenerator getGenerator() {
return trGenerator;
}
@Override
public int getConcurrencyIndex() {
if(!initialized) loadFromDb();
return concurency_index;
}
@Override
public Long getBeginTime() {
if(!initialized) loadFromDb();
return start_time;
}
@Override
public Long getEndTime() {
loadFromDb();
return end_time;
}
@Override
public List<ITxAttribute> getAttributes() {
if(attributes==null) {
loadFromDb();
}
return attributes;
}
@Override
public Collection<ITxRelation> getIncomingRelations() {
if(incoming==null) {
incoming = new ArrayList<ITxRelation>();
SeekingIterator<String, String> it = levelDb.iterator();
String key = "ri~"+String.format("%016x", id);
it.seek(key);
while(it.hasNext()) {
String val = it.next().getKey();
if(!val.startsWith(key)) break;;
String[] token = val.split("~");
long otherId = Long.parseLong(token[2], 16);
incoming.add(createRelation(otherId, token[3], false));
}
}
return incoming;
}
@Override
public Collection<ITxRelation> getOutgoingRelations() {
if(outgoing==null) {
outgoing = new ArrayList<ITxRelation>();
SeekingIterator<String, String> it = levelDb.iterator();
String key="ro~"+String.format("%016x", id);
it.seek(key);
while(it.hasNext()) {
String val = it.next().getKey();
if(!val.startsWith(key)) break;
String[] token = val.split("~");
long otherId = Long.parseLong(token[2], 16);
outgoing.add(createRelation(otherId, token[3], true));
}
}
return outgoing;
}
@Override
public int compareTo(ITx o) {
int res = this.getBeginTime().compareTo(o.getBeginTime());
if(res!=0)
return res;
else
return this.getId().compareTo(o.getId());
}
@Override
public String toString() {
return "tx#"+getId()+"["+getBeginTime()/1000000+"ns - "+getEndTime()/1000000+"ns]";
}
private void loadFromDb() throws JSONException {
JSONObject dbVal = new JSONObject(levelDb.get("x~"+ String.format("%016x", id)));
start_time=dbVal.getLong("START_TIME") * levelDb.getTimeResolution();
end_time=dbVal.getLong("END_TIME") * levelDb.getTimeResolution();
concurency_index=dbVal.getInt("conc");
attributes=new ArrayList<>();
JSONArray arr = dbVal.getJSONArray("attr");
arr.forEach(entry -> {
TxAttribute attr = new TxAttribute(this, (JSONObject) entry);
attributes.add(attr);
});
initialized=true;
}
private ITxRelation createRelation(long otherId, String name, boolean outgoing) {
try {
JSONObject otherTxVal = new JSONObject(levelDb.get("x~"+ String.format("%016x", otherId)));
if(otherTxVal.isEmpty()) return null;
JSONObject otherStreamVal = new JSONObject(levelDb.get("s~"+ String.format("%016x", otherTxVal.getLong("s"))));
if(otherStreamVal.isEmpty()) return null;
TxStream tgtStream = (TxStream) trStream.getDb().getStreamByName(otherStreamVal.getString("name"));
Tx that = (Tx) tgtStream.getTransactions().get(otherId);
return outgoing?
new TxRelation(trStream.getRelationType(name), this, that):
new TxRelation(trStream.getRelationType(name), that, this);
} catch (SecurityException | IllegalArgumentException | JSONException e) {
e.printStackTrace();
}
return null;
}
}

View File

@ -0,0 +1,56 @@
/*******************************************************************************
* Copyright (c) 2015 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.leveldb;
import org.json.JSONObject;
import com.minres.scviewer.database.AssociationType;
import com.minres.scviewer.database.DataType;
import com.minres.scviewer.database.ITxAttribute;
public class TxAttribute implements ITxAttribute{
private String name;
private DataType dataType;
private AssociationType associationType;
private Object value;
public TxAttribute(Tx trTransaction, JSONObject attribute) {
this.name=attribute.getString("name");
this.dataType=DataType.values()[attribute.getInt("type")];
this.associationType=AssociationType.values()[attribute.getInt("assoc")];
this.value=attribute.get("value");
}
@Override
public String getName() {
return name;
}
@Override
public DataType getDataType() {
return dataType;
}
@Override
public AssociationType getType() {
return associationType;
}
@Override
public Object getValue() {
return value;
}
}

View File

@ -0,0 +1,90 @@
package com.minres.scviewer.database.leveldb;
import static java.nio.charset.StandardCharsets.UTF_8;
import java.io.File;
import java.io.IOException;
import org.iq80.leveldb.Options;
import org.iq80.leveldb.Range;
import org.iq80.leveldb.ReadOptions;
import org.iq80.leveldb.Snapshot;
import org.iq80.leveldb.impl.DbImpl;
import org.iq80.leveldb.impl.SeekingIterator;
class TxDBWrapper {
private final Options options;
private final ReadOptions ro = new ReadOptions();
private final File databaseDir;
private DbImpl db;
private long timeResolution=1L;;
TxDBWrapper(Options options, File databaseDir) throws IOException {
this.options = options.verifyChecksums(true).createIfMissing(false).errorIfExists(false).cacheSize(64*1024*1024);
this.databaseDir = databaseDir;
this.db = new DbImpl(options, databaseDir);
ro.snapshot(db.getSnapshot());
}
public String get(String key) {
byte[] slice = db.get(LevelDBLoader.toByteArray(key));
if (slice == null) {
return null;
}
return new String(slice, UTF_8);
}
public String get(String key, Snapshot snapshot) {
byte[] slice = db.get(LevelDBLoader.toByteArray(key), ro);
return slice == null? null : new String(slice, UTF_8);
}
public void put(String key, String value) {
db.put(LevelDBLoader.toByteArray(key), LevelDBLoader.toByteArray(value));
}
public void delete(String key) {
db.delete(LevelDBLoader.toByteArray(key));
}
public SeekingIterator<String, String> iterator() {
return new StringDbIterator(db.iterator());
}
public Snapshot getSnapshot() {
return db.getSnapshot();
}
public void close() {
try {
ro.snapshot().close();
db.close();
} catch (IOException e) {} // ignore any error
}
public long size(String start, String limit) {
return db.getApproximateSizes(new Range(LevelDBLoader.toByteArray(start), LevelDBLoader.toByteArray(limit)));
}
public long getMaxNextLevelOverlappingBytes() {
return db.getMaxNextLevelOverlappingBytes();
}
public void reopen() throws IOException {
reopen(options);
}
public void reopen(Options options) throws IOException {
this.close();
db = new DbImpl(options.verifyChecksums(true).createIfMissing(false).errorIfExists(false), databaseDir);
ro.snapshot(db.getSnapshot());
}
public long getTimeResolution() {
return timeResolution;
}
public void setTimeResolution(long resolution) {
this.timeResolution = resolution;
}
}

View File

@ -8,39 +8,50 @@
* Contributors:
* MINRES Technologies GmbH - initial API and implementation
*******************************************************************************/
package com.minres.scviewer.database;
package com.minres.scviewer.database.leveldb;
public class SignalChange implements IWaveformEvent {
Long time;
public SignalChange() {
time=0L;
}
import com.minres.scviewer.database.ITx;
import com.minres.scviewer.database.ITxEvent;
import com.minres.scviewer.database.IWaveformEvent;
public SignalChange(Long time) {
public class TxEvent implements ITxEvent {
private final Type type;
private ITx tx;
public TxEvent(Type type, ITx tx) {
super();
this.time = time;
}
@Override
public int compareTo(IWaveformEvent o) {
return time.compareTo(o.getTime());
this.type = type;
this.tx = tx;
}
@Override
public Long getTime() {
return time;
}
public void setTime(Long time) {
this.time = time;
return type==Type.BEGIN?tx.getBeginTime():tx.getEndTime();
}
@Override
public IWaveformEvent duplicate() throws CloneNotSupportedException {
return (IWaveformEvent) this.clone();
return new TxEvent(type, tx);
}
@Override
public int compareTo(IWaveformEvent o) {
return getTime().compareTo(o.getTime());
}
@Override
public ITx getTransaction() {
return tx;
}
@Override
public Type getType() {
return type;
}
@Override
public String toString() {
return type.toString()+"@"+getTime()+" of tx #"+tx.getId();
}
}

View File

@ -0,0 +1,56 @@
/*******************************************************************************
* Copyright (c) 2015 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.leveldb;
import java.util.List;
import org.json.JSONObject;
import com.minres.scviewer.database.ITx;
import com.minres.scviewer.database.ITxEvent;
import com.minres.scviewer.database.ITxGenerator;
import com.minres.scviewer.database.ITxStream;
public class TxGenerator implements ITxGenerator {
private ITxStream<ITxEvent> stream;
private long id;
private String name;
public TxGenerator(ITxStream<ITxEvent> stream, JSONObject object) {
this.stream=stream;
this.id=object.getLong("id");
this.name=object.getString("name");
}
@Override
public Long getId() {
return id;
}
@Override
public ITxStream<ITxEvent> getStream() {
return stream;
}
@Override
public String getName() {
return name;
}
@Override
public List<ITx> getTransactions() {
return null;
}
}

View File

@ -0,0 +1,43 @@
/*******************************************************************************
* Copyright (c) 2015 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.leveldb;
import com.minres.scviewer.database.ITxRelation;
import com.minres.scviewer.database.ITx;
import com.minres.scviewer.database.RelationType;
public class TxRelation implements ITxRelation {
RelationType relationType;
Tx source, target;
public TxRelation(RelationType relationType, Tx source, Tx target) {
this.source = source;
this.target = target;
this.relationType = relationType;
}
@Override
public RelationType getRelationType() {
return relationType;
}
@Override
public ITx getSource() {
return source;
}
@Override
public ITx getTarget() {
return target;
}
}

View File

@ -0,0 +1,178 @@
/*******************************************************************************
* Copyright (c) 2015 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.leveldb;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.iq80.leveldb.impl.SeekingIterator;
import org.json.JSONObject;
import java.util.NavigableMap;
import java.util.TreeMap;
import java.util.Vector;
import com.minres.scviewer.database.HierNode;
import com.minres.scviewer.database.ITx;
import com.minres.scviewer.database.ITxEvent;
import com.minres.scviewer.database.ITxGenerator;
import com.minres.scviewer.database.ITxStream;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.IWaveformDb;
import com.minres.scviewer.database.RelationType;
public class TxStream extends HierNode implements ITxStream<ITxEvent> {
private TxDBWrapper levelDb;
private String fullName;
private String kind;
private IWaveformDb db;
private long id;
private TreeMap<Long, TxGenerator> generators;
private TreeMap<Long, ITx> transactions;
private Integer maxConcurrency;
private TreeMap<Long, List<ITxEvent>> events;
private List<RelationType> usedRelationsList;
public TxStream(TxDBWrapper database, IWaveformDb waveformDb, JSONObject object) {
super(object.get("name").toString());
this.levelDb=database;
this.db=waveformDb;
this.fullName=object.getString("name");
this.kind=object.getString("kind");
this.id = object.getLong("id");
}
@Override
public IWaveformDb getDb() {
return db;
}
@Override
public String getFullName() {
return fullName;
}
@Override
public Long getId() {
return id;
}
@Override
public String getKind() {
return kind;
}
@Override
public List<ITxGenerator> getGenerators() {
if(generators==null){
generators=new TreeMap<Long, TxGenerator>();
SeekingIterator<String, String> it = levelDb.iterator();
String key="sg~"+String.format("%016x", id);
it.seek(key);
while(it.hasNext()) {
Entry<String, String> val = it.next();
if(!val.getKey().startsWith(key)) break;
JSONObject jVal = new JSONObject(val.getValue());
generators.put(jVal.getLong("id"), new TxGenerator(this, jVal));
}
}
return new ArrayList<ITxGenerator>(generators.values());
}
@Override
public int getMaxConcurrency() {
if(maxConcurrency==null){
getTransactions();
}
return maxConcurrency;
}
@Override
public NavigableMap<Long, List<ITxEvent>> getEvents(){
if(events==null){
events=new TreeMap<Long, List<ITxEvent>>();
for(Entry<Long, ITx> entry:getTransactions().entrySet()){
ITx tx = entry.getValue();
putEvent(new TxEvent(TxEvent.Type.BEGIN, tx));
putEvent(new TxEvent(TxEvent.Type.END, tx));
}
}
return events;
}
private void putEvent(TxEvent ev){
Long time = ev.getTime();
if(!events.containsKey(time)){
Vector<ITxEvent> vector=new Vector<ITxEvent>();
vector.add(ev);
events.put(time, vector);
} else {
events.get(time).add(ev);
}
}
protected Map<Long, ITx> getTransactions() {
if(transactions==null){
if(generators==null) getGenerators();
transactions = new TreeMap<Long, ITx>();
maxConcurrency=0;
SeekingIterator<String, String> it = levelDb.iterator();
String key = "sgx~"+String.format("%016x", id);
it.seek(key);
while(it.hasNext()) {
Entry<String, String> val = it.next();
if(!val.getKey().startsWith(key)) break;
String[] token = val.getKey().split("~");
long gid = Long.parseLong(token[2], 16); // gen id
long id = Long.parseLong(token[3], 16); // tx id
ITx tx = new Tx(levelDb, this, generators.get(gid), id);
transactions.put(id, tx);
maxConcurrency= Math.max(maxConcurrency, tx.getConcurrencyIndex());
}
maxConcurrency++;
}
return transactions;
}
@Override
public Collection<ITxEvent> getWaveformEventsAtTime(Long time) {
return getEvents().get(time);
}
public void setRelationTypeList(List<RelationType> usedRelationsList){
this.usedRelationsList=usedRelationsList;
}
public RelationType getRelationType(String name) {
RelationType relType=RelationType.create(name);
if(!usedRelationsList.contains(relType)) usedRelationsList.add(relType);
return relType;
}
@Override
public Boolean equals(IWaveform other) {
return(other instanceof TxStream && this.getId()==other.getId());
}
}

View File

@ -1,6 +1,6 @@
<?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-1.7"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry exported="true" kind="lib" path="sqlite-jdbc-3.8.7.jar"/>

View File

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

View File

@ -1,7 +1,7 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.7
org.eclipse.jdt.core.compiler.source=1.8

View File

@ -4,14 +4,12 @@ Bundle-Name: SQLite transaction database
Bundle-SymbolicName: com.minres.scviewer.database.sqlite
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: MINRES Technologies GmbH
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0",
org.eclipse.equinox.util;bundle-version="1.0.500",
org.eclipse.equinox.ds;bundle-version="1.4.200",
org.eclipse.osgi.services;bundle-version="3.4.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
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
Bundle-ActivationPolicy: lazy
Embed-Dependency: sqlite-jdbc
Embedded-Artifacts: sqlite-jdbc-3.8.7.jar;g="org.xerial";
a="sqlite-jdbc";v="3.8.7"
Automatic-Module-Name: com.minres.scviewer.database.sqlite

View File

@ -4,7 +4,7 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>2.0.0-SNAPSHOT</version>
<relativePath>../com.minres.scviewer.parent</relativePath>
</parent>
<packaging>eclipse-plugin</packaging>
@ -15,4 +15,5 @@
<version>3.8.7</version>
</dependency>
</dependencies>
</project>
<version>1.0.0-SNAPSHOT</version>
</project>

View File

@ -13,6 +13,7 @@ package com.minres.scviewer.database.sqlite;
import java.beans.IntrospectionException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
import java.util.ArrayList;
@ -22,7 +23,6 @@ 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.IWaveformEvent;
import com.minres.scviewer.database.RelationType;
import com.minres.scviewer.database.sqlite.db.IDatabase;
import com.minres.scviewer.database.sqlite.db.SQLiteDatabase;
@ -60,9 +60,9 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
}
@Override
public List<IWaveform<? extends IWaveformEvent>> getAllWaves() {
public List<IWaveform> getAllWaves() {
SQLiteDatabaseSelectHandler<ScvStream> handler = new SQLiteDatabaseSelectHandler<ScvStream>(ScvStream.class, database);
List<IWaveform<? extends IWaveformEvent>> streams=new ArrayList<IWaveform<? extends IWaveformEvent>>();
List<IWaveform> streams=new ArrayList<IWaveform>();
try {
for(ScvStream scvStream:handler.selectObjects()){
TxStream stream = new TxStream(database, db, scvStream);
@ -81,14 +81,17 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
@Override
public boolean load(IWaveformDb db, File file) throws Exception {
this.db=db;
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[x.length];
int read = fis.read(buffer, 0, x.length);
fis.close();
if (read == x.length)
for (int i = 0; i < x.length; i++)
if (buffer[i] != x[i]) return false;
try {
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[x.length];
int read = fis.read(buffer, 0, x.length);
fis.close();
if (read == x.length)
for (int i = 0; i < x.length; i++)
if (buffer[i] != x[i]) return false;
} catch(FileNotFoundException e) {
return false;
}
database=new SQLiteDatabase(file.getAbsolutePath());
database.setData("TIMERESOLUTION", 1L);
SQLiteDatabaseSelectHandler<ScvSimProps> handler = new SQLiteDatabaseSelectHandler<ScvSimProps>(ScvSimProps.class, database);

View File

@ -29,7 +29,6 @@ import com.minres.scviewer.database.ITxGenerator;
import com.minres.scviewer.database.ITxStream;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.IWaveformDb;
import com.minres.scviewer.database.IWaveformEvent;
import com.minres.scviewer.database.RelationType;
import com.minres.scviewer.database.sqlite.db.IDatabase;
import com.minres.scviewer.database.sqlite.db.SQLiteDatabaseSelectHandler;
@ -117,6 +116,7 @@ public class TxStream extends HierNode implements ITxStream<ITxEvent> {
sb.append(scvStream.getId());
resultSet = statement.executeQuery(sb.toString());
while (resultSet.next()) {
if(maxConcurrency==null) maxConcurrency=0;
Object value = resultSet.getObject("concurrencyLevel");
if(value!=null)
maxConcurrency=(Integer) value;
@ -192,7 +192,7 @@ public class TxStream extends HierNode implements ITxStream<ITxEvent> {
}
@Override
public Boolean equals(IWaveform<? extends IWaveformEvent> other) {
public Boolean equals(IWaveform other) {
return(other instanceof TxStream && this.getId()==other.getId());
}

View File

@ -1,7 +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-1.7"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src/"/>
<classpathentry kind="src" path="src/">
<attributes>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@ -1,3 +0,0 @@
eclipse.preferences.version=1
encoding//src/com/minres/scviewer/database/test/DatabaseServicesTest.java=UTF-8
encoding/<project>=UTF-8

View File

@ -1,8 +1,8 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.7
org.eclipse.jdt.core.compiler.source=1.8

View File

@ -11,32 +11,32 @@
<booleanAttribute key="clearws" value="true"/>
<booleanAttribute key="clearwslog" value="false"/>
<stringAttribute key="configLocation" value="${workspace_loc}/.metadata/.plugins/org.eclipse.pde.core/pde-junit"/>
<booleanAttribute key="default" value="false"/>
<stringAttribute key="deselected_workspace_plugins" value="com.minres.scviewer.database.swt,com.minres.scviewer.e4.application,com.minres.scviewer.ui"/>
<booleanAttribute key="default" value="true"/>
<stringAttribute key="deselected_workspace_plugins" value="com.minres.scviewer.e4.application,com.minres.scviewer.ui"/>
<booleanAttribute key="includeOptional" value="true"/>
<stringAttribute key="location" value="${workspace_loc}/../junit-workspace"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/com.minres.scviewer.database.test/src/com/minres/scviewer/database/test/DatabaseServicesTest.java"/>
<listEntry value="/com.minres.scviewer.database.test"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="1"/>
<listEntry value="4"/>
</listAttribute>
<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value=""/>
<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value="=com.minres.scviewer.database.test"/>
<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/>
<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-1.7"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.minres.scviewer.database.test.DatabaseServicesTest"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value=""/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.minres.scviewer.database.test"/>
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms40m -Xmx512m -Xdock:icon=../Resources/Eclipse.icns -XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms40m -Xmx512m"/>
<stringAttribute key="pde.version" value="3.3"/>
<stringAttribute key="product" value="com.minres.scviewer.e4.product"/>
<booleanAttribute key="run_in_ui_thread" value="true"/>
<stringAttribute key="selected_target_plugins" value="com.google.guava*10.0.1.v201203051515@default:default,com.google.guava*15.0.0.v201403281430@default:default,com.ibm.icu@default:default,javax.annotation@default:default,javax.inject@default:default,javax.servlet*3.0.0.v201112011016@default:default,javax.servlet*3.1.0.v201410161800@default:default,javax.xml@default:default,org.apache.ant@default:default,org.apache.batik.css@default:default,org.apache.batik.util.gui@default:default,org.apache.batik.util@default:default,org.apache.commons.jxpath@default:default,org.apache.commons.logging@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.gogo.shell@default:default,org.codehaus.groovy*2.4.3.xx-201508121448-e45@default:default,org.eclipse.ant.core@default:default,org.eclipse.compare.core@default:default,org.eclipse.core.commands@default:default,org.eclipse.core.contenttype@default:default,org.eclipse.core.databinding.observable@default:default,org.eclipse.core.databinding.property@default:default,org.eclipse.core.databinding@default:default,org.eclipse.core.expressions@default:default,org.eclipse.core.filesystem.java7@default:false,org.eclipse.core.filesystem.macosx@default:false,org.eclipse.core.filesystem@default:default,org.eclipse.core.jobs@default:default,org.eclipse.core.resources@default:default,org.eclipse.core.runtime.compatibility.registry@default:false,org.eclipse.core.runtime@default:true,org.eclipse.core.variables@default:default,org.eclipse.e4.core.commands@default:default,org.eclipse.e4.core.contexts@default:default,org.eclipse.e4.core.di.annotations@default:default,org.eclipse.e4.core.di.extensions@default:default,org.eclipse.e4.core.di@default:default,org.eclipse.e4.core.services@default:default,org.eclipse.e4.emf.xpath@default:default,org.eclipse.e4.ui.bindings@default:default,org.eclipse.e4.ui.css.core@default:default,org.eclipse.e4.ui.css.swt.theme@default:default,org.eclipse.e4.ui.css.swt@default:default,org.eclipse.e4.ui.di@default:default,org.eclipse.e4.ui.model.workbench@default:default,org.eclipse.e4.ui.services@default:default,org.eclipse.e4.ui.widgets@default:default,org.eclipse.e4.ui.workbench.addons.swt@default:default,org.eclipse.e4.ui.workbench.renderers.swt.cocoa@default:false,org.eclipse.e4.ui.workbench.renderers.swt@default:default,org.eclipse.e4.ui.workbench.swt@default:default,org.eclipse.e4.ui.workbench3@default:default,org.eclipse.e4.ui.workbench@default:default,org.eclipse.emf.common@default:default,org.eclipse.emf.ecore.change@default:default,org.eclipse.emf.ecore.xmi@default:default,org.eclipse.emf.ecore@default:default,org.eclipse.equinox.app@default:default,org.eclipse.equinox.bidi@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.console@default:default,org.eclipse.equinox.ds@1:true,org.eclipse.equinox.event@default:default,org.eclipse.equinox.preferences@default:default,org.eclipse.equinox.registry@default:default,org.eclipse.equinox.util@default:default,org.eclipse.help@default:default,org.eclipse.jface.databinding@default:default,org.eclipse.jface@default:default,org.eclipse.osgi.compatibility.state@default:false,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.eclipse.swt.cocoa.macosx.x86_64@default:false,org.eclipse.swt@default:default,org.eclipse.team.core@default:default,org.eclipse.ui.cocoa@default:false,org.eclipse.ui.trace@default:default,org.eclipse.ui.workbench@default:default,org.eclipse.ui@default:default,org.hamcrest.core@default:default,org.junit@default:default,org.mozilla.javascript@default:default,org.w3c.css.sac@default:default,org.w3c.dom.events@default:default,org.w3c.dom.smil@default:default,org.w3c.dom.svg@default:default"/>
<stringAttribute key="selected_workspace_plugins" value="com.minres.scviewer.database.sqlite@default:true,com.minres.scviewer.database.test@default:default,com.minres.scviewer.database.text@default:true,com.minres.scviewer.database.vcd@default:default,com.minres.scviewer.database@default:true"/>
<stringAttribute key="selected_target_plugins" value="com.google.guava@default:default,javax.annotation@default:default,javax.inject@default:default,javax.servlet@default:default,org.apache.ant@default:default,org.apache.commons.jxpath@default:default,org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.codehaus.groovy@default:default,org.eclipse.ant.core@default:default,org.eclipse.core.commands@default:default,org.eclipse.core.contenttype@default:default,org.eclipse.core.expressions@default:default,org.eclipse.core.filesystem.macosx@default:false,org.eclipse.core.filesystem@default:default,org.eclipse.core.jobs@default:default,org.eclipse.core.resources@default:default,org.eclipse.core.runtime@default:true,org.eclipse.core.variables@default:default,org.eclipse.e4.core.contexts@default:default,org.eclipse.e4.core.di.annotations@default:default,org.eclipse.e4.core.di.extensions@default:default,org.eclipse.e4.core.di@default:default,org.eclipse.e4.core.services@default:default,org.eclipse.e4.emf.xpath@default:default,org.eclipse.e4.ui.di@default:default,org.eclipse.e4.ui.model.workbench@default:default,org.eclipse.e4.ui.services@default:default,org.eclipse.emf.common@default:default,org.eclipse.emf.ecore@default:default,org.eclipse.equinox.app@default:default,org.eclipse.equinox.bidi@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.ds@1:true,org.eclipse.equinox.preferences@default:default,org.eclipse.equinox.registry@default:default,org.eclipse.equinox.util@default:default,org.eclipse.jface@default:default,org.eclipse.osgi.compatibility.state@default:false,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.eclipse.swt.cocoa.macosx.x86_64@default:false,org.eclipse.swt@default:default,org.hamcrest.core@default:default,org.junit@default:default"/>
<stringAttribute key="selected_workspace_plugins" value="com.minres.scviewer.database.sqlite@default:true,com.minres.scviewer.database.test@default:default,com.minres.scviewer.database.text@default:true,com.minres.scviewer.database.ui.swt@default:default,com.minres.scviewer.database.ui@default:default,com.minres.scviewer.database.vcd@default:default,com.minres.scviewer.database@default:true,com.opcoach.e4.preferences@default:default"/>
<booleanAttribute key="show_selected_only" value="false"/>
<booleanAttribute key="tracing" value="false"/>
<booleanAttribute key="useCustomFeatures" value="false"/>

View File

@ -4,7 +4,7 @@ Bundle-Name: SCViewer database tests
Bundle-SymbolicName: com.minres.scviewer.database.test
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: MINRES Technologies GnbH
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Require-Bundle: org.junit,
com.minres.scviewer.database,
com.minres.scviewer.database.sqlite;bundle-version="1.0.0",
@ -12,3 +12,4 @@ Require-Bundle: org.junit,
com.minres.scviewer.database.vcd;bundle-version="1.0.0"
Bundle-ActivationPolicy: lazy
Service-Component: OSGI-INF/component.xml
Automatic-Module-Name: com.minres.scviewer.database.test

View File

@ -0,0 +1,2 @@
/.scviewer.*
/.my_db.txlog*

View File

@ -0,0 +1,238 @@
scv_tr_stream (ID 1, name "tr.pipelined_stream", kind "transactor")
scv_tr_stream (ID 2, name "tr.addr_stream", kind "transactor")
scv_tr_stream (ID 3, name "tr.data_stream", kind "transactor")
scv_tr_generator (ID 4, name "read", scv_tr_stream 1,
begin_attribute (ID 0, name "addr", type "UNSIGNED")
end_attribute (ID 1, name "data", type "UNSIGNED")
)
scv_tr_generator (ID 5, name "write", scv_tr_stream 1,
begin_attribute (ID 0, name "addr", type "UNSIGNED")
end_attribute (ID 1, name "data", type "UNSIGNED")
)
scv_tr_generator (ID 6, name "addr", scv_tr_stream 2,
begin_attribute (ID 0, name "addr", type "UNSIGNED")
)
scv_tr_generator (ID 7, name "rdata", scv_tr_stream 3,
end_attribute (ID 0, name "data", type "UNSIGNED")
)
scv_tr_generator (ID 8, name "wdata", scv_tr_stream 3,
begin_attribute (ID 0, name "data", type "UNSIGNED")
)
tx_begin 1 4 0 s
a 0
tx_record_attribute 1 "data_size" UNSIGNED = 24
tx_begin 2 6 0 s
a 0
tx_relation "addr_phase" 2 1
tx_end 2 6 180 ns
tx_begin 3 7 180 ns
tx_relation "data_phase" 3 1
tx_begin 4 4 180 ns
a 0
tx_record_attribute 4 "data_size" UNSIGNED = 24
tx_begin 5 6 180 ns
a 0
tx_relation "addr_phase" 5 4
tx_end 5 6 300 ns
tx_end 3 7 420 ns
a 0
tx_end 1 4 420 ns
a 0
tx_begin 6 4 420 ns
a 1
tx_record_attribute 6 "data_size" UNSIGNED = 24
tx_begin 7 6 420 ns
a 1
tx_relation "addr_phase" 7 6
tx_begin 8 7 420 ns
tx_relation "data_phase" 8 4
tx_end 7 6 480 ns
tx_end 8 7 620 ns
a 0
tx_end 4 4 620 ns
a 0
tx_begin 9 4 620 ns
a 1
tx_record_attribute 9 "data_size" UNSIGNED = 24
tx_begin 10 6 620 ns
a 1
tx_relation "addr_phase" 10 9
tx_begin 11 7 620 ns
tx_relation "data_phase" 11 6
tx_end 11 7 700 ns
a 1
tx_end 6 4 700 ns
a 1
tx_end 10 6 760 ns
tx_begin 12 7 760 ns
tx_relation "data_phase" 12 9
tx_begin 13 4 760 ns
a 2
tx_record_attribute 13 "data_size" UNSIGNED = 24
tx_begin 14 6 760 ns
a 2
tx_relation "addr_phase" 14 13
tx_end 14 6 880 ns
tx_end 12 7 980 ns
a 1
tx_end 9 4 980 ns
a 1
tx_begin 15 4 980 ns
a 2
tx_record_attribute 15 "data_size" UNSIGNED = 24
tx_begin 16 6 980 ns
a 2
tx_relation "addr_phase" 16 15
tx_begin 17 7 980 ns
tx_relation "data_phase" 17 13
tx_end 16 6 1040 ns
tx_end 17 7 1200 ns
a 2
tx_end 13 4 1200 ns
a 2
tx_begin 18 4 1200 ns
a 120
tx_record_attribute 18 "data_size" UNSIGNED = 24
tx_begin 19 6 1200 ns
a 120
tx_relation "addr_phase" 19 18
tx_begin 20 7 1200 ns
tx_relation "data_phase" 20 15
tx_end 19 6 1300 ns
tx_end 20 7 1340 ns
a 2
tx_end 15 4 1340 ns
a 2
tx_begin 21 4 1340 ns
a 11
tx_record_attribute 21 "data_size" UNSIGNED = 24
tx_begin 22 6 1340 ns
a 11
tx_relation "addr_phase" 22 21
tx_begin 23 7 1340 ns
tx_relation "data_phase" 23 18
tx_end 23 7 1420 ns
a 120
tx_end 18 4 1420 ns
a 120
tx_end 22 6 1540 ns
tx_begin 24 7 1540 ns
tx_relation "data_phase" 24 21
tx_begin 25 4 1540 ns
a 147
tx_record_attribute 25 "data_size" UNSIGNED = 24
tx_begin 26 6 1540 ns
a 147
tx_relation "addr_phase" 26 25
tx_end 24 7 1660 ns
a 11
tx_end 21 4 1660 ns
a 11
tx_end 26 6 1740 ns
tx_begin 27 7 1740 ns
tx_relation "data_phase" 27 25
tx_begin 28 4 1740 ns
a 99
tx_record_attribute 28 "data_size" UNSIGNED = 24
tx_begin 29 6 1740 ns
a 99
tx_relation "addr_phase" 29 28
tx_end 29 6 1800 ns
tx_end 27 7 1980 ns
a 147
tx_end 25 4 1980 ns
a 147
tx_begin 30 4 1980 ns
a 55
tx_record_attribute 30 "data_size" UNSIGNED = 24
tx_begin 31 6 1980 ns
a 55
tx_relation "addr_phase" 31 30
tx_begin 32 7 1980 ns
tx_relation "data_phase" 32 28
tx_end 32 7 2060 ns
a 99
tx_end 28 4 2060 ns
a 99
tx_end 31 6 2100 ns
tx_begin 33 7 2100 ns
tx_relation "data_phase" 33 30
tx_begin 34 4 2100 ns
a 126
tx_record_attribute 34 "data_size" UNSIGNED = 24
tx_begin 35 6 2100 ns
a 126
tx_relation "addr_phase" 35 34
tx_end 33 7 2340 ns
a 55
tx_end 30 4 2340 ns
a 55
tx_end 35 6 2340 ns
tx_begin 36 7 2340 ns
tx_relation "data_phase" 36 34
tx_begin 37 5 2340 ns
a 204
tx_record_attribute 37 "data_size" UNSIGNED = 24
tx_begin 38 6 2340 ns
a 204
tx_relation "addr_phase" 38 37
tx_end 38 6 2400 ns
tx_end 36 7 2540 ns
a 126
tx_end 34 4 2540 ns
a 126
tx_begin 39 5 2540 ns
a 242
tx_record_attribute 39 "data_size" UNSIGNED = 24
tx_begin 40 6 2540 ns
a 242
tx_relation "addr_phase" 40 39
tx_begin 41 8 2540 ns
a 211
tx_relation "data_phase" 41 37
tx_end 41 8 2640 ns
tx_end 37 5 2640 ns
a 211
tx_end 40 6 2780 ns
tx_begin 42 8 2780 ns
a 58
tx_relation "data_phase" 42 39
tx_begin 43 5 2780 ns
a 135
tx_record_attribute 43 "data_size" UNSIGNED = 24
tx_begin 44 6 2780 ns
a 135
tx_relation "addr_phase" 44 43
tx_end 44 6 2960 ns
tx_end 42 8 3 us
tx_end 39 5 3 us
a 58
tx_begin 45 5 3 us
a 26
tx_record_attribute 45 "data_size" UNSIGNED = 24
tx_begin 46 6 3 us
a 26
tx_relation "addr_phase" 46 45
tx_begin 47 8 3 us
a 31
tx_relation "data_phase" 47 43
tx_end 47 8 3140 ns
tx_end 43 5 3140 ns
a 31
tx_end 46 6 3200 ns
tx_begin 48 8 3200 ns
a 37
tx_relation "data_phase" 48 45
tx_begin 49 5 3200 ns
a 176
tx_record_attribute 49 "data_size" UNSIGNED = 24
tx_begin 50 6 3200 ns
a 176
tx_relation "addr_phase" 50 49
tx_end 50 6 3300 ns
tx_end 48 8 3380 ns
tx_end 45 5 3380 ns
a 37
tx_begin 51 5 3380 ns
a 58
tx_record_attribute 51 "data_

View File

@ -0,0 +1 @@
MANIFEST-000045

View File

@ -0,0 +1 @@
2018/11/03-15:38:59.715484 139851522529088Delete type=3 #1

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>2.0.0-SNAPSHOT</version>
<relativePath>../com.minres.scviewer.parent</relativePath>
</parent>
<packaging>eclipse-test-plugin</packaging>
@ -14,6 +14,7 @@
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-surefire-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<!-- <bundleStartLevel /> -->
<dependencies>
@ -26,6 +27,5 @@
</plugin>
</plugins>
</build>
<groupId>com.minres.scviewer</groupId>
<version>1.0.0-SNAPSHOT</version>
</project>

View File

@ -15,11 +15,23 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.util.List;
import java.util.Map.Entry;
import java.util.NavigableMap;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.minres.scviewer.database.AssociationType;
import com.minres.scviewer.database.DataType;
import com.minres.scviewer.database.ISignal;
import com.minres.scviewer.database.ITx;
import com.minres.scviewer.database.ITxAttribute;
import com.minres.scviewer.database.ITxEvent;
import com.minres.scviewer.database.ITxEvent.Type;
import com.minres.scviewer.database.ITxStream;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.IWaveformDb;
import com.minres.scviewer.database.IWaveformDbFactory;
@ -43,13 +55,6 @@ public class DatabaseServicesTest {
@Before
public void setUp() throws Exception {
waveformDb=waveformDbFactory.getDatabase();
// Wait for OSGi dependencies
// for (int i = 0; i < 10; i++) {
// if (waveformDb.size() == 3) // Dependencies fulfilled
// return;
// Thread.sleep(1000);
// }
// assertEquals("OSGi dependencies unfulfilled", 3, WaveformDb.getLoaders().size());
}
@After
@ -62,13 +67,22 @@ public class DatabaseServicesTest {
assertTrue(f.exists());
waveformDb.load(f);
assertNotNull(waveformDb);
assertEquals(14, waveformDb.getAllWaves().size());
List<IWaveform> waves= waveformDb.getAllWaves();
assertEquals(14, waves.size());
assertEquals(2, waveformDb.getChildNodes().size());
IWaveform bus_data_wave = waves.get(0);
ISignal<?> bus_data_sig = (ISignal<?>) bus_data_wave;
Entry<Long, ?> bus_data_entry = bus_data_sig.getEvents().floorEntry(1400000000L);
assertTrue("01111000".equals(bus_data_entry.getValue().toString()));
IWaveform rw_wave = waves.get(2);
ISignal<?> rw_sig = (ISignal<?>) rw_wave;
Entry<Long, ?> rw_entry = rw_sig.getEvents().floorEntry(2360000000L);
assertTrue("1".equals(rw_entry.getValue().toString()));
}
@Test
public void testTxSQLite() throws Exception {
File f = new File("inputs/my_db.txdb").getAbsoluteFile();
File f = new File("inputs/my_sqldb.txdb").getAbsoluteFile();
assertTrue(f.exists());
waveformDb.load(f);
assertNotNull(waveformDb);
@ -86,5 +100,58 @@ public class DatabaseServicesTest {
assertEquals(1, waveformDb.getChildNodes().size());
}
@Test
public void testTxTextTruncated() throws Exception {
File f = new File("inputs/my_db_truncated.txlog").getAbsoluteFile();
assertTrue(f.exists());
waveformDb.load(f);
assertNotNull(waveformDb);
assertEquals(3, waveformDb.getAllWaves().size());
assertEquals(1, waveformDb.getChildNodes().size());
}
//@Test
public void testTxLDb() throws Exception {
File f = new File("inputs/my_ldb.txldb").getAbsoluteFile();
assertTrue(f.exists());
waveformDb.load(f);
assertNotNull(waveformDb);
assertEquals(1, waveformDb.getChildNodes().size());
List<IWaveform> waves = waveformDb.getAllWaves();
assertEquals(3, waves.size());
IWaveform wave = waves.get(0);
assertTrue(wave instanceof ITxStream<?>);
ITxStream<?> stream = (ITxStream<?>) wave;
assertEquals(2, stream.getGenerators().size());
NavigableMap<Long, List<ITxEvent>> eventsList = stream.getEvents();
assertEquals(27, eventsList.size());
Entry<Long, List<ITxEvent>> eventEntry = eventsList.firstEntry();
assertEquals(100000000L, (long) eventEntry.getKey());
List<ITxEvent> events = eventEntry.getValue();
assertEquals(1, events.size());
ITxEvent event = events.get(0);
assertEquals(Type.BEGIN, event.getType());
ITx tx = event.getTransaction();
assertEquals(3L, (long) tx.getId());
List<ITxAttribute> attrs = tx.getAttributes();
assertEquals(1, attrs.size());
ITxAttribute attr = attrs.get(0);
assertEquals("data", attr.getName());
assertEquals(DataType.UNSIGNED, attr.getDataType());
assertEquals(AssociationType.END, attr.getType());
assertTrue(attr.getValue() instanceof Integer);
assertEquals(0, (int) attr.getValue());
}
@Test
public void testHierarchicalVCD() throws Exception {
File f = new File("inputs/simple_system.vcd").getAbsoluteFile();
assertTrue(f.exists());
waveformDb.load(f);
assertNotNull(waveformDb);
assertEquals(779, waveformDb.getAllWaves().size());
assertEquals(1, waveformDb.getChildNodes().size());
}
}

View File

@ -1,7 +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-1.7"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry exported="true" kind="lib" path="lib/mapdb-3.0.7.jar" sourcepath="lib/mapdb-3.0.7-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:platform:/resource/com.minres.scviewer.database.text/lib/mapdb-3.0.7-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="src/"/>
<classpathentry exported="true" kind="lib" path="lib/eclipse-collections-9.2.0.jar"/>
<classpathentry exported="true" kind="lib" path="lib/eclipse-collections-api-9.2.0.jar"/>
<classpathentry exported="true" kind="lib" path="lib/eclipse-collections-forkjoin-9.2.0.jar"/>
<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="output" path="target/classes"/>
</classpath>

View File

@ -1,8 +1,9 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.7
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=1.8

View File

@ -1,2 +1,2 @@
eclipse.preferences.version=1
groovy.compiler.level=23
groovy.compiler.level=25

View File

@ -2,16 +2,24 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Textual transaction database
Bundle-SymbolicName: com.minres.scviewer.database.text
Bundle-Version: 1.0.0.qualifier
Bundle-Version: 2.0.1.qualifier
Bundle-Vendor: MINRES Technologies GmbH
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Import-Package: com.minres.scviewer.database,
org.osgi.framework;version="1.3.0"
Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0",
org.codehaus.groovy;bundle-version="1.8.6",
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: org.osgi.framework;version="1.3.0"
Require-Bundle: com.minres.scviewer.database,
org.codehaus.groovy;bundle-version="2.5.8",
org.eclipse.equinox.util;bundle-version="1.0.500",
org.eclipse.equinox.ds;bundle-version="1.4.200",
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
Automatic-Module-Name: com.minres.scviewer.database.text
Bundle-ClassPath: lib/mapdb-3.0.7.jar,
.,
lib/eclipse-collections-9.2.0.jar,
lib/eclipse-collections-api-9.2.0.jar,
lib/eclipse-collections-forkjoin-9.2.0.jar,
lib/kotlin-stdlib-1.2.42.jar,
lib/lz4-1.3.0.jar,
lib/elsa-3.0.0-M5.jar

View File

@ -10,6 +10,16 @@
###############################################################################
bin.includes = META-INF/,\
.,\
OSGI-INF/
bin.excludes = **/*.groovy
OSGI-INF/,\
lib/,\
lib/mapdb-3.0.7.jar,\
lib/eclipse-collections-9.2.0.jar,\
lib/eclipse-collections-api-9.2.0.jar,\
lib/eclipse-collections-forkjoin-9.2.0.jar,\
lib/kotlin-stdlib-1.2.42.jar,\
lib/lz4-1.3.0.jar,\
lib/elsa-3.0.0-M5.jar
bin.excludes = **/*.groovy,\
lib/mapdb-3.0.7-sources.jar,\
lib/mapdb-3.0.7-javadoc.jar
source.. = src/

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -2,20 +2,26 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>com.minres.scviewer.database.text</artifactId>
<version>2.0.1-SNAPSHOT</version>
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>2.0.0-SNAPSHOT</version>
<relativePath>../com.minres.scviewer.parent</relativePath>
</parent>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-plugin</artifactId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<compilerId>groovy-eclipse-compiler</compilerId>
<compilerArguments>
<indy/><!-- optional; supported by batch 2.4.12-04+ -->
</compilerArguments>
<!-- set verbose to be true if you want lots of uninteresting messages -->
<!-- <verbose>true</verbose> -->
<source>1.7</source>
@ -31,13 +37,9 @@
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-batch</artifactId>
<version>${groovy-eclipse-batch-version}</version>
<!-- or choose a different compiler version -->
<!-- <version>2.1.8-01</version> -->
</dependency>
</dependencies>
</plugin>
</plugins>
</plugins>
</build>
<groupId>com.minres.scviewer</groupId>
<version>1.0.0-SNAPSHOT</version>
</project>

View File

@ -10,7 +10,15 @@
*******************************************************************************/
package com.minres.scviewer.database.text;
import java.nio.charset.CharsetDecoder;
import java.util.Collection;
import java.util.zip.GZIPInputStream
import org.codehaus.groovy.ast.stmt.CatchStatement
import org.mapdb.DB
import org.mapdb.DBMaker
import groovy.io.FileType
import com.minres.scviewer.database.AssociationType
import com.minres.scviewer.database.DataType
@ -20,16 +28,19 @@ import com.minres.scviewer.database.IWaveform
import com.minres.scviewer.database.IWaveformDb
import com.minres.scviewer.database.IWaveformDbLoader
import com.minres.scviewer.database.RelationType
import com.minres.scviewer.database.DataType
public class TextDbLoader implements IWaveformDbLoader{
private Long maxTime;
IWaveformDb db;
def streams = []
def relationTypes=[:]
DB mapDb
public TextDbLoader() {
}
@ -56,18 +67,64 @@ public class TextDbLoader implements IWaveformDbLoader{
boolean load(IWaveformDb db, File file) throws Exception {
this.db=db
this.streams=[]
FileInputStream fis = new FileInputStream(file)
byte[] buffer = new byte[x.size()]
def readCnt = fis.read(buffer, 0, x.size())
fis.close()
if(readCnt==x.size())
for(int i=0; i<x.size(); i++)
if(buffer[i]!=x[i]) return false
parseInput(file)
calculateConcurrencyIndicees()
try {
def gzipped = isGzipped(file)
if(isTxfile(gzipped?new GZIPInputStream(new FileInputStream(file)):new FileInputStream(file))){
def mapDbFile = File.createTempFile("."+file.name, "tmp", file.parentFile)
mapDbFile.delete()
mapDbFile.deleteOnExit()
this.mapDb = DBMaker
.fileDB(mapDbFile)
.fileMmapEnableIfSupported()
.fileMmapPreclearDisable()
.cleanerHackEnable()
.allocateStartSize(64*1024*1024)
.allocateIncrement(64*1024*1024)
.make()
// NPE here --->
parseInput(gzipped?new GZIPInputStream(new FileInputStream(file)):new FileInputStream(file))
calculateConcurrencyIndicees()
return true
}
} catch (IndexOutOfBoundsException e) {
return false
} catch (NumberFormatException e) {
return false
} catch(EOFException e) {
return true;
} catch(Exception e) {
System.out.println("---->>> Exception "+e.toString()+" caught while loading database");
//System.out.println("---->>> Exception "+e.toString()+" caught while loading database. StackTrace following... ");
//e.printStackTrace()
}
return false;
}
private static boolean isTxfile(InputStream istream) {
byte[] buffer = new byte[x.size()]
def readCnt = istream.read(buffer, 0, x.size())
istream.close()
if(readCnt==x.size()){
for(int i=0; i<x.size(); i++)
if(buffer[i]!=x[i]) return false
}
return true
}
private static boolean isGzipped(File f) {
InputStream is = null;
try {
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;
} finally {
if(is!=null) is.close()
}
}
private stringToScale(String scale){
switch(scale.trim()){
case "fs":return 1L
@ -77,8 +134,10 @@ public class TextDbLoader implements IWaveformDbLoader{
case "ms":return 1000000000000L
case "s": return 1000000000000000L
}
return "fs"
}
private def parseInput(File input){
private def parseInput(InputStream inputStream){
def streamsById = [:]
def generatorsById = [:]
def transactionsById = [:]
@ -86,8 +145,10 @@ public class TextDbLoader implements IWaveformDbLoader{
Tx transaction
boolean endTransaction=false
def matcher
input.eachLine { line ->
def tokens = line.split(/\s+/)
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
long lineCnt=0;
reader.eachLine { line ->
def tokens = line.split(/\s+/) as ArrayList
switch(tokens[0]){
case "scv_tr_stream":
case "scv_tr_generator":
@ -95,7 +156,7 @@ public class TextDbLoader implements IWaveformDbLoader{
case "end_attribute":
if ((matcher = line =~ /^scv_tr_stream\s+\(ID (\d+),\s+name\s+"([^"]+)",\s+kind\s+"([^"]+)"\)$/)) {
def id = Integer.parseInt(matcher[0][1])
def stream = new TxStream(db, id, matcher[0][2], matcher[0][3])
def stream = new TxStream(this, id, matcher[0][2], matcher[0][3])
streams<<stream
streamsById[id]=stream
} else if ((matcher = line =~ /^scv_tr_generator\s+\(ID\s+(\d+),\s+name\s+"([^"]+)",\s+scv_tr_stream\s+(\d+),$/)) {
@ -134,13 +195,18 @@ public class TextDbLoader implements IWaveformDbLoader{
break
case "tx_record_attribute"://matcher = line =~ /^tx_record_attribute\s+(\d+)\s+"([^"]+)"\s+(\S+)\s*=\s*(.+)$/
def id = Integer.parseInt(tokens[1])
transactionsById[id].attributes<<new TxAttribute(tokens[2][1..-2], DataType.valueOf(tokens[3]), AssociationType.RECORD, tokens[5..-1].join(' '))
def name = tokens[2][1..-2]
def type = tokens[3] as DataType
def remaining = tokens.size()>5?tokens[5..-1].join(' '):""
transactionsById[id].attributes<<new TxAttribute(name, type, AssociationType.RECORD, remaining)
break
case "a"://matcher = line =~ /^a\s+(.+)$/
if(endTransaction){
transaction.attributes << new TxAttribute(transaction.generator.end_attrs[0], tokens[1])
transaction.attributes << new TxAttribute(transaction.generator.end_attrs[transaction.generator.end_attrs_idx], tokens[1])
transaction.generator.end_attrs_idx++
} else {
transaction.attributes << new TxAttribute(transaction.generator.begin_attrs[0], tokens[1])
transaction.attributes << new TxAttribute(transaction.generator.begin_attrs[transaction.generator.begin_attrs_idx], tokens[1])
transaction.generator.begin_attrs_idx++
}
break
case "tx_relation"://matcher = line =~ /^tx_relation\s+\"(\S+)\"\s+(\d+)\s+(\d+)$/
@ -156,16 +222,38 @@ public class TextDbLoader implements IWaveformDbLoader{
println "Don't know what to do with: '$line'"
}
lineCnt++
}
}
private def toDataType(String str){
switch (str)
{
case "BOOLEAN": return DataType. BOOLEAN
case "ENUMERATION": return DataType. ENUMERATION
case "INTEGER": return DataType. INTEGER
case "UNSIGNED": return DataType. UNSIGNED
case "FLOATING_POINT_NUMBER": return DataType. FLOATING_POINT_NUMBER
case "BIT_VECTOR": return DataType. BIT_VECTOR
case "LOGIC_VECTOR": return DataType. LOGIC_VECTOR
case "FIXED_POINT_INTEGER": return DataType. FIXED_POINT_INTEGER
case "UNSIGNED_FIXED_POINT_INTEGER": return DataType. UNSIGNED_FIXED_POINT_INTEGER
case "RECORD": return DataType. RECORD
case "POINTER": return DataType. POINTER
case "ARRAY": return DataType. ARRAY
case "STRING": return DataType. STRING
default: return DataType.INTEGER
}
}
private def calculateConcurrencyIndicees(){
streams.each{ TxStream stream -> stream.getMaxConcurrency() }
}
public Collection<RelationType> getAllRelationTypes(){
return relationTypes.values();
}
}

View File

@ -17,7 +17,8 @@ import java.util.List;
import java.util.Map;
import java.util.NavigableMap;
import com.google.common.collect.TreeMultimap
import org.mapdb.Serializer
import com.minres.scviewer.database.ITxEvent;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.IWaveformDb
@ -44,14 +45,15 @@ class TxStream extends HierNode implements ITxStream {
private TreeMap<Long, List<ITxEvent>> events
TxStream(IWaveformDb db, int id, String name, String kind){
TxStream(TextDbLoader loader, int id, String name, String kind){
super(name)
this.id=id
this.database=db
this.database=loader.db
this.fullName=name
this.kind=kind
this.maxConcurrency=0
events = new TreeMap<Long, List<ITxEvent>>()
//events = new TreeMap<Long, List<ITxEvent>>()
events = loader.mapDb.treeMap(name).keySerializer(Serializer.LONG).createOrOpen();
}
List<ITxGenerator> getGenerators(){
@ -110,7 +112,7 @@ class TxStream extends HierNode implements ITxStream {
}
@Override
public Boolean equals(IWaveform<? extends IWaveformEvent> other) {
public Boolean equals(IWaveform other) {
return(other instanceof TxStream && this.getId()==other.getId());
}

View File

@ -1,7 +1,7 @@
<?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-1.7"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src/"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

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

View File

@ -1,7 +1,101 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
org.eclipse.jdt.core.compiler.annotation.nonnull.secondary=
org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary=
org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
org.eclipse.jdt.core.compiler.annotation.nullable.secondary=
org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
org.eclipse.jdt.core.compiler.problem.deadCode=warning
org.eclipse.jdt.core.compiler.problem.deprecation=warning
org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.7
org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation=warning
org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
org.eclipse.jdt.core.compiler.problem.nullReference=warning
org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
org.eclipse.jdt.core.compiler.problem.pessimisticNullAnalysisForFreeTypeVariables=warning
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedImport=warning
org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
org.eclipse.jdt.core.compiler.source=1.8

View File

@ -2,9 +2,9 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: SWT widget
Bundle-SymbolicName: com.minres.scviewer.database.ui.swt
Bundle-Version: 1.0.0.qualifier
Bundle-Version: 2.0.2.qualifier
Bundle-Vendor: MINRES Technologies GmbH
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
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",
@ -17,3 +17,4 @@ Export-Package: com.minres.scviewer.database.swt
Bundle-ClassPath: .
Bundle-ActivationPolicy: lazy
Bundle-Activator: com.minres.scviewer.database.swt.DatabaseUiPlugin
Automatic-Module-Name: com.minres.scviewer.database.ui.swt

View File

@ -5,7 +5,8 @@
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>2.0.0-SNAPSHOT</version>
<relativePath>../com.minres.scviewer.parent</relativePath>
</parent>
</project>
<version>2.0.2-SNAPSHOT</version>
</project>

View File

@ -0,0 +1,9 @@
package com.minres.scviewer.database.swt;
public class Constants {
public final static String[] unitString={"fs", "ps", "ns", "us", "ms"};//, "s"};
public final static int[] unitMultiplier={1, 3, 10, 30, 100, 300};
}

View File

@ -46,6 +46,8 @@ public class ArrowPainter implements IPainter {
private RelationType highlightType;
private long selectionOffset;
long scaleFactor;
boolean deferredUpdate;
@ -87,8 +89,9 @@ public class ArrowPainter implements IPainter {
deferredUpdate = true;
return;
}
selectionOffset = waveCanvas.getXOffset();
int laneHeight = painter.getHeight() / stream.getMaxConcurrency();
txRectangle = new Rectangle((int) (tx.getBeginTime() / scaleFactor),
txRectangle = new Rectangle((int) (tx.getBeginTime() / scaleFactor-waveCanvas.getXOffset()),
waveCanvas.rulerHeight + painter.getVerticalOffset() + laneHeight * tx.getConcurrencyIndex(),
(int) ((tx.getEndTime() - tx.getBeginTime()) / scaleFactor), laneHeight);
deriveGeom(tx.getIncomingRelations(), iRect, false);
@ -102,7 +105,7 @@ public class ArrowPainter implements IPainter {
ITxStream<?> stream = otherTx.getStream();
IWaveformPainter painter = waveCanvas.wave2painterMap.get(stream);
int laneHeight = painter.getHeight() / stream.getMaxConcurrency();
Rectangle bb = new Rectangle((int) (otherTx.getBeginTime() / scaleFactor),
Rectangle bb = new Rectangle((int) (otherTx.getBeginTime() / scaleFactor-waveCanvas.getXOffset()),
waveCanvas.rulerHeight + painter.getVerticalOffset()
+ laneHeight * otherTx.getConcurrencyIndex(),
(int) ((otherTx.getEndTime() - otherTx.getBeginTime()) / scaleFactor), laneHeight);
@ -120,14 +123,19 @@ public class ArrowPainter implements IPainter {
scaleFactor = waveCanvas.getScaleFactor();
calculateGeometries();
}
if(txRectangle == null) return;
int correctionValue = (int)(selectionOffset - waveCanvas.getXOffset());
Rectangle correctedTargetRectangle = new Rectangle(txRectangle.x+correctionValue, txRectangle.y, txRectangle.width, txRectangle.height);
for (LinkEntry entry : iRect) {
Rectangle correctedRectangle = new Rectangle(entry.rectangle.x+correctionValue, entry.rectangle.y, entry.rectangle.width, entry.rectangle.height);
Point target = drawPath(gc, highlightType.equals(entry.relationType) ? highliteColor : fgColor,
entry.rectangle, txRectangle);
correctedRectangle, correctedTargetRectangle);
drawArrow(gc, target);
}
for (LinkEntry entry : oRect) {
Point target = drawPath(gc, highlightType.equals(entry.relationType) ? highliteColor : fgColor, txRectangle,
entry.rectangle);
Rectangle correctedRectangle = new Rectangle(entry.rectangle.x+correctionValue, entry.rectangle.y, entry.rectangle.width, entry.rectangle.height);
Point target = drawPath(gc, highlightType.equals(entry.relationType) ? highliteColor : fgColor, correctedTargetRectangle,
correctedRectangle);
drawArrow(gc, target);
}
}

View File

@ -30,6 +30,11 @@ public class CursorPainter implements IPainter, ICursor {
public final int id;
/// maximum visible canvas position in canvas coordinates
int maxPosX;
/// maximum visible position in waveform coordinates
int maxValX;
/**
* @param i
* @param txDisplay
@ -56,23 +61,32 @@ public class CursorPainter implements IPainter, ICursor {
this.isDragging = isDragging;
}
public void paintArea(GC gc, Rectangle area) {
if(this.waveCanvas.painterList.size()>0){
long scaleFactor=waveCanvas.getScaleFactor();
long beginPos = area.x;
maxPosX = area.x + area.width;
maxValX = maxPosX + (int)waveCanvas.getXOffset();
// x position of marker in pixels on canvas
int x = (int) (time/scaleFactor);
// distance of marker from the top of Canvas' painting area
int top = id<0?area.y:area.y+15;
Color drawColor=waveCanvas.colors[id<0?WaveformColors.CURSOR.ordinal():WaveformColors.MARKER.ordinal()];
Color dragColor = waveCanvas.colors[WaveformColors.CURSOR_DRAG.ordinal()];
Color textColor=waveCanvas.colors[id<0?WaveformColors.CURSOR_TEXT.ordinal():WaveformColors.MARKER_TEXT.ordinal()];
if(x>=area.x && x<=(area.x+area.width)){
if(x>=beginPos && x<=maxValX){
gc.setForeground(isDragging?dragColor:drawColor);
gc.drawLine(x, top, x, area.y+area.height);
gc.drawLine(x-(int)waveCanvas.getXOffset(), top, x-(int)waveCanvas.getXOffset(), area.y+area.height);
gc.setBackground(drawColor);
gc.setForeground(textColor);
Double dTime=new Double(time);
gc.drawText((dTime/waveCanvas.getScaleFactorPow10())+waveCanvas.getUnitStr(), x+1, top);
gc.drawText((dTime/waveCanvas.getScaleFactorPow10())+waveCanvas.getUnitStr(), x+1-(int)waveCanvas.getXOffset(), top);
}
}
}
}
}

View File

@ -10,6 +10,8 @@
*******************************************************************************/
package com.minres.scviewer.database.swt.internal;
import java.text.DecimalFormat;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
@ -22,12 +24,15 @@ public class RulerPainter implements IPainter {
static final int rulerTickMinorC = 10;
static final int rulerTickMajorC = 100;
static final DecimalFormat df = new DecimalFormat("#.00####");
public RulerPainter(WaveformCanvas waveCanvas) {
this.waveCanvas=waveCanvas;
}
@Override
public void paintArea(GC gc, Rectangle area) {
Color headerFgColor=waveCanvas.getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND);
if(headerFgColor.isDisposed())
headerFgColor=SWTResourceManager.getColor(0,0,0);
@ -37,25 +42,24 @@ public class RulerPainter implements IPainter {
String unit=waveCanvas.getUnitStr();
int unitMultiplier=waveCanvas.getUnitMultiplier();
long scaleFactor=waveCanvas.getScaleFactor();
long zoomLevel = waveCanvas.getZoomLevel();
long start=area.x*scaleFactor;
long end=start+area.width*scaleFactor;
long startPos=area.x*scaleFactor;
long startVal=startPos + waveCanvas.getXOffset()*scaleFactor;
long endPos=startPos+area.width*scaleFactor;
long endVal=startVal+area.width*scaleFactor;
long rulerTickMinor = rulerTickMinorC*scaleFactor;
long rulerTickMajor = rulerTickMajorC*scaleFactor;
if(zoomLevel%3==1){
rulerTickMinor/=3;
rulerTickMajor/=3;
}
int minorTickY = waveCanvas.rulerHeight-5;
int majorTickY = waveCanvas.rulerHeight-15;
int textY=waveCanvas.rulerHeight-20;
int baselineY=waveCanvas.rulerHeight - 1;
int bottom=waveCanvas.rulerHeight - 2;
long startMinorIncr = start;
long modulo = start % rulerTickMinor;
startMinorIncr+=rulerTickMinor-modulo;
long modulo = startVal % rulerTickMinor;
long startMinorIncrPos = startPos+rulerTickMinor-modulo;
long startMinorIncrVal = startVal+rulerTickMinor-modulo;
gc.setBackground(waveCanvas.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
gc.fillRectangle(new Rectangle(area.x, area.y, area.width, waveCanvas.rulerHeight));
@ -64,15 +68,18 @@ public class RulerPainter implements IPainter {
gc.setForeground(headerFgColor);
gc.drawLine(area.x, area.y+bottom, area.x+area.width, area.y+bottom);
for (long tick = startMinorIncr; tick < end; tick += rulerTickMinor) {
int x0 = (int) (tick/scaleFactor);
int x0_max = 0;
for (long pos = startMinorIncrPos, tick = startMinorIncrVal; pos < endPos; pos+= rulerTickMinor, tick += rulerTickMinor) {
int x0_pos = (int) (pos/scaleFactor);
long x0_val = tick/scaleFactor;
x0_max = x0_pos;
if ((tick % rulerTickMajor) == 0) {
gc.drawText(Double.toString(tick/scaleFactor*unitMultiplier)+unit, x0, area.y+textY);
gc.drawLine(x0, area.y+majorTickY, x0,area.y+ bottom);
gc.drawText(df.format(x0_val*unitMultiplier)+unit, x0_pos, area.y+textY);
gc.drawLine(x0_pos, area.y+majorTickY, x0_pos,area.y+ bottom);
} else {
gc.drawLine(x0, area.y+minorTickY, x0, area.y+bottom);
gc.drawLine(x0_pos, area.y+minorTickY, x0_pos, area.y+bottom);
}
}
}
}

View File

@ -10,136 +10,429 @@
*******************************************************************************/
package com.minres.scviewer.database.swt.internal;
import java.util.Collection;
import java.util.Map.Entry;
import java.util.NavigableMap;
import javax.swing.JPanel;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import com.minres.scviewer.database.BitVector;
import com.minres.scviewer.database.ISignal;
import com.minres.scviewer.database.ISignalChange;
import com.minres.scviewer.database.ISignalChangeMulti;
import com.minres.scviewer.database.ISignalChangeSingle;
import com.minres.scviewer.database.ui.TrackEntry;
import com.minres.scviewer.database.ui.WaveformColors;
public class SignalPainter extends TrackPainter {
public class SignalPainter extends TrackPainter {
private class SignalChange {
long time;
Object value;
boolean fromMap;
public SignalChange(Entry<Long, ?> entry) {
time = entry.getKey();
value = entry.getValue();
fromMap = true;
}
public void set(Entry<Long, ?> entry, Long actTime) {
if (entry != null) {
time = entry.getKey();
value = entry.getValue();
fromMap = true;
} else {
time = actTime;
fromMap = false;
}
}
public void assign(SignalChange other) {
time = other.time;
value = other.value;
fromMap = other.fromMap;
}
}
/**
*
*/
private static final JPanel DUMMY_PANEL = new JPanel();
private final WaveformCanvas waveCanvas;
private ISignal<? extends ISignalChange> signal;
int yOffsetT;
int yOffsetM;
int yOffsetB;
/// maximum visible canvas position in canvas coordinates
int maxPosX;
/// maximum visible position in waveform coordinates
int maxValX;
public SignalPainter(WaveformCanvas txDisplay, boolean even, TrackEntry trackEntry) {
super(trackEntry, even);
this.waveCanvas = txDisplay;
this.signal=trackEntry.getSignal();
}
public void paintArea(GC gc, Rectangle area) {
if(trackEntry.selected)
private int getXValEnd(long time) {
long ltmp = time / this.waveCanvas.getScaleFactor();
return ltmp > maxValX ? maxValX : (int) ltmp;
}
private int getXPosEnd(long time) {
long ltmp = time / this.waveCanvas.getScaleFactor() - waveCanvas.getXOffset();
return ltmp > maxPosX ? maxPosX : (int) ltmp;
}
public void paintArea(GC gc, Rectangle area) {
ISignal<?> signal = trackEntry.getSignal();
if (trackEntry.selected)
gc.setBackground(this.waveCanvas.colors[WaveformColors.TRACK_BG_HIGHLITE.ordinal()]);
else
gc.setBackground(this.waveCanvas.colors[even?WaveformColors.TRACK_BG_EVEN.ordinal():WaveformColors.TRACK_BG_ODD.ordinal()]);
gc.setBackground(this.waveCanvas.colors[even ? WaveformColors.TRACK_BG_EVEN.ordinal() : WaveformColors.TRACK_BG_ODD.ordinal()]);
gc.setFillRule(SWT.FILL_EVEN_ODD);
gc.fillRectangle(area);
Entry<Long, ? extends ISignalChange> firstChange=signal.getEvents().floorEntry(area.x*this.waveCanvas.getScaleFactor());
Entry<Long, ? extends ISignalChange> lastTx=signal.getEvents().ceilingEntry((area.x+area.width)*this.waveCanvas.getScaleFactor());
if(firstChange==null){
if(lastTx==null) return;
firstChange = signal.getEvents().firstEntry();
} else if(lastTx==null){
lastTx=signal.getEvents().lastEntry();
long scaleFactor = this.waveCanvas.getScaleFactor();
long beginPos = area.x;
long beginTime = (beginPos + waveCanvas.getXOffset())*scaleFactor;
long endPos = beginPos + area.width;
long endTime = beginTime + area.width*scaleFactor;
Entry<Long, ?> first = signal.getEvents().floorEntry(beginTime);
Entry<Long, ?> last = signal.getEvents().floorEntry(endTime);
if (first == null) {
if (last == null)
return;
first = signal.getEvents().firstEntry();
} else if (last == null) {
last = signal.getEvents().lastEntry();
}
gc.setForeground(this.waveCanvas.colors[WaveformColors.LINE.ordinal()]);
gc.setLineStyle(SWT.LINE_SOLID);
gc.setLineWidth(1);
Entry<Long, ? extends ISignalChange> left=firstChange;
if(left.getValue() instanceof ISignalChangeSingle){
NavigableMap<Long, ? extends ISignalChange> entries=signal.getEvents().subMap(firstChange.getKey(), false, lastTx.getKey(), true);
for(Entry<Long, ? extends ISignalChange> right:entries.entrySet()){
int xEnd= (int)(right.getKey()/this.waveCanvas.getScaleFactor());
int xBegin= (int)(left.getKey()/this.waveCanvas.getScaleFactor());
if(xEnd>xBegin){
int yOffset = this.waveCanvas.getTrackHeight()/2;
Color color = this.waveCanvas.colors[WaveformColors.SIGNALX.ordinal()];
switch(((ISignalChangeSingle) left.getValue()).getValue()){
case '1':
color=this.waveCanvas.colors[WaveformColors.SIGNAL1.ordinal()];
yOffset = this.waveCanvas.getTrackHeight()/5;
break;
case '0':
color=this.waveCanvas.colors[WaveformColors.SIGNAL0.ordinal()];
yOffset = 4*this.waveCanvas.getTrackHeight()/5;
break;
case 'Z':
color=this.waveCanvas.colors[WaveformColors.SIGNALZ.ordinal()];
break;
default:
}
yOffset+=area.y;
gc.setForeground(color);
gc.drawLine(xBegin, yOffset, xEnd, yOffset);
int yNext = this.waveCanvas.getTrackHeight()/2;
switch(((ISignalChangeSingle) right.getValue()).getValue()){
case '1':
yNext = this.waveCanvas.getTrackHeight()/5+area.y;
break;
case '0':
yNext = 4*this.waveCanvas.getTrackHeight()/5+area.y;
break;
default:
}
gc.drawLine(xEnd, yOffset, xEnd, yNext);
}
left=right;
NavigableMap<Long, ?> entries = signal.getEvents().subMap(first.getKey(), false, last.getKey(), true);
SignalChange left = new SignalChange(first);
SignalChange right = new SignalChange(entries.size() > 0 ? entries.firstEntry() : first);
maxPosX = area.x + area.width;
maxValX = maxPosX + (int)waveCanvas.getXOffset();
yOffsetT = this.waveCanvas.getTrackHeight() / 5 + area.y;
yOffsetM = this.waveCanvas.getTrackHeight() / 2 + area.y;
yOffsetB = 4 * this.waveCanvas.getTrackHeight() / 5 + area.y;
int xSigChangeBeginVal = Math.max(area.x + (int)waveCanvas.getXOffset(), (int) (left.time / this.waveCanvas.getScaleFactor()));
int xSigChangeBeginPos = area.x;
int xSigChangeEndVal = Math.max(area.x + (int)waveCanvas.getXOffset(), getXValEnd(right.time));
int xSigChangeEndPos = Math.max(area.x, getXPosEnd(right.time));
boolean multiple = false;
if (xSigChangeEndPos == xSigChangeBeginPos) {
// this can trigger if
// a) left == right
// b) left to close to right
if (left.time == right.time) {
right.time = endTime;
} else {
multiple = true;
long eTime = (xSigChangeBeginVal + 1) * this.waveCanvas.getScaleFactor();
right.set(entries.floorEntry(eTime), endTime);
right.time = eTime;
}
} else if(left.getValue() instanceof ISignalChangeMulti){
NavigableMap<Long,? extends ISignalChange> entries=signal.getEvents().subMap(firstChange.getKey(), false, lastTx.getKey(), true);
for(Entry<Long, ? extends ISignalChange> right:entries.entrySet()){
int yOffsetT = this.waveCanvas.getTrackHeight()/5+area.y;
int yOffsetM = this.waveCanvas.getTrackHeight()/2+area.y;
int yOffsetB = 4*this.waveCanvas.getTrackHeight()/5+area.y;
Color colorBorder = this.waveCanvas.colors[WaveformColors.SIGNAL0.ordinal()];
ISignalChangeMulti last = (ISignalChangeMulti) left.getValue();
if(last.getValue().toString().contains("X")){
colorBorder=this.waveCanvas.colors[WaveformColors.SIGNALX.ordinal()];
}else if(last.getValue().toString().contains("Z")){
colorBorder=this.waveCanvas.colors[WaveformColors.SIGNALZ.ordinal()];
}
int beginTime= (int)(left.getKey()/this.waveCanvas.getScaleFactor());
int endTime= (int)(right.getKey()/this.waveCanvas.getScaleFactor());
int[] points = {
beginTime,yOffsetM,
beginTime+1,yOffsetT,
endTime-1,yOffsetT,
endTime,yOffsetM,
endTime-1,yOffsetB,
beginTime+1,yOffsetB
xSigChangeEndPos = getXPosEnd(right.time);
}
SignalStencil stencil = getStencil(gc, left, entries);
do {
stencil.draw(gc, area, left.value, right.value, xSigChangeBeginPos, xSigChangeEndPos, multiple);
if (right.time >= endTime)
break;
left.assign(right);
xSigChangeBeginPos = xSigChangeEndPos;
right.set(entries.higherEntry(left.time), endTime);
xSigChangeEndPos = getXPosEnd(right.time);
multiple = false;
if (xSigChangeEndPos == xSigChangeBeginPos) {
multiple = true;
long eTime = (xSigChangeBeginPos + 1) * this.waveCanvas.getScaleFactor();
Entry<Long, ?> entry = entries.floorEntry(eTime);
if(entry!=null && entry.getKey()> right.time)
right.set(entry, endTime);
xSigChangeEndPos = getXPosEnd(eTime);
}
} while (left.time < endTime);
}
private SignalStencil getStencil(GC gc, SignalChange left, NavigableMap<Long, ?> entries) {
Object val = left.value;
if(val instanceof BitVector) {
BitVector bv = (BitVector) val;
if(bv.getWidth()==1)
return new SingleBitStencil();
if(trackEntry.waveDisplay==TrackEntry.WaveDisplay.DEFAULT)
return new MultiBitStencil(gc);
else
return new MultiBitStencilAnalog(entries, left.value,
trackEntry.waveDisplay==TrackEntry.WaveDisplay.CONTINOUS,
trackEntry.valueDisplay==TrackEntry.ValueDisplay.SIGNED);
} else if (val instanceof Double)
return new RealStencil(entries, left.value, trackEntry.waveDisplay==TrackEntry.WaveDisplay.CONTINOUS);
else
return null;
}
private interface SignalStencil {
public void draw(GC gc, Rectangle area, Object left, Object right, int xBegin, int xEnd, boolean multiple);
}
private class MultiBitStencil implements SignalStencil {
private java.awt.Font tmpAwtFont;
private int height;
public MultiBitStencil(GC gc) {
FontData fd = gc.getFont().getFontData()[0];
height = gc.getDevice().getDPI().y * fd.getHeight() / 72;
tmpAwtFont = new java.awt.Font(fd.getName(), fd.getStyle(), height);
}
public void draw(GC gc, Rectangle area, Object left, Object right, int xBegin, int xEnd, boolean multiple) {
Color colorBorder = waveCanvas.colors[WaveformColors.SIGNAL0.ordinal()];
BitVector last = (BitVector) left;
if (last.getValue().toString().contains("X")) {
colorBorder = waveCanvas.colors[WaveformColors.SIGNALX.ordinal()];
} else if (last.getValue().toString().contains("Z")) {
colorBorder = waveCanvas.colors[WaveformColors.SIGNALZ.ordinal()];
}
int width = xEnd - xBegin;
if (width > 1) {
int[] points = {
xBegin, yOffsetM,
xBegin + 1, yOffsetT,
xEnd - 1, yOffsetT,
xEnd, yOffsetM,
xEnd - 1, yOffsetB,
xBegin + 1, yOffsetB
};
gc.setForeground(colorBorder);
gc.drawPolygon(points);
gc.setForeground(this.waveCanvas.colors[WaveformColors.SIGNAL_TEXT.ordinal()]);
int size = gc.getDevice().getDPI().y * gc.getFont().getFontData()[0].getHeight()/72;
if(beginTime<area.x) beginTime=area.x;
int width=endTime-beginTime;
if(width>6) {
gc.setForeground(waveCanvas.colors[WaveformColors.SIGNAL_TEXT.ordinal()]);
//TODO: this code should be provided from a central location
String label = null;
switch(trackEntry.valueDisplay) {
case SIGNED:
label=Long.toString(last.toSignedValue());
break;
case UNSIGNED:
label=Long.toString(last.toUnsignedValue());
break;
default:
label="h'"+last.toHexString();
}
Point bb = getBoxWidth(gc, label);
if (xBegin < area.x) {
xBegin = area.x;
width = xEnd - xBegin;
}
if (width > (bb.x+1)) {
Rectangle old = gc.getClipping();
gc.setClipping(beginTime+3, yOffsetT, endTime-beginTime-5, yOffsetB-yOffsetT);
gc.drawText("h'"+last.getValue().toHexString(), beginTime+3, yOffsetM-size/2-1);
gc.setClipping(xBegin + 3, yOffsetT, xEnd - xBegin - 5, yOffsetB - yOffsetT);
gc.drawText(label, xBegin + 3, yOffsetM - bb.y / 2 - 1);
gc.setClipping(old);
}
left=right;
} else {
gc.setForeground(colorBorder);
gc.drawLine(xEnd, yOffsetT, xEnd, yOffsetB);
}
}
private Point getBoxWidth(GC gc, String label) {
return new Point(DUMMY_PANEL.getFontMetrics(tmpAwtFont).stringWidth(label), height);
}
}
private class MultiBitStencilAnalog implements SignalStencil {
final boolean continous;
private long minVal;
private long range;
public MultiBitStencilAnalog(NavigableMap<Long, ?> entries, Object left, boolean continous, boolean signed) {
this.continous=continous;
Collection<?> values = ((NavigableMap<Long, ?>) entries).values();
minVal=((BitVector) left).toUnsignedValue();
range=2;
if(!values.isEmpty()) {
long maxVal=minVal;
for (Object e : entries.values()) {
long v = ((BitVector)e).toUnsignedValue();
maxVal=Math.max(maxVal, v);
minVal=Math.min(minVal, v);
}
if(maxVal==minVal) {
maxVal--;
minVal++;
}
range = maxVal-minVal;
} else
minVal--;
}
public void draw(GC gc, Rectangle area, Object left, Object right, int xBegin, int xEnd, boolean multiple) {
long leftVal = ((BitVector) left).toUnsignedValue();
long rightVal= ((BitVector) right).toUnsignedValue();
gc.setForeground(waveCanvas.colors[WaveformColors.SIGNAL_REAL.ordinal()]);
int yOffsetLeft = (int) ((leftVal-minVal) / range * (yOffsetB-yOffsetT));
int yOffsetRight = (int) ((rightVal-minVal) / range * (yOffsetB-yOffsetT));
if(continous) {
if (xEnd > maxPosX) {
gc.drawLine(xBegin, yOffsetB-yOffsetLeft, maxPosX, yOffsetB-yOffsetRight);
} else {
gc.drawLine(xBegin, yOffsetB-yOffsetLeft, xEnd, yOffsetB-yOffsetRight);
}
} else {
if (xEnd > maxPosX) {
gc.drawLine(xBegin, yOffsetB-yOffsetLeft, maxPosX, yOffsetB-yOffsetLeft);
} else {
gc.drawLine(xBegin, yOffsetB-yOffsetLeft, xEnd, yOffsetB-yOffsetLeft);
if(yOffsetRight!=yOffsetLeft) {
gc.drawLine(xEnd, yOffsetB-yOffsetLeft, xEnd, yOffsetB-yOffsetRight);
}
}
}
}
}
public ISignal<? extends ISignalChange> getSignal() {
return signal;
private class SingleBitStencil implements SignalStencil {
public void draw(GC gc, Rectangle area, Object left, Object right, int xBegin, int xEnd, boolean multiple) {
if (multiple) {
gc.setForeground(waveCanvas.colors[WaveformColors.SIGNALU.ordinal()]);
gc.drawLine(xBegin, yOffsetT, xBegin, yOffsetB);
if(xEnd>xBegin)
gc.drawLine(xEnd, yOffsetT, xEnd, yOffsetB);
} else {
Color color = waveCanvas.colors[WaveformColors.SIGNALX.ordinal()];
int yOffset = yOffsetM;
switch (((BitVector) left).getValue()[0]) {
case '1':
color = waveCanvas.colors[WaveformColors.SIGNAL1.ordinal()];
yOffset = yOffsetT;
break;
case '0':
color = waveCanvas.colors[WaveformColors.SIGNAL0.ordinal()];
yOffset = yOffsetB;
break;
case 'Z':
color = waveCanvas.colors[WaveformColors.SIGNALZ.ordinal()];
break;
default:
}
gc.setForeground(color);
if (xEnd > maxPosX) {
gc.drawLine(xBegin, yOffset, maxPosX, yOffset);
} else {
gc.drawLine(xBegin, yOffset, xEnd, yOffset);
int yNext = yOffsetM;
switch (((BitVector) right).getValue()[0]) {
case '1':
yNext = yOffsetT;
break;
case '0':
yNext = yOffsetB;
break;
default:
}
if (yOffset != yNext)
gc.drawLine(xEnd, yOffset, xEnd, yNext);
}
}
}
}
}
private class RealStencil implements SignalStencil {
double minVal, range;
final double scaleFactor = 1.05;
boolean continous=true;
public RealStencil(NavigableMap<Long, ?> entries, Object left, boolean continous) {
this.continous=continous;
Collection<?> values = ((NavigableMap<Long, ?>) entries).values();
minVal=(Double) left;
range=2.0;
if(!values.isEmpty()) {
double maxVal=minVal;
for (Object e : entries.values()) {
double v = ((Double)e);
if(Double.isNaN(maxVal))
maxVal=v;
else if(!Double.isNaN(v))
maxVal=Math.max(maxVal, v);
if(Double.isNaN(minVal))
minVal=v;
else if(!Double.isNaN(v))
minVal=Math.min(minVal, v);
}
if(Double.isNaN(maxVal)){
maxVal=minVal=0.0;
}
range = (maxVal-minVal)*scaleFactor;
double avg = (maxVal+minVal)/2.0;
minVal=avg-(avg-minVal)*scaleFactor;
}
}
public void draw(GC gc, Rectangle area, Object left, Object right, int xBegin, int xEnd, boolean multiple) {
double leftVal = (Double) left;
double rightVal= (Double) right;
if(Double.isNaN(leftVal)) {
Color color = waveCanvas.colors[WaveformColors.SIGNAL_NAN.ordinal()];
int width = xEnd - xBegin;
if (width > 1) {
int[] points = {
xBegin, yOffsetT,
xEnd, yOffsetT,
xEnd, yOffsetB,
xBegin, yOffsetB
};
gc.setForeground(color);
gc.drawPolygon(points);
gc.setBackground(color);
gc.fillPolygon(points);
} else {
gc.setForeground(color);
gc.drawLine(xEnd, yOffsetT, xEnd, yOffsetB);
}
} else {
gc.setForeground(waveCanvas.colors[WaveformColors.SIGNAL_REAL.ordinal()]);
int yOffsetLeft = (int) ((leftVal-minVal) / range * (yOffsetB-yOffsetT));
int yOffsetRight = Double.isNaN(rightVal)?yOffsetLeft:(int) ((rightVal-minVal) / range * (yOffsetB-yOffsetT));
if(continous) {
if (xEnd > maxPosX) {
gc.drawLine(xBegin, yOffsetB-yOffsetLeft, maxPosX, yOffsetB-yOffsetRight);
} else {
gc.drawLine(xBegin, yOffsetB-yOffsetLeft, xEnd, yOffsetB-yOffsetRight);
}
} else {
if (xEnd > maxPosX) {
gc.drawLine(xBegin, yOffsetB-yOffsetLeft, maxPosX, yOffsetB-yOffsetLeft);
} else {
gc.drawLine(xBegin, yOffsetB-yOffsetLeft, xEnd, yOffsetB-yOffsetLeft);
if(yOffsetRight!=yOffsetLeft) {
gc.drawLine(xEnd, yOffsetB-yOffsetLeft, xEnd, yOffsetB-yOffsetRight);
}
}
}
}
}
}
}

View File

@ -44,6 +44,20 @@ public class StreamPainter extends TrackPainter{
this.stream=trackEntry.getStream();
this.seenTx=new TreeSet<ITx>();
}
/*
* convert java.awt.Color to org.eclipse.swt.graphics.Color
*/
static org.eclipse.swt.graphics.Color toSwtColor( GC gc, java.awt.Color awtColor ){
return new org.eclipse.swt.graphics.Color( gc.getDevice(), awtColor.getRed(), awtColor.getGreen(), awtColor.getBlue() );
}
static org.eclipse.swt.graphics.Color[] toSwtColors( GC gc, java.awt.Color[] awtColors ){
org.eclipse.swt.graphics.Color[] swtColors = new org.eclipse.swt.graphics.Color[awtColors.length];
for( int i=0; i<awtColors.length; i++ )
swtColors[i] = toSwtColor( gc, awtColors[i] );
return swtColors;
}
@SuppressWarnings("unchecked")
public void paintArea(GC gc, Rectangle area) {
@ -51,58 +65,73 @@ public class StreamPainter extends TrackPainter{
int trackHeight=trackEntry.height/stream.getMaxConcurrency();
txBase=trackHeight/5;
txHeight=trackHeight*3/5;
if(trackEntry.selected)
if(trackEntry.selected) {
gc.setBackground(this.waveCanvas.colors[WaveformColors.TRACK_BG_HIGHLITE.ordinal()]);
}
else
gc.setBackground(this.waveCanvas.colors[even?WaveformColors.TRACK_BG_EVEN.ordinal():WaveformColors.TRACK_BG_ODD.ordinal()]);
gc.setFillRule(SWT.FILL_EVEN_ODD);
gc.fillRectangle(area);
Entry<Long, ?> firstTx=stream.getEvents().floorEntry(area.x*waveCanvas.getScaleFactor());
Entry<Long, ?> lastTx=stream.getEvents().ceilingEntry((area.x+area.width)*waveCanvas.getScaleFactor());
long scaleFactor = this.waveCanvas.getScaleFactor();
long beginPos = area.x;
long beginTime = (beginPos + waveCanvas.getXOffset())*scaleFactor;
//long endPos = beginPos + area.width;
long endTime = beginTime + area.width*scaleFactor;
Entry<Long, ?> firstTx=stream.getEvents().floorEntry(beginTime);
Entry<Long, ?> lastTx=stream.getEvents().ceilingEntry(endTime);
if(firstTx==null) firstTx = stream.getEvents().firstEntry();
if(lastTx==null) lastTx=stream.getEvents().lastEntry();
gc.setFillRule(SWT.FILL_EVEN_ODD);
gc.setLineStyle(SWT.LINE_SOLID);
gc.setLineWidth(1);
gc.setForeground(this.waveCanvas.colors[WaveformColors.LINE.ordinal()]);
for(int y1=area.y+trackHeight/2; y1<area.y+trackEntry.height; y1+=trackHeight)
for( int y1=area.y+trackHeight/2; y1<area.y+trackEntry.height; y1+=trackHeight)
gc.drawLine(area.x, y1, area.x+area.width, y1);
if(firstTx==lastTx)
if(firstTx==lastTx) {
for(ITxEvent txEvent:(Collection<? extends ITxEvent>)firstTx.getValue())
drawTx(gc, area, txEvent.getTransaction());
else{
drawTx(gc, area, txEvent.getTransaction(), false);
}else{
seenTx.clear();
NavigableMap<Long,?> entries = stream.getEvents().subMap(firstTx.getKey(), true, lastTx.getKey(), true);
boolean highlighed=false;
gc.setForeground(this.waveCanvas.colors[WaveformColors.LINE.ordinal()]);
gc.setBackground(this.waveCanvas.colors[WaveformColors.TX_BG.ordinal()]);
for(Entry<Long, ?> entry: entries.entrySet())
for(Entry<Long, ?> entry: entries.entrySet())
for(ITxEvent txEvent:(Collection<? extends ITxEvent>)entry.getValue()){
if(txEvent.getType()==ITxEvent.Type.BEGIN)
seenTx.add(txEvent.getTransaction());
if(txEvent.getType()==ITxEvent.Type.END){
ITx tx = txEvent.getTransaction();
highlighed|=waveCanvas.currentSelection!=null && waveCanvas.currentSelection.equals(tx);
drawTx(gc, area, tx);
drawTx(gc, area, tx, false);
seenTx.remove(tx);
}
}
for(ITx tx:seenTx){
drawTx(gc, area, tx);
drawTx(gc, area, tx, false);
}
if(highlighed){
gc.setForeground(this.waveCanvas.colors[WaveformColors.LINE_HIGHLITE.ordinal()]);
gc.setBackground(this.waveCanvas.colors[WaveformColors.TX_BG_HIGHLITE.ordinal()]);
drawTx(gc, area, waveCanvas.currentSelection);
drawTx(gc, area, waveCanvas.currentSelection, true);
}
}
}
protected void drawTx(GC gc, Rectangle area, ITx tx) {
protected void drawTx(GC gc, Rectangle area, ITx tx, boolean highlighted ) {
// compute colors
java.awt.Color[] fallbackColors = trackEntry.getColors();
java.awt.Color[] transColor = TrackEntry.computeColor( tx.getGenerator().getName(), fallbackColors[0], fallbackColors[1] );
gc.setBackground( toSwtColor( gc, transColor[highlighted?1:0] ) );
int offset = tx.getConcurrencyIndex()*this.waveCanvas.getTrackHeight();
Rectangle bb = new Rectangle(
(int)(tx.getBeginTime()/this.waveCanvas.getScaleFactor()), area.y+offset+txBase,
(int)(tx.getBeginTime()/this.waveCanvas.getScaleFactor()-waveCanvas.getXOffset()), area.y+offset+txBase,
(int)((tx.getEndTime()-tx.getBeginTime())/this.waveCanvas.getScaleFactor()), txHeight);
if(bb.x+bb.width<area.x || bb.x>area.x+area.width) return;
if(bb.width==0){
gc.drawLine(bb.x, bb.y, bb.x, bb.y+bb.height);
@ -110,7 +139,17 @@ public class StreamPainter extends TrackPainter{
gc.fillRectangle(bb);
gc.drawRectangle(bb);
} else {
gc.fillRoundRectangle(bb.x, bb.y, bb.width, bb.height, 5, 5);
if(bb.x < area.x) {
bb.width = bb.width-(area.x-bb.x)+5;
bb.x=area.x-5;
}
int bb_x2 = bb.x+bb.width;
int area_x2 = area.x+area.width;
if(bb_x2>area_x2){
bb_x2=area_x2+5;
bb.width= bb_x2-bb.x;
}
gc.fillRoundRectangle(bb.x, bb.y, bb.width, bb.height, 5, 5);
gc.drawRoundRectangle(bb.x, bb.y, bb.width, bb.height, 5, 5);
}
}

View File

@ -39,12 +39,13 @@ import org.eclipse.wb.swt.SWTResourceManager;
import com.google.common.collect.Lists;
import com.minres.scviewer.database.ITx;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.IWaveformEvent;
import com.minres.scviewer.database.RelationType;
import com.minres.scviewer.database.swt.Constants;
import com.minres.scviewer.database.ui.IWaveformViewer;
import com.minres.scviewer.database.ui.TrackEntry;
import com.minres.scviewer.database.ui.WaveformColors;
public class WaveformCanvas extends Canvas {
public class WaveformCanvas extends Canvas{
Color[] colors = new Color[WaveformColors.values().length];
@ -55,11 +56,7 @@ public class WaveformCanvas extends Canvas {
String unit="ns";
private int level = 12;
public final static String[] unitString={"fs", "ps", "ns", "µs", "ms"};//, "s"};
public final static int[] unitMultiplier={1, 3, 10, 30, 100, 300};
private long maxTime;
protected Point origin; /* original size */
@ -82,18 +79,18 @@ public class WaveformCanvas extends Canvas {
private List<CursorPainter> cursorPainters;
HashMap<IWaveform<?>, IWaveformPainter> wave2painterMap;
HashMap<IWaveform, IWaveformPainter> wave2painterMap;
/**
* Constructor for ScrollableCanvas.
*
* @param parent
* the parent of this control.
* the parent of this control.super(parent, style | SWT.DOUBLE_BUFFERED | SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE | SWT.V_SCROLL | SWT.H_SCROLL);
* @param style
* the style of this control.
*/
public WaveformCanvas(final Composite parent, int style) {
super(parent, style | SWT.DOUBLE_BUFFERED | SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE | SWT.V_SCROLL | SWT.H_SCROLL);
addControlListener(new ControlAdapter() { /* resize listener. */
addControlListener(new ControlAdapter() { /* resize listener. */
public void controlResized(ControlEvent event) {
syncScrollBars();
}
@ -126,8 +123,37 @@ public class WaveformCanvas extends Canvas {
painterList.add(marker);
cursorPainters.add(marker);
wave2painterMap=new HashMap<>();
}
// fall back initialization
colors[WaveformColors.LINE.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_RED);
colors[WaveformColors.LINE_HIGHLITE.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_CYAN);
colors[WaveformColors.TRACK_BG_EVEN.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_BLACK);
colors[WaveformColors.TRACK_BG_ODD.ordinal()] = SWTResourceManager.getColor(40, 40, 40);
colors[WaveformColors.TRACK_BG_HIGHLITE.ordinal()] = SWTResourceManager.getColor(40, 40, 80);
colors[WaveformColors.TX_BG.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_GREEN);
colors[WaveformColors.TX_BG_HIGHLITE.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_DARK_GREEN);
colors[WaveformColors.TX_BORDER.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_RED);
colors[WaveformColors.SIGNAL0.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_GREEN);
colors[WaveformColors.SIGNAL1.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_GREEN);
colors[WaveformColors.SIGNALZ.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_DARK_YELLOW);
colors[WaveformColors.SIGNALX.ordinal()] = SWTResourceManager.getColor(255, 51, 51);
colors[WaveformColors.SIGNALU.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_YELLOW);
colors[WaveformColors.SIGNAL_TEXT.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_WHITE);
colors[WaveformColors.SIGNAL_REAL.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_YELLOW);
colors[WaveformColors.SIGNAL_NAN.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_RED);
colors[WaveformColors.CURSOR.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_RED);
colors[WaveformColors.CURSOR_DRAG.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_GRAY);
colors[WaveformColors.CURSOR_TEXT.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_WHITE);
colors[WaveformColors.MARKER.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_DARK_GRAY);
colors[WaveformColors.MARKER_TEXT.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_WHITE);
colors[WaveformColors.REL_ARROW.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_MAGENTA);
colors[WaveformColors.REL_ARROW_HIGHLITE.ordinal()] = SWTResourceManager.getColor(255, 128, 255);
}
public long getXOffset() {
return -origin.x;
}
public void addCursoPainter(CursorPainter cursorPainter){
painterList.add(cursorPainter);
cursorPainters.add(cursorPainter);
@ -137,32 +163,10 @@ public class WaveformCanvas extends Canvas {
Display d = getDisplay();
if (colourMap != null) {
for (WaveformColors c : WaveformColors.values()) {
if (colourMap.containsKey(c)) {
if (colourMap.containsKey(c))
colors[c.ordinal()] = new Color(d, colourMap.get(c));
}
}
redraw();
} else {
colors[WaveformColors.LINE.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_RED);
colors[WaveformColors.LINE_HIGHLITE.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_CYAN);
colors[WaveformColors.TRACK_BG_EVEN.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_BLACK);
colors[WaveformColors.TRACK_BG_ODD.ordinal()] = SWTResourceManager.getColor(40, 40, 40);
colors[WaveformColors.TRACK_BG_HIGHLITE.ordinal()] = SWTResourceManager.getColor(40, 40, 80);
colors[WaveformColors.TX_BG.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_GREEN);
colors[WaveformColors.TX_BG_HIGHLITE.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_DARK_GREEN);
colors[WaveformColors.TX_BORDER.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_RED);
colors[WaveformColors.SIGNAL0.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_DARK_GREEN);
colors[WaveformColors.SIGNAL1.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_DARK_GREEN);
colors[WaveformColors.SIGNALZ.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_GRAY);
colors[WaveformColors.SIGNALX.ordinal()] = SWTResourceManager.getColor(255, 128, 182);
colors[WaveformColors.SIGNAL_TEXT.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_WHITE);
colors[WaveformColors.CURSOR.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_RED);
colors[WaveformColors.CURSOR_DRAG.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_GRAY);
colors[WaveformColors.CURSOR_TEXT.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_WHITE);
colors[WaveformColors.MARKER.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_DARK_GRAY);
colors[WaveformColors.MARKER_TEXT.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_WHITE);
colors[WaveformColors.REL_ARROW.ordinal()] = SWTResourceManager.getColor(SWT.COLOR_MAGENTA);
colors[WaveformColors.REL_ARROW_HIGHLITE.ordinal()] = SWTResourceManager.getColor(255, 128, 255);
}
}
@ -178,6 +182,9 @@ public class WaveformCanvas extends Canvas {
return origin;
}
public int getWidth() {
return getClientArea().width;
}
public void setOrigin(Point origin) {
setOrigin(origin.x, origin.y);
}
@ -218,20 +225,37 @@ public class WaveformCanvas extends Canvas {
}
public int getMaxZoomLevel(){
return unitMultiplier.length*unitString.length-1;
return Constants.unitMultiplier.length*Constants.unitString.length-1;
}
public void setZoomLevel(int level) {
if(level<unitMultiplier.length*unitString.length){
long oldScaleFactor=scaleFactor;
if(level<Constants.unitMultiplier.length*Constants.unitString.length){
this.level = level;
this.scaleFactor = (long) Math.pow(10, level/2);
if(level%2==1) this.scaleFactor*=3;
ITx tx = arrowPainter.getTx();
arrowPainter.setTx(null);
/*
* xc = tc/oldScaleFactor
* xoffs = xc+origin.x
* xcn = tc/newScaleFactor
* t0n = (xcn-xoffs)*scaleFactor
*/
long tc=cursorPainters.get(0).getTime(); // cursor time
long xc=tc/oldScaleFactor; // cursor total x-offset
long xoffs=xc+origin.x; // cursor offset relative to left border
long xcn=tc/scaleFactor; // new total x-offset
long originX=xcn-xoffs;
if(originX>0) {
origin.x=(int) -originX; // new cursor time offset relative to left border
}else {
origin.x=0;
}
syncScrollBars();
arrowPainter.setTx(tx);
arrowPainter.setTx(tx);
redraw();
}
}
}
public long getScaleFactor() {
@ -239,17 +263,17 @@ public class WaveformCanvas extends Canvas {
}
public long getScaleFactorPow10() {
int scale = level/unitMultiplier.length;
int scale = level/Constants.unitMultiplier.length;
double res = Math.pow(1000, scale);
return (long) res;
}
public String getUnitStr(){
return unitString[level/unitMultiplier.length];
return Constants.unitString[level/Constants.unitMultiplier.length];
}
public int getUnitMultiplier(){
return unitMultiplier[level%unitMultiplier.length];
return Constants.unitMultiplier[level%Constants.unitMultiplier.length];
}
public long getTimeForOffset(int xOffset){
@ -267,15 +291,23 @@ public class WaveformCanvas extends Canvas {
}
public void clearAllWaveformPainter() {
clearAllWaveformPainter(true);
}
void clearAllWaveformPainter(boolean update) {
trackAreaPainter.getTrackVerticalOffset().clear();
wave2painterMap.clear();
syncScrollBars();
if(update) syncScrollBars();
}
public void addWaveformPainter(IWaveformPainter painter) {
addWaveformPainter(painter, true);
}
void addWaveformPainter(IWaveformPainter painter, boolean update) {
trackAreaPainter.addTrackPainter(painter);
wave2painterMap.put(painter.getTrackEntry().waveform, painter);
syncScrollBars();
if(update) syncScrollBars();
}
public List<CursorPainter> getCursorPainters() {
@ -292,7 +324,7 @@ public class WaveformCanvas extends Canvas {
super.dispose();
}
/* Initalize the scrollbar and register listeners. */
/* Initialize the scrollbar and register listeners. */
private void initScrollBars() {
ScrollBar horizontal = getHorizontalBar();
horizontal.setEnabled(false);
@ -326,38 +358,43 @@ public class WaveformCanvas extends Canvas {
redraw();
return;
}
int height = trackAreaPainter.getHeight();
int width = (int) (maxTime / scaleFactor);
int height = trackAreaPainter.getHeight(); // incl. Ruler
long width = maxTime / scaleFactor;
Rectangle clientArea=getClientArea();
ScrollBar horizontal = getHorizontalBar();
horizontal.setIncrement((int) (getClientArea().width / 100));
horizontal.setPageIncrement(getClientArea().width);
int cw = getClientArea().width;
if (width > cw) { /* image is wider than client area */
horizontal.setMaximum(width);
int clientWidthw = clientArea.width;
if (width > clientWidthw) { /* image is wider than client area */
horizontal.setMinimum(0);
horizontal.setMaximum((int)width);
horizontal.setEnabled(true);
if (((int) -origin.x) > horizontal.getMaximum() - cw)
origin.x = -horizontal.getMaximum() + cw;
if (((int) -origin.x) > horizontal.getMaximum() - clientWidthw) {
origin.x = -horizontal.getMaximum() + clientWidthw;
}
} else { /* image is narrower than client area */
horizontal.setEnabled(false);
}
horizontal.setThumb(clientWidthw);
horizontal.setSelection(-origin.x);
horizontal.setThumb(cw);
ScrollBar vertical = getVerticalBar();
vertical.setIncrement((int) (getClientArea().height / 100));
vertical.setPageIncrement((int) (getClientArea().height));
int ch = getClientArea().height;
if (height > ch) { /* image is higher than client area */
int clientHeighth = clientArea.height;
if (height > clientHeighth) { /* image is higher than client area */
vertical.setMinimum(0);
vertical.setMaximum(height);
vertical.setEnabled(true);
if (((int) -origin.y) > vertical.getMaximum() - ch)
origin.y = -vertical.getMaximum() + ch;
if (((int) -origin.y) > vertical.getMaximum() - clientHeighth) {
origin.y = -vertical.getMaximum() + clientHeighth;
}
} else { /* image is less higher than client area */
vertical.setMaximum((int) (ch));
vertical.setMaximum((int) (clientHeighth));
vertical.setEnabled(false);
}
vertical.setThumb(clientHeighth);
vertical.setSelection(-origin.y);
vertical.setThumb(ch);
redraw();
fireSelectionEvent();
@ -366,12 +403,13 @@ public class WaveformCanvas extends Canvas {
/* Paint function */
private void paint(GC gc) {
Rectangle clientRect = getClientArea(); /* Canvas' painting area */
clientRect.x = -origin.x;
// clientRect.x = -origin.x;
clientRect.y = -origin.y;
// reset the transform
transform.identity();
// shift the content
transform.translate(origin.x, origin.y);
// DO NOT SHIFT HORIZONTALLY, the range is WAY TOO BIG for float!!!
transform.translate(0, origin.y);
gc.setTransform(transform);
gc.setClipping(clientRect);
if (painterList.size() > 0 ) {
@ -407,7 +445,7 @@ public class WaveformCanvas extends Canvas {
return result;
}
public List<Object> getEntriesAtPosition(IWaveform<? extends IWaveformEvent> iWaveform, int i) {
public List<Object> getEntriesAtPosition(IWaveform iWaveform, int i) {
LinkedList<Object> result=new LinkedList<>();
int x = i - origin.x;
for(IPainter p: wave2painterMap.values()){
@ -450,6 +488,27 @@ public class WaveformCanvas extends Canvas {
}
}
public void reveal(IWaveform waveform) {
for (IWaveformPainter painter : wave2painterMap.values()) {
TrackEntry te = painter.getTrackEntry();
if(te.waveform == waveform) {
Point size = getSize();
//size.x -= getVerticalBar().getSize().x + 2;
size.y -=+rulerHeight;
ScrollBar sb = getHorizontalBar();
if((sb.getStyle()&SWT.SCROLLBAR_OVERLAY)!=0 && sb.isVisible()) // TODO: check on other platform than MacOSX
size.y-= getHorizontalBar().getSize().y;
int top = te.vOffset;
int bottom = top + trackHeight;
if (top < -origin.y) {
setOrigin(origin.x, -(top-trackHeight));
} else if (bottom > (size.y - origin.y)) {
setOrigin(origin.x, size.y - bottom);
}
}
}
}
public void reveal(long time) {
int scaledTime = (int) (time / scaleFactor);
Point size = getSize();
@ -494,4 +553,11 @@ public class WaveformCanvas extends Canvas {
}
}
long getMaxVisibleTime() {
return (getClientArea().width+origin.x)*scaleFactor;
}
long getOriginTime() {
return origin.x * scaleFactor;
}
}

View File

@ -10,9 +10,11 @@
*******************************************************************************/
package com.minres.scviewer.database.swt.internal;
import java.awt.Color;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.text.DecimalFormat;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@ -20,6 +22,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.NoSuchElementException;
import java.util.TreeMap;
import org.eclipse.core.runtime.ListenerList;
@ -43,6 +46,7 @@ import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
@ -65,20 +69,19 @@ import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.wb.swt.SWTResourceManager;
import com.google.common.collect.Lists;
import com.minres.scviewer.database.BitVector;
import com.minres.scviewer.database.ISignal;
import com.minres.scviewer.database.ISignalChange;
import com.minres.scviewer.database.ISignalChangeMulti;
import com.minres.scviewer.database.ISignalChangeSingle;
import com.minres.scviewer.database.ITx;
import com.minres.scviewer.database.ITxEvent;
import com.minres.scviewer.database.ITxRelation;
import com.minres.scviewer.database.ITxStream;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.IWaveformEvent;
import com.minres.scviewer.database.RelationType;
import com.minres.scviewer.database.swt.Constants;
import com.minres.scviewer.database.ui.GotoDirection;
import com.minres.scviewer.database.ui.ICursor;
import com.minres.scviewer.database.ui.IWaveformViewer;
@ -87,10 +90,12 @@ import com.minres.scviewer.database.ui.WaveformColors;
public class WaveformViewer implements IWaveformViewer {
private ListenerList selectionChangedListeners = new ListenerList();
private ListenerList<ISelectionChangedListener> selectionChangedListeners = new ListenerList<ISelectionChangedListener>();
private PropertyChangeSupport pcs;
static final DecimalFormat df = new DecimalFormat("#.00####");
private ITx currentTxSelection;
private TrackEntry currentWaveformSelection;
@ -101,12 +106,14 @@ public class WaveformViewer implements IWaveformViewer {
private Control namePaneHeader;
private Canvas nameList;
final private Canvas nameList;
private Canvas valueList;
final private Canvas valueList;
WaveformCanvas waveformCanvas;
final WaveformCanvas waveformCanvas;
private boolean revealSelected=false;
private Composite top;
protected ObservableList<TrackEntry> streams;
@ -117,19 +124,16 @@ public class WaveformViewer implements IWaveformViewer {
private TreeMap<Integer, TrackEntry> trackVerticalOffset;
private HashMap<IWaveform<? extends IWaveformEvent>, String> actualValues;
private Font nameFont, nameFontB;
protected MouseListener nameValueMouseListener = new MouseAdapter() {
@Override
public void mouseDown(MouseEvent e) {
if ((e.button == 1 || e.button == 3)) {
if (e.button == 1) {
Entry<Integer, TrackEntry> entry = trackVerticalOffset.floorEntry(e.y);
if (entry != null)
setSelection(new StructuredSelection(entry.getValue()));
}
if (e.button == 3) {
} else if (e.button == 3) {
Menu topMenu= top.getMenu();
if(topMenu!=null) topMenu.setVisible(true);
}
@ -143,12 +147,10 @@ public class WaveformViewer implements IWaveformViewer {
@Override
public void mouseDown(MouseEvent e) {
start=new Point(e.x, e.y);
if((e.stateMask&SWT.MODIFIER_MASK)!=0) return; //don't react on modifier
if (e.button == 1) {
initialSelected = waveformCanvas.getClicked(start);
} else if (e.button == 3) {
List<Object> hitted = waveformCanvas.getClicked(start);
if(hitted!=null && hitted.size()>0)
setSelection(new StructuredSelection(hitted));
Menu topMenu= top.getMenu();
if(topMenu!=null) topMenu.setVisible(true);
}
@ -156,29 +158,19 @@ public class WaveformViewer implements IWaveformViewer {
@Override
public void mouseUp(MouseEvent e) {
if (e.button == 1) {
if(start==null) return;
if((e.stateMask&SWT.MODIFIER_MASK&~SWT.SHIFT)!=0) return; //don't react on modifier
if (e.button == 1 && ((e.stateMask&SWT.SHIFT)==0)) {
if(Math.abs(e.x-start.x)<3 && Math.abs(e.y-start.y)<3){
// first set time
// first set cursor time
setCursorTime(snapOffsetToEvent(e));
// then set selection and reveal
setSelection(new StructuredSelection(initialSelected));
e.widget.getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
waveformCanvas.redraw();
updateValueList();
}
});
asyncUpdate(e.widget);
}
}else if (e.button == 2) {
}else if (e.button == 2 ||(e.button==1 && (e.stateMask&SWT.SHIFT)!=0)) {
setMarkerTime(snapOffsetToEvent(e), selectedMarker);
e.widget.getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
waveformCanvas.redraw();
updateValueList();
}
});
asyncUpdate(e.widget);
}
}
@ -224,20 +216,19 @@ public class WaveformViewer implements IWaveformViewer {
trackVerticalOffset = new TreeMap<Integer, TrackEntry>();
trackVerticalHeight=0;
actualValues = new HashMap<IWaveform<? extends IWaveformEvent>, String>();
nameFont = parent.getDisplay().getSystemFont();
nameFontB = SWTResourceManager.getBoldFont(nameFont);
streams = new ObservableList<>();
streams.addPropertyChangeListener(this);
streams.addPropertyChangeListener("content", this);
top = new Composite(parent, SWT.NONE);
top.setLayout(new FillLayout(SWT.HORIZONTAL));
SashForm topSash = new SashForm(top, SWT.SMOOTH);
topSash.setBackground(topSash.getDisplay().getSystemColor(SWT.COLOR_GRAY));
Composite composite = new Composite(topSash, SWT.NONE);
composite.setLayout(new FillLayout(SWT.HORIZONTAL));
@ -272,9 +263,11 @@ public class WaveformViewer implements IWaveformViewer {
nameList.addListener(SWT.Paint, new Listener() {
@Override
public void handleEvent(Event event) {
GC gc = event.gc;
Rectangle rect = ((Canvas) event.widget).getClientArea();
paintNames(gc, rect);
if(!trackVerticalOffset.isEmpty()) {
GC gc = event.gc;
Rectangle rect = ((Canvas) event.widget).getClientArea();
paintNames(gc, rect);
}
}
});
nameList.addMouseListener(nameValueMouseListener);
@ -304,17 +297,19 @@ public class WaveformViewer implements IWaveformViewer {
valueList.addListener(SWT.Paint, new Listener() {
@Override
public void handleEvent(Event event) {
GC gc = event.gc;
Rectangle rect = ((Canvas) event.widget).getClientArea();
paintValues(gc, rect);
if(!trackVerticalOffset.isEmpty()) {
GC gc = event.gc;
Rectangle rect = ((Canvas) event.widget).getClientArea();
paintValues(gc, rect);
}
}
});
valueList.addMouseListener(nameValueMouseListener);
valueListScrolled.setContent(valueList);
waveformCanvas.setMaxTime(1);
waveformCanvas.setMaxTime(1);
waveformCanvas.addMouseListener(waveformMouseListener);
nameListScrolled.getVerticalBar().addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
int y = ((ScrollBar) e.widget).getSelection();
@ -376,23 +371,33 @@ public class WaveformViewer implements IWaveformViewer {
@Override
public void propertyChange(PropertyChangeEvent pce) {
if ("size".equals(pce.getPropertyName()) || "content".equals(pce.getPropertyName())) {
waveformCanvas.getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
updateTracklist();
}
});
if(revealSelected) {
waveformCanvas.getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
update();
waveformCanvas.reveal(currentWaveformSelection.waveform);
valueList.redraw();
nameList.redraw();
}
});
revealSelected=false;
} else
waveformCanvas.getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
update();
}
});
}
}
protected void updateTracklist() {
public void update() {
trackVerticalHeight = 0;
int nameMaxWidth = 0;
int previousHeight = trackVerticalOffset.size() == 0 ? 0 : trackVerticalOffset.lastKey();
IWaveformPainter painter = null;
trackVerticalOffset.clear();
actualValues.clear();
waveformCanvas.clearAllWaveformPainter();
waveformCanvas.clearAllWaveformPainter(false);
boolean even = true;
boolean clearSelection = true;
TextLayout tl = new TextLayout(waveformCanvas.getDisplay());
@ -402,47 +407,39 @@ public class WaveformViewer implements IWaveformViewer {
streamEntry.vOffset=trackVerticalHeight;
clearSelection &= currentWaveformSelection!=null && (streamEntry.waveform != currentWaveformSelection.waveform);
if (streamEntry.isStream()) {
streamEntry.currentValue="";
streamEntry.height *= streamEntry.getStream().getMaxConcurrency();
painter = new StreamPainter(waveformCanvas, even, streamEntry);
actualValues.put(streamEntry.waveform, "");
} else if (streamEntry.isSignal()) {
streamEntry.currentValue="---";
painter = new SignalPainter(waveformCanvas, even, streamEntry);
actualValues.put(streamEntry.waveform, "---");
}
waveformCanvas.addWaveformPainter(painter);
waveformCanvas.addWaveformPainter(painter, false);
trackVerticalOffset.put(trackVerticalHeight, streamEntry);
tl.setText(streamEntry.waveform.getFullName());
nameMaxWidth = Math.max(nameMaxWidth, tl.getBounds().width);
trackVerticalHeight += streamEntry.height;
even = !even;
}
waveformCanvas.syncScrollBars();
nameList.setSize(nameMaxWidth + 15, trackVerticalHeight);
nameListScrolled.setMinSize(nameMaxWidth + 15, trackVerticalHeight);
valueList.setSize(calculateValueWidth(), trackVerticalHeight);
valueListScrolled.setMinSize(calculateValueWidth(), trackVerticalHeight);
nameList.redraw();
updateValueList();
waveformCanvas.redraw();
top.layout(new Control[] { valueList, nameList, waveformCanvas });
if (trackVerticalOffset.isEmpty()){
waveformCanvas.setOrigin(0, 0);
}else if(previousHeight > trackVerticalOffset.lastKey()){
Point o = waveformCanvas.getOrigin();
waveformCanvas.setOrigin(o.x, o.y - (previousHeight - trackVerticalOffset.lastKey()));
}
if(clearSelection) setSelection(new StructuredSelection());
/* System.out.println("updateTracklist() state:");
for(Entry<Integer, IWaveform<? extends IWaveformEvent>> entry: trackVerticalOffset.entrySet()){
System.out.println(" "+entry.getKey()+": " +entry.getValue().getFullName());
}
*/ }
}
private int calculateValueWidth() {
TextLayout tl = new TextLayout(waveformCanvas.getDisplay());
tl.setFont(nameFontB);
int valueMaxWidth = 0;
for (String v : actualValues.values()) {
tl.setText(v);
for (TrackEntry v : streams) {
tl.setText(v.currentValue);
valueMaxWidth = Math.max(valueMaxWidth, tl.getBounds().width);
}
return valueMaxWidth + 15;
@ -450,16 +447,36 @@ public class WaveformViewer implements IWaveformViewer {
private void updateValueList(){
final Long time = getCursorTime();
for(Entry<IWaveform<? extends IWaveformEvent>, String> entry:actualValues.entrySet()){
if(entry.getKey() instanceof ISignal){
ISignalChange event = ((ISignal<?>)entry.getKey()).getWaveformEventsBeforeTime(time);
if(event instanceof ISignalChangeSingle){
entry.setValue("b'"+((ISignalChangeSingle)event).getValue());
} else if(event instanceof ISignalChangeMulti){
entry.setValue("h'"+((ISignalChangeMulti)event).getValue().toHexString());
for(TrackEntry entry:streams){
if(entry.isSignal()){
ISignal<?> signal = (ISignal<?>) entry.waveform;
Object value = signal.getWaveformValueBeforeTime(time);
if(value instanceof BitVector){
BitVector bv = (BitVector) value;
if(bv.getWidth()==1)
entry.currentValue="b'"+bv;
else {
// TODO: same code resides in SignalPainter, fix it
switch(entry.valueDisplay) {
case SIGNED:
entry.currentValue=Long.toString(bv.toSignedValue());
break;
case UNSIGNED:
entry.currentValue=Long.toString(bv.toUnsignedValue());
break;
default:
entry.currentValue="h'"+bv.toHexString();
}
}
} else if(value instanceof Double){
Double val = (Double) value;
if(val>0.001)
entry.currentValue=String.format("%1$,.3f", val);
else
entry.currentValue=Double.toString(val);
}
} else if(entry.getKey() instanceof ITxStream<?>){
ITxStream<?> stream = (ITxStream<?>) entry.getKey();
} else if(entry.isStream()){
ITxStream<?> stream = (ITxStream<?>) entry.waveform;
ITx[] resultsList = new ITx[stream.getMaxConcurrency()];
Entry<Long, List<ITxEvent>> firstTx=stream.getEvents().floorEntry(time);
if(firstTx!=null){
@ -471,23 +488,27 @@ public class WaveformViewer implements IWaveformViewer {
resultsList[tx.getConcurrencyIndex()]= evt.getTransaction();
}
}
firstTx=stream.getEvents().lowerEntry(firstTx.getKey());
firstTx=stream.getEvents().lowerEntry(firstTx.getKey());
}while(firstTx!=null && !isArrayFull(resultsList));
String value=null;
entry.currentValue="";
boolean separator=false;
for(ITx o:resultsList){
if(value==null)
value=new String();
else
value+="|";
if(o!=null) value+=((ITx)o).getGenerator().getName();
if(separator) entry.currentValue+="|";
if(o!=null) entry.currentValue+=((ITx)o).getGenerator().getName();
separator=true;
}
entry.setValue(value);
}
}
}
valueList.redraw();
int width = calculateValueWidth();
valueList.setSize(width, trackVerticalHeight);
valueListScrolled.setMinSize(width, trackVerticalHeight);
valueListScrolled.redraw();
}
private boolean isArrayFull(Object[] array){
for(Object o:array){
if(o==null) return false;
@ -548,11 +569,13 @@ public class WaveformViewer implements IWaveformViewer {
*/
@Override
public ISelection getSelection() {
if (currentTxSelection != null)
return new StructuredSelection(currentTxSelection);
else if (currentWaveformSelection != null)
return new StructuredSelection(currentWaveformSelection.waveform);
else
if (currentTxSelection != null) {
Object[] elem = {currentTxSelection, currentWaveformSelection};
return new StructuredSelection(elem);
} else if (currentWaveformSelection != null) {
Object[] elem = {currentWaveformSelection.waveform, currentWaveformSelection};
return new StructuredSelection(elem);
} else
return new StructuredSelection();
}
@ -583,6 +606,9 @@ public class WaveformViewer implements IWaveformViewer {
TrackEntry trackEntry = getEntryForStream(txSel.getStream());
if(trackEntry==null && addIfNeeded){
trackEntry=new TrackEntry(txSel.getStream());
// compute fallback colors
Color fallbackColors[] = TrackEntry.computeColor(txSel.getStream().getName(), TrackEntry.fallbackColor, TrackEntry.highlightedFallbackColor);
trackEntry.setColor(fallbackColors[0], fallbackColors[1]);
streams.add(trackEntry);
}
currentTxSelection = txSel;
@ -592,6 +618,7 @@ public class WaveformViewer implements IWaveformViewer {
currentWaveformSelection = (TrackEntry) sel;
if(currentTxSelection!=null && currentTxSelection.getStream()!=currentWaveformSelection)
currentTxSelection=null;
selectionChanged = true;
}
}
@ -604,6 +631,7 @@ public class WaveformViewer implements IWaveformViewer {
}
if(currentWaveformSelection!=null) currentWaveformSelection.selected=true;
if (selectionChanged) {
if(currentWaveformSelection!=null) waveformCanvas.reveal(currentWaveformSelection.waveform);
waveformCanvas.setSelected(currentTxSelection);
valueList.redraw();
nameList.redraw();
@ -627,7 +655,16 @@ public class WaveformViewer implements IWaveformViewer {
*/
@Override
public void moveSelection(GotoDirection direction) {
moveSelection(direction, NEXT_PREV_IN_STREAM) ;
if(direction==GotoDirection.NEXT || direction==GotoDirection.PREV)
moveSelection(direction, NEXT_PREV_IN_STREAM) ;
else {
int idx = streams.indexOf(currentWaveformSelection);
if(direction==GotoDirection.UP && idx>0) {
setSelection(new StructuredSelection(streams.get(idx-1)));
} else if(direction==GotoDirection.DOWN && idx<(streams.size()-1)) {
setSelection(new StructuredSelection(streams.get(idx+1)));
}
}
}
/* (non-Javadoc)
@ -723,10 +760,12 @@ public class WaveformViewer implements IWaveformViewer {
public void moveCursor(GotoDirection direction) {
long time = getCursorTime();
NavigableMap<Long, ?> map=null;
if(currentWaveformSelection.isStream()){
map=currentWaveformSelection.getStream().getEvents();
} else if(currentWaveformSelection.isSignal()){
map=currentWaveformSelection.getSignal().getEvents();
if(currentWaveformSelection!=null) {
if(currentWaveformSelection.isStream()){
map=currentWaveformSelection.getStream().getEvents();
} else if(currentWaveformSelection.isSignal()){
map=currentWaveformSelection.getSignal().getEvents();
}
}
if(map!=null){
Entry<Long, ?> entry=direction==GotoDirection.PREV?map.lowerEntry(time):map.higherEntry(time);
@ -735,6 +774,7 @@ public class WaveformViewer implements IWaveformViewer {
setCursorTime(time);
waveformCanvas.reveal(time);
waveformCanvas.redraw();
updateValueList();
}
}
@ -754,17 +794,21 @@ public class WaveformViewer implements IWaveformViewer {
@Override
public void moveSelectedTrack(int i) {
if(currentWaveformSelection!=null){
ITx selectedTx=currentTxSelection;
TrackEntry selectedWaveform=currentWaveformSelection;
int idx = streams.indexOf(currentWaveformSelection);
int newIdx=idx+i;
if(newIdx>=0 && newIdx<streams.size()){
Collections.swap(streams,idx,newIdx);
updateTracklist();
if(selectedTx!=null){
setSelection(new StructuredSelection(new Object[]{selectedTx, selectedWaveform.waveform}));
} else
setSelection(new StructuredSelection(selectedWaveform.waveform));
revealSelected=true;
// update();
// ITx selectedTx=currentTxSelection;
// if(selectedTx!=null){
// setSelection(new StructuredSelection(new Object[]{selectedTx, currentWaveformSelection.waveform}));
// } else {
// setSelection(new StructuredSelection(currentWaveformSelection.waveform));
// }
// waveformCanvas.reveal(currentWaveformSelection.waveform);
// valueList.redraw();
// nameList.redraw();
}
}
}
@ -772,52 +816,56 @@ public class WaveformViewer implements IWaveformViewer {
protected void paintNames(GC gc, Rectangle rect) {
if (streams.size() > 0) {
Integer firstKey = trackVerticalOffset.floorKey(rect.y);
if (firstKey == null)
firstKey = trackVerticalOffset.firstKey();
Integer lastKey = trackVerticalOffset.floorKey(rect.y + rect.height);
Rectangle subArea = new Rectangle(rect.x, 0, rect.width, waveformCanvas.getTrackHeight());
if (lastKey == firstKey) {
TrackEntry trackEntry=trackVerticalOffset.get(firstKey);
IWaveform<? extends IWaveformEvent> w = trackEntry.waveform;
if (w instanceof ITxStream<?>)
subArea.height *= ((ITxStream<?>) w).getMaxConcurrency();
drawTextFormat(gc, subArea, firstKey, w.getFullName(), trackEntry.selected);
} else {
for (Entry<Integer, TrackEntry> entry : trackVerticalOffset.subMap(firstKey, true, lastKey, true).entrySet()) {
IWaveform<? extends IWaveformEvent> w = entry.getValue().waveform;
subArea.height = waveformCanvas.getTrackHeight();
try {
Integer firstKey = trackVerticalOffset.floorKey(rect.y);
if (firstKey == null)
firstKey = trackVerticalOffset.firstKey();
Integer lastKey = trackVerticalOffset.floorKey(rect.y + rect.height);
Rectangle subArea = new Rectangle(rect.x, 0, rect.width, waveformCanvas.getTrackHeight());
if (lastKey == firstKey) {
TrackEntry trackEntry=trackVerticalOffset.get(firstKey);
IWaveform w = trackEntry.waveform;
if (w instanceof ITxStream<?>)
subArea.height *= ((ITxStream<?>) w).getMaxConcurrency();
drawTextFormat(gc, subArea, entry.getKey(), w.getFullName(), entry.getValue().selected);
drawTextFormat(gc, subArea, firstKey, w.getFullName(), trackEntry.selected);
} else {
for (Entry<Integer, TrackEntry> entry : trackVerticalOffset.subMap(firstKey, true, lastKey, true).entrySet()) {
IWaveform w = entry.getValue().waveform;
subArea.height = waveformCanvas.getTrackHeight();
if (w instanceof ITxStream<?>)
subArea.height *= ((ITxStream<?>) w).getMaxConcurrency();
drawTextFormat(gc, subArea, entry.getKey(), w.getFullName(), entry.getValue().selected);
}
}
}
}catch(NoSuchElementException e){}
}
}
protected void paintValues(GC gc, Rectangle rect) {
if (streams.size() > 0) {
Integer firstKey = trackVerticalOffset.floorKey(rect.y);
if (firstKey == null)
firstKey = trackVerticalOffset.firstKey();
Integer lastKey = trackVerticalOffset.floorKey(rect.y + rect.height);
Rectangle subArea = new Rectangle(rect.x, 0, rect.width, waveformCanvas.getTrackHeight());
if (lastKey == firstKey) {
TrackEntry trackEntry=trackVerticalOffset.get(firstKey);
IWaveform<? extends IWaveformEvent> w = trackEntry.waveform;
if (w instanceof ITxStream<?>)
subArea.height *= ((ITxStream<?>) w).getMaxConcurrency();
drawValue(gc, subArea, firstKey, actualValues.get(w), trackEntry.selected);
} else {
for (Entry<Integer, TrackEntry> entry : trackVerticalOffset.subMap(firstKey, true, lastKey, true)
.entrySet()) {
IWaveform<? extends IWaveformEvent> w = entry.getValue().waveform;
subArea.height = waveformCanvas.getTrackHeight();
try {
Integer firstKey = trackVerticalOffset.floorKey(rect.y);
if (firstKey == null)
firstKey = trackVerticalOffset.firstKey();
Integer lastKey = trackVerticalOffset.floorKey(rect.y + rect.height);
Rectangle subArea = new Rectangle(rect.x, 0, rect.width, waveformCanvas.getTrackHeight());
if (lastKey == firstKey) {
TrackEntry trackEntry=trackVerticalOffset.get(firstKey);
IWaveform w = trackEntry.waveform;
if (w instanceof ITxStream<?>)
subArea.height *= ((ITxStream<?>) w).getMaxConcurrency();
drawValue(gc, subArea, entry.getKey(), actualValues.get(w), entry.getValue().selected);
drawValue(gc, subArea, firstKey, trackEntry.currentValue, trackEntry.selected);
} else {
for (Entry<Integer, TrackEntry> entry : trackVerticalOffset.subMap(firstKey, true, lastKey, true)
.entrySet()) {
IWaveform w = entry.getValue().waveform;
subArea.height = waveformCanvas.getTrackHeight();
if (w instanceof ITxStream<?>)
subArea.height *= ((ITxStream<?>) w).getMaxConcurrency();
drawValue(gc, subArea, entry.getKey(), entry.getValue().currentValue, entry.getValue().selected);
}
}
}
}catch(NoSuchElementException e){}
}
}
@ -846,11 +894,11 @@ public class WaveformViewer implements IWaveformViewer {
gc.drawText(value, subArea.x + 5, subArea.y + yOffset + (waveformCanvas.getTrackHeight() - size.y) / 2, true);
}
public void setHighliteRelation(RelationType relationType){
this.waveformCanvas.setHighliteRelation(relationType);
}
public void setHighliteRelation(RelationType relationType){
this.waveformCanvas.setHighliteRelation(relationType);
}
/* (non-Javadoc)
* @see com.minres.scviewer.database.swt.IWaveformPanel#getMaxTime()
*/
@ -918,8 +966,8 @@ public class WaveformViewer implements IWaveformViewer {
* @see com.minres.scviewer.database.swt.IWaveformPanel#getActMarkerTime()
*/
@Override
public long getSelectedMarkerTime(){
return getMarkerTime(selectedMarker);
public int getSelectedMarkerId(){
return selectedMarker;
}
@Override
@ -982,7 +1030,7 @@ public class WaveformViewer implements IWaveformViewer {
else
streams.add(tgtIdx, srcWave);
currentWaveformSelection=srcWave;
updateTracklist();
update();
} else if(source instanceof CursorPainter){
((CursorPainter)source).setTime(0);
updateValueList();
@ -1001,7 +1049,7 @@ public class WaveformViewer implements IWaveformViewer {
});
}
public TrackEntry getEntryForStream(IWaveform<?> source) {
public TrackEntry getEntryForStream(IWaveform source) {
for(TrackEntry trackEntry:streams)
if(trackEntry.waveform.equals(source)) return trackEntry;
return null;
@ -1141,7 +1189,8 @@ public class WaveformViewer implements IWaveformViewer {
public String getScaledTime(long time) {
StringBuilder sb = new StringBuilder();
Double dTime=new Double(time);
return sb.append(dTime/waveformCanvas.getScaleFactorPow10()).append(waveformCanvas.getUnitStr()).toString();
Double scaledTime = dTime/waveformCanvas.getScaleFactorPow10();
return sb.append(df.format(scaledTime)).append(waveformCanvas.getUnitStr()).toString();
}
/* (non-Javadoc)
@ -1149,10 +1198,10 @@ public class WaveformViewer implements IWaveformViewer {
*/
@Override
public String[] getZoomLevels(){
String[] res = new String[WaveformCanvas.unitMultiplier.length*WaveformCanvas.unitString.length];
String[] res = new String[Constants.unitMultiplier.length*Constants.unitString.length];
int index=0;
for(String unit:WaveformCanvas.unitString){
for(int factor:WaveformCanvas.unitMultiplier){
for(String unit:Constants.unitString){
for(int factor:Constants.unitMultiplier){
res[index++]= new Integer(factor).toString()+unit;
}
}
@ -1163,4 +1212,48 @@ public class WaveformViewer implements IWaveformViewer {
public void setColors(HashMap<WaveformColors, RGB> colourMap) {
waveformCanvas.initColors(colourMap);
}
@Override
public long getBaselineTime() {
return -waveformCanvas.getScaleFactorPow10()*waveformCanvas.getOrigin().x;
}
@Override
public void setBaselineTime(Long time) {
Point origin = waveformCanvas.getOrigin();
origin.x=(int) (-time/waveformCanvas.getScaleFactorPow10());
waveformCanvas.setOrigin(origin);
}
@Override
public void scrollHorizontal(int percent) {
if(percent<-100) percent=-100;
if(percent>100) percent=100;
int diff = (waveformCanvas.getWidth()*percent)/100;
// ScrollBar sb = waveformCanvas.getHorizontalBar();
// int x = sb.getSelection();
// System.out.println("Setting sb to "+ (x+diff));
// if((x+diff)>0)
// sb.setSelection(x+diff);
// else
// sb.setSelection(0);
Point o = waveformCanvas.getOrigin();
waveformCanvas.setOrigin(o.x-diff, o.y);
waveformCanvas.redraw();
}
public void asyncUpdate(Widget widget) {
widget.getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
waveformCanvas.redraw();
updateValueList();
}
});
}
/// probably not the way it should be done
public void addDisposeListener( DisposeListener listener ) {
waveformCanvas.addDisposeListener(listener);
}
}

View File

@ -1,6 +1,6 @@
<?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-1.7"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>

View File

@ -1,7 +1,7 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.7
org.eclipse.jdt.core.compiler.source=1.8

View File

@ -2,9 +2,10 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Database UI
Bundle-SymbolicName: com.minres.scviewer.database.ui
Bundle-Version: 1.0.0.qualifier
Bundle-Version: 2.0.0.qualifier
Bundle-Vendor: MINRES Technologies GmbH
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Export-Package: com.minres.scviewer.database.ui
Require-Bundle: com.minres.scviewer.database,
org.eclipse.jface
Automatic-Module-Name: com.minres.scviewer.database.ui

View File

@ -1,12 +1,12 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>com.minres.scviewer.database.ui</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>2.0.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>2.0.0-SNAPSHOT</version>
<relativePath>../com.minres.scviewer.parent</relativePath>
</parent>
</project>

View File

@ -17,6 +17,7 @@ import java.util.List;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Control;
@ -34,6 +35,8 @@ public interface IWaveformViewer extends PropertyChangeListener, ISelectionProvi
public void addSelectionChangedListener(ISelectionChangedListener listener);
public void removeSelectionChangedListener(ISelectionChangedListener listener);
public void update();
public Control getControl();
@ -57,7 +60,7 @@ public interface IWaveformViewer extends PropertyChangeListener, ISelectionProvi
public List<TrackEntry> getStreamList();
public TrackEntry getEntryForStream(IWaveform<?> source);
public TrackEntry getEntryForStream(IWaveform source);
public void moveSelectedTrack(int i);
@ -77,7 +80,7 @@ public interface IWaveformViewer extends PropertyChangeListener, ISelectionProvi
public long getCursorTime();
public long getSelectedMarkerTime();
public int getSelectedMarkerId();
public long getMarkerTime(int index);
@ -96,4 +99,12 @@ public interface IWaveformViewer extends PropertyChangeListener, ISelectionProvi
public List<ICursor> getCursorList();
public void setColors(HashMap<WaveformColors, RGB> colourMap);
public long getBaselineTime();
public void setBaselineTime(Long scale);
public void scrollHorizontal(int percent);
public void addDisposeListener( DisposeListener listener );
}

View File

@ -10,15 +10,97 @@
*******************************************************************************/
package com.minres.scviewer.database.ui;
import java.awt.Color;
import com.minres.scviewer.database.ISignal;
import com.minres.scviewer.database.ISignalChange;
import com.minres.scviewer.database.ITxEvent;
import com.minres.scviewer.database.ITxStream;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.IWaveformEvent;
public class TrackEntry {
final public IWaveform<? extends IWaveformEvent> waveform;
// color info
public static Color fallbackColor = new Color(200,0,0);
public static Color highlightedFallbackColor = new Color(255,0,0);
private Color[]signalColors;
// list of random colors
private static Color[][] randomColors = {
{ new Color( 170, 66, 37 ), new Color ( 190, 66, 37 ) },
{ new Color( 96, 74, 110 ), new Color ( 96, 74, 130 ) },
{ new Color( 133, 105, 128 ), new Color ( 153, 105, 128 ) },
{ new Color( 0, 126, 135 ), new Color ( 0, 126, 155 ) },
{ new Color( 243, 146, 75 ), new Color ( 255, 146, 75 ) },
{ new Color( 206, 135, 163 ), new Color ( 226, 135, 163 ) },
{ new Color( 124, 103, 74 ), new Color ( 144, 103, 74 ) },
{ new Color( 194, 187, 169 ), new Color ( 214, 187, 169 ) },
{ new Color( 104, 73, 71 ), new Color ( 124, 73, 71 ) },
{ new Color( 75, 196, 213 ), new Color ( 75, 196, 233 ) },
{ new Color( 206, 232, 229 ), new Color ( 206, 252, 229 ) },
{ new Color( 169, 221, 199 ), new Color ( 169, 241, 199 ) },
{ new Color( 100, 165, 197 ), new Color ( 100, 165, 217 ) },
{ new Color( 150, 147, 178 ), new Color ( 150, 147, 198 ) },
{ new Color( 200, 222, 182 ), new Color ( 200, 242, 182 ) },
{ new Color( 147, 208, 197 ), new Color ( 147, 228, 197 ) }
};
public static Color[] computeColor (String streamValue, Color fallback, Color highlightedFallback) {
Color[]result = new Color[2];
result[0] = fallback;
result[1] = highlightedFallback;
// assign colors to standard values
if (streamValue.contains("read")){
result[0] = new Color(86,174,53);
result[1] = new Color (86,194,53);
}else if (streamValue.contains("rdata")){
result[0] = new Color(138,151,71);
result[1] = new Color (138,171,71);
}else if (streamValue.contains("addr")){
result[0] = new Color(233,187,68);
result[1] = new Color (233,207,68);
}else if (streamValue.contains("write")){
result[0] = new Color(1,128,191);
result[1] = new Color (1,128,211);
}else if (streamValue.contains("wdata")){
result[0] = new Color(2,181,160);
result[1] = new Color (2,201,160);
}else {
// assign "random" color here, one name always results in the same color!
if( randomColors.length > 0 ) {
int index = Math.abs(streamValue.hashCode()) % randomColors.length;
result[0] = randomColors[index][0];
result[1] = randomColors[index][1];
}
}
return result;
}
public void setColor(Color changedColor, Color highlightColor) {
signalColors[0] = changedColor;
signalColors[1] = highlightColor;
}
public Color[] getColors() {
return signalColors;
}
public enum ValueDisplay {
DEFAULT, SIGNED, UNSIGNED
}
public enum WaveDisplay {
DEFAULT, STEP_WISE, CONTINOUS
}
final public IWaveform waveform;
public int vOffset;
@ -26,11 +108,20 @@ public class TrackEntry {
public boolean selected;
public TrackEntry(IWaveform<? extends IWaveformEvent> waveform) {
public String currentValue="";
public ValueDisplay valueDisplay = ValueDisplay.DEFAULT;
public WaveDisplay waveDisplay = WaveDisplay.DEFAULT;
public TrackEntry(IWaveform waveform) {
this.waveform = waveform;
vOffset=0;
height=0;
selected=false;
signalColors = new Color[2];
signalColors[0] = fallbackColor;
signalColors[1] = highlightedFallbackColor;
}
public boolean isStream(){
@ -45,7 +136,7 @@ public class TrackEntry {
return waveform instanceof ISignal<?>;
}
public ISignal<? extends ISignalChange> getSignal(){
public ISignal<?> getSignal(){
return (ISignal<?>) waveform;
}

View File

@ -14,7 +14,7 @@ public enum WaveformColors {
LINE, LINE_HIGHLITE,
TRACK_BG_EVEN, TRACK_BG_ODD, TRACK_BG_HIGHLITE,
TX_BG, TX_BG_HIGHLITE, TX_BORDER,
SIGNAL0, SIGNAL1, SIGNALZ, SIGNALX, SIGNAL_TEXT,
SIGNAL0, SIGNAL1, SIGNALZ, SIGNALX, SIGNALU, SIGNAL_TEXT, SIGNAL_REAL, SIGNAL_NAN,
CURSOR, CURSOR_DRAG, CURSOR_TEXT,
MARKER, MARKER_TEXT, REL_ARROW, REL_ARROW_HIGHLITE
}

View File

@ -1,7 +1,7 @@
<?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-1.7"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src/"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

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

View File

@ -1,7 +1,7 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.7
org.eclipse.jdt.core.compiler.source=1.8

View File

@ -2,9 +2,9 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: VCD signal database
Bundle-SymbolicName: com.minres.scviewer.database.vcd
Bundle-Version: 1.0.0.qualifier
Bundle-Version: 2.0.2.qualifier
Bundle-Vendor: MINRES Technologies GmbH
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0",
org.eclipse.equinox.util;bundle-version="1.0.500",
org.eclipse.equinox.ds;bundle-version="1.4.200",
@ -13,3 +13,4 @@ Require-Bundle: com.minres.scviewer.database;bundle-version="1.0.0",
Service-Component: OSGI-INF/component.xml
Bundle-ActivationPolicy: lazy
Import-Package: com.google.common.collect
Automatic-Module-Name: com.minres.scviewer.database.vcd

View File

@ -1,11 +1,12 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>com.minres.scviewer.database.vcd</artifactId>
<version>2.0.2-SNAPSHOT</version>
<parent>
<groupId>com.minres.scviewer</groupId>
<artifactId>com.minres.scviewer.parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>2.0.0-SNAPSHOT</version>
<relativePath>../com.minres.scviewer.parent</relativePath>
</parent>
<packaging>eclipse-plugin</packaging>
</project>
</project>

View File

@ -12,9 +12,8 @@ package com.minres.scviewer.database.vcd;
import com.minres.scviewer.database.BitVector;
// TODO: Auto-generated Javadoc
/**
* The Interface ITraceBuilder.
* The Interface IVCDDatabaseBuilder. It allows to add VCD events into the database
*/
public interface IVCDDatabaseBuilder {
@ -35,26 +34,35 @@ public interface IVCDDatabaseBuilder {
*
* @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
* @return the integer
* @param width the width, -1 equals real, 0... is a bit vector
* @return the net id
*/
public Integer newNet(String netName, int i, int width) ;
/**
* Gets the net width.
*
* @param intValue the int value
* @return the net width
* @param intValue the net id
* @return the net width, -1 means a real-valued net
*/
public int getNetWidth(int intValue);
public int getNetWidth(int netId);
/**
* Append transition.
*
* @param signalId the int value
* @param netId the int value
* @param currentTime the current time in ps
* @param decodedValues the decoded values
*/
public void appendTransition(int signalId, long currentTime, BitVector decodedValues);
public void appendTransition(int netId, long currentTime, BitVector decodedValue);
/**
* Append transition.
*
* @param netId the int value
* @param currentTime the current time in ps
* @param decodedValue the decoded values
*/
public void appendTransition(int netId, long currentTime, double decodedValue);
}

View File

@ -12,53 +12,67 @@ package com.minres.scviewer.database.vcd;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.NavigableMap;
import java.util.Stack;
import java.util.TreeMap;
import java.util.Vector;
import java.util.zip.GZIPInputStream;
import com.minres.scviewer.database.BitVector;
import com.minres.scviewer.database.ISignal;
import com.minres.scviewer.database.ISignalChange;
import com.minres.scviewer.database.ISignalChangeMulti;
import com.minres.scviewer.database.ISignalChangeSingle;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.IWaveformDb;
import com.minres.scviewer.database.IWaveformDbLoader;
import com.minres.scviewer.database.IWaveformEvent;
import com.minres.scviewer.database.InputFormatException;
import com.minres.scviewer.database.RelationType;
// TODO: Auto-generated Javadoc
/**
* The Class VCDDb.
*/
public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
/** The Constant TIME_RES. */
private static final Long TIME_RES = 1000L; // ps;
/** The db. */
private IWaveformDb db;
/** The module stack. */
private Stack<String> moduleStack;
/** The signals. */
private List<IWaveform<? extends IWaveformEvent>> signals;
private List<IWaveform> signals;
/** The max time. */
private long maxTime;
/**
* Instantiates a new VCD db.
*
* @param netName the net name
*/
public VCDDbLoader() {
}
private byte[] x = "$date".getBytes();
private static boolean isGzipped(File f) {
InputStream is = null;
try {
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;
} finally {
try { is.close();} catch (IOException e) { }
}
}
/* (non-Javadoc)
* @see com.minres.scviewer.database.ITrDb#load(java.io.File)
@ -67,35 +81,36 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
@Override
public boolean load(IWaveformDb db, File file) throws Exception {
this.db=db;
this.maxTime=0;
String name = file.getCanonicalFile().getName();
if(!(name.endsWith(".vcd") ||
name.endsWith(".vcdz") ||
name.endsWith(".vcdgz") ||
name.endsWith(".vcd.gz")) )
return false;
signals = new Vector<IWaveform>();
moduleStack= new Stack<String>();
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[x.length];
int read = fis.read(buffer, 0, x.length);
fis.close();
if (read == x.length)
for (int i = 0; i < x.length; i++)
if (buffer[i] != x[i])
return false;
signals = new Vector<IWaveform<? extends IWaveformEvent>>();
moduleStack= new Stack<String>();
boolean res = new VCDFileParser(false).load(new FileInputStream(file), this);
boolean res = new VCDFileParser(false).load(isGzipped(file)?new GZIPInputStream(fis):fis, this);
moduleStack=null;
if(!res) throw new InputFormatException();
// calculate max time of database
for(IWaveform<? extends IWaveformEvent> waveform:signals)
maxTime= Math.max(maxTime, ((ISignal<? extends ISignalChange>)waveform).getEvents().lastKey());
for(IWaveform waveform:signals) {
NavigableMap<Long, ?> events =((ISignal<?>)waveform).getEvents();
if(events.size()>0)
maxTime= Math.max(maxTime, events.lastKey());
}
// extend signals to hav a last value set at max time
for(IWaveform<? extends IWaveformEvent> waveform:signals){
TreeMap<Long,? extends ISignalChange> events = ((VCDSignal<? extends ISignalChange>)waveform).values;
if(events.lastKey()<maxTime){
ISignalChange x = events.lastEntry().getValue();
if(x instanceof ISignalChangeSingle)
((VCDSignal<ISignalChangeSingle>)waveform).values.put(maxTime,
new VCDSignalChangeSingle(maxTime, ((ISignalChangeSingle)x).getValue()));
else
if(x instanceof ISignalChangeMulti)
((VCDSignal<ISignalChangeMulti>)waveform).values.put(maxTime,
new VCDSignalChangeMulti(maxTime, ((ISignalChangeMulti)x).getValue()));
for(IWaveform s:signals){
if(s instanceof VCDSignal<?>) {
TreeMap<Long,?> events = (TreeMap<Long, ?>) ((VCDSignal<?>)s).getEvents();
if(events.size()>0 && events.lastKey()<maxTime){
Object val = events.lastEntry().getValue();
if(val instanceof BitVector) {
((VCDSignal<BitVector>)s).addSignalChange(maxTime, (BitVector) val);
} else if(val instanceof Double)
((VCDSignal<Double>)s).addSignalChange(maxTime, (Double) val);
}
}
}
return true;
@ -113,7 +128,7 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
* @see com.minres.scviewer.database.ITrDb#getAllWaves()
*/
@Override
public List<IWaveform<? extends IWaveformEvent>> getAllWaves() {
public List<IWaveform> getAllWaves() {
return signals;
}
@ -122,9 +137,9 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
*/
@Override
public void enterModule(String tokenString) {
if(moduleStack.isEmpty())
moduleStack.push(tokenString);
else
if(moduleStack.isEmpty()) {
if("SystemC".compareTo(tokenString)!=0) moduleStack.push(tokenString);
} else
moduleStack.push(moduleStack.peek()+"."+tokenString);
}
@ -142,17 +157,17 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
*/
@SuppressWarnings("unchecked")
@Override
public Integer newNet(String netName, int i, int width) {
public Integer newNet(String name, int i, int width) {
String netName = moduleStack.empty()? name: moduleStack.lastElement()+"."+name;
int id = signals.size();
VCDSignal<? extends IWaveformEvent> signal;
if(width==1){
signal = i<0 ? new VCDSignal<ISignalChangeSingle>(db, id, netName) :
new VCDSignal<ISignalChangeSingle>((VCDSignal<ISignalChangeSingle>)signals.get(i), id, netName);
} else {
signal = i<0 ? new VCDSignal<ISignalChangeMulti>(db, id, netName, width) :
new VCDSignal<ISignalChangeMulti>((VCDSignal<VCDSignalChangeMulti>)signals.get(i), id, netName);
};
signals.add(signal);
assert(width>=0);
if(width==0) {
signals.add( i<0 ? new VCDSignal<Double>(db, id, netName, width) :
new VCDSignal<Double>((VCDSignal<Double>)signals.get(i), id, netName));
} else if(width>0){
signals.add( i<0 ? new VCDSignal<BitVector>(db, id, netName, width) :
new VCDSignal<BitVector>((VCDSignal<BitVector>)signals.get(i), id, netName));
}
return id;
}
@ -161,7 +176,7 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
*/
@Override
public int getNetWidth(int intValue) {
VCDSignal<? extends IWaveformEvent> signal = (VCDSignal<? extends IWaveformEvent>) signals.get(intValue);
VCDSignal<?> signal = (VCDSignal<?>) signals.get(intValue);
return signal.getWidth();
}
@ -170,16 +185,28 @@ public class VCDDbLoader implements IWaveformDbLoader, IVCDDatabaseBuilder {
*/
@SuppressWarnings("unchecked")
@Override
public void appendTransition(int signalId, long currentTime, BitVector decodedValues) {
VCDSignal<? extends IWaveformEvent> signal = (VCDSignal<? extends IWaveformEvent>) signals.get(signalId);
public void appendTransition(int signalId, long currentTime, BitVector value) {
VCDSignal<BitVector> signal = (VCDSignal<BitVector>) signals.get(signalId);
Long time = currentTime* TIME_RES;
if(signal.getWidth()==1){
((VCDSignal<ISignalChangeSingle>)signal).values.put(time, new VCDSignalChangeSingle(time, decodedValues.getValue()[0]));
} else {
((VCDSignal<VCDSignalChangeMulti>)signal).values.put(time, new VCDSignalChangeMulti(time, decodedValues));
signal.getEvents().put(time, value);
}
/* (non-Javadoc)
* @see com.minres.scviewer.database.vcd.ITraceBuilder#appendTransition(int, long, com.minres.scviewer.database.vcd.BitVector)
*/
@SuppressWarnings("unchecked")
@Override
public void appendTransition(int signalId, long currentTime, double value) {
VCDSignal<?> signal = (VCDSignal<?>) signals.get(signalId);
Long time = currentTime* TIME_RES;
if(signal.getWidth()==0){
((VCDSignal<Double>)signal).getEvents().put(time, value);
}
}
/* (non-Javadoc)
* @see com.minres.scviewer.database.IWaveformDbLoader#getAllRelationTypes()
*/
@Override
public Collection<RelationType> getAllRelationTypes(){
return Collections.emptyList();

View File

@ -13,6 +13,7 @@ package com.minres.scviewer.database.vcd;
import java.io.*;
import java.util.*;
import com.minres.scviewer.database.BitValue;
import com.minres.scviewer.database.BitVector;
class VCDFileParser {
@ -21,10 +22,12 @@ class VCDFileParser {
private HashMap<String, Integer> nameToNetMap = new HashMap<String, Integer>();
private long picoSecondsPerIncrement;
private boolean stripNetWidth;
private boolean replaceColon;
long currentTime;
public VCDFileParser(boolean stripNetWidth) {
this.stripNetWidth=stripNetWidth;
this.replaceColon=false;
}
public boolean load(InputStream is, IVCDDatabaseBuilder builder) {
@ -61,9 +64,11 @@ class VCDFileParser {
private void parseVar() throws Exception {
nextToken(); // type
String type = tokenizer.sval;
nextToken(); // size
int width = Integer.parseInt(tokenizer.sval);
if("real".equals(type))
width=0;
nextToken();
String id = tokenizer.sval;
nextToken();
@ -73,11 +78,17 @@ class VCDFileParser {
}
Integer net = nameToNetMap.get(id);
if (net == null) {
// We've never seen this net before
if (net == null) { // We've never seen this net before
int openBracket = netName.indexOf('[');
if(stripNetWidth){
int openBracket = netName.indexOf('[');
if (openBracket != -1) netName = netName.substring(0, openBracket);
openBracket = -1;
}
if(replaceColon) {
if (openBracket != -1) {
netName = netName.substring(0, openBracket).replaceAll(":", ".")+netName.substring(openBracket);
} else
netName=netName.replaceAll(":", ".");
}
nameToNetMap.put(id, traceBuilder.newNet(netName, -1, width));
} else {
@ -86,6 +97,17 @@ class VCDFileParser {
}
}
private void parseComment() throws Exception {
nextToken();
String s = tokenizer.sval;
nextToken();
while(!tokenizer.sval.equals("$end")){
s+=" "+tokenizer.sval;
nextToken();
}
replaceColon|=s.contains("ARTERIS Architecture");
}
private void parseTimescale() throws Exception {
nextToken();
String s = tokenizer.sval;
@ -129,6 +151,8 @@ class VCDFileParser {
parseUpscope();
else if (tokenizer.sval.equals("$timescale"))
parseTimescale();
else if (tokenizer.sval.equals("$comment"))
parseComment();
else if (tokenizer.sval.equals("$enddefinitions")) {
match("$end");
return false;
@ -153,7 +177,8 @@ class VCDFileParser {
} while (!tokenizer.sval.equals("$end"));
return true;
}
if (tokenizer.sval.equals("$dumpvars") || tokenizer.sval.equals("$end")) return true;
if (tokenizer.sval.equals("$dumpvars") || tokenizer.sval.equals("$end"))
return true;
String value, id;
if (tokenizer.sval.charAt(0) == 'b') {
// Multiple value net. Value appears first, followed by space,
@ -161,6 +186,12 @@ class VCDFileParser {
value = tokenizer.sval.substring(1);
nextToken();
id = tokenizer.sval;
}else if (tokenizer.sval.charAt(0) == 'r') {
// Multiple value net. Value appears first, followed by space,
// then identifier
value = tokenizer.sval.substring(1);
nextToken();
id = tokenizer.sval;
} else {
// Single value net. identifier first, then value, no space.
value = tokenizer.sval.substring(0, 1);
@ -174,39 +205,50 @@ class VCDFileParser {
}
int netWidth = traceBuilder.getNetWidth(net);
BitVector decodedValues = new BitVector(netWidth);
if (value.equals("z") && netWidth > 1) {
for (int i = 0; i < netWidth; i++)
decodedValues.setValue(i, BitVector.VALUE_Z);
} else if (value.equals("x") && netWidth > 1) {
for (int i = 0; i < netWidth; i++)
decodedValues.setValue(i, BitVector.VALUE_X);
if(netWidth==0) {
if("nan".equals(value))
traceBuilder.appendTransition(net, currentTime, Double.NaN);
else
traceBuilder.appendTransition(net, currentTime, Double.parseDouble(value));
} else {
int stringIndex = 0;
for (int convertedIndex = netWidth - value.length(); convertedIndex < netWidth; convertedIndex++) {
switch (value.charAt(stringIndex++)) {
case 'z':
decodedValues.setValue(convertedIndex, BitVector.VALUE_Z);
break;
BitVector decodedValues = new BitVector(netWidth);
if (value.equals("z") && netWidth > 1) {
for (int i = 0; i < netWidth; i++)
decodedValues.setValue(i, BitValue.Z);
} else if (value.equals("x") && netWidth > 1) {
for (int i = 0; i < netWidth; i++)
decodedValues.setValue(i, BitValue.X);
} else {
int stringIndex = 0;
for (int convertedIndex = netWidth -1; convertedIndex >=0; convertedIndex--) {
if(convertedIndex<value.length()) {
switch (value.charAt(stringIndex++)) {
case 'z':
decodedValues.setValue(convertedIndex, BitValue.Z);
break;
case '1':
decodedValues.setValue(convertedIndex, BitVector.VALUE_1);
break;
case '1':
decodedValues.setValue(convertedIndex, BitValue.ONE);
break;
case '0':
decodedValues.setValue(convertedIndex, BitVector.VALUE_0);
break;
case '0':
decodedValues.setValue(convertedIndex, BitValue.ZERO);
break;
case 'x':
decodedValues.setValue(convertedIndex, BitVector.VALUE_X);
break;
case 'x':
decodedValues.setValue(convertedIndex, BitValue.X);
break;
default:
decodedValues.setValue(convertedIndex, BitVector.VALUE_X);
default:
decodedValues.setValue(convertedIndex, BitValue.X);
}
} else {
decodedValues.setValue(convertedIndex, BitValue.ZERO);
}
}
}
traceBuilder.appendTransition(net, currentTime, decodedValues);
}
traceBuilder.appendTransition(net, currentTime, decodedValues);
}
return true;
}

View File

@ -10,17 +10,17 @@
*******************************************************************************/
package com.minres.scviewer.database.vcd;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.TreeMap;
import com.minres.scviewer.database.HierNode;
import com.minres.scviewer.database.ISignal;
import com.minres.scviewer.database.ISignalChange;
import com.minres.scviewer.database.IWaveform;
import com.minres.scviewer.database.IWaveformDb;
import com.minres.scviewer.database.IWaveformEvent;
public class VCDSignal<T extends ISignalChange> extends HierNode implements ISignal<T> {
public class VCDSignal<T> extends HierNode implements ISignal<T> {
private long id;
@ -29,10 +29,12 @@ public class VCDSignal<T extends ISignalChange> extends HierNode implements ISig
private final String kind = "signal";
private final int width;
private final T dummy = null;
private IWaveformDb db;
TreeMap<Long, T> values;
private TreeMap<Long, T> values;
public VCDSignal(IWaveformDb db, String name) {
this(db, 0, name, 1);
@ -52,7 +54,7 @@ public class VCDSignal<T extends ISignalChange> extends HierNode implements ISig
}
@SuppressWarnings("unchecked")
public VCDSignal(IWaveform<? extends ISignalChange> other, int id, String name) {
public VCDSignal(ISignal<T> other, int id, String name) {
super(name);
fullName=name;
this.id=id;
@ -90,8 +92,8 @@ public class VCDSignal<T extends ISignalChange> extends HierNode implements ISig
return db;
}
public void addSignalChange(T change){
values.put(change.getTime(), change);
public void addSignalChange(Long time, T value){
values.put(time, value);
}
@Override
@ -100,20 +102,29 @@ public class VCDSignal<T extends ISignalChange> extends HierNode implements ISig
}
@Override
public T getWaveformEventsAtTime(Long time) {
public T getWaveformValueAtTime(Long time) {
return values.get(time);
}
@Override
public T getWaveformEventsBeforeTime(Long time) {
return values.floorEntry(time).getValue();
public T getWaveformValueBeforeTime(Long time) {
Entry<Long, T> e = values.floorEntry(time);
if(e==null)
return null;
else
return values.floorEntry(time).getValue();
}
@Override
public Boolean equals(IWaveform<? extends IWaveformEvent> other) {
public Boolean equals(IWaveform other) {
return(other instanceof VCDSignal<?> && this.getId()==other.getId());
}
@Override
public Class<?> getType() {
return dummy.getClass();
}
}

View File

@ -1,43 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015 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.vcd;
import com.minres.scviewer.database.BitVector;
import com.minres.scviewer.database.ISignalChangeMulti;
import com.minres.scviewer.database.SignalChange;
public class VCDSignalChangeMulti extends SignalChange implements ISignalChangeMulti, Cloneable {
private BitVector value;
public VCDSignalChangeMulti(Long time) {
super(time);
}
public VCDSignalChangeMulti(Long time, BitVector decodedValues) {
super(time);
this.value=decodedValues;
}
public BitVector getValue() {
return value;
}
public void setValue(BitVector value) {
this.value = value;
}
@Override
public String toString() {
return value.toHexString()+"@"+getTime();
}
}

View File

@ -1,37 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015 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.vcd;
import com.minres.scviewer.database.ISignalChangeSingle;
import com.minres.scviewer.database.SignalChange;
public class VCDSignalChangeSingle extends SignalChange implements ISignalChangeSingle, Cloneable {
private char value;
public VCDSignalChangeSingle(Long time, char value) {
super(time);
this.value=value;
}
public char getValue() {
return value;
}
public void setValue(char value) {
this.value = value;
}
@Override
public String toString() {
return value+"@"+getTime();
}
}

View File

@ -1,7 +1,7 @@
<?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-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
<classpathentry kind="src" path="src/"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

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