From 92a5e5f4a7da487dc8c7b102271d4383b8811cbc Mon Sep 17 00:00:00 2001 From: Markus Quaritsch <markus.quaritsch@tugraz.at> Date: Thu, 26 Apr 2018 14:45:32 +0200 Subject: [PATCH] implementation of VTP Report refactoring: move IVectoHash interface to vectocommon project, provide methods for reading manufacturer report in a dedicated class (used by VTP mode and hashing tool) --- HashingCmd/Program.cs | 1 + HashingTool/Helper/HashingHelper.cs | 1 + .../UserControl/ManufacturerReportXMLFile.cs | 62 +- .../ViewModel/UserControl/ReportXMLFile.cs | 32 +- .../ViewModel/UserControl/VectoJobFile.cs | 1 + .../VerifyComponentInputDataViewModel.cs | 1 + VECTO/GUI/MainForm.vb | 3698 +++++++++-------- VECTO/Input Files/Engine.vb | 4 +- VECTO/Input Files/Gearbox.vb | 4 +- VECTO/Input Files/VectoEPTPJob.vb | 7 + VECTO/Input Files/Vehicle.vb | 4 +- .../Hashing}/IVectoHash.cs | 333 +- .../Hashing}/VectoComponents.cs | 222 +- .../InputData/DeclarationInputData.cs | 2 +- .../InputData/VTPDeclarationInputData.cs | 70 + VectoCommon/VectoCommon/Utils/SI.cs | 3146 +++++++------- VectoCommon/VectoCommon/VectoCommon.csproj | 2 + VectoCommon/VectoHashing/VectoHash.cs | 1 + VectoCommon/VectoHashing/VectoHashing.csproj | 14 +- VectoCommon/VectoHashingTest/VectoHashTest.cs | 1 + .../FileIO/JSON/JSONComponentInputData.cs | 2 +- .../InputData/FileIO/JSON/JSONEngineData.cs | 4 +- .../InputData/FileIO/JSON/JSONGearboxData.cs | 4 +- .../InputData/FileIO/JSON/JSONInputData.cs | 235 +- .../InputData/FileIO/JSON/JSONVehicleData.cs | 4 +- ...ractDeclarationXMLComponentDataProvider.cs | 20 +- .../XMLDeclarationInputDataProvider.cs | 28 +- .../XMLDeclarationVehicleDataProvider.cs | 3 +- .../XMLManufacturerReportReader.cs | 72 + ...ractEngineeringXMLComponentDataProvider.cs | 4 +- .../VectoCore/InputData/Impl/InputData.cs | 2 +- .../AbstractSimulationDataAdapter.cs | 14 +- .../DeclarationDataAdapter.cs | 2 +- .../Reader/DrivingCycleDataReader.cs | 86 +- .../DeclarationVTPModeVectoRunDataFactory.cs | 12 +- .../Models/Declaration/DeclarationData.cs | 6 + .../Models/Simulation/Data/VectoRunData.cs | 17 +- .../VectoCore/OutputData/DeclarationReport.cs | 10 +- VectoCore/VectoCore/OutputData/VTPReport.cs | 10 +- .../OutputData/XML/XMLCustomerReport.cs | 2 +- .../OutputData/XML/XMLDeclarationReport.cs | 2 +- .../OutputData/XML/XMLManufacturerReport.cs | 2 +- .../VectoCore/OutputData/XML/XMLVTPReport.cs | 375 +- .../Resources/XSD/VectoVTPReport.xsd | 24 +- VectoCore/VectoCore/VectoCore.csproj | 1 + .../SimulationComponentData/ValidationTest.cs | 2 +- ...or_4x2_vehicle-class-5_Generic vehicle.xml | 98 +- .../class_5_generic vehicle_DECL.vecto | 1 + .../Utils/MockEngineDataProvider.cs | 2 +- 49 files changed, 4618 insertions(+), 4032 deletions(-) rename VectoCommon/{VectoHashing => VectoCommon/Hashing}/IVectoHash.cs (98%) rename VectoCommon/{VectoHashing => VectoCommon/Hashing}/VectoComponents.cs (96%) create mode 100644 VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLManufacturerReportReader.cs diff --git a/HashingCmd/Program.cs b/HashingCmd/Program.cs index 89e4fa8963..785345ff8f 100644 --- a/HashingCmd/Program.cs +++ b/HashingCmd/Program.cs @@ -37,6 +37,7 @@ using System.Reflection; using System.Text; using System.Xml; using System.Xml.Schema; +using TUGraz.VectoCommon.Hashing; using TUGraz.VectoCore.Utils; using TUGraz.VectoHashing; diff --git a/HashingTool/Helper/HashingHelper.cs b/HashingTool/Helper/HashingHelper.cs index d838db3b2a..f44877b648 100644 --- a/HashingTool/Helper/HashingHelper.cs +++ b/HashingTool/Helper/HashingHelper.cs @@ -35,6 +35,7 @@ using System.Linq; using System.Xml; using HashingTool.ViewModel; using HashingTool.ViewModel.UserControl; +using TUGraz.VectoCommon.Hashing; using TUGraz.VectoCommon.Resources; using TUGraz.VectoHashing; diff --git a/HashingTool/ViewModel/UserControl/ManufacturerReportXMLFile.cs b/HashingTool/ViewModel/UserControl/ManufacturerReportXMLFile.cs index 577aed3639..8587b484e0 100644 --- a/HashingTool/ViewModel/UserControl/ManufacturerReportXMLFile.cs +++ b/HashingTool/ViewModel/UserControl/ManufacturerReportXMLFile.cs @@ -34,9 +34,11 @@ using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Xml; +using TUGraz.VectoCommon.Hashing; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Resources; using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.InputData.FileIO.XML.Declaration; using TUGraz.VectoHashing; namespace HashingTool.ViewModel.UserControl @@ -75,7 +77,7 @@ namespace HashingTool.ViewModel.UserControl RaisePropertyChanged("Components"); return; } - var components = GetContainigComponents().GroupBy(s => s) + var components = XMLManufacturerReportReader.GetContainingComponents(_xmlFile.Document).GroupBy(s => s) .Select(g => new { Entry = g.Key, Count = g.Count() }); var jobComponents = _jobData == null ? new ViewModel.ComponentEntry[] { } : _jobData.Components.ToArray(); _validationErrors.Clear(); @@ -87,21 +89,19 @@ namespace HashingTool.ViewModel.UserControl // collect c14n, digest method, digest value read, certification nr., digest value from job (re-computed) var componentData = new List<ComponentEntry>(); foreach (var component in components) { - if (component.Entry == XMLNames.Component_Vehicle) { + if (component.Entry == VectoComponents.Vehicle) { continue; } for (var i = 0; i < component.Count; i++) { - var node = GetNodes(component.Entry, i); + var node = XMLManufacturerReportReader.GetNodes(_xmlFile.Document, component.Entry, i); var entry = new ComponentEntry { Component = component.Count == 1 - ? component.Entry - : string.Format("{0} ({1})", component.Entry, i + 1), + ? component.Entry.XMLElementName() + : string.Format("{0} ({1})", component.Entry.XMLElementName(), i + 1), DigestValue = ReadElementValue(node, XMLNames.DI_Signature_Reference_DigestValue), CertificationMethod = ReadElementValue(node, XMLNames.Report_Component_CertificationMethod), }; - // rename 'Axle' from report to 'Tyre' as in job - if (entry.Component.StartsWith("Axle ")) { - entry.Component = entry.Component.Replace("Axle", "Tyre"); + if (entry.Component.StartsWith("Tyre ")) { entry.CertificationNumber = ReadElementValue(node, XMLNames.Report_Tyre_TyreCertificationNumber); } else { entry.CertificationNumber = ReadElementValue(node, XMLNames.Report_Component_CertificationNumber) ?? @@ -171,51 +171,9 @@ namespace HashingTool.ViewModel.UserControl return node.InnerText; } - protected XmlNode GetNodes(string component, int index) - { - var nodes = _xmlFile.Document.SelectNodes(GetComponentQueryString(component)); - if (nodes == null || nodes.Count == 0) { - throw new Exception(component == null - ? "No component found" - : string.Format("Component {0} not found", component)); - } - if (index >= nodes.Count) { - throw new Exception(string.Format("index exceeds number of components found! index: {0}, #components: {1}", index, - nodes.Count)); - } - return nodes[index]; - } - - protected static string GetComponentQueryString(string component = null) - { - if (component == null) { - return "(//*[@id])[1]"; - } - return string.Format("//*[local-name()='{0}']", component); - } - - protected IList<string> GetContainigComponents() - { - var retVal = new List<string>(); - foreach (var component in EnumHelper.GetValues<VectoComponents>()) { - var nodes = _xmlFile.Document.SelectNodes(string.Format("//*[local-name()='{0}']//*[local-name()='{1}']/*[local-name()='Model']", - XMLNames.VectoManufacturerReport, component.XMLElementName())); - var count = nodes == null ? 0 : nodes.Count; - for (var i = 0; i < count; i++) { - retVal.Add(component.XMLElementName()); - } - } - foreach (var component in new[] { XMLNames.AxleWheels_Axles_Axle }) { - var nodes = _xmlFile.Document.SelectNodes(string.Format("//*[local-name()='{0}']//*[local-name()='{1}']", - XMLNames.VectoManufacturerReport, component)); - var count = nodes == null ? 0 : nodes.Count; - for (var i = 0; i < count; i++) { - retVal.Add(component); - } - } - return retVal; - } + + public ComponentEntry[] Components { get; private set; } diff --git a/HashingTool/ViewModel/UserControl/ReportXMLFile.cs b/HashingTool/ViewModel/UserControl/ReportXMLFile.cs index 770390873b..6c639360d9 100644 --- a/HashingTool/ViewModel/UserControl/ReportXMLFile.cs +++ b/HashingTool/ViewModel/UserControl/ReportXMLFile.cs @@ -34,6 +34,8 @@ using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Xml; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCore.InputData.FileIO.XML.Declaration; using TUGraz.VectoHashing; namespace HashingTool.ViewModel.UserControl @@ -130,37 +132,19 @@ namespace HashingTool.ViewModel.UserControl // readout all required fields from the report xml: c14n, digest method, digest value of job, VIN, ... protected virtual void ReadReportData() { - var jobDigest = ""; - var jobDigestMethod = ""; + var digestData = new DigestData("", new string[]{}, "", ""); var vin = ""; - var jobc14NMethod = new string[] { }; - + if (_xmlFile.Document != null && _xmlFile.Document.DocumentElement != null) { - var digestValueNode = - _xmlFile.Document.SelectSingleNode("//*[local-name()='InputDataSignature']//*[local-name()='DigestValue']"); - if (digestValueNode != null) { - jobDigest = digestValueNode.InnerText; - } - var digestMethodNode = - _xmlFile.Document.SelectSingleNode( - "//*[local-name()='InputDataSignature']//*[local-name()='DigestMethod']/@Algorithm"); - if (digestMethodNode != null) { - jobDigestMethod = digestMethodNode.InnerText; - } - - var c14NtMethodNodes = - _xmlFile.Document.SelectNodes("//*[local-name()='InputDataSignature']//*[local-name()='Transform']/@Algorithm"); - if (c14NtMethodNodes != null) { - jobc14NMethod = (from XmlNode node in c14NtMethodNodes select node.InnerText).ToArray(); - } + digestData = new DigestData(_xmlFile.Document.SelectSingleNode("//*[local-name()='InputDataSignature']")); var vinNode = _xmlFile.Document.SelectSingleNode("//*[local-name()='VIN']"); if (vinNode != null) { vin = vinNode.InnerText; } } - JobCanonicalizationMethodRead = jobc14NMethod; - JobDigestMethodRead = jobDigestMethod; - JobDigestValueRead = jobDigest; + JobCanonicalizationMethodRead = digestData.CanonicalizationMethods; + JobDigestMethodRead = digestData.DigestMethod; + JobDigestValueRead = digestData.DigestValue; ReportVIN = vin; RaisePropertyChanged(GeneralUpdate); } diff --git a/HashingTool/ViewModel/UserControl/VectoJobFile.cs b/HashingTool/ViewModel/UserControl/VectoJobFile.cs index 1ce4e843ff..87a584106a 100644 --- a/HashingTool/ViewModel/UserControl/VectoJobFile.cs +++ b/HashingTool/ViewModel/UserControl/VectoJobFile.cs @@ -35,6 +35,7 @@ using System.ComponentModel; using System.Linq; using System.Xml; using HashingTool.Helper; +using TUGraz.VectoCommon.Hashing; using TUGraz.VectoCommon.Resources; using TUGraz.VectoHashing; diff --git a/HashingTool/ViewModel/VerifyComponentInputDataViewModel.cs b/HashingTool/ViewModel/VerifyComponentInputDataViewModel.cs index b6f2334a41..b23738e40f 100644 --- a/HashingTool/ViewModel/VerifyComponentInputDataViewModel.cs +++ b/HashingTool/ViewModel/VerifyComponentInputDataViewModel.cs @@ -38,6 +38,7 @@ using System.Windows; using System.Windows.Input; using HashingTool.Helper; using HashingTool.ViewModel.UserControl; +using TUGraz.VectoCommon.Hashing; using TUGraz.VectoHashing; namespace HashingTool.ViewModel diff --git a/VECTO/GUI/MainForm.vb b/VECTO/GUI/MainForm.vb index 0568209c72..eccee56f13 100644 --- a/VECTO/GUI/MainForm.vb +++ b/VECTO/GUI/MainForm.vb @@ -57,1984 +57,2024 @@ Imports TUGraz.VectoCore.Utils ''' </summary> ''' <remarks></remarks> -Public Class MainForm - Private _jobListView As FileListView - Private _cycleListView As FileListView + Public Class MainForm + Private _jobListView As FileListView + Private _cycleListView As FileListView - Private _lastModeName As String - Private _conMenTarget As ListView - Private _conMenTarJob As Boolean + Private _lastModeName As String + Private _conMenTarget As ListView + Private _conMenTarJob As Boolean - Private _guIlocked As Boolean + Private _guIlocked As Boolean - Private _checkLock As Boolean - Private _genChecked As Integer - Private _genCheckAllLock As Boolean + Private _checkLock As Boolean + Private _genChecked As Integer + Private _genCheckAllLock As Boolean - Private _cbDeclLock As Boolean = False + Private _cbDeclLock As Boolean = False #Region "SLEEP Control - Prevent sleep while VECTO is running" - Private Declare Function SetThreadExecutionState Lib "kernel32" (esFlags As Long) As Long + Private Declare Function SetThreadExecutionState Lib "kernel32"(esFlags As Long) As Long - Private Shared Sub AllowSleepOff() + Private Shared Sub AllowSleepOff() #If Not PLATFORM = "x86" Then - SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS Or EXECUTION_STATE.ES_SYSTEM_REQUIRED) + SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS Or EXECUTION_STATE.ES_SYSTEM_REQUIRED) #End If - End Sub + End Sub - Private Shared Sub AllowSleepOn() + Private Shared Sub AllowSleepOn() #If Not PLATFORM = "x86" Then - SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS) + SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS) #End If - End Sub + End Sub - Private Enum EXECUTION_STATE As Integer - ''' Informs the system that the state being set should remain in effect until the next call that uses ES_CONTINUOUS and one of the other state flags is cleared. - ES_CONTINUOUS = &H80000000 - ''' Forces the display to be on by resetting the display idle timer. - ES_DISPLAY_REQUIRED = &H2 - ''' Forces the system to be in the working state by resetting the system idle timer. - ES_SYSTEM_REQUIRED = &H1 - End Enum + Private Enum EXECUTION_STATE As Integer + ''' Informs the system that the state being set should remain in effect until the next call that uses ES_CONTINUOUS and one of the other state flags is cleared. + ES_CONTINUOUS = &H80000000 + ''' Forces the display to be on by resetting the display idle timer. + ES_DISPLAY_REQUIRED = &H2 + ''' Forces the system to be in the working state by resetting the system idle timer. + ES_SYSTEM_REQUIRED = &H1 + End Enum #End Region #Region "FileBrowser Init/Close" - Private Sub FB_Initialize() - FileBrowserFolderHistoryIninialized = False - Try - COREvers = VectoSimulationCore.VersionNumber() - Catch ex As Exception - LogFile.WriteToLog(MessageType.Err, ex.StackTrace) - End Try - - - FolderFileBrowser = New FileBrowser("WorkDir", True) - TextFileBrowser = New FileBrowser("FileLists") - JobfileFileBrowser = New FileBrowser("vecto") - VehicleFileBrowser = New FileBrowser("vveh") - VehicleXMLFileBrowser = New FileBrowser("vveh_xml") - FuelConsumptionMapFileBrowser = New FileBrowser("vmap") - DrivingCycleFileBrowser = New FileBrowser("vdri") - FullLoadCurveFileBrowser = New FileBrowser("vfld") - EngineFileBrowser = New FileBrowser("veng") - GearboxFileBrowser = New FileBrowser("vgbx") - DriverAccelerationFileBrowser = New FileBrowser("vacc") - AuxFileBrowser = New FileBrowser("vaux") - GearboxShiftPolygonFileBrowser = New FileBrowser("vgbs") - RetarderLossMapFileBrowser = New FileBrowser("vrlm") - TransmissionLossMapFileBrowser = New FileBrowser("vtlm") - PtoLossMapFileBrowser = New FileBrowser("vptol") - PTODrivingCycleFileBrowser = New FileBrowser("vptoc") - TorqueConverterFileBrowser = New FileBrowser("vtcc") - TorqueConverterShiftPolygonFileBrowser = New FileBrowser("vgbs") - CrossWindCorrectionFileBrowser = New FileBrowser("vcdx") - DriverDecisionFactorVelocityDropFileBrowser = New FileBrowser("DfVelocityDrop") - DriverDecisionFactorTargetSpeedFileBrowser = New FileBrowser("DfTargetSpeed") - DriverDecisionFactorVelocityDropFileBrowser.Extensions = New String() {"csv"} - DriverDecisionFactorTargetSpeedFileBrowser.Extensions = New String() {"csv"} - - ModalResultsFileBrowser = New FileBrowser("vmod") - - - '------------------------------------------------------- - TextFileBrowser.Extensions = New String() {"txt"} - JobfileFileBrowser.Extensions = New String() {"vecto"} - VehicleFileBrowser.Extensions = New String() {"vveh"} - VehicleXMLFileBrowser.Extensions = New String() {"xml"} - FuelConsumptionMapFileBrowser.Extensions = New String() {"vmap"} - DrivingCycleFileBrowser.Extensions = New String() {"vdri"} - FullLoadCurveFileBrowser.Extensions = New String() {"vfld"} - EngineFileBrowser.Extensions = New String() {"veng"} - GearboxFileBrowser.Extensions = New String() {"vgbx"} - DriverAccelerationFileBrowser.Extensions = New String() {"vacc"} - AuxFileBrowser.Extensions = New String() {"vaux"} - GearboxShiftPolygonFileBrowser.Extensions = New String() {"vgbs"} - RetarderLossMapFileBrowser.Extensions = New String() {"vrlm"} - TransmissionLossMapFileBrowser.Extensions = New String() {"vtlm"} - PtoLossMapFileBrowser.Extensions = New String() {"vptol"} - PTODrivingCycleFileBrowser.Extensions = New String() {"vptoc"} - TorqueConverterFileBrowser.Extensions = New String() {"vtcc"} - TorqueConverterShiftPolygonFileBrowser.Extensions = New String() {"vgbs"} - CrossWindCorrectionFileBrowser.Extensions = New String() {"vcdv", "vcdb"} - - ModalResultsFileBrowser.Extensions = New String() {"vmod"} - End Sub - - Private Sub FB_Close() - FolderFileBrowser.Close() - TextFileBrowser.Close() - JobfileFileBrowser.Close() - VehicleFileBrowser.Close() - VehicleXMLFileBrowser.Close() - FuelConsumptionMapFileBrowser.Close() - DrivingCycleFileBrowser.Close() - FullLoadCurveFileBrowser.Close() - EngineFileBrowser.Close() - GearboxFileBrowser.Close() - DriverAccelerationFileBrowser.Close() - AuxFileBrowser.Close() - GearboxShiftPolygonFileBrowser.Close() - RetarderLossMapFileBrowser.Close() - TransmissionLossMapFileBrowser.Close() - PtoLossMapFileBrowser.Close() - PTODrivingCycleFileBrowser.Close() - TorqueConverterFileBrowser.Close() - TorqueConverterShiftPolygonFileBrowser.Close() - CrossWindCorrectionFileBrowser.Close() - ModalResultsFileBrowser.Close() - End Sub + Private Sub FB_Initialize() + FileBrowserFolderHistoryIninialized = False + Try + COREvers = VectoSimulationCore.VersionNumber() + Catch ex As Exception + LogFile.WriteToLog(MessageType.Err, ex.StackTrace) + End Try + + + FolderFileBrowser = New FileBrowser("WorkDir", True) + TextFileBrowser = New FileBrowser("FileLists") + JobfileFileBrowser = New FileBrowser("vecto") + VehicleFileBrowser = New FileBrowser("vveh") + VehicleXMLFileBrowser = New FileBrowser("vveh_xml") + FuelConsumptionMapFileBrowser = New FileBrowser("vmap") + DrivingCycleFileBrowser = New FileBrowser("vdri") + FullLoadCurveFileBrowser = New FileBrowser("vfld") + EngineFileBrowser = New FileBrowser("veng") + GearboxFileBrowser = New FileBrowser("vgbx") + DriverAccelerationFileBrowser = New FileBrowser("vacc") + AuxFileBrowser = New FileBrowser("vaux") + GearboxShiftPolygonFileBrowser = New FileBrowser("vgbs") + RetarderLossMapFileBrowser = New FileBrowser("vrlm") + TransmissionLossMapFileBrowser = New FileBrowser("vtlm") + PtoLossMapFileBrowser = New FileBrowser("vptol") + PTODrivingCycleFileBrowser = New FileBrowser("vptoc") + TorqueConverterFileBrowser = New FileBrowser("vtcc") + TorqueConverterShiftPolygonFileBrowser = New FileBrowser("vgbs") + CrossWindCorrectionFileBrowser = New FileBrowser("vcdx") + DriverDecisionFactorVelocityDropFileBrowser = New FileBrowser("DfVelocityDrop") + DriverDecisionFactorTargetSpeedFileBrowser = New FileBrowser("DfTargetSpeed") + DriverDecisionFactorVelocityDropFileBrowser.Extensions = New String() {"csv"} + DriverDecisionFactorTargetSpeedFileBrowser.Extensions = New String() {"csv"} + + ModalResultsFileBrowser = New FileBrowser("vmod") + + + '------------------------------------------------------- + TextFileBrowser.Extensions = New String() {"txt"} + JobfileFileBrowser.Extensions = New String() {"vecto"} + VehicleFileBrowser.Extensions = New String() {"vveh"} + VehicleXMLFileBrowser.Extensions = New String() {"xml"} + FuelConsumptionMapFileBrowser.Extensions = New String() {"vmap"} + DrivingCycleFileBrowser.Extensions = New String() {"vdri"} + FullLoadCurveFileBrowser.Extensions = New String() {"vfld"} + EngineFileBrowser.Extensions = New String() {"veng"} + GearboxFileBrowser.Extensions = New String() {"vgbx"} + DriverAccelerationFileBrowser.Extensions = New String() {"vacc"} + AuxFileBrowser.Extensions = New String() {"vaux"} + GearboxShiftPolygonFileBrowser.Extensions = New String() {"vgbs"} + RetarderLossMapFileBrowser.Extensions = New String() {"vrlm"} + TransmissionLossMapFileBrowser.Extensions = New String() {"vtlm"} + PtoLossMapFileBrowser.Extensions = New String() {"vptol"} + PTODrivingCycleFileBrowser.Extensions = New String() {"vptoc"} + TorqueConverterFileBrowser.Extensions = New String() {"vtcc"} + TorqueConverterShiftPolygonFileBrowser.Extensions = New String() {"vgbs"} + CrossWindCorrectionFileBrowser.Extensions = New String() {"vcdv", "vcdb"} + + ModalResultsFileBrowser.Extensions = New String() {"vmod"} + End Sub + + Private Sub FB_Close() + FolderFileBrowser.Close() + TextFileBrowser.Close() + JobfileFileBrowser.Close() + VehicleFileBrowser.Close() + VehicleXMLFileBrowser.Close() + FuelConsumptionMapFileBrowser.Close() + DrivingCycleFileBrowser.Close() + FullLoadCurveFileBrowser.Close() + EngineFileBrowser.Close() + GearboxFileBrowser.Close() + DriverAccelerationFileBrowser.Close() + AuxFileBrowser.Close() + GearboxShiftPolygonFileBrowser.Close() + RetarderLossMapFileBrowser.Close() + TransmissionLossMapFileBrowser.Close() + PtoLossMapFileBrowser.Close() + PTODrivingCycleFileBrowser.Close() + TorqueConverterFileBrowser.Close() + TorqueConverterShiftPolygonFileBrowser.Close() + CrossWindCorrectionFileBrowser.Close() + ModalResultsFileBrowser.Close() + End Sub #End Region - 'Lock certain GUI elements while VECTO is running - Private Sub LockGUI(lock As Boolean) - _guIlocked = lock + 'Lock certain GUI elements while VECTO is running + Private Sub LockGUI(lock As Boolean) + _guIlocked = lock - PanelOptAllg.Enabled = Not lock + PanelOptAllg.Enabled = Not lock - BtGENup.Enabled = Not lock - BtGENdown.Enabled = Not lock - ButtonGENadd.Enabled = Not lock - ButtonGENremove.Enabled = Not lock - LvGEN.LabelEdit = Not lock - ChBoxAllGEN.Enabled = Not lock + BtGENup.Enabled = Not lock + BtGENdown.Enabled = Not lock + ButtonGENadd.Enabled = Not lock + ButtonGENremove.Enabled = Not lock + LvGEN.LabelEdit = Not lock + ChBoxAllGEN.Enabled = Not lock - btStartV3.Enabled = Not lock - End Sub + btStartV3.Enabled = Not lock + End Sub #Region "Form Init/Close" - 'Initialise - Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load - Dim x As Integer + 'Initialise + Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load + Dim x As Integer - _guIlocked = False - _checkLock = False - _genCheckAllLock = False - _genChecked = 0 + _guIlocked = False + _checkLock = False + _genCheckAllLock = False + _genChecked = 0 - 'Load Tabs properly (otherwise problem with ListViews) - For x = 0 To TabControl1.TabCount - 1 - TabControl1.TabPages(x).Show() - Next + 'Load Tabs properly (otherwise problem with ListViews) + For x = 0 To TabControl1.TabCount - 1 + TabControl1.TabPages(x).Show() + Next - _lastModeName = "" + _lastModeName = "" - FB_Initialize() + FB_Initialize() - Text = "VECTO " & VECTOvers & " / VectoCore " & COREvers + Text = "VECTO " & VECTOvers & " / VectoCore " & COREvers - 'FileLists - _jobListView = New FileListView(MyConfPath & "joblist.txt") - _jobListView.LVbox = LvGEN - _cycleListView = New FileListView(MyConfPath & "cyclelist.txt") + 'FileLists + _jobListView = New FileListView(MyConfPath & "joblist.txt") + _jobListView.LVbox = LvGEN + _cycleListView = New FileListView(MyConfPath & "cyclelist.txt") - _jobListView.LoadList() + _jobListView.LoadList() - LoadOptions() + LoadOptions() - 'Resize columns ... after Loading the @file-lists - LvGEN.Columns(1).Width = -2 - LvMsg.Columns(2).Width = -2 + 'Resize columns ... after Loading the @file-lists + LvGEN.Columns(1).Width = - 2 + LvMsg.Columns(2).Width = - 2 - 'Initialize BackgroundWorker + 'Initialize BackgroundWorker - VectoWorkerV3 = New BackgroundWorker() - AddHandler VectoWorkerV3.DoWork, AddressOf VectoWorkerV3_OnDoWork - AddHandler VectoWorkerV3.ProgressChanged, AddressOf VectoWorkerV3_OnProgressChanged - AddHandler VectoWorkerV3.RunWorkerCompleted, AddressOf VectoWorkerV3_OnRunWorkerCompleted + VectoWorkerV3 = New BackgroundWorker() + AddHandler VectoWorkerV3.DoWork, AddressOf VectoWorkerV3_OnDoWork + AddHandler VectoWorkerV3.ProgressChanged, AddressOf VectoWorkerV3_OnProgressChanged + AddHandler VectoWorkerV3.RunWorkerCompleted, AddressOf VectoWorkerV3_OnRunWorkerCompleted - VectoWorkerV3.WorkerReportsProgress = True - VectoWorkerV3.WorkerSupportsCancellation = True + VectoWorkerV3.WorkerReportsProgress = True + VectoWorkerV3.WorkerSupportsCancellation = True - 'Set mode (Batch/Standard) - ModeUpdate() + 'Set mode (Batch/Standard) + ModeUpdate() - DeclOnOff() - End Sub + DeclOnOff() + End Sub - ' ReSharper disable once UnusedMember.Global -- used via Logging Framework! - Public Shared Sub LogMethod(level As String, message As String) - If VectoWorkerV3.IsBusy AndAlso Not VectoWorkerV3.CancellationPending Then - If level = "Warn" Then - VectoWorkerV3.ReportProgress(100, New VectoProgress With {.Target = "ListBoxWarning", .Message = message}) - ElseIf level = "Error" Or level = "Fatal" Then - VectoWorkerV3.ReportProgress(100, New VectoProgress With {.Target = "ListBoxError", .Message = message}) - End If - End If - End Sub + ' ReSharper disable once UnusedMember.Global -- used via Logging Framework! + Public Shared Sub LogMethod(level As String, message As String) + If VectoWorkerV3.IsBusy AndAlso Not VectoWorkerV3.CancellationPending Then + If level = "Warn" Then + VectoWorkerV3.ReportProgress(100, + New VectoProgress With {.Target = "ListBoxWarning", .Message = message}) + ElseIf level = "Error" Or level = "Fatal" Then + VectoWorkerV3.ReportProgress(100, New VectoProgress With {.Target = "ListBoxError", .Message = message}) + End If + End If + End Sub - 'Declaration mode GUI settings - Private Sub DeclOnOff() + 'Declaration mode GUI settings + Private Sub DeclOnOff() - If Cfg.DeclMode Then - Text = "VECTO " & COREvers & " - Declaration Mode" - Cfg.DeclInit() - Else - Text = "VECTO " & COREvers - End If + If Cfg.DeclMode Then + Text = "VECTO " & COREvers & " - Declaration Mode" + Cfg.DeclInit() + Else + Text = "VECTO " & COREvers + End If - If Cfg.DeclMode Then - _lastModeName = "Declaration" - Else - _lastModeName = "Engineering" - End If + If Cfg.DeclMode Then + _lastModeName = "Declaration" + Else + _lastModeName = "Engineering" + End If - Status(_lastModeName & " Mode") + Status(_lastModeName & " Mode") - LoadOptions() + LoadOptions() - LbDecl.Visible = Cfg.DeclMode - End Sub + LbDecl.Visible = Cfg.DeclMode + End Sub - 'Shown Event (Form-Load finished) ... here StartUp Forms are loaded (DEV, GEN/ADV- Editor ..) - Private Sub F01_MAINForm_Shown(sender As Object, e As EventArgs) Handles Me.Shown - Dim fwelcome As WelcomeDialog + 'Shown Event (Form-Load finished) ... here StartUp Forms are loaded (DEV, GEN/ADV- Editor ..) + Private Sub F01_MAINForm_Shown(sender As Object, e As EventArgs) Handles Me.Shown + Dim fwelcome As WelcomeDialog - If Cfg.FirstRun Then - Cfg.FirstRun = False - fwelcome = New WelcomeDialog - fwelcome.ShowDialog() - End If - End Sub + If Cfg.FirstRun Then + Cfg.FirstRun = False + fwelcome = New WelcomeDialog + fwelcome.ShowDialog() + End If + End Sub - 'Open file + 'Open file - 'Close - Private Sub F01_MAINForm_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing + 'Close + Private Sub F01_MAINForm_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing - 'Save File-Lists - SaveFileLists() + 'Save File-Lists + SaveFileLists() - 'Close log - LogFile.CloseLog() + 'Close log + LogFile.CloseLog() - 'Config save - SetOptions() - Cfg.Save() + 'Config save + SetOptions() + Cfg.Save() - 'File browser instances close - FB_Close() - End Sub + 'File browser instances close + FB_Close() + End Sub #End Region - 'Open file - Job, vehicle, engine, gearbox or signature file - Public Sub OpenVectoFile(file As String) - - If Not IO.File.Exists(file) Then - - GUIMsg(MessageType.Err, "File not found! (" & file & ")") - MsgBox("File not found! (" & file & ")", MsgBoxStyle.Critical) - - Else - - Select Case UCase(GetExtension(file)) - Case ".VGBX" - If Not GearboxForm.Visible Then - GearboxForm.Show() - Else - GearboxForm.JobDir = "" - If GearboxForm.WindowState = FormWindowState.Minimized Then GearboxForm.WindowState = FormWindowState.Normal - GearboxForm.BringToFront() - End If - Try - GearboxForm.OpenGbx(file, VehicleCategory.RigidTruck) - Catch ex As Exception - MsgBox("Failed to open Gearbox File: " + ex.Message) - End Try - Case ".VVEH" - If Not VehicleForm.Visible Then - VehicleForm.Show() - Else - VehicleForm.JobDir = "" - If VehicleForm.WindowState = FormWindowState.Minimized Then VehicleForm.WindowState = FormWindowState.Normal - VehicleForm.BringToFront() - End If - Try - VehicleForm.OpenVehicle(file) - Catch ex As Exception - MsgBox(ex.Message, MsgBoxStyle.OkOnly, "Error loading Vehicle File") - End Try - Case ".VENG" - If Not EngineForm.Visible Then - EngineForm.Show() - Else - EngineForm.JobDir = "" - If EngineForm.WindowState = FormWindowState.Minimized Then EngineForm.WindowState = FormWindowState.Normal - EngineForm.BringToFront() - End If - Try - EngineForm.OpenEngineFile(file) - Catch ex As Exception - MsgBox(ex.Message, MsgBoxStyle.OkOnly, "Error loading Engine File") - End Try - Case ".VECTO" - OpenVECTOeditor(file) - Case Else - MsgBox("Type '" & GetExtension(file) & "' unknown!", MsgBoxStyle.Critical) - End Select - - End If - End Sub + 'Open file - Job, vehicle, engine, gearbox or signature file + Public Sub OpenVectoFile(file As String) + + If Not IO.File.Exists(file) Then + + GUIMsg(MessageType.Err, "File not found! (" & file & ")") + MsgBox("File not found! (" & file & ")", MsgBoxStyle.Critical) + + Else + + Select Case UCase(GetExtension(file)) + Case ".VGBX" + If Not GearboxForm.Visible Then + GearboxForm.Show() + Else + GearboxForm.JobDir = "" + If GearboxForm.WindowState = FormWindowState.Minimized Then _ + GearboxForm.WindowState = FormWindowState.Normal + GearboxForm.BringToFront() + End If + Try + GearboxForm.OpenGbx(file, VehicleCategory.RigidTruck) + Catch ex As Exception + MsgBox("Failed to open Gearbox File: " + ex.Message) + End Try + Case ".VVEH" + If Not VehicleForm.Visible Then + VehicleForm.Show() + Else + VehicleForm.JobDir = "" + If VehicleForm.WindowState = FormWindowState.Minimized Then _ + VehicleForm.WindowState = FormWindowState.Normal + VehicleForm.BringToFront() + End If + Try + VehicleForm.OpenVehicle(file) + Catch ex As Exception + MsgBox(ex.Message, MsgBoxStyle.OkOnly, "Error loading Vehicle File") + End Try + Case ".VENG" + If Not EngineForm.Visible Then + EngineForm.Show() + Else + EngineForm.JobDir = "" + If EngineForm.WindowState = FormWindowState.Minimized Then _ + EngineForm.WindowState = FormWindowState.Normal + EngineForm.BringToFront() + End If + Try + EngineForm.OpenEngineFile(file) + Catch ex As Exception + MsgBox(ex.Message, MsgBoxStyle.OkOnly, "Error loading Engine File") + End Try + Case ".VECTO" + OpenVECTOeditor(file) + Case Else + MsgBox("Type '" & GetExtension(file) & "' unknown!", MsgBoxStyle.Critical) + End Select + + End If + End Sub #Region "Events" - Private Sub ButtonGENremove_Click(sender As Object, e As EventArgs) _ - Handles ButtonGENremove.Click - RemoveJobFile() - End Sub - - Private Sub ButtonGENadd_Click(sender As Object, e As EventArgs) _ - Handles ButtonGENadd.Click - AddJobFile() - End Sub - - Private Sub ListViewGEN_KeyDown(sender As Object, e As KeyEventArgs) _ - Handles LvGEN.KeyDown - Select Case e.KeyCode - Case Keys.Delete, Keys.Back - If Not _guIlocked Then RemoveJobFile() - Case Keys.Enter - OpenJobFile() - End Select - End Sub - - Private Sub ListViewGEN_DoubleClick(sender As Object, e As EventArgs) Handles LvGEN.DoubleClick - If LvGEN.SelectedItems.Count > 0 Then - LvGEN.SelectedItems(0).Checked = Not LvGEN.SelectedItems(0).Checked - OpenJobFile() - End If - End Sub - - Private Sub LvGEN_ItemChecked(sender As Object, e As ItemCheckedEventArgs) _ - Handles LvGEN.ItemChecked - - If e.Item.Checked Then - _genChecked += 1 - Else - _genChecked -= 1 - End If - - If _checkLock Then Exit Sub - UpdateJobTabText() - End Sub - - Private Sub ChBoxAllGEN_CheckedChanged(sender As Object, e As EventArgs) _ - Handles ChBoxAllGEN.CheckedChanged - - If _genCheckAllLock And ChBoxAllGEN.CheckState = CheckState.Indeterminate Then Exit Sub - - CheckAllGen(ChBoxAllGEN.Checked) - End Sub - - Private Sub CheckAllGen(check As Boolean) - Dim x As ListViewItem - - _checkLock = True - LvGEN.BeginUpdate() - - For Each x In LvGEN.Items - x.Checked = check - Next - - LvGEN.EndUpdate() - _checkLock = False - - _genChecked = LvGEN.CheckedItems.Count - UpdateJobTabText() - End Sub - - Private Sub ListGEN_DragEnter(sender As Object, e As DragEventArgs) _ - Handles LvGEN.DragEnter - If (e.Data.GetDataPresent(DataFormats.FileDrop)) Then - e.Effect = DragDropEffects.Copy - End If - End Sub - - Private Sub ListGEN_DragDrop(sender As Object, e As DragEventArgs) _ - Handles LvGEN.DragDrop - Dim f As String() - f = CType(e.Data.GetData(DataFormats.FileDrop), String()) - AddToJobListView(f) - End Sub - - Private Sub BtGENup_Click(sender As Object, e As EventArgs) Handles BtGENup.Click - MoveItem(LvGEN, True) - End Sub - - Private Sub BtGENdown_Click(sender As Object, e As EventArgs) Handles BtGENdown.Click - MoveItem(LvGEN, False) - End Sub + Private Sub ButtonGENremove_Click(sender As Object, e As EventArgs) _ + Handles ButtonGENremove.Click + RemoveJobFile() + End Sub + + Private Sub ButtonGENadd_Click(sender As Object, e As EventArgs) _ + Handles ButtonGENadd.Click + AddJobFile() + End Sub + + Private Sub ListViewGEN_KeyDown(sender As Object, e As KeyEventArgs) _ + Handles LvGEN.KeyDown + Select Case e.KeyCode + Case Keys.Delete, Keys.Back + If Not _guIlocked Then RemoveJobFile() + Case Keys.Enter + OpenJobFile() + End Select + End Sub + + Private Sub ListViewGEN_DoubleClick(sender As Object, e As EventArgs) Handles LvGEN.DoubleClick + If LvGEN.SelectedItems.Count > 0 Then + LvGEN.SelectedItems(0).Checked = Not LvGEN.SelectedItems(0).Checked + OpenJobFile() + End If + End Sub + + Private Sub LvGEN_ItemChecked(sender As Object, e As ItemCheckedEventArgs) _ + Handles LvGEN.ItemChecked + + If e.Item.Checked Then + _genChecked += 1 + Else + _genChecked -= 1 + End If + + If _checkLock Then Exit Sub + UpdateJobTabText() + End Sub + + Private Sub ChBoxAllGEN_CheckedChanged(sender As Object, e As EventArgs) _ + Handles ChBoxAllGEN.CheckedChanged + + If _genCheckAllLock And ChBoxAllGEN.CheckState = CheckState.Indeterminate Then Exit Sub + + CheckAllGen(ChBoxAllGEN.Checked) + End Sub + + Private Sub CheckAllGen(check As Boolean) + Dim x As ListViewItem + + _checkLock = True + LvGEN.BeginUpdate() + + For Each x In LvGEN.Items + x.Checked = check + Next + + LvGEN.EndUpdate() + _checkLock = False + + _genChecked = LvGEN.CheckedItems.Count + UpdateJobTabText() + End Sub + + Private Sub ListGEN_DragEnter(sender As Object, e As DragEventArgs) _ + Handles LvGEN.DragEnter + If (e.Data.GetDataPresent(DataFormats.FileDrop)) Then + e.Effect = DragDropEffects.Copy + End If + End Sub + + Private Sub ListGEN_DragDrop(sender As Object, e As DragEventArgs) _ + Handles LvGEN.DragDrop + Dim f As String() + f = CType(e.Data.GetData(DataFormats.FileDrop), String()) + AddToJobListView(f) + End Sub + + Private Sub BtGENup_Click(sender As Object, e As EventArgs) Handles BtGENup.Click + MoveItem(LvGEN, True) + End Sub + + Private Sub BtGENdown_Click(sender As Object, e As EventArgs) Handles BtGENdown.Click + MoveItem(LvGEN, False) + End Sub #End Region - 'Remove selected file(s) from job list - Private Sub RemoveJobFile() - Dim lastindx As Integer - Dim selIx() As Integer - Dim i As Integer - - If LvGEN.SelectedItems.Count < 1 Then - If LvGEN.Items.Count = 1 Then - LvGEN.Items(0).Selected = True - Else - Exit Sub - End If - End If - - LvGEN.BeginUpdate() - _checkLock = True - - ReDim selIx(LvGEN.SelectedItems.Count - 1) - LvGEN.SelectedIndices.CopyTo(selIx, 0) - - lastindx = LvGEN.SelectedIndices(LvGEN.SelectedItems.Count - 1) - - For i = UBound(selIx) To 0 Step -1 - LvGEN.Items.RemoveAt(selIx(i)) - Next - - If lastindx < LvGEN.Items.Count Then - LvGEN.Items(lastindx).Selected = True - Else - If LvGEN.Items.Count > 0 Then LvGEN.Items(LvGEN.Items.Count - 1).Selected = True - End If - - LvGEN.EndUpdate() - _checkLock = False - - _genChecked = LvGEN.CheckedItems.Count - UpdateJobTabText() - End Sub - - 'Browse for job file(s) and add to job list with AddToJobListView - Private Sub AddJobFile() - Dim x As String() - Dim chck As Boolean = False - - x = New String() {""} - - Dim extensions As String = "vecto" - Dim inputDataExtensions As String() = New String() {"xml"} - If (inputDataExtensions.Any()) Then extensions = String.Join(",", extensions, String.Join(",", inputDataExtensions)) - - 'STANDARD/BATCH - If JobfileFileBrowser.OpenDialog("", True, extensions) Then - chck = True - x = JobfileFileBrowser.Files - End If - - If chck Then AddToJobListView(x) - End Sub - - 'Open file in list - Private Sub OpenJobFile() - Dim f As String - - If LvGEN.SelectedItems.Count < 1 Then - If LvGEN.Items.Count = 1 Then - LvGEN.Items(0).Selected = True - Else - Exit Sub - End If - End If - - f = LvGEN.SelectedItems(0).SubItems(0).Text - f = FileRepl(f) - If Path.GetExtension(f) <> VectoCore.Configuration.Constants.FileExtensions.VectoJobFile Then - MsgBox("Job File " + f + " can not be opened in Job Editor. Try importing the file.") - Exit Sub - End If - If Not File.Exists(f) Then - MsgBox(f & " not found!") - Else - OpenVECTOeditor(f) - End If - End Sub - - 'Add File to job listview (multiple files) - Private Sub AddToJobListView(path As String(), Optional ByVal txt As String = " ") - Dim pDim As Integer - Dim p As Integer - Dim f As Integer - Dim fList As String() - Dim fListDim As Integer = -1 - Dim listViewItem As ListViewItem - - 'If VECTO runs: Cancel operation (because Mode-change during calculation is not very clever) - If VectoWorkerV3.IsBusy Then Exit Sub - - pDim = UBound(path) - ReDim fList(0) 'um Nullverweisausnahme-Warnung zu verhindern - - '******************************************* Begin Update '******************************************* - LvGEN.BeginUpdate() - _checkLock = True - - LvGEN.SelectedIndices.Clear() - - If pDim = 0 Then - fListDim = LvGEN.Items.Count - 1 - ReDim fList(fListDim) - For f = 0 To fListDim - fList(f) = FileRepl(LvGEN.Items(f).SubItems(0).Text) - Next - End If - - For p = 0 To pDim - - If pDim = 0 Then - - For f = 0 To fListDim - - 'If file already exists in the list: Do not append (only when a single file) - If UCase(path(p)) = UCase(fList(f)) Then - - 'Status reset - LvGEN.Items(f).SubItems(1).Text = txt - LvGEN.Items(f).BackColor = Color.FromKnownColor(KnownColor.Window) - LvGEN.Items(f).ForeColor = Color.FromKnownColor(KnownColor.WindowText) - - 'Element auswählen und anhaken |@@| Element selection and hook - LvGEN.Items(f).Selected = True - LvGEN.Items(f).Checked = True - LvGEN.Items(f).EnsureVisible() - - GoTo lbFound - End If - Next - - End If - - 'Otherwise: Add File (without WorkDir) - listViewItem = New ListViewItem(path(p)) 'fFileWD(Path(p))) - listViewItem.SubItems.Add(" ") - listViewItem.Checked = True - listViewItem.Selected = True - LvGEN.Items.Add(listViewItem) - listViewItem.EnsureVisible() -lbFound: - Next - - LvGEN.EndUpdate() - _checkLock = False - '******************************************* End Update '******************************************* - - 'Number update - _genChecked = LvGEN.CheckedItems.Count - UpdateJobTabText() - End Sub - - 'Add File to job listview (single file) - Public Sub AddToJobListView(path As String, Optional ByVal txt As String = " ") - Dim p(0) As String - p(0) = path - AddToJobListView(p, txt) - End Sub - - 'Update job files counter in tab titel - Private Sub UpdateJobTabText() - Dim count As Integer = LvGEN.Items.Count - - TabPageGEN.Text = String.Format("Job Files ( {0} / {1} )", _genChecked, count) - - _genCheckAllLock = True - - If _genChecked = 0 Then - ChBoxAllGEN.CheckState = CheckState.Unchecked - ElseIf _genChecked = count Then - ChBoxAllGEN.CheckState = CheckState.Checked - Else - ChBoxAllGEN.CheckState = CheckState.Indeterminate - End If - - _genCheckAllLock = False - End Sub + 'Remove selected file(s) from job list + Private Sub RemoveJobFile() + Dim lastindx As Integer + Dim selIx() As Integer + Dim i As Integer + + If LvGEN.SelectedItems.Count < 1 Then + If LvGEN.Items.Count = 1 Then + LvGEN.Items(0).Selected = True + Else + Exit Sub + End If + End If + + LvGEN.BeginUpdate() + _checkLock = True + + ReDim selIx(LvGEN.SelectedItems.Count - 1) + LvGEN.SelectedIndices.CopyTo(selIx, 0) + + lastindx = LvGEN.SelectedIndices(LvGEN.SelectedItems.Count - 1) + + For i = UBound(selIx) To 0 Step - 1 + LvGEN.Items.RemoveAt(selIx(i)) + Next + + If lastindx < LvGEN.Items.Count Then + LvGEN.Items(lastindx).Selected = True + Else + If LvGEN.Items.Count > 0 Then LvGEN.Items(LvGEN.Items.Count - 1).Selected = True + End If + + LvGEN.EndUpdate() + _checkLock = False + + _genChecked = LvGEN.CheckedItems.Count + UpdateJobTabText() + End Sub + + 'Browse for job file(s) and add to job list with AddToJobListView + Private Sub AddJobFile() + Dim x As String() + Dim chck As Boolean = False + + x = New String() {""} + + Dim extensions As String = "vecto" + Dim inputDataExtensions As String() = New String() {"xml"} + If (inputDataExtensions.Any()) Then _ + extensions = String.Join(",", extensions, String.Join(",", inputDataExtensions)) + + 'STANDARD/BATCH + If JobfileFileBrowser.OpenDialog("", True, extensions) Then + chck = True + x = JobfileFileBrowser.Files + End If + + If chck Then AddToJobListView(x) + End Sub + + 'Open file in list + Private Sub OpenJobFile() + Dim f As String + + If LvGEN.SelectedItems.Count < 1 Then + If LvGEN.Items.Count = 1 Then + LvGEN.Items(0).Selected = True + Else + Exit Sub + End If + End If + + f = LvGEN.SelectedItems(0).SubItems(0).Text + f = FileRepl(f) + If Path.GetExtension(f) <> VectoCore.Configuration.Constants.FileExtensions.VectoJobFile Then + MsgBox("Job File " + f + " can not be opened in Job Editor. Try importing the file.") + Exit Sub + End If + If Not File.Exists(f) Then + MsgBox(f & " not found!") + Else + OpenVECTOeditor(f) + End If + End Sub + + 'Add File to job listview (multiple files) + Private Sub AddToJobListView(path As String(), Optional ByVal txt As String = " ") + Dim pDim As Integer + Dim p As Integer + Dim f As Integer + Dim fList As String() + Dim fListDim As Integer = - 1 + Dim listViewItem As ListViewItem + + 'If VECTO runs: Cancel operation (because Mode-change during calculation is not very clever) + If VectoWorkerV3.IsBusy Then Exit Sub + + pDim = UBound(path) + ReDim fList(0) 'um Nullverweisausnahme-Warnung zu verhindern + + '******************************************* Begin Update '******************************************* + LvGEN.BeginUpdate() + _checkLock = True + + LvGEN.SelectedIndices.Clear() + + If pDim = 0 Then + fListDim = LvGEN.Items.Count - 1 + ReDim fList(fListDim) + For f = 0 To fListDim + fList(f) = FileRepl(LvGEN.Items(f).SubItems(0).Text) + Next + End If + + For p = 0 To pDim + + If pDim = 0 Then + + For f = 0 To fListDim + + 'If file already exists in the list: Do not append (only when a single file) + If UCase(path(p)) = UCase(fList(f)) Then + + 'Status reset + LvGEN.Items(f).SubItems(1).Text = txt + LvGEN.Items(f).BackColor = Color.FromKnownColor(KnownColor.Window) + LvGEN.Items(f).ForeColor = Color.FromKnownColor(KnownColor.WindowText) + + 'Element auswählen und anhaken |@@| Element selection and hook + LvGEN.Items(f).Selected = True + LvGEN.Items(f).Checked = True + LvGEN.Items(f).EnsureVisible() + + GoTo lbFound + End If + Next + + End If + + 'Otherwise: Add File (without WorkDir) + listViewItem = New ListViewItem(path(p)) 'fFileWD(Path(p))) + listViewItem.SubItems.Add(" ") + listViewItem.Checked = True + listViewItem.Selected = True + LvGEN.Items.Add(listViewItem) + listViewItem.EnsureVisible() + lbFound: + Next + + LvGEN.EndUpdate() + _checkLock = False + '******************************************* End Update '******************************************* + + 'Number update + _genChecked = LvGEN.CheckedItems.Count + UpdateJobTabText() + End Sub + + 'Add File to job listview (single file) + Public Sub AddToJobListView(path As String, Optional ByVal txt As String = " ") + Dim p(0) As String + p(0) = path + AddToJobListView(p, txt) + End Sub + + 'Update job files counter in tab titel + Private Sub UpdateJobTabText() + Dim count As Integer = LvGEN.Items.Count + + TabPageGEN.Text = String.Format("Job Files ( {0} / {1} )", _genChecked, count) + + _genCheckAllLock = True + + If _genChecked = 0 Then + ChBoxAllGEN.CheckState = CheckState.Unchecked + ElseIf _genChecked = count Then + ChBoxAllGEN.CheckState = CheckState.Checked + Else + ChBoxAllGEN.CheckState = CheckState.Indeterminate + End If + + _genCheckAllLock = False + End Sub #Region "Toolstrip" - 'New Job file - Private Sub ToolStripBtNew_Click(sender As Object, e As EventArgs) Handles ToolStripBtNew.Click - OpenVECTOeditor("<New>") - End Sub - - 'Open input file - Private Sub ToolStripBtOpen_Click(sender As Object, e As EventArgs) Handles ToolStripBtOpen.Click - - If JobfileFileBrowser.OpenDialog("", False, "vecto,vveh,vgbx,veng") Then - OpenVectoFile(JobfileFileBrowser.Files(0)) - End If - End Sub - - Private Sub GENEditorToolStripMenuItem1_Click(sender As Object, e As EventArgs) _ - Handles GENEditorToolStripMenuItem1.Click - OpenVECTOeditor("<New>") - End Sub - - Private Sub VEHEditorToolStripMenuItem_Click(sender As Object, e As EventArgs) _ - Handles VEHEditorToolStripMenuItem.Click - If Not VehicleForm.Visible Then - VehicleForm.Show() - Else - If VehicleForm.WindowState = FormWindowState.Minimized Then VehicleForm.WindowState = FormWindowState.Normal - VehicleForm.BringToFront() - End If - End Sub - - Private Sub EngineEditorToolStripMenuItem_Click(sender As Object, e As EventArgs) _ - Handles EngineEditorToolStripMenuItem.Click - If Not EngineForm.Visible Then - EngineForm.Show() - Else - If EngineForm.WindowState = FormWindowState.Minimized Then EngineForm.WindowState = FormWindowState.Normal - EngineForm.BringToFront() - End If - End Sub - - Private Sub GearboxEditorToolStripMenuItem_Click(sender As Object, e As EventArgs) _ - Handles GearboxEditorToolStripMenuItem.Click - If Not GearboxForm.Visible Then - GearboxForm.Show() - Else - If GearboxForm.WindowState = FormWindowState.Minimized Then GearboxForm.WindowState = FormWindowState.Normal - GearboxForm.BringToFront() - End If - End Sub - - Private Sub GraphToolStripMenuItem_Click(sender As Object, e As EventArgs) _ - Handles GraphToolStripMenuItem.Click - Dim graphForm As New GraphForm - graphForm.Show() - End Sub - - Private Sub OpenLogToolStripMenuItem_Click(sender As Object, e As EventArgs) _ - Handles OpenLogToolStripMenuItem.Click - Process.Start(MyAppPath & "log.txt") - End Sub - - Private Sub SettingsToolStripMenuItem_Click(sender As Object, e As EventArgs) _ - Handles SettingsToolStripMenuItem.Click - Settings.ShowDialog() - End Sub - - Private Sub UserManualToolStripMenuItem_Click(sender As Object, e As EventArgs) _ - Handles UserManualToolStripMenuItem.Click - If File.Exists(MyAppPath & "User Manual\help.html") Then - Dim defaultBrowserPath As String = BrowserUtils.GetDefaultBrowserPath() - Process.Start(defaultBrowserPath, String.Format("""file://{0}{1}""", MyAppPath, "User Manual\help.html")) - Else - MsgBox("User Manual not found!", MsgBoxStyle.Critical) - End If - End Sub - - Private Sub UpdateNotesToolStripMenuItem_Click(sender As Object, e As EventArgs) _ - Handles UpdateNotesToolStripMenuItem.Click - If File.Exists(MyAppPath & "User Manual\Release Notes.pdf") Then - Process.Start(MyAppPath & "User Manual\Release Notes.pdf") - Else - MsgBox("Release Notes not found!", MsgBoxStyle.Critical) - End If - End Sub - - Private Sub ReportBugViaCITnetToolStripMenuItem_Click(sender As Object, e As EventArgs) _ - Handles ReportBugViaCITnetToolStripMenuItem.Click - JiraDialog.ShowDialog() - End Sub - - Private Sub AboutVECTOToolStripMenuItem1_Click(sender As Object, e As EventArgs) _ - Handles AboutVECTOToolStripMenuItem1.Click - AboutBox.ShowDialog() - End Sub + 'New Job file + Private Sub ToolStripBtNew_Click(sender As Object, e As EventArgs) Handles ToolStripBtNew.Click + OpenVECTOeditor("<New>") + End Sub + + 'Open input file + Private Sub ToolStripBtOpen_Click(sender As Object, e As EventArgs) Handles ToolStripBtOpen.Click + + If JobfileFileBrowser.OpenDialog("", False, "vecto,vveh,vgbx,veng") Then + OpenVectoFile(JobfileFileBrowser.Files(0)) + End If + End Sub + + Private Sub GENEditorToolStripMenuItem1_Click(sender As Object, e As EventArgs) _ + Handles GENEditorToolStripMenuItem1.Click + OpenVECTOeditor("<New>") + End Sub + + Private Sub VEHEditorToolStripMenuItem_Click(sender As Object, e As EventArgs) _ + Handles VEHEditorToolStripMenuItem.Click + If Not VehicleForm.Visible Then + VehicleForm.Show() + Else + If VehicleForm.WindowState = FormWindowState.Minimized Then VehicleForm.WindowState = FormWindowState.Normal + VehicleForm.BringToFront() + End If + End Sub + + Private Sub EngineEditorToolStripMenuItem_Click(sender As Object, e As EventArgs) _ + Handles EngineEditorToolStripMenuItem.Click + If Not EngineForm.Visible Then + EngineForm.Show() + Else + If EngineForm.WindowState = FormWindowState.Minimized Then EngineForm.WindowState = FormWindowState.Normal + EngineForm.BringToFront() + End If + End Sub + + Private Sub GearboxEditorToolStripMenuItem_Click(sender As Object, e As EventArgs) _ + Handles GearboxEditorToolStripMenuItem.Click + If Not GearboxForm.Visible Then + GearboxForm.Show() + Else + If GearboxForm.WindowState = FormWindowState.Minimized Then GearboxForm.WindowState = FormWindowState.Normal + GearboxForm.BringToFront() + End If + End Sub + + Private Sub GraphToolStripMenuItem_Click(sender As Object, e As EventArgs) _ + Handles GraphToolStripMenuItem.Click + Dim graphForm As New GraphForm + graphForm.Show() + End Sub + + Private Sub OpenLogToolStripMenuItem_Click(sender As Object, e As EventArgs) _ + Handles OpenLogToolStripMenuItem.Click + Process.Start(MyAppPath & "log.txt") + End Sub + + Private Sub SettingsToolStripMenuItem_Click(sender As Object, e As EventArgs) _ + Handles SettingsToolStripMenuItem.Click + Settings.ShowDialog() + End Sub + + Private Sub UserManualToolStripMenuItem_Click(sender As Object, e As EventArgs) _ + Handles UserManualToolStripMenuItem.Click + If File.Exists(MyAppPath & "User Manual\help.html") Then + Dim defaultBrowserPath As String = BrowserUtils.GetDefaultBrowserPath() + Process.Start(defaultBrowserPath, String.Format("""file://{0}{1}""", MyAppPath, "User Manual\help.html")) + Else + MsgBox("User Manual not found!", MsgBoxStyle.Critical) + End If + End Sub + + Private Sub UpdateNotesToolStripMenuItem_Click(sender As Object, e As EventArgs) _ + Handles UpdateNotesToolStripMenuItem.Click + If File.Exists(MyAppPath & "User Manual\Release Notes.pdf") Then + Process.Start(MyAppPath & "User Manual\Release Notes.pdf") + Else + MsgBox("Release Notes not found!", MsgBoxStyle.Critical) + End If + End Sub + + Private Sub ReportBugViaCITnetToolStripMenuItem_Click(sender As Object, e As EventArgs) _ + Handles ReportBugViaCITnetToolStripMenuItem.Click + JiraDialog.ShowDialog() + End Sub + + Private Sub AboutVECTOToolStripMenuItem1_Click(sender As Object, e As EventArgs) _ + Handles AboutVECTOToolStripMenuItem1.Click + AboutBox.ShowDialog() + End Sub #End Region - 'Move job/cycle file up or down in list view - Private Sub MoveItem(ByRef listView As ListView, moveUp As Boolean) - Dim x As Integer - Dim y As Integer - Dim y1 As Integer - Dim items() As String - Dim check() As Boolean - Dim index() As Integer - Dim listViewItem As ListViewItem - - If _guIlocked Then Exit Sub - - 'Cache Selected Items - y1 = listView.SelectedItems.Count - 1 - ReDim items(y1) - ReDim check(y1) - ReDim index(y1) - y = 0 - For Each x In listView.SelectedIndices - items(y) = listView.Items(x).SubItems(0).Text - check(y) = listView.Items(x).Checked - If moveUp Then - If x = 0 Then Exit Sub - index(y) = x - 1 - Else - If x = listView.Items.Count - 1 Then Exit Sub - index(y) = x + 1 - End If - y += 1 - Next - - listView.BeginUpdate() - - 'Delete Selected Items - For Each listViewItem In listView.SelectedItems - listViewItem.Remove() - Next - - 'Items select and Insert - For y = 0 To y1 - If Not check(y) Then _genChecked += 1 - listViewItem = listView.Items.Insert(index(y), items(y)) - listViewItem.SubItems.Add(" ") - listViewItem.Checked = check(y) - listView.SelectedIndices.Add(index(y)) - Next - - listView.EndUpdate() - End Sub + 'Move job/cycle file up or down in list view + Private Sub MoveItem(ByRef listView As ListView, moveUp As Boolean) + Dim x As Integer + Dim y As Integer + Dim y1 As Integer + Dim items() As String + Dim check() As Boolean + Dim index() As Integer + Dim listViewItem As ListViewItem + + If _guIlocked Then Exit Sub + + 'Cache Selected Items + y1 = listView.SelectedItems.Count - 1 + ReDim items(y1) + ReDim check(y1) + ReDim index(y1) + y = 0 + For Each x In listView.SelectedIndices + items(y) = listView.Items(x).SubItems(0).Text + check(y) = listView.Items(x).Checked + If moveUp Then + If x = 0 Then Exit Sub + index(y) = x - 1 + Else + If x = listView.Items.Count - 1 Then Exit Sub + index(y) = x + 1 + End If + y += 1 + Next + + listView.BeginUpdate() + + 'Delete Selected Items + For Each listViewItem In listView.SelectedItems + listViewItem.Remove() + Next + + 'Items select and Insert + For y = 0 To y1 + If Not check(y) Then _genChecked += 1 + listViewItem = listView.Items.Insert(index(y), items(y)) + listViewItem.SubItems.Add(" ") + listViewItem.Checked = check(y) + listView.SelectedIndices.Add(index(y)) + Next + + listView.EndUpdate() + End Sub #Region "job/cycle file List - Context Menu" - 'Save List - Private Sub SaveListToolStripMenuItem_Click(sender As Object, e As EventArgs) _ - Handles SaveListToolStripMenuItem.Click - If TextFileBrowser.SaveDialog("") Then - If _conMenTarJob Then - _jobListView.SaveList(TextFileBrowser.Files(0)) - Else - _cycleListView.SaveList(TextFileBrowser.Files(0)) - End If - End If - End Sub + 'Save List + Private Sub SaveListToolStripMenuItem_Click(sender As Object, e As EventArgs) _ + Handles SaveListToolStripMenuItem.Click + If TextFileBrowser.SaveDialog("") Then + If _conMenTarJob Then + _jobListView.SaveList(TextFileBrowser.Files(0)) + Else + _cycleListView.SaveList(TextFileBrowser.Files(0)) + End If + End If + End Sub - 'Load List - Private Sub LoadListToolStripMenuItem_Click(sender As Object, e As EventArgs) _ - Handles LoadListToolStripMenuItem.Click + 'Load List + Private Sub LoadListToolStripMenuItem_Click(sender As Object, e As EventArgs) _ + Handles LoadListToolStripMenuItem.Click - If _guIlocked Then Exit Sub + If _guIlocked Then Exit Sub - If TextFileBrowser.OpenDialog("") Then + If TextFileBrowser.OpenDialog("") Then - If _conMenTarJob Then 'GEN - _jobListView.LoadList(TextFileBrowser.Files(0)) - _genChecked = LvGEN.CheckedItems.Count - UpdateJobTabText() - Else 'DRI - 'Mode toggle - _cycleListView.LoadList(TextFileBrowser.Files(0)) - End If + If _conMenTarJob Then 'GEN + _jobListView.LoadList(TextFileBrowser.Files(0)) + _genChecked = LvGEN.CheckedItems.Count + UpdateJobTabText() + Else 'DRI + 'Mode toggle + _cycleListView.LoadList(TextFileBrowser.Files(0)) + End If - End If - End Sub + End If + End Sub - 'Load Default List - Private Sub LoadDefaultListToolStripMenuItem_Click(sender As Object, e As EventArgs) _ - Handles LoadDefaultListToolStripMenuItem.Click + 'Load Default List + Private Sub LoadDefaultListToolStripMenuItem_Click(sender As Object, e As EventArgs) _ + Handles LoadDefaultListToolStripMenuItem.Click - If _guIlocked Then Exit Sub + If _guIlocked Then Exit Sub - If _conMenTarJob Then + If _conMenTarJob Then - _jobListView.LoadList() + _jobListView.LoadList() - _genChecked = LvGEN.CheckedItems.Count - UpdateJobTabText() - Else - _cycleListView.LoadList() + _genChecked = LvGEN.CheckedItems.Count + UpdateJobTabText() + Else + _cycleListView.LoadList() - End If - End Sub + End If + End Sub - 'Clear List - Private Sub ClearListToolStripMenuItem_Click(sender As Object, e As EventArgs) _ - Handles ClearListToolStripMenuItem.Click + 'Clear List + Private Sub ClearListToolStripMenuItem_Click(sender As Object, e As EventArgs) _ + Handles ClearListToolStripMenuItem.Click - If _guIlocked Then Exit Sub + If _guIlocked Then Exit Sub - _conMenTarget.Items.Clear() - If _conMenTarJob Then - _genChecked = LvGEN.CheckedItems.Count - UpdateJobTabText() - End If - End Sub + _conMenTarget.Items.Clear() + If _conMenTarJob Then + _genChecked = LvGEN.CheckedItems.Count + UpdateJobTabText() + End If + End Sub #End Region - 'VECTO Start button - Calls VECTO_Launcher or aborts calculation - - Private Sub btStartV3_Click(sender As Object, e As EventArgs) Handles btStartV3.Click - If Not VectoWorkerV3.IsBusy Then - 'Save Lists for Crash - SaveFileLists() - - LvGEN.SelectedItems.Clear() - - If LvGEN.CheckedItems.Count = 0 Then - GUIMsg(MessageType.Err, "No job file selected!") - Exit Sub - End If - - Status("Launching VECTO ...") - JobFileList.Clear() - JobFileList.AddRange( - From listViewItem As ListViewItem In LvGEN.CheckedItems.Cast(Of ListViewItem)() - Select fFileRepl = FileRepl(listViewItem.SubItems(0).Text)) - - SetOptions() - Cfg.Save() - ClearMsg() - - LockGUI(True) - btStartV3.Enabled = True - btStartV3.Text = "STOP" - btStartV3.Image = My.Resources.Stop_icon - - ToolStripProgBarOverall.Value = 0 - ToolStripProgBarOverall.Style = ProgressBarStyle.Continuous - ToolStripProgBarOverall.Visible = True - - VectoWorkerV3.RunWorkerAsync() - Else - btStartV3.Enabled = False - btStartV3.Text = "Aborting..." - btStartV3.Image = My.Resources.Play_icon_gray - VectoWorkerV3.CancelAsync() - End If - End Sub - - - Private Sub VectoWorkerV3_OnDoWork(theSender As Object, e As DoWorkEventArgs) - Dim sender As BackgroundWorker = TryCast(theSender, BackgroundWorker) - If sender Is Nothing Then Exit Sub - - AllowSleepOff() - - Dim sumFileWriter As FileOutputWriter = New FileOutputWriter(JobFileList(0)) - Dim sumWriter As SummaryDataContainer = New SummaryDataContainer(sumFileWriter) - Dim jobContainer As JobContainer = New JobContainer(sumWriter) - - Dim mode As ExecutionMode - If Cfg.DeclMode Then - mode = ExecutionMode.Declaration - Else - mode = ExecutionMode.Engineering - Physics.AirDensity = Cfg.AirDensity.SI(Of KilogramPerCubicMeter)() - End If - - 'dictionary of run-identifiers to fileWriters (used for output directory of modfile) - Dim fileWriters As Dictionary(Of Integer, FileOutputWriter) = New Dictionary(Of Integer, FileOutputWriter) - - 'list of finished runs - Dim finishedRuns As List(Of Integer) = New List(Of Integer) - For Each jobFile As String In JobFileList - Try - sender.ReportProgress(0, - New VectoProgress With {.Target = "ListBox", .Message = "Reading File " + jobFile, .Link = jobFile}) - - Dim extension As String = Path.GetExtension(jobFile) - Dim input As IInputDataProvider = Nothing - Select Case extension - Case VectoCore.Configuration.Constants.FileExtensions.VectoJobFile - input = JSONInputDataFactory.ReadJsonJob(jobFile) - Case ".xml" - Dim xDocument As XDocument = xDocument.Load(jobFile) - Dim rootNode As String = If(xDocument Is Nothing, "", xDocument.Root.Name.LocalName) - Select Case rootNode - Case XMLNames.VectoInputEngineering - input = New XMLEngineeringInputDataProvider(jobFile, True) - Case XMLNames.VectoInputDeclaration - input = New XMLDeclarationInputDataProvider(XmlReader.Create(jobFile), True) - End Select - End Select - - If input Is Nothing Then - sender.ReportProgress(0, - New VectoProgress With {.Target = "ListBoxError", .Message = "No Input Provider for job: " + jobFile}) - Continue For - End If - - Dim fileWriter As FileOutputWriter = New FileOutputWriter(jobFile) - - Dim runsFactory As SimulatorFactory = New SimulatorFactory(mode, input, fileWriter) - runsFactory.WriteModalResults = Cfg.ModOut - runsFactory.ModalResults1Hz = Cfg.Mod1Hz - runsFactory.Validate = cbValidateRunData.Checked - runsFactory.ActualModalData = cbActVmod.Checked - - For Each runId As Integer In jobContainer.AddRuns(runsFactory) - fileWriters.Add(runId, fileWriter) - Next - - - sender.ReportProgress(0, - New VectoProgress With {.Target = "ListBox", .Message = "Finished Reading Data for job: " + jobFile}) - - Catch ex As Exception - MsgBox(String.Format("ERROR running job {0}: {1}", jobFile, ex.Message), MsgBoxStyle.Critical) - sender.ReportProgress(0, New VectoProgress With {.Target = "ListBoxError", .Message = ex.Message}) - Return - End Try - Next - - 'print detected cycles - For Each cycle As JobContainer.CycleTypeDescription In jobContainer.GetCycleTypes() - sender.ReportProgress(0, - New VectoProgress _ - With {.Target = "ListBox", .Message = String.Format("Detected Cycle {0}: {1}", cycle.Name, cycle.CycleType)}) - Next - - sender.ReportProgress(0, New VectoProgress With {.Target = "ListBox", - .Message = _ - String.Format("Starting Simulation ({0} Jobs, {1} Runs)", JobFileList.Count, jobContainer.GetProgress().Count)}) - - jobContainer.Execute(True) - - Dim start As DateTime = DateTime.Now() - - While Not jobContainer.AllCompleted - 'cancel the job if thread is interrupted (button "Stop" clicked) - If sender.CancellationPending Then - jobContainer.Cancel() - Return - End If - - Dim progress As Dictionary(Of Integer, JobContainer.ProgressEntry) = jobContainer.GetProgress() - Dim sumProgress As Double = progress.Sum(Function(pair) pair.Value.Progress) - Dim duration As Double = (DateTime.Now() - start).TotalSeconds - - sender.ReportProgress(Convert.ToInt32((sumProgress * 100.0) / progress.Count), - New VectoProgress With {.Target = "Status", - .Message = _ - String.Format("Duration: {0:0}s, Current Progress: {1:P} ({2})", duration, sumProgress / progress.Count, - String.Join(", ", progress.Select(Function(pair) String.Format("{0,4:P}", pair.Value.Progress))))}) - - Dim justFinished As Dictionary(Of Integer, JobContainer.ProgressEntry) = - progress.Where(Function(proc) proc.Value.Done AndAlso Not finishedRuns.Contains(proc.Key)).ToDictionary( - Function(pair) pair.Key, Function(pair) pair.Value) - PrintRuns(justFinished, fileWriters) - finishedRuns.AddRange(justFinished.Select(Function(pair) pair.Key)) - Thread.Sleep(100) - End While - - Dim remainingRuns As Dictionary(Of Integer, JobContainer.ProgressEntry) = - jobContainer.GetProgress().Where(Function(proc) proc.Value.Done AndAlso Not finishedRuns.Contains(proc.Key)). - ToDictionary(Function(pair) pair.Key, Function(pair) pair.Value) - PrintRuns(remainingRuns, fileWriters) - - finishedRuns.Clear() - fileWriters.Clear() - - For Each progressEntry As KeyValuePair(Of Integer, JobContainer.ProgressEntry) In jobContainer.GetProgress() - sender.ReportProgress(100, New VectoProgress With {.Target = "ListBox", - .Message = String.Format("{0,-60} {1,8:P} {2,10:F2}s - {3}", - String.Format("{0} {1} {2}", progressEntry.Value.RunName, progressEntry.Value.CycleName, - progressEntry.Value.RunSuffix), - progressEntry.Value.Progress, progressEntry.Value.ExecTime / 1000.0, - IIf(progressEntry.Value.Success, "Success", "Aborted"))}) - If (Not progressEntry.Value.Success) Then - sender.ReportProgress(100, - New VectoProgress With {.Target = "ListBox", .Message = progressEntry.Value.Error.Message}) - End If - - Next - - For Each job As String In JobFileList - Dim report As String = New FileOutputWriter(job).XMLFullReportName - If File.Exists(report) Then - sender.ReportProgress(100, New VectoProgress With {.Target = "ListBox", - .Message = String.Format("XML Manufacturer Report for '{0}' written to {1}", Path.GetFileName(job), report), - .Link = "<XML>" + report}) - End If - report = New FileOutputWriter(job).XMLCustomerReportName - If File.Exists(report) Then - sender.ReportProgress(100, New VectoProgress With {.Target = "ListBox", - .Message = String.Format("XML Customer Report for '{0}' written to {1}", Path.GetFileName(job), report), - .Link = "<XML>" + report}) - End If - Next - - If File.Exists(sumFileWriter.SumFileName) Then - sender.ReportProgress(100, New VectoProgress With {.Target = "ListBox", - .Message = String.Format("Sum File written to {0}", sumFileWriter.SumFileName), - .Link = sumFileWriter.SumFileName}) - End If - - sender.ReportProgress(100, New VectoProgress With {.Target = "ListBox", - .Message = String.Format("Simulation Finished in {0:0}s", (DateTime.Now() - start).TotalSeconds)}) - End Sub - - - Private Shared Sub PrintRuns(progress As Dictionary(Of Integer, JobContainer.ProgressEntry), - fileWriters As Dictionary(Of Integer, FileOutputWriter)) - For Each p As KeyValuePair(Of Integer, JobContainer.ProgressEntry) In progress - Dim modFilename As String = fileWriters(p.Key).GetModDataFileName(p.Value.RunName, p.Value.CycleName, - p.Value.RunSuffix + If(Cfg.Mod1Hz, "_1Hz", "")) - - Dim runName As String = String.Format("{0} {1} {2}", p.Value.RunName, p.Value.CycleName, p.Value.RunSuffix) - - If Not p.Value.Error Is Nothing Then - VectoWorkerV3.ReportProgress(0, New VectoProgress With {.Target = "ListBoxError", - .Message = String.Format("Finished Run {0} with ERROR: {1}", runName, p.Value.Error.Message), - .Link = modFilename}) - Else - VectoWorkerV3.ReportProgress(0, - New VectoProgress _ - With {.Target = "ListBox", .Message = String.Format("Finished Run {0} successfully.", runName)}) - End If - - If (File.Exists(modFilename)) Then - VectoWorkerV3.ReportProgress(0, New VectoProgress With {.Target = "ListBox", - .Message = String.Format("Run {0}: Modal Results written to {1}", runName, modFilename), .Link = modFilename - }) - End If - Next - End Sub - - Private Sub VectoWorkerV3_OnProgressChanged(sender As Object, e As ProgressChangedEventArgs) - Dim progress As VectoProgress = TryCast(e.UserState, VectoProgress) - If progress Is Nothing Then Exit Sub - - Select Case progress.Target - Case "ListBox" - If progress.Link Is Nothing Then - MsgToForm(MessageType.Normal, progress.Message, "", "") - Else - MsgToForm(MessageType.Normal, progress.Message, "", progress.Link) - End If - Case "ListBoxWarning" - MsgToForm(MessageType.Warn, progress.Message, "", "") - Return - Case "ListBoxError" - MsgToForm(MessageType.Err, progress.Message, "", "") - Return - Case "Status" - Status(progress.Message) - End Select - - ToolStripProgBarOverall.Value = e.ProgressPercentage - End Sub - - Private Sub VectoWorkerV3_OnRunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) - - 'Progbar reset - ToolStripProgBarOverall.Visible = False - ToolStripProgBarOverall.Style = ProgressBarStyle.Continuous - ToolStripProgBarOverall.Value = 0 - ProgSecStop() - - LvGEN.SelectedIndices.Clear() - - 'ShutDown when Unexpected Error - If e.Error IsNot Nothing Then - MsgBox("An Unexpected Error occurred!" & ChrW(10) & ChrW(10) & - e.Error.Message.ToString, MsgBoxStyle.Critical, "Unexpected Error") - LogFile.WriteToLog(MessageType.Err, ">>>Unexpected Error:" & e.Error.ToString()) - End If - - 'Options enable / GUI reset - LockGUI(False) - btStartV3.Text = "START" - btStartV3.Image = My.Resources.Play_icon - Status(_lastModeName & " Mode") - - 'SLEEP reactivate - AllowSleepOn() - End Sub - - - Private Sub ModeUpdate() - - 'Save lists - _jobListView.SaveList() - - 'GUI changes according to current mode - - If Cfg.DeclMode Then - _lastModeName = "Declaration" - Else - _lastModeName = "Engineering" - End If - - 'Update job counter - _genChecked = LvGEN.CheckedItems.Count - UpdateJobTabText() - - 'Status label - Status(_lastModeName & " Mode") - End Sub - - 'Class for ListView control - Job and cycle lists - Private Class FileListView - Private ReadOnly _filePath As String - Private _loadedDefault As Boolean - Public LVbox As ListView - - Public Sub New(path As String) - _filePath = path - _loadedDefault = False - End Sub - - Public Sub SaveList(Optional ByVal path As String = "") - Dim x As Integer - If path = "" Then - If Not _loadedDefault Then Exit Sub - path = _filePath - End If - Dim file As StreamWriter = My.Computer.FileSystem.OpenTextFileWriter(path, False, Encoding.UTF8) - For x = 1 To LVbox.Items.Count - file.WriteLine(String.Join("?", LVbox.Items(x - 1).SubItems(0).Text, Math.Abs(CInt(LVbox.Items(x - 1).Checked)))) - Next - file.Close() - End Sub - - Public Sub LoadList(Optional ByVal path As String = "") - 'Dim line As String() - Dim noCheck As Boolean - 'Dim file As CsvFile - Dim listViewItem As ListViewItem - - If path = "" Then - path = _filePath - _loadedDefault = True - End If - - 'file = New CsvFile - - If Not File.Exists(path) Then - If Not _loadedDefault Then GUIMsg(MessageType.Err, "Cannot open file (" & path & ")!") - Exit Sub - End If - - MainForm._checkLock = True - LVbox.BeginUpdate() - - LVbox.Items.Clear() - - noCheck = False - Dim reader As TextFieldParser = New TextFieldParser(path, Encoding.Default) - reader.TextFieldType = FieldType.Delimited - reader.Delimiters = New String() {"?"} - - Do While Not reader.EndOfData - Dim line As String() = reader.ReadFields() - If Strings.Left(Trim(line(0)), 1) = "#" Then Continue Do - - listViewItem = New ListViewItem(line(0)) - listViewItem.SubItems.Add(" ") - - If noCheck Then - listViewItem.Checked = True - Else - If UBound(line) < 1 Then - noCheck = True - listViewItem.Checked = True - Else - If IsNumeric(line(1)) Then - listViewItem.Checked = CBool(line(1)) - Else - listViewItem.Checked = True - End If - End If - End If - LVbox.Items.Add(listViewItem) - Loop - - reader.Close() - - LVbox.EndUpdate() - MainForm._checkLock = False - - If LVbox.Items.Count > 0 Then LVbox.Items(LVbox.Items.Count - 1).EnsureVisible() - End Sub - End Class - - - 'Open Job Editor and open file (or new file) - Friend Sub OpenVECTOeditor(x As String) - - If x = "<New>" Then - ShowVectoJobForm() - VectoJobForm.VectoNew() - ElseIf x = "<VTP>" Then - ShowVectoEPTPJobForm() - VectoVTPJobForm.VectoNew() - Else - Try - Dim engJob As IVTPEngineeringInputDataProvider = TryCast(JSONInputDataFactory.ReadComponentData(x), IVTPEngineeringInputDataProvider) - Dim declJob As IVTPDeclarationInputDataProvider = TryCast(JSONInputDataFactory.ReadComponentData(x), IVTPDeclarationInputDataProvider) - If engJob Is Nothing AndAlso declJob is Nothing Then - ShowVectoJobForm() - VectoJobForm.VECTOload2Form(x) - Else - ShowVectoEPTPJobForm() - VectoVTPJobForm.VECTOload2Form(x) - End If - Catch ex As Exception - MsgBox(ex.Message, MsgBoxStyle.OkOnly, "Error loading Vecto Job File") - End Try - End If - - VectoJobForm.Activate() - End Sub - - Private Sub ShowVectoJobForm() - If Not VectoJobForm.Visible Then - VectoJobForm.Show() - Else - If VectoJobForm.WindowState = FormWindowState.Minimized Then VectoJobForm.WindowState = FormWindowState.Normal - VectoJobForm.BringToFront() - End If - End Sub - - Private Sub ShowVectoEPTPJobForm() - If Not VectoVTPJobForm.Visible Then - VectoVTPJobForm.Show() - Else - If VectoVTPJobForm.WindowState = FormWindowState.Minimized Then _ - VectoVTPJobForm.WindowState = FormWindowState.Normal - VectoVTPJobForm.BringToFront() - End If - End Sub - - 'Save job and cycle file lists - Private Sub SaveFileLists() - _jobListView.SaveList() - 'If Cfg.BatchMode Then CycleListView.SaveList() - End Sub + 'VECTO Start button - Calls VECTO_Launcher or aborts calculation + + Private Sub btStartV3_Click(sender As Object, e As EventArgs) Handles btStartV3.Click + If Not VectoWorkerV3.IsBusy Then + 'Save Lists for Crash + SaveFileLists() + + LvGEN.SelectedItems.Clear() + + If LvGEN.CheckedItems.Count = 0 Then + GUIMsg(MessageType.Err, "No job file selected!") + Exit Sub + End If + + Status("Launching VECTO ...") + JobFileList.Clear() + JobFileList.AddRange( + From listViewItem As ListViewItem In LvGEN.CheckedItems.Cast (Of ListViewItem)() + Select fFileRepl = FileRepl(listViewItem.SubItems(0).Text)) + + SetOptions() + Cfg.Save() + ClearMsg() + + LockGUI(True) + btStartV3.Enabled = True + btStartV3.Text = "STOP" + btStartV3.Image = My.Resources.Stop_icon + + ToolStripProgBarOverall.Value = 0 + ToolStripProgBarOverall.Style = ProgressBarStyle.Continuous + ToolStripProgBarOverall.Visible = True + + VectoWorkerV3.RunWorkerAsync() + Else + btStartV3.Enabled = False + btStartV3.Text = "Aborting..." + btStartV3.Image = My.Resources.Play_icon_gray + VectoWorkerV3.CancelAsync() + End If + End Sub + + + Private Sub VectoWorkerV3_OnDoWork(theSender As Object, e As DoWorkEventArgs) + Dim sender As BackgroundWorker = TryCast(theSender, BackgroundWorker) + If sender Is Nothing Then Exit Sub + + AllowSleepOff() + + Dim sumFileWriter As FileOutputWriter = New FileOutputWriter(JobFileList(0)) + Dim sumWriter As SummaryDataContainer = New SummaryDataContainer(sumFileWriter) + Dim jobContainer As JobContainer = New JobContainer(sumWriter) + + Dim mode As ExecutionMode + If Cfg.DeclMode Then + mode = ExecutionMode.Declaration + Else + mode = ExecutionMode.Engineering + Physics.AirDensity = Cfg.AirDensity.SI (Of KilogramPerCubicMeter)() + End If + + 'dictionary of run-identifiers to fileWriters (used for output directory of modfile) + Dim fileWriters As Dictionary(Of Integer, FileOutputWriter) = New Dictionary(Of Integer, FileOutputWriter) + + 'list of finished runs + Dim finishedRuns As List(Of Integer) = New List(Of Integer) + For Each jobFile As String In JobFileList + Try + sender.ReportProgress(0, + New VectoProgress _ + With {.Target = "ListBox", .Message = "Reading File " + jobFile, + .Link = jobFile}) + + Dim extension As String = Path.GetExtension(jobFile) + Dim input As IInputDataProvider = Nothing + Select Case extension + Case VectoCore.Configuration.Constants.FileExtensions.VectoJobFile + input = JSONInputDataFactory.ReadJsonJob(jobFile) + Case ".xml" + Dim xDocument As XDocument = xDocument.Load(jobFile) + Dim rootNode As String = If(xDocument Is Nothing, "", xDocument.Root.Name.LocalName) + Select Case rootNode + Case XMLNames.VectoInputEngineering + input = New XMLEngineeringInputDataProvider(jobFile, True) + Case XMLNames.VectoInputDeclaration + input = New XMLDeclarationInputDataProvider(XmlReader.Create(jobFile), True) + End Select + End Select + + If input Is Nothing Then + sender.ReportProgress(0, + New VectoProgress _ + With {.Target = "ListBoxError", + .Message = "No Input Provider for job: " + jobFile}) + Continue For + End If + + Dim fileWriter As FileOutputWriter = New FileOutputWriter(jobFile) + + Dim runsFactory As SimulatorFactory = New SimulatorFactory(mode, input, fileWriter) + runsFactory.WriteModalResults = Cfg.ModOut + runsFactory.ModalResults1Hz = Cfg.Mod1Hz + runsFactory.Validate = cbValidateRunData.Checked + runsFactory.ActualModalData = cbActVmod.Checked + + For Each runId As Integer In jobContainer.AddRuns(runsFactory) + fileWriters.Add(runId, fileWriter) + Next + + + sender.ReportProgress(0, + New VectoProgress _ + With {.Target = "ListBox", + .Message = "Finished Reading Data for job: " + jobFile}) + + Catch ex As Exception + MsgBox(String.Format("ERROR running job {0}: {1}", jobFile, ex.Message), MsgBoxStyle.Critical) + sender.ReportProgress(0, New VectoProgress With {.Target = "ListBoxError", .Message = ex.Message}) + Return + End Try + Next + + 'print detected cycles + For Each cycle As JobContainer.CycleTypeDescription In jobContainer.GetCycleTypes() + sender.ReportProgress(0, + New VectoProgress _ + With {.Target = "ListBox", + .Message = String.Format("Detected Cycle {0}: {1}", cycle.Name, cycle.CycleType)}) + Next + + sender.ReportProgress(0, New VectoProgress With {.Target = "ListBox", + .Message = _ + String.Format("Starting Simulation ({0} Jobs, {1} Runs)", JobFileList.Count, + jobContainer.GetProgress().Count)}) + + jobContainer.Execute(True) + + Dim start As DateTime = DateTime.Now() + + While Not jobContainer.AllCompleted + 'cancel the job if thread is interrupted (button "Stop" clicked) + If sender.CancellationPending Then + jobContainer.Cancel() + Return + End If + + Dim progress As Dictionary(Of Integer, JobContainer.ProgressEntry) = jobContainer.GetProgress() + Dim sumProgress As Double = progress.Sum(Function(pair) pair.Value.Progress) + Dim duration As Double = (DateTime.Now() - start).TotalSeconds + + sender.ReportProgress(Convert.ToInt32((sumProgress*100.0)/progress.Count), + New VectoProgress With {.Target = "Status", + .Message = _ + String.Format("Duration: {0:0}s, Current Progress: {1:P} ({2})", duration, + sumProgress/progress.Count, + String.Join(", ", + progress.Select( + Function(pair) _ + String.Format("{0,4:P}", + pair.Value.Progress))))}) + + Dim justFinished As Dictionary(Of Integer, JobContainer.ProgressEntry) = + progress.Where(Function(proc) proc.Value.Done AndAlso Not finishedRuns.Contains(proc.Key)). + ToDictionary( + Function(pair) pair.Key, Function(pair) pair.Value) + PrintRuns(justFinished, fileWriters) + finishedRuns.AddRange(justFinished.Select(Function(pair) pair.Key)) + Thread.Sleep(100) + End While + + Dim remainingRuns As Dictionary(Of Integer, JobContainer.ProgressEntry) = + jobContainer.GetProgress().Where( + Function(proc) proc.Value.Done AndAlso Not finishedRuns.Contains(proc.Key)). + ToDictionary(Function(pair) pair.Key, Function(pair) pair.Value) + PrintRuns(remainingRuns, fileWriters) + + finishedRuns.Clear() + fileWriters.Clear() + + For Each progressEntry As KeyValuePair(Of Integer, JobContainer.ProgressEntry) In jobContainer.GetProgress() + sender.ReportProgress(100, New VectoProgress With {.Target = "ListBox", + .Message = String.Format("{0,-60} {1,8:P} {2,10:F2}s - {3}", + String.Format("{0} {1} {2}", progressEntry.Value.RunName, + progressEntry.Value.CycleName, + progressEntry.Value.RunSuffix), + progressEntry.Value.Progress, + progressEntry.Value.ExecTime/1000.0, + IIf(progressEntry.Value.Success, "Success", "Aborted"))}) + If (Not progressEntry.Value.Success) Then + sender.ReportProgress(100, + New VectoProgress _ + With {.Target = "ListBox", .Message = progressEntry.Value.Error.Message}) + End If + + Next + + For Each job As String In JobFileList + dim w as FileOutputWriter = new FileOutputWriter(job) + For Each entry as KeyValuePair(Of string, string) In _ + new Dictionary(Of string, string) _ + from {{w.XMLFullReportName, "XML Manufacturer Report"}, {w.XMLCustomerReportName, "Customer Report"}, + {w.XMLVTPReportName, "VTP Report"}} + If File.Exists(entry.Key) Then + sender.ReportProgress(100, New VectoProgress With {.Target = "ListBox", + .Message = + String.Format("{2} for '{0}' written to {1}", Path.GetFileName(job), + entry.Key, entry.Value), + .Link = "<XML>" + entry.Key}) + End If + Next + Next + + If File.Exists(sumFileWriter.SumFileName) Then + sender.ReportProgress(100, New VectoProgress With {.Target = "ListBox", + .Message = String.Format("Sum File written to {0}", sumFileWriter.SumFileName), + .Link = sumFileWriter.SumFileName}) + End If + + sender.ReportProgress(100, New VectoProgress With {.Target = "ListBox", + .Message = + String.Format("Simulation Finished in {0:0}s", (DateTime.Now() - start).TotalSeconds)}) + End Sub + + + Private Shared Sub PrintRuns(progress As Dictionary(Of Integer, JobContainer.ProgressEntry), + fileWriters As Dictionary(Of Integer, FileOutputWriter)) + For Each p As KeyValuePair(Of Integer, JobContainer.ProgressEntry) In progress + Dim modFilename As String = fileWriters(p.Key).GetModDataFileName(p.Value.RunName, p.Value.CycleName, + p.Value.RunSuffix + + If(Cfg.Mod1Hz, "_1Hz", "")) + + Dim runName As String = String.Format("{0} {1} {2}", p.Value.RunName, p.Value.CycleName, p.Value.RunSuffix) + + If Not p.Value.Error Is Nothing Then + VectoWorkerV3.ReportProgress(0, New VectoProgress With {.Target = "ListBoxError", + .Message = + String.Format("Finished Run {0} with ERROR: {1}", runName, + p.Value.Error.Message), + .Link = modFilename}) + Else + VectoWorkerV3.ReportProgress(0, + New VectoProgress _ + With {.Target = "ListBox", + .Message = String.Format("Finished Run {0} successfully.", runName)}) + End If + + If (File.Exists(modFilename)) Then + VectoWorkerV3.ReportProgress(0, New VectoProgress With {.Target = "ListBox", + .Message = + String.Format("Run {0}: Modal Results written to {1}", runName, + modFilename), .Link = modFilename + }) + End If + Next + End Sub + + Private Sub VectoWorkerV3_OnProgressChanged(sender As Object, e As ProgressChangedEventArgs) + Dim progress As VectoProgress = TryCast(e.UserState, VectoProgress) + If progress Is Nothing Then Exit Sub + + Select Case progress.Target + Case "ListBox" + If progress.Link Is Nothing Then + MsgToForm(MessageType.Normal, progress.Message, "", "") + Else + MsgToForm(MessageType.Normal, progress.Message, "", progress.Link) + End If + Case "ListBoxWarning" + MsgToForm(MessageType.Warn, progress.Message, "", "") + Return + Case "ListBoxError" + MsgToForm(MessageType.Err, progress.Message, "", "") + Return + Case "Status" + Status(progress.Message) + End Select + + ToolStripProgBarOverall.Value = e.ProgressPercentage + End Sub + + Private Sub VectoWorkerV3_OnRunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) + + 'Progbar reset + ToolStripProgBarOverall.Visible = False + ToolStripProgBarOverall.Style = ProgressBarStyle.Continuous + ToolStripProgBarOverall.Value = 0 + ProgSecStop() + + LvGEN.SelectedIndices.Clear() + + 'ShutDown when Unexpected Error + If e.Error IsNot Nothing Then + MsgBox("An Unexpected Error occurred!" & ChrW(10) & ChrW(10) & + e.Error.Message.ToString, MsgBoxStyle.Critical, "Unexpected Error") + LogFile.WriteToLog(MessageType.Err, ">>>Unexpected Error:" & e.Error.ToString()) + End If + + 'Options enable / GUI reset + LockGUI(False) + btStartV3.Text = "START" + btStartV3.Image = My.Resources.Play_icon + Status(_lastModeName & " Mode") + + 'SLEEP reactivate + AllowSleepOn() + End Sub + + + Private Sub ModeUpdate() + + 'Save lists + _jobListView.SaveList() + + 'GUI changes according to current mode + + If Cfg.DeclMode Then + _lastModeName = "Declaration" + Else + _lastModeName = "Engineering" + End If + + 'Update job counter + _genChecked = LvGEN.CheckedItems.Count + UpdateJobTabText() + + 'Status label + Status(_lastModeName & " Mode") + End Sub + + 'Class for ListView control - Job and cycle lists + Private Class FileListView + Private ReadOnly _filePath As String + Private _loadedDefault As Boolean + Public LVbox As ListView + + Public Sub New(path As String) + _filePath = path + _loadedDefault = False + End Sub + + Public Sub SaveList(Optional ByVal path As String = "") + Dim x As Integer + If path = "" Then + If Not _loadedDefault Then Exit Sub + path = _filePath + End If + Dim file As StreamWriter = My.Computer.FileSystem.OpenTextFileWriter(path, False, Encoding.UTF8) + For x = 1 To LVbox.Items.Count + file.WriteLine(String.Join("?", LVbox.Items(x - 1).SubItems(0).Text, + Math.Abs(CInt(LVbox.Items(x - 1).Checked)))) + Next + file.Close() + End Sub + + Public Sub LoadList(Optional ByVal path As String = "") + 'Dim line As String() + Dim noCheck As Boolean + 'Dim file As CsvFile + Dim listViewItem As ListViewItem + + If path = "" Then + path = _filePath + _loadedDefault = True + End If + + 'file = New CsvFile + + If Not File.Exists(path) Then + If Not _loadedDefault Then GUIMsg(MessageType.Err, "Cannot open file (" & path & ")!") + Exit Sub + End If + + MainForm._checkLock = True + LVbox.BeginUpdate() + + LVbox.Items.Clear() + + noCheck = False + Dim reader As TextFieldParser = New TextFieldParser(path, Encoding.Default) + reader.TextFieldType = FieldType.Delimited + reader.Delimiters = New String() {"?"} + + Do While Not reader.EndOfData + Dim line As String() = reader.ReadFields() + If Strings.Left(Trim(line(0)), 1) = "#" Then Continue Do + + listViewItem = New ListViewItem(line(0)) + listViewItem.SubItems.Add(" ") + + If noCheck Then + listViewItem.Checked = True + Else + If UBound(line) < 1 Then + noCheck = True + listViewItem.Checked = True + Else + If IsNumeric(line(1)) Then + listViewItem.Checked = CBool(line(1)) + Else + listViewItem.Checked = True + End If + End If + End If + LVbox.Items.Add(listViewItem) + Loop + + reader.Close() + + LVbox.EndUpdate() + MainForm._checkLock = False + + If LVbox.Items.Count > 0 Then LVbox.Items(LVbox.Items.Count - 1).EnsureVisible() + End Sub + End Class + + + 'Open Job Editor and open file (or new file) + Friend Sub OpenVECTOeditor(x As String) + + If x = "<New>" Then + ShowVectoJobForm() + VectoJobForm.VectoNew() + ElseIf x = "<VTP>" Then + ShowVectoEPTPJobForm() + VectoVTPJobForm.VectoNew() + Else + Try + Dim engJob As IVTPEngineeringInputDataProvider = TryCast(JSONInputDataFactory.ReadComponentData(x), + IVTPEngineeringInputDataProvider) + Dim declJob As IVTPDeclarationInputDataProvider = TryCast(JSONInputDataFactory.ReadComponentData(x), + IVTPDeclarationInputDataProvider) + If engJob Is Nothing AndAlso declJob is Nothing Then + ShowVectoJobForm() + VectoJobForm.VECTOload2Form(x) + Else + ShowVectoEPTPJobForm() + VectoVTPJobForm.VECTOload2Form(x) + End If + Catch ex As Exception + MsgBox(ex.Message, MsgBoxStyle.OkOnly, "Error loading Vecto Job File") + End Try + End If + + VectoJobForm.Activate() + End Sub + + Private Sub ShowVectoJobForm() + If Not VectoJobForm.Visible Then + VectoJobForm.Show() + Else + If VectoJobForm.WindowState = FormWindowState.Minimized Then _ + VectoJobForm.WindowState = FormWindowState.Normal + VectoJobForm.BringToFront() + End If + End Sub + + Private Sub ShowVectoEPTPJobForm() + If Not VectoVTPJobForm.Visible Then + VectoVTPJobForm.Show() + Else + If VectoVTPJobForm.WindowState = FormWindowState.Minimized Then _ + VectoVTPJobForm.WindowState = FormWindowState.Normal + VectoVTPJobForm.BringToFront() + End If + End Sub + + 'Save job and cycle file lists + Private Sub SaveFileLists() + _jobListView.SaveList() + 'If Cfg.BatchMode Then CycleListView.SaveList() + End Sub #Region "Progressbar controls" - 'Initialise progress bar (Start of next job in calculation) + 'Initialise progress bar (Start of next job in calculation) - 'Stop - Hide progress bar - Private Sub ProgSecStop() - TmProgSec.Stop() - ToolStripProgBarJob.Visible = False - ToolStripProgBarJob.Value = 0 - End Sub + 'Stop - Hide progress bar + Private Sub ProgSecStop() + TmProgSec.Stop() + ToolStripProgBarJob.Visible = False + ToolStripProgBarJob.Value = 0 + End Sub - 'Timer to update progress bar regularly - Private Sub TmProgSec_Tick(sender As Object, e As EventArgs) Handles TmProgSec.Tick - If _guItest.TestActive Then - Call _guItest.TestTick() - Exit Sub - Else - If Not ProgBarCtrl.ProgLock Then ProgSecUpdate() - End If - End Sub + 'Timer to update progress bar regularly + Private Sub TmProgSec_Tick(sender As Object, e As EventArgs) Handles TmProgSec.Tick + If _guItest.TestActive Then + Call _guItest.TestTick() + Exit Sub + Else + If Not ProgBarCtrl.ProgLock Then ProgSecUpdate() + End If + End Sub - 'Update progress bar (timer controlled) - Private Sub ProgSecUpdate() + 'Update progress bar (timer controlled) + Private Sub ProgSecUpdate() - With ProgBarCtrl + With ProgBarCtrl - If .ProgJobInt > 0 AndAlso ToolStripProgBarJob.Style = ProgressBarStyle.Marquee Then - ToolStripProgBarJob.Style = ProgressBarStyle.Continuous - End If + If .ProgJobInt > 0 AndAlso ToolStripProgBarJob.Style = ProgressBarStyle.Marquee Then + ToolStripProgBarJob.Style = ProgressBarStyle.Continuous + End If - If .ProgJobInt < 0 Then - .ProgJobInt = 0 - ElseIf .ProgJobInt > 100 Then - .ProgJobInt = 100 - End If + If .ProgJobInt < 0 Then + .ProgJobInt = 0 + ElseIf .ProgJobInt > 100 Then + .ProgJobInt = 100 + End If - ToolStripProgBarJob.Value = .ProgJobInt + ToolStripProgBarJob.Value = .ProgJobInt - If .ProgOverallStartInt > -1 Then - ToolStripProgBarOverall.Value = - CInt(.ProgOverallStartInt + (.PgroOverallEndInt - .ProgOverallStartInt) * .ProgJobInt / 100) - End If + If .ProgOverallStartInt > - 1 Then + ToolStripProgBarOverall.Value = + CInt(.ProgOverallStartInt + (.PgroOverallEndInt - .ProgOverallStartInt)*.ProgJobInt/100) + End If - End With - End Sub + End With + End Sub #End Region #Region "Options Tab" - 'Load options from config class - Public Sub LoadOptions() - ChBoxModOut.Checked = Cfg.ModOut - ChBoxMod1Hz.Checked = Cfg.Mod1Hz + 'Load options from config class + Public Sub LoadOptions() + ChBoxModOut.Checked = Cfg.ModOut + ChBoxMod1Hz.Checked = Cfg.Mod1Hz - RbDecl.Checked = Cfg.DeclMode + RbDecl.Checked = Cfg.DeclMode cbValidateRunData.Checked = cfg.ValidateRunData - End Sub + End Sub - 'Update config class from options in GUI, e.g. before running calculations - Private Sub SetOptions() - Cfg.ModOut = ChBoxModOut.Checked - Cfg.Mod1Hz = ChBoxMod1Hz.Checked + 'Update config class from options in GUI, e.g. before running calculations + Private Sub SetOptions() + Cfg.ModOut = ChBoxModOut.Checked + Cfg.Mod1Hz = ChBoxMod1Hz.Checked Cfg.ValidateRunData = cbValidateRunData.Checked - End Sub + End Sub #End Region - 'Add message to message list - Public Sub MsgToForm(id As MessageType, msg As String, source As String, link As String) - - If (InvokeRequired) Then - 'Me.Invoke(New MsgToFormDelegate(AddressOf MSGtoForm), ID, Msg, Source, Link) - Exit Sub - End If - Dim lv0 As ListViewItem - - lv0 = New ListViewItem - lv0.Text = msg - lv0.SubItems.Add(Now.ToString("HH:mm:ss.ff")) - lv0.SubItems.Add(source) - - If LvMsg.Items.Count > 9999 Then LvMsg.Items.RemoveAt(0) - - LogFile.WriteToLog(id, msg & vbTab & source) - - Select Case id - - Case MessageType.Err - - lv0.BackColor = Color.Red - lv0.ForeColor = Color.White - - Case MessageType.Warn - - lv0.BackColor = Color.Khaki 'FromArgb(218, 125, 0) 'DarkOrange - lv0.ForeColor = Color.Black - - Case Else - - If id = MessageType.NewJob Then - lv0.BackColor = Color.LightGray - lv0.ForeColor = Color.DarkBlue - End If - - End Select - - If link <> "" Then - If Not id = MessageType.Err Then lv0.ForeColor = Color.Blue - lv0.SubItems(0).Font = New Font(LvMsg.Font, FontStyle.Underline) - lv0.Tag = link - End If - - - LvMsg.Items.Add(lv0) - - lv0.EnsureVisible() - End Sub - - - 'Open link in message list - Private Sub LvMsg_MouseClick(sender As Object, e As MouseEventArgs) Handles LvMsg.MouseClick - Dim txt As String - If LvMsg.SelectedIndices.Count > 0 Then - If Not LvMsg.SelectedItems(0).Tag Is Nothing Then - If _ - Len(CStr(LvMsg.SelectedItems(0).Tag)) > 4 AndAlso - Microsoft.VisualBasic.Left(CStr(LvMsg.SelectedItems(0).Tag), 4) = "<UM>" Then - txt = CStr(LvMsg.SelectedItems(0).Tag).Replace("<UM>", MyAppPath & "User Manual") - txt = txt.Replace(" ", "%20") - txt = txt.Replace("\", "/") - txt = "file:///" & txt - Try - Process.Start(txt) - Catch ex As Exception - MsgBox("Cannot open link! (-_-;)") - End Try - ElseIf _ - Len(CStr(LvMsg.SelectedItems(0).Tag)) > 5 AndAlso - Microsoft.VisualBasic.Left(CStr(LvMsg.SelectedItems(0).Tag), 5) = "<GUI>" Then - txt = CStr(LvMsg.SelectedItems(0).Tag).Replace("<GUI>", "") - OpenVectoFile(txt) - ElseIf _ - Len(CStr(LvMsg.SelectedItems(0).Tag)) > 5 AndAlso - Microsoft.VisualBasic.Left(CStr(LvMsg.SelectedItems(0).Tag), 5) = "<RUN>" Then - txt = CStr(LvMsg.SelectedItems(0).Tag).Replace("<RUN>", "") - Try - Process.Start(txt) - Catch ex As Exception - GUIMsg(MessageType.Err, "Could not run '" & txt & "'!") - End Try - ElseIf _ - Len(CStr(LvMsg.SelectedItems(0).Tag)) > 5 AndAlso - Microsoft.VisualBasic.Left(CStr(LvMsg.SelectedItems(0).Tag), 5) = "<XML>" Then - txt = CStr(LvMsg.SelectedItems(0).Tag).Replace("<XML>", "") - OpenFiles(txt) - Else - OpenFiles(CStr(LvMsg.SelectedItems(0).Tag)) - End If - End If - End If - End Sub - - 'Link-cursor (Hand) for links - Private Sub LvMsg_MouseMove(sender As Object, e As MouseEventArgs) Handles LvMsg.MouseMove - Dim lv0 As ListViewItem - lv0 = LvMsg.GetItemAt(e.Location.X, e.Location.Y) - If lv0 Is Nothing OrElse lv0.Tag Is Nothing Then - LvMsg.Cursor = Cursors.Arrow - Else - LvMsg.Cursor = Cursors.Hand - End If - If _mouseDownOnListView Then - Try - LvMsg.HitTest(e.Location).Item.Selected = True - Catch - End Try - End If - End Sub + 'Add message to message list + Public Sub MsgToForm(id As MessageType, msg As String, source As String, link As String) + + If (InvokeRequired) Then + 'Me.Invoke(New MsgToFormDelegate(AddressOf MSGtoForm), ID, Msg, Source, Link) + Exit Sub + End If + Dim lv0 As ListViewItem + + lv0 = New ListViewItem + lv0.Text = msg + lv0.SubItems.Add(Now.ToString("HH:mm:ss.ff")) + lv0.SubItems.Add(source) + + If LvMsg.Items.Count > 9999 Then LvMsg.Items.RemoveAt(0) + + LogFile.WriteToLog(id, msg & vbTab & source) + + Select Case id + + Case MessageType.Err + + lv0.BackColor = Color.Red + lv0.ForeColor = Color.White + + Case MessageType.Warn + + lv0.BackColor = Color.Khaki 'FromArgb(218, 125, 0) 'DarkOrange + lv0.ForeColor = Color.Black + + Case Else + + If id = MessageType.NewJob Then + lv0.BackColor = Color.LightGray + lv0.ForeColor = Color.DarkBlue + End If + + End Select + + If link <> "" Then + If Not id = MessageType.Err Then lv0.ForeColor = Color.Blue + lv0.SubItems(0).Font = New Font(LvMsg.Font, FontStyle.Underline) + lv0.Tag = link + End If + + + LvMsg.Items.Add(lv0) + + lv0.EnsureVisible() + End Sub + + + 'Open link in message list + Private Sub LvMsg_MouseClick(sender As Object, e As MouseEventArgs) Handles LvMsg.MouseClick + Dim txt As String + If LvMsg.SelectedIndices.Count > 0 Then + If Not LvMsg.SelectedItems(0).Tag Is Nothing Then + If _ + Len(CStr(LvMsg.SelectedItems(0).Tag)) > 4 AndAlso + Microsoft.VisualBasic.Left(CStr(LvMsg.SelectedItems(0).Tag), 4) = "<UM>" Then + txt = CStr(LvMsg.SelectedItems(0).Tag).Replace("<UM>", MyAppPath & "User Manual") + txt = txt.Replace(" ", "%20") + txt = txt.Replace("\", "/") + txt = "file:///" & txt + Try + Process.Start(txt) + Catch ex As Exception + MsgBox("Cannot open link! (-_-;)") + End Try + ElseIf _ + Len(CStr(LvMsg.SelectedItems(0).Tag)) > 5 AndAlso + Microsoft.VisualBasic.Left(CStr(LvMsg.SelectedItems(0).Tag), 5) = "<GUI>" Then + txt = CStr(LvMsg.SelectedItems(0).Tag).Replace("<GUI>", "") + OpenVectoFile(txt) + ElseIf _ + Len(CStr(LvMsg.SelectedItems(0).Tag)) > 5 AndAlso + Microsoft.VisualBasic.Left(CStr(LvMsg.SelectedItems(0).Tag), 5) = "<RUN>" Then + txt = CStr(LvMsg.SelectedItems(0).Tag).Replace("<RUN>", "") + Try + Process.Start(txt) + Catch ex As Exception + GUIMsg(MessageType.Err, "Could not run '" & txt & "'!") + End Try + ElseIf _ + Len(CStr(LvMsg.SelectedItems(0).Tag)) > 5 AndAlso + Microsoft.VisualBasic.Left(CStr(LvMsg.SelectedItems(0).Tag), 5) = "<XML>" Then + txt = CStr(LvMsg.SelectedItems(0).Tag).Replace("<XML>", "") + OpenFiles(txt) + Else + OpenFiles(CStr(LvMsg.SelectedItems(0).Tag)) + End If + End If + End If + End Sub + + 'Link-cursor (Hand) for links + Private Sub LvMsg_MouseMove(sender As Object, e As MouseEventArgs) Handles LvMsg.MouseMove + Dim lv0 As ListViewItem + lv0 = LvMsg.GetItemAt(e.Location.X, e.Location.Y) + If lv0 Is Nothing OrElse lv0.Tag Is Nothing Then + LvMsg.Cursor = Cursors.Arrow + Else + LvMsg.Cursor = Cursors.Hand + End If + If _mouseDownOnListView Then + Try + LvMsg.HitTest(e.Location).Item.Selected = True + Catch + End Try + End If + End Sub #Region "Open File Context Menu" - Private _contextMenuFiles As String() + Private _contextMenuFiles As String() - 'Initialise and open context menu - Private Sub OpenFiles(ParamArray files() As String) + 'Initialise and open context menu + Private Sub OpenFiles(ParamArray files() As String) - If files.Length = 0 Then Exit Sub + If files.Length = 0 Then Exit Sub - _contextMenuFiles = files + _contextMenuFiles = files - OpenInGraphWindowToolStripMenuItem.Enabled = (UCase(GetExtension(_contextMenuFiles(0))) = ".VMOD") + OpenInGraphWindowToolStripMenuItem.Enabled = (UCase(GetExtension(_contextMenuFiles(0))) = ".VMOD") - OpenWithToolStripMenuItem.Text = "Open with " & Cfg.OpenCmdName + OpenWithToolStripMenuItem.Text = "Open with " & Cfg.OpenCmdName - CmOpenFile.Show(Cursor.Position) - End Sub + CmOpenFile.Show(Cursor.Position) + End Sub - 'Open with tool defined in Settings - Private Sub OpenWithToolStripMenuItem_Click(sender As Object, e As EventArgs) _ - Handles OpenWithToolStripMenuItem.Click - If Not FileOpenAlt(_contextMenuFiles(0)) Then MsgBox("Failed to open file!") - End Sub + 'Open with tool defined in Settings + Private Sub OpenWithToolStripMenuItem_Click(sender As Object, e As EventArgs) _ + Handles OpenWithToolStripMenuItem.Click + If Not FileOpenAlt(_contextMenuFiles(0)) Then MsgBox("Failed to open file!") + End Sub - Private Sub OpenInGraphWindowToolStripMenuItem_Click(sender As Object, e As EventArgs) _ - Handles OpenInGraphWindowToolStripMenuItem.Click - Dim graphForm As New GraphForm - graphForm.Show() - graphForm.LoadNewFile(_contextMenuFiles(0)) - End Sub + Private Sub OpenInGraphWindowToolStripMenuItem_Click(sender As Object, e As EventArgs) _ + Handles OpenInGraphWindowToolStripMenuItem.Click + Dim graphForm As New GraphForm + graphForm.Show() + graphForm.LoadNewFile(_contextMenuFiles(0)) + End Sub - 'Show in folder - Private Sub ShowInFolderToolStripMenuItem_Click(sender As Object, e As EventArgs) _ - Handles ShowInFolderToolStripMenuItem.Click - If File.Exists(_contextMenuFiles(0)) Then - Try - Process.Start("explorer", "/select,""" & _contextMenuFiles(0) & "") - Catch ex As Exception - MsgBox("Failed to open file!") - End Try - Else - MsgBox("File not found!") - End If - End Sub + 'Show in folder + Private Sub ShowInFolderToolStripMenuItem_Click(sender As Object, e As EventArgs) _ + Handles ShowInFolderToolStripMenuItem.Click + If File.Exists(_contextMenuFiles(0)) Then + Try + Process.Start("explorer", "/select,""" & _contextMenuFiles(0) & "") + Catch ex As Exception + MsgBox("Failed to open file!") + End Try + Else + MsgBox("File not found!") + End If + End Sub #End Region - 'Change Declaraion Mode - Private Sub RbDecl_CheckedChanged(sender As Object, e As EventArgs) Handles RbDecl.CheckedChanged - If _cbDeclLock Then Exit Sub + 'Change Declaraion Mode + Private Sub RbDecl_CheckedChanged(sender As Object, e As EventArgs) Handles RbDecl.CheckedChanged + If _cbDeclLock Then Exit Sub - If VectoJobForm.Visible Or VehicleForm.Visible Or GearboxForm.Visible Or EngineForm.Visible Then - _cbDeclLock = True - RbDecl.Checked = Not RbDecl.Checked - _cbDeclLock = False - MsgBox("Please close all dialog windows (e.g. Job Editor) before changing mode!") - Else - Cfg.DeclMode = RbDecl.Checked - RbDev.Checked = Not RbDecl.Checked - DeclOnOff() - End If - End Sub + If VectoJobForm.Visible Or VehicleForm.Visible Or GearboxForm.Visible Or EngineForm.Visible Then + _cbDeclLock = True + RbDecl.Checked = Not RbDecl.Checked + _cbDeclLock = False + MsgBox("Please close all dialog windows (e.g. Job Editor) before changing mode!") + Else + Cfg.DeclMode = RbDecl.Checked + RbDev.Checked = Not RbDecl.Checked + DeclOnOff() + End If + End Sub #Region "GUI Tests" - Private ReadOnly _guItest As New GUItest(Me) - Private _mouseDownOnListView As Boolean - - Private Class GUItest - Private Const RowLim As Integer = 9 - Private Const ColLim As Integer = 45 - Public TestActive As Boolean = False - Private _testAborted As Boolean - Private _xCtrl As Integer - Private _xPanel As Integer - Private _scr As Integer - Private _pRbAlt As Boolean - Private ReadOnly _ctrls(RowLim + 1) As Integer - Private ReadOnly _pnls(RowLim + 1) As Integer - Private _ctrlC As Integer - Private _ctrlCl As Integer - Private _pnDir As Integer - Private _pnDirC As Integer - Private _pnDirCl As Integer - Private _pnDirRnd As Integer - Private _ctrlRnd As Integer - Private _diffC As Integer - Private _diffLvl As Integer - Private _bInit As Integer - Private ReadOnly _mainForm As MainForm - Private ReadOnly _keyCode As List(Of Integer) - - Private Sub TestRun() - - Dim z As Integer - - _xPanel = ColLim - 10 - _xCtrl = ColLim - 10 - _pRbAlt = False - _scr = 0 - _pnDir = 0 - _pnDirCl = 10 - _pnDirC = 0 ' StrDirCL - _ctrlCl = 5 - _ctrlC = _ctrlCl - _pnDirRnd = 5 - _ctrlRnd = 8 - _diffC = 0 - _diffLvl = 1 - _bInit = 0 - _testAborted = False - Randomize() - - - _mainForm.LvMsg.Items.Clear() - _mainForm.ToolStripLbStatus.Text = "Score: 0000 Press <Esc> to Quit" - - For z = 1 To RowLim - 6 - _pRbAlt = Not _pRbAlt - If Not _pRbAlt Then - _mainForm.LvMsg.Items.Add(Space(ColLim - 11) & "*| |*") - Else - _mainForm.LvMsg.Items.Add(Space(ColLim - 11) & "*| | |*") - End If - Next - - _pRbAlt = False - - _mainForm.LvMsg.Items.Add(" VECTO Interactive Mode" & Space(ColLim - 35) & "*| |*") - _mainForm.LvMsg.Items.Add(Space(ColLim - 11) & "*| | |*") - _mainForm.LvMsg.Items.Add(Space(ColLim - 11) & "*| |*") - _mainForm.LvMsg.Items.Add(Space(ColLim - 11) & "*| | |*") - _mainForm.LvMsg.Items.Add(Space(ColLim - 11) & "*| |*") - _mainForm.LvMsg.Items.Add(Space(ColLim - 11) & "*| ∆ |*") - - For z = 1 To RowLim + 1 - _pnls(z) = ColLim - 10 - _ctrls(z) = 0 - Next - - _mainForm.TmProgSec.Interval = 200 - - _mainForm.LvMsg.Focus() - - _mainForm.TmProgSec.Start() - End Sub - - Public Sub TestStop() - _mainForm.TmProgSec.Stop() - TestActive = False - _mainForm.LvMsg.Items.Clear() - _ctrlC = 0 - _mainForm.ToolStripLbStatus.Text = _mainForm._lastModeName & " Mode" - End Sub - - Public Sub TestTick() - - If _bInit = 24 Then GoTo LbRace - _bInit += 1 - - Select Case _bInit - Case 10 - _mainForm.LvMsg.Items.RemoveAt(RowLim - 6) - _mainForm.LvMsg.Items.RemoveAt(RowLim - 5) - _mainForm.LvMsg.Items.Insert(RowLim - 6, Space(ColLim - 11) & "*| |*") - _mainForm.LvMsg.Items.Insert(RowLim - 4, Space(ColLim - 30) & " 3 " & Space(10) & "*| |*") - Case 14 - _mainForm.LvMsg.Items.RemoveAt(RowLim - 4) - _mainForm.LvMsg.Items.Insert(RowLim - 4, Space(ColLim - 30) & " 2 " & Space(10) & "*| |*") - Case 18 - _mainForm.LvMsg.Items.RemoveAt(RowLim - 4) - _mainForm.LvMsg.Items.Insert(RowLim - 4, Space(ColLim - 30) & " 1 " & Space(10) & "*| |*") - Case 22 - _mainForm.LvMsg.Items.RemoveAt(RowLim - 4) - _mainForm.LvMsg.Items.Insert(RowLim - 4, Space(ColLim - 30) & " Go! " & Space(10) & "*| |*") - Case 24 - _mainForm.LvMsg.Items.RemoveAt(RowLim - 4) - _mainForm.LvMsg.Items.Insert(RowLim - 4, Space(ColLim - 30) & " " & Space(10) & "*| |*") - End Select - Exit Sub -LbRace: - - _pRbAlt = Not _pRbAlt - - _mainForm.LvMsg.BeginUpdate() - - Lists() - - Align() - - SetCtrl() - - SetPanel() - - _mainForm.LvMsg.Items.RemoveAt(RowLim) - - UpdateCtrl() - - _mainForm.LvMsg.EndUpdate() - - If Math.Abs(_xCtrl - _pnls(2)) > 4 Then - Abort() - Exit Sub - ElseIf _ctrls(2) <> 0 Then - If _xCtrl = _pnls(2) + _ctrls(2) - 4 Then - Abort() - Exit Sub - End If - _scr += 5 * _diffLvl - End If - - _scr += _diffLvl - _diffC += 1 - - 'Erhöhe Schwierigkeitsgrad - If _diffC = (_diffLvl + 3) * 4 Then - _diffC = 0 - _diffLvl += 1 - If _diffLvl > 2 And _diffLvl < 7 Then _mainForm.TmProgSec.Interval = 300 - (_diffLvl) * 30 - _scr += 100 - Select Case _diffLvl - Case 3 - _pnDirCl = 3 - _ctrlCl = 4 - _ctrlRnd = 6 - Case 5 - _pnDirCl = 2 - _pnDirRnd = 4 - Case 8 - _ctrlCl = 2 - Case 10 - _ctrlRnd = 4 - _pnDirRnd = 3 - End Select - End If - End Sub - - Public Sub TestKey(key As Integer) - - If TestActive Then - Select Case key - Case Keys.Left - _xCtrl -= 1 - UpdateCtrl() - Case Keys.Right - _xCtrl += 1 - UpdateCtrl() - Case Keys.Escape - TestStop() - End Select - Else - - If _keyCode(_ctrlC) = key Then - _ctrlC += 1 - If _ctrlC = _keyCode.Count Then - TestActive = True - TestRun() - End If - Else - _ctrlC = 0 - End If - - End If - End Sub - - Private Sub Abort() - - Dim s As String, s1 As String - - If _testAborted Then Exit Sub - - _testAborted = True - - _mainForm.TmProgSec.Stop() - - _mainForm.LvMsg.BeginUpdate() - - s = _mainForm.LvMsg.Items(0).Text - _mainForm.LvMsg.Items.RemoveAt(0) - _mainForm.LvMsg.Items.Insert(0, "You crashed!" & Microsoft.VisualBasic.Right(s, Len(s) - 12)) - - s = _mainForm.LvMsg.Items(1).Text - s1 = "Score: " & _scr & " " - _mainForm.LvMsg.Items.RemoveAt(1) - _mainForm.LvMsg.Items.Insert(1, s1 & Microsoft.VisualBasic.Right(s, Len(s) - Len(s1))) - - _mainForm.LvMsg.EndUpdate() - - LogFile.WriteToLog(MessageType.Normal, "*** Race Score: " & _scr.ToString("0000") & " ***") - - _ctrlC = 0 - TestActive = False - - _mainForm.ToolStripLbStatus.Text = _mainForm._lastModeName & " Mode" - End Sub - - Private Sub SetCtrl() - Dim x As Integer - If _scr < 10 Then Exit Sub - _ctrls(RowLim + 1) = 0 - _ctrlC += 1 - If _ctrlC < _ctrlCl Then Exit Sub - Select Case CInt(Int((_ctrlRnd * Rnd()) + 1)) - Case 1, 2 - _ctrlC = 0 - x = CInt(Int((7 * Rnd()) + 1)) - _ctrls(RowLim + 1) = x - End Select - End Sub - - Private Sub UpdateCtrl() - Dim s As String - If _bInit < 21 Then - _xCtrl = ColLim - 10 - Exit Sub - End If - If Math.Abs(_xCtrl - _pnls(1)) > 5 Then - Abort() - Exit Sub - End If - s = Replace(_mainForm.LvMsg.Items(RowLim - 1).Text.ToString, "∆", " ") & " " - s = Microsoft.VisualBasic.Left(s, ColLim + 15) - 's = s.Remove(0, 20) - 's = "Press <Esc> to Quit " & s - If Mid(s, _xCtrl + 5, 1) = "X" Then - Abort() - Exit Sub - End If - s = s.Remove(_xCtrl + 4, 1) - 's = Trim(s.Insert(xCar + 4, "∆")) & Space(ColLim + 5 - Streets(2)) & "Pts: " & Pts & " Lv: " & DiffLvl - s = Space(_pnls(2) - 1) & Trim(s.Insert(_xCtrl + 4, "∆")) - _mainForm.LvMsg.Items.RemoveAt(RowLim - 1) - _mainForm.LvMsg.Items.Insert(RowLim - 1, s) - _mainForm.ToolStripLbStatus.Text = "Score: " & _scr.ToString("0000") & " Press <Esc> to Quit" - End Sub - - Private Sub SetPanel() - Dim s As String - s = "*| | |*" - If _pRbAlt Then - s = s.Remove(5, 1) - s = s.Insert(5, " ") - End If - If _ctrls(RowLim + 1) <> 0 Then - s = s.Remove(_ctrls(RowLim + 1) + 1, 1) - s = s.Insert(_ctrls(RowLim + 1) + 1, "X") - End If - Select Case _xPanel - _pnls(RowLim) - Case -1 - s = Replace(s, "|", "\") - Case 1 - s = Replace(s, "|", "/") - End Select - _mainForm.LvMsg.Items.Insert(0, Space(_xPanel - 1) & s) - End Sub - - Private Sub Align() - _pnDirC += 1 - If _pnDirC < _pnDirCl Then GoTo Lb1 - _pnDirC = 0 - Select Case CInt(Int((_pnDirRnd * Rnd()) + 1)) - Case 1 - _pnDir = 1 - Case 2 - _pnDir = -1 - Case Else - _pnDir = 0 - End Select -Lb1: - _xPanel += _pnDir - If _xPanel > ColLim Then - _xPanel = ColLim - ElseIf _xPanel < 22 Then - _xPanel = 22 - End If - _pnls(RowLim + 1) = _xPanel - End Sub - - Private Sub Lists() - Dim x As Integer - For x = 2 To RowLim + 1 - _ctrls(x - 1) = _ctrls(x) - _pnls(x - 1) = _pnls(x) - Next - End Sub - - Public Sub New(form As MainForm) - _mainForm = form - _keyCode = New List(Of Integer) - _keyCode.Add(Keys.Up) - _keyCode.Add(Keys.Up) - _keyCode.Add(Keys.Down) - _keyCode.Add(Keys.Down) - _keyCode.Add(Keys.Left) - _keyCode.Add(Keys.Right) - _keyCode.Add(Keys.Left) - _keyCode.Add(Keys.Right) - _keyCode.Add(Keys.B) - _keyCode.Add(Keys.A) - _ctrlC = 0 - End Sub - End Class - - Private Sub LvMsg_KeyDown(sender As Object, e As KeyEventArgs) Handles LvMsg.KeyDown - _guItest.TestKey(e.KeyValue) - If _guItest.TestActive Then e.SuppressKeyPress = True - End Sub - - Private Sub LvMsg_LostFocus(sender As Object, e As EventArgs) Handles LvMsg.LostFocus - If _guItest.TestActive Then _guItest.TestStop() - End Sub + Private ReadOnly _guItest As New GUItest(Me) + Private _mouseDownOnListView As Boolean + + Private Class GUItest + Private Const RowLim As Integer = 9 + Private Const ColLim As Integer = 45 + Public TestActive As Boolean = False + Private _testAborted As Boolean + Private _xCtrl As Integer + Private _xPanel As Integer + Private _scr As Integer + Private _pRbAlt As Boolean + Private ReadOnly _ctrls(RowLim + 1) As Integer + Private ReadOnly _pnls(RowLim + 1) As Integer + Private _ctrlC As Integer + Private _ctrlCl As Integer + Private _pnDir As Integer + Private _pnDirC As Integer + Private _pnDirCl As Integer + Private _pnDirRnd As Integer + Private _ctrlRnd As Integer + Private _diffC As Integer + Private _diffLvl As Integer + Private _bInit As Integer + Private ReadOnly _mainForm As MainForm + Private ReadOnly _keyCode As List(Of Integer) + + Private Sub TestRun() + + Dim z As Integer + + _xPanel = ColLim - 10 + _xCtrl = ColLim - 10 + _pRbAlt = False + _scr = 0 + _pnDir = 0 + _pnDirCl = 10 + _pnDirC = 0 ' StrDirCL + _ctrlCl = 5 + _ctrlC = _ctrlCl + _pnDirRnd = 5 + _ctrlRnd = 8 + _diffC = 0 + _diffLvl = 1 + _bInit = 0 + _testAborted = False + Randomize() + + + _mainForm.LvMsg.Items.Clear() + _mainForm.ToolStripLbStatus.Text = "Score: 0000 Press <Esc> to Quit" + + For z = 1 To RowLim - 6 + _pRbAlt = Not _pRbAlt + If Not _pRbAlt Then + _mainForm.LvMsg.Items.Add(Space(ColLim - 11) & "*| |*") + Else + _mainForm.LvMsg.Items.Add(Space(ColLim - 11) & "*| | |*") + End If + Next + + _pRbAlt = False + + _mainForm.LvMsg.Items.Add(" VECTO Interactive Mode" & Space(ColLim - 35) & "*| |*") + _mainForm.LvMsg.Items.Add(Space(ColLim - 11) & "*| | |*") + _mainForm.LvMsg.Items.Add(Space(ColLim - 11) & "*| |*") + _mainForm.LvMsg.Items.Add(Space(ColLim - 11) & "*| | |*") + _mainForm.LvMsg.Items.Add(Space(ColLim - 11) & "*| |*") + _mainForm.LvMsg.Items.Add(Space(ColLim - 11) & "*| ∆ |*") + + For z = 1 To RowLim + 1 + _pnls(z) = ColLim - 10 + _ctrls(z) = 0 + Next + + _mainForm.TmProgSec.Interval = 200 + + _mainForm.LvMsg.Focus() + + _mainForm.TmProgSec.Start() + End Sub + + Public Sub TestStop() + _mainForm.TmProgSec.Stop() + TestActive = False + _mainForm.LvMsg.Items.Clear() + _ctrlC = 0 + _mainForm.ToolStripLbStatus.Text = _mainForm._lastModeName & " Mode" + End Sub + + Public Sub TestTick() + + If _bInit = 24 Then GoTo LbRace + _bInit += 1 + + Select Case _bInit + Case 10 + _mainForm.LvMsg.Items.RemoveAt(RowLim - 6) + _mainForm.LvMsg.Items.RemoveAt(RowLim - 5) + _mainForm.LvMsg.Items.Insert(RowLim - 6, Space(ColLim - 11) & "*| |*") + _mainForm.LvMsg.Items.Insert(RowLim - 4, + Space(ColLim - 30) & " 3 " & Space(10) & "*| |*") + Case 14 + _mainForm.LvMsg.Items.RemoveAt(RowLim - 4) + _mainForm.LvMsg.Items.Insert(RowLim - 4, + Space(ColLim - 30) & " 2 " & Space(10) & "*| |*") + Case 18 + _mainForm.LvMsg.Items.RemoveAt(RowLim - 4) + _mainForm.LvMsg.Items.Insert(RowLim - 4, + Space(ColLim - 30) & " 1 " & Space(10) & "*| |*") + Case 22 + _mainForm.LvMsg.Items.RemoveAt(RowLim - 4) + _mainForm.LvMsg.Items.Insert(RowLim - 4, + Space(ColLim - 30) & " Go! " & Space(10) & "*| |*") + Case 24 + _mainForm.LvMsg.Items.RemoveAt(RowLim - 4) + _mainForm.LvMsg.Items.Insert(RowLim - 4, + Space(ColLim - 30) & " " & Space(10) & "*| |*") + End Select + Exit Sub + LbRace: + + _pRbAlt = Not _pRbAlt + + _mainForm.LvMsg.BeginUpdate() + + Lists() + + Align() + + SetCtrl() + + SetPanel() + + _mainForm.LvMsg.Items.RemoveAt(RowLim) + + UpdateCtrl() + + _mainForm.LvMsg.EndUpdate() + + If Math.Abs(_xCtrl - _pnls(2)) > 4 Then + Abort() + Exit Sub + ElseIf _ctrls(2) <> 0 Then + If _xCtrl = _pnls(2) + _ctrls(2) - 4 Then + Abort() + Exit Sub + End If + _scr += 5*_diffLvl + End If + + _scr += _diffLvl + _diffC += 1 + + 'Erhöhe Schwierigkeitsgrad + If _diffC = (_diffLvl + 3)*4 Then + _diffC = 0 + _diffLvl += 1 + If _diffLvl > 2 And _diffLvl < 7 Then _mainForm.TmProgSec.Interval = 300 - (_diffLvl)*30 + _scr += 100 + Select Case _diffLvl + Case 3 + _pnDirCl = 3 + _ctrlCl = 4 + _ctrlRnd = 6 + Case 5 + _pnDirCl = 2 + _pnDirRnd = 4 + Case 8 + _ctrlCl = 2 + Case 10 + _ctrlRnd = 4 + _pnDirRnd = 3 + End Select + End If + End Sub + + Public Sub TestKey(key As Integer) + + If TestActive Then + Select Case key + Case Keys.Left + _xCtrl -= 1 + UpdateCtrl() + Case Keys.Right + _xCtrl += 1 + UpdateCtrl() + Case Keys.Escape + TestStop() + End Select + Else + + If _keyCode(_ctrlC) = key Then + _ctrlC += 1 + If _ctrlC = _keyCode.Count Then + TestActive = True + TestRun() + End If + Else + _ctrlC = 0 + End If + + End If + End Sub + + Private Sub Abort() + + Dim s As String, s1 As String + + If _testAborted Then Exit Sub + + _testAborted = True + + _mainForm.TmProgSec.Stop() + + _mainForm.LvMsg.BeginUpdate() + + s = _mainForm.LvMsg.Items(0).Text + _mainForm.LvMsg.Items.RemoveAt(0) + _mainForm.LvMsg.Items.Insert(0, "You crashed!" & Microsoft.VisualBasic.Right(s, Len(s) - 12)) + + s = _mainForm.LvMsg.Items(1).Text + s1 = "Score: " & _scr & " " + _mainForm.LvMsg.Items.RemoveAt(1) + _mainForm.LvMsg.Items.Insert(1, s1 & Microsoft.VisualBasic.Right(s, Len(s) - Len(s1))) + + _mainForm.LvMsg.EndUpdate() + + LogFile.WriteToLog(MessageType.Normal, "*** Race Score: " & _scr.ToString("0000") & " ***") + + _ctrlC = 0 + TestActive = False + + _mainForm.ToolStripLbStatus.Text = _mainForm._lastModeName & " Mode" + End Sub + + Private Sub SetCtrl() + Dim x As Integer + If _scr < 10 Then Exit Sub + _ctrls(RowLim + 1) = 0 + _ctrlC += 1 + If _ctrlC < _ctrlCl Then Exit Sub + Select Case CInt(Int((_ctrlRnd*Rnd()) + 1)) + Case 1, 2 + _ctrlC = 0 + x = CInt(Int((7*Rnd()) + 1)) + _ctrls(RowLim + 1) = x + End Select + End Sub + + Private Sub UpdateCtrl() + Dim s As String + If _bInit < 21 Then + _xCtrl = ColLim - 10 + Exit Sub + End If + If Math.Abs(_xCtrl - _pnls(1)) > 5 Then + Abort() + Exit Sub + End If + s = Replace(_mainForm.LvMsg.Items(RowLim - 1).Text.ToString, "∆", " ") & " " + s = Microsoft.VisualBasic.Left(s, ColLim + 15) + 's = s.Remove(0, 20) + 's = "Press <Esc> to Quit " & s + If Mid(s, _xCtrl + 5, 1) = "X" Then + Abort() + Exit Sub + End If + s = s.Remove(_xCtrl + 4, 1) + 's = Trim(s.Insert(xCar + 4, "∆")) & Space(ColLim + 5 - Streets(2)) & "Pts: " & Pts & " Lv: " & DiffLvl + s = Space(_pnls(2) - 1) & Trim(s.Insert(_xCtrl + 4, "∆")) + _mainForm.LvMsg.Items.RemoveAt(RowLim - 1) + _mainForm.LvMsg.Items.Insert(RowLim - 1, s) + _mainForm.ToolStripLbStatus.Text = "Score: " & _scr.ToString("0000") & " Press <Esc> to Quit" + End Sub + + Private Sub SetPanel() + Dim s As String + s = "*| | |*" + If _pRbAlt Then + s = s.Remove(5, 1) + s = s.Insert(5, " ") + End If + If _ctrls(RowLim + 1) <> 0 Then + s = s.Remove(_ctrls(RowLim + 1) + 1, 1) + s = s.Insert(_ctrls(RowLim + 1) + 1, "X") + End If + Select Case _xPanel - _pnls(RowLim) + Case - 1 + s = Replace(s, "|", "\") + Case 1 + s = Replace(s, "|", "/") + End Select + _mainForm.LvMsg.Items.Insert(0, Space(_xPanel - 1) & s) + End Sub + + Private Sub Align() + _pnDirC += 1 + If _pnDirC < _pnDirCl Then GoTo Lb1 + _pnDirC = 0 + Select Case CInt(Int((_pnDirRnd*Rnd()) + 1)) + Case 1 + _pnDir = 1 + Case 2 + _pnDir = - 1 + Case Else + _pnDir = 0 + End Select + Lb1: + _xPanel += _pnDir + If _xPanel > ColLim Then + _xPanel = ColLim + ElseIf _xPanel < 22 Then + _xPanel = 22 + End If + _pnls(RowLim + 1) = _xPanel + End Sub + + Private Sub Lists() + Dim x As Integer + For x = 2 To RowLim + 1 + _ctrls(x - 1) = _ctrls(x) + _pnls(x - 1) = _pnls(x) + Next + End Sub + + Public Sub New(form As MainForm) + _mainForm = form + _keyCode = New List(Of Integer) + _keyCode.Add(Keys.Up) + _keyCode.Add(Keys.Up) + _keyCode.Add(Keys.Down) + _keyCode.Add(Keys.Down) + _keyCode.Add(Keys.Left) + _keyCode.Add(Keys.Right) + _keyCode.Add(Keys.Left) + _keyCode.Add(Keys.Right) + _keyCode.Add(Keys.B) + _keyCode.Add(Keys.A) + _ctrlC = 0 + End Sub + End Class + + Private Sub LvMsg_KeyDown(sender As Object, e As KeyEventArgs) Handles LvMsg.KeyDown + _guItest.TestKey(e.KeyValue) + If _guItest.TestActive Then e.SuppressKeyPress = True + End Sub + + Private Sub LvMsg_LostFocus(sender As Object, e As EventArgs) Handles LvMsg.LostFocus + If _guItest.TestActive Then _guItest.TestStop() + End Sub #End Region - Private Sub LvMsg_KeyUp(sender As Object, e As KeyEventArgs) Handles LvMsg.KeyUp - If (e.Control And e.KeyCode = Keys.C) Then - Dim builder As StringBuilder = New StringBuilder() - For Each selectedItem As ListViewItem In LvMsg.SelectedItems - builder.AppendLine(String.Join(", ", - selectedItem.SubItems.Cast(Of ListViewItem.ListViewSubItem).Select( - Function(item) item.Text))) - Next - Clipboard.SetText(builder.ToString()) - End If - End Sub - - Private Sub LvMsg_MouseDown(sender As Object, e As MouseEventArgs) Handles LvMsg.MouseDown - _mouseDownOnListView = True - End Sub - - Private Sub LvMsg_MouseUp(sender As Object, e As MouseEventArgs) Handles LvMsg.MouseUp - _mouseDownOnListView = False - End Sub - - Private Sub RbDev_CheckedChanged(sender As Object, e As EventArgs) Handles RbDev.CheckedChanged - End Sub - - - Private Class VectoProgress - Public Target As String - Public Message As String - Public Link As String - End Class - - Private Sub btnExportXML_Click(sender As Object, e As EventArgs) Handles btnExportXML.Click - - If LvGEN.SelectedItems.Count < 1 Then - If LvGEN.Items.Count = 1 Then - LvGEN.Items(0).Selected = True - Else - Exit Sub - End If - End If - - Dim f As String = LvGEN.SelectedItems(0).SubItems(0).Text - f = FileRepl(f) - If Not File.Exists(f) Then - MsgBox(f & " not found!") - Return - End If - Try - Dim input As IInputDataProvider = Nothing - Dim extension As String = Path.GetExtension(f) - Select Case extension - Case ".vecto" - input = JSONInputDataFactory.ReadJsonJob(f) - Case ".xml" - Dim xDocument As XDocument = xDocument.Load(f) - Dim rootNode As String = If(xDocument Is Nothing, "", xDocument.Root.Name.LocalName) - Select Case rootNode - Case XMLNames.VectoInputEngineering - input = New XMLEngineeringInputDataProvider(f, True) - Case XMLNames.VectoInputDeclaration - input = New XMLDeclarationInputDataProvider(XmlReader.Create(f), True) - End Select - End Select - - If input Is Nothing Then Throw New VectoException("No InputDataProvider for file {0} found!", f) - - XMLExportJobDialog.Initialize(input) - XMLExportJobDialog.ShowDialog() - Catch ex As Exception - MsgBox("Exporting job failed: " + ex.Message) - End Try - End Sub - - Private Sub LvGEN_SelectedIndexChanged(sender As Object, e As EventArgs) Handles LvGEN.SelectedIndexChanged - btnExportXML.Enabled = (LvGEN.SelectedItems.Count = 1) - End Sub - - Private Sub btnImportXML_Click(sender As Object, e As EventArgs) Handles btnImportXML.Click - 'Try - ' Dim jobFile As String = PluginRegistry.Instance.GetImportPlugin("TUG.IVT.Vecto.XMLImport").ImportJob() - ' AddToJobListView(jobFile) - 'Catch ex As Exception - ' MsgBox("Importing job failed: " + ex.Message) - 'End Try - End Sub - - Private Sub LvGEN_MouseClick(sender As Object, e As MouseEventArgs) Handles LvGEN.MouseClick - If e.Button = MouseButtons.Right Then - _conMenTarget = LvGEN - _conMenTarJob = True - - 'Locked functions show/hide - LoadListToolStripMenuItem.Enabled = Not _guIlocked - LoadDefaultListToolStripMenuItem.Enabled = Not _guIlocked - ClearListToolStripMenuItem.Enabled = Not _guIlocked - - ConMenFilelist.Show(MousePosition) - End If - End Sub - - Private Sub ShowInFolderMenuItem_Click(sender As Object, e As EventArgs) Handles ShowInFolderMenuItem.Click - - For Each item As ListViewItem In LvGEN.SelectedItems - Dim fileName As String = FileRepl(item.SubItems(0).Text) - If File.Exists(fileName) Then - Try - Process.Start("explorer", "/select,""" & fileName & "") - Catch ex As Exception - MsgBox("Failed to open file!") - End Try - Else - MsgBox("File not found: " & fileName) - End If - Next - End Sub - - Private Sub EPTPJobEditorToolStripMenuItem_Click(sender As Object, e As EventArgs) _ - Handles EPTPJobEditorToolStripMenuItem.Click - OpenVECTOeditor("<VTP>") - End Sub + Private Sub LvMsg_KeyUp(sender As Object, e As KeyEventArgs) Handles LvMsg.KeyUp + If (e.Control And e.KeyCode = Keys.C) Then + Dim builder As StringBuilder = New StringBuilder() + For Each selectedItem As ListViewItem In LvMsg.SelectedItems + builder.AppendLine(String.Join(", ", + selectedItem.SubItems.Cast (Of ListViewItem.ListViewSubItem).Select( + Function(item) item.Text))) + Next + Clipboard.SetText(builder.ToString()) + End If + End Sub + + Private Sub LvMsg_MouseDown(sender As Object, e As MouseEventArgs) Handles LvMsg.MouseDown + _mouseDownOnListView = True + End Sub + + Private Sub LvMsg_MouseUp(sender As Object, e As MouseEventArgs) Handles LvMsg.MouseUp + _mouseDownOnListView = False + End Sub + + Private Sub RbDev_CheckedChanged(sender As Object, e As EventArgs) Handles RbDev.CheckedChanged + End Sub + + + Private Class VectoProgress + Public Target As String + Public Message As String + Public Link As String + End Class + + Private Sub btnExportXML_Click(sender As Object, e As EventArgs) Handles btnExportXML.Click + + If LvGEN.SelectedItems.Count < 1 Then + If LvGEN.Items.Count = 1 Then + LvGEN.Items(0).Selected = True + Else + Exit Sub + End If + End If + + Dim f As String = LvGEN.SelectedItems(0).SubItems(0).Text + f = FileRepl(f) + If Not File.Exists(f) Then + MsgBox(f & " not found!") + Return + End If + Try + Dim input As IInputDataProvider = Nothing + Dim extension As String = Path.GetExtension(f) + Select Case extension + Case ".vecto" + input = JSONInputDataFactory.ReadJsonJob(f) + Case ".xml" + Dim xDocument As XDocument = xDocument.Load(f) + Dim rootNode As String = If(xDocument Is Nothing, "", xDocument.Root.Name.LocalName) + Select Case rootNode + Case XMLNames.VectoInputEngineering + input = New XMLEngineeringInputDataProvider(f, True) + Case XMLNames.VectoInputDeclaration + input = New XMLDeclarationInputDataProvider(XmlReader.Create(f), True) + End Select + End Select + + If input Is Nothing Then Throw New VectoException("No InputDataProvider for file {0} found!", f) + + XMLExportJobDialog.Initialize(input) + XMLExportJobDialog.ShowDialog() + Catch ex As Exception + MsgBox("Exporting job failed: " + ex.Message) + End Try + End Sub + + Private Sub LvGEN_SelectedIndexChanged(sender As Object, e As EventArgs) Handles LvGEN.SelectedIndexChanged + btnExportXML.Enabled = (LvGEN.SelectedItems.Count = 1) + End Sub + + Private Sub btnImportXML_Click(sender As Object, e As EventArgs) Handles btnImportXML.Click + 'Try + ' Dim jobFile As String = PluginRegistry.Instance.GetImportPlugin("TUG.IVT.Vecto.XMLImport").ImportJob() + ' AddToJobListView(jobFile) + 'Catch ex As Exception + ' MsgBox("Importing job failed: " + ex.Message) + 'End Try + End Sub + + Private Sub LvGEN_MouseClick(sender As Object, e As MouseEventArgs) Handles LvGEN.MouseClick + If e.Button = MouseButtons.Right Then + _conMenTarget = LvGEN + _conMenTarJob = True + + 'Locked functions show/hide + LoadListToolStripMenuItem.Enabled = Not _guIlocked + LoadDefaultListToolStripMenuItem.Enabled = Not _guIlocked + ClearListToolStripMenuItem.Enabled = Not _guIlocked + + ConMenFilelist.Show(MousePosition) + End If + End Sub + + Private Sub ShowInFolderMenuItem_Click(sender As Object, e As EventArgs) Handles ShowInFolderMenuItem.Click + + For Each item As ListViewItem In LvGEN.SelectedItems + Dim fileName As String = FileRepl(item.SubItems(0).Text) + If File.Exists(fileName) Then + Try + Process.Start("explorer", "/select,""" & fileName & "") + Catch ex As Exception + MsgBox("Failed to open file!") + End Try + Else + MsgBox("File not found: " & fileName) + End If + Next + End Sub + + Private Sub EPTPJobEditorToolStripMenuItem_Click(sender As Object, e As EventArgs) _ + Handles EPTPJobEditorToolStripMenuItem.Click + OpenVECTOeditor("<VTP>") + End Sub End Class diff --git a/VECTO/Input Files/Engine.vb b/VECTO/Input Files/Engine.vb index 8844e6825d..2231cd359a 100644 --- a/VECTO/Input Files/Engine.vb +++ b/VECTO/Input Files/Engine.vb @@ -313,9 +313,9 @@ Public Class Engine End Get End Property - Public ReadOnly Property DigestValue As String Implements IComponentInputData.DigestValue + Public ReadOnly Property DigestValue As DigestData Implements IComponentInputData.DigestValue Get - Return "" + Return Nothing End Get End Property diff --git a/VECTO/Input Files/Gearbox.vb b/VECTO/Input Files/Gearbox.vb index 7e71142719..b579746241 100644 --- a/VECTO/Input Files/Gearbox.vb +++ b/VECTO/Input Files/Gearbox.vb @@ -331,9 +331,9 @@ Public Class Gearbox End Get End Property - Public ReadOnly Property DigestValue As String Implements IComponentInputData.DigestValue + Public ReadOnly Property DigestValue As DigestData Implements IComponentInputData.DigestValue Get - Return "" + Return Nothing End Get End Property diff --git a/VECTO/Input Files/VectoEPTPJob.vb b/VECTO/Input Files/VectoEPTPJob.vb index f0e35fd2d4..21751d63aa 100644 --- a/VECTO/Input Files/VectoEPTPJob.vb +++ b/VECTO/Input Files/VectoEPTPJob.vb @@ -14,6 +14,7 @@ Imports TUGraz.VectoCore.InputData.FileIO.XML.Declaration Imports TUGraz.VectoCore.InputData.Impl Imports TUGraz.VectoCore.Models.Declaration Imports TUGraz.VectoCore.Utils +Imports TUGraz.VectoHashing <CustomValidation(GetType(VectoVTPJob), "ValidateJob")> Public Class VectoVTPJob @@ -115,6 +116,11 @@ Public Class VectoVTPJob End Get End Property + Public ReadOnly Property IVTPDeclarationJobInputData_ManufacturerReportInputData As IManufacturerReport Implements IVTPDeclarationJobInputData.ManufacturerReportInputData + + Public ReadOnly Property VectoJobHash As IVectoHash Implements IVTPDeclarationJobInputData.VectoJobHash + Public ReadOnly Property VectoManufacturerReportHash As IVectoHash Implements IVTPDeclarationJobInputData.VectoManufacturerReportHash + Public ReadOnly Property Cycles As IList(Of ICycleData) Implements IVTPEngineeringJobInputData.Cycles Get Dim retVal As ICycleData() = New ICycleData(CycleFiles.Count - 1) {} @@ -174,6 +180,7 @@ Public Class VectoVTPJob End Get End Property + Public ReadOnly Property IVTPDeclarationInputDataProvider_JobInputData As IVTPDeclarationJobInputData _ Implements IVTPDeclarationInputDataProvider.JobInputData get diff --git a/VECTO/Input Files/Vehicle.vb b/VECTO/Input Files/Vehicle.vb index 73b06f1558..49bc8665e1 100644 --- a/VECTO/Input Files/Vehicle.vb +++ b/VECTO/Input Files/Vehicle.vb @@ -300,9 +300,9 @@ Public Class Vehicle End Get End Property - Public ReadOnly Property DigestValue As String Implements IComponentInputData.DigestValue + Public ReadOnly Property DigestValue As DigestData Implements IComponentInputData.DigestValue Get - Return "" + Return Nothing End Get End Property diff --git a/VectoCommon/VectoHashing/IVectoHash.cs b/VectoCommon/VectoCommon/Hashing/IVectoHash.cs similarity index 98% rename from VectoCommon/VectoHashing/IVectoHash.cs rename to VectoCommon/VectoCommon/Hashing/IVectoHash.cs index e41eb4599a..96a9b21bb4 100644 --- a/VectoCommon/VectoHashing/IVectoHash.cs +++ b/VectoCommon/VectoCommon/Hashing/IVectoHash.cs @@ -1,166 +1,167 @@ -/* -* This file is part of VECTO. -* -* Copyright © 2012-2017 European Union -* -* Developed by Graz University of Technology, -* Institute of Internal Combustion Engines and Thermodynamics, -* Institute of Technical Informatics -* -* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved -* by the European Commission - subsequent versions of the EUPL (the "Licence"); -* You may not use VECTO except in compliance with the Licence. -* You may obtain a copy of the Licence at: -* -* https://joinup.ec.europa.eu/community/eupl/og_page/eupl -* -* Unless required by applicable law or agreed to in writing, VECTO -* distributed under the Licence is distributed on an "AS IS" basis, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the Licence for the specific language governing permissions and -* limitations under the Licence. -* -* Authors: -* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology -* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology -* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology -* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology -* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology -* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology -*/ - -using System.Collections.Generic; -using System.Xml.Linq; - -namespace TUGraz.VectoHashing -{ - /// <summary> - /// Interface definition for hashing and verifying VECTO XML files - /// </summary> - public interface IVectoHash - { - /// <summary> - /// Get a list of all vecto components contained in the XML file. If a certain - /// component appears multiple times (e.g. tires) it is provided multiple times - /// in the returned list. - /// to get a list with unique entries (and the number of occurences) use e.g. - /// GetContainigComponents().GroupBy(s => s).Select(g => new { Entry = g.Key, Count = g.Count() }) - /// </summary> - /// <returns>List of components contained in the current XML document</returns> - IList<VectoComponents> GetContainigComponents(); - - - /// <summary> - /// Get the digest method used to compute the digest value of the top-level Signature element - /// if there is no top-level Signature element, the default digest method is returned (see XMLHashProvider.DefaultDigestMethod) - /// </summary> - /// <returns>identifier (urn) of the digest method</returns> - string GetDigestMethod(); - - - /// <summary> - /// Get the digest method of the Signature element for the given component. If a component exists - /// multiple times (e.g., tires), the index specifies for which component the digest method is returned - /// </summary> - /// <param name="component">VectoComponent to get the digest method for</param> - /// <param name="index">index of the component to use if a component may exist multiple times. Default: 0</param> - /// <returns>identifier (urn) of the digest method</returns> - string GetDigestMethod(VectoComponents component, int index = 0); - - - /// <summary> - /// Get the list of canonicalization methods used to compute the digest value of the top-level Signature element - /// If there is no top-level Signature element, the default digest method is returned (see XMLHashProvider.DefaulCanonicalizationMethod) - /// </summary> - /// <returns>returns a list of identifiers (urns) of the canonicalization methods</returns> - IEnumerable<string> GetCanonicalizationMethods(); - - - /// <summary> - /// Get the list of canonicalization methods used to compute the digest value of the Signature element - /// for the given component. If a component exists multiple times (e.g., tires) the indes specifies for which - /// component the canonicalization method is returned - /// If there is no top-level Signature element, the default digest method is returned (see XMLHashProvider.DefaulCanonicalizationMethod) - /// </summary> - /// <param name="component">VectoComponent to get the canonicalization methods for</param> - /// <param name="index">index of the component to use if a component may exist multiple times. Default: 0</param> - /// <returns>returns a list of identifiers (urns) of the canonicalization methods</returns> - IEnumerable<string> GetCanonicalizationMethods(VectoComponents component, int index = 0); - - - /// <summary> - /// Reads the hash-value of the top-level Signature element - /// </summary> - /// <returns>base64 encoded hash value</returns> - string ReadHash(); - - - /// <summary> - /// Reads the hash-value of the Signature element for the given component. If a component can exist - /// multiple times (i.e., tires), the index specifies for which component the hash is computed - /// </summary> - /// <param name="component">VectoComponent to get the canonicalization methods for</param> - /// <param name="index">index of the component to use if a component may exist multiple times. Default: 0</param> - /// <returns>base64 encoded hash value</returns> - string ReadHash(VectoComponents component, int index = 0); - - - /// <summary> - /// Computes the hash-value of the top-level Data element (or vehicle) - /// If the canoonicalizationMethods is null the canonicalizationMethods from - /// the signature element are read if available or the default canonicalization is applied - /// If the digestMethod is null the digestMethod from the signature element is read if - /// available or the default digestMethod is used - /// Note: the top-level Data element is required to have an id attribute! - /// </summary> - /// <param name="canonicalizationMethods">Canonicalization methods to use. If null the default methods are applied</param> - /// <param name="digestMethod">Digest method to use. If null, the default digest method is used.</param> - /// <returns>base64 encoded hash value</returns> - string ComputeHash(IEnumerable<string> canonicalizationMethods = null, string digestMethod = null); - - - /// <summary> - /// Computes the hash-value for the given component. If a component can exist multiple times - /// (i.e., Tyres) the index specifies for which component the hash is computed - /// If the canoonicalizationMethods is null the canonicalizationMethods from - /// the signature element are read if available or the default canonicalization is applied - /// If the digestMethod is null the digestMethod from the signature element is read if - /// available or the default digestMethod is used - /// Note: the Data element is required to have an id attribute! - /// </summary> - /// <param name="component">VectoComponent to get the canonicalization methods for</param> - /// <param name="index">index of the component to use if a component may exist multiple times. Default: 0</param> - /// <param name="canonicalizationMethods">list of identifiers (urn) of the canonicalization methods to apply. If null, the default canonicalization methods are used</param> - /// <param name="digestMethod">identifier (urn) of the digest method to use. If null, the default digest method is used</param> - /// <returns></returns> - string ComputeHash(VectoComponents component, int index = 0, IEnumerable<string> canonicalizationMethods = null, - string digestMethod = null); - - - /// <summary> - /// Validates the hash of the top-level component (or vehicle) - /// </summary> - /// <returns>true, if the re-computed digest value matches the document's digest value, false otherwise</returns> - bool ValidateHash(); - - - /// <summary> - /// Validates the hash for the given component. - /// </summary> - /// <param name="component">VectoComponent to get the canonicalization methods for</param> - /// <param name="index">index of the component to use if a component may exist multiple times. Default: 0</param> - /// <returns>true, if the re-computed digest value matches the document's digest value, false otherwise</returns> - bool ValidateHash(VectoComponents component, int index = 0); - - - /// <summary> - /// Computes the hash-value of the outer Data element and adds the according Signature element - /// after the Data element. - /// The default CaonocalizationMethods and DigestMethod are used. - /// Note: the id attribute is added to the Data element automatically. if an id attribute is already - /// present its value is overwritten unless its lenth is more than 5 characters. - /// </summary> - /// <returns>returns the given document including the Signature element with the hash of the Data block</returns> - XDocument AddHash(); - } -} +/* +* This file is part of VECTO. +* +* Copyright © 2012-2017 European Union +* +* Developed by Graz University of Technology, +* Institute of Internal Combustion Engines and Thermodynamics, +* Institute of Technical Informatics +* +* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved +* by the European Commission - subsequent versions of the EUPL (the "Licence"); +* You may not use VECTO except in compliance with the Licence. +* You may obtain a copy of the Licence at: +* +* https://joinup.ec.europa.eu/community/eupl/og_page/eupl +* +* Unless required by applicable law or agreed to in writing, VECTO +* distributed under the Licence is distributed on an "AS IS" basis, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the Licence for the specific language governing permissions and +* limitations under the Licence. +* +* Authors: +* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology +* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology +* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology +* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology +* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology +* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology +*/ + +using System.Collections.Generic; +using System.Xml.Linq; +using TUGraz.VectoCommon.Hashing; + +namespace TUGraz.VectoHashing +{ + /// <summary> + /// Interface definition for hashing and verifying VECTO XML files + /// </summary> + public interface IVectoHash + { + /// <summary> + /// Get a list of all vecto components contained in the XML file. If a certain + /// component appears multiple times (e.g. tires) it is provided multiple times + /// in the returned list. + /// to get a list with unique entries (and the number of occurences) use e.g. + /// GetContainigComponents().GroupBy(s => s).Select(g => new { Entry = g.Key, Count = g.Count() }) + /// </summary> + /// <returns>List of components contained in the current XML document</returns> + IList<VectoComponents> GetContainigComponents(); + + + /// <summary> + /// Get the digest method used to compute the digest value of the top-level Signature element + /// if there is no top-level Signature element, the default digest method is returned (see XMLHashProvider.DefaultDigestMethod) + /// </summary> + /// <returns>identifier (urn) of the digest method</returns> + string GetDigestMethod(); + + + /// <summary> + /// Get the digest method of the Signature element for the given component. If a component exists + /// multiple times (e.g., tires), the index specifies for which component the digest method is returned + /// </summary> + /// <param name="component">VectoComponent to get the digest method for</param> + /// <param name="index">index of the component to use if a component may exist multiple times. Default: 0</param> + /// <returns>identifier (urn) of the digest method</returns> + string GetDigestMethod(VectoComponents component, int index = 0); + + + /// <summary> + /// Get the list of canonicalization methods used to compute the digest value of the top-level Signature element + /// If there is no top-level Signature element, the default digest method is returned (see XMLHashProvider.DefaulCanonicalizationMethod) + /// </summary> + /// <returns>returns a list of identifiers (urns) of the canonicalization methods</returns> + IEnumerable<string> GetCanonicalizationMethods(); + + + /// <summary> + /// Get the list of canonicalization methods used to compute the digest value of the Signature element + /// for the given component. If a component exists multiple times (e.g., tires) the indes specifies for which + /// component the canonicalization method is returned + /// If there is no top-level Signature element, the default digest method is returned (see XMLHashProvider.DefaulCanonicalizationMethod) + /// </summary> + /// <param name="component">VectoComponent to get the canonicalization methods for</param> + /// <param name="index">index of the component to use if a component may exist multiple times. Default: 0</param> + /// <returns>returns a list of identifiers (urns) of the canonicalization methods</returns> + IEnumerable<string> GetCanonicalizationMethods(VectoComponents component, int index = 0); + + + /// <summary> + /// Reads the hash-value of the top-level Signature element + /// </summary> + /// <returns>base64 encoded hash value</returns> + string ReadHash(); + + + /// <summary> + /// Reads the hash-value of the Signature element for the given component. If a component can exist + /// multiple times (i.e., tires), the index specifies for which component the hash is computed + /// </summary> + /// <param name="component">VectoComponent to get the canonicalization methods for</param> + /// <param name="index">index of the component to use if a component may exist multiple times. Default: 0</param> + /// <returns>base64 encoded hash value</returns> + string ReadHash(VectoComponents component, int index = 0); + + + /// <summary> + /// Computes the hash-value of the top-level Data element (or vehicle) + /// If the canoonicalizationMethods is null the canonicalizationMethods from + /// the signature element are read if available or the default canonicalization is applied + /// If the digestMethod is null the digestMethod from the signature element is read if + /// available or the default digestMethod is used + /// Note: the top-level Data element is required to have an id attribute! + /// </summary> + /// <param name="canonicalizationMethods">Canonicalization methods to use. If null the default methods are applied</param> + /// <param name="digestMethod">Digest method to use. If null, the default digest method is used.</param> + /// <returns>base64 encoded hash value</returns> + string ComputeHash(IEnumerable<string> canonicalizationMethods = null, string digestMethod = null); + + + /// <summary> + /// Computes the hash-value for the given component. If a component can exist multiple times + /// (i.e., Tyres) the index specifies for which component the hash is computed + /// If the canoonicalizationMethods is null the canonicalizationMethods from + /// the signature element are read if available or the default canonicalization is applied + /// If the digestMethod is null the digestMethod from the signature element is read if + /// available or the default digestMethod is used + /// Note: the Data element is required to have an id attribute! + /// </summary> + /// <param name="component">VectoComponent to get the canonicalization methods for</param> + /// <param name="index">index of the component to use if a component may exist multiple times. Default: 0</param> + /// <param name="canonicalizationMethods">list of identifiers (urn) of the canonicalization methods to apply. If null, the default canonicalization methods are used</param> + /// <param name="digestMethod">identifier (urn) of the digest method to use. If null, the default digest method is used</param> + /// <returns></returns> + string ComputeHash(VectoComponents component, int index = 0, IEnumerable<string> canonicalizationMethods = null, + string digestMethod = null); + + + /// <summary> + /// Validates the hash of the top-level component (or vehicle) + /// </summary> + /// <returns>true, if the re-computed digest value matches the document's digest value, false otherwise</returns> + bool ValidateHash(); + + + /// <summary> + /// Validates the hash for the given component. + /// </summary> + /// <param name="component">VectoComponent to get the canonicalization methods for</param> + /// <param name="index">index of the component to use if a component may exist multiple times. Default: 0</param> + /// <returns>true, if the re-computed digest value matches the document's digest value, false otherwise</returns> + bool ValidateHash(VectoComponents component, int index = 0); + + + /// <summary> + /// Computes the hash-value of the outer Data element and adds the according Signature element + /// after the Data element. + /// The default CaonocalizationMethods and DigestMethod are used. + /// Note: the id attribute is added to the Data element automatically. if an id attribute is already + /// present its value is overwritten unless its lenth is more than 5 characters. + /// </summary> + /// <returns>returns the given document including the Signature element with the hash of the Data block</returns> + XDocument AddHash(); + } +} diff --git a/VectoCommon/VectoHashing/VectoComponents.cs b/VectoCommon/VectoCommon/Hashing/VectoComponents.cs similarity index 96% rename from VectoCommon/VectoHashing/VectoComponents.cs rename to VectoCommon/VectoCommon/Hashing/VectoComponents.cs index 81665bc0e7..0b4d642d43 100644 --- a/VectoCommon/VectoHashing/VectoComponents.cs +++ b/VectoCommon/VectoCommon/Hashing/VectoComponents.cs @@ -1,112 +1,112 @@ -/* -* This file is part of VECTO. -* -* Copyright © 2012-2017 European Union -* -* Developed by Graz University of Technology, -* Institute of Internal Combustion Engines and Thermodynamics, -* Institute of Technical Informatics -* -* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved -* by the European Commission - subsequent versions of the EUPL (the "Licence"); -* You may not use VECTO except in compliance with the Licence. -* You may obtain a copy of the Licence at: -* -* https://joinup.ec.europa.eu/community/eupl/og_page/eupl -* -* Unless required by applicable law or agreed to in writing, VECTO -* distributed under the Licence is distributed on an "AS IS" basis, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the Licence for the specific language governing permissions and -* limitations under the Licence. -* -* Authors: -* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology -* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology -* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology -* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology -* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology -* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology -*/ - -using System; -using TUGraz.VectoCommon.Resources; - -namespace TUGraz.VectoHashing -{ - public enum VectoComponents - { - Engine, - Gearbox, - Axlegear, - Retarder, - TorqueConverter, - Angledrive, - Airdrag, - Tyre, - Vehicle, - VectoOutput, - VectoCustomerInformation - } - - public static class VectoComponentsExtensionMethods - { - public static string XMLElementName(this VectoComponents component) - { - switch (component) { - case VectoComponents.Engine: - return XMLNames.Component_Engine; - case VectoComponents.Gearbox: - return XMLNames.Component_Gearbox; - case VectoComponents.Axlegear: - return XMLNames.Component_Axlegear; - case VectoComponents.Retarder: - return XMLNames.Component_Retarder; - case VectoComponents.TorqueConverter: - return XMLNames.Component_TorqueConverter; - case VectoComponents.Angledrive: - return XMLNames.Component_Angledrive; - case VectoComponents.Airdrag: - return XMLNames.Component_AirDrag; - case VectoComponents.Tyre: - return XMLNames.AxleWheels_Axles_Axle_Tyre; - case VectoComponents.Vehicle: - return XMLNames.Component_Vehicle; - case VectoComponents.VectoOutput: - return "VectoOutput"; - case VectoComponents.VectoCustomerInformation: - return "VectoCustomerInformation"; - default: - throw new ArgumentOutOfRangeException("VectoComponents", component, null); - } - } - - public static string HashIdPrefix(this VectoComponents component) - { - switch (component) { - case VectoComponents.Engine: - return "ENG-"; - case VectoComponents.Gearbox: - return "GBX-"; - case VectoComponents.Axlegear: - return "AXL-"; - case VectoComponents.Retarder: - return "RET-"; - case VectoComponents.TorqueConverter: - return "TC-"; - case VectoComponents.Angledrive: - return "ANGL-"; - case VectoComponents.Airdrag: - return "AD-"; - case VectoComponents.Tyre: - return "TYRE-"; - case VectoComponents.VectoOutput: - return "RESULT-"; - case VectoComponents.VectoCustomerInformation: - return "COC-"; - default: - throw new ArgumentOutOfRangeException("VectoComponents", component, null); - } - } - } +/* +* This file is part of VECTO. +* +* Copyright © 2012-2017 European Union +* +* Developed by Graz University of Technology, +* Institute of Internal Combustion Engines and Thermodynamics, +* Institute of Technical Informatics +* +* VECTO is licensed under the EUPL, Version 1.1 or - as soon they will be approved +* by the European Commission - subsequent versions of the EUPL (the "Licence"); +* You may not use VECTO except in compliance with the Licence. +* You may obtain a copy of the Licence at: +* +* https://joinup.ec.europa.eu/community/eupl/og_page/eupl +* +* Unless required by applicable law or agreed to in writing, VECTO +* distributed under the Licence is distributed on an "AS IS" basis, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the Licence for the specific language governing permissions and +* limitations under the Licence. +* +* Authors: +* Stefan Hausberger, hausberger@ivt.tugraz.at, IVT, Graz University of Technology +* Christian Kreiner, christian.kreiner@tugraz.at, ITI, Graz University of Technology +* Michael Krisper, michael.krisper@tugraz.at, ITI, Graz University of Technology +* Raphael Luz, luz@ivt.tugraz.at, IVT, Graz University of Technology +* Markus Quaritsch, markus.quaritsch@tugraz.at, IVT, Graz University of Technology +* Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology +*/ + +using System; +using TUGraz.VectoCommon.Resources; + +namespace TUGraz.VectoCommon.Hashing +{ + public enum VectoComponents + { + Engine, + Gearbox, + Axlegear, + Retarder, + TorqueConverter, + Angledrive, + Airdrag, + Tyre, + Vehicle, + VectoOutput, + VectoCustomerInformation + } + + public static class VectoComponentsExtensionMethods + { + public static string XMLElementName(this VectoComponents component) + { + switch (component) { + case VectoComponents.Engine: + return XMLNames.Component_Engine; + case VectoComponents.Gearbox: + return XMLNames.Component_Gearbox; + case VectoComponents.Axlegear: + return XMLNames.Component_Axlegear; + case VectoComponents.Retarder: + return XMLNames.Component_Retarder; + case VectoComponents.TorqueConverter: + return XMLNames.Component_TorqueConverter; + case VectoComponents.Angledrive: + return XMLNames.Component_Angledrive; + case VectoComponents.Airdrag: + return XMLNames.Component_AirDrag; + case VectoComponents.Tyre: + return XMLNames.AxleWheels_Axles_Axle_Tyre; + case VectoComponents.Vehicle: + return XMLNames.Component_Vehicle; + case VectoComponents.VectoOutput: + return "VectoOutput"; + case VectoComponents.VectoCustomerInformation: + return "VectoCustomerInformation"; + default: + throw new ArgumentOutOfRangeException("VectoComponents", component, null); + } + } + + public static string HashIdPrefix(this VectoComponents component) + { + switch (component) { + case VectoComponents.Engine: + return "ENG-"; + case VectoComponents.Gearbox: + return "GBX-"; + case VectoComponents.Axlegear: + return "AXL-"; + case VectoComponents.Retarder: + return "RET-"; + case VectoComponents.TorqueConverter: + return "TC-"; + case VectoComponents.Angledrive: + return "ANGL-"; + case VectoComponents.Airdrag: + return "AD-"; + case VectoComponents.Tyre: + return "TYRE-"; + case VectoComponents.VectoOutput: + return "RESULT-"; + case VectoComponents.VectoCustomerInformation: + return "COC-"; + default: + throw new ArgumentOutOfRangeException("VectoComponents", component, null); + } + } + } } \ No newline at end of file diff --git a/VectoCommon/VectoCommon/InputData/DeclarationInputData.cs b/VectoCommon/VectoCommon/InputData/DeclarationInputData.cs index 9bbbb02469..740bd2adbf 100644 --- a/VectoCommon/VectoCommon/InputData/DeclarationInputData.cs +++ b/VectoCommon/VectoCommon/InputData/DeclarationInputData.cs @@ -62,7 +62,7 @@ namespace TUGraz.VectoCommon.InputData string CertificationNumber { get; } - string DigestValue { get; } + DigestData DigestValue { get; } } public interface IVehicleDeclarationInputData : IComponentInputData diff --git a/VectoCommon/VectoCommon/InputData/VTPDeclarationInputData.cs b/VectoCommon/VectoCommon/InputData/VTPDeclarationInputData.cs index 530be45d71..9f7918bb28 100644 --- a/VectoCommon/VectoCommon/InputData/VTPDeclarationInputData.cs +++ b/VectoCommon/VectoCommon/InputData/VTPDeclarationInputData.cs @@ -30,19 +30,30 @@ */ using System.Collections.Generic; +using System.Xml; +using System.Xml.XPath; +using TUGraz.VectoCommon.Hashing; using TUGraz.VectoCommon.Utils; +using TUGraz.VectoHashing; namespace TUGraz.VectoCommon.InputData { public interface IVTPDeclarationInputDataProvider : IInputDataProvider { IVTPDeclarationJobInputData JobInputData { get; } + } public interface IVTPDeclarationJobInputData { IVehicleDeclarationInputData Vehicle { get; } + IManufacturerReport ManufacturerReportInputData { get; } + + IVectoHash VectoJobHash { get; } + + IVectoHash VectoManufacturerReportHash { get; } + IList<ICycleData> Cycles { get; } IEnumerable<double> FanPowerCoefficents { get; } @@ -51,4 +62,63 @@ namespace TUGraz.VectoCommon.InputData Meter FanDiameter { get; } } + + public interface IManufacturerReport + { + IDictionary<VectoComponents,IList<string>> ComponentDigests { get; } + + DigestData JobDigest { get; } + } + + public class DigestData + { + private const string ReferenceQueryXPath = ".//*[local-name()='Reference']/@URI"; + private const string AlgorithmQueryXPath = ".//*[local-name()='Transform']/@Algorithm"; + private const string DigestMethodQueryXPath = ".//*[local-name()='DigestMethod']/@Algorithm"; + private const string DigestValueQuerXPath = ".//*[local-name()='DigestValue']"; + + public DigestData(string reference, string[] c14n, string digestMethod, string digestValue) + { + Reference = reference; + CanonicalizationMethods = c14n; + DigestMethod = digestMethod; + DigestValue = digestValue; + } + + public DigestData(XPathNavigator navigator) + { + Reference = navigator.SelectSingleNode(ReferenceQueryXPath)?.InnerXml; + var nodes = navigator.Select(AlgorithmQueryXPath); + var c14n = new List<string>(); + while (nodes.MoveNext()) { + c14n.Add(nodes.Current.InnerXml); + } + CanonicalizationMethods = c14n.ToArray(); + DigestMethod = navigator.SelectSingleNode(DigestMethodQueryXPath)?.InnerXml; + DigestValue = navigator.SelectSingleNode(DigestValueQuerXPath)?.InnerXml; + } + + public DigestData(XmlNode xmlNode) + { + Reference = xmlNode.SelectSingleNode(ReferenceQueryXPath)?.InnerXml; + var nodes = xmlNode.SelectNodes(AlgorithmQueryXPath); + var c14n = new List<string>(); + if (nodes != null) { + for (var i = 0; i < nodes.Count; i++) { + c14n.Add(nodes[i].InnerXml); + } + } + CanonicalizationMethods = c14n.ToArray(); + DigestMethod = xmlNode.SelectSingleNode(DigestMethodQueryXPath)?.InnerXml; + DigestValue = xmlNode.SelectSingleNode(DigestValueQuerXPath)?.InnerXml; + } + + public string DigestValue { get; } + + public string Reference { get; } + + public string[] CanonicalizationMethods { get; } + public string DigestMethod { get; } + + } } diff --git a/VectoCommon/VectoCommon/Utils/SI.cs b/VectoCommon/VectoCommon/Utils/SI.cs index 658a9a8b32..ed8559e923 100644 --- a/VectoCommon/VectoCommon/Utils/SI.cs +++ b/VectoCommon/VectoCommon/Utils/SI.cs @@ -42,1720 +42,1720 @@ using TUGraz.VectoCommon.Exceptions; namespace TUGraz.VectoCommon.Utils { - /// <summary> - /// SI Class for Scalar Values. Converts implicitely to double and is only castable if the SI value has no units. - /// </summary> - public class Scalar : SIBase<Scalar> - { - private static readonly int[] Units = { 0, 0, 0, 0, 0, 0, 0 }; - - [DebuggerHidden] - private Scalar(double val) : base(val, Units) { } - - public static implicit operator double(Scalar self) - { - return self.Val; - } - - [DebuggerHidden] - public static Scalar operator +(Scalar si1, Scalar si2) - { - return Create(si1.Val + si2.Val); - } - - [DebuggerHidden] - public static Scalar operator +(Scalar si1, double si2) - { - return Create(si1.Val + si2); - } - - [DebuggerHidden] - public static Scalar operator +(double si1, Scalar si2) - { - return Create(si1 + si2.Val); - } - - [DebuggerHidden] - public static Scalar operator -(Scalar si1, Scalar si2) - { - return Create(si1.Val - si2.Val); - } - - [DebuggerHidden] - public static Scalar operator -(Scalar si1, double si2) - { - return Create(si1.Val - si2); - } - - [DebuggerHidden] - public static Scalar operator -(double si1, Scalar si2) - { - return Create(si1 - si2.Val); - } - } - - /// <summary> - /// SI Class for Newton [N]. - /// </summary> - public class Newton : SIBase<Newton> - { - private static readonly int[] Units = { 1, 1, -2, 0, 0, 0, 0 }; - - [DebuggerHidden] - private Newton(double val) : base(val, Units) { } - - public override string UnitString { get { return "N"; } } + /// <summary> + /// SI Class for Scalar Values. Converts implicitely to double and is only castable if the SI value has no units. + /// </summary> + public class Scalar : SIBase<Scalar> + { + private static readonly int[] Units = { 0, 0, 0, 0, 0, 0, 0 }; [DebuggerHidden] - public static NewtonMeter operator *(Newton newton, Meter meter) - { - return SIBase<NewtonMeter>.Create(newton.Val * meter.Value()); - } - - [DebuggerHidden] - public static Watt operator *(Newton newton, MeterPerSecond meterPerSecond) - { - return SIBase<Watt>.Create(newton.Val * meterPerSecond.Value()); - } - - [DebuggerHidden] - public static Watt operator *(MeterPerSecond meterPerSecond, Newton newton) - { - return SIBase<Watt>.Create(newton.Val * meterPerSecond.Value()); - } - } - - /// <summary> - /// SI Class for Radian [] (rad). - /// </summary> - public class Radian : SIBase<Radian> - { - private static readonly int[] Units = { 0, 0, 0, 0, 0, 0, 0 }; - - [DebuggerHidden] - private Radian(double val) : base(val, Units) { } - } - - /// <summary> - /// SI Class for PerSquareSecond [1/s^2]. - /// </summary> - public class PerSquareSecond : SIBase<PerSquareSecond> - { - private static readonly int[] Units = { 0, 0, -2, 0, 0, 0, 0 }; - - [DebuggerHidden] - private PerSquareSecond(double val) : base(val, Units) { } - - [DebuggerHidden] - public static PerSecond operator *(PerSquareSecond perSquareSecond, Second second) - { - return SIBase<PerSecond>.Create(perSquareSecond.Val * second.Value()); - } - } - - /// <summary> - /// SI Class for Meter per square second [m/s^2]. - /// </summary> - public class MeterPerSquareSecond : SIBase<MeterPerSquareSecond> - { - private static readonly int[] Units = { 0, 1, -2, 0, 0, 0, 0 }; - - [DebuggerHidden] - private MeterPerSquareSecond(double val) : base(val, Units) { } - - /// <summary> - /// Implements the operator *. - /// </summary> - [DebuggerHidden] - public static MeterPerSecond operator *(MeterPerSquareSecond meterPerSecond, Second second) - { - return SIBase<MeterPerSecond>.Create(meterPerSecond.Val * second.Value()); - } - } - - /// <summary> - /// SI Class for Second [s]. - /// </summary> - public class Second : SIBase<Second> - { - private static readonly int[] Units = { 0, 0, 1, 0, 0, 0, 0 }; - - [DebuggerHidden] - private Second(double val) : base(val, Units) { } - } - - /// <summary> - /// SI Class for Meter [m]. - /// </summary> - public class Meter : SIBase<Meter> - { - private static readonly int[] Units = { 0, 1, 0, 0, 0, 0, 0 }; - - [DebuggerHidden] - private Meter(double val) : base(val, Units) { } - - [DebuggerHidden] - public static MeterPerSecond operator /(Meter meter, Second second) - { - return SIBase<MeterPerSecond>.Create(meter.Val / second.Value()); - } - - [DebuggerHidden] - public static MeterPerSecond operator *(Meter meter, PerSecond perSecond) - { - return SIBase<MeterPerSecond>.Create(meter.Val * perSecond.Value()); - } - - /// <summary> - /// Implements the operator /. - /// </summary> - [DebuggerHidden] - public static Second operator /(Meter second, MeterPerSecond meterPerSecond) - { - return SIBase<Second>.Create(second.Val / meterPerSecond.Value()); - } - } - - /// <summary> - /// SI Class for KilogramPerMeter [kg/m]. - /// </summary> - public class KilogramPerMeter : SIBase<KilogramPerMeter> - { - private static readonly int[] Units = { 1, -1, 0, 0, 0, 0, 0 }; - - [DebuggerHidden] - private KilogramPerMeter(double val) : base(val, Units) { } - - public override string UnitString { get { return "kg/m"; } } + private Scalar(double val) : base(val, Units) { } - public static KilogramPerMeterMass operator /(KilogramPerMeter kpm, Kilogram kg) + public static implicit operator double(Scalar self) { - return SIBase<KilogramPerMeterMass>.Create(kpm.Val / kg.Value()); + return self.Val; } - public static KilogramPerMeterCubicMeter operator /(KilogramPerMeter kpm, CubicMeter vol) + [DebuggerHidden] + public static Scalar operator +(Scalar si1, Scalar si2) { - return SIBase<KilogramPerMeterCubicMeter>.Create(kpm.Val / vol.Value()); + return Create(si1.Val + si2.Val); } - } - /// <summary> - /// SI Class for Liter per Second [l/s]. - /// </summary> - public class LiterPerSecond : SIBase<LiterPerSecond> - { - private static readonly int[] Units = { 0, 3, -1, 0, 0, 0, 0 }; + [DebuggerHidden] + public static Scalar operator +(Scalar si1, double si2) + { + return Create(si1.Val + si2); + } - private LiterPerSecond(double val) : base(val, 0.001, Units) { } + [DebuggerHidden] + public static Scalar operator +(double si1, Scalar si2) + { + return Create(si1 + si2.Val); + } - public override string UnitString { get { return "l/s"; } } + [DebuggerHidden] + public static Scalar operator -(Scalar si1, Scalar si2) + { + return Create(si1.Val - si2.Val); + } [DebuggerHidden] - public static Liter operator *(LiterPerSecond l, Second second) + public static Scalar operator -(Scalar si1, double si2) { - return SIBase<Liter>.Create(l.Val * second.Value()); + return Create(si1.Val - si2); } [DebuggerHidden] - public static Liter operator *(Second second, LiterPerSecond l) + public static Scalar operator -(double si1, Scalar si2) { - return SIBase<Liter>.Create(l.Val * second.Value()); + return Create(si1 - si2.Val); } } - /// <summary> - /// SI Class for Kilogram [kg]. - /// </summary> - public class Kilogram : SIBase<Kilogram> - { - private static readonly int[] Units = { 1, 0, 0, 0, 0, 0, 0 }; - - [DebuggerHidden] - private Kilogram(double val) : base(val, Units) { } - - [DebuggerHidden] - public static KilogramPerSecond operator /(Kilogram kg, Second second) - { - return SIBase<KilogramPerSecond>.Create(kg.Val / second.Value()); - } - - //[DebuggerHidden] - //public static SI operator /(Kilogram kg, Joule j) - //{ - // return (kg as SI) / j; - //} - - [DebuggerHidden] - public static Scalar operator /(Kilogram kg, Kilogram kg2) - { - return SIBase<Scalar>.Create(kg.Val / kg2.Val); - } - - [DebuggerHidden] - public static KilogramPerMeter operator /(Kilogram kg, Meter m) - { - return SIBase<KilogramPerMeter>.Create(kg.Val / m.Value()); - } + /// <summary> + /// SI Class for Newton [N]. + /// </summary> + public class Newton : SIBase<Newton> + { + private static readonly int[] Units = { 1, 1, -2, 0, 0, 0, 0 }; [DebuggerHidden] - public static SpecificFuelConsumption operator /(Kilogram kg, WattSecond ws) + private Newton(double val) : base(val, Units) { } + + public override string UnitString { get { return "N"; } } + + [DebuggerHidden] + public static NewtonMeter operator *(Newton newton, Meter meter) { - return SIBase<SpecificFuelConsumption>.Create(kg.Val / ws.Value()); + return SIBase<NewtonMeter>.Create(newton.Val * meter.Value()); } [DebuggerHidden] - public static Newton operator *(Kilogram kg, MeterPerSquareSecond m) - { - return SIBase<Newton>.Create(kg.Val * m.Value()); - } + public static Watt operator *(Newton newton, MeterPerSecond meterPerSecond) + { + return SIBase<Watt>.Create(newton.Val * meterPerSecond.Value()); + } - [DebuggerHidden] - public static Kilogram operator *(Kilogram kg, double d) - { - return new Kilogram(kg.Val * d); - } + [DebuggerHidden] + public static Watt operator *(MeterPerSecond meterPerSecond, Newton newton) + { + return SIBase<Watt>.Create(newton.Val * meterPerSecond.Value()); + } + } - [DebuggerHidden] - public static Kilogram operator *(double d, Kilogram kg) - { - return new Kilogram(d * kg.Val); - } + /// <summary> + /// SI Class for Radian [] (rad). + /// </summary> + public class Radian : SIBase<Radian> + { + private static readonly int[] Units = { 0, 0, 0, 0, 0, 0, 0 }; - public static CubicMeter operator /(Kilogram kilogram, KilogramPerCubicMeter kilogramPerCubicMeter) - { - return SIBase<CubicMeter>.Create(kilogram.Value() / kilogramPerCubicMeter.Value()); - } - } + [DebuggerHidden] + private Radian(double val) : base(val, Units) { } + } - public class Liter : SIBase<Liter> - { - private static readonly int[] Units = { 0, 3, 0, 0, 0, 0, 0 }; + /// <summary> + /// SI Class for PerSquareSecond [1/s^2]. + /// </summary> + public class PerSquareSecond : SIBase<PerSquareSecond> + { + private static readonly int[] Units = { 0, 0, -2, 0, 0, 0, 0 }; - [DebuggerHidden] - //[DebuggerHidden] - private Liter(double val) : base(val , 0.001, Units) { } + [DebuggerHidden] + private PerSquareSecond(double val) : base(val, Units) { } - public override string UnitString { get { return "l"; } } + [DebuggerHidden] + public static PerSecond operator *(PerSquareSecond perSquareSecond, Second second) + { + return SIBase<PerSecond>.Create(perSquareSecond.Val * second.Value()); + } + } - public static Kilogram operator *(Liter liter, KilogramPerCubicMeter kilogramPerCubicMeter) - { - return SIBase<Kilogram>.Create(liter.AsBasicUnit * kilogramPerCubicMeter.Value()); - } - } + /// <summary> + /// SI Class for Meter per square second [m/s^2]. + /// </summary> + public class MeterPerSquareSecond : SIBase<MeterPerSquareSecond> + { + private static readonly int[] Units = { 0, 1, -2, 0, 0, 0, 0 }; - /// <summary> - /// - /// </summary> - public class NormLiter : SIBase<NormLiter> - { - private static readonly int[] Units = { 0, 3, 0, 0, 0, 0, 0 }; + [DebuggerHidden] + private MeterPerSquareSecond(double val) : base(val, Units) { } - //[DebuggerHidden] - private NormLiter(double val) : base(val , 0.001, Units) { } + /// <summary> + /// Implements the operator *. + /// </summary> + [DebuggerHidden] + public static MeterPerSecond operator *(MeterPerSquareSecond meterPerSecond, Second second) + { + return SIBase<MeterPerSecond>.Create(meterPerSecond.Val * second.Value()); + } + } - public override string UnitString { get { return "Nl"; } } + /// <summary> + /// SI Class for Second [s]. + /// </summary> + public class Second : SIBase<Second> + { + private static readonly int[] Units = { 0, 0, 1, 0, 0, 0, 0 }; - public static NormLiterPerSecond operator /(NormLiter nl, Second s) - { - return SIBase<NormLiterPerSecond>.Create(nl.Val / s.Value()); - } - } - - /// <summary> - /// - /// </summary> - public class NormLiterPerSecond : SIBase<NormLiterPerSecond> - { - private static readonly int[] Units = { 0, 3, -1, 0, 0, 0, 0 }; + [DebuggerHidden] + private Second(double val) : base(val, Units) { } + } - //[DebuggerHidden] - private NormLiterPerSecond(double val) : base(val, 0.001, Units) { } + /// <summary> + /// SI Class for Meter [m]. + /// </summary> + public class Meter : SIBase<Meter> + { + private static readonly int[] Units = { 0, 1, 0, 0, 0, 0, 0 }; - public override string UnitString { get { return "Nl/s"; } } + [DebuggerHidden] + private Meter(double val) : base(val, Units) { } - public static NormLiter operator *(NormLiterPerSecond nips, Second s) - { - return SIBase<NormLiter>.Create(nips.Val * s.Value()); - } + [DebuggerHidden] + public static MeterPerSecond operator /(Meter meter, Second second) + { + return SIBase<MeterPerSecond>.Create(meter.Val / second.Value()); + } - public static NormLiterPerSecond operator *(NormLiterPerSecond nps, double val) - { - return Create(nps.Val * val); - } + [DebuggerHidden] + public static MeterPerSecond operator *(Meter meter, PerSecond perSecond) + { + return SIBase<MeterPerSecond>.Create(meter.Val * perSecond.Value()); + } - public static NormLiterPerSecond operator /(NormLiterPerSecond nps, double val) + /// <summary> + /// Implements the operator /. + /// </summary> + [DebuggerHidden] + public static Second operator /(Meter second, MeterPerSecond meterPerSecond) { - return Create(nps.Val / val); + return SIBase<Second>.Create(second.Val / meterPerSecond.Value()); } } - /// <summary> - /// SI Class for Kilogram per Second [kg]. - /// </summary> - public class KilogramPerSecond : SIBase<KilogramPerSecond> - { - private static readonly int[] Units = { 1, 0, -1, 0, 0, 0, 0 }; - - [DebuggerHidden] - private KilogramPerSecond(double value) : base(value, Units) { } - - [DebuggerHidden] - public static Kilogram operator *(KilogramPerSecond kilogramPerSecond, Second second) - { - return SIBase<Kilogram>.Create(kilogramPerSecond.Val * second.Value()); - } - } - - /// <summary> - /// SI Class for Square meter [m^2]. - /// </summary> - public class SquareMeter : SIBase<SquareMeter> - { - private static readonly int[] Units = { 0, 2, 0, 0, 0, 0, 0 }; - - [DebuggerHidden] - private SquareMeter(double value) : base(value, Units) { } - } - - /// <summary> - /// SI Class for cubic meter [m^3]. - /// </summary> - public class CubicMeter : SIBase<CubicMeter> - { - private static readonly int[] Units = { 0, 3, 0, 0, 0, 0, 0 }; - - [DebuggerHidden] - private CubicMeter(double value) - : base(value, Units) { } - } - - /// <summary> - /// SI Class for Kilogram Square Meter [kgm^2]. - /// </summary> - public class KilogramSquareMeter : SIBase<KilogramSquareMeter> - { - private static readonly int[] Units = { 1, 2, 0, 0, 0, 0, 0 }; - - [DebuggerHidden] - private KilogramSquareMeter(double value) : base(value, Units) { } - - [DebuggerHidden] - public static NewtonMeter operator *(KilogramSquareMeter kilogramSquareMeter, PerSquareSecond perSquareSecond) - { - return SIBase<NewtonMeter>.Create(kilogramSquareMeter.Val * perSquareSecond.Value()); - } - } - - /// <summary> - /// SI Class for Kilogram per Cubic Meter [kg/m^3]. - /// </summary> - public class KilogramPerCubicMeter : SIBase<KilogramPerCubicMeter> - { - private static readonly int[] Units = { 1, -3, 0, 0, 0, 0, 0 }; - - [DebuggerHidden] - private KilogramPerCubicMeter(double value) : base(value, Units) { } - - public override string UnitString { get { return "kg/m^3"; } } + /// <summary> + /// SI Class for KilogramPerMeter [kg/m]. + /// </summary> + public class KilogramPerMeter : SIBase<KilogramPerMeter> + { + private static readonly int[] Units = { 1, -1, 0, 0, 0, 0, 0 }; [DebuggerHidden] - public static Kilogram operator *(KilogramPerCubicMeter kilogramPerCubicMeter, CubicMeter cubicMeter) - { - return SIBase<Kilogram>.Create(kilogramPerCubicMeter.Val * cubicMeter.Value()); - } - - } + private KilogramPerMeter(double val) : base(val, Units) { } - /// <summary> - /// SI Class for Kilogramm per watt second [kg/Ws]. - /// W = kgm^2/s^3 - /// </summary> - public class KilogramPerWattSecond : SIBase<KilogramPerWattSecond> - { - private static readonly int[] Units = { 0, -2, 2, 0, 0, 0, 0 }; + public override string UnitString { get { return "kg/m"; } } - [DebuggerHidden] - private KilogramPerWattSecond(double val) : base(val, Units) { } + public static KilogramPerMeterMass operator /(KilogramPerMeter kpm, Kilogram kg) + { + return SIBase<KilogramPerMeterMass>.Create(kpm.Val / kg.Value()); + } - public override string UnitString { get { return "kg/Ws"; } } + public static KilogramPerMeterCubicMeter operator /(KilogramPerMeter kpm, CubicMeter vol) + { + return SIBase<KilogramPerMeterCubicMeter>.Create(kpm.Val / vol.Value()); + } } - /// <summary> - /// SI Class for watt second [Ws]. - /// W = kgm^2/s^3 - /// </summary> - public class WattSecond : SIBase<WattSecond> - { - private static readonly int[] Units = { 1, 2, -2, 0, 0, 0, 0 }; + /// <summary> + /// SI Class for Liter per Second [l/s]. + /// </summary> + public class LiterPerSecond : SIBase<LiterPerSecond> + { + private static readonly int[] Units = { 0, 3, -1, 0, 0, 0, 0 }; - [DebuggerHidden] - private WattSecond(double val) : base(val, Units) { } + private LiterPerSecond(double val) : base(val, 0.001, Units) { } - public override string UnitString { get { return "Ws"; } } + public override string UnitString { get { return "l/s"; } } [DebuggerHidden] - public static Watt operator /(WattSecond wattSecond, Second second) - { - return SIBase<Watt>.Create(wattSecond.Val / second.Value()); - } - } - - /// <summary> - /// SI Class for Watt [W]. - /// </summary> - public class Watt : SIBase<Watt> - { - private static readonly int[] Units = { 1, 2, -3, 0, 0, 0, 0 }; + public static Liter operator *(LiterPerSecond l, Second second) + { + return SIBase<Liter>.Create(l.Val * second.Value()); + } - [DebuggerHidden] - private Watt(double val) : base(val, Units) { } + [DebuggerHidden] + public static Liter operator *(Second second, LiterPerSecond l) + { + return SIBase<Liter>.Create(l.Val * second.Value()); + } + } - public override string UnitString { get { return "W"; } } + /// <summary> + /// SI Class for Kilogram [kg]. + /// </summary> + public class Kilogram : SIBase<Kilogram> + { + private static readonly int[] Units = { 1, 0, 0, 0, 0, 0, 0 }; - /// <summary> - /// Implements the operator /. - /// </summary> - /// <param name="watt">The watt.</param> - /// <param name="newtonMeter">The newton meter.</param> - /// <returns> - /// The result of the operator. - /// </returns> [DebuggerHidden] - public static PerSecond operator /(Watt watt, NewtonMeter newtonMeter) - { - return SIBase<PerSecond>.Create(watt.Val / newtonMeter.Value()); - } - - [DebuggerHidden] - public static Newton operator /(Watt watt, MeterPerSecond meterPerSecond) - { - return SIBase<Newton>.Create(watt.Val / meterPerSecond.Value()); - } - - /// <summary> - /// Implements the operator /. - /// </summary> - /// <param name="watt">The watt.</param> - /// <param name="perSecond">The per second.</param> - /// <returns> - /// The result of the operator. - /// </returns> - [DebuggerHidden] - public static NewtonMeter operator /(Watt watt, PerSecond perSecond) - { - return SIBase<NewtonMeter>.Create(watt.Val / perSecond.Value()); - } - - [DebuggerHidden] - public static WattSecond operator *(Watt watt, Second second) - { - return SIBase<WattSecond>.Create(watt.Val * second.Value()); - } - - [DebuggerHidden] - public static Watt operator *(Watt watt, double val) - { - return Create(watt.Val * val); - } - } - - /// <summary> - /// SI Class for Joule [J]. - /// J = Ws = kgm^2/s^2 - /// </summary> - public class Joule : SIBase<Joule> - { - private static readonly int[] Units = { 1, 2, -2, 0, 0, 0, 0 }; - - [DebuggerHidden] - private Joule(double val) : base(val, Units) { } - - public override string UnitString { get { return "J"; } } + private Kilogram(double val) : base(val, Units) { } - public static implicit operator Joule(WattSecond self) - { - return Create(self.Value()); - } + [DebuggerHidden] + public static KilogramPerSecond operator /(Kilogram kg, Second second) + { + return SIBase<KilogramPerSecond>.Create(kg.Val / second.Value()); + } - public static Joule operator +(Joule joule, WattSecond ws) - { - return Create(joule.Val + ws.Value()); - } + //[DebuggerHidden] + //public static SI operator /(Kilogram kg, Joule j) + //{ + // return (kg as SI) / j; + //} - public static Watt operator /(Joule joule, Second s) - { - return SIBase<Watt>.Create(joule.Val / s.Value()); - } + [DebuggerHidden] + public static Scalar operator /(Kilogram kg, Kilogram kg2) + { + return SIBase<Scalar>.Create(kg.Val / kg2.Val); + } - public static JoulePerMeter operator /(Joule joule, Meter meter) - { - return SIBase<JoulePerMeter>.Create(joule.Val / meter.Value()); - } - } + [DebuggerHidden] + public static KilogramPerMeter operator /(Kilogram kg, Meter m) + { + return SIBase<KilogramPerMeter>.Create(kg.Val / m.Value()); + } - /// <summary> - /// SI Class for Joule / kg. - /// </summary> - public class JoulePerKilogramm : SIBase<JoulePerKilogramm> - { - private static readonly int[] Units = { 0, 2, -2, 0, 0, 0, 0 }; + [DebuggerHidden] + public static SpecificFuelConsumption operator /(Kilogram kg, WattSecond ws) + { + return SIBase<SpecificFuelConsumption>.Create(kg.Val / ws.Value()); + } - private JoulePerKilogramm(double val) : base(val, Units) { } + [DebuggerHidden] + public static Newton operator *(Kilogram kg, MeterPerSquareSecond m) + { + return SIBase<Newton>.Create(kg.Val * m.Value()); + } - public override string UnitString { get { return "J/kg"; } } + [DebuggerHidden] + public static Kilogram operator *(Kilogram kg, double d) + { + return new Kilogram(kg.Val * d); + } - public static Joule operator *(Kilogram kg, JoulePerKilogramm jpg) - { - return SIBase<Joule>.Create(kg.Value() * jpg.Val); - } - } - - /// <summary> - /// SI Class for Joule per Meter [J/m]. - /// J = Ws - /// W = kgm^2/s^3 - /// </summary> - public class JoulePerMeter : SIBase<JoulePerMeter> - { - private static readonly int[] Units = { 1, 1, -2, 0, 0, 0, 0 }; - - [DebuggerHidden] - private JoulePerMeter(double val) : base(val, Units) { } + [DebuggerHidden] + public static Kilogram operator *(double d, Kilogram kg) + { + return new Kilogram(d * kg.Val); + } - public override string UnitString { get { return "J/m"; } } + public static CubicMeter operator /(Kilogram kilogram, KilogramPerCubicMeter kilogramPerCubicMeter) + { + return SIBase<CubicMeter>.Create(kilogram.Value() / kilogramPerCubicMeter.Value()); + } } - /// <summary> - /// SI Class for one per second [1/s]. - /// </summary> - [DebuggerDisplay("rad/s: {Val} | rpm: {AsRPM}")] - public class PerSecond : SIBase<PerSecond> - { - private static readonly int[] Units = { 0, 0, -1, 0, 0, 0, 0 }; - - [DebuggerHidden] - private PerSecond(double val) : base(val, Units) { } - - [DebuggerHidden] - public static PerSquareSecond operator /(PerSecond perSecond, Second second) - { - return SIBase<PerSquareSecond>.Create(perSecond.Val / second.Value()); - } - - public double AsRPM - { - get { return Val * 60 / (2 * Math.PI); } - } - } - - /// <summary> - /// SI Class for Meter per second [m/s]. - /// </summary> - [DebuggerDisplay("{Val} | {AsKmph}")] - public class MeterPerSecond : SIBase<MeterPerSecond> - { - private static readonly int[] Units = { 0, 1, -1, 0, 0, 0, 0 }; - - [DebuggerHidden] - private MeterPerSecond(double val) : base(val, Units) { } - - public double AsKmph - { - get { return Val * 3.6; } - } - - /// <summary> - /// Implements the operator /. - /// </summary> - [DebuggerHidden] - public static PerSecond operator /(MeterPerSecond meterPerSecond, Meter meter) - { - return SIBase<PerSecond>.Create(meterPerSecond.Val / meter.Value()); - } - - /// <summary> - /// Implements the operator /. - /// </summary> - [DebuggerHidden] - public static Second operator /(MeterPerSecond meterPerSecond, MeterPerSquareSecond meterPerSquareSecond) - { - return SIBase<Second>.Create(meterPerSecond.Val / meterPerSquareSecond.Value()); - } - - /// <summary> - /// Implements the operator /. - /// </summary> - [DebuggerHidden] - public static MeterPerSquareSecond operator /(MeterPerSecond meterPerSecond, Second second) - { - return SIBase<MeterPerSquareSecond>.Create(meterPerSecond.Val / second.Value()); - } - - /// <summary> - /// Implements the operator *. - /// </summary> - [DebuggerHidden] - public static Meter operator *(MeterPerSecond meterPerSecond, Second second) - { - return SIBase<Meter>.Create(meterPerSecond.Val * second.Value()); - } - - /// <summary> - /// Implements the operator *. - /// </summary> - [DebuggerHidden] - public static MeterPerSquareSecond operator *(MeterPerSecond meterPerSecond, PerSecond perSecond) - { - return SIBase<MeterPerSquareSecond>.Create(meterPerSecond.Val * perSecond.Value()); - } - - /// <summary> - /// Implements the operator *. - /// </summary> - [DebuggerHidden] - public static Meter operator *(Second second, MeterPerSecond meterPerSecond) - { - return SIBase<Meter>.Create(second.Value() * meterPerSecond.Val); - } - } - - /// <summary> - /// SI Class for NewtonMeter [Nm]. - /// N = kgm/s^2 - /// </summary> - public class NewtonMeter : SIBase<NewtonMeter> - { - private static readonly int[] Units = { 1, 2, -2, 0, 0, 0, 0 }; - - [DebuggerHidden] - private NewtonMeter(double val) : base(val, Units) { } - - public override string UnitString { get { return "Nm"; } } + public class Liter : SIBase<Liter> + { + private static readonly int[] Units = { 0, 3, 0, 0, 0, 0, 0 }; [DebuggerHidden] - public static Watt operator *(NewtonMeter newtonMeter, PerSecond perSecond) - { - return SIBase<Watt>.Create(newtonMeter.Val * perSecond.Value()); - } - - [DebuggerHidden] - public static Watt operator *(PerSecond perSecond, NewtonMeter newtonMeter) - { - return SIBase<Watt>.Create(perSecond.Value() * newtonMeter.Val); - } - - [DebuggerHidden] - public static Second operator /(NewtonMeter newtonMeter, Watt watt) - { - return SIBase<Second>.Create(newtonMeter.Val / watt.Value()); - } - - [DebuggerHidden] - public static PerSquareSecond operator /(NewtonMeter newtonMeter, KilogramSquareMeter kgKilogramSquareMeter) - { - return SIBase<PerSquareSecond>.Create(newtonMeter.Val / kgKilogramSquareMeter.Value()); - } - - [DebuggerHidden] - public static PerSecond operator /(NewtonMeter newtonMeter, NewtonMeterSecond newtonMeterSecond) - { - return SIBase<PerSecond>.Create(newtonMeter.Val / newtonMeterSecond.Value()); - } - - [DebuggerHidden] - public static Newton operator /(NewtonMeter newtonMeter, Meter meter) - { - return SIBase<Newton>.Create(newtonMeter.Val / meter.Value()); - } - - [DebuggerHidden] - public static NewtonMeterSecond operator /(NewtonMeter newtonMeter, PerSecond perSecond) - { - return SIBase<NewtonMeterSecond>.Create(newtonMeter.Val / perSecond.Value()); - } - } - - /// <summary> - /// SI Class for NewtonMeterSecond [Nms]. - /// N = kgm/s^2 - /// </summary> - public class NewtonMeterSecond : SIBase<NewtonMeterSecond> - { - private static readonly int[] Units = { 1, 2, -1, 0, 0, 0, 0 }; - private NewtonMeterSecond(double val) : base(val, Units) { } + //[DebuggerHidden] + private Liter(double val) : base(val , 0.001, Units) { } - public override string UnitString { get { return "Nms"; } } + public override string UnitString { get { return "l"; } } + + public static Kilogram operator *(Liter liter, KilogramPerCubicMeter kilogramPerCubicMeter) + { + return SIBase<Kilogram>.Create(liter.AsBasicUnit * kilogramPerCubicMeter.Value()); + } } - /// <summary> - /// SI Class for Amperer [A]. - /// </summary> - public class Ampere : SIBase<Ampere> - { - private static readonly int[] Units = { 0, 0, 0, 1, 0, 0, 0 }; - private Ampere(double val) : base(val, Units) { } - - public static Watt operator *(Ampere ampere, Volt volt) - { - return SIBase<Watt>.Create(volt.Value() * ampere.Val); - } - - public static Ampere operator *(Ampere ampere, double val) - { - return Create(ampere.Val * val); - } - - public static Volt operator /(Watt watt, Ampere ampere) - { - return SIBase<Volt>.Create(watt.Value() / ampere.Value()); - } - } - - /// <summary> - /// SI Class for Amperer [V]. - /// V = kgm^2/As^2 - /// </summary> - public class Volt : SIBase<Volt> - { - private static readonly int[] Units = { 1, 2, -2, -1, 0, 0, 0 }; - private Volt(double val) : base(val, Units) { } + /// <summary> + /// + /// </summary> + public class NormLiter : SIBase<NormLiter> + { + private static readonly int[] Units = { 0, 3, 0, 0, 0, 0, 0 }; - public override string UnitString { get { return "V"; } } + //[DebuggerHidden] + private NormLiter(double val) : base(val , 0.001, Units) { } - public static Watt operator *(Volt volt, Ampere ampere) - { - return SIBase<Watt>.Create(volt.Val * ampere.Value()); - } + public override string UnitString { get { return "Nl"; } } - public static Ampere operator /(Watt watt, Volt volt) - { - return SIBase<Ampere>.Create(watt.Value() / volt.Value()); - } - } + public static NormLiterPerSecond operator /(NormLiter nl, Second s) + { + return SIBase<NormLiterPerSecond>.Create(nl.Val / s.Value()); + } + } - public class VolumePerMeter : SIBase<VolumePerMeter> + /// <summary> + /// + /// </summary> + public class NormLiterPerSecond : SIBase<NormLiterPerSecond> { - private static readonly int[] Units = { 0, 2, 0, 0, 0, 0, 0 }; - private VolumePerMeter(double val) : base(val, Units) { } + private static readonly int[] Units = { 0, 3, -1, 0, 0, 0, 0 }; - public override string UnitString { get { return "m^3/m"; } } + //[DebuggerHidden] + private NormLiterPerSecond(double val) : base(val, 0.001, Units) { } - public static VolumePerMeterMass operator /(VolumePerMeter vpm, Kilogram kg) + public override string UnitString { get { return "Nl/s"; } } + + public static NormLiter operator *(NormLiterPerSecond nips, Second s) { - return SIBase<VolumePerMeterMass>.Create(vpm.Val / kg.Value()); + return SIBase<NormLiter>.Create(nips.Val * s.Value()); } - public static VolumePerMeterVolume operator /(VolumePerMeter vpm, CubicMeter vol) + public static NormLiterPerSecond operator *(NormLiterPerSecond nps, double val) { - return SIBase<VolumePerMeterVolume>.Create(vpm.Val / vol.Value()); + return Create(nps.Val * val); } + public static NormLiterPerSecond operator /(NormLiterPerSecond nps, double val) + { + return Create(nps.Val / val); + } } - public class VolumePerMeterMass : SIBase<VolumePerMeterMass> + /// <summary> + /// SI Class for Kilogram per Second [kg]. + /// </summary> + public class KilogramPerSecond : SIBase<KilogramPerSecond> { - private static readonly int[] Units = { -1, 2, 0, 0, 0, 0, 0 }; + private static readonly int[] Units = { 1, 0, -1, 0, 0, 0, 0 }; - private VolumePerMeterMass(double val) : base (val, Units) { } + [DebuggerHidden] + private KilogramPerSecond(double value) : base(value, Units) { } - public override string UnitString { get { return "m^3/kgm"; } } + [DebuggerHidden] + public static Kilogram operator *(KilogramPerSecond kilogramPerSecond, Second second) + { + return SIBase<Kilogram>.Create(kilogramPerSecond.Val * second.Value()); + } } - public class VolumePerMeterVolume : SIBase<VolumePerMeterVolume> + /// <summary> + /// SI Class for Square meter [m^2]. + /// </summary> + public class SquareMeter : SIBase<SquareMeter> { - private static readonly int[] Units = { 0, -1, 0, 0, 0, 0, 0 }; - - private VolumePerMeterVolume(double val) : base (val, Units) { } + private static readonly int[] Units = { 0, 2, 0, 0, 0, 0, 0 }; - public override string UnitString { get { return "m^3/kgm^3"; } } + [DebuggerHidden] + private SquareMeter(double value) : base(value, Units) { } } - public class KilogramPerMeterCubicMeter : SIBase<KilogramPerMeterCubicMeter> + /// <summary> + /// SI Class for cubic meter [m^3]. + /// </summary> + public class CubicMeter : SIBase<CubicMeter> { - private static readonly int[] Units = { 1, -4, 0, 0, 0, 0, 0 }; + private static readonly int[] Units = { 0, 3, 0, 0, 0, 0, 0 }; - private KilogramPerMeterCubicMeter(double val) : base(val, Units) { } - - public override string UnitString { get { return "kg/(m m^3)"; } } + [DebuggerHidden] + private CubicMeter(double value) + : base(value, Units) { } } - - public class KilogramPerMeterMass : SIBase<KilogramPerMeterMass> + /// <summary> + /// SI Class for Kilogram Square Meter [kgm^2]. + /// </summary> + public class KilogramSquareMeter : SIBase<KilogramSquareMeter> { - private static readonly int[] Units = { 0, -1, 0, 0, 0, 0, 0 }; + private static readonly int[] Units = { 1, 2, 0, 0, 0, 0, 0 }; - private KilogramPerMeterMass(double val) : base(val, Units) { } + [DebuggerHidden] + private KilogramSquareMeter(double value) : base(value, Units) { } - public override string UnitString { get { return "kg/(m kg)"; } } + [DebuggerHidden] + public static NewtonMeter operator *(KilogramSquareMeter kilogramSquareMeter, PerSquareSecond perSquareSecond) + { + return SIBase<NewtonMeter>.Create(kilogramSquareMeter.Val * perSquareSecond.Value()); + } } - public class SpecificFuelConsumption : SIBase<SpecificFuelConsumption> + /// <summary> + /// SI Class for Kilogram per Cubic Meter [kg/m^3]. + /// </summary> + public class KilogramPerCubicMeter : SIBase<KilogramPerCubicMeter> { - private static readonly int[] Units = { 0, -2,2, 0, 0, 0, 0 }; + private static readonly int[] Units = { 1, -3, 0, 0, 0, 0, 0 }; - private SpecificFuelConsumption(double val) : base(val, Units) { } - } + [DebuggerHidden] + private KilogramPerCubicMeter(double value) : base(value, Units) { } - /// <summary> - /// Base Class for all special SI Classes. Not intended to be used directly. + public override string UnitString { get { return "kg/m^3"; } } + + [DebuggerHidden] + public static Kilogram operator *(KilogramPerCubicMeter kilogramPerCubicMeter, CubicMeter cubicMeter) + { + return SIBase<Kilogram>.Create(kilogramPerCubicMeter.Val * cubicMeter.Value()); + } + + } + + /// <summary> + /// SI Class for Kilogramm per watt second [kg/Ws]. + /// W = kgm^2/s^3 + /// </summary> + public class KilogramPerWattSecond : SIBase<KilogramPerWattSecond> + { + private static readonly int[] Units = { 0, -2, 2, 0, 0, 0, 0 }; + + [DebuggerHidden] + private KilogramPerWattSecond(double val) : base(val, Units) { } + + public override string UnitString { get { return "kg/Ws"; } } + } + + /// <summary> + /// SI Class for watt second [Ws]. + /// W = kgm^2/s^3 + /// </summary> + public class WattSecond : SIBase<WattSecond> + { + private static readonly int[] Units = { 1, 2, -2, 0, 0, 0, 0 }; + + [DebuggerHidden] + private WattSecond(double val) : base(val, Units) { } + + public override string UnitString { get { return "Ws"; } } + + [DebuggerHidden] + public static Watt operator /(WattSecond wattSecond, Second second) + { + return SIBase<Watt>.Create(wattSecond.Val / second.Value()); + } + } + + /// <summary> + /// SI Class for Watt [W]. + /// </summary> + public class Watt : SIBase<Watt> + { + private static readonly int[] Units = { 1, 2, -3, 0, 0, 0, 0 }; + + [DebuggerHidden] + private Watt(double val) : base(val, Units) { } + + public override string UnitString { get { return "W"; } } + + /// <summary> + /// Implements the operator /. + /// </summary> + /// <param name="watt">The watt.</param> + /// <param name="newtonMeter">The newton meter.</param> + /// <returns> + /// The result of the operator. + /// </returns> + [DebuggerHidden] + public static PerSecond operator /(Watt watt, NewtonMeter newtonMeter) + { + return SIBase<PerSecond>.Create(watt.Val / newtonMeter.Value()); + } + + [DebuggerHidden] + public static Newton operator /(Watt watt, MeterPerSecond meterPerSecond) + { + return SIBase<Newton>.Create(watt.Val / meterPerSecond.Value()); + } + + /// <summary> + /// Implements the operator /. + /// </summary> + /// <param name="watt">The watt.</param> + /// <param name="perSecond">The per second.</param> + /// <returns> + /// The result of the operator. + /// </returns> + [DebuggerHidden] + public static NewtonMeter operator /(Watt watt, PerSecond perSecond) + { + return SIBase<NewtonMeter>.Create(watt.Val / perSecond.Value()); + } + + [DebuggerHidden] + public static WattSecond operator *(Watt watt, Second second) + { + return SIBase<WattSecond>.Create(watt.Val * second.Value()); + } + + [DebuggerHidden] + public static Watt operator *(Watt watt, double val) + { + return Create(watt.Val * val); + } + } + + /// <summary> + /// SI Class for Joule [J]. + /// J = Ws = kgm^2/s^2 + /// </summary> + public class Joule : SIBase<Joule> + { + private static readonly int[] Units = { 1, 2, -2, 0, 0, 0, 0 }; + + [DebuggerHidden] + private Joule(double val) : base(val, Units) { } + + public override string UnitString { get { return "J"; } } + + public static implicit operator Joule(WattSecond self) + { + return Create(self.Value()); + } + + public static Joule operator +(Joule joule, WattSecond ws) + { + return Create(joule.Val + ws.Value()); + } + + public static Watt operator /(Joule joule, Second s) + { + return SIBase<Watt>.Create(joule.Val / s.Value()); + } + + public static JoulePerMeter operator /(Joule joule, Meter meter) + { + return SIBase<JoulePerMeter>.Create(joule.Val / meter.Value()); + } + } + + /// <summary> + /// SI Class for Joule / kg. + /// </summary> + public class JoulePerKilogramm : SIBase<JoulePerKilogramm> + { + private static readonly int[] Units = { 0, 2, -2, 0, 0, 0, 0 }; + + private JoulePerKilogramm(double val) : base(val, Units) { } + + public override string UnitString { get { return "J/kg"; } } + + public static Joule operator *(Kilogram kg, JoulePerKilogramm jpg) + { + return SIBase<Joule>.Create(kg.Value() * jpg.Val); + } + } + + /// <summary> + /// SI Class for Joule per Meter [J/m]. + /// J = Ws + /// W = kgm^2/s^3 + /// </summary> + public class JoulePerMeter : SIBase<JoulePerMeter> + { + private static readonly int[] Units = { 1, 1, -2, 0, 0, 0, 0 }; + + [DebuggerHidden] + private JoulePerMeter(double val) : base(val, Units) { } + + public override string UnitString { get { return "J/m"; } } + } + + /// <summary> + /// SI Class for one per second [1/s]. + /// </summary> + [DebuggerDisplay("rad/s: {Val} | rpm: {AsRPM}")] + public class PerSecond : SIBase<PerSecond> + { + private static readonly int[] Units = { 0, 0, -1, 0, 0, 0, 0 }; + + [DebuggerHidden] + private PerSecond(double val) : base(val, Units) { } + + [DebuggerHidden] + public static PerSquareSecond operator /(PerSecond perSecond, Second second) + { + return SIBase<PerSquareSecond>.Create(perSecond.Val / second.Value()); + } + + public double AsRPM + { + get { return Val * 60 / (2 * Math.PI); } + } + } + + /// <summary> + /// SI Class for Meter per second [m/s]. + /// </summary> + [DebuggerDisplay("{Val} | {AsKmph}")] + public class MeterPerSecond : SIBase<MeterPerSecond> + { + private static readonly int[] Units = { 0, 1, -1, 0, 0, 0, 0 }; + + [DebuggerHidden] + private MeterPerSecond(double val) : base(val, Units) { } + + public double AsKmph + { + get { return Val * 3.6; } + } + + /// <summary> + /// Implements the operator /. + /// </summary> + [DebuggerHidden] + public static PerSecond operator /(MeterPerSecond meterPerSecond, Meter meter) + { + return SIBase<PerSecond>.Create(meterPerSecond.Val / meter.Value()); + } + + /// <summary> + /// Implements the operator /. + /// </summary> + [DebuggerHidden] + public static Second operator /(MeterPerSecond meterPerSecond, MeterPerSquareSecond meterPerSquareSecond) + { + return SIBase<Second>.Create(meterPerSecond.Val / meterPerSquareSecond.Value()); + } + + /// <summary> + /// Implements the operator /. + /// </summary> + [DebuggerHidden] + public static MeterPerSquareSecond operator /(MeterPerSecond meterPerSecond, Second second) + { + return SIBase<MeterPerSquareSecond>.Create(meterPerSecond.Val / second.Value()); + } + + /// <summary> + /// Implements the operator *. + /// </summary> + [DebuggerHidden] + public static Meter operator *(MeterPerSecond meterPerSecond, Second second) + { + return SIBase<Meter>.Create(meterPerSecond.Val * second.Value()); + } + + /// <summary> + /// Implements the operator *. + /// </summary> + [DebuggerHidden] + public static MeterPerSquareSecond operator *(MeterPerSecond meterPerSecond, PerSecond perSecond) + { + return SIBase<MeterPerSquareSecond>.Create(meterPerSecond.Val * perSecond.Value()); + } + + /// <summary> + /// Implements the operator *. + /// </summary> + [DebuggerHidden] + public static Meter operator *(Second second, MeterPerSecond meterPerSecond) + { + return SIBase<Meter>.Create(second.Value() * meterPerSecond.Val); + } + } + + /// <summary> + /// SI Class for NewtonMeter [Nm]. + /// N = kgm/s^2 + /// </summary> + public class NewtonMeter : SIBase<NewtonMeter> + { + private static readonly int[] Units = { 1, 2, -2, 0, 0, 0, 0 }; + + [DebuggerHidden] + private NewtonMeter(double val) : base(val, Units) { } + + public override string UnitString { get { return "Nm"; } } + + [DebuggerHidden] + public static Watt operator *(NewtonMeter newtonMeter, PerSecond perSecond) + { + return SIBase<Watt>.Create(newtonMeter.Val * perSecond.Value()); + } + + [DebuggerHidden] + public static Watt operator *(PerSecond perSecond, NewtonMeter newtonMeter) + { + return SIBase<Watt>.Create(perSecond.Value() * newtonMeter.Val); + } + + [DebuggerHidden] + public static Second operator /(NewtonMeter newtonMeter, Watt watt) + { + return SIBase<Second>.Create(newtonMeter.Val / watt.Value()); + } + + [DebuggerHidden] + public static PerSquareSecond operator /(NewtonMeter newtonMeter, KilogramSquareMeter kgKilogramSquareMeter) + { + return SIBase<PerSquareSecond>.Create(newtonMeter.Val / kgKilogramSquareMeter.Value()); + } + + [DebuggerHidden] + public static PerSecond operator /(NewtonMeter newtonMeter, NewtonMeterSecond newtonMeterSecond) + { + return SIBase<PerSecond>.Create(newtonMeter.Val / newtonMeterSecond.Value()); + } + + [DebuggerHidden] + public static Newton operator /(NewtonMeter newtonMeter, Meter meter) + { + return SIBase<Newton>.Create(newtonMeter.Val / meter.Value()); + } + + [DebuggerHidden] + public static NewtonMeterSecond operator /(NewtonMeter newtonMeter, PerSecond perSecond) + { + return SIBase<NewtonMeterSecond>.Create(newtonMeter.Val / perSecond.Value()); + } + } + + /// <summary> + /// SI Class for NewtonMeterSecond [Nms]. + /// N = kgm/s^2 + /// </summary> + public class NewtonMeterSecond : SIBase<NewtonMeterSecond> + { + private static readonly int[] Units = { 1, 2, -1, 0, 0, 0, 0 }; + private NewtonMeterSecond(double val) : base(val, Units) { } + + public override string UnitString { get { return "Nms"; } } + } + + /// <summary> + /// SI Class for Amperer [A]. + /// </summary> + public class Ampere : SIBase<Ampere> + { + private static readonly int[] Units = { 0, 0, 0, 1, 0, 0, 0 }; + private Ampere(double val) : base(val, Units) { } + + public static Watt operator *(Ampere ampere, Volt volt) + { + return SIBase<Watt>.Create(volt.Value() * ampere.Val); + } + + public static Ampere operator *(Ampere ampere, double val) + { + return Create(ampere.Val * val); + } + + public static Volt operator /(Watt watt, Ampere ampere) + { + return SIBase<Volt>.Create(watt.Value() / ampere.Value()); + } + } + + /// <summary> + /// SI Class for Amperer [V]. + /// V = kgm^2/As^2 + /// </summary> + public class Volt : SIBase<Volt> + { + private static readonly int[] Units = { 1, 2, -2, -1, 0, 0, 0 }; + private Volt(double val) : base(val, Units) { } + + public override string UnitString { get { return "V"; } } + + public static Watt operator *(Volt volt, Ampere ampere) + { + return SIBase<Watt>.Create(volt.Val * ampere.Value()); + } + + public static Ampere operator /(Watt watt, Volt volt) + { + return SIBase<Ampere>.Create(watt.Value() / volt.Value()); + } + } + + public class VolumePerMeter : SIBase<VolumePerMeter> + { + private static readonly int[] Units = { 0, 2, 0, 0, 0, 0, 0 }; + private VolumePerMeter(double val) : base(val, Units) { } + + public override string UnitString { get { return "m^3/m"; } } + + public static VolumePerMeterMass operator /(VolumePerMeter vpm, Kilogram kg) + { + return SIBase<VolumePerMeterMass>.Create(vpm.Val / kg.Value()); + } + + public static VolumePerMeterVolume operator /(VolumePerMeter vpm, CubicMeter vol) + { + return SIBase<VolumePerMeterVolume>.Create(vpm.Val / vol.Value()); + } + + } + + public class VolumePerMeterMass : SIBase<VolumePerMeterMass> + { + private static readonly int[] Units = { -1, 2, 0, 0, 0, 0, 0 }; + + private VolumePerMeterMass(double val) : base (val, Units) { } + + public override string UnitString { get { return "m^3/kgm"; } } + } + + public class VolumePerMeterVolume : SIBase<VolumePerMeterVolume> + { + private static readonly int[] Units = { 0, -1, 0, 0, 0, 0, 0 }; + + private VolumePerMeterVolume(double val) : base (val, Units) { } + + public override string UnitString { get { return "m^3/kgm^3"; } } + } + + public class KilogramPerMeterCubicMeter : SIBase<KilogramPerMeterCubicMeter> + { + private static readonly int[] Units = { 1, -4, 0, 0, 0, 0, 0 }; + + private KilogramPerMeterCubicMeter(double val) : base(val, Units) { } + + public override string UnitString { get { return "kg/(m m^3)"; } } + } + + + public class KilogramPerMeterMass : SIBase<KilogramPerMeterMass> + { + private static readonly int[] Units = { 0, -1, 0, 0, 0, 0, 0 }; + + private KilogramPerMeterMass(double val) : base(val, Units) { } + + public override string UnitString { get { return "kg/(m kg)"; } } + } + + public class SpecificFuelConsumption : SIBase<SpecificFuelConsumption> + { + private static readonly int[] Units = { 0, -2,2, 0, 0, 0, 0 }; + + private SpecificFuelConsumption(double val) : base(val, Units) { } + } + + /// <summary> + /// Base Class for all special SI Classes. Not intended to be used directly. /// Implements templated operators for type safety and convenience. /// </summary> /// <typeparam name="T"></typeparam> public abstract class SIBase<T> : SI where T : SIBase<T> - { - private static readonly T ZeroPrototype; - - static SIBase() - { - const BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance; - var constructorInfo = typeof(T).GetConstructor(bindingFlags, null, new[] { typeof(double) }, null); - var parameter = Expression.Parameter(typeof(double)); - var lambda = Expression.Lambda<Func<double, T>>(Expression.New(constructorInfo, parameter), parameter); - Constructor = lambda.Compile(); - ZeroPrototype = Constructor(0); - } - - /// <summary> - /// The constructor for the generic type T. - /// </summary> - private static readonly Func<double, T> Constructor; - - /// <summary> - /// Creates the specified special SI object. - /// </summary> - /// <param name="val">The value of the SI object.</param> - [DebuggerStepThrough] - public static T Create(double val) - { - if (val == 0) { - return ZeroPrototype; - } - - return Constructor(val); - } - - [DebuggerStepThrough] - protected SIBase(double value, int[] units) : base(value, units) { } + { + private static readonly T ZeroPrototype; + + static SIBase() + { + const BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance; + var constructorInfo = typeof(T).GetConstructor(bindingFlags, null, new[] { typeof(double) }, null); + var parameter = Expression.Parameter(typeof(double)); + var lambda = Expression.Lambda<Func<double, T>>(Expression.New(constructorInfo, parameter), parameter); + Constructor = lambda.Compile(); + ZeroPrototype = Constructor(0); + } + + /// <summary> + /// The constructor for the generic type T. + /// </summary> + private static readonly Func<double, T> Constructor; + + /// <summary> + /// Creates the specified special SI object. + /// </summary> + /// <param name="val">The value of the SI object.</param> + [DebuggerStepThrough] + public static T Create(double val) + { + if (val == 0) { + return ZeroPrototype; + } + + return Constructor(val); + } + + [DebuggerStepThrough] + protected SIBase(double value, int[] units) : base(value, units) { } + + protected SIBase(double value, double unitFactor, int[] units) : base(value, unitFactor, units) { } + + [DebuggerStepThrough] + public new T Abs() + { + return Create(Math.Abs(Val)); + } + + #region Operators + + /// <summary> + /// Implements the operator + for two specialized SI Classes. + /// </summary> + /// <param name="si1">The si1.</param> + /// <param name="si2">The si2.</param> + /// <returns> + /// The result of the operator. + /// </returns> + [DebuggerHidden] + public static T operator +(SIBase<T> si1, SIBase<T> si2) + { + return Create(si1.Val + si2.Val); + } + + /// <summary> + /// Implements the operator + for a specialized SI Class and a generic SI Class. + /// </summary> + /// <param name="si1">The si1.</param> + /// <param name="si2">The si2.</param> + /// <returns> + /// The result of the operator. + /// </returns> + [DebuggerHidden] + public static T operator +(SIBase<T> si1, SI si2) + { + return ((si1 as SI) + si2).Cast<T>(); + } + + /// <summary> + /// Implements the operator + for a generic SI Class and a specialized SI Class. + /// </summary> + /// <param name="si1">The si1.</param> + /// <param name="si2">The si2.</param> + /// <returns> + /// The result of the operator. + /// </returns> + [DebuggerHidden] + public static T operator +(SI si1, SIBase<T> si2) + { + return (si1 + (si2 as SI)).Cast<T>(); + } + + /// <summary> + /// Implements the unary operator -. + /// </summary> + /// <param name="si1">The si1.</param> + /// <returns> + /// The result of the operator. + /// </returns> + [DebuggerHidden] + public static T operator -(SIBase<T> si1) + { + return Create(-si1.Val); + } + + /// <summary> + /// Implements the operator - for two specialized SI classes. + /// </summary> + /// <param name="si1">The si1.</param> + /// <param name="si2">The si2.</param> + /// <returns> + /// The result of the operator. + /// </returns> + [DebuggerHidden] + public static T operator -(SIBase<T> si1, SIBase<T> si2) + { + return Create(si1.Val - si2.Val); + } + + /// <summary> + /// Implements the operator - for a specialized SI class and a generic SI class. + /// </summary> + /// <param name="si1">The si1.</param> + /// <param name="si2">The si2.</param> + /// <returns> + /// The result of the operator. + /// </returns> + [DebuggerHidden] + public static T operator -(SIBase<T> si1, SI si2) + { + return ((si1 as SI) - si2).Cast<T>(); + } + + /// <summary> + /// Implements the operator - for a generic SI class and a specialized SI class. + /// </summary> + /// <param name="si1">The si1.</param> + /// <param name="si2">The si2.</param> + /// <returns> + /// The result of the operator. + /// </returns> + [DebuggerHidden] + public static T operator -(SI si1, SIBase<T> si2) + { + return (si1 - (si2 as SI)).Cast<T>(); + } + + /// <summary> + /// Implements the operator * for a double and a specialized SI class. + /// </summary> + /// <param name="d">The double value.</param> + /// <param name="si">The si.</param> + /// <returns> + /// The result of the operator. + /// </returns> + [DebuggerHidden] + public static T operator *(double d, SIBase<T> si) + { + return Create(d * si.Val); + } + + /// <summary> + /// Implements the operator * for a specialized SI class and a double. + /// </summary> + /// <param name="si">The si.</param> + /// <param name="d">The double.</param> + /// <returns> + /// The result of the operator. + /// </returns> + [DebuggerHidden] + public static T operator *(SIBase<T> si, double d) + { + return Create(si.Val * d); + } + + /// <summary> + /// Implements the operator / for a specialized SI class and a double. + /// </summary> + /// <param name="si">The si.</param> + /// <param name="d">The double.</param> + /// <returns> + /// The result of the operator. + /// </returns> + [DebuggerHidden] + public static T operator /(SIBase<T> si, double d) + { + return Create(si.Val / d); + } + + [DebuggerHidden] + public static Scalar operator /(SIBase<T> si, SIBase<T> si2) + { + return SIBase<Scalar>.Create(si.Val / si2.Val); + } + + #endregion + } + + /// <summary> + /// Class for representing generic SI Units. + /// </summary> + /// <remarks> + /// Usage: new SI(1.0).Newton.Meter, new SI(2.3).Rounds.Per.Minute + /// </remarks> + [DebuggerDisplay("{Val} [{UnitString}]")] + public class SI : IComparable + { + /// <summary> + /// The basic scalar value of the SI. + /// </summary> + protected readonly double Val; + + /// <summary> + /// The array of the SI units. + /// </summary> + private readonly int[] _units; + + private double UnitFactor; + + /// <summary> + /// Initializes a new instance of the <see cref="SI"/> class which allows to construct a new SI with all parameters. + /// </summary> + /// <param name="val">The value.</param> + /// <param name="unitFactor"></param> + /// <param name="units">The units.</param> + protected SI(double val, double unitFactor, int[] units) + { + Val = val; + _units = units; + UnitFactor = unitFactor; + + if (double.IsNaN(Val)) { + throw new VectoException("NaN [{0}] is not allowed for SI-Values in Vecto.", GetUnitString()); + } + + if (double.IsInfinity(Val)) { + throw new VectoException("Infinity [{0}] is not allowed for SI-Values in Vecto.", GetUnitString()); + } + } + + protected SI(double val, int[] units) : this(val, 1, units) { } + + + public SI(UnitInstance si, double val = 0) : this(val * si.Factor, si.GetSIUnits()) { } + + /// <summary> + /// Initializes a new instance of the <see cref="SI"/> class which copies the units from an already existing SI. + /// </summary> + /// <param name="val">The value.</param> + /// <param name="unit">The unit.</param> + [DebuggerHidden] + private SI(double val, SI unit) : this(val, unit.UnitFactor,unit._units) { } + + /// <summary> + /// Casts the SI Unit to the concrete unit type (if the units allow such an cast). + /// </summary> + /// <typeparam name="T">the specialized SI unit. e.g. Watt, NewtonMeter, Second</typeparam> + [DebuggerHidden] + public T Cast<T>() where T : SIBase<T> + { + var si = ToBasicUnits(); + var zero = SIBase<T>.Create(0); + var t = SIBase<T>.Create(si.Val / zero.UnitFactor); + if (!si.HasEqualUnit(t)) { + throw new VectoException("SI Unit Conversion failed: From {0} to {1}", si, t); + } + return t; + } + + /// <summary> + /// Converts the derived SI units to the basic units and returns this as a new SI object. + /// </summary> + public SI ToBasicUnits() + { + return new SI(Val * UnitFactor, _units); + } + + protected double AsBasicUnit + { + get { return Val * UnitFactor; } + } + + + /// <summary> + /// Gets the underlying scalar double value. + /// </summary> + [DebuggerHidden] + public double Value() + { + return Val; + } + + /// <summary> + /// Clones this instance. + /// </summary> + public SI Clone() + { + return new SI(Val, _units); + } + + /// <summary> + /// Returns the absolute value. + /// </summary> + public SI Abs() + { + return new SI(Math.Abs(Val), this); + } + + /// <summary> + /// Returns the numerical sign of the SI. + /// </summary> + /// <returns>-1 if si < 0. 0 if si==0, 1 if si > 0.</returns> + [DebuggerHidden] + public int Sign() + { + return Math.Sign(Val); + } + + #region Operators + + [DebuggerHidden] + public static SI operator +(SI si1, SI si2) + { + if (!si1.HasEqualUnit(si2)) { + throw new VectoException("Operator '+' can only operate on SI Objects with the same unit. Got: {0} + {1}", si1, si2); + } + + + return new SI(si1.Val + si2.Val, si1); + } + + [DebuggerHidden] + public static SI operator -(SI si1, SI si2) + { + if (!si1.HasEqualUnit(si2)) { + throw new VectoException("Operator '-' can only operate on SI Objects with the same unit. Got: {0} - {1}", si1, si2); + } + return new SI(si1.Val - si2.Val, si1); + } + + [DebuggerHidden] + public static SI operator -(SI si1) + { + return new SI(-si1.Val, si1); + } + + public static SI operator *(SI si1, SI si2) + { + var unitArray = SIUtils.CombineUnits(si1._units, si2._units); + return new SI(si1.AsBasicUnit * si2.AsBasicUnit, unitArray); + } - protected SIBase(double value, double unitFactor, int[] units) : base(value, unitFactor, units) { } + [DebuggerHidden] + public static SI operator *(SI si1, double d) + { + return new SI(si1.Val * d, si1); + } - [DebuggerStepThrough] - public new T Abs() - { - return Create(Math.Abs(Val)); - } - - #region Operators - - /// <summary> - /// Implements the operator + for two specialized SI Classes. - /// </summary> - /// <param name="si1">The si1.</param> - /// <param name="si2">The si2.</param> - /// <returns> - /// The result of the operator. - /// </returns> - [DebuggerHidden] - public static T operator +(SIBase<T> si1, SIBase<T> si2) - { - return Create(si1.Val + si2.Val); - } - - /// <summary> - /// Implements the operator + for a specialized SI Class and a generic SI Class. - /// </summary> - /// <param name="si1">The si1.</param> - /// <param name="si2">The si2.</param> - /// <returns> - /// The result of the operator. - /// </returns> - [DebuggerHidden] - public static T operator +(SIBase<T> si1, SI si2) - { - return ((si1 as SI) + si2).Cast<T>(); - } - - /// <summary> - /// Implements the operator + for a generic SI Class and a specialized SI Class. - /// </summary> - /// <param name="si1">The si1.</param> - /// <param name="si2">The si2.</param> - /// <returns> - /// The result of the operator. - /// </returns> - [DebuggerHidden] - public static T operator +(SI si1, SIBase<T> si2) - { - return (si1 + (si2 as SI)).Cast<T>(); - } - - /// <summary> - /// Implements the unary operator -. - /// </summary> - /// <param name="si1">The si1.</param> - /// <returns> - /// The result of the operator. - /// </returns> - [DebuggerHidden] - public static T operator -(SIBase<T> si1) - { - return Create(-si1.Val); - } - - /// <summary> - /// Implements the operator - for two specialized SI classes. - /// </summary> - /// <param name="si1">The si1.</param> - /// <param name="si2">The si2.</param> - /// <returns> - /// The result of the operator. - /// </returns> - [DebuggerHidden] - public static T operator -(SIBase<T> si1, SIBase<T> si2) - { - return Create(si1.Val - si2.Val); - } - - /// <summary> - /// Implements the operator - for a specialized SI class and a generic SI class. - /// </summary> - /// <param name="si1">The si1.</param> - /// <param name="si2">The si2.</param> - /// <returns> - /// The result of the operator. - /// </returns> - [DebuggerHidden] - public static T operator -(SIBase<T> si1, SI si2) - { - return ((si1 as SI) - si2).Cast<T>(); - } - - /// <summary> - /// Implements the operator - for a generic SI class and a specialized SI class. - /// </summary> - /// <param name="si1">The si1.</param> - /// <param name="si2">The si2.</param> - /// <returns> - /// The result of the operator. - /// </returns> - [DebuggerHidden] - public static T operator -(SI si1, SIBase<T> si2) - { - return (si1 - (si2 as SI)).Cast<T>(); - } - - /// <summary> - /// Implements the operator * for a double and a specialized SI class. - /// </summary> - /// <param name="d">The double value.</param> - /// <param name="si">The si.</param> - /// <returns> - /// The result of the operator. - /// </returns> - [DebuggerHidden] - public static T operator *(double d, SIBase<T> si) - { - return Create(d * si.Val); - } - - /// <summary> - /// Implements the operator * for a specialized SI class and a double. - /// </summary> - /// <param name="si">The si.</param> - /// <param name="d">The double.</param> - /// <returns> - /// The result of the operator. - /// </returns> - [DebuggerHidden] - public static T operator *(SIBase<T> si, double d) - { - return Create(si.Val * d); - } - - /// <summary> - /// Implements the operator / for a specialized SI class and a double. - /// </summary> - /// <param name="si">The si.</param> - /// <param name="d">The double.</param> - /// <returns> - /// The result of the operator. - /// </returns> - [DebuggerHidden] - public static T operator /(SIBase<T> si, double d) - { - return Create(si.Val / d); - } - - [DebuggerHidden] - public static Scalar operator /(SIBase<T> si, SIBase<T> si2) - { - return SIBase<Scalar>.Create(si.Val / si2.Val); - } - - #endregion - } - - /// <summary> - /// Class for representing generic SI Units. - /// </summary> - /// <remarks> - /// Usage: new SI(1.0).Newton.Meter, new SI(2.3).Rounds.Per.Minute - /// </remarks> - [DebuggerDisplay("{Val} [{UnitString}]")] - public class SI : IComparable - { - /// <summary> - /// The basic scalar value of the SI. - /// </summary> - protected readonly double Val; - - /// <summary> - /// The array of the SI units. - /// </summary> - private readonly int[] _units; + [DebuggerHidden] + public static SI operator *(double d, SI si1) + { + return new SI(d * si1.Val, si1); + } - private double UnitFactor; + public static SI operator /(SI si1, SI si2) + { + double result; + try { + result = si1.AsBasicUnit / si2.AsBasicUnit; + + // bad cases: Infinity = x / 0.0 (for x != 0), NaN = 0.0 / 0.0 + if (double.IsInfinity(result) || double.IsNaN(result)) { + throw new DivideByZeroException(); + } + } catch (DivideByZeroException ex) { + throw new VectoException( + string.Format("Can not compute division by zero ([{0}] / 0[{1}])", si1.UnitString, si2.UnitString), ex); + } - /// <summary> - /// Initializes a new instance of the <see cref="SI"/> class which allows to construct a new SI with all parameters. - /// </summary> - /// <param name="val">The value.</param> - /// <param name="unitFactor"></param> - /// <param name="units">The units.</param> - protected SI(double val, double unitFactor, int[] units) - { - Val = val; - _units = units; - UnitFactor = unitFactor; + var unitArray = SIUtils.CombineUnits(si1._units, SIUtils.MultiplyUnits(si2._units, -1)); - if (double.IsNaN(Val)) { - throw new VectoException("NaN [{0}] is not allowed for SI-Values in Vecto.", GetUnitString()); - } + return new SI(result, unitArray); + } - if (double.IsInfinity(Val)) { - throw new VectoException("Infinity [{0}] is not allowed for SI-Values in Vecto.", GetUnitString()); - } - } + [DebuggerHidden] + public static SI operator /(SI si1, double d) + { + if (d.IsEqual(0)) { + throw new VectoException(string.Format("Can not compute division by zero ([{0}] / 0)", si1.UnitString), new DivideByZeroException()); + } - protected SI(double val, int[] units) : this(val, 1, units) { } + return new SI(si1.Val / d, si1); + } + [DebuggerHidden] + public static SI operator /(double d, SI si1) + { + if (si1.IsEqual(0)) { + throw new VectoException(string.Format("Can not compute division by zero (x / 0[{0}])", si1.UnitString), + new DivideByZeroException()); + } - public SI(UnitInstance si, double val = 0) : this(val * si.Factor, si.GetSIUnits()) { } + return new SI(d / si1.AsBasicUnit, si1._units.Select(u => -u).ToArray()); + } - /// <summary> - /// Initializes a new instance of the <see cref="SI"/> class which copies the units from an already existing SI. - /// </summary> - /// <param name="val">The value.</param> - /// <param name="unit">The unit.</param> - [DebuggerHidden] - private SI(double val, SI unit) : this(val, unit.UnitFactor,unit._units) { } - - /// <summary> - /// Casts the SI Unit to the concrete unit type (if the units allow such an cast). - /// </summary> - /// <typeparam name="T">the specialized SI unit. e.g. Watt, NewtonMeter, Second</typeparam> - [DebuggerHidden] - public T Cast<T>() where T : SIBase<T> - { - var si = ToBasicUnits(); - var zero = SIBase<T>.Create(0); - var t = SIBase<T>.Create(si.Val / zero.UnitFactor); - if (!si.HasEqualUnit(t)) { - throw new VectoException("SI Unit Conversion failed: From {0} to {1}", si, t); - } - return t; - } - - /// <summary> - /// Converts the derived SI units to the basic units and returns this as a new SI object. - /// </summary> - public SI ToBasicUnits() - { - return new SI(Val * UnitFactor, _units); - } + [DebuggerHidden] + public static bool operator <(SI si1, SI si2) + { + if (!si1.HasEqualUnit(si2)) { + throw new VectoException("Operator '<' can only operate on SI Objects with the same unit. Got: {0} < {1}", si1, si2); + } + return si1.AsBasicUnit < si2.AsBasicUnit; + } - protected double AsBasicUnit + [DebuggerHidden] + public static bool operator <(SI si1, double d) { - get { return Val * UnitFactor; } + return si1 != null && si1.Val < d; + } + + [DebuggerHidden] + public static bool operator >(SI si1, SI si2) + { + if (!si1.HasEqualUnit(si2)) { + throw new VectoException("Operator '>' can only operate on SI Objects with the same unit. Got: {0} > {1}", si1, si2); + } + return si1.AsBasicUnit > si2.AsBasicUnit; + } + + [DebuggerHidden] + public static bool operator >(SI si1, double d) + { + return si1 != null && si1.Val > d; + } + + [DebuggerHidden] + public static bool operator >(double d, SI si1) + { + return si1 != null && d > si1.Val; + } + + [DebuggerHidden] + public static bool operator <(double d, SI si1) + { + return si1 != null && d < si1.Val; + } + + [DebuggerHidden] + public static bool operator <=(SI si1, SI si2) + { + if (!si1.HasEqualUnit(si2)) { + throw new VectoException("Operator '<=' can only operate on SI Objects with the same unit. Got: {0} <= {1}", si1, + si2); + } + return si1.AsBasicUnit <= si2.AsBasicUnit; + } + + [DebuggerHidden] + public static bool operator <=(SI si1, double d) + { + return si1 != null && si1.Val <= d; + } + + [DebuggerHidden] + public static bool operator >=(SI si1, SI si2) + { + if (!si1.HasEqualUnit(si2)) { + throw new VectoException("Operator '>=' can only operate on SI Objects with the same unit. Got: {0} >= {1}", si1, + si2); + } + return si1.AsBasicUnit >= si2.AsBasicUnit; + } + + [DebuggerHidden] + public static bool operator >=(SI si1, double d) + { + return si1 != null && si1.Val >= d; + } + + [DebuggerHidden] + public static bool operator >=(double d, SI si1) + { + return si1 != null && d >= si1.Val; + } + + [DebuggerHidden] + public static bool operator <=(double d, SI si1) + { + return si1 != null && d <= si1.Val; + } + + /// <summary> + /// Determines whether the SI is between lower and uppper bound. + /// </summary> + /// <param name="lower">The lower bound.</param> + /// <param name="upper">The upper bound.</param> + /// <returns></returns> + public bool IsBetween(SI lower, SI upper) + { + return lower <= Val && Val <= upper; } + /// <summary> + /// Determines whether the SI is between lower and upper bound. + /// </summary> + /// <param name="lower">The lower bound.</param> + /// <param name="upper">The upper bound.</param> + /// <returns></returns> + public bool IsBetween(double lower, double upper) + { + return lower <= Val && Val <= upper; + } - /// <summary> - /// Gets the underlying scalar double value. - /// </summary> - [DebuggerHidden] - public double Value() - { - return Val; - } - - /// <summary> - /// Clones this instance. - /// </summary> - public SI Clone() - { - return new SI(Val, _units); - } - - /// <summary> - /// Returns the absolute value. - /// </summary> - public SI Abs() - { - return new SI(Math.Abs(Val), this); - } - - /// <summary> - /// Returns the numerical sign of the SI. - /// </summary> - /// <returns>-1 if si < 0. 0 if si==0, 1 if si > 0.</returns> - [DebuggerHidden] - public int Sign() - { - return Math.Sign(Val); - } - - #region Operators - - [DebuggerHidden] - public static SI operator +(SI si1, SI si2) - { - if (!si1.HasEqualUnit(si2)) { - throw new VectoException("Operator '+' can only operate on SI Objects with the same unit. Got: {0} + {1}", si1, si2); - } - - - return new SI(si1.Val + si2.Val, si1); - } - - [DebuggerHidden] - public static SI operator -(SI si1, SI si2) - { - if (!si1.HasEqualUnit(si2)) { - throw new VectoException("Operator '-' can only operate on SI Objects with the same unit. Got: {0} - {1}", si1, si2); - } - return new SI(si1.Val - si2.Val, si1); - } - - [DebuggerHidden] - public static SI operator -(SI si1) - { - return new SI(-si1.Val, si1); - } - - public static SI operator *(SI si1, SI si2) - { - var unitArray = SIUtils.CombineUnits(si1._units, si2._units); - return new SI(si1.AsBasicUnit * si2.AsBasicUnit, unitArray); - } - - [DebuggerHidden] - public static SI operator *(SI si1, double d) - { - return new SI(si1.Val * d, si1); - } - - [DebuggerHidden] - public static SI operator *(double d, SI si1) - { - return new SI(d * si1.Val, si1); - } - - public static SI operator /(SI si1, SI si2) - { - double result; - try { - result = si1.AsBasicUnit / si2.AsBasicUnit; - - // bad cases: Infinity = x / 0.0 (for x != 0), NaN = 0.0 / 0.0 - if (double.IsInfinity(result) || double.IsNaN(result)) { - throw new DivideByZeroException(); - } - } catch (DivideByZeroException ex) { - throw new VectoException( - string.Format("Can not compute division by zero ([{0}] / 0[{1}])", si1.UnitString, si2.UnitString), ex); - } - - var unitArray = SIUtils.CombineUnits(si1._units, SIUtils.MultiplyUnits(si2._units, -1)); - - return new SI(result, unitArray); - } - - [DebuggerHidden] - public static SI operator /(SI si1, double d) - { - if (d.IsEqual(0)) { - throw new VectoException(string.Format("Can not compute division by zero ([{0}] / 0)", si1.UnitString), new DivideByZeroException()); - } - - return new SI(si1.Val / d, si1); - } - - [DebuggerHidden] - public static SI operator /(double d, SI si1) - { - if (si1.IsEqual(0)) { - throw new VectoException(string.Format("Can not compute division by zero (x / 0[{0}])", si1.UnitString), - new DivideByZeroException()); - } - - return new SI(d / si1.AsBasicUnit, si1._units.Select(u => -u).ToArray()); - } - - [DebuggerHidden] - public static bool operator <(SI si1, SI si2) - { - if (!si1.HasEqualUnit(si2)) { - throw new VectoException("Operator '<' can only operate on SI Objects with the same unit. Got: {0} < {1}", si1, si2); - } - return si1.AsBasicUnit < si2.AsBasicUnit; - } - - [DebuggerHidden] - public static bool operator <(SI si1, double d) - { - return si1 != null && si1.Val < d; - } - - [DebuggerHidden] - public static bool operator >(SI si1, SI si2) - { - if (!si1.HasEqualUnit(si2)) { - throw new VectoException("Operator '>' can only operate on SI Objects with the same unit. Got: {0} > {1}", si1, si2); - } - return si1.AsBasicUnit > si2.AsBasicUnit; - } - - [DebuggerHidden] - public static bool operator >(SI si1, double d) - { - return si1 != null && si1.Val > d; - } - - [DebuggerHidden] - public static bool operator >(double d, SI si1) - { - return si1 != null && d > si1.Val; - } - - [DebuggerHidden] - public static bool operator <(double d, SI si1) - { - return si1 != null && d < si1.Val; - } - - [DebuggerHidden] - public static bool operator <=(SI si1, SI si2) - { - if (!si1.HasEqualUnit(si2)) { - throw new VectoException("Operator '<=' can only operate on SI Objects with the same unit. Got: {0} <= {1}", si1, - si2); - } - return si1.AsBasicUnit <= si2.AsBasicUnit; - } - - [DebuggerHidden] - public static bool operator <=(SI si1, double d) - { - return si1 != null && si1.Val <= d; - } - - [DebuggerHidden] - public static bool operator >=(SI si1, SI si2) - { - if (!si1.HasEqualUnit(si2)) { - throw new VectoException("Operator '>=' can only operate on SI Objects with the same unit. Got: {0} >= {1}", si1, - si2); - } - return si1.AsBasicUnit >= si2.AsBasicUnit; - } - - [DebuggerHidden] - public static bool operator >=(SI si1, double d) - { - return si1 != null && si1.Val >= d; - } - - [DebuggerHidden] - public static bool operator >=(double d, SI si1) - { - return si1 != null && d >= si1.Val; - } - - [DebuggerHidden] - public static bool operator <=(double d, SI si1) - { - return si1 != null && d <= si1.Val; - } - - /// <summary> - /// Determines whether the SI is between lower and uppper bound. - /// </summary> - /// <param name="lower">The lower bound.</param> - /// <param name="upper">The upper bound.</param> - /// <returns></returns> - public bool IsBetween(SI lower, SI upper) - { - return lower <= Val && Val <= upper; - } - - /// <summary> - /// Determines whether the SI is between lower and upper bound. - /// </summary> - /// <param name="lower">The lower bound.</param> - /// <param name="upper">The upper bound.</param> - /// <returns></returns> - public bool IsBetween(double lower, double upper) - { - return lower <= Val && Val <= upper; - } - - #endregion - - #region ToString - - /// <summary> - /// Returns the Unit Part of the SI Unit Expression. - /// </summary> - public static string GetUnitString(int[] units = null) - { - if (units == null) { + #endregion + + #region ToString + + /// <summary> + /// Returns the Unit Part of the SI Unit Expression. + /// </summary> + public static string GetUnitString(int[] units = null) + { + if (units == null) { return ""; } - return Unit.GetUnitString(units); - } + return Unit.GetUnitString(units); + } - public override string ToString() - { - return ToString(null); - } + public override string ToString() + { + return ToString(null); + } public virtual string UnitString { get { return GetUnitString(_units); } } - private string ToString(string format) - { - if (string.IsNullOrEmpty(format)) { - format = "F4"; - } - - return string.Format(CultureInfo.InvariantCulture, "{0:" + format + "} [{2}]", Val, format, UnitString); - } - - #endregion - - #region Equality members - - /// <summary> - /// Compares the Unit-Parts of two SI Units. - /// </summary> - /// <param name="si">The si.</param> - /// <returns></returns> - [DebuggerHidden] - public bool HasEqualUnit(SI si) - { - return SIUtils.CompareUnits(_units, si._units); - } - - /// <summary> - /// Determines whether the specified <see cref="System.Object" />, is equal to this instance. - /// </summary> - /// <param name="obj">The <see cref="System.Object" /> to compare with this instance.</param> - /// <returns> - /// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>. - /// </returns> - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) { - return false; - } - if (ReferenceEquals(this, obj)) { - return true; - } - var other = obj as SI; - - return other != null && AsBasicUnit.Equals(other.AsBasicUnit) && HasEqualUnit(other); - } - - /// <summary> - /// Determines whether the specified si is equal. - /// </summary> - /// <param name="si">The si.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - public bool IsEqual(SI si, SI tolerance = null) - { - return (tolerance == null || HasEqualUnit(tolerance)) && HasEqualUnit(si) && - AsBasicUnit.IsEqual(si.AsBasicUnit, tolerance == null ? DoubleExtensionMethods.Tolerance : tolerance.Value()); - } - - /// <summary> - /// Determines whether the specified value is equal. - /// </summary> - /// <param name="val">The value.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - [DebuggerHidden] - public bool IsEqual(double val, double tolerance = DoubleExtensionMethods.Tolerance) - { - return Val.IsEqual(val, tolerance); - } - - /// <summary> - /// Determines whether the specified si is smaller. - /// </summary> - /// <param name="si">The si.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - public bool IsSmaller(SI si, SI tolerance = null) - { - if (!HasEqualUnit(si)) { - throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si); - } - if (tolerance != null && !HasEqualUnit(tolerance)) { - throw new VectoException("tolerance has to be the same unit. Got: {0} <=> {1}", this, tolerance); - } - - return AsBasicUnit.IsSmaller(si.AsBasicUnit, tolerance == null ? DoubleExtensionMethods.Tolerance : tolerance.Value()); - } - - /// <summary> - /// Determines whether the specified si is smaller. - /// </summary> - /// <param name="si">The si.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - public bool IsSmaller(SI si, double tolerance) - { - if (!HasEqualUnit(si)) { - throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si); - } - - return Val.IsSmaller(si.Val, tolerance); - } - - /// <summary> - /// Determines whether [is smaller or equal] [the specified si]. - /// </summary> - /// <param name="si">The si.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - public bool IsSmallerOrEqual(SI si, SI tolerance = null) - { - if (!HasEqualUnit(si)) { - throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si); - } - if (tolerance != null && !HasEqualUnit(tolerance)) { - throw new VectoException("tolerance has to be the same unit. Got: {0} <=> {1}", this, tolerance); - } - - return AsBasicUnit.IsSmallerOrEqual(si.AsBasicUnit, tolerance == null ? DoubleExtensionMethods.Tolerance : tolerance.Value()); - } - - /// <summary> - /// Determines whether the specified si is greater. - /// </summary> - /// <param name="si">The si.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - public bool IsGreater(SI si, SI tolerance = null) - { - if (!HasEqualUnit(si)) { - throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si); - } - if (tolerance != null && !HasEqualUnit(tolerance)) { - throw new VectoException("tolerance has to be the same unit. Got: {0} <=> {1}", this, tolerance); - } - - return AsBasicUnit.IsGreater(si.AsBasicUnit, tolerance == null ? DoubleExtensionMethods.Tolerance : tolerance.Value()); - } - - /// <summary> - /// Determines whether the specified si is greater. - /// </summary> - /// <param name="si">The si.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - [DebuggerStepThrough] - public bool IsGreater(SI si, double tolerance) - { - if (!HasEqualUnit(si)) { - throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si); - } - - return Val.IsGreater(si.Val, tolerance); - } - - /// <summary> - /// Determines whether [is greater or equal] [the specified si]. - /// </summary> - /// <param name="si">The si.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - [DebuggerStepThrough] - public bool IsGreaterOrEqual(SI si, SI tolerance = null) - { - if (!HasEqualUnit(si)) { - throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si); - } - if (tolerance != null && !HasEqualUnit(tolerance)) { - throw new VectoException("tolerance has to be the same unit. Got: {0} <=> {1}", this, tolerance); - } - - return AsBasicUnit.IsGreaterOrEqual(si.AsBasicUnit, tolerance == null ? DoubleExtensionMethods.Tolerance : tolerance.Value()); - } - - /// <summary> - /// Determines whether the specified value is smaller. - /// </summary> - /// <param name="val">The value.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - [DebuggerStepThrough] - public bool IsSmaller(double val, double tolerance = DoubleExtensionMethods.Tolerance) - { - return Val.IsSmaller(val, tolerance); - } - - /// <summary> - /// Determines whether [is smaller or equal] [the specified value]. - /// </summary> - /// <param name="val">The value.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - [DebuggerStepThrough] - public bool IsSmallerOrEqual(double val, double tolerance = DoubleExtensionMethods.Tolerance) - { - return Val.IsSmallerOrEqual(val, tolerance); - } - - /// <summary> - /// Determines whether the specified value is greater. - /// </summary> - /// <param name="val">The value.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - [DebuggerStepThrough] - public bool IsGreater(double val, double tolerance = DoubleExtensionMethods.Tolerance) - { - return Val.IsGreater(val, tolerance); - } - - /// <summary> - /// Determines whether [is greater or equal] [the specified value]. - /// </summary> - /// <param name="val">The value.</param> - /// <param name="tolerance">The tolerance.</param> - /// <returns></returns> - [DebuggerStepThrough] - public bool IsGreaterOrEqual(double val, double tolerance = DoubleExtensionMethods.Tolerance) - { - return Val.IsGreaterOrEqual(val, tolerance); - } - - public override int GetHashCode() - { - unchecked { - // ReSharper disable once NonReadonlyMemberInGetHashCode - var hashCode = Val.GetHashCode(); - hashCode = (hashCode * 397) ^ (_units != null ? _units.GetHashCode() : 0); - return hashCode; - } - } - - public int CompareTo(object obj) - { - var si = obj as SI; - if (si == null) { - return 1; - } - - if (!HasEqualUnit(si)) { + private string ToString(string format) + { + if (string.IsNullOrEmpty(format)) { + format = "F4"; + } + + return string.Format(CultureInfo.InvariantCulture, "{0:" + format + "} [{2}]", Val, format, UnitString); + } + + #endregion + + #region Equality members + + /// <summary> + /// Compares the Unit-Parts of two SI Units. + /// </summary> + /// <param name="si">The si.</param> + /// <returns></returns> + [DebuggerHidden] + public bool HasEqualUnit(SI si) + { + return SIUtils.CompareUnits(_units, si._units); + } + + /// <summary> + /// Determines whether the specified <see cref="System.Object" />, is equal to this instance. + /// </summary> + /// <param name="obj">The <see cref="System.Object" /> to compare with this instance.</param> + /// <returns> + /// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>. + /// </returns> + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) { + return false; + } + if (ReferenceEquals(this, obj)) { + return true; + } + var other = obj as SI; + + return other != null && AsBasicUnit.Equals(other.AsBasicUnit) && HasEqualUnit(other); + } + + /// <summary> + /// Determines whether the specified si is equal. + /// </summary> + /// <param name="si">The si.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + public bool IsEqual(SI si, SI tolerance = null) + { + return (tolerance == null || HasEqualUnit(tolerance)) && HasEqualUnit(si) && + AsBasicUnit.IsEqual(si.AsBasicUnit, tolerance == null ? DoubleExtensionMethods.Tolerance : tolerance.Value()); + } + + /// <summary> + /// Determines whether the specified value is equal. + /// </summary> + /// <param name="val">The value.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + [DebuggerHidden] + public bool IsEqual(double val, double tolerance = DoubleExtensionMethods.Tolerance) + { + return Val.IsEqual(val, tolerance); + } + + /// <summary> + /// Determines whether the specified si is smaller. + /// </summary> + /// <param name="si">The si.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + public bool IsSmaller(SI si, SI tolerance = null) + { + if (!HasEqualUnit(si)) { + throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si); + } + if (tolerance != null && !HasEqualUnit(tolerance)) { + throw new VectoException("tolerance has to be the same unit. Got: {0} <=> {1}", this, tolerance); + } + + return AsBasicUnit.IsSmaller(si.AsBasicUnit, tolerance == null ? DoubleExtensionMethods.Tolerance : tolerance.Value()); + } + + /// <summary> + /// Determines whether the specified si is smaller. + /// </summary> + /// <param name="si">The si.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + public bool IsSmaller(SI si, double tolerance) + { + if (!HasEqualUnit(si)) { + throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si); + } + + return Val.IsSmaller(si.Val, tolerance); + } + + /// <summary> + /// Determines whether [is smaller or equal] [the specified si]. + /// </summary> + /// <param name="si">The si.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + public bool IsSmallerOrEqual(SI si, SI tolerance = null) + { + if (!HasEqualUnit(si)) { + throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si); + } + if (tolerance != null && !HasEqualUnit(tolerance)) { + throw new VectoException("tolerance has to be the same unit. Got: {0} <=> {1}", this, tolerance); + } + + return AsBasicUnit.IsSmallerOrEqual(si.AsBasicUnit, tolerance == null ? DoubleExtensionMethods.Tolerance : tolerance.Value()); + } + + /// <summary> + /// Determines whether the specified si is greater. + /// </summary> + /// <param name="si">The si.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + public bool IsGreater(SI si, SI tolerance = null) + { + if (!HasEqualUnit(si)) { + throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si); + } + if (tolerance != null && !HasEqualUnit(tolerance)) { + throw new VectoException("tolerance has to be the same unit. Got: {0} <=> {1}", this, tolerance); + } + + return AsBasicUnit.IsGreater(si.AsBasicUnit, tolerance == null ? DoubleExtensionMethods.Tolerance : tolerance.Value()); + } + + /// <summary> + /// Determines whether the specified si is greater. + /// </summary> + /// <param name="si">The si.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + [DebuggerStepThrough] + public bool IsGreater(SI si, double tolerance) + { + if (!HasEqualUnit(si)) { + throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si); + } + + return Val.IsGreater(si.Val, tolerance); + } + + /// <summary> + /// Determines whether [is greater or equal] [the specified si]. + /// </summary> + /// <param name="si">The si.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + [DebuggerStepThrough] + public bool IsGreaterOrEqual(SI si, SI tolerance = null) + { + if (!HasEqualUnit(si)) { + throw new VectoException("compared value has to be the same unit. Got: {0} <=> {1}", this, si); + } + if (tolerance != null && !HasEqualUnit(tolerance)) { + throw new VectoException("tolerance has to be the same unit. Got: {0} <=> {1}", this, tolerance); + } + + return AsBasicUnit.IsGreaterOrEqual(si.AsBasicUnit, tolerance == null ? DoubleExtensionMethods.Tolerance : tolerance.Value()); + } + + /// <summary> + /// Determines whether the specified value is smaller. + /// </summary> + /// <param name="val">The value.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + [DebuggerStepThrough] + public bool IsSmaller(double val, double tolerance = DoubleExtensionMethods.Tolerance) + { + return Val.IsSmaller(val, tolerance); + } + + /// <summary> + /// Determines whether [is smaller or equal] [the specified value]. + /// </summary> + /// <param name="val">The value.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + [DebuggerStepThrough] + public bool IsSmallerOrEqual(double val, double tolerance = DoubleExtensionMethods.Tolerance) + { + return Val.IsSmallerOrEqual(val, tolerance); + } + + /// <summary> + /// Determines whether the specified value is greater. + /// </summary> + /// <param name="val">The value.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + [DebuggerStepThrough] + public bool IsGreater(double val, double tolerance = DoubleExtensionMethods.Tolerance) + { + return Val.IsGreater(val, tolerance); + } + + /// <summary> + /// Determines whether [is greater or equal] [the specified value]. + /// </summary> + /// <param name="val">The value.</param> + /// <param name="tolerance">The tolerance.</param> + /// <returns></returns> + [DebuggerStepThrough] + public bool IsGreaterOrEqual(double val, double tolerance = DoubleExtensionMethods.Tolerance) + { + return Val.IsGreaterOrEqual(val, tolerance); + } + + public override int GetHashCode() + { + unchecked { + // ReSharper disable once NonReadonlyMemberInGetHashCode + var hashCode = Val.GetHashCode(); + hashCode = (hashCode * 397) ^ (_units != null ? _units.GetHashCode() : 0); + return hashCode; + } + } + + public int CompareTo(object obj) + { + var si = obj as SI; + if (si == null) { + return 1; + } + + if (!HasEqualUnit(si)) { // TODO: thow exception! - var sum1 = 0; - var sum2 = 0; - for (var i = 0; i < _units.Length; i++) { - sum1 += Math.Abs(si._units[i]); - sum2 += Math.Abs(_units[i]); - } - return sum1 >= sum2 ? -1 : 1; - } - - if (this > si) { - return 1; - } - - if (this < si) { - return -1; - } - - return 0; - } - - public static bool operator ==(SI left, SI right) - { - return Equals(left, right); - } - - public static bool operator !=(SI left, SI right) - { - return !Equals(left, right); - } - - #endregion - - /// <summary> - /// Convert the SI to a string in the wished output format. - /// </summary> - /// <param name="decimals">The decimals.</param> - /// <param name="outputFactor">The output factor.</param> - /// <param name="showUnit">The show unit.</param> - /// <returns></returns> - public string ToOutputFormat(uint? decimals = null, double? outputFactor = null, bool? showUnit = null) - { - decimals = decimals ?? 4; - outputFactor = outputFactor ?? 1.0; - showUnit = showUnit ?? false; - - if (showUnit.Value) { - return (Val * outputFactor.Value).ToString("F" + decimals.Value, CultureInfo.InvariantCulture) + " [" + - UnitString + "]"; - } - - return (Val * outputFactor.Value).ToString("F" + decimals.Value, CultureInfo.InvariantCulture); - } - - public string ToGUIFormat() - { - return Val.ToGUIFormat(); - } - - public string ToXMLFormat(uint? decimals = null) - { - decimals = decimals ?? 2; - return Val.ToString("F" + decimals.Value, CultureInfo.InvariantCulture); - } - - public class EqualityComparer<T> : IEqualityComparer<T> where T : SI - { - private readonly double _precision; - - public EqualityComparer(double precision = DoubleExtensionMethods.Tolerance) - { - _precision = precision; - } - - public bool Equals(T x, T y) - { - return y != null && x != null && x.IsEqual(y.Value(), _precision); - } - - public int GetHashCode(T obj) - { - return obj.Value().GetHashCode(); - } - } - } + var sum1 = 0; + var sum2 = 0; + for (var i = 0; i < _units.Length; i++) { + sum1 += Math.Abs(si._units[i]); + sum2 += Math.Abs(_units[i]); + } + return sum1 >= sum2 ? -1 : 1; + } + + if (this > si) { + return 1; + } + + if (this < si) { + return -1; + } + + return 0; + } + + public static bool operator ==(SI left, SI right) + { + return Equals(left, right); + } + + public static bool operator !=(SI left, SI right) + { + return !Equals(left, right); + } + + #endregion + + /// <summary> + /// Convert the SI to a string in the wished output format. + /// </summary> + /// <param name="decimals">The decimals.</param> + /// <param name="outputFactor">The output factor.</param> + /// <param name="showUnit">The show unit.</param> + /// <returns></returns> + public string ToOutputFormat(uint? decimals = null, double? outputFactor = null, bool? showUnit = null) + { + decimals = decimals ?? 4; + outputFactor = outputFactor ?? 1.0; + showUnit = showUnit ?? false; + + if (showUnit.Value) { + return (Val * outputFactor.Value).ToString("F" + decimals.Value, CultureInfo.InvariantCulture) + " [" + + UnitString + "]"; + } + + return (Val * outputFactor.Value).ToString("F" + decimals.Value, CultureInfo.InvariantCulture); + } + + public string ToGUIFormat() + { + return Val.ToGUIFormat(); + } + + public string ToXMLFormat(uint? decimals = null) + { + decimals = decimals ?? 2; + return Val.ToString("F" + decimals.Value, CultureInfo.InvariantCulture); + } + + public class EqualityComparer<T> : IEqualityComparer<T> where T : SI + { + private readonly double _precision; + + public EqualityComparer(double precision = DoubleExtensionMethods.Tolerance) + { + _precision = precision; + } + + public bool Equals(T x, T y) + { + return y != null && x != null && x.IsEqual(y.Value(), _precision); + } + + public int GetHashCode(T obj) + { + return obj.Value().GetHashCode(); + } + } + } } \ No newline at end of file diff --git a/VectoCommon/VectoCommon/VectoCommon.csproj b/VectoCommon/VectoCommon/VectoCommon.csproj index 863d09c76a..ada7b6397c 100644 --- a/VectoCommon/VectoCommon/VectoCommon.csproj +++ b/VectoCommon/VectoCommon/VectoCommon.csproj @@ -44,6 +44,8 @@ <Reference Include="System.Xml" /> </ItemGroup> <ItemGroup> + <Compile Include="Hashing\IVectoHash.cs" /> + <Compile Include="Hashing\VectoComponents.cs" /> <Compile Include="InputData\DataSourceType.cs" /> <Compile Include="InputData\TableData.cs"> <SubType>Component</SubType> diff --git a/VectoCommon/VectoHashing/VectoHash.cs b/VectoCommon/VectoHashing/VectoHash.cs index 8b42dd4bd2..60b5ae0156 100644 --- a/VectoCommon/VectoHashing/VectoHash.cs +++ b/VectoCommon/VectoHashing/VectoHash.cs @@ -37,6 +37,7 @@ using System.Linq; using System.Security.Cryptography.X509Certificates; using System.Xml; using System.Xml.Linq; +using TUGraz.VectoCommon.Hashing; using TUGraz.VectoCommon.Resources; using TUGraz.VectoCommon.Utils; using TUGraz.VectoHashing.Impl; diff --git a/VectoCommon/VectoHashing/VectoHashing.csproj b/VectoCommon/VectoHashing/VectoHashing.csproj index ef6a15de8a..8d496c1df7 100644 --- a/VectoCommon/VectoHashing/VectoHashing.csproj +++ b/VectoCommon/VectoHashing/VectoHashing.csproj @@ -44,9 +44,7 @@ </ItemGroup> <ItemGroup> <Compile Include="Impl\XmlDsigVectoTransform.cs" /> - <Compile Include="IVectoHash.cs" /> <Compile Include="Util\XmlDocumentExtensions.cs" /> - <Compile Include="VectoComponents.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="VectoHash.cs" /> <Compile Include="Impl\XmlHashProvider.cs" /> @@ -59,12 +57,6 @@ <ItemGroup> <EmbeddedResource Include="Resources\XSLT\SortInputData.xslt" /> </ItemGroup> - <ItemGroup> - <ProjectReference Include="..\VectoCommon\VectoCommon.csproj"> - <Project>{79A066AD-69A9-4223-90F6-6ED5D2D084F4}</Project> - <Name>VectoCommon</Name> - </ProjectReference> - </ItemGroup> <ItemGroup> <None Include="Properties\Version.tt"> <Generator>TextTemplatingFileGenerator</Generator> @@ -74,6 +66,12 @@ <ItemGroup> <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" /> </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\VectoCommon\VectoCommon.csproj"> + <Project>{79A066AD-69A9-4223-90F6-6ED5D2D084F4}</Project> + <Name>VectoCommon</Name> + </ProjectReference> + </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets. diff --git a/VectoCommon/VectoHashingTest/VectoHashTest.cs b/VectoCommon/VectoHashingTest/VectoHashTest.cs index 163bff91ce..a627545a37 100644 --- a/VectoCommon/VectoHashingTest/VectoHashTest.cs +++ b/VectoCommon/VectoHashingTest/VectoHashTest.cs @@ -38,6 +38,7 @@ using System.Xml.Linq; using System.Xml.Schema; using System.Xml.XPath; using NUnit.Framework; +using TUGraz.VectoCommon.Hashing; using TUGraz.VectoCore.Utils; using TUGraz.VectoHashing; using VectoHashingTest.Utils; diff --git a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONComponentInputData.cs b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONComponentInputData.cs index 2a028c292f..3ad0ed8663 100644 --- a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONComponentInputData.cs +++ b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONComponentInputData.cs @@ -124,7 +124,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON public string Date { get; private set; } public CertificationMethod CertificationMethod { get; private set; } public string CertificationNumber { get; private set; } - public string DigestValue { get; private set; } + public DigestData DigestValue { get; private set; } IVehicleDeclarationInputData IDeclarationJobInputData.Vehicle { diff --git a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONEngineData.cs b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONEngineData.cs index d3971d189c..a6af4ce772 100644 --- a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONEngineData.cs +++ b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONEngineData.cs @@ -241,9 +241,9 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON get { return "N/A"; } } - public string DigestValue + public DigestData DigestValue { - get { return "N/A"; } + get { return null; } } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONGearboxData.cs b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONGearboxData.cs index e541d37d53..ae7c0ba2f0 100644 --- a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONGearboxData.cs +++ b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONGearboxData.cs @@ -500,9 +500,9 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON get { return "N/A"; } } - public string DigestValue + public DigestData DigestValue { - get { return ""; } + get { return null; } } } } diff --git a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputData.cs b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputData.cs index 9f5a5f9005..21b708c4f9 100644 --- a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputData.cs +++ b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONInputData.cs @@ -37,6 +37,7 @@ using System.Linq; using System.Xml; using System.Xml.Linq; using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Hashing; using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Resources; @@ -47,6 +48,7 @@ using TUGraz.VectoCore.InputData.Impl; using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.SimulationComponent.Data; using TUGraz.VectoCore.Utils; +using TUGraz.VectoHashing; namespace TUGraz.VectoCore.InputData.FileIO.JSON { @@ -98,9 +100,11 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON throw new VectoException("Failed to read file for {0}: {1}", e, tableType, filename); } } + if (required) { throw new VectoException("Invalid filename for {0}: {1}", tableType, filename); } + return null; } @@ -113,10 +117,11 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON public static JObject GetDummyJSONStructure() { - return JObject.FromObject(new Dictionary<string, object>() { - { JsonKeys.JsonHeader, new object() }, - { JsonKeys.JsonBody, new object() } - }); + return JObject.FromObject( + new Dictionary<string, object>() { + { JsonKeys.JsonHeader, new object() }, + { JsonKeys.JsonBody, new object() } + }); } } @@ -175,11 +180,14 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON Path.Combine(BasePath, vehicleFile), this); } catch (Exception e) { if (!TolerateMissing) { - throw new VectoException("JobFile: Failed to read Vehicle file '{0}': {1}", e, + throw new VectoException( + "JobFile: Failed to read Vehicle file '{0}': {1}", e, Body[JsonKeys.Vehicle_VehicleFile], e.Message); } - return new JSONVehicleDataV7(GetDummyJSONStructure(), + + return new JSONVehicleDataV7( + GetDummyJSONStructure(), Path.Combine(BasePath, Body.GetEx(JsonKeys.Vehicle_VehicleFile).Value<string>()) + MissingFileSuffix, this); } @@ -193,11 +201,14 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON return JSONInputDataFactory.ReadGearbox(Path.Combine(BasePath, gearboxFile)); } catch (Exception e) { if (!TolerateMissing) { - throw new VectoException("JobFile: Failed to read Gearbox file '{0}': {1}", e, + throw new VectoException( + "JobFile: Failed to read Gearbox file '{0}': {1}", e, Body[JsonKeys.Vehicle_GearboxFile], e.Message); } - return new JSONGearboxDataV6(GetDummyJSONStructure(), + + return new JSONGearboxDataV6( + GetDummyJSONStructure(), Path.Combine(BasePath, Body.GetEx(JsonKeys.Vehicle_GearboxFile).Value<string>()) + MissingFileSuffix); } @@ -210,13 +221,15 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON Path.Combine(BasePath, Body.GetEx(JsonKeys.Vehicle_EngineFile).Value<string>())); } catch (Exception e) { if (!TolerateMissing) { - throw new VectoException("JobFile: Failed to read Engine file '{0}': {1}", e, + throw new VectoException( + "JobFile: Failed to read Engine file '{0}': {1}", e, Body[JsonKeys.Vehicle_EngineFile], e.Message); } return - new JSONEngineDataV3(GetDummyJSONStructure(), + new JSONEngineDataV3( + GetDummyJSONStructure(), Path.Combine(BasePath, Body.GetEx(JsonKeys.Vehicle_EngineFile).Value<string>()) + MissingFileSuffix); } @@ -246,26 +259,28 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON public virtual IVehicleEngineeringInputData VehicleInputData { - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", + [System.Diagnostics.CodeAnalysis.SuppressMessage( + "Microsoft.Design", "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] - get - { + get { if (VehicleData == null) { throw new InvalidFileFormatException("VehicleData not found "); } + return VehicleData; } } public virtual IEngineEngineeringInputData EngineOnly { - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", + [System.Diagnostics.CodeAnalysis.SuppressMessage( + "Microsoft.Design", "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] - get - { + get { if (Engine == null) { throw new InvalidFileFormatException("EngineData not found"); } + return Engine; } } @@ -286,14 +301,15 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON public virtual IList<ICycleData> Cycles { - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", + [System.Diagnostics.CodeAnalysis.SuppressMessage( + "Microsoft.Design", "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] - get - { + get { var retVal = new List<ICycleData>(); if (Body[JsonKeys.Job_Cycles] == null) { return retVal; } + foreach (var cycle in Body.GetEx(JsonKeys.Job_Cycles)) { //.Select(cycle => var cycleFile = Path.Combine(BasePath, cycle.Value<string>()); @@ -304,21 +320,26 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON try { var resourceName = DeclarationData.DeclarationDataResourcePrefix + ".MissionCycles." + cycle.Value<string>() + Constants.FileExtensions.CycleFile; - cycleData = VectoCSVFile.ReadStream(RessourceHelper.ReadStream(resourceName), + cycleData = VectoCSVFile.ReadStream( + RessourceHelper.ReadStream(resourceName), source: resourceName); } catch (Exception e) { Log.Debug("Driving Cycle could not be read: " + cycleFile); if (!TolerateMissing) { throw new VectoException("Driving Cycle could not be read: " + cycleFile, e); } + cycleData = new TableData(cycleFile + MissingFileSuffix, DataSourceType.Missing); } } - retVal.Add(new CycleInputData() { - Name = Path.GetFileNameWithoutExtension(cycle.Value<string>()), - CycleData = cycleData - }); + + retVal.Add( + new CycleInputData() { + Name = Path.GetFileNameWithoutExtension(cycle.Value<string>()), + CycleData = cycleData + }); } + return retVal; } } @@ -339,8 +360,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON public virtual ILookaheadCoastingInputData Lookahead { - get - { + get { if (Body[JsonKeys.DriverData_LookaheadCoasting] == null) { return null; } @@ -362,6 +382,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON : DeclarationData.Driver.LookAhead.MinimumSpeed; return new LookAheadCoastingInputData() { Enabled = lac.GetEx<bool>(JsonKeys.DriverData_Lookahead_Enabled), + //Deceleration = lac.GetEx<double>(JsonKeys.DriverData_Lookahead_Deceleration).SI<MeterPerSquareSecond>(), MinSpeed = minSpeed, LookaheadDistanceFactor = distanceScalingFactor, @@ -379,8 +400,10 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON string.IsNullOrWhiteSpace(lac["Df_velocityDropLookup"].Value<string>())) { return null; } + try { - return ReadTableData(lac.GetEx<string>("Df_velocityDropLookup"), + return ReadTableData( + lac.GetEx<string>("Df_velocityDropLookup"), "Lookahead Coasting Decisionfactor - Velocity drop"); } catch (Exception) { if (TolerateMissing) { @@ -390,6 +413,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON DataSourceType.Missing); } } + return null; } @@ -399,8 +423,10 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON string.IsNullOrWhiteSpace(lac["DF_targetSpeedLookup"].Value<string>())) { return null; } + try { - return ReadTableData(lac.GetEx<string>("DF_targetSpeedLookup"), + return ReadTableData( + lac.GetEx<string>("DF_targetSpeedLookup"), "Lookahead Coasting Decisionfactor - Target speed"); } catch (Exception) { if (TolerateMissing) { @@ -410,21 +436,21 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON DataSourceType.Missing); } } + return null; } public virtual IOverSpeedEcoRollEngineeringInputData OverSpeedEcoRoll { - get - { + get { var overspeed = Body.GetEx(JsonKeys.DriverData_OverspeedEcoRoll); return new OverSpeedEcoRollInputData() { Mode = DriverData.ParseDriverMode( overspeed.GetEx<string>(JsonKeys.DriverData_OverspeedEcoRoll_Mode)), MinSpeed = overspeed.GetEx<double>(JsonKeys.DriverData_OverspeedEcoRoll_MinSpeed) - .KMPHtoMeterPerSecond(), + .KMPHtoMeterPerSecond(), OverSpeed = overspeed.GetEx<double>(JsonKeys.DriverData_OverspeedEcoRoll_OverSpeed) - .KMPHtoMeterPerSecond(), + .KMPHtoMeterPerSecond(), UnderSpeed = overspeed.GetEx<double>(JsonKeys.DriverData_OverspeedEcoRoll_UnderSpeed).KMPHtoMeterPerSecond() }; @@ -433,15 +459,17 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON public virtual TableData AccelerationCurve { - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", + [System.Diagnostics.CodeAnalysis.SuppressMessage( + "Microsoft.Design", "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] - get - { + get { var acceleration = Body[JsonKeys.DriverData_AccelerationCurve]; if (acceleration == null || EmptyOrInvalidFileName(acceleration.Value<string>())) { return null; + // throw new VectoException("AccelerationCurve (VACC) required"); } + try { return ReadTableData(acceleration.Value<string>(), "DriverAccelerationCurve"); } catch (VectoException e) { @@ -455,7 +483,9 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON if (!TolerateMissing) { throw new VectoException("Failed to read Driver Acceleration Curve: " + e.Message, e); } - return new TableData(Path.Combine(BasePath, acceleration.Value<string>()) + MissingFileSuffix, + + return new TableData( + Path.Combine(BasePath, acceleration.Value<string>()) + MissingFileSuffix, DataSourceType.Missing); } } @@ -512,9 +542,11 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON continue; } - AuxiliaryFileHelper.FillAuxiliaryDataInputData(auxData, + AuxiliaryFileHelper.FillAuxiliaryDataInputData( + auxData, Path.Combine(BasePath, auxFile.Value<string>())); } + return retVal; } @@ -535,6 +567,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON newTech = tech; break; } + return newTech; } @@ -544,11 +577,11 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON public AuxiliaryModel AuxiliaryAssembly { - get - { - return AuxiliaryModelHelper.Parse(Body["AuxiliaryAssembly"] == null - ? "" - : Body["AuxiliaryAssembly"].ToString()); + get { + return AuxiliaryModelHelper.Parse( + Body["AuxiliaryAssembly"] == null + ? "" + : Body["AuxiliaryAssembly"].ToString()); } } @@ -559,8 +592,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON public string AdvancedAuxiliaryFilePath { - get - { + get { return Body["AdvancedAuxiliaryFilePath"] != null ? Path.Combine(Path.GetFullPath(BasePath), Body["AdvancedAuxiliaryFilePath"].Value<string>()) : ""; @@ -579,11 +611,12 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON { var retVal = new List<AuxiliaryDataInputData>(); if (Body["Padd"] != null) { - retVal.Add(new AuxiliaryDataInputData() { - ID = "ConstantAux", - AuxiliaryType = AuxiliaryDemandType.Constant, - ConstantPowerDemand = Body.GetEx<double>("Padd").SI<Watt>() - }); + retVal.Add( + new AuxiliaryDataInputData() { + ID = "ConstantAux", + AuxiliaryType = AuxiliaryDemandType.Constant, + ConstantPowerDemand = Body.GetEx<double>("Padd").SI<Watt>() + }); } foreach (var aux in Body["Aux"] ?? Enumerable.Empty<JToken>()) { try { @@ -608,9 +641,12 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON if (auxFile == null || EmptyOrInvalidFileName(auxFile.Value<string>())) { continue; } - AuxiliaryFileHelper.FillAuxiliaryDataInputData(auxData, + + AuxiliaryFileHelper.FillAuxiliaryDataInputData( + auxData, Path.Combine(BasePath, auxFile.Value<string>())); } + return retVal; } } @@ -622,44 +658,64 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON : base(data, filename, tolerateMissing) { } } - public class JSONVTPInputDataV4 : JSONFile, IVTPEngineeringInputDataProvider, IVTPEngineeringJobInputData, IVTPDeclarationInputDataProvider + public class JSONVTPInputDataV4 : JSONFile, IVTPEngineeringInputDataProvider, IVTPEngineeringJobInputData, + IVTPDeclarationInputDataProvider, IManufacturerReport { - public JSONVTPInputDataV4(JObject data, string filename, bool tolerateMissing = false) : base(data, filename, - tolerateMissing) { } + private IDictionary<VectoComponents, IList<string>> _componentDigests = null; + private DigestData _jobDigest = null; + + public JSONVTPInputDataV4(JObject data, string filename, bool tolerateMissing = false) : base( + data, filename, tolerateMissing) + { + VectoJobHash = VectoHashing.VectoHash.Load( + Path.Combine(Path.GetFullPath(BasePath), Body["DeclarationVehicle"].Value<string>())); + VectoManufacturerReportHash = VectoHashing.VectoHash.Load( + Path.Combine(Path.GetFullPath(BasePath), Body["ManufacturerRecord"].Value<string>())); + } public IVTPEngineeringJobInputData JobInputData { get { return this; } } + public IManufacturerReport ManufacturerReportInputData + { + get { return this; } + } + public IVehicleDeclarationInputData Vehicle { - get - { + get { return new XMLDeclarationInputDataProvider( Path.Combine(Path.GetFullPath(BasePath), Body["DeclarationVehicle"].Value<string>()), true).JobInputData.Vehicle; } } + public IVectoHash VectoJobHash { get; } + + public IVectoHash VectoManufacturerReportHash { get; } + public IList<ICycleData> Cycles { - get - { + get { var retVal = new List<ICycleData>(); if (Body[JsonKeys.Job_Cycles] == null) { return retVal; } + foreach (var cycle in Body.GetEx(JsonKeys.Job_Cycles)) { var cycleFile = Path.Combine(BasePath, cycle.Value<string>()); if (File.Exists(cycleFile)) { var cycleData = VectoCSVFile.Read(cycleFile); - retVal.Add(new CycleInputData() { - Name = Path.GetFileNameWithoutExtension(cycle.Value<string>()), - CycleData = cycleData - }); + retVal.Add( + new CycleInputData() { + Name = Path.GetFileNameWithoutExtension(cycle.Value<string>()), + CycleData = cycleData + }); } } + return retVal; } } @@ -682,5 +738,60 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON } #endregion + + #region Implementation of IManufacturerReport + + IDictionary<VectoComponents, IList<string>> IManufacturerReport.ComponentDigests + { + get { + if (_componentDigests == null) { + ReadManufacturerReport(); + } + return _componentDigests; + } + } + + public DigestData JobDigest + { + get { + if (_jobDigest == null) { + ReadManufacturerReport(); + } + return _jobDigest; + } + } + + #endregion + + private void ReadManufacturerReport() + { + var xmlDoc = new XmlDocument(); + xmlDoc.Load(Path.Combine(Path.GetFullPath(BasePath), Body["ManufacturerRecord"].Value<string>())); + var components = XMLManufacturerReportReader.GetContainingComponents(xmlDoc).GroupBy(s => s) + .Select(g => new { Entry = g.Key, Count = g.Count() }); + _componentDigests = new Dictionary<VectoComponents, IList<string>>(); + + try { + foreach (var component in components) { + if (component.Entry == VectoComponents.Vehicle) { + continue; + } + + for (var i = 0; i < component.Count; i++) { + if (!_componentDigests.ContainsKey(component.Entry)) { + _componentDigests[component.Entry] = new List<string>(); + } + _componentDigests[component.Entry].Add( + XMLManufacturerReportReader.GetComponentDataDigestValue(xmlDoc, component.Entry, i)); + } + } + } catch (Exception) { } + + try { + _jobDigest = new DigestData(xmlDoc.SelectSingleNode("//*[local-name()='InputDataSignature']")); + } catch (Exception) { + _jobDigest = new DigestData("", new string[] {},"","" ); + } + } } -} \ No newline at end of file +} diff --git a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONVehicleData.cs b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONVehicleData.cs index 0f44e5907d..0382ce6c7e 100644 --- a/VectoCore/VectoCore/InputData/FileIO/JSON/JSONVehicleData.cs +++ b/VectoCore/VectoCore/InputData/FileIO/JSON/JSONVehicleData.cs @@ -486,9 +486,9 @@ namespace TUGraz.VectoCore.InputData.FileIO.JSON get { return "N.A."; } } - public string DigestValue + public DigestData DigestValue { - get { return ""; } + get { return null; } } } } diff --git a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/AbstractDeclarationXMLComponentDataProvider.cs b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/AbstractDeclarationXMLComponentDataProvider.cs index 09dd2e462e..2b292d2737 100644 --- a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/AbstractDeclarationXMLComponentDataProvider.cs +++ b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/AbstractDeclarationXMLComponentDataProvider.cs @@ -112,17 +112,16 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration get { return GetElementValue(XMLNames.Component_CertificationNumber); } } - public virtual string DigestValue + public virtual DigestData DigestValue { - get { return GetElementValue("..//*[local-name()='DigestValue']"); } + get { return new DigestData(Navigator.SelectSingleNode(XBasePath + "/..", Manager)); } } protected bool ElementExists(string relativePath) { var path = Helper.Query(XBasePath, relativePath.Any() ? relativePath : null); - //new StringBuilder(XBasePath + (relativePath.Any() ? "/" + relativePath : "")); - + var node = Navigator.SelectSingleNode(path, Manager); return node != null; } @@ -138,6 +137,19 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration return node.InnerXml; } + protected string[] GetElementValues(string querypath) + { + var path = Helper.Query(XBasePath, querypath.Any() ? querypath : null); + + var nodes = Navigator.Select(path, Manager); + var retVal = new List<string>(); + while (nodes.MoveNext()) { + retVal.Add(nodes.Current.InnerXml); + } + + return retVal.ToArray(); + } + protected double GetDoubleElementValue(string relativePath) { return GetElementValue(relativePath).ToDouble(); diff --git a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLDeclarationInputDataProvider.cs b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLDeclarationInputDataProvider.cs index 63ad01d6dd..f583290f3e 100644 --- a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLDeclarationInputDataProvider.cs +++ b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLDeclarationInputDataProvider.cs @@ -49,19 +49,19 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration private readonly XMLDeclarationJobInputDataProvider _xmlJobData; - public XMLDeclarationInputDataProvider(string filename, bool verifyXml) : - this(XmlReader.Create(filename), filename, verifyXml) - { - } + public XMLDeclarationInputDataProvider(string filename, bool verifyXml) : + this(XmlReader.Create(filename), filename, verifyXml) + { + } - public XMLDeclarationInputDataProvider(XmlReader inputData, bool verifyXml) : this(inputData, "", verifyXml) - { - - } + public XMLDeclarationInputDataProvider(XmlReader inputData, bool verifyXml) : this(inputData, "", verifyXml) + { + + } - protected XMLDeclarationInputDataProvider(XmlReader inputData, string source, bool verifyXml) - { - Source = source; + protected XMLDeclarationInputDataProvider(XmlReader inputData, string source, bool verifyXml) + { + Source = source; var xmldoc = new XmlDocument(); xmldoc.Load(inputData); @@ -72,13 +72,13 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration var h = VectoHash.Load(xmldoc); XMLHash = h.ComputeXmlHash(); Document = new XPathDocument(new XmlNodeReader(xmldoc)); - + _xmlJobData = new XMLDeclarationJobInputDataProvider(this); } - public string Source { get; protected set; } + public string Source { get; protected set; } - private static void ValidationCallBack(XmlSeverityType severity, ValidationEvent evt) + private static void ValidationCallBack(XmlSeverityType severity, ValidationEvent evt) { if (severity == XmlSeverityType.Error) { var args = evt.ValidationEventArgs; diff --git a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLDeclarationVehicleDataProvider.cs b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLDeclarationVehicleDataProvider.cs index c4a8d1c726..842f2050a7 100644 --- a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLDeclarationVehicleDataProvider.cs +++ b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLDeclarationVehicleDataProvider.cs @@ -139,7 +139,6 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration var rollResistance = tyre.SelectSingleNode(Helper.NSPrefix(XMLNames.AxleWheels_Axles_Axle_RRCDeclared), Manager); var tyreTestLoad = tyre.SelectSingleNode(Helper.NSPrefix(XMLNames.AxleWheels_Axles_Axle_FzISO), Manager); var certirficationNumber = tyre.SelectSingleNode(Helper.NSPrefix(XMLNames.Component_CertificationNumber), Manager); - var digestValue = tyre.SelectSingleNode(Helper.Query("..//*[local-name()='DigestValue']"), Manager); retVal[axleNumber - 1] = new AxleInputData { AxleType = axleType == null ? AxleType.VehicleNonDriven : axleType.Value.ParseEnum<AxleType>(), TwinTyres = twinTyres != null && XmlConvert.ToBoolean(twinTyres.Value), @@ -150,7 +149,7 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration Dimension = dimension == null ? null : dimension.Value, CertificationNumber = certirficationNumber == null ? null : certirficationNumber.Value, CertificationMethod = CertificationMethod.Measured, - DigestValue = digestValue == null ? "" : digestValue.Value + DigestValue = new DigestData(tyre.SelectSingleNode(Helper.Query("..//*[local-name()='DigestValue']/.."), Manager)) } }; } diff --git a/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLManufacturerReportReader.cs b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLManufacturerReportReader.cs new file mode 100644 index 0000000000..82d1b095e6 --- /dev/null +++ b/VectoCore/VectoCore/InputData/FileIO/XML/Declaration/XMLManufacturerReportReader.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Xml; +using TUGraz.VectoCommon.Hashing; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Resources; +using TUGraz.VectoCommon.Utils; + +namespace TUGraz.VectoCore.InputData.FileIO.XML.Declaration +{ + public class XMLManufacturerReportReader + { + public static IList<VectoComponents> GetContainingComponents(XmlDocument xmlDocument) + { + var retVal = new List<VectoComponents>(); + foreach (var component in EnumHelper.GetValues<VectoComponents>()) { + var nodes = xmlDocument.SelectNodes(string.Format("//*[local-name()='{0}']//*[local-name()='{1}']/*[local-name()='Model']", + XMLNames.VectoManufacturerReport, component.XMLElementName())); + var count = nodes == null ? 0 : nodes.Count; + for (var i = 0; i < count; i++) { + retVal.Add(component); + } + } + foreach (var component in new[] { XMLNames.AxleWheels_Axles_Axle }) { + var nodes = xmlDocument.SelectNodes(string.Format("//*[local-name()='{0}']//*[local-name()='{1}']", + XMLNames.VectoManufacturerReport, component)); + var count = nodes == null ? 0 : nodes.Count; + for (var i = 0; i < count; i++) { + retVal.Add(VectoComponents.Tyre); + } + } + return retVal; + } + + public static string GetComponentDataDigestValue(XmlDocument xmlDocument, VectoComponents component, int i) + { + var node = GetNodes(xmlDocument, component, i); + + return ReadElementValue(node, XMLNames.DI_Signature_Reference_DigestValue); + } + + public static XmlNode GetNodes(XmlDocument xmlDocument, VectoComponents component, int index) + { + var nodes = xmlDocument.SelectNodes(GetComponentQueryString(component == VectoComponents.Tyre ? "Axle" : component.XMLElementName())); + if (nodes == null || nodes.Count == 0) { + throw new Exception(string.Format("Component {0} not found", component)); + } + if (index >= nodes.Count) { + throw new Exception(string.Format("index exceeds number of components found! index: {0}, #components: {1}", index, + nodes.Count)); + } + return nodes[index]; + } + + static string GetComponentQueryString(string component = null) + { + if (component == null) { + return "(//*[@id])[1]"; + } + return string.Format("//*[local-name()='{0}']", component); + } + + static string ReadElementValue(XmlNode xmlNode, string elementName) + { + var node = xmlNode.SelectSingleNode(string.Format("./*[local-name()='{0}']", elementName)); + if (node == null) { + return null; + } + return node.InnerText; + } + } +} diff --git a/VectoCore/VectoCore/InputData/FileIO/XML/Engineering/AbstractEngineeringXMLComponentDataProvider.cs b/VectoCore/VectoCore/InputData/FileIO/XML/Engineering/AbstractEngineeringXMLComponentDataProvider.cs index b4bc0fb6f9..c8060152b6 100644 --- a/VectoCore/VectoCore/InputData/FileIO/XML/Engineering/AbstractEngineeringXMLComponentDataProvider.cs +++ b/VectoCore/VectoCore/InputData/FileIO/XML/Engineering/AbstractEngineeringXMLComponentDataProvider.cs @@ -89,9 +89,9 @@ namespace TUGraz.VectoCore.InputData.FileIO.XML.Engineering get { return GetElementValue(XMLNames.Component_Date); } } - public override string DigestValue + public override DigestData DigestValue { - get { return ""; } + get { return null; } } public override string CertificationNumber diff --git a/VectoCore/VectoCore/InputData/Impl/InputData.cs b/VectoCore/VectoCore/InputData/Impl/InputData.cs index 968031b997..24f1862055 100644 --- a/VectoCore/VectoCore/InputData/Impl/InputData.cs +++ b/VectoCore/VectoCore/InputData/Impl/InputData.cs @@ -125,7 +125,7 @@ namespace TUGraz.VectoCore.InputData.Impl public string CertificationNumber { get; internal set; } - public string DigestValue { get; internal set; } + public DigestData DigestValue { get; internal set; } public string Dimension { get; internal set; } diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/AbstractSimulationDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/AbstractSimulationDataAdapter.cs index ec5307606e..e48b0122dc 100644 --- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/AbstractSimulationDataAdapter.cs +++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/AbstractSimulationDataAdapter.cs @@ -56,7 +56,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter ModelName = data.Model, Date = data.Date, //CertificationNumber = data.CertificationNumber, - DigestValueInput = data.DigestValue, + DigestValueInput = data.DigestValue.DigestValue, VehicleCategory = data.VehicleCategory, AxleConfiguration = data.AxleConfiguration, CurbWeight = data.CurbMassChassis, @@ -76,7 +76,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter Date = data.Date, CertificationMethod = data.CertificationMethod, CertificationNumber = data.CertificationNumber, - DigestValueInput = data.DigestValue, + DigestValueInput = data.DigestValue.DigestValue, }; return retVal; } @@ -113,7 +113,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter retarder.Date = data.Date; retarder.CertificationMethod = data.CertificationMethod; retarder.CertificationNumber = data.CertificationNumber; - retarder.DigestValueInput = data.DigestValue; + retarder.DigestValueInput = data.DigestValue.DigestValue; return retarder; } catch (Exception e) { @@ -129,7 +129,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter ModelName = data.Model, Date = data.Date, CertificationNumber = data.CertificationNumber, - DigestValueInput = data.DigestValue, + DigestValueInput = data.DigestValue.DigestValue, Displacement = data.Displacement, IdleSpeed = data.IdleSpeed, ConsumptionMap = FuelConsumptionMapReader.Create(data.FuelConsumptionMap), @@ -150,7 +150,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter Date = data.Date, CertificationMethod = data.CertificationMethod, CertificationNumber = data.CertificationNumber, - DigestValueInput = data.DigestValue, + DigestValueInput = data.DigestValue.DigestValue, Type = data.Type }; } @@ -224,7 +224,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter Date = data.Date, CertificationMethod = data.CertificationMethod, CertificationNumber = data.CertificationNumber, - DigestValueInput = data.DigestValue, + DigestValueInput = data.DigestValue.DigestValue, AxleGear = new GearData { Ratio = data.Ratio } }; } @@ -252,7 +252,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter Date = data.Date, CertificationMethod = data.CertificationMethod, CertificationNumber = data.CertificationNumber, - DigestValueInput = data.DigestValue, + DigestValueInput = data.DigestValue.DigestValue, Type = type, Angledrive = new TransmissionData { Ratio = data.Ratio } }; diff --git a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs index 0c934c136d..0d051fc854 100644 --- a/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs +++ b/VectoCore/VectoCore/InputData/Reader/DataObjectAdapter/DeclarationDataAdapter.cs @@ -122,7 +122,7 @@ namespace TUGraz.VectoCore.InputData.Reader.DataObjectAdapter TyreTestLoad = axleInput.Tyre.TyreTestLoad, Inertia = DeclarationData.Wheels.Lookup(axleInput.Tyre.Dimension.RemoveWhitespace()).Inertia, CertificationNumber = axleInput.Tyre.CertificationNumber, - DigestValueInput = axleInput.Tyre.DigestValue, + DigestValueInput = axleInput.Tyre.DigestValue.DigestValue, }; axleData.Add(axle); } diff --git a/VectoCore/VectoCore/InputData/Reader/DrivingCycleDataReader.cs b/VectoCore/VectoCore/InputData/Reader/DrivingCycleDataReader.cs index 18879c3ce7..16a67cc062 100644 --- a/VectoCore/VectoCore/InputData/Reader/DrivingCycleDataReader.cs +++ b/VectoCore/VectoCore/InputData/Reader/DrivingCycleDataReader.cs @@ -74,9 +74,9 @@ namespace TUGraz.VectoCore.InputData.Reader if (DistanceBasedCycleDataParser.ValidateHeader(cols, false)) { return CycleType.DistanceBased; } - if (VTPCycleDataParser.ValidateHeader(cols, false)) { - return CycleType.VTP; - } + if (VTPCycleDataParser.ValidateHeader(cols, false)) { + return CycleType.VTP; + } throw new VectoException("CycleFile format is unknown."); } @@ -95,10 +95,10 @@ namespace TUGraz.VectoCore.InputData.Reader return new MeasuredSpeedDataParser(); case CycleType.PTO: return new PTOCycleDataParser(); - case CycleType.VTP: - return new VTPCycleDataParser(); + case CycleType.VTP: + return new VTPCycleDataParser(); - default: + default: throw new ArgumentOutOfRangeException("Cycle Type", type.ToString()); } } @@ -317,8 +317,8 @@ namespace TUGraz.VectoCore.InputData.Reader public const string RoadGradient = "grad"; public const string StoppingTime = "stop"; public const string EngineSpeed = "n"; - public const string EngineSpeedSuffix = "n_eng"; - public const string FanSpeed = "n_fan"; + public const string EngineSpeedSuffix = "n_eng"; + public const string FanSpeed = "n_fan"; public const string WheelTorqueLeft = "tq_left"; public const string WheelTorqueRight = "tq_right"; public const string WheelSpeedLeft = "n_wh_left"; @@ -414,7 +414,7 @@ namespace TUGraz.VectoCore.InputData.Reader VehicleTargetSpeed = row.ParseDouble(Fields.VehicleSpeed).KMPHtoMeterPerSecond(), RoadGradient = VectoMath.InclinationToAngle(row.ParseDoubleOrGetDefault(Fields.RoadGradient) / 100.0), StoppingTime = row.ParseDouble(Fields.StoppingTime).SI<Second>(), - AdditionalAuxPowerDemand = row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI(Unit.SI.Kilo.Watt).Cast<Watt>(), + AdditionalAuxPowerDemand = row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI(Unit.SI.Kilo.Watt).Cast<Watt>(), AngularVelocity = row.ParseDoubleOrGetDefault(Fields.EngineSpeed).RPMtoRad(), Gear = (uint)row.ParseDoubleOrGetDefault(Fields.Gear), AirSpeedRelativeToVehicle = @@ -467,7 +467,7 @@ namespace TUGraz.VectoCore.InputData.Reader Time = row.ParseDoubleOrGetDefault(Fields.Time, absTime).SI<Second>(), AngularVelocity = row.ParseDoubleOrGetDefault(Fields.EngineSpeed).RPMtoRad(), AdditionalAuxPowerDemand = - row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI(Unit.SI.Kilo.Watt).Cast<Watt>(), + row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI(Unit.SI.Kilo.Watt).Cast<Watt>(), AuxiliarySupplyPower = row.GetAuxiliaries() }; @@ -481,7 +481,7 @@ namespace TUGraz.VectoCore.InputData.Reader if (row.Field<string>(Fields.EnginePower).Equals("<DRAG>")) { entry.Drag = true; } else { - entry.Torque = row.ParseDouble(Fields.EnginePower).SI(Unit.SI.Kilo.Watt).Cast<Watt>() / entry.AngularVelocity; + entry.Torque = row.ParseDouble(Fields.EnginePower).SI(Unit.SI.Kilo.Watt).Cast<Watt>() / entry.AngularVelocity; } } absTime += 1; @@ -542,10 +542,10 @@ namespace TUGraz.VectoCore.InputData.Reader var entries = table.Rows.Cast<DataRow>().Select(row => new DrivingCycleData.DrivingCycleEntry { Time = row.ParseDouble(Fields.Time).SI<Second>(), - PWheel = row.ParseDouble(Fields.PWheel).SI(Unit.SI.Kilo.Watt).Cast<Watt>(), + PWheel = row.ParseDouble(Fields.PWheel).SI(Unit.SI.Kilo.Watt).Cast<Watt>(), Gear = (uint)row.ParseDouble(Fields.Gear), AngularVelocity = row.ParseDouble(Fields.EngineSpeed).RPMtoRad(), - AdditionalAuxPowerDemand = row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI(Unit.SI.Kilo.Watt).Cast<Watt>(), + AdditionalAuxPowerDemand = row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI(Unit.SI.Kilo.Watt).Cast<Watt>(), }).ToArray(); return entries; @@ -585,7 +585,7 @@ namespace TUGraz.VectoCore.InputData.Reader Time = row.ParseDouble(Fields.Time).SI<Second>(), VehicleTargetSpeed = row.ParseDouble(Fields.VehicleSpeed).KMPHtoMeterPerSecond(), RoadGradient = VectoMath.InclinationToAngle(row.ParseDoubleOrGetDefault(Fields.RoadGradient) / 100.0), - AdditionalAuxPowerDemand = row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI(Unit.SI.Kilo.Watt).Cast<Watt>(), + AdditionalAuxPowerDemand = row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI(Unit.SI.Kilo.Watt).Cast<Watt>(), AirSpeedRelativeToVehicle = crossWindRequired ? row.ParseDouble(Fields.AirSpeedRelativeToVehicle).KMPHtoMeterPerSecond() : null, WindYawAngle = crossWindRequired ? row.ParseDouble(Fields.WindYawAngle) : 0, @@ -632,7 +632,7 @@ namespace TUGraz.VectoCore.InputData.Reader Time = row.ParseDouble(Fields.Time).SI<Second>(), VehicleTargetSpeed = row.ParseDouble(Fields.VehicleSpeed).KMPHtoMeterPerSecond(), RoadGradient = VectoMath.InclinationToAngle(row.ParseDoubleOrGetDefault(Fields.RoadGradient) / 100.0), - AdditionalAuxPowerDemand = row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI(Unit.SI.Kilo.Watt).Cast<Watt>(), + AdditionalAuxPowerDemand = row.ParseDoubleOrGetDefault(Fields.AdditionalAuxPowerDemand).SI(Unit.SI.Kilo.Watt).Cast<Watt>(), AngularVelocity = row.ParseDoubleOrGetDefault(Fields.EngineSpeed).RPMtoRad(), Gear = (uint)row.ParseDouble(Fields.Gear), TorqueConverterActive = table.Columns.Contains(Fields.TorqueConverterActive) @@ -712,17 +712,17 @@ namespace TUGraz.VectoCore.InputData.Reader } } - /// <summary> - /// Parser for PTO Cycles. - /// </summary> - // <t>,<v> [km/h],<Pwheel> [kW],<n_eng> [rpm],<n_fan> [rpm], <Padd> [kW] - private class VTPCycleDataParser : AbstractCycleDataParser - { - public override IEnumerable<DrivingCycleData.DrivingCycleEntry> Parse(DataTable table, bool crossWindRequired) - { - ValidateHeader(table.Columns); - - var entries = table.Rows.Cast<DataRow>().Select(row => { + /// <summary> + /// Parser for PTO Cycles. + /// </summary> + // <t>,<v> [km/h],<Pwheel> [kW],<n_eng> [rpm],<n_fan> [rpm], <Padd> [kW] + private class VTPCycleDataParser : AbstractCycleDataParser + { + public override IEnumerable<DrivingCycleData.DrivingCycleEntry> Parse(DataTable table, bool crossWindRequired) + { + ValidateHeader(table.Columns); + + var entries = table.Rows.Cast<DataRow>().Select(row => { var wheelSpeed = ((row.ParseDouble(Fields.WheelSpeedLeft) + row.ParseDouble(Fields.WheelSpeedRight)) / 2).RPMtoRad(); var wheelPower = row.ParseDouble(Fields.WheelTorqueLeft).SI<NewtonMeter>() * row.ParseDouble(Fields.WheelSpeedLeft).RPMtoRad() + @@ -742,23 +742,23 @@ namespace TUGraz.VectoCore.InputData.Reader }; }).ToArray(); - return entries; - } + return entries; + } - public static bool ValidateHeader(DataColumnCollection header, bool throwExceptions = true) - { - var requiredCols = new[] { - Fields.Time, - Fields.VehicleSpeed, - Fields.EngineSpeedSuffix, - Fields.FanSpeed, + public static bool ValidateHeader(DataColumnCollection header, bool throwExceptions = true) + { + var requiredCols = new[] { + Fields.Time, + Fields.VehicleSpeed, + Fields.EngineSpeedSuffix, + Fields.FanSpeed, Fields.WheelSpeedLeft, Fields.WheelSpeedRight, Fields.WheelTorqueLeft, Fields.WheelTorqueRight, - }; + }; - var allowedCols = new[] { + var allowedCols = new[] { Fields.Time, Fields.VehicleSpeed, Fields.EngineSpeedSuffix, @@ -771,14 +771,14 @@ namespace TUGraz.VectoCore.InputData.Reader Fields.FuelConsumption }; - const bool allowAux = true; + const bool allowAux = true; - return CheckColumns(header, allowedCols, requiredCols, throwExceptions, allowAux) && - CheckComboColumns(header, new[] { Fields.AirSpeedRelativeToVehicle, Fields.WindYawAngle }, throwExceptions); - } - } + return CheckColumns(header, allowedCols, requiredCols, throwExceptions, allowAux) && + CheckComboColumns(header, new[] { Fields.AirSpeedRelativeToVehicle, Fields.WindYawAngle }, throwExceptions); + } + } - } + } #endregion } \ No newline at end of file diff --git a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationVTPModeVectoRunDataFactory.cs b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationVTPModeVectoRunDataFactory.cs index 90f36b8e84..74bd09ad7e 100644 --- a/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationVTPModeVectoRunDataFactory.cs +++ b/VectoCore/VectoCore/InputData/Reader/Impl/DeclarationVTPModeVectoRunDataFactory.cs @@ -67,6 +67,9 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl _segment.VehicleClass), }; powertrainConfig.VehicleData.VehicleClass = _segment.VehicleClass; + Report.InputDataHash = JobInputData.VectoJobHash; + Report.ManufacturerRecord = JobInputData.ManufacturerReportInputData; + Report.ManufacturerRecordHash = JobInputData.VectoManufacturerReportHash; Report.InitializeReport(powertrainConfig); } @@ -115,8 +118,8 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl } // simulate the LongHaul cycle with RefLoad - foreach (var mission in _segment.Missions.Where(m => m.MissionType == MissionType.LongHaul)) { - foreach (var loading in mission.Loadings.Where(l => l.Key == LoadingType.ReferenceLoad)) { + foreach (var mission in _segment.Missions.Where(m => m.MissionType == DeclarationData.VTPMode.SelectedMission)) { + foreach (var loading in mission.Loadings.Where(l => l.Key == DeclarationData.VTPMode.SelectedLoading)) { var runData = CreateVectoRunData(_segment, mission, loading.Value); runData.ModFileSuffix = loading.Key.ToString(); var cycle = DrivingCycleDataReader.ReadFromStream(mission.CycleFile, CycleType.DistanceBased, "", false); @@ -127,6 +130,7 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl runData.ExecutionMode = ExecutionMode.Declaration; runData.SimulationType = SimulationType.DistanceCycle; runData.Mission = mission; + runData.Loading = loading.Key; yield return runData; } } @@ -147,6 +151,10 @@ namespace TUGraz.VectoCore.InputData.Reader.Impl runData.Mission = new Mission() { MissionType = MissionType.VerificationTest }; + runData.VTPData = new VTPData() { + CorrectionFactor = 1, + FuelNetCalorificValue = 0.SI<JoulePerKilogramm>() + }; yield return runData; } diff --git a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs index f4ec537cbe..111825b14a 100644 --- a/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs +++ b/VectoCore/VectoCore/Models/Declaration/DeclarationData.cs @@ -499,5 +499,11 @@ namespace TUGraz.VectoCore.Models.Declaration public const string DefaultPTOActivationCycle = DeclarationDataResourcePrefix + ".MissionCycles.MunicipalUtility_PTO_generic.vptoc"; } + + public static class VTPMode + { + public const MissionType SelectedMission = MissionType.LongHaul; + public const LoadingType SelectedLoading = LoadingType.ReferenceLoad; + } } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs b/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs index 1ab02409ad..21cfcb0a6f 100644 --- a/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs +++ b/VectoCore/VectoCore/Models/Simulation/Data/VectoRunData.cs @@ -104,10 +104,12 @@ namespace TUGraz.VectoCore.Models.Simulation.Data public int JobRunId { get; internal set; } - public AuxFanData FanData { get; internal set; } + public AuxFanData FanData { get; internal set; } public SimulationType SimulationType { get; set; } + public VTPData VTPData { get; set; } + public class AuxData { // ReSharper disable once InconsistentNaming @@ -205,7 +207,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Data } catch (VectoException) { return new ValidationResult( string.Format("Interpolation of Gear-{0}-LossMap failed with torque={1} and angularSpeed={2}", gear.Key, - inTorque, angularVelocity.ConvertToRoundsPerMinute())); + inTorque, angularVelocity.ConvertToRoundsPerMinute())); } var axlegearTorque = angledriveTorque; try { @@ -216,7 +218,7 @@ namespace TUGraz.VectoCore.Models.Simulation.Data } catch (VectoException) { return new ValidationResult( string.Format("Interpolation of Angledrive-LossMap failed with torque={0} and angularSpeed={1}", - angledriveTorque, (angularVelocity / gear.Value.Ratio).ConvertToRoundsPerMinute())); + angledriveTorque, (angularVelocity / gear.Value.Ratio).ConvertToRoundsPerMinute())); } if (axleGearData != null) { @@ -228,13 +230,20 @@ namespace TUGraz.VectoCore.Models.Simulation.Data new ValidationResult( string.Format( "Interpolation of AxleGear-LossMap failed with torque={0} and angularSpeed={1} (gear={2}, velocity={3})", - axlegearTorque, axleAngularVelocity.ConvertToRoundsPerMinute(), gear.Key, velocity)); + axlegearTorque, axleAngularVelocity.ConvertToRoundsPerMinute(), gear.Key, velocity)); } } return null; } } + public class VTPData + { + public double CorrectionFactor; + + public JoulePerKilogramm FuelNetCalorificValue; + } + public class AuxFanData { public double[] FanCoefficients; diff --git a/VectoCore/VectoCore/OutputData/DeclarationReport.cs b/VectoCore/VectoCore/OutputData/DeclarationReport.cs index b70bbb0ffb..5226da768a 100644 --- a/VectoCore/VectoCore/OutputData/DeclarationReport.cs +++ b/VectoCore/VectoCore/OutputData/DeclarationReport.cs @@ -71,7 +71,7 @@ namespace TUGraz.VectoCore.OutputData { public MissionType Mission; - public Dictionary<LoadingType, TEntry> ModData; + public Dictionary<LoadingType, TEntry> ResultEntry; } @@ -103,10 +103,10 @@ namespace TUGraz.VectoCore.OutputData if (!Missions.ContainsKey(mission.MissionType)) { Missions[mission.MissionType] = new ResultContainer<T>() { Mission = mission.MissionType, - ModData = new Dictionary<LoadingType, T>(), + ResultEntry = new Dictionary<LoadingType, T>(), }; } - Missions[mission.MissionType].ModData[loading] = new T(); + Missions[mission.MissionType].ResultEntry[loading] = new T(); _resultCount++; } @@ -118,12 +118,12 @@ namespace TUGraz.VectoCore.OutputData if (!Missions.ContainsKey(mission.MissionType)) { throw new VectoException("Unknown mission type {0} for generating declaration report", mission.MissionType); } - if (!Missions[mission.MissionType].ModData.ContainsKey(loadingType)) { + if (!Missions[mission.MissionType].ResultEntry.ContainsKey(loadingType)) { throw new VectoException("Unknown loading type {0} for mission {1}", loadingType, mission.MissionType); } _resultCount--; - DoAddResult(Missions[mission.MissionType].ModData[loadingType], runData, modData); + DoAddResult(Missions[mission.MissionType].ResultEntry[loadingType], runData, modData); if (_resultCount == 0) { DoWriteReport(); diff --git a/VectoCore/VectoCore/OutputData/VTPReport.cs b/VectoCore/VectoCore/OutputData/VTPReport.cs index ef9ba34eeb..ea16cc1ea4 100644 --- a/VectoCore/VectoCore/OutputData/VTPReport.cs +++ b/VectoCore/VectoCore/OutputData/VTPReport.cs @@ -29,6 +29,14 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoHashing; + namespace TUGraz.VectoCore.OutputData { - public interface IVTPReport : IDeclarationReport { } + public interface IVTPReport : IDeclarationReport { + IVectoHash InputDataHash { set; } + + IManufacturerReport ManufacturerRecord { set; } + IVectoHash ManufacturerRecordHash { set; } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/OutputData/XML/XMLCustomerReport.cs b/VectoCore/VectoCore/OutputData/XML/XMLCustomerReport.cs index 068610a218..84f923be97 100644 --- a/VectoCore/VectoCore/OutputData/XML/XMLCustomerReport.cs +++ b/VectoCore/VectoCore/OutputData/XML/XMLCustomerReport.cs @@ -111,7 +111,7 @@ namespace TUGraz.VectoCore.OutputData.XML public void AddResult( DeclarationReport<XMLDeclarationReport.ResultEntry>.ResultContainer<XMLDeclarationReport.ResultEntry> entry) { - foreach (var resultEntry in entry.ModData) { + foreach (var resultEntry in entry.ResultEntry) { allSuccess &= resultEntry.Value.Status == VectoRun.Status.Success; Results.Add(new XElement(tns + XMLNames.Report_Result_Result, new XAttribute(XMLNames.Report_Result_Status_Attr, diff --git a/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs b/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs index a5876323b2..6cddaf27a9 100644 --- a/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs +++ b/VectoCore/VectoCore/OutputData/XML/XMLDeclarationReport.cs @@ -90,7 +90,7 @@ namespace TUGraz.VectoCore.OutputData.XML public CubicMeter CargoVolume { get; private set; } - public void SetResultData(VectoRunData runData, IModalDataContainer data) + public virtual void SetResultData(VectoRunData runData, IModalDataContainer data) { FuelType = data.FuelData.FuelType; Payload = runData.VehicleData.Loading; diff --git a/VectoCore/VectoCore/OutputData/XML/XMLManufacturerReport.cs b/VectoCore/VectoCore/OutputData/XML/XMLManufacturerReport.cs index 5e4646beb3..7ee4656e47 100644 --- a/VectoCore/VectoCore/OutputData/XML/XMLManufacturerReport.cs +++ b/VectoCore/VectoCore/OutputData/XML/XMLManufacturerReport.cs @@ -271,7 +271,7 @@ namespace TUGraz.VectoCore.OutputData.XML public void AddResult( DeclarationReport<XMLDeclarationReport.ResultEntry>.ResultContainer<XMLDeclarationReport.ResultEntry> entry) { - foreach (var resultEntry in entry.ModData) { + foreach (var resultEntry in entry.ResultEntry) { _allSuccess &= resultEntry.Value.Status == VectoRun.Status.Success; Results.Add(new XElement(tns + XMLNames.Report_Result_Result, new XAttribute(XMLNames.Report_Result_Status_Attr, diff --git a/VectoCore/VectoCore/OutputData/XML/XMLVTPReport.cs b/VectoCore/VectoCore/OutputData/XML/XMLVTPReport.cs index daa46516a3..5d9b0e8461 100644 --- a/VectoCore/VectoCore/OutputData/XML/XMLVTPReport.cs +++ b/VectoCore/VectoCore/OutputData/XML/XMLVTPReport.cs @@ -1,22 +1,33 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Xml; using System.Xml.Linq; using TUGraz.IVT.VectoXML.Writer; +using TUGraz.VectoCommon.Hashing; +using TUGraz.VectoCommon.InputData; using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Resources; using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.InputData.Reader.Impl; using TUGraz.VectoCore.Models.Declaration; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.SimulationComponent.Data; using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; +using TUGraz.VectoCore.Utils; +using TUGraz.VectoHashing; -namespace TUGraz.VectoCore.OutputData.XML { - internal class XMLVTPReport : DeclarationReport<XMLDeclarationReport.ResultEntry>, IVTPReport +namespace TUGraz.VectoCore.OutputData.XML +{ + internal class XMLVTPReport : DeclarationReport<XMLVTPReport.ResultEntry>, IVTPReport { public const string CURRENT_SCHEMA_VERSION = "0.1"; protected XElement VehiclePart; + protected XElement GeneralPart; + protected XElement DataIntegrityPart; + protected XElement TestConditionsPart; protected XElement Results; @@ -27,11 +38,47 @@ namespace TUGraz.VectoCore.OutputData.XML { //protected XNamespace di; //private bool allSuccess = true; + public class ResultEntry : XMLDeclarationReport.ResultEntry + { + public Watt AverageFanPower; + public Kilogram VTPFcFinalSimulated; + public WattSecond VTPWorkPWheelPos; + public double VTPFcCorrectionFactor; + public JoulePerKilogramm VTPNCV; + public Kilogram VTPFcMeasured; + + #region Overrides of ResultEntry + + public override void SetResultData(VectoRunData runData, IModalDataContainer data) + { + base.SetResultData(runData, data); + + if (runData.SimulationType != SimulationType.VerificationTest) { + return; + } + + var aux = data.Auxiliaries.FirstOrDefault(x => x.Key == Constants.Auxiliaries.IDs.Fan); + AverageFanPower = data.AuxiliaryWork(aux.Value) / data.Duration(); + VTPWorkPWheelPos = runData.Cycle.Entries.Select(x => x.PWheel > 0 ? x.PWheel : 0.SI<Watt>()).Sum().Cast<Watt>() * + data.Duration(); + + VTPFcMeasured = runData.Cycle.Entries.Sum(x => x.Fuelconsumption) * data.Duration(); + VTPFcFinalSimulated = data.TimeIntegral<Kilogram>(ModalResultField.FCFinal); + VTPFcCorrectionFactor = runData.VTPData.CorrectionFactor; + VTPNCV = runData.VTPData.FuelNetCalorificValue; + } + + #endregion + } + public XMLVTPReport(IOutputDataWriter writer) { //di = "http://www.w3.org/2000/09/xmldsig#"; tns = "urn:tugraz:ivt:VectoAPI:VTPReport:v" + CURRENT_SCHEMA_VERSION; VehiclePart = new XElement(tns + XMLNames.Component_Vehicle); + GeneralPart = new XElement(tns + "General"); + DataIntegrityPart = new XElement(tns + "DataIntegrityCheck"); + TestConditionsPart = new XElement(tns + "TestConditions"); Results = new XElement(tns + "Results"); _writer = writer; @@ -40,37 +87,114 @@ namespace TUGraz.VectoCore.OutputData.XML { #region Overrides of DeclarationReport<ResultEntry> - protected override void DoAddResult(XMLDeclarationReport.ResultEntry entry, VectoRunData runData, IModalDataContainer modData) + protected override void DoAddResult( + ResultEntry entry, VectoRunData runData, IModalDataContainer modData) { entry.SetResultData(runData, modData); } protected internal override void DoWriteReport() { + GenerateResults(); + var report = GenerateReport(); if (_writer != null) { _writer.WriteReport(ReportType.DeclarationVTPReportXML, report); } } + private void GenerateResults() + { + var vtpResult = Missions.FirstOrDefault(x => x.Key == MissionType.VerificationTest).Value.ResultEntry + .FirstOrDefault().Value; + + const MissionType selectedMission = DeclarationData.VTPMode.SelectedMission; + const LoadingType selectedLoading = DeclarationData.VTPMode.SelectedLoading; + var result = Missions.FirstOrDefault(x => x.Key == selectedMission).Value.ResultEntry + .FirstOrDefault(x => x.Key == selectedLoading).Value; + var vtpFcMeasured = vtpResult.VTPFcMeasured / vtpResult.VTPWorkPWheelPos; + var vtpFcMeasuredCorr = vtpResult.VTPFcMeasured / vtpResult.VTPWorkPWheelPos * vtpResult.VTPFcCorrectionFactor; + var vtpFcSimulated = vtpResult.VTPFcFinalSimulated / vtpResult.VTPWorkPWheelPos; + var cVtp = vtpFcMeasuredCorr / vtpFcSimulated; + var declaredCO2 = result.FuelConsumptionTotal / result.Distance / result.Payload; + var verifiedCO2 = declaredCO2 * cVtp; + + Results.Add( + new XElement(tns + "Status", cVtp < 1.075 ? "Passed" : "Failed"), + new XElement( + tns + "AverageFanPower", + new XAttribute(XMLNames.Report_Results_Unit_Attr, "kW"), + vtpResult.AverageFanPower.ConvertToKiloWatt().ToXMLFormat(3)), + new XElement( + tns + "WorkPosVT", new XAttribute(XMLNames.Report_Results_Unit_Attr, "kWh"), + vtpResult.VTPWorkPWheelPos.ConvertToKiloWattHour().ToXMLFormat(3)), + new XElement( + tns + "TestFuelNCV", new XAttribute(XMLNames.Report_Results_Unit_Attr, "MJ/kg"), + (vtpResult.VTPNCV / 1e6).ToXMLFormat(3)), + new XElement( + tns + "FuelConsumption", + new XElement( + tns + "Measured", + new XAttribute(XMLNames.Report_Results_Unit_Attr, "g/kWh"), + vtpFcMeasured.ConvertToGramPerKiloWattHour().ToXMLFormat(3) + ), + new XElement( + tns + "MeasuredCorrected", + new XAttribute(XMLNames.Report_Results_Unit_Attr, "g/kWh"), + vtpFcMeasuredCorr.ConvertToGramPerKiloWattHour().ToXMLFormat(3) + ), + new XElement( + tns + "Simulated", + new XAttribute(XMLNames.Report_Results_Unit_Attr, "g/kWh"), + vtpFcSimulated.ConvertToGramPerKiloWattHour().ToXMLFormat(3) + ) + ), + new XElement( + tns + "CO2", + new XElement( + tns + "Mission", + string.Format("{0}, {1}", selectedMission.ToXMLFormat(), selectedLoading.ToString()) + ), + new XElement( + tns + "Declared", new XAttribute(XMLNames.Report_Results_Unit_Attr, "g/t-km"), + declaredCO2.ConvertToGrammPerTonKilometer().ToMinSignificantDigits(3, 1) + ), + new XElement( + tns + "Verified", new XAttribute(XMLNames.Report_Results_Unit_Attr, "g/t-km"), + verifiedCO2.ConvertToGrammPerTonKilometer().ToMinSignificantDigits(3, 1) + ) + ), + new XElement(tns + "VTRatio", cVtp.ToXMLFormat(4))); + } + private XDocument GenerateReport() { var xsi = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance"); var retVal = new XDocument(); - retVal.Add(new XProcessingInstruction("xml-stylesheet", "href=\"https://webgate.ec.europa.eu/CITnet/svn/VECTO/trunk/Share/XML/CSS/VectoReports.css\"")); - retVal.Add(new XElement(tns + XMLNames.VectoManufacturerReport, - new XAttribute("schemaVersion", CURRENT_SCHEMA_VERSION), - new XAttribute(XNamespace.Xmlns + "xsi", xsi.NamespaceName), - new XAttribute("xmlns", tns), - //new XAttribute(XNamespace.Xmlns + "di", di), - new XAttribute(xsi + "schemaLocation", - string.Format("{0} {1}VTPReport.{2}.xsd", tns, AbstractXMLWriter.SchemaLocationBaseUrl, CURRENT_SCHEMA_VERSION)), - new XElement(tns + "Data", - new XElement(VehiclePart) - //results, - //GetApplicationInfo() - ) - ) + retVal.Add( + new XProcessingInstruction( + "xml-stylesheet", "href=\"https://webgate.ec.europa.eu/CITnet/svn/VECTO/trunk/Share/XML/CSS/VectoReports.css\"")); + retVal.Add( + new XElement( + tns + "VectoVTPReport", + new XAttribute("schemaVersion", CURRENT_SCHEMA_VERSION), + new XAttribute(XNamespace.Xmlns + "xsi", xsi.NamespaceName), + new XAttribute("xmlns", tns), + + //new XAttribute(XNamespace.Xmlns + "di", di), + new XAttribute( + xsi + "schemaLocation", + string.Format("{0} {1}VTPReport.{2}.xsd", tns, AbstractXMLWriter.SchemaLocationBaseUrl, CURRENT_SCHEMA_VERSION)), + new XElement( + tns + "Data", + new XElement(GeneralPart), + new XElement(VehiclePart), + new XElement(DataIntegrityPart), + new XElement(TestConditionsPart), + new XElement(Results), + GetApplicationInfo() + ) + ) ); return retVal; @@ -78,53 +202,184 @@ namespace TUGraz.VectoCore.OutputData.XML { public override void InitializeReport(VectoRunData modelData) { + GeneralPart.Add( + new XElement(tns + XMLNames.Component_Manufacturer, modelData.VehicleData.Manufacturer), + new XElement(tns + XMLNames.Component_ManufacturerAddress, modelData.VehicleData.ManufacturerAddress)); VehiclePart.Add( + new XElement(tns + XMLNames.Component_Model, modelData.VehicleData.ModelName), new XElement(tns + XMLNames.Vehicle_VIN, modelData.VehicleData.VIN), new XElement(tns + XMLNames.Vehicle_LegislativeClass, modelData.VehicleData.LegislativeClass.ToXMLFormat()), new XElement(tns + XMLNames.Report_Vehicle_VehicleGroup, modelData.VehicleData.VehicleClass.GetClassNumber()), new XElement(tns + XMLNames.Vehicle_AxleConfiguration, modelData.VehicleData.AxleConfiguration.GetName()), new XElement(tns + XMLNames.Vehicle_GrossVehicleMass, modelData.VehicleData.GrossVehicleWeight.ToXMLFormat(0)), new XElement(tns + XMLNames.Vehicle_CurbMassChassis, modelData.VehicleData.CurbWeight.ToXMLFormat(0)), + modelData.Retarder.Type.IsDedicatedComponent() + ? new XElement(tns + XMLNames.Vehicle_RetarderRatio, modelData.Retarder.Ratio.ToXMLFormat(3)) + : null, new XElement(tns + XMLNames.Vehicle_PTO, modelData.PTO != null), - - new XElement(tns + XMLNames.Vehicle_Components, - GetEngineDescription(modelData.EngineData), - GetGearboxDescription(modelData.GearboxData), - GetTorqueConverterDescription(modelData.GearboxData.TorqueConverterData), - GetRetarderDescription(modelData.Retarder), - GetAngledriveDescription(modelData.AngledriveData), - GetAxlegearDescription(modelData.AxleGearData), - GetAirDragDescription(modelData.AirdragData), - GetAxleWheelsDescription(modelData.VehicleData), - GetAuxiliariesDescription(modelData.Aux) + new XElement( + tns + XMLNames.Vehicle_Components, + GetEngineDescription(modelData.EngineData), + GetGearboxDescription(modelData.GearboxData), + GetTorqueConverterDescription(modelData.GearboxData.TorqueConverterData), + GetRetarderDescription(modelData.Retarder), + GetAngledriveDescription(modelData.AngledriveData), + GetAxlegearDescription(modelData.AxleGearData), + GetAirDragDescription(modelData.AirdragData), + GetAxleWheelsDescription(modelData.VehicleData), + GetAuxiliariesDescription(modelData.Aux) + ) + ); + + var componentChecks = new List<object>(); + + if (InputDataHash == null) { + return; + } + + var allSuccess = true; + var components = InputDataHash.GetContainigComponents().GroupBy(s => s) + .Select(g => new { Entry = g.Key, Count = g.Count() }); + foreach (var component in components) { + if (component.Entry == VectoComponents.Vehicle) { + continue; + } + + for (var i = 0; i < component.Count; i++) { + var recomputed = ""; + var read = ""; + var readJob = ""; + var error = ""; + bool status; + try { + recomputed = InputDataHash.ComputeHash(component.Entry, i); + readJob = InputDataHash.ReadHash(component.Entry, i); + read = ManufacturerRecord.ComponentDigests[component.Entry][i]; + status = string.Equals(readJob, recomputed) && string.Equals(recomputed, read); + } catch (Exception e) { + status = false; + error = e.Message; + } + + allSuccess = allSuccess && status; + componentChecks.Add( + new XElement( + tns + "Component", + new XAttribute( + "componentName", component.Count == 1 + ? component.Entry.XMLElementName() + : string.Format("{0} ({1})", component.Entry.XMLElementName(), i + 1)), + new XAttribute("status", status ? "success" : "failed"), + new XElement(tns + "DigestValueRecomputed", recomputed), + new XElement( + tns + "DigestValueRead", + new XAttribute("source", "JobData"), + readJob + ), + new XElement( + tns + "DigestValueRead", + new XAttribute("source", "ManufacturerRecord"), + read + ), + status ? null : new XElement(tns + "Error", error) + )); + } + } + + string jobHashRecomputed = null; + string jobHashRead = null; + bool jobStatus; + string jobError = null; + try { + var jobHashMethods = ManufacturerRecord.JobDigest; + jobHashRecomputed = InputDataHash.ComputeHash(jobHashMethods.CanonicalizationMethods, jobHashMethods.DigestMethod); + jobHashRead = jobHashMethods.DigestValue; + jobStatus = string.Equals(jobHashRecomputed, jobHashRead); + } catch (Exception e) { + jobStatus = false; + jobError = e.Message; + } + + allSuccess = allSuccess && jobStatus; + string mrHashRead = null; + string mrHashRecomputed = null; + bool mrStatus; + string mrError = null; + try { + mrHashRead = ManufacturerRecordHash.ReadHash(); + mrHashRecomputed = ManufacturerRecordHash.ComputeHash(); + mrStatus = ManufacturerRecordHash.ValidateHash(); + } catch (Exception e) { + mrStatus = false; + mrError = e.Message; + } + allSuccess = allSuccess && mrStatus; + DataIntegrityPart.Add( + new XAttribute("status", allSuccess ? "success" : "failed"), + new XElement( + tns + "Components", + componentChecks.ToArray() + ), + new XElement( + tns + "ManufacturerReport", + new XAttribute("status", mrStatus ? "success" : "failed"), + new XElement(tns + "DigestValueRecomputed", mrHashRecomputed), + new XElement( + tns + "DigestValueRead", + new XAttribute("source", "ManufacturerRecord"), mrHashRead), + mrStatus ? null : new XElement(tns + "Error", mrError) + ), + new XElement( + tns + "JobData", + new XAttribute("status", jobStatus ? "success" : "failed"), + new XElement( + tns + "DigestValueRecomputed", + jobHashRecomputed), + new XElement( + tns + "DigestValueRead", + new XAttribute("source", "ManufacturerRecord"), + jobHashRead), + jobStatus ? null : new XElement(tns + "Error", jobError) ) ); } #endregion + private XElement GetApplicationInfo() + { + return new XElement( + tns + XMLNames.Report_ApplicationInfo_ApplicationInformation, + new XElement(tns + XMLNames.Report_ApplicationInfo_SimulationToolVersion, VectoSimulationCore.VersionNumber), + new XElement( + tns + XMLNames.Report_ApplicationInfo_Date, + XmlConvert.ToString(DateTime.Now, XmlDateTimeSerializationMode.Utc))); + } + private XElement GetEngineDescription(CombustionEngineData engineData) { - return new XElement(tns + XMLNames.Component_Engine, + return new XElement( + tns + XMLNames.Component_Engine, GetCommonDescription(engineData), new XElement(tns + XMLNames.Engine_RatedPower, engineData.RatedPowerDeclared.ToXMLFormat(0)), - new XElement(tns + XMLNames.Engine_IdlingSpeed, engineData.IdleSpeed.AsRPM.ToXMLFormat(0)), - new XElement(tns + XMLNames.Engine_RatedSpeed, engineData.RatedSpeedDeclared.AsRPM.ToXMLFormat(0)), - new XElement(tns + XMLNames.Engine_Displacement, + new XElement( + tns + XMLNames.Engine_Displacement, engineData.Displacement.ConvertToCubicCentiMeter().ToXMLFormat(0)), new XElement(tns + XMLNames.Engine_FuelType, engineData.FuelType.ToXMLFormat()) - ); + ); } private XElement GetGearboxDescription(GearboxData gearboxData) { - return new XElement(tns + XMLNames.Component_Gearbox, + return new XElement( + tns + XMLNames.Component_Gearbox, GetCommonDescription(gearboxData), new XElement(tns + XMLNames.Gearbox_TransmissionType, gearboxData.Type.ToXMLFormat()), new XElement(tns + XMLNames.Report_GetGearbox_GearsCount, gearboxData.Gears.Count), - new XElement(tns + XMLNames.Report_Gearbox_TransmissionRatioFinalGear, + new XElement( + tns + XMLNames.Report_Gearbox_TransmissionRatioFinalGear, gearboxData.Gears.Last().Value.Ratio.ToXMLFormat(3)) - ); + ); } private XElement GetTorqueConverterDescription(TorqueConverterData torqueConverterData) @@ -132,13 +387,16 @@ namespace TUGraz.VectoCore.OutputData.XML { if (torqueConverterData == null) { return null; } - return new XElement(tns + XMLNames.Component_TorqueConverter, + + return new XElement( + tns + XMLNames.Component_TorqueConverter, GetCommonDescription(torqueConverterData)); } private XElement GetRetarderDescription(RetarderData retarder) { - return new XElement(tns + XMLNames.Component_Retarder, + return new XElement( + tns + XMLNames.Component_Retarder, new XElement(tns + XMLNames.Vehicle_RetarderType, retarder.Type.ToXMLFormat()), retarder.Type.IsDedicatedComponent() ? GetCommonDescription(retarder) : null); } @@ -148,14 +406,17 @@ namespace TUGraz.VectoCore.OutputData.XML { if (angledriveData == null) { return null; } - return new XElement(tns + XMLNames.Component_Angledrive, + + return new XElement( + tns + XMLNames.Component_Angledrive, GetCommonDescription(angledriveData), new XElement(tns + XMLNames.AngleDrive_Ratio, angledriveData.Angledrive.Ratio)); } private XElement GetAxlegearDescription(AxleGearData axleGearData) { - return new XElement(tns + XMLNames.Component_Axlegear, + return new XElement( + tns + XMLNames.Component_Axlegear, GetCommonDescription(axleGearData), new XElement(tns + XMLNames.Axlegear_LineType, axleGearData.LineType.ToXMLFormat()), new XElement(tns + XMLNames.Axlegear_Ratio, axleGearData.AxleGear.Ratio.ToXMLFormat(3))); @@ -164,18 +425,20 @@ namespace TUGraz.VectoCore.OutputData.XML { private XElement GetAirDragDescription(AirdragData airdragData) { if (airdragData.CertificationMethod == CertificationMethod.StandardValues) { - return new XElement(tns + XMLNames.Component_AirDrag, + return new XElement( + tns + XMLNames.Component_AirDrag, new XElement(tns + XMLNames.Report_Component_CertificationMethod, airdragData.CertificationMethod.ToXMLFormat()), new XElement(tns + XMLNames.Report_AirDrag_CdxA, airdragData.DeclaredAirdragArea.ToXMLFormat(2)) - ); + ); } - return new XElement(tns + XMLNames.Component_AirDrag, + + return new XElement( + tns + XMLNames.Component_AirDrag, new XElement(tns + XMLNames.Component_Model, airdragData.ModelName), new XElement(tns + XMLNames.Report_Component_CertificationMethod, airdragData.CertificationMethod.ToXMLFormat()), new XElement(tns + XMLNames.Report_Component_CertificationNumber, airdragData.CertificationNumber), - new XElement(tns + XMLNames.DI_Signature_Reference_DigestValue, airdragData.DigestValueInput), new XElement(tns + XMLNames.Report_AirDrag_CdxA, airdragData.DeclaredAirdragArea.ToXMLFormat(2)) - ); + ); } private XElement GetAxleWheelsDescription(VehicleData vehicleData) @@ -186,6 +449,7 @@ namespace TUGraz.VectoCore.OutputData.XML { if (axleData[i].AxleType == AxleType.Trailer) { continue; } + retVal.Add(GetAxleDescription(i + 1, axleData[i])); } @@ -194,11 +458,11 @@ namespace TUGraz.VectoCore.OutputData.XML { private XElement GetAxleDescription(int i, Axle axle) { - return new XElement(tns + XMLNames.AxleWheels_Axles_Axle, + return new XElement( + tns + XMLNames.AxleWheels_Axles_Axle, new XAttribute(XMLNames.AxleWheels_Axles_Axle_AxleNumber_Attr, i), new XElement(tns + XMLNames.Report_Tyre_TyreDimension, axle.WheelsDimension), - new XElement(tns + XMLNames.Report_Tyre_TyreCertificationNumber, axle.CertificationNumber), - new XElement(tns + XMLNames.DI_Signature_Reference_DigestValue, axle.DigestValueInput), + new XElement(tns + XMLNames.Component_CertificationNumber, axle.CertificationNumber), new XElement(tns + XMLNames.Report_Tyre_TyreRRCDeclared, axle.RollResistanceCoefficient.ToXMLFormat(4)), new XElement(tns + XMLNames.AxleWheels_Axles_Axle_TwinTyres, axle.TwinTyres)); } @@ -216,6 +480,7 @@ namespace TUGraz.VectoCore.OutputData.XML { retVal.Add(new XElement(tns + GetTagName(auxId), entry)); } } + return retVal; } @@ -229,7 +494,6 @@ namespace TUGraz.VectoCore.OutputData.XML { return new object[] { new XElement(tns + XMLNames.Component_Model, data.ModelName), new XElement(tns + XMLNames.Report_Component_CertificationNumber, data.CertificationNumber), - new XElement(tns + XMLNames.DI_Signature_Reference_DigestValue, data.DigestValueInput) }; } @@ -241,8 +505,17 @@ namespace TUGraz.VectoCore.OutputData.XML { data.CertificationMethod == CertificationMethod.StandardValues ? null : new XElement(tns + XMLNames.Report_Component_CertificationNumber, data.CertificationNumber), - new XElement(tns + XMLNames.DI_Signature_Reference_DigestValue, data.DigestValueInput) }; } + + #region Implementation of IVTPReport + + public IVectoHash InputDataHash { protected get; set; } + + public IManufacturerReport ManufacturerRecord { protected get; set; } + + public IVectoHash ManufacturerRecordHash { protected get; set; } + + #endregion } -} \ No newline at end of file +} diff --git a/VectoCore/VectoCore/Resources/XSD/VectoVTPReport.xsd b/VectoCore/VectoCore/Resources/XSD/VectoVTPReport.xsd index e19994b671..57728b89c5 100644 --- a/VectoCore/VectoCore/Resources/XSD/VectoVTPReport.xsd +++ b/VectoCore/VectoCore/Resources/XSD/VectoVTPReport.xsd @@ -180,6 +180,13 @@ </xs:complexType> <xs:complexType name="CO2ResultType"> <xs:sequence> + <xs:element name="Mission"> + <xs:simpleType> + <xs:restriction base="xs:string"> + <xs:minLength value="1"/> + </xs:restriction> + </xs:simpleType> + </xs:element> <xs:element name="Declared"> <xs:complexType> <xs:simpleContent> @@ -205,7 +212,7 @@ <xs:element name="Components"> <xs:complexType> <xs:sequence> - <xs:element name="Component" maxOccurs="unbounded"> + <xs:element name="Component" minOccurs="0" maxOccurs="unbounded"> <xs:complexType> <xs:complexContent> <xs:extension base="DataIntegrityResultType"> @@ -224,8 +231,17 @@ </xs:complexType> <xs:complexType name="DataIntegrityResultType"> <xs:sequence> - <xs:element name="DigestValueRead"/> - <xs:element name="DigestValueRecomputed"/> + <xs:element name="DigestValueRecomputed" type="xs:token"/> + <xs:element name="DigestValueRead" maxOccurs="unbounded"> + <xs:complexType> + <xs:simpleContent> + <xs:extension base="xs:token"> + <xs:attribute name="source" type="xs:token" use="required"/> + </xs:extension> + </xs:simpleContent> + </xs:complexType> + </xs:element> + <xs:element name="Error" type="xs:string" minOccurs="0"/> </xs:sequence> <xs:attribute name="status" type="DataIntegrityStatusType" use="required"/> </xs:complexType> @@ -462,7 +478,7 @@ <xs:element name="Gearbox" type="GearboxType"/> <xs:element name="TorqueConverter" type="TorqueConverterType" minOccurs="0"/> <xs:element name="Retarder" type="RetarderType"/> - <xs:element name="AngleDrive" type="AngleDriveType"/> + <xs:element name="AngleDrive" type="AngleDriveType" minOccurs="0"/> <xs:element name="Axlegear" type="AxlegearType"/> <xs:element name="AirDrag" type="AirDragType"/> <xs:element name="AxleWheels" type="AxleWheelsType"/> diff --git a/VectoCore/VectoCore/VectoCore.csproj b/VectoCore/VectoCore/VectoCore.csproj index 65e64974d1..d9d686776b 100644 --- a/VectoCore/VectoCore/VectoCore.csproj +++ b/VectoCore/VectoCore/VectoCore.csproj @@ -124,6 +124,7 @@ <Compile Include="InputData\FileIO\XML\Declaration\XMLDeclarationTorqueConverterDataProvider.cs" /> <Compile Include="InputData\FileIO\XML\Declaration\XMLDeclarationVehicleDataProvider.cs" /> <Compile Include="InputData\FileIO\XML\Declaration\XMLDeclarationInputDataProvider.cs" /> + <Compile Include="InputData\FileIO\XML\Declaration\XMLManufacturerReportReader.cs" /> <Compile Include="InputData\FileIO\XML\Engineering\AbstractEngineeringXMLComponentDataProvider.cs" /> <Compile Include="InputData\FileIO\XML\Engineering\XMLEngineeringAirdragDataProvider.cs" /> <Compile Include="InputData\FileIO\XML\Engineering\XMLEngineeringAngledriveDataProvider.cs" /> diff --git a/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs b/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs index e529782f2d..a6d639b66c 100644 --- a/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs +++ b/VectoCore/VectoCoreTest/Models/SimulationComponentData/ValidationTest.cs @@ -633,7 +633,7 @@ namespace TUGraz.VectoCore.Tests.Models.SimulationComponentData } public string CertificationNumber { get; set; } - public string DigestValue { get; set; } + public DigestData DigestValue { get; set; } public GearboxType Type { get; set; } public IList<ITransmissionInputData> Gears { get; set; } diff --git a/VectoCore/VectoCoreTest/TestData/Integration/VTPMode/GenericVehicle/Tractor_4x2_vehicle-class-5_Generic vehicle.xml b/VectoCore/VectoCoreTest/TestData/Integration/VTPMode/GenericVehicle/Tractor_4x2_vehicle-class-5_Generic vehicle.xml index 3356681805..dfa7c42f70 100644 --- a/VectoCore/VectoCoreTest/TestData/Integration/VTPMode/GenericVehicle/Tractor_4x2_vehicle-class-5_Generic vehicle.xml +++ b/VectoCore/VectoCoreTest/TestData/Integration/VTPMode/GenericVehicle/Tractor_4x2_vehicle-class-5_Generic vehicle.xml @@ -1,5 +1,9 @@ <?xml version="1.0" encoding="utf-8"?> -<tns:VectoInputDeclaration schemaVersion="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:tugraz:ivt:VectoAPI:DeclarationDefinitions:v1.0" xmlns:tns="urn:tugraz:ivt:VectoAPI:DeclarationInput:v1.0" xsi:schemaLocation="urn:tugraz:ivt:VectoAPI:DeclarationInput:v1.0 https://webgate.ec.europa.eu/CITnet/svn/VECTO/trunk/Share/XML/XSD/VectoInput.xsd"> +<tns:VectoInputDeclaration schemaVersion="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="urn:tugraz:ivt:VectoAPI:DeclarationDefinitions:v1.0" + xmlns:tns="urn:tugraz:ivt:VectoAPI:DeclarationInput:v1.0" + xmlns:di="http://www.w3.org/2000/09/xmldsig#" + xsi:schemaLocation="urn:tugraz:ivt:VectoAPI:DeclarationInput:v1.0 https://webgate.ec.europa.eu/CITnet/svn/VECTO/trunk/Share/XML/XSD/VectoInput.xsd"> <Vehicle id="VEH-Tabelle1_Class-5_Genericvehicle"> <Manufacturer>Generic Vendor</Manufacturer> <ManufacturerAddress>N.A.</ManufacturerAddress> @@ -176,12 +180,12 @@ </Data> <Signature> <Reference URI="#ENG-GenericEngine" xmlns="http://www.w3.org/2000/09/xmldsig#"> - <Transforms> - <Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithoutComments" /> - <Transform Algorithm="urn:vecto:xml:2017:canonicalization" /> - </Transforms> - <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /> - <DigestValue></DigestValue> + <di:Transforms> + <di:Transform Algorithm="urn:vecto:xml:2017:canonicalization" /> + <di:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /> + </di:Transforms> + <di:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /> + <di:DigestValue>UxwXPq/SM3L4WIYOBWlMy1KbUowxU670gdh+B1MXDpo=</di:DigestValue> </Reference> </Signature> </Engine> @@ -379,12 +383,12 @@ </Data> <Signature> <Reference URI="#GBX-GB_12-gear" xmlns="http://www.w3.org/2000/09/xmldsig#"> - <Transforms> - <Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithoutComments" /> - <Transform Algorithm="urn:vecto:xml:2017:canonicalization" /> - </Transforms> - <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /> - <DigestValue></DigestValue> + <di:Transforms> + <di:Transform Algorithm="urn:vecto:xml:2017:canonicalization" /> + <di:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /> + </di:Transforms> + <di:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /> + <di:DigestValue>JN8KciKSKfvIE54oFkwnuOX1pcxsR//cklWLP8gtNvY=</di:DigestValue> </Reference> </Signature> </Gearbox> @@ -432,12 +436,12 @@ </Data> <Signature> <Reference URI="#RET-RET-generic" xmlns="http://www.w3.org/2000/09/xmldsig#"> - <Transforms> - <Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithoutComments" /> - <Transform Algorithm="urn:vecto:xml:2017:canonicalization" /> - </Transforms> - <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /> - <DigestValue></DigestValue> + <di:Transforms> + <di:Transform Algorithm="urn:vecto:xml:2017:canonicalization" /> + <di:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /> + </di:Transforms> + <di:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /> + <di:DigestValue>acR2Tz1XQ825YZRvDenOm9zarI6Dcw5QLgwPtDRVW1c=</di:DigestValue> </Reference> </Signature> </Retarder> @@ -466,12 +470,12 @@ </Data> <Signature> <Reference URI="#AXLGEAR-2640" xmlns="http://www.w3.org/2000/09/xmldsig#"> - <Transforms> - <Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithoutComments" /> - <Transform Algorithm="urn:vecto:xml:2017:canonicalization" /> - </Transforms> - <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /> - <DigestValue></DigestValue> + <di:Transforms> + <di:Transform Algorithm="urn:vecto:xml:2017:canonicalization" /> + <di:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /> + </di:Transforms> + <di:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /> + <di:DigestValue>cKOhQhbRAelCtdfBGL8VjF5HcvQkVrw9sr0OkWeEYb0=</di:DigestValue> </Reference> </Signature> </Axlegear> @@ -494,14 +498,14 @@ <FzISO>33350</FzISO> </Data> <Signature> - <Reference URI="#TYRE-315_70R225" xmlns="http://www.w3.org/2000/09/xmldsig#"> - <Transforms> - <Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithoutComments" /> - <Transform Algorithm="urn:vecto:xml:2017:canonicalization" /> - </Transforms> - <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /> - <DigestValue></DigestValue> - </Reference> + <di:Reference URI="#TYRE-315_70R225"> + <di:Transforms> + <di:Transform Algorithm="urn:vecto:xml:2017:canonicalization" /> + <di:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /> + </di:Transforms> + <di:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /> + <di:DigestValue>hr4Dcmy/uO+zoYr0KcPvcAOS93XYlCIKMyy1XeMO0AM=</di:DigestValue> + </di:Reference> </Signature> </Tyre> </Axle> @@ -521,14 +525,14 @@ <FzISO>33350</FzISO> </Data> <Signature> - <Reference URI="#TYRE-315_70R225" xmlns="http://www.w3.org/2000/09/xmldsig#"> - <Transforms> - <Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithoutComments" /> - <Transform Algorithm="urn:vecto:xml:2017:canonicalization" /> - </Transforms> - <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /> - <DigestValue></DigestValue> - </Reference> + <di:Reference URI="#TYRE-315_70R225"> + <di:Transforms> + <di:Transform Algorithm="urn:vecto:xml:2017:canonicalization" /> + <di:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /> + </di:Transforms> + <di:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /> + <di:DigestValue>AsCRWiSEqb1HYnmM1SPXdz6KVzEZjXfvDkFppwyImY0=</di:DigestValue> + </di:Reference> </Signature> </Tyre> </Axle> @@ -567,12 +571,12 @@ </Data> <Signature> <Reference URI="#Airdrag-genericcabin" xmlns="http://www.w3.org/2000/09/xmldsig#"> - <Transforms> - <Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithoutComments" /> - <Transform Algorithm="urn:vecto:xml:2017:canonicalization" /> - </Transforms> - <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /> - <DigestValue></DigestValue> + <di:Transforms> + <di:Transform Algorithm="urn:vecto:xml:2017:canonicalization" /> + <di:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /> + </di:Transforms> + <di:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /> + <di:DigestValue>xbCnjthzGoDH8oiydVX5eQmUoaeZ4aXpKwHtvd3ZkNQ=</di:DigestValue> </Reference> </Signature> </AirDrag> diff --git a/VectoCore/VectoCoreTest/TestData/Integration/VTPMode/GenericVehicle/class_5_generic vehicle_DECL.vecto b/VectoCore/VectoCoreTest/TestData/Integration/VTPMode/GenericVehicle/class_5_generic vehicle_DECL.vecto index 4d6d7b6a60..fdc0895c42 100644 --- a/VectoCore/VectoCoreTest/TestData/Integration/VTPMode/GenericVehicle/class_5_generic vehicle_DECL.vecto +++ b/VectoCore/VectoCoreTest/TestData/Integration/VTPMode/GenericVehicle/class_5_generic vehicle_DECL.vecto @@ -8,6 +8,7 @@ "Body": { "SavedInDeclMode": true, "DeclarationVehicle": "Tractor_4x2_vehicle-class-5_Generic vehicle.xml", + "ManufacturerRecord": "Tractor_4x2_vehicle-class-5_Generic vehicle.RSLT_MANUFACTURER.xml", "FanPowerCoefficients": [ 5.5E-07, 15.0, diff --git a/VectoCore/VectoCoreTest/Utils/MockEngineDataProvider.cs b/VectoCore/VectoCoreTest/Utils/MockEngineDataProvider.cs index f857cd088e..7d6b8fe901 100644 --- a/VectoCore/VectoCoreTest/Utils/MockEngineDataProvider.cs +++ b/VectoCore/VectoCoreTest/Utils/MockEngineDataProvider.cs @@ -48,7 +48,7 @@ namespace TUGraz.VectoCore.Tests.Utils public string TechnicalReportId { get; set; } public CertificationMethod CertificationMethod { get{return CertificationMethod.NotCertified;} } public string CertificationNumber { get; set; } - public string DigestValue { get; set; } + public DigestData DigestValue { get; set; } public CubicMeter Displacement { get; set; } public PerSecond IdleSpeed { get; set; } public double WHTCMotorway { get; set; } -- GitLab