diff --git a/Autosar-Configurator.csproj b/Autosar-Configurator.csproj index fa6a0cd..a0a4a19 100644 --- a/Autosar-Configurator.csproj +++ b/Autosar-Configurator.csproj @@ -29,13 +29,20 @@ + + + + - - lib\EcucBaseCore.dll + + lib\Autosar.dll + + + lib\XObjectsCore.dll diff --git a/EcucBase/EcucBase.cs b/EcucBase/EcucBase.cs new file mode 100644 index 0000000..0ae99d4 --- /dev/null +++ b/EcucBase/EcucBase.cs @@ -0,0 +1,643 @@ +/* + * This file is a part of Autosar Configurator for ECU GUI based + * configuration, checking and code generation. + * + * Copyright (C) 2021-2022 DJS Studio E-mail:DD-Silence@sina.cn + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +using Autosar; +using Ecuc.EcucBase.EData; +using Ecuc.EcucBase.EInstance; +using System.ComponentModel; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Ecuc.EcucBase.EBase +{ + /// + /// INotifyPropertyChanged abstaract to avoid type property name + /// + public class NotifyPropertyChangedBase : INotifyPropertyChanged + { + public event PropertyChangedEventHandler? PropertyChanged; + + public void RaisePropertyChanged([CallerMemberName] string propertyName = "") + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + } + + /// + /// Asr Class represent a single arxml file + /// + public class Asr + { + /// + /// File name of arxml file. + /// + private string FileName { get; } = ""; + /// + /// Whether arxml model is modified or not. + /// + private bool isDirty = false; + /// + /// Converted data model of arxml file. + /// + public AUTOSAR? Model { get; } = null; + /// + /// Packages of Autosar in arxml file. + /// + public List ArPackages { get; } = new List(); + /// + /// ECUC modules in arxml file. + /// + public List Modules { get; } = new List(); + /// + /// Dictionary between Autosar path and converted model. + /// + public Dictionary AsrPathModelDict { get; } = new Dictionary(); + + /// + /// Whether arxml model is modified or not. + /// + public bool IsDirty + { + get + { + return isDirty; + } + set + { + if (value != IsDirty) + { + isDirty = value; + // dirty from true to false shall tranfer to all modules + if (value == false) + { + foreach (var module in Modules) + { + module.IsDirty = false; + } + } + } + } + } + + /// + /// Initialze Asr from filename. + /// File will be converted to data model. All Autosar packages will be extracted. + /// Autosar path dictionary will be generated. + /// + /// Filename of file want to be converted. + public Asr(string filename) + { + FileName = filename; + Model = AUTOSAR.Load(filename); + + if (Model != null) + { + // get all autosar packages + FindAllArPackage(); + // iterate all elements to generate Autosar path dictionary + CreateAsrPath(); + } + } + + /// + /// Iterate all ARPACKAGE and ARPACKAGES tag to get all Autosar package from Model. + /// ARPACKAGES tag can have ARPACKAGE member and ARPACKAGE tag can have ARPACKAGES member. + /// All ARPACKAGES and ARPACKAGE tag shall be checked to find all Autosar packages. + /// + private void FindAllArPackage() + { + if (Model == null) + { + return; + } + + var query = from package in Model.ARPACKAGES.ARPACKAGE + select package; + query.ToList().ForEach(x => + { + if (x.ARPACKAGES != null) + { + // Tag ARPACKAGE has ARPACKAGES member, step deeper. + FindAllArPackage(x); + } + // Tag ARPACKAGE has no ARPACKAGES member, get it. + ArPackages.Add(x); + }); + } + + /// + /// Iterate all ARPACKAGE and ARPACKAGES tag to get all Autosar package from ARPACKAGE. + /// + /// Autosar package to be checked + private void FindAllArPackage(ARPACKAGE arPackage) + { + var query = from package in arPackage.ARPACKAGES.ARPACKAGE + select package; + query.ToList().ForEach(x => + { + if (x.ARPACKAGES != null) + { + // Tag ARPACKAGE has ARPACKAGES member, step deeper. + FindAllArPackage(x); + } + // Tag ARPACKAGE has no ARPACKAGES member, get it. + ArPackages.Add(x); + }); + } + + /// + /// Iterate all tag in Model to genereate Autosar path dictionary. + /// Any tag has SHORTNAME member can be treated as a dictionary. + /// SHORTNAME with seperator "/" from top can idenfify tags in Model. + /// as directory path in file system. + /// + private void CreateAsrPath() + { + string asrPath = ""; + if (Model != null) + { + // start from top with ARPACKAGES tag + CreateAsrPath(Model.ARPACKAGES, asrPath); + } + } + + /// + /// Iterate all tag in model to genereate Autosar path dictionary. + /// Any tag has SHORTNAME member can be treated as a dictionary. + /// SHORTNAME with seperator "/" from top can idenfify tags in Model. + /// + /// model to be checked + /// current Autosar path + private void CreateAsrPath(object model, string asrPath) + { + // Reflect all properties to get SHORTNAME in model + foreach (var prop in model.GetType().GetProperties()) + { + if (prop.Name == "SHORTNAME") + { + // Property with member "SHORTNAME" + if (prop.GetValue(model) is IDENTIFIER identifier) + { + // It is an IDENTIFIER instance, generate new path and put it into dictionary + asrPath += $"/{identifier.TypedValue}"; + AsrPathModelDict.Add(asrPath, model); + } + } + } + + // Reflect all properties to decide it is needed to check deeper + foreach (var prop in model.GetType().GetProperties()) + { + if ((prop.PropertyType.Namespace == "Autosar") || (prop.PropertyType.Namespace == "System.Collections.Generic")) + { + // Property with namespace "Autosar" or it is a Generic Collection instance + var v = prop.GetValue(model); + if ((v != null) && (prop.Name != "SHORTNAME")) + { + // Property is not null and not "SHORTNAME" + if (v is IEnumerable valueList) + { + // Property is a Generic Collection instance, check each member deeper + foreach (var v2 in valueList) + { + CreateAsrPath(v2, asrPath); + } + } + else + { + // Property is not Generic Collection instance, check it deeper + CreateAsrPath(v, asrPath); + } + } + } + } + } + + /// + /// Save model to file. + /// After save, all module shall make IsDirty to false. + /// + public void Save() + { + if (FileName != "" && Model != null) + { + Model.Save(FileName); + IsDirty = false; + } + } + } + + /// + /// Ecuc solve action handler delegate to invalid data. + /// + /// Ecuc data to solve invalid. + public delegate void EcucSolveHandler(EcucData data, object? param); + + /// + /// Ecuc solve class. + /// + public class EcucSolve + { + /// + /// Description of solve. + /// + public string Description { get; } + /// + /// Handler to solve invalid data. + /// + public EcucSolveHandler Handler { get; set; } + /// + /// Ecuc valid this solve belong to. + /// + public EcucValid Valid { get; } + + /// + /// Paramter for solve opearation. + /// + private readonly object? parameter; + + /// + /// Initialize Ecuc solve class. + /// + /// Description of invalid solve. + /// Handler of invalid solve. + /// Ecuc valid this solve belong to. + /// Parameter for solve operation. + public EcucSolve(string desc, EcucSolveHandler handler, EcucValid valid, object? param = null) + { + Description = desc; + Handler = handler; + Valid = valid; + parameter = param; + } + + /// + /// Solve the valid problem. + /// + public void Solve() + { + // Only solve Ecuc valid with data + if (Valid.Data != null) + { + try + { + // Use handler to solve problem + Handler(Valid.Data, parameter); + // Change valid to true + Valid.UpdateValidStatus(true); + } + catch + { + Console.WriteLine($"Solve {Description} failed"); + } + } + } + } + + /// + /// Ecuc valid class. + /// Describe valid status, invalid reason and solve actions. + /// + public class EcucValid : NotifyPropertyChangedBase + { + /// + /// Valid status. + /// + private bool valid; + /// + /// Invalid reason. + /// + private string invalidReason; + + /// + /// Instance of this valid belong to. + /// + public IEcucInstanceBase Instance { get; } + + /// + /// Data of this valid belong to. + /// + public EcucData? Data { get; private set; } + + /// + /// Solves to solve problem. + /// + public List Solves { get; private set; } = new(); + + /// + /// Valid status. + /// + public bool ValidStatus + { + get + { + return valid; + } + } + + /// + /// Invalid reason. + /// + public string InvalidReason + { + get + { + return invalidReason; + } + } + + /// + /// Recursice valid from this level to bottom. + /// + public List ValidRecursive + { + get + { + var result = new List(); + // Module asks containers + if (Instance is EcucInstanceModule instanceModule) + { + foreach (var container in instanceModule.Containers) + { + if (container.Valid.ValidRecursive.Count > 0) + { + result.AddRange(container.Valid.ValidRecursive); + } + } + } + + // Container asks containers, parameters and references + if (Instance is EcucInstanceContainer instanceContainer) + { + foreach (var container in instanceContainer.Containers) + { + if (container.Valid.ValidRecursive.Count > 0) + { + result.AddRange(container.Valid.ValidRecursive); + } + } + foreach (var para in instanceContainer.Paras) + { + if (para.Valid.ValidRecursive.Count > 0) + { + result.AddRange(para.Valid.ValidRecursive); + } + } + foreach (var reference in instanceContainer.Refs) + { + if (reference.Valid.ValidRecursive.Count > 0) + { + result.AddRange(reference.Valid.ValidRecursive); + } + } + } + + if (valid == false) + { + // If self valid is false, add self + result.Add(this); + } + return result; + } + } + + /// + /// Valid infomation. + /// + public string Info + { + get + { + return Instance switch + { + IEcucInstanceModule module => $"{module.AsrPath}: {InvalidReason}", + IEcucInstanceParam param => $"{Instance.BswmdPathShort}@{param.Parent.AsrPath}: {InvalidReason}", + IEcucInstanceReference reference => $"{Instance.BswmdPathShort}@{reference.Parent.AsrPath}: {InvalidReason}", + _ => throw new Exception($"Invalid instance type {Instance.GetType()}"), + }; + } + } + + /// + /// Initialize Ecuc valid class. + /// + /// Instance of this valid belong to. + /// Valid status. + /// Invalid reason. + public EcucValid(IEcucInstanceBase instance, bool v = true, string vReason = "") + { + Instance = instance; + valid = v; + if (v == false) + { + invalidReason = vReason; + } + else + { + // ignore vReason when valid status is true + invalidReason = ""; + } + } + + /// + /// Change data of this valid belong to. + /// + /// Data of this valid belong to. + public void UpdateData(EcucData data) + { + Data = data; + } + + /// + /// Change valid status and invalid reason. + /// + /// Valid status. + /// Invalid status. + public void UpdateValidStatus(bool v, string vReason = "") + { + if (v == true) + { + if (valid == false) + { + // Valid status from false to true + valid = true; + invalidReason = ""; + RaisePropertyChanged("Valid"); + } + } + else + { + if (valid == true) + { + // Valid status from true to false + valid = false; + invalidReason = vReason; + RaisePropertyChanged("Valid"); + } + else + { + // Valid status from false to false + if (invalidReason != vReason) + { + invalidReason = vReason; + RaisePropertyChanged("Valid"); + } + } + } + } + + /// + /// Add solve to valid. + /// + /// Descrption of solve. + /// Handler of solve. + /// Parameter of solve operation. + public void UpdateSolve(string desc, EcucSolveHandler handler, object? param = null) + { + Solves.Add(new EcucSolve(desc, handler, this, param)); + } + + /// + /// Change solves of valid. + /// + /// Solves to change. + public void UpdateSolve(List solves) + { + Solves = solves; + } + + /// + /// Clear all solves. + /// + public void ClearSolve() + { + Solves.Clear(); + } + + /// + /// Execute solver. + /// + /// + public void Solve(int index) + { + if (Data != null) + { + if (index < Solves.Count && index >= 0) + { + // Run handler and update status + Solves[index].Solve(); + UpdateValidStatus(true); + } + } + } + } + + public class EcucIdRangeCheck + { + readonly SortedDictionary> IdDict = new(); + + public void Add(Int64 id, EcucData data) + { + try + { + if (!IdDict.ContainsKey(id)) + { + IdDict.Add(id, new()); + } + IdDict[id].Add(data); + } + catch + { + Console.WriteLine($"Id range add fail when add data with id {id}"); + } + } + + public void Check() + { + Int64 expected = 0; + Int64 suggested = 0; + + foreach (var pair in IdDict) + { + if (pair.Key < 0) + { + Console.WriteLine($"Id is negtive."); + foreach (var data in pair.Value) + { + data.UpdateValidStatus(false, $"Id is negtive."); + data.ClearValidSolve(); + data.UpdateValidSolve($"Rearrange Id to {suggested}", IdRerangeHandler, suggested); + suggested++; + } + } + else if (pair.Value.Count > 1) + { + Console.WriteLine($"Id is not unique ({pair.Key})."); + foreach (var data in pair.Value) + { + data.UpdateValidStatus(false, $"Id is not unique."); + data.ClearValidSolve(); + data.UpdateValidSolve($"Rearrange Id to {suggested}", IdRerangeHandler, suggested); + suggested++; + } + } + else if (pair.Key != expected) + { + Console.WriteLine($"Id is not consecutive."); + foreach (var data in pair.Value) + { + data.UpdateValidStatus(false, $"Id is not consecutive."); + data.ClearValidSolve(); + data.UpdateValidSolve($"Rearrange Id to {suggested}", IdRerangeHandler, suggested); + suggested++; + } + } + else + { + foreach (var data in pair.Value) + { + if (expected != suggested) + { + Console.WriteLine($"Id shall be re-arranged."); + data.UpdateValidStatus(false, $"Id shall be re-arranged."); + data.ClearValidSolve(); + data.UpdateValidSolve($"Rearrange Id to {suggested}", IdRerangeHandler, suggested); + } + else + { + data.UpdateValidStatus(true); + data.ClearValidSolve(); + } + expected++; + suggested++; + } + } + } + } + + private void IdRerangeHandler(EcucData data, object? idSuggest) + { + if (idSuggest is Int64 id) + { + data.Value = id.ToString(); + } + } + } +} diff --git a/EcucBase/EcucBswmd.cs b/EcucBase/EcucBswmd.cs new file mode 100644 index 0000000..cc584b2 --- /dev/null +++ b/EcucBase/EcucBswmd.cs @@ -0,0 +1,1836 @@ +/* + * This file is a part of Autosar Configurator for ECU GUI based + * configuration, checking and code generation. + * + * Copyright (C) 2021-2022 DJS Studio E-mail:DD-Silence@sina.cn + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +using Ecuc.EcucBase.EBase; +using Autosar; +using System.Numerics; + +namespace Ecuc.EcucBase.EBswmd +{ + /// + /// ECU Configuration BSW Module Description (EcucBswmd) interface. + /// Base interface of all kind of BSW Module Description interface. + /// + public interface IEcucBswmdBase + { + /// + /// Model of EcucBswmd. + /// + IArEcucBswmdBase Model { get; } + /// + /// Manager of this class.. + /// + EcucBswmdManager Manager { get; } + /// + /// ShortName of EcucBswmd module. + /// + string ShortName { get; } + /// + /// Description of EcucBswmd module. + /// + string Desc { get; } + /// + /// Trace of EcucBswmd module. + /// + string Trace { get; } + /// + /// Smallest quantity of EcucBswmd can exist in Bswmd module. + /// + uint Lower { get; } + /// + /// Biggest quantity of EcucBswmd can exist in Bswmd module. + /// + uint Upper { get; } + /// + /// Autosar path of refined module from standard. + /// + string RefinedPath { get; } + /// + /// Autosar path of Bswmd module. + /// + string AsrPath { get; } + /// + /// Short form of AsrPath. + /// + string AsrPathShort { get; } + /// + /// Whether this is a multiply EcucBswmd. + /// Multiply means biggest quantity can be more than 1 + /// + bool IsMultiply { get; } + /// + /// Whether this is a single EcucBswmd. + /// Single means biggest quantity can only be 1 + /// + bool IsSingle { get; } + /// + /// Whether this is a single EcucBswmd. + /// Single means biggest quantity can only be 1 + /// + bool IsRequired { get; } + + /// + /// Get EcucBswmd from BswmdPath. + /// BswmdPath is Autosar path of EcucBswmd. + /// It usually comes from EcucInstance DEFINITION-REF tag. + /// + /// BswmdPath of EcucBswmd to be got. + /// If bswmdPath is "", this will be returned. + /// EcucBswmd has Autosar path of bswmdPath + /// Can not find EcucBswmd has Autosar path of bswmdPath + IEcucBswmdBase GetBswmdFromBswmdPath(string bswmdPath); + } + + public class EcucBswmdBase : IEcucBswmdBase + { + /// + /// Model of EcucBswmd + /// + public IArEcucBswmdBase Model { get; protected set; } + /// + /// Root data model of EcucBswmd. + /// + public EcucBswmdManager Manager { get; protected set; } + + /// + /// ShortName of EcucBswmd module. + /// + public string ShortName => Model.SHORTNAME.TypedValue; + + /// + /// Description of EcucBswmd module. + /// + public string Desc + { + get + { + var result = ""; + + try + { + foreach (var d in Model.DESC.L2) + { + result += d.Untyped.Value; + } + foreach (var p in Model.INTRODUCTION.P) + { + result += $"{Environment.NewLine}{p.Untyped.Value}"; + } + } + catch + { + result = ""; + } + + return result; + } + } + + /// + /// Trace of EcucBswmd module. + /// + public string Trace + { + get + { + var result = ""; + + try + { + foreach (var t in Model.INTRODUCTION.TRACE) + { + foreach (var l4 in t.LONGNAME.L4) + { + result += $"{l4.Untyped.Value} "; + } + } + } + catch + { + result = ""; + } + + return result; + } + } + + /// + /// Smallest quantity of EcucBswmd can exist in Bswmd module. + /// + public uint Lower => uint.Parse(Model.LOWERMULTIPLICITY.Untyped.Value); + + /// + /// Biggest quantity of EcucBswmd can exist in Bswmd module. + /// + public uint Upper + { + get + { + if (Model.UPPERMULTIPLICITYINFINITE != null) + { + return uint.MaxValue; + } + else + { + try + { + return uint.Parse(Model.UPPERMULTIPLICITY.Untyped.Value); + } + catch + { + return uint.MaxValue; + } + } + } + } + + /// + /// Autosar path of refined module from standard. + /// + public string RefinedPath { get; protected set; } + + /// + /// Autosar path of Bswmd module. + /// + public string AsrPath + { + get + { + try + { + return Manager.AsrRawAsrPathDict[Model]; + } + catch + { + throw new Exception($"Can not find Autosar model {Model}"); + } + } + } + + /// + /// Short form of AsrPath. + /// + public string AsrPathShort + { + get + { + var parts = AsrPath.Split('/'); + if (parts.Length > 0) + { + return parts[^1]; + } + return ""; + } + } + + /// + /// Whether this is a multiply EcucBswmd. + /// Multiply means biggest quantity can be more than 1 + /// + public bool IsMultiply => Upper > 1; + + /// + /// Whether this is a single EcucBswmd. + /// Single means biggest quantity can only be 1 + /// + public bool IsSingle => Upper == 1; + + /// + /// Whether this is a single EcucBswmd. + /// Single means biggest quantity can only be 1 + /// + public bool IsRequired => Lower != 0; + + /// + /// Get EcucBswmd from BswmdPath. + /// BswmdPath is Autosar path of EcucBswmd. + /// It usually comes from EcucInstance DEFINITION-REF tag. + /// + /// BswmdPath of EcucBswmd to be got. + /// If bswmdPath is "", this will be returned. + /// EcucBswmd has Autosar path of bswmdPath + /// Can not find EcucBswmd has Autosar path of bswmdPath + public IEcucBswmdBase GetBswmdFromBswmdPath(string bswmdPath) + { + if (bswmdPath == "") + { + // bswmdPath is "", return this + return this; + } + else + { + try + { + // get EcucBswmd from Root + return Manager.AsrPathBswmdDict[bswmdPath]; + } + catch + { + throw new Exception($"Can not find bswmd with path {bswmdPath}"); + } + } + } + + public EcucBswmdBase(IArEcucBswmdBase model, EcucBswmdManager manager) + { + Model = model; + Manager = manager; + RefinedPath = ""; + } + } + + /// + /// Bswmd module interface + /// Base interface of all kind of Bswmd class with Containers member. + /// + public interface IEcucBswmdModule : IEcucBswmdBase + { + /// + /// Containers in EcucBswmd. + /// + List Containers { get; } + } + + /// + /// Bswmd container interface + /// Base interface of all kind of Bswmd class with Containers, Parameters and References member. + /// + public interface IEcucBswmdContainer : IEcucBswmdModule + { + /// + /// Parent EcucBswmd. + /// Parent shall be EcucBswmd with Containers member. + /// + IEcucBswmdModule Parent { get; } + /// + /// Parameters in EcucBswmd. + /// + List Paras { get; } + /// + /// References in EcucBswmd. + /// + List Refs { get; } + } + + /// + /// Bswmd parameter interface + /// Base interface of all kind of Bswmd parameter in Bswmd container. + /// + public interface IEcucBswmdParam : IEcucBswmdBase + { + /// + /// Parent EcucBswmd. + /// Parent shall be EcucBswmd with Containers member. + /// + public IEcucBswmdModule Parent { get; } + } + + /// + /// Bswmd reference interface + /// Base interface of all kind of Bswmd reference in Bswmd container. + /// + public interface IEcucBswmdReference : IEcucBswmdBase + { + /// + /// Parent EcucBswmd. + /// Parent shall be EcucBswmd with Containers member. + /// + public IEcucBswmdModule Parent { get; } + } + + /// + /// EcucBswmd top level manager of several arxml files. + /// EcucBswmd elements in several arxml files are combined. + /// + public class EcucBswmdManager + { + /// + /// Several Asr from several arxml files. + /// + private readonly List Autosars = new(); + /// + /// EcucBswmd moudles converted from several arxml files. + /// + public List EcucModules { get; } = new(); + /// + /// Data model to Autosar path dictionary. + /// + public Dictionary AsrRawAsrPathDict = new(); + /// + /// Autosar path to EcucBswmd dictionary. + /// + public Dictionary AsrPathBswmdDict = new(); + + /// + /// Initialize EcucBswmd from several arxml files. + /// + /// File names of arxml files. + public EcucBswmdManager(string[] fileNames) + { + InitMultiple(fileNames); + } + + /// + /// Internal procees of Initialization of EcucBswmd from serveral arxml files. + /// + /// + private void InitMultiple(string[] fileNames) + { + // create one task for each arxml file. + var tasks1 = new Task[fileNames.Length]; + // step 1 to convert arxml file to Asr + for (int i = 0; i < fileNames.Length; i++) + { + tasks1[i] = InitMultipleSingleStep1(fileNames[i]); + } + Task.WaitAll(tasks1); + + // create one task for each Asr data model. + var tasks2 = new Task[Autosars.Count]; + // step 2 to collect all Autosar path. + for (int i = 0; i < Autosars.Count; i++) + { + tasks2[i] = InitMultipleSingleStep2(Autosars[i]); + } + Task.WaitAll(tasks2); + + // create one task for each Asr data model. + var tasks3 = new Task[Autosars.Count]; + // step 3 to extract EcucBswmd module. + for (int i = 0; i < Autosars.Count; i++) + { + tasks3[i] = InitMultipleSingleStep3(Autosars[i]); + } + Task.WaitAll(tasks3); + } + + /// + /// Step 1 to convert arxml file to Asr + /// + /// Arxml file name + /// + private Task InitMultipleSingleStep1(string fileName) + { + return Task.Run(() => + { + var autosar = new Asr(fileName); + + Monitor.Enter(Autosars); + try + { + // collect all Asr data model. + Autosars.Add(autosar); + } + finally + { + Monitor.Exit(Autosars); + } + + List arPackages = new(); + foreach (var package in autosar.ArPackages) + { + // collect all ArPackages. + arPackages.Add(package); + } + }); + } + + /// + /// Step 2 to collect all Autosar path. + /// + /// Asr data model + /// + private Task InitMultipleSingleStep2(Asr ar) + { + return Task.Run(() => + { + Monitor.Enter(AsrRawAsrPathDict); + try + { + // exchange value and key + foreach (var value in ar.AsrPathModelDict) + { + AsrRawAsrPathDict[value.Value] = value.Key; + } + } + finally + { + Monitor.Exit(AsrRawAsrPathDict); + } + }); + } + + /// + /// Step 3 to extract EcucBswmd module. + /// + /// Asr data model + /// + private Task InitMultipleSingleStep3(Asr ar) + { + return Task.Run(() => + { + // filter arPackages which has ECUCMODULEDEF member. + var query = from package in ar.ArPackages + where package.ELEMENTS?.ECUCMODULEDEF != null + from ecucModule in package.ELEMENTS.ECUCMODULEDEF + select ecucModule; + + Monitor.Enter(EcucModules); + try + { + // convert EcucBswmd module from tag ECUCMODULEDEF + query.ToList().ForEach(x => EcucModules.Add(new EcucBswmdModule(x, this, ar))); + } + finally + { + Monitor.Exit(EcucModules); + } + }); + } + + /// + /// Index EcucBswmd module by short name. + /// + /// Short name of targeted EcucBswmd module + /// EcucBswmd module with shortName + /// Can not find EcucBswmd module with shortName + public EcucBswmdModule this[string shortName] + { + get + { + var query = from module in EcucModules + where module.ShortName == shortName + select module; + + var result = query.ToList(); + if (result.Count > 0) + { + return result[0]; + } + else + { + throw new Exception($"Can not find bswmd module {shortName}"); + } + } + } + + /// + /// Get EcucBswmd from BswmdPath. + /// BswmdPath is Autosar path of EcucBswmd. + /// It usually comes from EcucInstance DEFINITION-REF tag. + /// + /// BswmdPath of EcucBswmd to be got. + /// If bswmdPath is "", this will be returned. + /// EcucBswmd has Autosar path of bswmdPath + /// Can not find EcucBswmd has Autosar path of bswmdPath + public IEcucBswmdBase GetBswmdFromBswmdPath(string bswmdPath) + { + try + { + return AsrPathBswmdDict[bswmdPath]; + } + catch + { + throw new Exception($"Can not find bswmd path {bswmdPath}"); + } + } + } + + /// + /// EcucBswmd module class. + /// EcucBswmd module class represent module of ECUCMODULEDEF tag. + /// + public class EcucBswmdModule : EcucBswmdBase, IEcucBswmdModule + { + /// + /// Containers of EcucBswmd module. + /// + public List Containers { get; } = new(); + /// + /// Parent Autosar data model. + /// + public Asr Parent { get; } + + /// + /// Local unpacked model + /// + public ECUCMODULEDEF ModelLocal + { + get + { + if (Model is ECUCMODULEDEF modelLocal) + { + return modelLocal; + } + else + { + throw new Exception("Invalid model type"); + } + } + } + + /// + /// Initialize EcucBswmd module class. + /// + /// Data model converted from arxml file. + /// Manager of this class. + /// Autosar data model which contain this EcucBswmd module. + public EcucBswmdModule(ECUCMODULEDEF model, EcucBswmdManager manager, Asr parent) + : base(model, manager) + { + Parent = parent; + if (ModelLocal.REFINEDMODULEDEFREF != null) + { + RefinedPath = ModelLocal.REFINEDMODULEDEFREF.Untyped.Value; + } + else + { + RefinedPath = ""; + } + + // Register this to manager + Monitor.Enter(Manager.AsrPathBswmdDict); + try + { + Manager.AsrPathBswmdDict[AsrPath] = this; + if (RefinedPath != "") + { + Manager.AsrPathBswmdDict[RefinedPath] = this; + } + } + finally + { + Monitor.Exit(Manager.AsrPathBswmdDict); + } + + // Collect all containers + if (ModelLocal.CONTAINERS != null) + { + if (ModelLocal.CONTAINERS.ECUCPARAMCONFCONTAINERDEF != null) + { + // parameter container case + foreach (var container in ModelLocal.CONTAINERS.ECUCPARAMCONFCONTAINERDEF) + { + Containers.Add(new EcucBswmdContainer(container, Manager, this, RefinedPath)); + } + } + + if (ModelLocal.CONTAINERS.ECUCCHOICECONTAINERDEF != null) + { + // choice container case + foreach (var container in ModelLocal.CONTAINERS.ECUCCHOICECONTAINERDEF) + { + Containers.Add(new EcucBswmdChoiceContainer(container, Manager, this, RefinedPath)); + } + } + } + } + } + + /// + /// EcucBswmd container class. + /// EcucBswmd container class represent tag ECUCPARAMCONFCONTAINERDEF. + /// + public class EcucBswmdContainer : EcucBswmdBase, IEcucBswmdContainer + { + /// + /// Containers of EcucBswmd container. + /// + public List Containers { get; } = new(); + /// + /// Parameters of EcucBswmd container. + /// + public List Paras { get; } = new(); + /// + /// References of EcucBswmd container. + /// + public List Refs { get; } = new(); + /// + /// Parent EcucBswmd module. + /// + public IEcucBswmdModule Parent { get; } + + /// + /// Local unpacked model + /// + public ECUCPARAMCONFCONTAINERDEF ModelLocal + { + get + { + if (Model is ECUCPARAMCONFCONTAINERDEF modelLocal) + { + return modelLocal; + } + else + { + throw new Exception("Invalid model type"); + } + } + } + + /// + /// Initialize EcucBswmd container. + /// + /// Data model convert from arxml. + /// Manager of this class. + /// Parent EcucBswmd module or container + public EcucBswmdContainer(ECUCPARAMCONFCONTAINERDEF model, EcucBswmdManager manager, IEcucBswmdModule parent, string refinedPath) + : base(model, manager) + { + Parent = parent; + if (refinedPath == "") + { + RefinedPath = ""; + } + else + { + RefinedPath = $"{refinedPath}/{AsrPathShort}"; + } + + // Register this to manager + Monitor.Enter(Manager.AsrPathBswmdDict); + try + { + Manager.AsrPathBswmdDict[AsrPath] = this; + if (RefinedPath != "") + { + Manager.AsrPathBswmdDict[RefinedPath] = this; + } + } + finally + { + Monitor.Exit(Manager.AsrPathBswmdDict); + } + + // Parse EcucBswmd container + if (ModelLocal.SUBCONTAINERS != null) + { + if (ModelLocal.SUBCONTAINERS != null) + { + if (ModelLocal.SUBCONTAINERS.ECUCPARAMCONFCONTAINERDEF != null) + { + foreach (var container in ModelLocal.SUBCONTAINERS.ECUCPARAMCONFCONTAINERDEF) + { + Containers.Add(new EcucBswmdContainer(container, Manager, this, RefinedPath)); + } + } + + if (ModelLocal.SUBCONTAINERS.ECUCCHOICECONTAINERDEF != null) + { + foreach (var container in ModelLocal.SUBCONTAINERS.ECUCCHOICECONTAINERDEF) + { + Containers.Add(new EcucBswmdChoiceContainer(container, Manager, this, RefinedPath)); + } + } + } + } + + // Parse EcucBswmd parameter + if (ModelLocal.PARAMETERS != null) + { + if (ModelLocal.PARAMETERS.ECUCENUMERATIONPARAMDEF != null) + { + foreach (var para in ModelLocal.PARAMETERS.ECUCENUMERATIONPARAMDEF) + { + Paras.Add(new EcucBswmdEnumerationPara(para, Manager, this, RefinedPath)); + } + } + + if (ModelLocal.PARAMETERS.ECUCINTEGERPARAMDEF != null) + { + foreach (var para in ModelLocal.PARAMETERS.ECUCINTEGERPARAMDEF) + { + Paras.Add(new EcucBswmdIntegerPara(para, Manager, this, RefinedPath)); + } + } + + if (ModelLocal.PARAMETERS.ECUCBOOLEANPARAMDEF != null) + { + foreach (var para in ModelLocal.PARAMETERS.ECUCBOOLEANPARAMDEF) + { + Paras.Add(new EcucBswmdBooleanPara(para, Manager, this, RefinedPath)); + } + } + + if (ModelLocal.PARAMETERS.ECUCFLOATPARAMDEF != null) + { + foreach (var para in ModelLocal.PARAMETERS.ECUCFLOATPARAMDEF) + { + Paras.Add(new EcucBswmdFloatPara(para, Manager, this, RefinedPath)); + } + } + + if (ModelLocal.PARAMETERS.ECUCSTRINGPARAMDEF != null) + { + foreach (var para in ModelLocal.PARAMETERS.ECUCSTRINGPARAMDEF) + { + Paras.Add(new EcucBswmdStringPara(para, Manager, this, RefinedPath)); + } + } + + if (ModelLocal.PARAMETERS.ECUCFUNCTIONNAMEDEF != null) + { + foreach (var para in ModelLocal.PARAMETERS.ECUCFUNCTIONNAMEDEF) + { + Paras.Add(new EcucBswmdFunctionNamePara(para, Manager, this, RefinedPath)); + } + } + } + + // Parse EcucBswmd reference + if (ModelLocal.REFERENCES != null) + { + if (ModelLocal.REFERENCES.ECUCREFERENCEDEF != null) + { + foreach (var reference in ModelLocal.REFERENCES.ECUCREFERENCEDEF) + { + Refs.Add(new EcucBswmdRef(reference, Manager, this, RefinedPath)); + } + } + + if (ModelLocal.REFERENCES.ECUCFOREIGNREFERENCEDEF != null) + { + foreach (var reference in ModelLocal.REFERENCES.ECUCFOREIGNREFERENCEDEF) + { + Refs.Add(new EcucBswmdForeignRef(reference, Manager, this, RefinedPath)); + } + } + + if (ModelLocal.REFERENCES.ECUCSYMBOLICNAMEREFERENCEDEF != null) + { + foreach (var reference in ModelLocal.REFERENCES.ECUCSYMBOLICNAMEREFERENCEDEF) + { + Refs.Add(new EcucBswmdSymbolicNameRef(reference, Manager, this, RefinedPath)); + } + } + + if (ModelLocal.REFERENCES.ECUCCHOICEREFERENCEDEF != null) + { + foreach (var reference in ModelLocal.REFERENCES.ECUCCHOICEREFERENCEDEF) + { + Refs.Add(new EcucBswmdChoiceRef(reference, Manager, this, RefinedPath)); + } + } + } + } + } + + /// + /// EcucBswmd choice container. + /// Choice container contains several option containers. + /// Only one of choice containers can exist in parent container. + /// + public class EcucBswmdChoiceContainer : EcucBswmdBase, IEcucBswmdContainer + { + /// + /// Containers of EcucBswmd container. + /// + public List Containers { get; } = new(); + /// + /// Parameters of EcucBswmd container. + /// + public List Paras { get; } = new(); + /// + /// References of EcucBswmd container. + /// + public List Refs { get; } = new(); + /// + /// Parent EcucBswmd module. + /// + public IEcucBswmdModule Parent { get; } + + /// + /// Unpacked EcucBswmd choice container. + /// + public ECUCCHOICECONTAINERDEF ModelLocal + { + get + { + if (Model is ECUCCHOICECONTAINERDEF modelLocal) + { + return modelLocal; + } + else + { + throw new Exception("Invalid model type"); + } + } + } + + /// + /// Initialize EcucBswmd choice container. + /// + /// Model data converted from arxml. + /// Manager of this class. + /// Parent EcucBswmd module or container. + public EcucBswmdChoiceContainer(ECUCCHOICECONTAINERDEF model, EcucBswmdManager manager, IEcucBswmdModule parent, string refinedPath) + : base(model, manager) + { + Parent = parent; + if (refinedPath == "") + { + RefinedPath = ""; + } + else + { + RefinedPath = $"{refinedPath}/{AsrPathShort}"; + } + + // Register this to manager + Monitor.Enter(Manager.AsrPathBswmdDict); + try + { + Manager.AsrPathBswmdDict[AsrPath] = this; + if (refinedPath != "") + { + Manager.AsrPathBswmdDict[RefinedPath] = this; + } + } + finally + { + Monitor.Exit(Manager.AsrPathBswmdDict); + } + + // Parse children of EcucBswmd container + foreach (var choice in ModelLocal.CHOICES.ECUCPARAMCONFCONTAINERDEF) + { + if (refinedPath == "") + { + Containers.Add(new EcucBswmdContainer(choice, Manager, this, refinedPath)); + } + else + { + Containers.Add(new EcucBswmdContainer(choice, Manager, this, $"{refinedPath}/{AsrPathShort}")); + } + } + } + } + + /// + /// EcucBswmd parameter of enumeration. + /// Enumeration parameter with several candidate value. + /// Only oen candidate is chosen as value. + /// + public class EcucBswmdEnumerationPara : EcucBswmdBase, IEcucBswmdParam + { + /// + /// Candidate strings. + /// + public List Candidate { get; set; } = new(); + /// + /// Default string. + /// Default string shall one of candidate. + /// + public string Default { get; } + /// + /// Parent EcucBswmd module. + /// + public IEcucBswmdModule Parent { get; } + + /// + /// Unpacked EcucBswmd choice container. + /// + public ECUCENUMERATIONPARAMDEF ModelLocal + { + get + { + if (Model is ECUCENUMERATIONPARAMDEF modelLocal) + { + return modelLocal; + } + else + { + throw new Exception("Invalid model type"); + } + } + } + + /// + /// Initi + /// + /// Data model converted from arxml. + /// Manager of this class. + /// Parent EcucBswmd container. + public EcucBswmdEnumerationPara(ECUCENUMERATIONPARAMDEF model, EcucBswmdManager manager, IEcucBswmdModule parent, string refinedPath) + : base(model, manager) + { + Parent = parent; + if (refinedPath == "") + { + RefinedPath = ""; + } + else + { + RefinedPath = $"{refinedPath}/{AsrPathShort}"; + } + + // Register this to manager + Monitor.Enter(Manager.AsrPathBswmdDict); + try + { + Manager.AsrPathBswmdDict[AsrPath] = this; + if (refinedPath != "") + { + Manager.AsrPathBswmdDict[RefinedPath] = this; + } + } + finally + { + Monitor.Exit(Manager.AsrPathBswmdDict); + } + + // Parse all candidate values + foreach (var literal in ModelLocal.LITERALS.ECUCENUMERATIONLITERALDEF) + { + Candidate.Add(literal.SHORTNAME.TypedValue); + } + + // Parse default value + var value = ModelLocal.DEFAULTVALUE; + if (value != null) + { + Default = value.Untyped.Value; + } + else + { + if (Candidate.Count > 0) + { + Default = Candidate[0]; + } + else + { + Default = ""; + } + } + } + } + + /// + /// EcucBswmd parameter of integer class. + /// + public class EcucBswmdIntegerPara : EcucBswmdBase, IEcucBswmdParam + { + /// + /// Minimun value of integer. + /// + public BigInteger Min { get; } + /// + /// Maxinum value of integer. + /// + public BigInteger? Max { get; } + /// + /// Default value of integer. + /// + public BigInteger Default { get; } + /// + /// Format of data displayed. + /// HEX for 16 digital representation, DEC for 10 digital representation. + /// + public string Format { get; } + /// + /// Parent EcucBswmd module. + /// + public IEcucBswmdModule Parent { get; } + + /// + /// Unpacked EcucBswmd choice container. + /// + public ECUCINTEGERPARAMDEF ModelLocal + { + get + { + if (Model is ECUCINTEGERPARAMDEF modelLocal) + { + return modelLocal; + } + else + { + throw new Exception("Invalid model type"); + } + } + } + + /// + /// Initialize EcucBswmd parameter of integer. + /// + /// Data model converted from arxml. + /// Manager of this class. + /// Parent EcucBswmd container. + public EcucBswmdIntegerPara(ECUCINTEGERPARAMDEF model, EcucBswmdManager manager, IEcucBswmdModule parent, string refinedPath) + : base(model, manager) + { + Parent = parent; + if (refinedPath == "") + { + RefinedPath = ""; + } + else + { + RefinedPath = $"{refinedPath}/{AsrPathShort}"; + } + + // Register this to manager + Monitor.Enter(Manager.AsrPathBswmdDict); + try + { + Manager.AsrPathBswmdDict[AsrPath] = this; + if (refinedPath != "") + { + Manager.AsrPathBswmdDict[RefinedPath] = this; + } + } + finally + { + Monitor.Exit(Manager.AsrPathBswmdDict); + } + + // Parse mininum value + try + { + Min = BigInteger.Parse(ModelLocal.MIN.Untyped.Value); + } + catch + { + Min = 0; + } + + // Parse maximun value if exist + if (ModelLocal.MAX == null) + { + Max = null; + } + else if (ModelLocal.MAX.Untyped.Value == "*") + { + Max = null; + } + else + { + Max = BigInteger.Parse(ModelLocal.MAX.Untyped.Value); + } + + // Parse default value + var value = ModelLocal.DEFAULTVALUE; + if (value != null) + { + if (value.Untyped.Value == "") + { + Default = Min; + } + else + { + Default = BigInteger.Parse(value.Untyped.Value); + } + } + else + { + Default = Min; + } + + // Parse format + var format = ModelLocal.ADMINDATA; + if (format != null) + { + var formats = format.SDGS.SDG; + foreach (var f in formats) + { + if (f.GID == "DV:Display") + { + var formats2 = f.SD; + foreach (var f2 in formats2) + { + if (f2.GID == "DV:DefaultFormat") + { + Format = f2.Untyped.Value; + } + } + } + } + } + + // Check format at last + if (Format == null) + { + Format = ""; + } + } + } + + /// + /// EcucBswmd parameter of boolean. + /// + public class EcucBswmdBooleanPara : EcucBswmdBase, IEcucBswmdParam + { + /// + /// Default value. + /// false or true + /// + public bool Default { get; } + /// + /// Parent EcucBswmd module. + /// + public IEcucBswmdModule Parent { get; } + + /// + /// Unpacked EcucBswmd choice container. + /// + public ECUCBOOLEANPARAMDEF ModelLocal + { + get + { + if (Model is ECUCBOOLEANPARAMDEF modelLocal) + { + return modelLocal; + } + else + { + throw new Exception("Invalid model type"); + } + } + } + + /// + /// Initialize EcucBswmd boolean parameter. + /// + /// Model data converted form arxml. + /// Manager of this class. + /// Parent EcucBswmd container. + public EcucBswmdBooleanPara(ECUCBOOLEANPARAMDEF model, EcucBswmdManager manager, IEcucBswmdModule parent, string refinedPath) + : base(model, manager) + { + Parent = parent; + if (refinedPath == "") + { + RefinedPath = ""; + } + else + { + RefinedPath = $"{refinedPath}/{AsrPathShort}"; + } + + // Register this to manager + Monitor.Enter(Manager.AsrPathBswmdDict); + try + { + Manager.AsrPathBswmdDict[AsrPath] = this; + if (refinedPath != "") + { + Manager.AsrPathBswmdDict[RefinedPath] = this; + } + } + finally + { + Monitor.Exit(Manager.AsrPathBswmdDict); + } + + // Parse default value + var value = ModelLocal.DEFAULTVALUE; + try + { + if (value.Untyped.Value == "1") + { + Default = true; + } + else if (value.Untyped.Value == "0") + { + Default = false; + } + else + { + Default = bool.Parse(value.Untyped.Value); + } + } + catch + { + Default = false; + } + } + } + + /// + /// EcucBswmd parameter of float. + /// + public class EcucBswmdFloatPara : EcucBswmdBase, IEcucBswmdParam + { + /// + /// Default value. + /// + public double Default { get; } + /// + /// Parent EcucBswmd module. + /// + public IEcucBswmdModule Parent { get; } + + /// + /// Unpacked EcucBswmd choice container. + /// + public ECUCFLOATPARAMDEF ModelLocal + { + get + { + if (Model is ECUCFLOATPARAMDEF modelLocal) + { + return modelLocal; + } + else + { + throw new Exception("Invalid model type"); + } + } + } + + /// + /// Initialize EcucBswmd float parameter. + /// + /// Model data converted from arxml. + /// Manager of this class. + /// Parent EcucBswmd container. + public EcucBswmdFloatPara(ECUCFLOATPARAMDEF model, EcucBswmdManager manager, IEcucBswmdModule parent, string refinedPath) + : base(model, manager) + { + Parent = parent; + if (refinedPath == "") + { + RefinedPath = ""; + } + else + { + RefinedPath = $"{refinedPath}/{AsrPathShort}"; + } + + // Register this to manager + Monitor.Enter(Manager.AsrPathBswmdDict); + try + { + Manager.AsrPathBswmdDict[AsrPath] = this; + if (refinedPath != "") + { + Manager.AsrPathBswmdDict[RefinedPath] = this; + } + } + finally + { + Monitor.Exit(Manager.AsrPathBswmdDict); + } + + // Parse default value + var value = ModelLocal.DEFAULTVALUE; + try + { + Default = double.Parse(value.Untyped.Value); + } + catch + { + Default = 0.0f; + } + } + } + + /// + /// EcucBswmd parameter of string. + /// + public class EcucBswmdStringPara : EcucBswmdBase, IEcucBswmdParam + { + /// + /// Default value. + /// + public List Default { get; } = new(); + /// + /// Parent EcucBswmd module. + /// + public IEcucBswmdModule Parent { get; } + + /// + /// Unpacked EcucBswmd choice container. + /// + public ECUCSTRINGPARAMDEF ModelLocal + { + get + { + if (Model is ECUCSTRINGPARAMDEF modelLocal) + { + return modelLocal; + } + else + { + throw new Exception("Invalid model type"); + } + } + } + + /// + /// + /// + /// Model data converted from arxml. + /// Manager of this class. + /// Parent EcucBswmd container. + public EcucBswmdStringPara(ECUCSTRINGPARAMDEF model, EcucBswmdManager manager, IEcucBswmdModule parent, string refinedPath) + : base(model, manager) + { + Parent = parent; + if (refinedPath == "") + { + RefinedPath = ""; + } + else + { + RefinedPath = $"{refinedPath}/{AsrPathShort}"; + } + + // Register this to manager. + Monitor.Enter(Manager.AsrPathBswmdDict); + try + { + Manager.AsrPathBswmdDict[AsrPath] = this; + if (refinedPath != "") + { + Manager.AsrPathBswmdDict[RefinedPath] = this; + } + } + finally + { + Monitor.Exit(Manager.AsrPathBswmdDict); + } + + // Parse default strings + if (ModelLocal.ECUCSTRINGPARAMDEFVARIANTS != null) + { + foreach (var variant in ModelLocal.ECUCSTRINGPARAMDEFVARIANTS.ECUCSTRINGPARAMDEFCONDITIONAL) + { + if (variant.DEFAULTVALUE != null) + { + Default.Add(variant.DEFAULTVALUE.Untyped.Value); + } + } + } + } + } + + /// + /// EcucBswmd paramter of function name. + /// + public class EcucBswmdFunctionNamePara : EcucBswmdBase, IEcucBswmdParam + { + /// + /// Default value. + /// + public List Default { get; } = new(); + /// + /// Parent EcucBswmd module. + /// + public IEcucBswmdModule Parent { get; } + + /// + /// Unpacked EcucBswmd choice container. + /// + public ECUCFUNCTIONNAMEDEF ModelLocal + { + get + { + if (Model is ECUCFUNCTIONNAMEDEF modelLocal) + { + return modelLocal; + } + else + { + throw new Exception("Invalid model type"); + } + } + } + + /// + /// Initialize EcucBswmd function name parameter. + /// + /// Model data converted from arxml. + /// Manager of this class. + /// Parent of EcucBswmd container. + public EcucBswmdFunctionNamePara(ECUCFUNCTIONNAMEDEF model, EcucBswmdManager manager, IEcucBswmdModule parent, string refinedPath) + : base(model, manager) + { + Parent = parent; + if (refinedPath == "") + { + RefinedPath = ""; + } + else + { + RefinedPath = $"{refinedPath}/{AsrPathShort}"; + } + + // Register this to manager. + Monitor.Enter(Manager.AsrPathBswmdDict); + try + { + Manager.AsrPathBswmdDict[AsrPath] = this; + if (refinedPath != "") + { + Manager.AsrPathBswmdDict[RefinedPath] = this; + } + } + finally + { + Monitor.Exit(Manager.AsrPathBswmdDict); + } + + // Parese default values. + if (ModelLocal.ECUCFUNCTIONNAMEDEFVARIANTS != null) + { + foreach (var variant in ModelLocal.ECUCFUNCTIONNAMEDEFVARIANTS.ECUCFUNCTIONNAMEDEFCONDITIONAL) + { + if (variant.DEFAULTVALUE != null) + { + Default.Add(variant.DEFAULTVALUE.Untyped.Value); + } + } + } + + if (Default.Count == 0) + { + Default.Add(""); + } + } + } + + /// + /// EcucBsemd reference. + /// + public class EcucBswmdRef : EcucBswmdBase, IEcucBswmdReference + { + /// + /// Parent EcucBswmd module. + /// + public IEcucBswmdModule Parent { get; } + + /// + /// Unpacked EcucBswmd choice container. + /// + public ECUCREFERENCEDEF ModelLocal + { + get + { + if (Model is ECUCREFERENCEDEF modelLocal) + { + return modelLocal; + } + else + { + throw new Exception("Invalid model type"); + } + } + } + + /// + /// Reference desitination Bswmd path. + /// + public string DestPath + { + get + { + return ModelLocal.DESTINATIONREF.TypedValue; + } + } + + /// + /// Reference desitination tag. + /// + public string Dest + { + get + { + return ModelLocal.DESTINATIONREF.DEST; + } + } + + /// + /// Initialize EcucBswmd reference. + /// + /// Data model converted from arxml. + /// Manager of this class. + /// Parent EcucBswmd container. + public EcucBswmdRef(ECUCREFERENCEDEF model, EcucBswmdManager manager, IEcucBswmdModule parent, string refinedPath) + : base(model, manager) + { + Parent = parent; + if (refinedPath == "") + { + RefinedPath = ""; + } + else + { + RefinedPath = $"{refinedPath}/{AsrPathShort}"; + } + + // Register this to manager. + Monitor.Enter(Manager.AsrPathBswmdDict); + try + { + Manager.AsrPathBswmdDict[AsrPath] = this; + if (refinedPath != "") + { + Manager.AsrPathBswmdDict[RefinedPath] = this; + } + } + finally + { + Monitor.Exit(Manager.AsrPathBswmdDict); + } + } + } + + /// + /// EcucBswmd reference from tag other than Ecuc tags. + /// + public class EcucBswmdForeignRef : EcucBswmdBase, IEcucBswmdReference + { + /// + /// Parent EcucBswmd module. + /// + public IEcucBswmdModule Parent { get; } + + /// + /// Unpacked EcucBswmd choice container. + /// + public ECUCFOREIGNREFERENCEDEF ModelLocal + { + get + { + if (Model is ECUCFOREIGNREFERENCEDEF modelLocal) + { + return modelLocal; + } + else + { + throw new Exception("Invalid model type"); + } + } + } + + /// + /// Reference desitination tag. + /// + public string DestType + { + get + { + return ModelLocal.DESTINATIONTYPE.TypedValue; + } + } + + /// + /// Initialize + /// + /// Model data converted from arxml. + /// Manager of this class. + /// Parent EcucBswmd container. + public EcucBswmdForeignRef(ECUCFOREIGNREFERENCEDEF model, EcucBswmdManager manager, IEcucBswmdModule parent, string refinedPath) + : base(model, manager) + { + Parent = parent; + if (refinedPath == "") + { + RefinedPath = ""; + } + else + { + RefinedPath = $"{refinedPath}/{AsrPathShort}"; + } + + // Register this to manager. + Monitor.Enter(Manager.AsrPathBswmdDict); + try + { + Manager.AsrPathBswmdDict[AsrPath] = this; + if (refinedPath != "") + { + Manager.AsrPathBswmdDict[RefinedPath] = this; + } + } + finally + { + Monitor.Exit(Manager.AsrPathBswmdDict); + } + } + } + + /// + /// EcucBswmd reference of symbolic name. + /// + public class EcucBswmdSymbolicNameRef : EcucBswmdBase, IEcucBswmdReference + { + /// + /// Parent EcucBswmd module. + /// + public IEcucBswmdModule Parent { get; } + + /// + /// Unpacked EcucBswmd choice container. + /// + public ECUCSYMBOLICNAMEREFERENCEDEF ModelLocal + { + get + { + if (Model is ECUCSYMBOLICNAMEREFERENCEDEF modelLocal) + { + return modelLocal; + } + else + { + throw new Exception("Invalid model type"); + } + } + } + + /// + /// Reference desitination tag. + /// + public string Dest + { + get + { + return ModelLocal.DESTINATIONREF.DEST; + } + } + + /// + /// Reference desitination desitination tag. + /// + public string DestPath + { + get + { + return ModelLocal.DESTINATIONREF.TypedValue; + } + } + + /// + /// Initialize EcucBswmd symbolic name. + /// + /// Model data converted from arxml. + /// Manager of this class. + /// Parent EcucBswmd container. + public EcucBswmdSymbolicNameRef(ECUCSYMBOLICNAMEREFERENCEDEF model, EcucBswmdManager manager, IEcucBswmdModule parent, string refinedPath) + : base(model, manager) + { + Parent = parent; + if (refinedPath == "") + { + RefinedPath = ""; + } + else + { + RefinedPath = $"{refinedPath}/{AsrPathShort}"; + } + + // Register this to manager. + Monitor.Enter(Manager.AsrPathBswmdDict); + try + { + Manager.AsrPathBswmdDict[AsrPath] = this; + if (refinedPath != "") + { + Manager.AsrPathBswmdDict[RefinedPath] = this; + } + } + finally + { + Monitor.Exit(Manager.AsrPathBswmdDict); + } + } + } + + /// + /// EcucBswmd reference of choice reference. + /// + public class EcucBswmdChoiceRef : EcucBswmdBase, IEcucBswmdReference + { + /// + /// Parent EcucBswmd module. + /// + public IEcucBswmdModule Parent { get; } + + /// + /// Unpacked EcucBswmd choice container. + /// + public ECUCCHOICEREFERENCEDEF ModelLocal + { + get + { + if (Model is ECUCCHOICEREFERENCEDEF modelLocal) + { + return modelLocal; + } + else + { + throw new Exception("Invalid model type"); + } + } + } + + /// + /// Parse choices reference. + /// + public Dictionary Choices + { + get + { + var result = new Dictionary(); + foreach (var destRef in ModelLocal.DESTINATIONREFS.DESTINATIONREF) + { + result[destRef.TypedValue] = destRef.DEST; + } + return result; + } + } + + /// + /// Initialize EcucBswmd reference of choices. + /// + /// Model data from converted arxml. + /// Manager of this class. + /// Parent EcucBswmd container. + public EcucBswmdChoiceRef(ECUCCHOICEREFERENCEDEF model, EcucBswmdManager manager, IEcucBswmdModule parent, string refinedPath) + : base(model, manager) + { + Parent = parent; + if (refinedPath == "") + { + RefinedPath = ""; + } + else + { + RefinedPath = $"{refinedPath}/{AsrPathShort}"; + } + + // Register this to manager. + Monitor.Enter(Manager.AsrPathBswmdDict); + try + { + Manager.AsrPathBswmdDict[AsrPath] = this; + if (refinedPath != "") + { + Manager.AsrPathBswmdDict[RefinedPath] = this; + } + } + finally + { + Monitor.Exit(Manager.AsrPathBswmdDict); + } + } + } +} diff --git a/EcucBase/EcucData.cs b/EcucBase/EcucData.cs new file mode 100644 index 0000000..0bf5dde --- /dev/null +++ b/EcucBase/EcucData.cs @@ -0,0 +1,2249 @@ +/* + * This file is a part of Autosar Configurator for ECU GUI based + * configuration, checking and code generation. + * + * Copyright (C) 2021-2022 DJS Studio E-mail:DD-Silence@sina.cn + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +using Ecuc.EcucBase.EBase; +using Ecuc.EcucBase.EBswmd; +using Ecuc.EcucBase.EInstance; +using System.ComponentModel; +using System.Numerics; + +namespace Ecuc.EcucBase.EData +{ + /// + /// EcucData multiply status. + /// Multiply status is calculated from quantity in instance, lower and upper + /// in bswmd. It is represent as int, every status occupy one bit. Several + /// status can exist at same time. + /// + public class EcucDataMultiplyStatus + { + /// + /// Status enumeration + /// + public enum StatusType + { + /// + /// Fatal error happen during calculation or EcucBswmd upper is 0. + /// + Invalid = 0, + /// + /// The quantity is 0. + /// + Empty = 1, + /// + /// The quantity is less than lower. + /// + Lack = 2, + /// + /// The quantity is same as lower. + /// + OkLower = 4, + /// + /// The quantity is bigger than lower and smaller than upper. + /// + OkMiddle = 8, + /// + /// The quantity is same as upper. + /// + OkUpper = 16, + /// + /// The quantity is bigger than upper. + /// + Overflow = 32, + } + + /// + /// Status. + /// + public StatusType Status { get; } + + /// + /// Initialize class by status enumeration. + /// + /// + public EcucDataMultiplyStatus(StatusType status) + { + Status = status; + } + + /// + /// Helper property to get whether invalid. + /// + public bool Invalid => Status == StatusType.Invalid; + /// + /// Helper property to get whether empty. + /// + public bool Empty => (Status & StatusType.Empty) == StatusType.Empty; + /// + /// Helper property to get whether lack. + /// + public bool Lack => (Status & StatusType.Lack) == StatusType.Lack; + /// + /// Helper property to get whether okLower. + /// + public bool OkLower => (Status & StatusType.OkLower) == StatusType.OkLower; + /// + /// Helper property to get whether okMiddle. + /// + public bool OkMiddle => (Status & StatusType.OkMiddle) == StatusType.OkMiddle; + /// + /// Helper property to get whether okUpper. + /// + public bool OkUpper => (Status & StatusType.OkUpper) == StatusType.OkUpper; + /// + /// Helper property to get whether overflow. + /// + public bool Overflow => (Status & StatusType.Overflow) == StatusType.Overflow; + + /// + /// Helper property to get whether can add more. + /// + public bool CanAdd => !OkUpper && !Overflow && !Invalid; + /// + /// Helper property to get whether can remove one. + /// + public bool CanRemove => !Lack && !OkLower && !Invalid; + /// + /// Helper property to get whether ok. + /// + public bool Ok => OkLower || OkMiddle || OkUpper; + /// + /// Helper property to get whether not ok. + /// + public bool NotOk => !Ok; + } + + /// + /// Ecuc data class. + /// Ecuc data integrate EcucInstance and EcucBswmd. From EcucData, quantity of instance + /// can be evalutaed. Add and Remove operation can also be evaluated by MultiplyStatus. + /// + public class EcucData : NotifyPropertyChangedBase + { + /// + /// EcucInstance. + /// + private IEcucInstanceBase Instance { get; } + /// + /// EcucBswmd. + /// + private IEcucBswmdBase Bswmd { get; } + + /// + /// Whether data is invalid. + /// + public bool ValidStatus + { + get + { + return Instance.Valid.ValidRecursive.Count == 0; + } + } + + /// + /// Whether data is invalid. + /// + public string ValidInfo + { + get + { + string result = ""; + foreach (var v in Instance.Valid.ValidRecursive) + { + result += $"{v.Info}{Environment.NewLine}"; + } + return result; + } + } + + /// + /// Whether data is invalid. + /// + public List ValidRecursive + { + get + { + return Instance.Valid.ValidRecursive; + } + } + + /// + /// Short form of AsrPath + /// + public string AsrPathShort + { + get + { + var parts = AsrPath.Split('/'); + if (parts.Length > 0) + { + return parts[^1]; + } + return ""; + } + } + + /// + /// Autosar path of EcucInstance as moudle or container. + /// + public string AsrPath + { + get + { + return InstanceAsModule.AsrPath; + } + } + + /// + /// EcucInstance class type. + /// + public Type InstanceType + { + get + { + return Instance.GetType(); + } + } + + /// + /// EcucBswmd class type. + /// + public Type BswmdType + { + get + { + return Bswmd.GetType(); + } + } + + /// + /// EcucBswmd description. + /// + public string Desc + { + get + { + return Bswmd.Desc; + } + } + + /// + /// EcucBswmd trace. + /// + public string Trace + { + get + { + return Bswmd.Trace; + } + } + + /// + /// EcucBswmd smallest quantity. + /// + public uint Lower + { + get + { + return Bswmd.Lower; + } + } + + /// + /// EcucBswmd biggest quantity. + /// + public uint Upper + { + get + { + return Bswmd.Upper; + } + } + + /// + /// EcucInstance as IEcucInstanceModule. + /// + private IEcucInstanceModule InstanceAsModule + { + get + { + if (Instance is IEcucInstanceModule container) + { + return container; + } + else + { + throw new Exception("Instance of ecuc data is not module kind"); + } + } + } + + /// + /// EcucBswmd as IEcucBswmdModule. + /// + private IEcucBswmdModule BswmdAsModule + { + get + { + if (Bswmd is IEcucBswmdModule container) + { + return container; + } + else + { + throw new Exception("Bswmd of ecuc data is not module kind"); + } + } + } + + /// + /// EcucInstance as IEcucInstanceContainer. + /// + private IEcucInstanceContainer InstanceAsContainer + { + get + { + if (Instance is IEcucInstanceContainer container) + { + return container; + } + else + { + throw new Exception("Instance of ecuc data is not container kind"); + } + } + } + + /// + /// EcucBswmd as IEcucBswmdContainer. + /// + private IEcucBswmdContainer BswmdAsContainer + { + get + { + if (Bswmd is IEcucBswmdContainer container) + { + return container; + } + else + { + throw new Exception("Bswmd of ecuc data is not container kind"); + } + } + } + + /// + /// EcucBswmd path as well as EcucInstance BswmdPath. + /// + public string BswmdPath + { + get + { + return Bswmd.AsrPath; + } + } + + /// + /// Short form of BswmdPath. + /// + public string BswmdPathShort + { + get + { + return Bswmd.AsrPathShort; + } + } + + /// + /// Continers in EcucInstance + /// + public List Containers + { + get + { + return InstanceAsModule.Containers; + } + } + + /// + /// Parameters in EcucInstance + /// + public List Paras + { + get + { + return InstanceAsContainer.Paras; + } + } + + /// + /// References in EcucInstance + /// + public List Refs + { + get + { + return InstanceAsContainer.Refs; + } + } + + /// + /// Continers in EcucBswmd + /// + public List BswmdContainers + { + get + { + return BswmdAsModule.Containers; + } + } + + /// + /// Parameters in EcucBswmd + /// + public List BswmdParas + { + get + { + return BswmdAsContainer.Paras; + } + } + + /// + /// References in EcucBswmd + /// + public List BswmdRefs + { + get + { + return BswmdAsContainer.Refs; + } + } + + /// + /// The reference point to Autosar path + /// + public List Usage + { + get + { + try + { + return Instance.GetReferenceByAsrPath(AsrPath); + } + catch + { + return new List(); + } + } + } + + /// + /// Get EcucBswmd from BswmdPath. + /// + /// + /// + public IEcucBswmdBase GetBswmdFromBswmdPath(string bswmdPath) + { + return Bswmd.GetBswmdFromBswmdPath(bswmdPath); + } + + /// + /// Sort containers in EcucInstance according to IEcucBswmdModule + /// + public Dictionary SortedContainers + { + get + { + var result = new Dictionary(); + // Iterate bswmd containers in bswmd container + foreach (var bswmdSubContainer in BswmdAsModule.Containers) + { + result[bswmdSubContainer] = new EcucDataList(); + // Find containers according to bswmd + var instanceContainters = InstanceAsModule.FindContainerByBswmd(bswmdSubContainer.AsrPath); + // Pack each container to EcucData and then to EcucDataList + foreach (var instanceContainter in instanceContainters) + { + result[bswmdSubContainer].Add(new EcucData(instanceContainter, bswmdSubContainer)); + } + } + return result; + } + } + + /// + /// Sort parameters in EcucInstance according to IEcucBswmdParam + /// + public Dictionary SortedParas + { + get + { + var result = new Dictionary(); + // Iterate bswmd parameters in bswmd container + foreach (var bswmdPara in BswmdAsContainer.Paras) + { + result[bswmdPara] = new EcucDataList(); + // Find parameters according to bswmd + var instanceParas = InstanceAsContainer.FindParaByBswmd(bswmdPara.AsrPath); + // Pack each parameter to EcucData and then to EcucDataList + foreach (var instancePara in instanceParas) + { + result[bswmdPara].Add(new EcucData(instancePara, bswmdPara)); + } + } + return result; + } + } + + /// + /// Sort references in EcucInstance according to IEcucBswmdReference + /// + public Dictionary SortedRefs + { + get + { + var result = new Dictionary(); + // Iterate bswmd references in bswmd container + foreach (var bswmdRef in BswmdAsContainer.Refs) + { + result[bswmdRef] = new EcucDataList(); + // Find references according to bswmd + var instanceRefs = InstanceAsContainer.FindRefByBswmd(bswmdRef.AsrPath); + // Pack each reference to EcucData and then to EcucDataList + foreach (var instanceRef in instanceRefs) + { + result[bswmdRef].Add(new EcucData(instanceRef, bswmdRef)); + } + } + return result; + } + } + + /// + /// Value of EcucData. + /// For IEcucInstanceModule, ShortName will be returned. + /// For IEcucInstanceParam, Parameter value will be returned. + /// For IEcucInstanceReference, Reference valueRef will be returned. + /// + public string Value + { + get + { + switch (Instance) + { + // For IEcucInstanceModule, ShortName will be returned + case IEcucInstanceModule instanceContainer: + return instanceContainer.AsrPathShort; + + // For IEcucInstanceParam, further handle is needed + case IEcucInstanceParam instancePara: + switch (Instance) + { + // For EcucInstanceNumericalParamValue + case EcucInstanceNumericalParamValue: + switch (Bswmd) + { + case EcucBswmdIntegerPara bswmdInteger: + // For EcucBswmdIntegerPara + switch (bswmdInteger.Format) + { + // Hex format, 10 base string to integer and then to 16 base string + case "HEX": + try + { + return $"0x{Convert.ToInt64(instancePara.Value, 10):X}"; + } + catch + { + throw new Exception($"Invalid format of value {instancePara.Value}"); + } + + // Dec format + default: + return instancePara.Value; + } + + case EcucBswmdBooleanPara: + // For EcucBswmdBooleanPara + if (instancePara.Value == "0") + { + return "false"; + } + else + { + return "true"; + } + + // For others, no need to change + default: + return instancePara.Value; + } + + // For others, no need to change + default: + return instancePara.Value; + } + + // For IEcucInstanceReference, ValueRef will be returned + case IEcucInstanceReference instanceRef: + return instanceRef.ValueRef; + + default: + throw new Exception("invalid instance type"); + } + } + set + { + switch (Instance) + { + case IEcucInstanceModule instanceContainer: + instanceContainer.ShortName = value; + break; + + case IEcucInstanceParam instancePara: + switch (Instance) + { + case EcucInstanceNumericalParamValue: + switch (Bswmd) + { + case EcucBswmdIntegerPara bswmdInteger: + switch (bswmdInteger.Format) + { + case "HEX": + try + { + instancePara.Value = Convert.ToInt64(value, 16).ToString(); + } + catch + { + throw new Exception($"invalid format of value {value}"); + } + break; + + default: + instancePara.Value = value; + break; + } + break; + + default: + instancePara.Value = value; + break; + } + break; + + default: + instancePara.Value = value; + break; + } + break; + + case IEcucInstanceReference instanceRef: + instanceRef.ValueRef = value; + break; + + default: + break; + } + RaisePropertyChanged(); + } + } + + /// + /// Value of EcucData convert to Int64. + /// For IEcucInstanceParam, Parameter value with will be returned. + /// + public Int64 ValueAsInt + { + get + { + if (Instance is EcucInstanceNumericalParamValue instancePara && Bswmd is EcucBswmdIntegerPara) + { + try + { + return Convert.ToInt64(instancePara.Value, 10); + } + catch + { + throw new Exception($"Invalid format of value {instancePara.Value}"); + } + } + throw new Exception($"Instance can not convert to integer."); + } + set + { + if (Instance is EcucInstanceNumericalParamValue instancePara && Bswmd is EcucBswmdIntegerPara bswmdInteger) + { + switch (bswmdInteger.Format) + { + case "HEX": + try + { + instancePara.Value = Convert.ToString(value, 16); + } + catch + { + throw new Exception($"invalid format of value {value}"); + } + break; + + default: + instancePara.Value = Convert.ToString(value, 10); + break; + } + } + RaisePropertyChanged(); + } + } + + public string ValueShort + { + get + { + var parts = Value.Split('/'); + if (parts.Length > 0) + { + return parts[^1]; + } + return ""; + } + set + { + var parts = Value.Split('/'); + parts[^1] = value; + Value = string.Join("/", parts); + RaisePropertyChanged(); + } + } + + public EcucData(IEcucInstanceBase instance, IEcucBswmdBase bswmd) + { + Instance = instance; + Bswmd = bswmd; + + Instance.PropertyChanged += PropertyChangedEventHandler; + } + + public EcucData(EcucInstanceManager isntanceManager, EcucBswmdManager bswmdManager, string name) + { + var instanceModule = isntanceManager[name]; + if (instanceModule == null) + { + throw new Exception($"Can not get instance with name {name}"); + } + var bswmdModule = bswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath); + if (bswmdModule == null) + { + throw new Exception($"Can not get bswmd with path {instanceModule.BswmdPath}"); + } + Instance = instanceModule; + Bswmd = bswmdModule; + } + + public EcucDataList this[string key] + { + get + { + var result = new EcucDataList(); + if (Bswmd != null) + { + var bswmdGet = Bswmd.GetBswmdFromBswmdPath($"{Instance.BswmdPath}/{key}"); + switch (bswmdGet) + { + case IEcucBswmdModule: + { + if (Instance is IEcucInstanceModule instanceContainer && Bswmd is IEcucBswmdModule bswmdContainer) + { + var query = from container in instanceContainer.Containers + where container.BswmdPathShort == key + select container; + + query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet))); + } + } + break; + + case IEcucBswmdParam: + { + if (Instance is IEcucInstanceContainer instanceOtherContainer && Bswmd is IEcucBswmdContainer bswmdOtherContainer) + { + var query = from para in instanceOtherContainer.Paras + where para.BswmdPathShort == key + select para; + + query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet))); + } + } + break; + + case IEcucBswmdReference: + { + if (Instance is IEcucInstanceContainer instanceOtherContainer && Bswmd is IEcucBswmdContainer bswmdOtherContainer) + { + var query = from reference in instanceOtherContainer.Refs + where reference.BswmdPathShort == key + select reference; + + query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet))); + } + } + break; + + default: + break; + } + } + return result; + } + } + + public EcucDataList this[string key, string name] + { + get + { + var result = new EcucDataList(); + if (Bswmd != null) + { + var bswmdGet = Bswmd.GetBswmdFromBswmdPath($"{Instance.BswmdPath}/{key}"); + switch (bswmdGet) + { + case IEcucBswmdModule: + { + if (Instance is IEcucInstanceModule instanceContainer && Bswmd is IEcucBswmdModule bswmdContainer) + { + var query = from container in instanceContainer.Containers + where container.BswmdPathShort == key + where container.ShortName == name + select container; + + query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet))); + } + } + break; + + case IEcucBswmdParam: + { + if (Instance is IEcucInstanceContainer instanceOtherContainer && Bswmd is IEcucBswmdContainer bswmdOtherContainer) + { + var query = from para in instanceOtherContainer.Paras + where para.BswmdPathShort == key + select para; + + query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet))); + } + } + break; + + case IEcucBswmdReference: + { + if (Instance is IEcucInstanceContainer instanceOtherContainer && Bswmd is IEcucBswmdContainer bswmdOtherContainer) + { + var query = from reference in instanceOtherContainer.Refs + where reference.BswmdPathShort == key + where reference.ValueRefShort == name + select reference; + + query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet))); + } + } + break; + + default: + break; + } + } + return result; + } + } + + public delegate bool FilterFunc(EcucData data); + public EcucDataList this[string key, FilterFunc func] + { + get + { + var result = new EcucDataList(); + if (Bswmd != null) + { + var bswmdGet = Bswmd.GetBswmdFromBswmdPath($"{Instance.BswmdPath}/{key}"); + switch (bswmdGet) + { + case IEcucBswmdModule: + { + if (Instance is IEcucInstanceModule instanceContainer && Bswmd is IEcucBswmdModule bswmdContainer) + { + var query = from container in instanceContainer.Containers + where container.BswmdPathShort == key + where func(new EcucData(container, bswmdGet)) + select container; + + query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet))); + } + } + break; + + case IEcucBswmdParam: + { + if (Instance is IEcucInstanceContainer instanceOtherContainer && Bswmd is IEcucBswmdContainer bswmdOtherContainer) + { + var query = from para in instanceOtherContainer.Paras + where para.BswmdPathShort == key + where func(new EcucData(para, bswmdGet)) + select para; + + query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet))); + } + } + break; + + case IEcucBswmdReference: + { + if (Instance is IEcucInstanceContainer instanceOtherContainer && Bswmd is IEcucBswmdContainer bswmdOtherContainer) + { + var query = from reference in instanceOtherContainer.Refs + where reference.BswmdPathShort == key + where func(new EcucData(reference, bswmdGet)) + select reference; + + query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet))); + } + } + break; + + default: + break; + } + } + return result; + } + } + + private string RecommendedName(string bswmdPathShort) + { + if (Bswmd is IEcucBswmdModule bswmd && Instance is IEcucInstanceModule instance) + { + foreach (var bswmdSubContainer in bswmd.Containers) + { + if (bswmdSubContainer.AsrPathShort == bswmdPathShort) + { + var instances = instance.FindContainerByBswmd(bswmdSubContainer.AsrPath); + bool okFlag = true; + var recommendedName = bswmdSubContainer.AsrPathShort; + + foreach (var container in instances) + { + if (container.ShortName == recommendedName) + { + okFlag = false; + break; + } + } + + if (okFlag == true) + { + return recommendedName; + } + + for (int i = 0; i < 999; i++) + { + okFlag = true; + recommendedName = $"{bswmdSubContainer.AsrPathShort}_{i:D3}"; + foreach (var container in instances) + { + if (container.ShortName == recommendedName) + { + okFlag = false; + break; + } + } + + if (okFlag == true) + { + return recommendedName; + } + } + } + } + throw new Exception("Fail to find recommended name due to every candidate is used"); + } + else + { + throw new Exception("Fail to find recommended name due to wrong Bswmd or Instance type"); + } + } + + public EcucData AddContainer(string bswmdPathShort) + { + return AddContainer(bswmdPathShort, RecommendedName(bswmdPathShort)); + } + + public EcucData AddContainer(string bswmdPathShort, string shortName) + { + if (Bswmd is IEcucBswmdModule bswmdContainerContainer && Instance is IEcucInstanceModule instanceContainerContainer) + { + foreach (var bswmd in bswmdContainerContainer.Containers) + { + if (bswmd.AsrPathShort == bswmdPathShort) + { + if (GetMultiplyStatus(bswmd.AsrPath).CanAdd == true) + { + switch (bswmd) + { + case EcucBswmdContainer: + { + var instance = instanceContainerContainer.AddContainer(bswmdPathShort, shortName); + RaisePropertyChanged(); + return new EcucData(instance, bswmd); + } + + case EcucBswmdChoiceContainer: + { + var instance = instanceContainerContainer.AddContainer(bswmdPathShort, shortName); + RaisePropertyChanged(); + return new EcucData(instance, bswmd); + } + + default: + throw new NotImplementedException(); + } + } + else + { + throw new Exception($"Can not add container due to upper limit"); + } + } + } + throw new Exception($"Unexpected bswmd path {bswmdPathShort}"); + } + else + { + throw new Exception($"Unexpected bswmd type {Bswmd.GetType()} or instance type {Instance.GetType()}"); + } + } + + public int DelContainer(string bswmdPathShort) + { + if (Bswmd is IEcucBswmdModule bswmdContainerContainer && Instance is IEcucInstanceModule instanceContainerContainer) + { + foreach (var bswmd in bswmdContainerContainer.Containers) + { + if (bswmd.AsrPathShort == bswmdPathShort) + { + if (bswmd.IsRequired == false) + { + RaisePropertyChanged(); + return instanceContainerContainer.DelContainer(bswmd.AsrPath); + } + else + { + throw new Exception($"Can not delete container due to this is a required container"); + } + } + } + throw new Exception($"Can not delete container due to invalid path {bswmdPathShort}"); + } + else + { + throw new Exception($"Unexpected bswmd type {Bswmd.GetType()} or instance type {Instance.GetType()}"); + } + } + + public int DelContainer(string bswmdPathShort, string shortName) + { + if (Bswmd is IEcucBswmdModule bswmdContainerContainer && Instance is IEcucInstanceModule instanceContainerContainer) + { + foreach (var bswmd in bswmdContainerContainer.Containers) + { + if (bswmd.AsrPathShort == bswmdPathShort) + { + if (GetMultiplyStatus(bswmd.AsrPath).CanRemove == true) + { + RaisePropertyChanged(); + return instanceContainerContainer.DelContainer(bswmd.AsrPath, shortName); + } + else + { + throw new Exception($"Can not delete container due to lower limit"); + } + } + } + throw new Exception($"Can not delete container due to invalid path {bswmdPathShort}"); + } + else + { + throw new Exception($"Unexpected bswmd type {Bswmd.GetType()} or instance type {Instance.GetType()}"); + } + } + + public EcucData AddContainerWithRequiredField(string bswmdPathShort) + { + return AddContainerWithRequiredField(bswmdPathShort, RecommendedName(bswmdPathShort)); + } + + public EcucData AddContainerWithRequiredField(string bswmdPathShort, string shortName) + { + if (Bswmd is IEcucBswmdModule bswmdContainerContainer && Instance is IEcucInstanceModule instanceContainerContainer) + { + foreach (var bswmd in bswmdContainerContainer.Containers) + { + if (bswmd.AsrPathShort == bswmdPathShort) + { + if (GetMultiplyStatus(bswmd.AsrPath).CanAdd == true) + { + + switch (bswmd) + { + case EcucBswmdContainer: + case EcucBswmdChoiceContainer: + var instance = instanceContainerContainer.AddContainer(bswmdPathShort, shortName); + var dataNew = new EcucData(instance, bswmd); + if (bswmd is EcucBswmdContainer bswmdContainer) + { + foreach (var bswmd2 in bswmdContainer.Containers) + { + if (bswmd2.IsRequired == true) + { + dataNew.AddContainerWithRequiredField(bswmd2.AsrPathShort, bswmd2.AsrPathShort); + } + } + foreach (var bswmd3 in bswmdContainer.Paras) + { + if (bswmd3.IsRequired == true) + { + switch (bswmd3) + { + case EcucBswmdEnumerationPara bswmdEnum: + dataNew.AddPara(bswmdEnum.AsrPathShort, bswmdEnum.Default); + break; + + case EcucBswmdIntegerPara bswmdIntegert: + dataNew.AddPara(bswmdIntegert.AsrPathShort, bswmdIntegert.Default.ToString()); + break; + + case EcucBswmdBooleanPara bswmdBoolean: + dataNew.AddPara(bswmdBoolean.AsrPathShort, bswmdBoolean.Default.ToString()); + break; + + case EcucBswmdFloatPara bswmdFloat: + dataNew.AddPara(bswmdFloat.AsrPathShort, bswmdFloat.Default.ToString()); + break; + + case EcucBswmdStringPara bswmdString: + if (bswmdString.Default.Count > 0) + { + dataNew.AddPara(bswmdString.AsrPathShort, bswmdString.Default[0]); + } + else + { + dataNew.AddPara(bswmdString.AsrPathShort, ""); + } + break; + + case EcucBswmdFunctionNamePara bswmdFunction: + dataNew.AddPara(bswmdFunction.AsrPathShort, bswmdFunction.Default[0]); + break; + + default: + throw new NotImplementedException(); + } + } + } + } + RaisePropertyChanged(); + return dataNew; + + default: + throw new NotImplementedException(); + } + } + else + { + throw new Exception($"Can not add container due to upper limit"); + } + } + } + throw new Exception($"Unexpected bswmd path {bswmdPathShort}"); + } + else + { + throw new Exception($"Unexpected bswmd type {Bswmd.GetType()} or instance type {Instance.GetType()}"); + } + } + + public List ContainerChain(Dictionary chain) + { + var result = new List(); + + if (Instance is IEcucInstanceModule instanceContainerContainer) + { + EcucData data = this; + foreach (var kvp in chain) + { + try + { + var instanceBase = instanceContainerContainer.GetInstanceFromAsrPath($"{instanceContainerContainer.AsrPath}/{kvp.Value}"); + if (instanceBase.BswmdPath == $"{Bswmd.AsrPath}/{kvp.Key}") + { + var bswmd = Bswmd.GetBswmdFromBswmdPath(instanceBase.BswmdPath); + if (bswmd != null) + { + data = new EcucData(instanceBase, bswmd); + result.Add(data); + } + } + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + data = data.AddContainer(kvp.Key, kvp.Value); + result.Add(data); + } + } + } + return result; + } + + public EcucData AddPara(string bswmdPathShort, string value) + { + if (Bswmd is IEcucBswmdContainer bswmdContainerContainer && Instance is IEcucInstanceContainer instanceContainerContainer) + { + foreach (var bswmd in bswmdContainerContainer.Paras) + { + if (bswmd.AsrPathShort == bswmdPathShort) + { + if (GetMultiplyStatus(bswmd.AsrPath).CanAdd == true) + { + if (instanceContainerContainer is EcucInstanceContainer instanceContainer) + { + switch (bswmd) + { + case EcucBswmdEnumerationPara bswmdEnum: + if (bswmdEnum.Candidate.Count > 0) + { + if (bswmdEnum.Candidate.Contains(value) == true) + { + var textualPara = instanceContainer.AddTextualPara(bswmdPathShort, value, "ECUC-ENUMERATION-PARAM-DEF"); + RaisePropertyChanged(); + return new EcucData(textualPara, bswmd); + } + else + { + throw new Exception($"Can not add Enumerate Parameter {bswmdPathShort} due to value {value} not in candidate"); + } + } + else + { + var textualPara = instanceContainer.AddTextualPara(bswmdPathShort, value, "ECUC-ENUMERATION-PARAM-DEF"); + RaisePropertyChanged(); + return new EcucData(textualPara, bswmd); + } + + case EcucBswmdIntegerPara bswmdIntegert: + if (BigInteger.TryParse(value, out BigInteger integer) == true) + { + if (bswmdIntegert.Max != null) + { + if (integer <= bswmdIntegert.Max && integer >= bswmdIntegert.Min) + { + var numericalPara = instanceContainer.AddNumericalPara(bswmdPathShort, value, "ECUC-INTEGER-PARAM-DEF"); + RaisePropertyChanged(); + return new EcucData(numericalPara, bswmd); + } + else + { + throw new Exception($"Can not add integer parameter {bswmdPathShort} due to beyond range, Max is {bswmdIntegert.Max}, Min is {bswmdIntegert.Min}, Value is {value}"); + } + } + else + { + if (integer >= bswmdIntegert.Min) + { + var numericalPara = instanceContainer.AddNumericalPara(bswmdPathShort, value, "ECUC-INTEGER-PARAM-DEF"); + RaisePropertyChanged(); + return new EcucData(numericalPara, bswmd); + } + else + { + throw new Exception($"Can not add integer parameter {bswmdPathShort} due to beyond range, Min is {bswmdIntegert.Min}, Value is {value}"); + } + } + } + else + { + throw new Exception($"Can not add Integer Parameter {bswmdPathShort} due to can not convert value {value}"); + } + + case EcucBswmdBooleanPara: + if (bool.TryParse(value, out _) == true) + { + var numericalPara = instanceContainer.AddNumericalPara(bswmdPathShort, value, "ECUC-BOOLEAN-PARAM-DEF"); + RaisePropertyChanged(); + return new EcucData(numericalPara, bswmd); + } + else + { + throw new Exception($"Can not add boolean parameter {bswmdPathShort} dut to can not convert {value} to boolean"); + } + + case EcucBswmdFloatPara: + if (Double.TryParse(value, out _) == true) + { + var numericalPara = instanceContainer.AddNumericalPara(bswmdPathShort, value, "ECUC-FLOAT-PARAM-DEF"); + RaisePropertyChanged(); + return new EcucData(numericalPara, bswmd); + } + else + { + throw new Exception($"Can not add float parameter {bswmdPathShort} dut to can not convert {value} to float"); + } + + case EcucBswmdStringPara: + { + var textualPara = instanceContainer.AddTextualPara(bswmdPathShort, value, "ECUC-STRING-PARAM-DEF"); + RaisePropertyChanged(); + return new EcucData(textualPara, bswmd); + } + + case EcucBswmdFunctionNamePara: + { + var textualPara = instanceContainer.AddTextualPara(bswmdPathShort, value, "ECUC-FUNCTION-NAME-DEF"); + RaisePropertyChanged(); + return new EcucData(textualPara, bswmd); + } + + default: + throw new NotImplementedException(); + } + } + else + { + throw new Exception($"Unexpected instance type {Instance.GetType()}"); + } + } + else + { + throw new Exception($"Can not add container due to upper limit"); + } + } + } + throw new Exception($"Unexpected bswmd path {bswmdPathShort}"); + } + else + { + throw new Exception($"Unexpected bswmd type {Bswmd.GetType()} or instance type {Instance.GetType()}"); + } + } + + public EcucData AddPara(string bswmdPathShort) + { + if (Bswmd is IEcucBswmdContainer bswmdContainerContainer && Instance is IEcucInstanceContainer instanceContainerContainer) + { + foreach (var bswmd in bswmdContainerContainer.Paras) + { + if (bswmd.AsrPathShort == bswmdPathShort) + { + if (GetMultiplyStatus(bswmd.AsrPath).CanAdd == true) + { + if (instanceContainerContainer is EcucInstanceContainer instanceContainer) + { + switch (bswmd) + { + case EcucBswmdEnumerationPara bswmdEnum: + { + var textualPara = instanceContainer.AddTextualPara(bswmdPathShort, bswmdEnum.Default, "ECUC-ENUMERATION-PARAM-DEF"); + RaisePropertyChanged(); + return new EcucData(textualPara, bswmd); + } + + case EcucBswmdIntegerPara bswmdIntegert: + { + var numericalPara = instanceContainer.AddNumericalPara(bswmdPathShort, bswmdIntegert.Default.ToString(), "ECUC-INTEGER-PARAM-DEF"); + RaisePropertyChanged(); + return new EcucData(numericalPara, bswmd); + } + + case EcucBswmdBooleanPara BswmdBoolean: + { + var numericalPara = instanceContainer.AddNumericalPara(bswmdPathShort, BswmdBoolean.Default.ToString(), "ECUC-BOOLEAN-PARAM-DEF"); + RaisePropertyChanged(); + return new EcucData(numericalPara, bswmd); + } + + case EcucBswmdFloatPara BswmdFloat: + { + var numericalPara = instanceContainer.AddNumericalPara(bswmdPathShort, BswmdFloat.Default.ToString(), "ECUC-FLOAT-PARAM-DEF"); + RaisePropertyChanged(); + return new EcucData(numericalPara, bswmd); + } + + case EcucBswmdStringPara BswmdString: + { + var textualPara = instanceContainer.AddTextualPara(bswmdPathShort, BswmdString.Default[0], "ECUC-STRING-PARAM-DEF"); + RaisePropertyChanged(); + return new EcucData(textualPara, bswmd); + } + + case EcucBswmdFunctionNamePara BswmdFunction: + { + var textualPara = instanceContainer.AddTextualPara(bswmdPathShort, BswmdFunction.Default[0], "ECUC-FUNCTION-NAME-DEF"); + RaisePropertyChanged(); + return new EcucData(textualPara, bswmd); + } + + default: + throw new NotImplementedException(); + } + } + else + { + throw new Exception($"Unexpected instance type {Instance.GetType()}"); + } + } + else + { + throw new Exception($"Can not add container due to upper limit"); + } + } + } + throw new Exception($"Unexpected bswmd path {bswmdPathShort}"); + } + else + { + throw new Exception($"Unexpected bswmd type {Bswmd.GetType()} or instance type {Instance.GetType()}"); + } + } + + public List ParaChain(Dictionary chain) + { + var result = new List(); + + foreach (var kvp in chain) + { + result.Add(AddPara(kvp.Key, kvp.Value)); + } + return result; + } + + public void DelPara(string bswmdPathShort, string value) + { + if (Bswmd is IEcucBswmdContainer bswmdOtherContainer && Instance is IEcucInstanceContainer instanceOtherContainer) + { + foreach (var bswmd in bswmdOtherContainer.Paras) + { + if (bswmd.AsrPathShort == bswmdPathShort) + { + if (GetMultiplyStatus(bswmd.AsrPath).CanRemove == true) + { + if (instanceOtherContainer is EcucInstanceContainer instanceContainer) + { + switch (bswmd) + { + case EcucBswmdEnumerationPara: + instanceContainer.DelTextualPara(bswmdPathShort, value); + break; + + case EcucBswmdIntegerPara: + instanceContainer.DelNumericalPara(bswmdPathShort, value); + break; + + case EcucBswmdBooleanPara: + instanceContainer.DelNumericalPara(bswmdPathShort, value); + break; + + case EcucBswmdFloatPara: + instanceContainer.DelNumericalPara(bswmdPathShort, value); + break; + + case EcucBswmdStringPara: + instanceContainer.DelTextualPara(bswmdPathShort, value); + break; + + case EcucBswmdFunctionNamePara: + instanceContainer.DelTextualPara(bswmdPathShort, value); + break; + + default: + throw new NotImplementedException(); + } + } + else + { + throw new Exception($"Unexpected instance type {Instance.GetType()}"); + } + } + } + } + RaisePropertyChanged(); + } + } + + public void DelPara(string bswmdPath) + { + if (Bswmd is IEcucBswmdContainer bswmdOtherContainer && Instance is IEcucInstanceContainer instanceOtherContainer) + { + foreach (var bswmd in bswmdOtherContainer.Paras) + { + if (bswmd.AsrPathShort == bswmdPath) + { + if (bswmd.IsRequired == false) + { + if (instanceOtherContainer is EcucInstanceContainer instanceContainer) + { + switch (bswmd) + { + case EcucBswmdEnumerationPara: + instanceContainer.DelTextualPara(bswmdPath); + break; + + case EcucBswmdIntegerPara: + instanceContainer.DelNumericalPara(bswmdPath); + break; + + case EcucBswmdBooleanPara: + instanceContainer.DelNumericalPara(bswmdPath); + break; + + case EcucBswmdFloatPara: + instanceContainer.DelNumericalPara(bswmdPath); + break; + + case EcucBswmdStringPara: + instanceContainer.DelTextualPara(bswmdPath); + break; + + case EcucBswmdFunctionNamePara: + instanceContainer.DelTextualPara(bswmdPath); + break; + + default: + throw new NotImplementedException(); + } + } + else + { + throw new Exception($"Unexpected instance type {Instance.GetType()}"); + } + } + } + } + RaisePropertyChanged(); + } + } + + public EcucData AddRef(string bswmdPathShort, string value, string typ = "") + { + if (Bswmd is IEcucBswmdContainer bswmdOtherContainer && Instance is IEcucInstanceContainer instanceOtherContainer) + { + foreach (var bswmd in bswmdOtherContainer.Refs) + { + if (bswmd.AsrPathShort == bswmdPathShort) + { + if (GetMultiplyStatus(bswmd.AsrPath).CanAdd == true) + { + if (instanceOtherContainer is EcucInstanceContainer instanceContainer) + { + switch (bswmd) + { + case EcucBswmdRef bswmdRef: + { + var reference = instanceContainer.AddReference(bswmdPathShort, "ECUC-REFERENCE-DEF", value, bswmdRef.Dest); + RaisePropertyChanged(); + return new EcucData(reference, bswmd); + } + + case EcucBswmdForeignRef bswmdForeign: + { + var reference = instanceContainer.AddReference(bswmdPathShort, "ECUC-FOREIGN-REFERENCE-DEF", value, bswmdForeign.DestType); + RaisePropertyChanged(); + return new EcucData(reference, bswmd); + } + + case EcucBswmdSymbolicNameRef bswmdSymbolic: + { + var reference = instanceContainer.AddReference(bswmdPathShort, "ECUC-SYMBOLIC-NAME-REFERENCE-DEF", value, bswmdSymbolic.Dest); + RaisePropertyChanged(); + return new EcucData(reference, bswmd); + } + + case EcucBswmdChoiceRef bswmdChoice: + { + foreach (var choice in bswmdChoice.Choices) + { + if (typ == choice.Key) + { + var reference = instanceContainer.AddReference(bswmdPathShort, choice.Value, value, choice.Key); + RaisePropertyChanged(); + return new EcucData(reference, bswmd); + } + } + throw new Exception($"Unexpected input type {typ}"); + } + + default: + throw new NotImplementedException(); + } + } + else + { + throw new Exception($"Unexpected instance type {Instance.GetType()}"); + } + } + else + { + throw new Exception($"Can not add container due to upper limit"); + } + } + } + throw new Exception($"Unexpected bswmd path {bswmdPathShort}"); + } + else + { + throw new Exception($"Unexpected bswmd type {Bswmd.GetType()} or instance type {Instance.GetType()}"); + } + } + + public List RefChain(Dictionary chain) + { + var result = new List(); + + foreach (var kvp in chain) + { + result.Add(AddRef(kvp.Key, kvp.Value)); + } + return result; + } + + public EcucData DeRef() + { + if (Instance is EcucInstanceReferenceValue instanceRef) + { + var referenced = Instance.GetInstanceFromAsrPath(instanceRef.ValueRef); + + if (referenced != null) + { + var bswmd = Bswmd.GetBswmdFromBswmdPath(referenced.BswmdPath); + if (bswmd != null) + { + return new EcucData(referenced, bswmd); + } + } + } + throw new Exception($"Can not dereference"); + } + + public void DelRef(string bswmdPathShort, string valueRef) + { + if (Bswmd is IEcucBswmdContainer bswmdOtherContainer && Instance is IEcucInstanceContainer instanceOtherContainer) + { + foreach (var bswmd in bswmdOtherContainer.Refs) + { + if (bswmd.AsrPathShort == bswmdPathShort) + { + if (GetMultiplyStatus(bswmd.AsrPath).CanRemove == true) + { + if (instanceOtherContainer is EcucInstanceContainer instanceContainer) + { + switch (bswmd) + { + case EcucBswmdRef: + instanceContainer.DelReference(bswmdPathShort, valueRef); + break; + + + case EcucBswmdForeignRef: + instanceContainer.DelReference(bswmdPathShort, valueRef); + break; + + + case EcucBswmdSymbolicNameRef: + instanceContainer.DelReference(bswmdPathShort, valueRef); + break; + + case EcucBswmdChoiceRef: + instanceContainer.DelReference(bswmdPathShort, valueRef); + break; + + default: + throw new NotImplementedException(); + }; + } + else + { + throw new Exception($"Unexpected instance type {Instance.GetType()}"); + } + } + else + { + throw new Exception($"Can not delete container due to lower limit"); + } + } + } + RaisePropertyChanged(); + } + else + { + throw new Exception($"Unexpected bswmd type {Bswmd.GetType()} or instance type {Instance.GetType()}"); + } + } + + public void DelRef(string bswmdPath) + { + if (Bswmd is IEcucBswmdContainer bswmdOtherContainer && Instance is IEcucInstanceContainer instanceOtherContainer) + { + foreach (var bswmd in bswmdOtherContainer.Refs) + { + if (bswmd.AsrPathShort == bswmdPath) + { + if (bswmd.IsRequired == false) + { + if (instanceOtherContainer is EcucInstanceContainer instanceContainer) + { + switch (bswmd) + { + case EcucBswmdRef: + instanceContainer.DelReference(bswmdPath); + break; + + + case EcucBswmdForeignRef: + instanceContainer.DelReference(bswmdPath); + break; + + + case EcucBswmdSymbolicNameRef: + instanceContainer.DelReference(bswmdPath); + break; + + case EcucBswmdChoiceRef: + instanceContainer.DelReference(bswmdPath); + break; + + default: + throw new NotImplementedException(); + }; + } + else + { + throw new Exception($"Unexpected instance type {Instance.GetType()}"); + } + } + else + { + throw new Exception($"Can not delete container due to lower limit"); + } + } + } + RaisePropertyChanged(); + } + else + { + throw new Exception($"Unexpected bswmd type {Bswmd.GetType()} or instance type {Instance.GetType()}"); + } + } + + public EcucDataMultiplyStatus GetMultiplyStatus(string bswmdPath) + { + EcucDataMultiplyStatus.StatusType result = EcucDataMultiplyStatus.StatusType.Invalid; + try + { + var bswmd = Bswmd.GetBswmdFromBswmdPath(bswmdPath); + int count = 0; + + switch (bswmd) + { + case IEcucBswmdModule: + { + var instances = InstanceAsModule.FindContainerByBswmd(bswmdPath); + count = instances.Count; + } + break; + + case IEcucBswmdParam: + { + var instances = InstanceAsContainer.FindParaByBswmd(bswmdPath); + count = instances.Count; + } + break; + + case IEcucBswmdReference: + { + var instances = InstanceAsContainer.FindRefByBswmd(bswmdPath); + count = instances.Count; + } + break; + + default: + break; + } + + if (count == 0) + { + result |= EcucDataMultiplyStatus.StatusType.Empty; + } + + if (count == bswmd.Upper) + { + result |= EcucDataMultiplyStatus.StatusType.OkUpper; + } + + if (count < bswmd.Lower) + { + result |= EcucDataMultiplyStatus.StatusType.Lack; + } + else if (count == bswmd.Lower) + { + result |= EcucDataMultiplyStatus.StatusType.OkLower; + } + else if (count < bswmd.Upper) + { + result |= EcucDataMultiplyStatus.StatusType.OkMiddle; + } + else + { + result |= EcucDataMultiplyStatus.StatusType.Overflow; + } + } + catch + { + result = EcucDataMultiplyStatus.StatusType.Invalid; + } + + return new EcucDataMultiplyStatus(result); + } + + void PropertyChangedEventHandler(object? sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == "Valid") + { + RaisePropertyChanged(nameof(ValidStatus)); + } + } + + public void UpdateValidStatus(bool v, string vReason = "") + { + Instance.Valid.UpdateData(this); + Instance.Valid.UpdateValidStatus(v, vReason); + } + + public void UpdateValidSolve(string desc, EcucSolveHandler handler, object? param=null) + { + Instance.Valid.UpdateSolve(desc, handler, param); + } + + public void UpdateValidSolve(List solves) + { + Instance.Valid.UpdateSolve(solves); + } + + public void ClearValidSolve() + { + Instance.Valid.ClearSolve(); + } + } + + public class EcucDataList : List + { + /// + /// Wheter data is valid. + /// + public bool ValidStatus + { + get + { + // iterate all data in datas checking Invalid + foreach (var data in this) + { + if (data.ValidStatus == false) + { + return false; + } + } + return true; + } + } + + public string ValidInfo + { + get + { + string result = ""; + foreach (var data in this) + { + result += data.ValidInfo; + } + return result; + } + } + + public List AsrPath + { + get + { + var result = new List(); + foreach (var data in this) + { + result.Add(data.AsrPath); + } + return result; + } + } + + public List AsrPathShort + { + get + { + var result = new List(); + foreach (var data in this) + { + result.Add(data.AsrPathShort); + } + return result; + } + } + + public EcucDataList this[string key] + { + get + { + var result = new EcucDataList(); + foreach (var data in this) + { + var bswmdGet = data.GetBswmdFromBswmdPath($"{data.BswmdPath}/{key}"); + switch (bswmdGet) + { + case IEcucBswmdModule: + { + var query = from container in data.Containers + where container.BswmdPathShort == key + select container; + + query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet))); + } + break; + + case IEcucBswmdParam: + { + var query = from para in data.Paras + where para.BswmdPathShort == key + select para; + + query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet))); + } + break; + + case IEcucBswmdReference: + { + var query = from reference in data.Refs + where reference.BswmdPathShort == key + select reference; + + query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet))); + } + break; + + default: + break; + } + } + + return result; + } + } + + public EcucDataList this[string key, string name] + { + get + { + var result = new EcucDataList(); + foreach (var data in this) + { + var bswmdGet = data.GetBswmdFromBswmdPath($"{data.BswmdPath}/{key}"); + switch (bswmdGet) + { + case IEcucBswmdModule: + { + var query = from container in data.Containers + where container.BswmdPathShort == key + where container.ShortName == name + select container; + + query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet))); + } + break; + + case IEcucBswmdParam: + { + var query = from para in data.Paras + where para.BswmdPathShort == key + where para.Value == name + select para; + + query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet))); + } + break; + + case IEcucBswmdReference: + { + var query = from reference in data.Refs + where reference.BswmdPathShort == key + where reference.ValueRefShort == name + select reference; + + query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet))); + } + break; + + default: + break; + } + } + + return result; + } + } + + public delegate bool SearchFunc(EcucData data); + public EcucDataList this[string key, SearchFunc func] + { + get + { + var result = new EcucDataList(); + foreach (var data in this) + { + var bswmdGet = data.GetBswmdFromBswmdPath($"{data.BswmdPath}/{key}"); + switch (bswmdGet) + { + case IEcucBswmdModule: + { + var query = from container in data.Containers + where container.BswmdPathShort == key + where func(new EcucData(container, bswmdGet)) + select container; + + query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet))); + } + break; + + case IEcucBswmdParam: + { + var query = from para in data.Paras + where para.BswmdPathShort == key + where func(new EcucData(para, bswmdGet)) + select para; + + query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet))); + } + break; + + case IEcucBswmdReference: + { + var query = from reference in data.Refs + where reference.BswmdPathShort == key + where func(new EcucData(reference, bswmdGet)) + select reference; + + query.ToList().ForEach(x => result.Add(new EcucData(x, bswmdGet))); + } + break; + + default: + break; + } + } + + return result; + } + } + + public EcucDataList() + { + + } + + public EcucDataList(List datas) + { + foreach (var data in datas) + { + Add(data); + } + } + + public List Value + { + get + { + var result = new List(); + foreach (var data in this) + { + result.Add(data.Value); + } + return result; + } + set + { + if (value != null) + { + if (value.Count == Count) + { + for (int i = 0; i < Count; i++) + { + this[i].Value = value[i]; + } + } + } + } + } + + public bool ValueSingleEqual(string value) + { + if (Value.Count == 1) + { + return Value[0] == value; + } + return false; + } + + public EcucData First + { + get + { + if (Count > 0) + { + return this[0]; + } + else + { + throw new Exception($"There is no data inside"); + } + } + } + + public string FirstValue + { + get + { + if (Count > 0) + { + return this[0].Value; + } + else + { + throw new Exception($"There is no text inside"); + } + } + set + { + if (value != null) + { + if (Count > 0) + { + this[0].Value = value; + } + } + } + } + + public Int64 FirstValueAsInt + { + get + { + if (Count > 0) + { + return this[0].ValueAsInt; + } + else + { + throw new Exception($"There is no integer inside"); + } + } + set + { + if (Count > 0) + { + this[0].ValueAsInt = value; + } + } + } + + public EcucDataList DeRef() + { + var result = new EcucDataList(); + + foreach (var data in this) + { + var referenced = data.DeRef(); + + if (referenced != null) + { + result.Add(referenced); + } + } + return result; + } + + public EcucDataMultiplyStatus GetMultiplyStatus(IEcucBswmdBase bswmd) + { + EcucDataMultiplyStatus.StatusType result = EcucDataMultiplyStatus.StatusType.Invalid; + + try + { + if (bswmd.Upper == 0) + { + result = EcucDataMultiplyStatus.StatusType.Invalid; + } + else + { + if (Count == 0) + { + result |= EcucDataMultiplyStatus.StatusType.Empty; + } + + if (Count == bswmd.Upper) + { + result |= EcucDataMultiplyStatus.StatusType.OkUpper; + } + + if (Count < bswmd.Lower) + { + result |= EcucDataMultiplyStatus.StatusType.Lack; + } + else if (Count == bswmd.Lower) + { + result |= EcucDataMultiplyStatus.StatusType.OkLower; + } + else if (Count < bswmd.Upper) + { + result |= EcucDataMultiplyStatus.StatusType.OkMiddle; + } + else if (Count > bswmd.Upper) + { + result |= EcucDataMultiplyStatus.StatusType.Overflow; + } + } + } + catch + { + result = EcucDataMultiplyStatus.StatusType.Invalid; + } + + return new EcucDataMultiplyStatus(result); + } + } +} diff --git a/EcucBase/EcucInstance.cs b/EcucBase/EcucInstance.cs new file mode 100644 index 0000000..c98cece --- /dev/null +++ b/EcucBase/EcucInstance.cs @@ -0,0 +1,2166 @@ +/* + * This file is a part of Autosar Configurator for ECU GUI based + * configuration, checking and code generation. + * + * Copyright (C) 2021-2022 DJS Studio E-mail:DD-Silence@sina.cn + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +using Ecuc.EcucBase.EBase; +using Autosar; +using System.ComponentModel; + +namespace Ecuc.EcucBase.EInstance +{ + public class CommentGroup + { + public SDG Model { get; } + + public string Name + { + get + { + return Model.Untyped.Value; + } + } + + public CommentGroupList Groups + { + get + { + return new CommentGroupList(Model.SDG1); + } + } + + public Dictionary Data + { + get + { + var result = new Dictionary(); + + foreach (var sd in Model.SD) + { + result[sd.GID] = sd.Untyped.Value; + } + return result; + } + } + + public Dictionary Ref + { + get + { + var result = new Dictionary(); + + foreach (var sd in Model.SDXREF) + { + result[sd.Untyped.Value] = sd.DEST; + } + return result; + } + } + + public CommentGroup(SDG model) + { + Model = model; + } + + public CommentGroup this[string name] + { + get + { + try + { + return Groups[name]; + } + catch + { + throw new Exception($"Fail to get comment {name}"); + } + } + set + { + Groups[name] = value; + } + } + + public string GetCommentByName(string name) + { + try + { + return Data[name]; + } + catch + { + throw new Exception($"Can not get comment {name}"); + } + } + + public void SetCommentByName(string name, string value) + { + var sdNew = new SD + { + GID = name + }; + sdNew.Untyped.Value = value; + Model.SD.Add(sdNew); + } + } + + public class CommentGroupList : List + { + public IList Model { get; } + + public CommentGroupList() + { + Model = new List(); + } + + public CommentGroupList(IList model) + { + Model = model; + foreach (var m in Model) + { + Add(new CommentGroup(m)); + } + } + + public CommentGroup this[string name] + { + get + { + foreach (var sdg in Model) + { + if (sdg.GID == name) + { + return new CommentGroup(sdg); + } + } + throw new Exception($"Fail to get comment group {name}"); + } + set + { + if (value == null) + { + return; + } + + foreach (var sdg in Model) + { + if (sdg.GID == name) + { + return; + } + } + + Add(value); + } + } + } + + public interface IEcucInstanceBase : INotifyPropertyChanged + { + string BswmdPath { get; } + string BswmdPathShort + { + get + { + var parts = BswmdPath.Split('/'); + if (parts.Length > 0) + { + return parts[^1]; + } + return ""; + } + } + + EcucInstanceManager Manager { get; } + + IEcucInstanceBase GetInstanceFromAsrPath(string path) + { + try + { + return Manager.AsrPathInstanceDict[path]; + } + catch + { + throw new Exception($"Can not get isntance from {path}"); + } + } + + List GetReferenceByAsrPath(string path) + { + try + { + return Manager.InstanceReferenceDict[path]; + } + catch + { + throw new Exception($"Can not get reference from {path}"); + } + } + + bool IsDirty { get; set; } + EcucValid Valid { get; } + } + + public interface IEcucInstanceModule : IEcucInstanceBase + { + string ShortName { get; set; } + string AsrPath { get; } + string AsrPathShort { get; } + List Containers { get; } + CommentGroupList Comment { get; set; } + + EcucInstanceContainer AddContainer(string path, string shortName); + int DelContainer(string path, string shortName); + int DelContainer(string path); + void DelContainer(); + void UpdateAsrPathShort(string newName); + void UpdateAsrPathPrefix(string newName); + + List FindContainerByBswmd(string bswmdPath) + { + if (bswmdPath == "") + { + return Containers; + } + else + { + var query = from container in Containers + where container.BswmdPath == bswmdPath + select container; + + return query.ToList(); + } + } + } + + public interface IEcucInstanceContainer : IEcucInstanceModule + { + List Paras { get; } + List Refs { get; } + IEcucInstanceModule Parent { get; } + + List FindParaByBswmd(string bswmdPath) + { + var query = from para in Paras + where para.BswmdPath == bswmdPath + select para; + + return query.ToList(); + } + + List FindRefByBswmd(string bswmdPath) + { + var query = from reference in Refs + where reference.BswmdPath == bswmdPath + select reference; + + return query.ToList(); + } + } + + public interface IEcucInstanceParam : IEcucInstanceBase + { + IEcucInstanceModule Parent { get; } + string Value { get; set; } + public List Comment { get; set; } + } + + public interface IEcucInstanceReference : IEcucInstanceBase + { + IEcucInstanceModule Parent { get; } + string ValueRef { get; set; } + string ValueRefShort + { + get + { + var parts = ValueRef.Split('/'); + if (parts.Length > 0) + { + return parts[^1]; + } + return ""; + } + set + { + var ValueRefOld = ValueRef; + var parts = ValueRef.Split('/'); + if (parts.Length > 0) + { + if (parts[^1] != value) + { + parts[^1] = value; + ValueRef = string.Join("/", parts); + Manager.InstanceReferenceDict[ValueRef] = Manager.InstanceReferenceDict[ValueRefOld]; + Manager.InstanceReferenceDict.Remove(ValueRefOld); + } + } + } + } + public List Comment { get; set; } + } + + public class EcucInstanceManager + { + private readonly List Autosars = new(); + public List EcucModules { get; } = new(); + public Dictionary AsrRawAsrPathDict = new(); + public Dictionary AsrPathAsrRawDict = new(); + public Dictionary> BswmdPathInstanceDict = new(); + public Dictionary AsrPathInstanceDict = new(); + public Dictionary> InstanceReferenceDict = new(); + public Dictionary FileAsrRawDict = new(); + private bool isDirty = false; + + public bool IsDirty + { + get + { + return isDirty; + } + set + { + if (value != IsDirty) + { + isDirty = value; + } + } + } + + public EcucInstanceManager(string content) + { + InitSingle(content); + } + + public EcucInstanceManager(string[] fileNames) + { + InitMultiple(fileNames); + var query = from module in EcucModules + orderby module.ShortName ascending + select module; + EcucModules = query.ToList(); + } + + private void InitSingle(string content) + { + var autosar = new Asr(content); + Autosars.Add(autosar); + List arPackages = new(); + foreach (var package in autosar.ArPackages) + { + arPackages.Add(package); + } + + foreach (var value in autosar.AsrPathModelDict) + { + AsrPathAsrRawDict[value.Key] = value.Value; + AsrRawAsrPathDict[value.Value] = value.Key; + } + + Monitor.Enter(EcucModules); + try + { + var query = from package in arPackages + where package.ELEMENTS?.ECUCMODULECONFIGURATIONVALUES != null + from ecucModuleValue in package.ELEMENTS.ECUCMODULECONFIGURATIONVALUES + select ecucModuleValue; + + query.ToList().ForEach(x => EcucModules.Add(new EcucInstanceModule(x, this, autosar))); + } + finally + { + Monitor.Exit(EcucModules); + } + } + + private void InitMultiple(string[] fileNames) + { + var tasks = new Task[fileNames.Length]; + + for (int i = 0; i < fileNames.Length; i++) + { + tasks[i] = InitMultipleSingleStep1(fileNames[i]); + } + Task.WaitAll(tasks); + + tasks = new Task[Autosars.Count]; + for (int i = 0; i < Autosars.Count; i++) + { + tasks[i] = InitMultipleSingleStep2(Autosars[i]); + } + Task.WaitAll(tasks); + + for (int i = 0; i < Autosars.Count; i++) + { + tasks[i] = InitMultipleSingleStep3(Autosars[i]); + } + Task.WaitAll(tasks); + } + + private Task InitMultipleSingleStep1(string fileName) + { + return Task.Run(() => + { + var autosar = new Asr(fileName); + Monitor.Enter(Autosars); + try + { + Autosars.Add(autosar); + } + finally + { + Monitor.Exit(Autosars); + } + }); + } + + private Task InitMultipleSingleStep2(Asr ar) + { + return Task.Run(() => + { + Monitor.Enter(AsrRawAsrPathDict); + try + { + foreach (var value in ar.AsrPathModelDict) + { + if (AsrPathAsrRawDict.ContainsKey(value.Key) == false) + { + AsrPathAsrRawDict[value.Key] = value.Value; + AsrRawAsrPathDict[value.Value] = value.Key; + } + } + } + finally + { + Monitor.Exit(AsrRawAsrPathDict); + } + }); + } + + private Task InitMultipleSingleStep3(Asr ar) + { + return Task.Run(() => + { + Monitor.Enter(EcucModules); + try + { + var query = from package in ar.ArPackages + where package.ELEMENTS.ECUCMODULECONFIGURATIONVALUES != null + from ecucModuleValue in package.ELEMENTS.ECUCMODULECONFIGURATIONVALUES + select ecucModuleValue; + + query.ToList().ForEach(x => + { + var module = new EcucInstanceModule(x, this, ar); + EcucModules.Add(module); + ar.Modules.Add(module); + }); + } + finally + { + Monitor.Exit(EcucModules); + } + }); + } + + public List GetInstancesByBswmdPath(string bswmdPath) + { + var result = new List(); + + if (BswmdPathInstanceDict.ContainsKey(bswmdPath)) + { + result = BswmdPathInstanceDict[bswmdPath]; + } + return result; + } + + public IEcucInstanceBase GetInstanceByAsrPath(string path) + { + try + { + return AsrPathInstanceDict[path]; + } + catch + { + throw new Exception($"Can not get isntance from {path}"); + } + } + + public List GetReferenceByAsrPath(string path) + { + try + { + return InstanceReferenceDict[path]; + } + catch + { + throw new Exception($"Can not get reference from {path}"); + } + } + + public EcucInstanceModule? this[string name] + { + get + { + var query = from module in EcucModules + where module.ShortName == name + select module; + + var result = query.ToList(); + if (result.Count > 0) + { + return result[0]; + } + else + { + return null; + } + } + } + + public void Save() + { + var query = from asr in Autosars + where asr.IsDirty == true + select asr; + + var result = query.ToList(); + + var tasks = new Task[result.Count]; + + for (int i = 0; i < result.Count; i++) + { + tasks[i] = SaveSingle(result[i]); + } + Task.WaitAll(tasks); + } + + private static Task SaveSingle(Asr asr) + { + return Task.Run(() => + { + asr.Save(); + }); + } + + /// + /// Add object with name to dictionary. + /// + /// + /// + public void AddAsrPath(string name, object model) + { + AsrPathAsrRawDict[name] = model; + AsrRawAsrPathDict[model] = name; + if (model is IEcucInstanceBase instance) + { + AsrPathInstanceDict[name] = instance; + } + } + + public void RemoveAsrPath(string name, object model) + { + AsrPathAsrRawDict.Remove(name); + AsrRawAsrPathDict.Remove(model); + } + } + + public class EcucInstanceModule : NotifyPropertyChangedBase, IEcucInstanceModule + { + private ECUCMODULECONFIGURATIONVALUES Model { get; } + public EcucInstanceManager Manager { get; } + public Asr Parent { get; } + public EcucValid Valid { get; set; } + + private bool isDirty = false; + + public bool IsDirty + { + get + { + return isDirty; + } + set + { + if (value != IsDirty) + { + isDirty = value; + + if (isDirty == true) + { + Parent.IsDirty = true; + } + else + { + foreach (var container in Containers) + { + container.IsDirty = false; + } + } + } + } + } + + public CommentGroupList Comment + { + get + { + if (Model.ADMINDATA == null) + { + return new CommentGroupList(); + } + + if (Model.ADMINDATA.SDGS == null) + { + return new CommentGroupList(); + } + + return new CommentGroupList(Model.ADMINDATA.SDGS.SDG); + } + set + { + if (value == null) + { + return; + } + + if (value.Count == 0) + { + return; + } + + if (Model.ADMINDATA == null) + { + Model.ADMINDATA = new ADMINDATA(); + } + + if (Model.ADMINDATA.SDGS == null) + { + Model.ADMINDATA.SDGS = new ADMINDATA.SDGSLocalType(); + } + + foreach (var item in value) + { + Model.ADMINDATA.SDGS.SDG.Add(item.Model); + } + } + } + + public string BswmdPath + { + get + { + return Model.DEFINITIONREF.TypedValue; + } + } + + public string ShortName + { + get + { + return Model.SHORTNAME.TypedValue; + } + set + { + if (value != null) + { + if (ShortName != value) + { + // cache old autosar path + var asrPathOld = AsrPath; + var parts = asrPathOld.Split('/'); + if (parts.Length > 0) + { + // add new path to dict + UpdateAsrPathShort(value); + // autosar model modify + Model.SHORTNAME.TypedValue = value; + } + } + } + } + } + + public string AsrPath + { + get + { + return Manager.AsrRawAsrPathDict[Model]; + } + } + + public string AsrPathShort + { + get + { + var parts = AsrPath.Split('/'); + if (parts.Length > 0) + { + return parts[^1]; + } + return ""; + } + } + + public List Containers { get; } = new List(); + + public EcucInstanceModule(ECUCMODULECONFIGURATIONVALUES model, EcucInstanceManager manager, Asr parent) + { + Model = model; + Manager = manager; + Parent = parent; + Valid = new EcucValid(this); + Valid.PropertyChanged += ValidChangedEventHandler; + + Monitor.Enter(Manager.BswmdPathInstanceDict); + try + { + if (Manager.BswmdPathInstanceDict.ContainsKey(BswmdPath)) + { + Manager.BswmdPathInstanceDict[BswmdPath].Add(this); + } + else + { + Manager.BswmdPathInstanceDict[BswmdPath] = new List() { this }; + } + } + finally + { + Monitor.Exit(Manager.BswmdPathInstanceDict); + } + + Monitor.Enter(Manager.AsrPathInstanceDict); + try + { + Manager.AsrPathInstanceDict[AsrPath] = this; + } + finally + { + Monitor.Exit(Manager.AsrPathInstanceDict); + } + + if (Model.CONTAINERS != null) + { + if (Model.CONTAINERS.ECUCCONTAINERVALUE != null) + { + foreach (ECUCCONTAINERVALUE container in Model.CONTAINERS.ECUCCONTAINERVALUE) + { + Containers.Add(new EcucInstanceContainer(container, Manager, this)); + } + } + } + } + + public EcucInstanceContainer AddContainer(string path, string shortName) + { + var model = new ECUCCONTAINERVALUE + { + DEFINITIONREF = new ECUCCONTAINERVALUE.DEFINITIONREFLocalType + { + DEST = "ECUC-PARAM-CONF-CONTAINER-DEF", + TypedValue = $"{BswmdPath}/{path}" + }, + SHORTNAME = new IDENTIFIER + { + TypedValue = shortName + }, + UUID = Guid.NewGuid().ToString() + }; + + if (Manager.AsrPathAsrRawDict.ContainsKey($"{AsrPath}/{shortName}") == false) + { + if (Model.CONTAINERS == null) + { + Model.CONTAINERS = new ECUCMODULECONFIGURATIONVALUES.CONTAINERSLocalType(); + } + Model.CONTAINERS.ECUCCONTAINERVALUE.Add(model); + Manager.AddAsrPath($"{AsrPath}/{shortName}", model); + var newContainer = new EcucInstanceContainer(model, Manager, this); + Containers.Add(newContainer); + IsDirty = true; + return newContainer; + } + else + { + throw new Exception($"Find duplicate container {shortName} when add continer"); + } + } + + public int DelContainer(string path, string shortName) + { + foreach (var container in Containers) + { + if (container.BswmdPath == path && container.ShortName == shortName) + { + if (container is EcucInstanceContainer instanceContainer) + { + Manager.RemoveAsrPath(instanceContainer.AsrPath, instanceContainer); + Model.CONTAINERS.ECUCCONTAINERVALUE.Remove(instanceContainer.Model); + IsDirty = true; + + if (container.Containers.Count > 0) + { + if (container is EcucInstanceContainer instanceContainer2) + { + instanceContainer2.DelContainer(); + } + } + } + } + } + + Containers.RemoveAll(x => x.BswmdPath == path && x.ShortName == shortName); + return Containers.FindAll(x => x.BswmdPath == path).Count; + } + + public int DelContainer(string path) + { + foreach (var container in Containers) + { + if (container.BswmdPathShort == path) + { + if (container is EcucInstanceContainer instanceContainer) + { + Manager.RemoveAsrPath(instanceContainer.AsrPath, instanceContainer); + Model.CONTAINERS.ECUCCONTAINERVALUE.Remove(instanceContainer.Model); + IsDirty = true; + + if (container.Containers.Count > 0) + { + if (container is EcucInstanceContainer instanceContainer2) + { + instanceContainer2.DelContainer(); + } + } + } + } + } + + Containers.RemoveAll(x => x.BswmdPath == path); + return Containers.FindAll(x => x.BswmdPath == path).Count; + } + + public void DelContainer() + { + foreach (var container in Containers) + { + if (container is EcucInstanceContainer instanceContainer) + { + Manager.RemoveAsrPath(instanceContainer.AsrPath, instanceContainer); + Model.CONTAINERS.ECUCCONTAINERVALUE.Remove(instanceContainer.Model); + IsDirty = true; + + if (container.Containers.Count > 0) + { + if (container is EcucInstanceContainer instanceContainer2) + { + instanceContainer2.DelContainer(); + } + } + } + } + Containers.RemoveAll(x => x.BswmdPath != ""); + } + + /// + /// Update autosar path dictionary of container + /// + /// New short name of container + public void UpdateAsrPathShort(string newName) + { + // Construct new autosar path + var asrPathOld = AsrPath; + var parts = AsrPath.Split("/"); + parts[^1] = newName; + var asrPathNew = string.Join("/", parts); + + // Check name duplication + if (Manager.AsrPathAsrRawDict.ContainsKey(asrPathNew)) + { + throw new Exception($"Already have continer with name {newName}"); + } + + // Update AsrPathAsrRawDict + Manager.AsrPathAsrRawDict[asrPathNew] = Manager.AsrPathAsrRawDict[asrPathOld]; + Manager.AsrPathAsrRawDict.Remove(asrPathOld); + // Update AsrRawAsrPathDict + Manager.AsrRawAsrPathDict[Model] = asrPathNew; + // Update AsrPathInstanceDict + Manager.AsrPathInstanceDict[asrPathNew] = Manager.AsrPathInstanceDict[asrPathOld]; + Manager.AsrPathInstanceDict.Remove(asrPathOld); + + // Updata InstanceReferenceDict, change all reference point to container + try + { + var usage = (this as IEcucInstanceBase).GetReferenceByAsrPath(asrPathOld); + foreach (var u in usage) + { + u.ValueRef = asrPathNew; + } + } + catch + { + + } + + foreach (var continer in Containers) + { + continer.UpdateAsrPathPrefix(asrPathNew); + } + } + + /// + /// Update autosar path prefix of container. + /// The prefix may be changed by parent container shortname changed. + /// + /// New short name of container + public void UpdateAsrPathPrefix(string newName) + { + // Construct new autosar path + var asrPathOld = AsrPath; + var parts = AsrPath.Split("/"); + var asrPathNew = $"{newName}/{parts[^1]}"; + + // Check name duplication + if (Manager.AsrPathAsrRawDict.ContainsKey(asrPathNew)) + { + throw new Exception($"Already have continer with name {newName}"); + } + + // Update AsrPathAsrRawDict + Manager.AsrPathAsrRawDict[asrPathNew] = Manager.AsrPathAsrRawDict[asrPathOld]; + Manager.AsrPathAsrRawDict.Remove(asrPathOld); + // Update AsrRawAsrPathDict + Manager.AsrRawAsrPathDict[Model] = asrPathNew; + // Update AsrPathInstanceDict + Manager.AsrPathInstanceDict[asrPathNew] = Manager.AsrPathInstanceDict[asrPathOld]; + Manager.AsrPathInstanceDict.Remove(asrPathOld); + + // Updata InstanceReferenceDict, change all reference point to container + try + { + var usage = (this as IEcucInstanceBase).GetReferenceByAsrPath(asrPathOld); + foreach (var u in usage) + { + u.ValueRef = asrPathNew; + } + } + catch + { + + } + + foreach (var continer in Containers) + { + continer.UpdateAsrPathPrefix(asrPathNew); + } + } + + private void ValidChangedEventHandler(object? sender, PropertyChangedEventArgs e) + { + RaisePropertyChanged(nameof(Valid)); + } + } + + public class EcucInstanceContainer : NotifyPropertyChangedBase, IEcucInstanceContainer + { + public ECUCCONTAINERVALUE Model { get; } + public EcucInstanceManager Manager { get; } + public IEcucInstanceModule Parent { get; } + public EcucValid Valid { get; set; } + + private bool isDirty = false; + + public bool IsDirty + { + get + { + return isDirty; + } + set + { + if (value != IsDirty) + { + isDirty = value; + if (value == true) + { + Parent.IsDirty = true; + } + else + { + foreach (var container in Containers) + { + container.IsDirty = false; + } + } + } + } + } + + public CommentGroupList Comment + { + get + { + if (Model.ADMINDATA == null) + { + return new CommentGroupList(); + } + + if (Model.ADMINDATA.SDGS == null) + { + return new CommentGroupList(); + } + + return new CommentGroupList(Model.ADMINDATA.SDGS.SDG); + } + set + { + if (value == null) + { + return; + } + + if (value.Count == 0) + { + return; + } + + if (Model.ADMINDATA == null) + { + Model.ADMINDATA = new ADMINDATA(); + } + + if (Model.ADMINDATA.SDGS == null) + { + Model.ADMINDATA.SDGS = new ADMINDATA.SDGSLocalType(); + } + + foreach (var item in value) + { + Model.ADMINDATA.SDGS.SDG.Add(item.Model); + } + } + } + + public string BswmdPath + { + get + { + return Model.DEFINITIONREF.TypedValue; + } + } + + public string ShortName + { + get + { + return Model.SHORTNAME.TypedValue; + } + set + { + if (value != null) + { + if (ShortName != value) + { + // cache old autosar path + var asrPathOld = AsrPath; + var parts = asrPathOld.Split('/'); + if (parts.Length > 0) + { + // add new path to dict + UpdateAsrPathShort(value); + // autosar model modify + Model.SHORTNAME.TypedValue = value; + } + } + } + } + } + + public string AsrPath + { + get + { + return Manager.AsrRawAsrPathDict[Model]; + } + } + + public string AsrPathShort + { + get + { + var parts = AsrPath.Split('/'); + if (parts.Length > 0) + { + return parts[^1]; + } + return ""; + } + } + + public List Containers { get; } = new(); + public List Paras { get; } = new(); + public List Refs { get; } = new(); + + public EcucInstanceContainer(ECUCCONTAINERVALUE model, EcucInstanceManager manager, IEcucInstanceModule parent) + { + Model = model; + Manager = manager; + Parent = parent; + Valid = new EcucValid(this); + Valid.PropertyChanged += ValidChangedEventHandler; + + Monitor.Enter(Manager.BswmdPathInstanceDict); + try + { + if (Manager.BswmdPathInstanceDict.ContainsKey(BswmdPath)) + { + Manager.BswmdPathInstanceDict[BswmdPath].Add(this); + } + else + { + Manager.BswmdPathInstanceDict[BswmdPath] = new List() { this }; + } + } + finally + { + Monitor.Exit(Manager.BswmdPathInstanceDict); + } + + Monitor.Enter(Manager.AsrPathInstanceDict); + try + { + Manager.AsrPathInstanceDict[AsrPath] = this; + } + finally + { + Monitor.Exit(Manager.AsrPathInstanceDict); + } + + if (Model.SUBCONTAINERS != null) + { + if (Model.SUBCONTAINERS.ECUCCONTAINERVALUE != null) + { + foreach (ECUCCONTAINERVALUE container in Model.SUBCONTAINERS.ECUCCONTAINERVALUE) + { + Containers.Add(new EcucInstanceContainer(container, Manager, this)); + } + } + } + + if (Model.PARAMETERVALUES != null) + { + if (Model.PARAMETERVALUES.ECUCTEXTUALPARAMVALUE != null) + { + foreach (ECUCTEXTUALPARAMVALUE para in Model.PARAMETERVALUES.ECUCTEXTUALPARAMVALUE) + { + Paras.Add(new EcucInstanceTextualParamValue(para, Manager, this)); + } + } + + if (Model.PARAMETERVALUES.ECUCNUMERICALPARAMVALUE != null) + { + foreach (ECUCNUMERICALPARAMVALUE para in Model.PARAMETERVALUES.ECUCNUMERICALPARAMVALUE) + { + Paras.Add(new EcucInstanceNumericalParamValue(para, Manager, this)); + } + } + } + + if (Model.REFERENCEVALUES != null) + { + if (Model.REFERENCEVALUES.ECUCREFERENCEVALUE != null) + { + foreach (ECUCREFERENCEVALUE reference in Model.REFERENCEVALUES.ECUCREFERENCEVALUE) + { + Refs.Add(new EcucInstanceReferenceValue(reference, Manager, this)); + } + } + } + } + + public EcucInstanceContainer AddContainer(string path, string shortName) + { + var model = new ECUCCONTAINERVALUE + { + DEFINITIONREF = new ECUCCONTAINERVALUE.DEFINITIONREFLocalType + { + DEST = "ECUC-PARAM-CONF-CONTAINER-DEF", + TypedValue = $"{BswmdPath}/{path}" + }, + SHORTNAME = new IDENTIFIER + { + TypedValue = shortName + }, + UUID = Guid.NewGuid().ToString() + }; + + if (Manager.AsrPathAsrRawDict.ContainsKey($"{AsrPath}/{shortName}") == false) + { + if (Model.SUBCONTAINERS == null) + { + Model.SUBCONTAINERS = new ECUCCONTAINERVALUE.SUBCONTAINERSLocalType(); + } + Model.SUBCONTAINERS.ECUCCONTAINERVALUE.Add(model); + Manager.AsrPathAsrRawDict[$"{AsrPath}/{shortName}"] = model; + Manager.AsrRawAsrPathDict[model] = $"{AsrPath}/{shortName}"; + var newContainer = new EcucInstanceContainer(model, Manager, this); + Containers.Add(newContainer); + IsDirty = true; + return newContainer; + } + else + { + throw new Exception($"Find duplicate container {shortName} when add continer"); + } + } + + public int DelContainer(string path, string shortName) + { + foreach (var container in Containers) + { + if (container.BswmdPath == path && container.ShortName == shortName) + { + if (container is EcucInstanceContainer instanceContainer) + { + Manager.AsrPathAsrRawDict.Remove(instanceContainer.AsrPath); + Manager.AsrRawAsrPathDict.Remove(instanceContainer); + Model.SUBCONTAINERS.ECUCCONTAINERVALUE.Remove(instanceContainer.Model); + IsDirty = true; + + if (container.Containers.Count > 0) + { + if (container is EcucInstanceContainer instanceContainer2) + { + instanceContainer2.DelContainer(); + } + } + } + } + } + + Containers.RemoveAll(x => x.BswmdPath == path && x.ShortName == shortName); + return Containers.FindAll(x => x.BswmdPath == path).Count; + } + + public int DelContainer(string path) + { + foreach (var container in Containers) + { + if (container.BswmdPathShort == path) + { + if (container is EcucInstanceContainer instanceContainer) + { + Manager.AsrPathAsrRawDict.Remove(instanceContainer.AsrPath); + Manager.AsrRawAsrPathDict.Remove(instanceContainer); + Model.SUBCONTAINERS.ECUCCONTAINERVALUE.Remove(instanceContainer.Model); + IsDirty = true; + + if (container.Containers.Count > 0) + { + if (container is EcucInstanceContainer instanceContainer2) + { + instanceContainer2.DelContainer(); + } + } + } + } + } + + Containers.RemoveAll(x => x.BswmdPath == path); + return Containers.FindAll(x => x.BswmdPath == path).Count; + } + + public void DelContainer() + { + foreach (var container in Containers) + { + if (container is EcucInstanceContainer instanceContainer) + { + Manager.AsrPathAsrRawDict.Remove(instanceContainer.AsrPath); + Manager.AsrRawAsrPathDict.Remove(instanceContainer); + Model.SUBCONTAINERS.ECUCCONTAINERVALUE.Remove(instanceContainer.Model); + IsDirty = true; + + if (container.Containers.Count > 0) + { + if (container is EcucInstanceContainer instanceContainer2) + { + instanceContainer2.DelContainer(); + } + } + } + } + Containers.RemoveAll(x => x.BswmdPath != ""); + } + + public EcucInstanceTextualParamValue AddTextualPara(string path, string value, string dest) + { + var paraNew = new EcucInstanceTextualParamValue($"{BswmdPath}/{path}", dest, value, Manager, this); + + if (Model.PARAMETERVALUES == null) + { + Model.PARAMETERVALUES = new ECUCCONTAINERVALUE.PARAMETERVALUESLocalType(); + } + Model.PARAMETERVALUES.ECUCTEXTUALPARAMVALUE.Add(paraNew.Model); + Paras.Add(paraNew); + paraNew.IsDirty = true; + return paraNew; + } + + public void DelTextualPara(string path, string value) + { + var query = from para in Paras + where para.BswmdPathShort == path && para.Value == value + select para; + + foreach (var para in query.ToList()) + { + if (para is EcucInstanceTextualParamValue textualPara) + { + Model.PARAMETERVALUES.ECUCTEXTUALPARAMVALUE.Remove(textualPara.Model); + Manager.BswmdPathInstanceDict[para.BswmdPath].Remove(para); + Paras.Remove(para); + IsDirty = true; + } + } + } + + public void DelTextualPara(string path) + { + var query = from para in Paras + where para.BswmdPathShort == path + select para; + + foreach (var para in query.ToList()) + { + if (para is EcucInstanceTextualParamValue textualPara) + { + Model.PARAMETERVALUES.ECUCTEXTUALPARAMVALUE.Remove(textualPara.Model); + Manager.BswmdPathInstanceDict[para.BswmdPath].Remove(para); + Paras.Remove(para); + IsDirty = true; + } + } + } + + public EcucInstanceNumericalParamValue AddNumericalPara(string path, string value, string dest) + { + var paraNew = new EcucInstanceNumericalParamValue($"{BswmdPath}/{path}", dest, value, Manager, this); + if (Model.PARAMETERVALUES == null) + { + Model.PARAMETERVALUES = new ECUCCONTAINERVALUE.PARAMETERVALUESLocalType(); + } + Model.PARAMETERVALUES.ECUCNUMERICALPARAMVALUE.Add(paraNew.Model); + Paras.Add(paraNew); + paraNew.IsDirty = true; + return paraNew; + } + + public void DelNumericalPara(string path, string value) + { + var query = from para in Paras + where para.BswmdPathShort == path && para.Value == value + select para; + + foreach (var para in query.ToList()) + { + if (para is EcucInstanceNumericalParamValue numericalPara) + { + Model.PARAMETERVALUES.ECUCNUMERICALPARAMVALUE.Remove(numericalPara.Model); + Manager.BswmdPathInstanceDict[para.BswmdPath].Remove(para); + Paras.Remove(para); + IsDirty = true; + } + } + } + + public void DelNumericalPara(string path) + { + var query = from para in Paras + where para.BswmdPathShort == path + select para; + + foreach (var para in query.ToList()) + { + if (para is EcucInstanceNumericalParamValue numericalPara) + { + Model.PARAMETERVALUES.ECUCNUMERICALPARAMVALUE.Remove(numericalPara.Model); + Manager.BswmdPathInstanceDict[para.BswmdPath].Remove(para); + Paras.Remove(para); + IsDirty = true; + } + } + } + + public EcucInstanceReferenceValue AddReference(string path, string defDest, string valueRef, string valueDest) + { + var refNew = new EcucInstanceReferenceValue($"{BswmdPath}/{path}", defDest, valueRef, valueDest, Manager, this); + if (Model.REFERENCEVALUES == null) + { + Model.REFERENCEVALUES = new ECUCCONTAINERVALUE.REFERENCEVALUESLocalType(); + } + Model.REFERENCEVALUES.ECUCREFERENCEVALUE.Add(refNew.Model); + refNew.IsDirty = true; + Refs.Add(refNew); + return refNew; + } + + public void DelReference(string path, string valueRef) + { + var query = from reference in Refs + where reference.BswmdPathShort == path && reference.ValueRef == valueRef + select reference; + + foreach (var reference in query.ToList()) + { + if (reference is EcucInstanceReferenceValue instanceReference) + { + Model.REFERENCEVALUES.ECUCREFERENCEVALUE.Remove(instanceReference.Model); + Refs.Remove(instanceReference); + IsDirty = true; + } + } + } + + public void DelReference(string path) + { + var query = from reference in Refs + where reference.BswmdPathShort == path + select reference; + + foreach (var reference in query.ToList()) + { + if (reference is EcucInstanceReferenceValue instanceReference) + { + Model.REFERENCEVALUES.ECUCREFERENCEVALUE.Remove(instanceReference.Model); + Refs.Remove(instanceReference); + IsDirty = true; + } + } + } + + /// + /// Update autosar path dictionary of container + /// + /// New short name of container + public void UpdateAsrPathShort(string newName) + { + // Construct new autosar path + var asrPathOld = AsrPath; + var parts = AsrPath.Split("/"); + parts[^1] = newName; + var asrPathNew = string.Join("/", parts); + + // Check name duplication + if (Manager.AsrPathAsrRawDict.ContainsKey(asrPathNew)) + { + throw new Exception($"Already have continer with name {newName}"); + } + + // Update AsrPathAsrRawDict + Manager.AsrPathAsrRawDict[asrPathNew] = Manager.AsrPathAsrRawDict[asrPathOld]; + Manager.AsrPathAsrRawDict.Remove(asrPathOld); + // Update AsrRawAsrPathDict + Manager.AsrRawAsrPathDict[Model] = asrPathNew; + // Update AsrPathInstanceDict + Manager.AsrPathInstanceDict[asrPathNew] = Manager.AsrPathInstanceDict[asrPathOld]; + Manager.AsrPathInstanceDict.Remove(asrPathOld); + + // Updata InstanceReferenceDict, change all reference point to container + try + { + var usage = (this as IEcucInstanceBase).GetReferenceByAsrPath(asrPathOld); + foreach (var u in usage) + { + u.ValueRef = asrPathNew; + } + Manager.InstanceReferenceDict[asrPathNew] = Manager.InstanceReferenceDict[asrPathOld]; + Manager.InstanceReferenceDict.Remove(asrPathOld); + } + catch + { + + } + + foreach (var continer in Containers) + { + continer.UpdateAsrPathPrefix(asrPathNew); + } + } + + /// + /// Update autosar path prefix of container. + /// The prefix may be changed by parent container shortname changed. + /// + /// New short name of container + public void UpdateAsrPathPrefix(string newName) + { + // Construct new autosar path + var asrPathOld = AsrPath; + var parts = AsrPath.Split("/"); + var asrPathNew = $"{newName}/{parts[^1]}"; + + // Check name duplication + if (Manager.AsrPathAsrRawDict.ContainsKey(asrPathNew)) + { + throw new Exception($"Already have continer with name {newName}"); + } + + // Update AsrPathAsrRawDict + Manager.AsrPathAsrRawDict[asrPathNew] = Manager.AsrPathAsrRawDict[asrPathOld]; + Manager.AsrPathAsrRawDict.Remove(asrPathOld); + // Update AsrRawAsrPathDict + Manager.AsrRawAsrPathDict[Model] = asrPathNew; + // Update AsrPathInstanceDict + Manager.AsrPathInstanceDict[asrPathNew] = Manager.AsrPathInstanceDict[asrPathOld]; + Manager.AsrPathInstanceDict.Remove(asrPathOld); + + // Updata InstanceReferenceDict, change all reference point to container + try + { + var usage = (this as IEcucInstanceBase).GetReferenceByAsrPath(asrPathOld); + foreach (var u in usage) + { + u.ValueRef = asrPathNew; + } + Manager.InstanceReferenceDict[asrPathNew] = Manager.InstanceReferenceDict[asrPathOld]; + Manager.InstanceReferenceDict.Remove(asrPathOld); + } + catch + { + + } + + foreach (var continer in Containers) + { + continer.UpdateAsrPathPrefix(asrPathNew); + } + } + + private void ValidChangedEventHandler(object? sender, PropertyChangedEventArgs e) + { + Parent.Valid.RaisePropertyChanged(nameof(Valid)); + RaisePropertyChanged(nameof(Valid)); + } + } + + public class EcucInstanceTextualParamValue : NotifyPropertyChangedBase, IEcucInstanceParam + { + public ECUCTEXTUALPARAMVALUE Model { get; } + public EcucInstanceManager Manager { get; } + public IEcucInstanceModule Parent { get; } + public EcucValid Valid { get; set; } + + private bool isDirty = false; + + public bool IsDirty + { + get + { + return isDirty; + } + set + { + if (value != IsDirty) + { + isDirty = value; + if (value == true) + { + Parent.IsDirty = true; + } + } + } + } + + public string BswmdPath + { + get + { + return Model.DEFINITIONREF.TypedValue; + } + set + { + if (value == null) + { + return; + } + if (BswmdPath == value) + { + return; + } + Model.DEFINITIONREF.TypedValue = value; + } + } + + public string Value + { + get + { + try + { + return Model.VALUE.TypedValue; + } + catch + { + return ""; + } + } + set + { + if (value == null) + { + return; + } + if (Value == value) + { + return; + } + Model.VALUE.TypedValue = value; + IsDirty = true; + } + } + + public string Dest + { + get + { + return Model.DEFINITIONREF.DEST; + } + set + { + if (value == null) + { + return; + } + if (Dest == value) + { + return; + } + Model.DEFINITIONREF.DEST = value; + } + } + + public List Comment + { + get + { + var result = new List(); + foreach (var anno in Model.ANNOTATIONS.ANNOTATION) + { + result.Add(anno.ANNOTATIONORIGIN.TypedValue); + } + return result; + } + set + { + Model.ANNOTATIONS.ANNOTATION = new List(); + foreach (var comment in value) + { + Model.ANNOTATIONS.ANNOTATION.Add + ( + new ANNOTATION + { + ANNOTATIONORIGIN = new STRING + { + TypedValue = comment + } + } + ); + } + } + } + + public EcucInstanceTextualParamValue(string bswmdPath, string dest, string value, EcucInstanceManager manager, IEcucInstanceModule parent) + { + Model = new ECUCTEXTUALPARAMVALUE + { + VALUE = new VERBATIMSTRING + { + TypedValue = value + }, + DEFINITIONREF = new ECUCTEXTUALPARAMVALUE.DEFINITIONREFLocalType + { + TypedValue = bswmdPath, + DEST = dest + }, + }; + Manager = manager; + Parent = parent; + IsDirty = parent.IsDirty; + Valid = new EcucValid(this); + Valid.PropertyChanged += ValidChangedEventHandler; + + Register(); + } + + public EcucInstanceTextualParamValue(ECUCTEXTUALPARAMVALUE model, EcucInstanceManager manager, IEcucInstanceModule parent) + { + Model = model; + Manager = manager; + Parent = parent; + IsDirty = parent.IsDirty; + Valid = new EcucValid(this); + Valid.PropertyChanged += ValidChangedEventHandler; + + Register(); + } + + private void Register() + { + Monitor.Enter(Manager.BswmdPathInstanceDict); + try + { + if (Manager.BswmdPathInstanceDict.ContainsKey(BswmdPath)) + { + Manager.BswmdPathInstanceDict[BswmdPath].Add(this); + } + else + { + Manager.BswmdPathInstanceDict[BswmdPath] = new List() { this }; + } + } + finally + { + Monitor.Exit(Manager.BswmdPathInstanceDict); + } + } + + private void ValidChangedEventHandler(object? sender, PropertyChangedEventArgs e) + { + Parent.Valid.RaisePropertyChanged(nameof(Valid)); + RaisePropertyChanged(nameof(Valid)); + } + } + + public class EcucInstanceNumericalParamValue : NotifyPropertyChangedBase, IEcucInstanceParam + { + public ECUCNUMERICALPARAMVALUE Model { get; } + public EcucInstanceManager Manager { get; } + public IEcucInstanceModule Parent { get; } + public EcucValid Valid { get; set; } + + private bool isDirty = false; + + public bool IsDirty + { + get + { + return isDirty; + } + set + { + if (value != IsDirty) + { + isDirty = value; + if (value == true) + { + Parent.IsDirty = true; + } + } + } + } + + public string BswmdPath + { + get + { + return Model.DEFINITIONREF.TypedValue; + } + set + { + if (value == null) + { + return; + } + if (BswmdPath == value) + { + return; + } + Model.DEFINITIONREF.TypedValue = value; + } + } + + public string Value + { + get + { + try + { + return Model.VALUE.Untyped.Value; + } + catch + { + return "0"; + } + } + set + { + if (value == null) + { + return; + } + if (Value == value) + { + return; + } + Model.VALUE.Untyped.Value = value; + IsDirty = true; + } + } + + public string Dest + { + get + { + return Model.DEFINITIONREF.DEST; + } + set + { + if (value == null) + { + return; + } + if (Dest == value) + { + return; + } + Model.DEFINITIONREF.DEST = value; + } + } + + public List Comment + { + get + { + var result = new List(); + foreach (var anno in Model.ANNOTATIONS.ANNOTATION) + { + result.Add(anno.ANNOTATIONORIGIN.TypedValue); + } + return result; + } + set + { + Model.ANNOTATIONS.ANNOTATION = new List(); + foreach (var comment in value) + { + Model.ANNOTATIONS.ANNOTATION.Add + ( + new ANNOTATION + { + ANNOTATIONORIGIN = new STRING + { + TypedValue = comment + } + } + ); + } + } + } + + public EcucInstanceNumericalParamValue(string bswmdPath, string dest, string value, EcucInstanceManager manager, IEcucInstanceModule parent) + { + Model = new ECUCNUMERICALPARAMVALUE + { + VALUE = new NUMERICALVALUEVARIATIONPOINT(), + DEFINITIONREF = new ECUCNUMERICALPARAMVALUE.DEFINITIONREFLocalType + { + TypedValue = bswmdPath, + DEST = dest + } + }; + Model.VALUE.Untyped.Value = value; + Manager = manager; + Parent = parent; + IsDirty = parent.IsDirty; + Valid = new EcucValid(this); + Valid.PropertyChanged += ValidChangedEventHandler; + + Register(); + } + + public EcucInstanceNumericalParamValue(ECUCNUMERICALPARAMVALUE model, EcucInstanceManager manager, IEcucInstanceModule parent) + { + Model = model; + Manager = manager; + Parent = parent; + IsDirty = parent.IsDirty; + Valid = new EcucValid(this); + Valid.PropertyChanged += ValidChangedEventHandler; + + Register(); + } + + private void Register() + { + Monitor.Enter(Manager.BswmdPathInstanceDict); + try + { + if (Manager.BswmdPathInstanceDict.ContainsKey(BswmdPath)) + { + Manager.BswmdPathInstanceDict[BswmdPath].Add(this); + } + else + { + Manager.BswmdPathInstanceDict[BswmdPath] = new List() { this }; + } + } + finally + { + Monitor.Exit(Manager.BswmdPathInstanceDict); + } + } + + private void ValidChangedEventHandler(object? sender, PropertyChangedEventArgs e) + { + Parent.Valid.RaisePropertyChanged(nameof(Valid)); + RaisePropertyChanged(nameof(Valid)); + } + } + + public class EcucInstanceReferenceValue : NotifyPropertyChangedBase, IEcucInstanceReference + { + public ECUCREFERENCEVALUE Model { get; } + public EcucInstanceManager Manager { get; } + public IEcucInstanceModule Parent { get; } + public EcucValid Valid { get; set; } + + private bool isDirty = false; + + public bool IsDirty + { + get + { + return isDirty; + } + set + { + if (value != IsDirty) + { + isDirty = value; + if (value == true) + { + Parent.IsDirty = true; + } + } + } + } + + public string BswmdPath + { + get + { + return Model.DEFINITIONREF.TypedValue; + } + } + + public string DefDest + { + get + { + return Model.VALUEREF.DEST; + } + set + { + if (value == null) + { + return; + } + if (DefDest == value) + { + return; + } + + Model.VALUEREF.DEST = value; + } + } + + public string ValueRef + { + get + { + if (Model.VALUEREF != null) + { + return Model.VALUEREF.TypedValue; + } + else + { + return ""; + } + } + set + { + if (value == null) + { + return; + } + if (ValueRef == value) + { + return; + } + + Model.VALUEREF.TypedValue = value; + IsDirty = true; + } + } + + public string ValueDest + { + get + { + return Model.VALUEREF.DEST; + } + set + { + if (value == null) + { + return; + } + if (ValueDest == value) + { + return; + } + + Model.VALUEREF.DEST = value; + } + } + + public List Comment + { + get + { + var result = new List(); + foreach (var anno in Model.ANNOTATIONS.ANNOTATION) + { + result.Add(anno.ANNOTATIONORIGIN.TypedValue); + } + return result; + } + set + { + Model.ANNOTATIONS.ANNOTATION = new List(); + foreach (var comment in value) + { + Model.ANNOTATIONS.ANNOTATION.Add + ( + new ANNOTATION + { + ANNOTATIONORIGIN = new STRING + { + TypedValue = comment + } + } + ); + } + } + } + + public EcucInstanceReferenceValue(string bswmdPath, string defDest, string valueRef, string valueDest, EcucInstanceManager manager, IEcucInstanceModule parent) + { + valueDest = valueDest switch + { + "ECUC-PARAM-CONF-CONTAINER-DEF" => "ECUC-CONTAINER-VALUE", + "ECUC-ENUMERATION-PARAM-DEF" => "ECUC-TEXTUAL-PARAM-VALUE", + "ECUC-INTEGER-PARAM-DEF" => "ECUC-NUMERICAL-PARAM-VALUE", + "ECUC-BOOLEAN-PARAM-DEF" => "ECUC-NUMERICAL-PARAM-VALUE", + "ECUC-FLOAT-PARAM-DEF" => "ECUC-NUMERICAL-PARAM-VALUE", + "ECUC-STRING-PARAM-DEF" => "ECUC-TEXTUAL-PARAM-VALUE", + "ECUC-FUNCTION-NAME-DEF" => "ECUC-TEXTUAL-PARAM-VALUE", + "ECUC-REFERENCE-DEF" => "ECUC-REFERENCE-VALUE", + "ECUC-FOREIGN-REFERENCE-DEF" => "ECUC-REFERENCE-VALUE", + "ECUC-SYMBOLIC-NAME-REFERENCE-DEF" => "ECUC-REFERENCE-VALUE", + _ => throw new NotImplementedException(), + }; + Model = new ECUCREFERENCEVALUE + { + DEFINITIONREF = new ECUCREFERENCEVALUE.DEFINITIONREFLocalType + { + TypedValue = bswmdPath, + DEST = defDest + }, + VALUEREF = new ECUCREFERENCEVALUE.VALUEREFLocalType + { + TypedValue = valueRef, + DEST = valueDest + } + }; + Manager = manager; + Parent = parent; + IsDirty = parent.IsDirty; + Valid = new EcucValid(this); + Valid.PropertyChanged += ValidChangedEventHandler; + + Register(); + } + + public EcucInstanceReferenceValue(ECUCREFERENCEVALUE model, EcucInstanceManager manager, IEcucInstanceModule parent) + { + Model = model; + Manager = manager; + Parent = parent; + IsDirty = parent.IsDirty; + Valid = new EcucValid(this); + Valid.PropertyChanged += ValidChangedEventHandler; + + Register(); + } + + private void Register() + { + Monitor.Enter(Manager.BswmdPathInstanceDict); + try + { + if (Manager.BswmdPathInstanceDict.ContainsKey(BswmdPath)) + { + Manager.BswmdPathInstanceDict[BswmdPath].Add(this); + } + else + { + Manager.BswmdPathInstanceDict[BswmdPath] = new List() { this }; + } + } + finally + { + Monitor.Exit(Manager.BswmdPathInstanceDict); + } + + Monitor.Enter(Manager.InstanceReferenceDict); + try + { + if (Manager.InstanceReferenceDict.ContainsKey(ValueRef)) + { + Manager.InstanceReferenceDict[ValueRef].Add(this); + } + else + { + Manager.InstanceReferenceDict[ValueRef] = new List() { this }; + } + } + finally + { + Monitor.Exit(Manager.InstanceReferenceDict); + } + } + + private void ValidChangedEventHandler(object? sender, PropertyChangedEventArgs e) + { + Parent.Valid.RaisePropertyChanged(nameof(Valid)); + RaisePropertyChanged(nameof(Valid)); + } + } +} diff --git a/EcucBase/EcucPdu.cs b/EcucBase/EcucPdu.cs new file mode 100644 index 0000000..c854efe --- /dev/null +++ b/EcucBase/EcucPdu.cs @@ -0,0 +1,558 @@ +/* + * This file is a part of Autosar Configurator for ECU GUI based + * configuration, checking and code generation. + * + * Copyright (C) 2021-2022 DJS Studio E-mail:DD-Silence@sina.cn + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +using Ecuc.EcucBase.EBswmd; +using Ecuc.EcucBase.EData; +using Ecuc.EcucBase.EInstance; + +namespace Ecuc.EcucBase.EPdu +{ + public enum EcucPduType + { + CanIfRx = 0, + CanIfTx, + ComRx, + ComTx, + SecOCRx, + SecOCTx, + CanTpNSduRx, + CanTpNSduTx, + CanTpNPduRx, + CanTpNPduTx, + CanTpFcNPduRx, + CanTpFcNPduTx, + EcucPdu + } + + public class EcucPdu + { + EcucBswmdManager BswmdManager { get; } + EcucInstanceManager InstanceManager { get; } + + public EcucPdu(EcucBswmdManager bswmdManager, EcucInstanceManager instanceManager) + { + BswmdManager = bswmdManager; + InstanceManager = instanceManager; + } + + private static bool FilterFuncComRx(EcucData data) + { + return data["ComIPduDirection"].ValueSingleEqual("RECEIVE"); + } + + private static bool FilterFuncComTx(EcucData data) + { + return data["ComIPduDirection"].ValueSingleEqual("SEND"); + } + + public EcucDataList GetPdusByType(EcucPduType typ) + { + switch (typ) + { + case EcucPduType.CanIfRx: + { + var instanceModule = InstanceManager["CanIf"]; + if (instanceModule == null) + { + return new EcucDataList(); + } + var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath); + if (bswmdModule == null) + { + return new EcucDataList(); + } + var data = new EcucData(instanceModule, bswmdModule); + return data["CanIfInitCfg"]["CanIfRxPduCfg"]; + } + + case EcucPduType.CanIfTx: + { + var instanceModule = InstanceManager["CanIf"]; + if (instanceModule == null) + { + return new EcucDataList(); + } + var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath); + if (bswmdModule == null) + { + return new EcucDataList(); + } + var data = new EcucData(instanceModule, bswmdModule); + return data["CanIfInitCfg"]["CanIfTxPduCfg"]; + } + + case EcucPduType.ComRx: + { + var instanceModule = InstanceManager["Com"]; + if (instanceModule == null) + { + return new EcucDataList(); + } + var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath); + if (bswmdModule == null) + { + return new EcucDataList(); + } + var data = new EcucData(instanceModule, bswmdModule); + return data["ComConfig"]["ComIPdu", x => FilterFuncComRx(x)]; + } + + case EcucPduType.ComTx: + { + var instanceModule = InstanceManager["Com"]; + if (instanceModule == null) + { + return new EcucDataList(); + } + var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath); + if (bswmdModule == null) + { + return new EcucDataList(); + } + var data = new EcucData(instanceModule, bswmdModule); + return data["ComConfig"]["ComIPdu", x => FilterFuncComTx(x)]; + } + + case EcucPduType.SecOCRx: + { + var instanceModule = InstanceManager["SecOC"]; + if (instanceModule == null) + { + return new EcucDataList(); + } + var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath); + if (bswmdModule == null) + { + return new EcucDataList(); + } + var data = new EcucData(instanceModule, bswmdModule); + return data["SecOCRxPduProcessing"]["SecOCRxAuthenticPduLayer"]; + } + + case EcucPduType.SecOCTx: + { + var instanceModule = InstanceManager["SecOC"]; + if (instanceModule == null) + { + return new EcucDataList(); + } + var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath); + if (bswmdModule == null) + { + return new EcucDataList(); + } + var data = new EcucData(instanceModule, bswmdModule); + return data["SecOCRxPduProcessing"]["SecOCTxAuthenticPduLayer"]; + } + + case EcucPduType.CanTpNSduRx: + { + var instanceModule = InstanceManager["CanTp"]; + if (instanceModule == null) + { + return new EcucDataList(); + } + var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath); + if (bswmdModule == null) + { + return new EcucDataList(); + } + var data = new EcucData(instanceModule, bswmdModule); + return data["CanTpConfig"]["CanTpChannel"]["CanTpRxNSdu"]; + } + + case EcucPduType.CanTpNSduTx: + { + var instanceModule = InstanceManager["CanTp"]; + if (instanceModule == null) + { + return new EcucDataList(); + } + var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath); + if (bswmdModule == null) + { + return new EcucDataList(); + } + var data = new EcucData(instanceModule, bswmdModule); + return data["CanTpConfig"]["CanTpChannel"]["CanTpTxNSdu"]; + } + + case EcucPduType.CanTpNPduRx: + { + var instanceModule = InstanceManager["CanTp"]; + if (instanceModule == null) + { + return new EcucDataList(); + } + var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath); + if (bswmdModule == null) + { + return new EcucDataList(); + } + var data = new EcucData(instanceModule, bswmdModule); + return data["CanTpConfig"]["CanTpChannel"]["CanTpRxNSdu"]["CanTpRxNPdu"]; + } + + case EcucPduType.CanTpNPduTx: + { + var instanceModule = InstanceManager["CanTp"]; + if (instanceModule == null) + { + return new EcucDataList(); + } + var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath); + if (bswmdModule == null) + { + return new EcucDataList(); + } + var data = new EcucData(instanceModule, bswmdModule); + return data["CanTpConfig"]["CanTpChannel"]["CanTpTxNSdu"]["CanTpTxNPdu"]; + } + + case EcucPduType.CanTpFcNPduRx: + { + var instanceModule = InstanceManager["CanTp"]; + if (instanceModule == null) + { + return new EcucDataList(); + } + var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath); + if (bswmdModule == null) + { + return new EcucDataList(); + } + var data = new EcucData(instanceModule, bswmdModule); + return data["CanTpConfig"]["CanTpChannel"]["CanTpRxNSdu"]["CanTpTxFcNPdu"]; + } + + case EcucPduType.CanTpFcNPduTx: + { + var instanceModule = InstanceManager["CanTp"]; + if (instanceModule == null) + { + return new EcucDataList(); + } + var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath); + if (bswmdModule == null) + { + return new EcucDataList(); + } + var data = new EcucData(instanceModule, bswmdModule); + return data["CanTpConfig"]["CanTpChannel"]["CanTpTxNSdu"]["CanTpRxFcNPdu"]; + } + + case EcucPduType.EcucPdu: + { + var instanceModule = InstanceManager["SecOc"]; + if (instanceModule == null) + { + return new EcucDataList(); + } + var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath); + if (bswmdModule == null) + { + return new EcucDataList(); + } + var data = new EcucData(instanceModule, bswmdModule); + return data["EcucPduCollection"]["Pdu"]; + } + + default: + return new EcucDataList(); + } + } + + static private bool FilterShortNameFunc(EcucData data, string name) + { + return data.Value.StartsWith(name); + } + + private static bool FilterShortNameFuncComRx(EcucData data, string name) + { + return data.Value.StartsWith(name) && data["ComIPduDirection"].ValueSingleEqual("RECEIVE"); + } + + private static bool FilterShortNameFuncComTx(EcucData data, string name) + { + return data.Value.StartsWith(name) && data["ComIPduDirection"].ValueSingleEqual("SEND"); + } + + public EcucDataList GetPduByTypeAndName(EcucPduType typ, string name) + { + switch (typ) + { + case EcucPduType.CanIfRx: + { + var instanceModule = InstanceManager["CanIf"]; + if (instanceModule == null) + { + return new EcucDataList(); ; + } + var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath); + if (bswmdModule == null) + { + return new EcucDataList(); + } + var data = new EcucData(instanceModule, bswmdModule); + return data["CanIfInitCfg"]["CanIfRxPduCfg", x => FilterShortNameFunc(x, name)]; + } + + case EcucPduType.CanIfTx: + { + var instanceModule = InstanceManager["CanIf"]; + if (instanceModule == null) + { + return new EcucDataList(); + } + var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath); + if (bswmdModule == null) + { + return new EcucDataList(); + } + var data = new EcucData(instanceModule, bswmdModule); + return data["CanIfInitCfg"]["CanIfTxPduCfg", x => FilterShortNameFunc(x, name)]; + } + + case EcucPduType.ComRx: + { + var instanceModule = InstanceManager["Com"]; + if (instanceModule == null) + { + return new EcucDataList(); + } + var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath); + if (bswmdModule == null) + { + return new EcucDataList(); + } + var data = new EcucData(instanceModule, bswmdModule); + return data["ComConfig"]["ComIPdu", x => FilterShortNameFuncComRx(x, name)]; + } + + case EcucPduType.ComTx: + { + var instanceModule = InstanceManager["Com"]; + if (instanceModule == null) + { + return new EcucDataList(); + } + var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath); + if (bswmdModule == null) + { + return new EcucDataList(); + } + var data = new EcucData(instanceModule, bswmdModule); + return data["ComConfig"]["ComIPdu", x => FilterShortNameFuncComTx(x, name)]; + } + + case EcucPduType.SecOCRx: + { + var instanceModule = InstanceManager["SecOC"]; + if (instanceModule == null) + { + return new EcucDataList(); + } + var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath); + if (bswmdModule == null) + { + return new EcucDataList(); + } + var data = new EcucData(instanceModule, bswmdModule); + return data["SecOCRxPduProcessing"]["SecOCRxAuthenticPduLayer", x => FilterShortNameFunc(x, name)]; + } + + case EcucPduType.SecOCTx: + { + var instanceModule = InstanceManager["SecOC"]; + if (instanceModule == null) + { + return new EcucDataList(); + } + var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath); + if (bswmdModule == null) + { + return new EcucDataList(); + } + var data = new EcucData(instanceModule, bswmdModule); + return data["SecOCRxPduProcessing"]["SecOCTxAuthenticPduLayer", x => FilterShortNameFunc(x, name)]; + } + + case EcucPduType.CanTpNSduRx: + { + var instanceModule = InstanceManager["CanTp"]; + if (instanceModule == null) + { + return new EcucDataList(); + } + var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath); + if (bswmdModule == null) + { + return new EcucDataList(); + } + var data = new EcucData(instanceModule, bswmdModule); + return data["CanTpConfig"]["CanTpChannel"]["CanTpRxNSdu", x => FilterShortNameFunc(x, name)]; + } + + case EcucPduType.CanTpNSduTx: + { + var instanceModule = InstanceManager["CanTp"]; + if (instanceModule == null) + { + return new EcucDataList(); + } + var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath); + if (bswmdModule == null) + { + return new EcucDataList(); + } + var data = new EcucData(instanceModule, bswmdModule); + return data["CanTpConfig"]["CanTpChannel"]["CanTpTxNSdu", x => FilterShortNameFunc(x, name)]; + } + + case EcucPduType.CanTpNPduRx: + { + var instanceModule = InstanceManager["CanTp"]; + if (instanceModule == null) + { + return new EcucDataList(); + } + var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath); + if (bswmdModule == null) + { + return new EcucDataList(); + } + var data = new EcucData(instanceModule, bswmdModule); + return data["CanTpConfig"]["CanTpChannel"]["CanTpRxNSdu"]["CanTpRxNPdu", x => FilterShortNameFunc(x, name)]; + } + + case EcucPduType.CanTpNPduTx: + { + var instanceModule = InstanceManager["CanTp"]; + if (instanceModule == null) + { + return new EcucDataList(); + } + var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath); + if (bswmdModule == null) + { + return new EcucDataList(); + } + var data = new EcucData(instanceModule, bswmdModule); + return data["CanTpConfig"]["CanTpChannel"]["CanTpTxNSdu"]["CanTpTxNPdu", x => FilterShortNameFunc(x, name)]; + } + + case EcucPduType.CanTpFcNPduRx: + { + var instanceModule = InstanceManager["CanTp"]; + if (instanceModule == null) + { + return new EcucDataList(); + } + var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath); + if (bswmdModule == null) + { + return new EcucDataList(); + } + var data = new EcucData(instanceModule, bswmdModule); + return data["CanTpConfig"]["CanTpChannel"]["CanTpRxNSdu"]["CanTpTxFcNPdu", x => FilterShortNameFunc(x, name)]; + } + + case EcucPduType.CanTpFcNPduTx: + { + var instanceModule = InstanceManager["CanTp"]; + if (instanceModule == null) + { + return new EcucDataList(); + } + var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath); + if (bswmdModule == null) + { + return new EcucDataList(); + } + var data = new EcucData(instanceModule, bswmdModule); + return data["CanTpConfig"]["CanTpChannel"]["CanTpTxNSdu"]["CanTpRxFcNPdu", x => FilterShortNameFunc(x, name)]; + } + + case EcucPduType.EcucPdu: + { + var instanceModule = InstanceManager["SecOc"]; + if (instanceModule == null) + { + return new EcucDataList(); + } + var bswmdModule = BswmdManager.GetBswmdFromBswmdPath(instanceModule.BswmdPath); + if (bswmdModule == null) + { + return new EcucDataList(); + } + var data = new EcucData(instanceModule, bswmdModule); + return data["EcucPduCollection"]["Pdu", x => FilterShortNameFunc(x, name)]; + } + + + default: + return new EcucDataList(); + } + } + } + + public class EcucPduResult + { + public EcucDataList Datas { get; } + private EcucPduType Typ { get; } + + public EcucDataList Reference + { + get + { + return Typ switch + { + EcucPduType.CanIfRx => Datas["CanIfRxPduRef"], + EcucPduType.CanIfTx => Datas["CanIfTxPduRef"], + EcucPduType.ComRx => Datas["ComPduIdRef"], + EcucPduType.ComTx => Datas["ComPduIdRef"], + EcucPduType.SecOCRx => Datas["SecOCRxAuthenticLayerPduRef"], + EcucPduType.SecOCTx => Datas["SecOCTxAuthenticLayerPduRef"], + EcucPduType.CanTpNSduRx => Datas["CanTpRxNSduRef"], + EcucPduType.CanTpNSduTx => Datas["CanTpTxNSduRef"], + EcucPduType.CanTpNPduRx => Datas["CanTpRxNPduRef"], + EcucPduType.CanTpNPduTx => Datas["CanTpTxNPduRef"], + EcucPduType.CanTpFcNPduRx => Datas["CanTpRxFcNPduRef"], + EcucPduType.CanTpFcNPduTx => Datas["CanTpTxFcNPduRef"], + _ => new EcucDataList(), + }; + } + } + + public EcucDataList DeReference + { + get + { + return Reference.DeRef(); + } + } + + public EcucPduResult(EcucDataList datas, EcucPduType typ) + { + Datas = datas; + Typ = typ; + } + } +} diff --git a/EcucUi/Main.Designer.cs b/EcucUi/Main.Designer.cs index 81aaf4a..6fb2f6e 100644 --- a/EcucUi/Main.Designer.cs +++ b/EcucUi/Main.Designer.cs @@ -335,7 +335,7 @@ private void InitializeComponent() this.MainMenuStrip = this.menuStrip1; this.Margin = new System.Windows.Forms.Padding(4); this.Name = "WdMain"; - this.Text = "Autosar Configurator V1.1"; + this.Text = "Autosar Configurator V1.2"; this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.WdMain_FormClosing); this.Load += new System.EventHandler(this.WdMain_Load); this.splitContainer1.Panel1.ResumeLayout(false); diff --git a/lib/EcucBaseCore.dll b/lib/EcucBaseCore.dll deleted file mode 100644 index 98ce277..0000000 Binary files a/lib/EcucBaseCore.dll and /dev/null differ