diff --git a/HashingCmd/Program.cs b/HashingCmd/Program.cs index 9bfab906e36ed7faeda803cc45f877a22193a6eb..e693f7f472d9a8c8f0d4c2ccb0929877d2597500 100644 --- a/HashingCmd/Program.cs +++ b/HashingCmd/Program.cs @@ -29,28 +29,28 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Xml; -using System.Xml.Schema; -using TUGraz.VectoCore.Utils; -using TUGraz.VectoHashing; - -namespace HashingCmd -{ - class Program - { - public delegate void HashingAction(string filename, VectoHash h); - +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Xml; +using System.Xml.Schema; +using TUGraz.VectoCore.Utils; +using TUGraz.VectoHashing; + +namespace HashingCmd +{ + class Program + { + public delegate void HashingAction(string filename, VectoHash h); + private const string Usage = @" hashingcmd.exe (-h | [-v] [[-s] -x] [-c] [-r]) <file.xml> <file2.xml> <file3.xml> -"; - +"; + private const string Help = @" hashingcmd.exe @@ -60,234 +60,235 @@ hashingcmd.exe -x: validate generated XML against VECTO XML schema -c: compute hash and write to stdout -r: read hash from file and write to stdout -"; - - private static readonly Dictionary<string, HashingAction> Actions = new Dictionary<string, HashingAction> { - { "-v", VerifyHashAction }, - { "-c", ComputeHashAction }, - { "-r", ReadHashAction }, - { "-s", CreateHashedFileAction } - }; - - static bool _validateXML; - private static bool xmlValid = true; - - static int Main(string[] args) - { - try { - if (args.Contains("-h")) { - ShowVersionInformation(); - Console.Write(Help); - return 0; - } - - if (args.Contains("-x")) { - _validateXML = true; - } - - var fileList = args.Except(Actions.Keys.Concat(new[] { "-x" })).ToArray(); - if (fileList.Length == 0 || !args.Intersect(Actions.Keys.ToArray()).Any()) { - ShowVersionInformation(); - Console.Write(Usage); - return 0; - } - foreach (var file in fileList) { - Console.Error.WriteLine("processing " + Path.GetFileName(file)); - if (!File.Exists(Path.GetFullPath(file))) { - Console.Error.WriteLine("file " + Path.GetFullPath(file) + " not found!"); - continue; - } - foreach (var arg in args) { - if (Actions.ContainsKey(arg)) { - try { - var h = VectoHash.Load(file); - Actions[arg](Path.GetFullPath(file), h); - } catch (Exception e) { - Console.ForegroundColor = ConsoleColor.Red; - Console.Error.WriteLine(e.Message); - if (e.InnerException != null) { - Console.Error.WriteLine(e.InnerException.Message); - } - Console.ResetColor(); - } - } - } - } - } catch (Exception e) { - Console.ForegroundColor = ConsoleColor.Red; - Console.Error.WriteLine(e.Message); - Console.ResetColor(); - - //Console.Error.WriteLine("Please see log-file for further details (logs/log.txt)"); - Environment.ExitCode = Environment.ExitCode != 0 ? Environment.ExitCode : 1; - } -#if DEBUG - Console.Error.WriteLine("done."); - - if (!Console.IsInputRedirected) - Console.ReadKey(); -#endif - return Environment.ExitCode; - } - - private static void CreateHashedFileAction(string filename, VectoHash h) - { - var destination = Path.Combine(Path.GetDirectoryName(filename), - Path.GetFileNameWithoutExtension(filename) + "_hashed.xml"); - if (File.Exists(destination)) { - Console.Error.WriteLine("hashed file already exists. overwrite? (y/n) "); - var key = Console.ReadKey(true); - while (!(key.KeyChar == 'y' || key.KeyChar == 'n')) { - Console.Error.WriteLine("overwrite? (y/n) "); - key = Console.ReadKey(true); - } - if (key.KeyChar == 'n') { - return; - } - Console.Error.WriteLine("overwriting file " + Path.GetFileName(destination)); - } else { - Console.Error.WriteLine("creating file " + Path.GetFileName(destination)); - } - var result = h.AddHash(); - var writer = new XmlTextWriter(destination, Encoding.UTF8) { - Formatting = Formatting.Indented, - Indentation = 4 - }; - result.WriteTo(writer); - writer.Flush(); - writer.Close(); - - if (_validateXML) { - ValidateXML(destination); - } - } - - private static void ValidateXML(string filename) - { - try { - var settings = new XmlReaderSettings { - ValidationType = ValidationType.Schema, - ValidationFlags = //XmlSchemaValidationFlags.ProcessInlineSchema | - //XmlSchemaValidationFlags.ProcessSchemaLocation | - XmlSchemaValidationFlags.ReportValidationWarnings - }; - settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack); - settings.Schemas.Add(GetXMLSchema("")); - - var vreader = XmlReader.Create(filename, settings); - var doc = new XmlDocument(); - doc.Load(vreader); - doc.Validate(ValidationCallBack); - //while (vreader.Read()) { - // Console.WriteLine(vreader.Value); - //} - if (xmlValid) { - WriteLine("Valid", ConsoleColor.Green); - } - } catch (Exception e) { - Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine("Failed to validate hashed XML file!"); - Console.Error.WriteLine(e.Message); - if (e.InnerException != null) { - Console.Error.WriteLine(e.InnerException.Message); - } - Console.ResetColor(); - } - } - - private static void ValidationCallBack(object sender, ValidationEventArgs args) - { - xmlValid = false; - if (args.Severity == XmlSeverityType.Error) { - throw new Exception(string.Format("Validation error: {0}" + Environment.NewLine + - "Line: {1}", args.Message, args.Exception.LineNumber)); - } else { - Console.Error.WriteLine(string.Format("Validation warning: {0}" + Environment.NewLine + - "Line: {1}", args.Message, args.Exception.LineNumber)); - } - } - - private static XmlSchemaSet GetXMLSchema(string version) - { - var resource = RessourceHelper.LoadResourceAsStream(RessourceHelper.ResourceType.XMLSchema, "VectoComponent.xsd"); - var xset = new XmlSchemaSet() { XmlResolver = new XmlResourceResolver() }; - var reader = XmlReader.Create(resource, new XmlReaderSettings(), "schema://"); - xset.Add(XmlSchema.Read(reader, null)); - xset.Compile(); - return xset; - } - - private static void ReadHashAction(string filename, VectoHash h) - { - WriteLine("reading hashes"); - var components = h.GetContainigComponents().GroupBy(s => s) - .Select(g => new { Entry = g.Key, Count = g.Count() }); - - foreach (var component in components) { - if (component.Entry == VectoComponents.Vehicle) { - continue; - } - for (var i = 0; i < component.Count; i++) { - var readHash = h.ReadHash(component.Entry, i); - WriteLine(" " + component.Entry.XMLElementName() + "\t ... " + readHash + ""); - } - } - } - - private static void ComputeHashAction(string filename, VectoHash h) - { - WriteLine("computing hashes"); - var components = h.GetContainigComponents(); - - if (components.Count > 1) { - var grouped = components.GroupBy(s => s) - .Select(g => new { Entry = g.Key, Count = g.Count() }); - foreach (var component in grouped) { - if (component.Entry == VectoComponents.Vehicle) { - continue; - } - for (var i = 0; i < component.Count; i++) { - var computedHash = h.ComputeHash(component.Entry, i); - WriteLine(" " + component.Entry.XMLElementName() + "\t ... " + computedHash + ""); - } - } - var jobHash = h.ComputeHash(); - WriteLine(" job file\t ... " + jobHash + ""); - } else { - var hash = h.ComputeHash(); - WriteLine(" computed hash: " + hash + ""); - } - } - - private static void VerifyHashAction(string filename, VectoHash h) - { - WriteLine("validating hashes"); - - var components = h.GetContainigComponents().GroupBy(s => s) - .Select(g => new { Entry = g.Key, Count = g.Count() }); - foreach (var component in components) { - if (component.Entry == VectoComponents.Vehicle) { - continue; - } - for (var i = 0; i < component.Count; i++) { - var result = h.ValidateHash(component.Entry, i); - WriteLine(" " + component.Entry.XMLElementName() + "\t ... " + (result ? "valid" : "invalid"), - result ? ConsoleColor.Green : ConsoleColor.Red); - } - } - } - - private static void WriteLine(string message, ConsoleColor foregroundColor = ConsoleColor.Gray) - { - Console.ForegroundColor = foregroundColor; - Console.WriteLine(message); - Console.ResetColor(); - } - - private static void ShowVersionInformation() - { - var hashingLib = Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory + "VectoHashing.dll").GetName(); - WriteLine(string.Format(@"HashingLibrary: {0}", hashingLib.Version)); - } - } +"; + + private static readonly Dictionary<string, HashingAction> Actions = new Dictionary<string, HashingAction> { + { "-v", VerifyHashAction }, + { "-c", ComputeHashAction }, + { "-r", ReadHashAction }, + { "-s", CreateHashedFileAction } + }; + + static bool _validateXML; + private static bool xmlValid = true; + + static int Main(string[] args) + { + try { + if (args.Contains("-h")) { + ShowVersionInformation(); + Console.Write(Help); + return 0; + } + + if (args.Contains("-x")) { + _validateXML = true; + } + + var fileList = args.Except(Actions.Keys.Concat(new[] { "-x" })).ToArray(); + if (fileList.Length == 0 || !args.Intersect(Actions.Keys.ToArray()).Any()) { + ShowVersionInformation(); + Console.Write(Usage); + return 0; + } + foreach (var file in fileList) { + Console.Error.WriteLine("processing " + Path.GetFileName(file)); + if (!File.Exists(Path.GetFullPath(file))) { + Console.Error.WriteLine("file " + Path.GetFullPath(file) + " not found!"); + continue; + } + foreach (var arg in args) { + if (Actions.ContainsKey(arg)) { + try { + var h = VectoHash.Load(file); + Actions[arg](Path.GetFullPath(file), h); + } catch (Exception e) { + Console.ForegroundColor = ConsoleColor.Red; + Console.Error.WriteLine(e.Message); + if (e.InnerException != null) { + Console.Error.WriteLine(e.InnerException.Message); + } + Console.ResetColor(); + } + } + } + } + } catch (Exception e) { + Console.ForegroundColor = ConsoleColor.Red; + Console.Error.WriteLine(e.Message); + Console.ResetColor(); + + //Console.Error.WriteLine("Please see log-file for further details (logs/log.txt)"); + Environment.ExitCode = Environment.ExitCode != 0 ? Environment.ExitCode : 1; + } +#if DEBUG + Console.Error.WriteLine("done."); + + if (!Console.IsInputRedirected) + Console.ReadKey(); +#endif + return Environment.ExitCode; + } + + private static void CreateHashedFileAction(string filename, VectoHash h) + { + var destination = Path.Combine(Path.GetDirectoryName(filename), + Path.GetFileNameWithoutExtension(filename) + "_hashed.xml"); + if (File.Exists(destination)) { + Console.Error.WriteLine("hashed file already exists. overwrite? (y/n) "); + var key = Console.ReadKey(true); + while (!(key.KeyChar == 'y' || key.KeyChar == 'n')) { + Console.Error.WriteLine("overwrite? (y/n) "); + key = Console.ReadKey(true); + } + if (key.KeyChar == 'n') { + return; + } + Console.Error.WriteLine("overwriting file " + Path.GetFileName(destination)); + } else { + Console.Error.WriteLine("creating file " + Path.GetFileName(destination)); + } + var result = h.AddHash(); + var writer = new XmlTextWriter(destination, Encoding.UTF8) { + Formatting = Formatting.Indented, + Indentation = 4 + }; + result.WriteTo(writer); + writer.Flush(); + writer.Close(); + + if (_validateXML) { + ValidateXML(destination); + } + } + + private static void ValidateXML(string filename) + { + try { + var settings = new XmlReaderSettings { + ValidationType = ValidationType.Schema, + ValidationFlags = //XmlSchemaValidationFlags.ProcessInlineSchema | + //XmlSchemaValidationFlags.ProcessSchemaLocation | + XmlSchemaValidationFlags.ReportValidationWarnings + }; + settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack); + settings.Schemas.Add(GetXMLSchema("")); + + var vreader = XmlReader.Create(filename, settings); + var doc = new XmlDocument(); + doc.Load(vreader); + doc.Validate(ValidationCallBack); + //while (vreader.Read()) { + // Console.WriteLine(vreader.Value); + //} + if (xmlValid) { + WriteLine("Valid", ConsoleColor.Green); + } + } catch (Exception e) { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("Failed to validate hashed XML file!"); + Console.Error.WriteLine(e.Message); + if (e.InnerException != null) { + Console.Error.WriteLine(e.InnerException.Message); + } + Console.ResetColor(); + } + } + + private static void ValidationCallBack(object sender, ValidationEventArgs args) + { + xmlValid = false; + if (args.Severity == XmlSeverityType.Error) { + throw new Exception(string.Format("Validation error: {0}" + Environment.NewLine + + "Line: {1}", args.Message, args.Exception.LineNumber)); + } else { + Console.Error.WriteLine(string.Format("Validation warning: {0}" + Environment.NewLine + + "Line: {1}", args.Message, args.Exception.LineNumber)); + } + } + + private static XmlSchemaSet GetXMLSchema(string version) + { + var resource = RessourceHelper.LoadResourceAsStream(RessourceHelper.ResourceType.XMLSchema, "VectoComponent.xsd"); + var xset = new XmlSchemaSet() { XmlResolver = new XmlResourceResolver() }; + var reader = XmlReader.Create(resource, new XmlReaderSettings(), "schema://"); + xset.Add(XmlSchema.Read(reader, null)); + xset.Compile(); + return xset; + } + + private static void ReadHashAction(string filename, VectoHash h) + { + WriteLine("reading hashes"); + var components = h.GetContainigComponents().GroupBy(s => s) + .Select(g => new { Entry = g.Key, Count = g.Count() }); + + foreach (var component in components) { + if (component.Entry == VectoComponents.Vehicle) { + continue; + } + for (var i = 0; i < component.Count; i++) { + var readHash = h.ReadHash(component.Entry, i); + WriteLine(" " + component.Entry.XMLElementName() + "\t ... " + readHash + ""); + } + } + } + + private static void ComputeHashAction(string filename, VectoHash h) + { + WriteLine("computing hashes"); + var components = h.GetContainigComponents(); + + if (components.Count > 1) { + var grouped = components.GroupBy(s => s) + .Select(g => new { Entry = g.Key, Count = g.Count() }); + foreach (var component in grouped) { + if (component.Entry == VectoComponents.Vehicle) { + continue; + } + for (var i = 0; i < component.Count; i++) { + var computedHash = h.ComputeHash(component.Entry, i); + WriteLine(" " + component.Entry.XMLElementName() + "\t ... " + computedHash + ""); + } + } + var jobHash = h.ComputeHash(); + WriteLine(" job file\t ... " + jobHash + ""); + } else { + var hash = h.ComputeHash(); + WriteLine(" computed hash: " + hash + ""); + } + } + + private static void VerifyHashAction(string filename, VectoHash h) + { + WriteLine("validating hashes"); + + var components = h.GetContainigComponents().GroupBy(s => s) + .Select(g => new { Entry = g.Key, Count = g.Count() }); + foreach (var component in components) { + if (component.Entry == VectoComponents.Vehicle) { + continue; + } + for (var i = 0; i < component.Count; i++) { + var result = h.ValidateHash(component.Entry, i); + WriteLine(" " + component.Entry.XMLElementName() + "\t ... " + (result ? "valid" : "invalid"), + result ? ConsoleColor.Green : ConsoleColor.Red); + } + } + } + + private static void WriteLine(string message, ConsoleColor foregroundColor = ConsoleColor.Gray) + { + Console.ForegroundColor = foregroundColor; + Console.WriteLine(message); + Console.ResetColor(); + } + + private static void ShowVersionInformation() + { + var hashingLib = Assembly.LoadFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "VectoHashing.dll")) + .GetName(); + WriteLine(string.Format(@"HashingLibrary: {0}", hashingLib.Version)); + } + } } \ No newline at end of file diff --git a/VectoConsole/Program.cs b/VectoConsole/Program.cs index c40f91769e4cfd49ed076e9a922a9d8d522affd9..9e4d0f73b25843e4f22cecdf1fdf243531c1ba0e 100644 --- a/VectoConsole/Program.cs +++ b/VectoConsole/Program.cs @@ -29,41 +29,41 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Threading; -using System.Xml; -using System.Xml.Linq; -using NLog; -using NLog.Config; -using NLog.Targets; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.InputData; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCore.Configuration; -using TUGraz.VectoCore.InputData.FileIO.JSON; -using TUGraz.VectoCore.InputData.FileIO.XML.Declaration; -using TUGraz.VectoCore.InputData.FileIO.XML.Engineering; -using TUGraz.VectoCore.Models.Simulation.Impl; -using TUGraz.VectoCore.OutputData; -using TUGraz.VectoCore.OutputData.FileIO; -using LogManager = NLog.LogManager; - -namespace VectoConsole -{ - internal static class Program - { - public static List<string> WarningMessages = new List<string>(); - - private static int _numLines; - private static int ProgessCounter { get; set; } - - private const string Usage = @"Usage: vectocmd.exe [-h] [-v] FILE1.vecto [FILE2.vecto ...]"; - +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading; +using System.Xml; +using System.Xml.Linq; +using NLog; +using NLog.Config; +using NLog.Targets; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCore.Configuration; +using TUGraz.VectoCore.InputData.FileIO.JSON; +using TUGraz.VectoCore.InputData.FileIO.XML.Declaration; +using TUGraz.VectoCore.InputData.FileIO.XML.Engineering; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.OutputData; +using TUGraz.VectoCore.OutputData.FileIO; +using LogManager = NLog.LogManager; + +namespace VectoConsole +{ + internal static class Program + { + public static List<string> WarningMessages = new List<string>(); + + private static int _numLines; + private static int ProgessCounter { get; set; } + + private const string Usage = @"Usage: vectocmd.exe [-h] [-v] FILE1.vecto [FILE2.vecto ...]"; + private const string Help = @" Commandline Interface for Vecto. @@ -94,221 +94,221 @@ Examples: vecto.exe -v 24tCoach.vecto vecto.exe -v jobs\40t_Long_Haul_Truck.vecto vecto.exe -h -"; - - private static JobContainer _jobContainer; - private static bool _quiet; - private static bool _debugEnabled; - - private static int Main(string[] args) - { - try { - // on -h display help and terminate. - if (args.Contains("-h")) { - ShowVersionInformation(); - Console.Write(Help); - return 0; - } - - if (args.Contains("-q")) { - _quiet = true; - } - - // on -v: activate verbose console logger - var logLevel = LogLevel.Fatal; - - // Fatal > Error > Warn > Info > Debug > Trace - - if (args.Contains("-v")) { - // display errors, warnings - logLevel = LogLevel.Warn; - _debugEnabled = true; - } else if (args.Contains("-vv")) { - // also display info - logLevel = LogLevel.Info; - _debugEnabled = true; - } else if (args.Contains("-vvv")) { - // display debug messages - logLevel = LogLevel.Debug; - _debugEnabled = true; - } else if (args.Contains("-vvvv")) { - // display everything! - logLevel = LogLevel.Trace; - _debugEnabled = true; - } - - var config = LogManager.Configuration; - config.LoggingRules.Add(new LoggingRule("*", logLevel, config.FindTargetByName("LogFile"))); - - if (logLevel > LogLevel.Warn) { - var methodCallTarget = new MethodCallTarget { - ClassName = "VectoConsole.Program, vectocmd", - MethodName = "LogWarning", - Name = "WarningLogger" - }; - methodCallTarget.Parameters.Add(new MethodCallParameter("${level}")); - methodCallTarget.Parameters.Add(new MethodCallParameter("${message}")); - config.LoggingRules.Add(new LoggingRule("*", LogLevel.Warn, methodCallTarget)); - } - LogManager.Configuration = config; - - if (args.Contains("-V") || _debugEnabled) { - ShowVersionInformation(); - } - - var fileList = - args.Except(new[] { "-v", "-vv", "-vvv", "-vvvv", "-V", "-nv", "-mod", "-eng", "-t", "-1Hz", "-q", "-act" }) - .ToArray(); - var jobFiles = - fileList.Where( - f => - Path.GetExtension(f) == Constants.FileExtensions.VectoJobFile || - Path.GetExtension(f) == Constants.FileExtensions.VectoXMLDeclarationFile).ToList(); - - // if no other arguments given: display usage and terminate - if (!args.Any()) { - Console.Write(Usage); - return 1; - } - - var stopWatch = new Stopwatch(); - var timings = new Dictionary<string, double>(); - - // process the file list and start simulation - var fileWriter = new FileOutputWriter(fileList.First()); - var sumWriter = new SummaryDataContainer(fileWriter); - _jobContainer = new JobContainer(sumWriter); - - var mode = ExecutionMode.Declaration; - if (args.Contains("-eng")) { - mode = ExecutionMode.Engineering; - WriteLine(@"Switching to Engineering Mode. Make sure the job-file is saved in engineering mode!", - ConsoleColor.White); - } - - stopWatch.Start(); - - if (!jobFiles.Any()) { - WriteLine(@"No Job files found. Please restart the application with a valid '.vecto' file.", ConsoleColor.Red); - return 1; - } - - foreach (var file in jobFiles) { - WriteLine(@"Reading job: " + file); - var extension = Path.GetExtension(file); - IInputDataProvider dataProvider = null; - switch (extension) { - case Constants.FileExtensions.VectoJobFile: - dataProvider = JSONInputDataFactory.ReadJsonJob(file); - break; - case ".xml": - var xDocument = XDocument.Load(file); - var rootNode = xDocument == null ? "" : xDocument.Root.Name.LocalName; - switch (rootNode) { - case "VectoInputEngineering": - dataProvider = new XMLEngineeringInputDataProvider(file, true); - break; - case "VectoInputDeclaration": - dataProvider = new XMLDeclarationInputDataProvider(XmlReader.Create(file), true); - break; - } - break; - } - - if (dataProvider == null) { - WriteLine(string.Format(@"failed to read job: '{0}'", file)); - continue; - } - - fileWriter = new FileOutputWriter(file); - var runsFactory = new SimulatorFactory(mode, dataProvider, fileWriter) { - ModalResults1Hz = args.Contains("-1Hz"), - WriteModalResults = args.Contains("-mod"), - ActualModalData = args.Contains("-act"), - Validate = args.Contains("-nv"), - }; - - _jobContainer.AddRuns(runsFactory); - } - - WriteLine(); - WriteLine(@"Detected cycles:", ConsoleColor.White); - - foreach (var cycle in _jobContainer.GetCycleTypes()) { +"; + + private static JobContainer _jobContainer; + private static bool _quiet; + private static bool _debugEnabled; + + private static int Main(string[] args) + { + try { + // on -h display help and terminate. + if (args.Contains("-h")) { + ShowVersionInformation(); + Console.Write(Help); + return 0; + } + + if (args.Contains("-q")) { + _quiet = true; + } + + // on -v: activate verbose console logger + var logLevel = LogLevel.Fatal; + + // Fatal > Error > Warn > Info > Debug > Trace + + if (args.Contains("-v")) { + // display errors, warnings + logLevel = LogLevel.Warn; + _debugEnabled = true; + } else if (args.Contains("-vv")) { + // also display info + logLevel = LogLevel.Info; + _debugEnabled = true; + } else if (args.Contains("-vvv")) { + // display debug messages + logLevel = LogLevel.Debug; + _debugEnabled = true; + } else if (args.Contains("-vvvv")) { + // display everything! + logLevel = LogLevel.Trace; + _debugEnabled = true; + } + + var config = LogManager.Configuration; + config.LoggingRules.Add(new LoggingRule("*", logLevel, config.FindTargetByName("LogFile"))); + + if (logLevel > LogLevel.Warn) { + var methodCallTarget = new MethodCallTarget { + ClassName = "VectoConsole.Program, vectocmd", + MethodName = "LogWarning", + Name = "WarningLogger" + }; + methodCallTarget.Parameters.Add(new MethodCallParameter("${level}")); + methodCallTarget.Parameters.Add(new MethodCallParameter("${message}")); + config.LoggingRules.Add(new LoggingRule("*", LogLevel.Warn, methodCallTarget)); + } + LogManager.Configuration = config; + + if (args.Contains("-V") || _debugEnabled) { + ShowVersionInformation(); + } + + var fileList = + args.Except(new[] { "-v", "-vv", "-vvv", "-vvvv", "-V", "-nv", "-mod", "-eng", "-t", "-1Hz", "-q", "-act" }) + .ToArray(); + var jobFiles = + fileList.Where( + f => + Path.GetExtension(f) == Constants.FileExtensions.VectoJobFile || + Path.GetExtension(f) == Constants.FileExtensions.VectoXMLDeclarationFile).ToList(); + + // if no other arguments given: display usage and terminate + if (!args.Any()) { + Console.Write(Usage); + return 1; + } + + var stopWatch = new Stopwatch(); + var timings = new Dictionary<string, double>(); + + // process the file list and start simulation + var fileWriter = new FileOutputWriter(fileList.First()); + var sumWriter = new SummaryDataContainer(fileWriter); + _jobContainer = new JobContainer(sumWriter); + + var mode = ExecutionMode.Declaration; + if (args.Contains("-eng")) { + mode = ExecutionMode.Engineering; + WriteLine(@"Switching to Engineering Mode. Make sure the job-file is saved in engineering mode!", + ConsoleColor.White); + } + + stopWatch.Start(); + + if (!jobFiles.Any()) { + WriteLine(@"No Job files found. Please restart the application with a valid '.vecto' file.", ConsoleColor.Red); + return 1; + } + + foreach (var file in jobFiles) { + WriteLine(@"Reading job: " + file); + var extension = Path.GetExtension(file); + IInputDataProvider dataProvider = null; + switch (extension) { + case Constants.FileExtensions.VectoJobFile: + dataProvider = JSONInputDataFactory.ReadJsonJob(file); + break; + case ".xml": + var xDocument = XDocument.Load(file); + var rootNode = xDocument == null ? "" : xDocument.Root.Name.LocalName; + switch (rootNode) { + case "VectoInputEngineering": + dataProvider = new XMLEngineeringInputDataProvider(file, true); + break; + case "VectoInputDeclaration": + dataProvider = new XMLDeclarationInputDataProvider(XmlReader.Create(file), true); + break; + } + break; + } + + if (dataProvider == null) { + WriteLine(string.Format(@"failed to read job: '{0}'", file)); + continue; + } + + fileWriter = new FileOutputWriter(file); + var runsFactory = new SimulatorFactory(mode, dataProvider, fileWriter) { + ModalResults1Hz = args.Contains("-1Hz"), + WriteModalResults = args.Contains("-mod"), + ActualModalData = args.Contains("-act"), + Validate = args.Contains("-nv"), + }; + + _jobContainer.AddRuns(runsFactory); + } + + WriteLine(); + WriteLine(@"Detected cycles:", ConsoleColor.White); + + foreach (var cycle in _jobContainer.GetCycleTypes()) { WriteLineStdOut(string.Format(@" {0}: {1}", cycle.Name, cycle.CycleType)); - } - WriteLine(); - - stopWatch.Stop(); - timings.Add("Reading input files", stopWatch.Elapsed.TotalMilliseconds); - stopWatch.Reset(); - - WriteLine(@"Starting simulation runs", ConsoleColor.White); - if (_debugEnabled) { - WriteLine(@"Debug-Output is enabled, executing simulation runs sequentially", ConsoleColor.Yellow); - } - WriteLine(); - - DisplayWarnings(); - WriteLine(); - stopWatch.Start(); - _jobContainer.Execute(!_debugEnabled); - - Console.CancelKeyPress += (sender, e) => { - if (e.SpecialKey == ConsoleSpecialKey.ControlC) { - e.Cancel = true; - _jobContainer.CancelCurrent(); - } - }; - - while (!_jobContainer.AllCompleted) { - PrintProgress(_jobContainer.GetProgress()); - Thread.Sleep(100); - } - stopWatch.Stop(); - timings.Add("Simulation runs", stopWatch.Elapsed.TotalMilliseconds); - - PrintProgress(_jobContainer.GetProgress(), args.Contains("-t"), force: true); - - if (args.Contains("-t")) { - PrintTimings(timings); - } - - DisplayWarnings(); - } catch (Exception e) { - if (!_quiet) { - Console.ForegroundColor = ConsoleColor.Red; - Console.Error.WriteLine(e.Message); - Console.ResetColor(); - - Console.Error.WriteLine("Please see log-file for further details (logs/log.txt)"); - } - Environment.ExitCode = Environment.ExitCode != 0 ? Environment.ExitCode : 1; - } - -#if DEBUG + } + WriteLine(); + + stopWatch.Stop(); + timings.Add("Reading input files", stopWatch.Elapsed.TotalMilliseconds); + stopWatch.Reset(); + + WriteLine(@"Starting simulation runs", ConsoleColor.White); + if (_debugEnabled) { + WriteLine(@"Debug-Output is enabled, executing simulation runs sequentially", ConsoleColor.Yellow); + } + WriteLine(); + + DisplayWarnings(); + WriteLine(); + stopWatch.Start(); + _jobContainer.Execute(!_debugEnabled); + + Console.CancelKeyPress += (sender, e) => { + if (e.SpecialKey == ConsoleSpecialKey.ControlC) { + e.Cancel = true; + _jobContainer.CancelCurrent(); + } + }; + + while (!_jobContainer.AllCompleted) { + PrintProgress(_jobContainer.GetProgress()); + Thread.Sleep(100); + } + stopWatch.Stop(); + timings.Add("Simulation runs", stopWatch.Elapsed.TotalMilliseconds); + + PrintProgress(_jobContainer.GetProgress(), args.Contains("-t"), force: true); + + if (args.Contains("-t")) { + PrintTimings(timings); + } + + DisplayWarnings(); + } catch (Exception e) { + if (!_quiet) { + Console.ForegroundColor = ConsoleColor.Red; + Console.Error.WriteLine(e.Message); + Console.ResetColor(); + + Console.Error.WriteLine("Please see log-file for further details (logs/log.txt)"); + } + Environment.ExitCode = Environment.ExitCode != 0 ? Environment.ExitCode : 1; + } + +#if DEBUG Console.Error.WriteLine("done."); if (!Console.IsInputRedirected) - Console.ReadKey(); -#endif - return Environment.ExitCode; - } - - private static void WriteLine() - { - if (_quiet && !_debugEnabled) { - return; - } + Console.ReadKey(); +#endif + return Environment.ExitCode; + } + + private static void WriteLine() + { + if (_quiet && !_debugEnabled) { + return; + } Console.Error.WriteLine(); - } - - private static void WriteLine(string message, ConsoleColor foregroundColor = ConsoleColor.Gray) - { - if (_quiet && !_debugEnabled) { - return; - } - Console.ForegroundColor = foregroundColor; + } + + private static void WriteLine(string message, ConsoleColor foregroundColor = ConsoleColor.Gray) + { + if (_quiet && !_debugEnabled) { + return; + } + Console.ForegroundColor = foregroundColor; Console.Error.WriteLine(message); Console.ResetColor(); } @@ -319,97 +319,97 @@ Examples: return; } Console.ForegroundColor = foregroundColor; - Console.WriteLine(message); - Console.ResetColor(); - } - - private static void DisplayWarnings() - { - if (_quiet) { - return; - } - - if (WarningMessages.Any()) { - Console.ForegroundColor = ConsoleColor.Yellow; - foreach (var message in WarningMessages) { - Console.Error.WriteLine(message); - } - Console.ResetColor(); - } - WarningMessages.Clear(); - } - - public static void LogWarning(string level, string message) - { - if (level == "Warn") { - WarningMessages.Add(message); - } - } - - private static void ShowVersionInformation() - { - WriteLine(string.Format(@"VectoConsole: {0}", Assembly.GetExecutingAssembly().GetName().Version)); - WriteLine(string.Format(@"VectoCore: {0}", - Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + "VectoCore.dll").GetName().Version)); - } - - private static void PrintProgress(Dictionary<int, JobContainer.ProgressEntry> progessData, - bool showTiming = true, bool force = false) - { - try { - if (_quiet || (Console.IsOutputRedirected && !force)) { - return; - } - - if (!Console.IsOutputRedirected) { - Console.SetCursorPosition(0, Console.CursorTop - _numLines); - } - - _numLines = 0; - var sumProgress = 0.0; - foreach (var progressEntry in progessData) { - if (progressEntry.Value.Success) { - Console.ForegroundColor = ConsoleColor.Green; - } else if (progressEntry.Value.Error != null) { - Console.ForegroundColor = ConsoleColor.Red; - } - var timingString = ""; - if (showTiming && progressEntry.Value.ExecTime > 0) { - timingString = string.Format("{0,9:F2}s", progressEntry.Value.ExecTime / 1000.0); - } - var runName = string.Format("{0} {1} {2}", progressEntry.Value.RunName, progressEntry.Value.CycleName, - progressEntry.Value.RunSuffix); - Console.WriteLine(@"{0,-60} {1,8:P}{2}", runName, progressEntry.Value.Progress, timingString); - Console.ResetColor(); - sumProgress += progressEntry.Value.Progress; - _numLines++; - } - sumProgress /= _numLines; - var spinner = "/-\\|"[ProgessCounter++ % 4]; - var bar = new string('#', (int)(sumProgress * 100.0 / 2)); - Console.WriteLine(@" {2} [{1,-50}] [{0,7:P}]", sumProgress, bar, spinner); - - if (WarningMessages.Any()) { - Console.ForegroundColor = ConsoleColor.Yellow; + Console.WriteLine(message); + Console.ResetColor(); + } + + private static void DisplayWarnings() + { + if (_quiet) { + return; + } + + if (WarningMessages.Any()) { + Console.ForegroundColor = ConsoleColor.Yellow; + foreach (var message in WarningMessages) { + Console.Error.WriteLine(message); + } + Console.ResetColor(); + } + WarningMessages.Clear(); + } + + public static void LogWarning(string level, string message) + { + if (level == "Warn") { + WarningMessages.Add(message); + } + } + + private static void ShowVersionInformation() + { + WriteLine(string.Format(@"VectoConsole: {0}", Assembly.GetExecutingAssembly().GetName().Version)); + WriteLine(string.Format(@"VectoCore: {0}", + Assembly.LoadFrom(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "VectoCore.dll")).GetName().Version)); + } + + private static void PrintProgress(Dictionary<int, JobContainer.ProgressEntry> progessData, + bool showTiming = true, bool force = false) + { + try { + if (_quiet || (Console.IsOutputRedirected && !force)) { + return; + } + + if (!Console.IsOutputRedirected) { + Console.SetCursorPosition(0, Console.CursorTop - _numLines); + } + + _numLines = 0; + var sumProgress = 0.0; + foreach (var progressEntry in progessData) { + if (progressEntry.Value.Success) { + Console.ForegroundColor = ConsoleColor.Green; + } else if (progressEntry.Value.Error != null) { + Console.ForegroundColor = ConsoleColor.Red; + } + var timingString = ""; + if (showTiming && progressEntry.Value.ExecTime > 0) { + timingString = string.Format("{0,9:F2}s", progressEntry.Value.ExecTime / 1000.0); + } + var runName = string.Format("{0} {1} {2}", progressEntry.Value.RunName, progressEntry.Value.CycleName, + progressEntry.Value.RunSuffix); + Console.WriteLine(@"{0,-60} {1,8:P}{2}", runName, progressEntry.Value.Progress, timingString); + Console.ResetColor(); + sumProgress += progressEntry.Value.Progress; + _numLines++; + } + sumProgress /= _numLines; + var spinner = "/-\\|"[ProgessCounter++ % 4]; + var bar = new string('#', (int)(sumProgress * 100.0 / 2)); + Console.WriteLine(@" {2} [{1,-50}] [{0,7:P}]", sumProgress, bar, spinner); + + if (WarningMessages.Any()) { + Console.ForegroundColor = ConsoleColor.Yellow; Console.Error.WriteLine(@"Warnings: {0,5}", WarningMessages.Count); - Console.ResetColor(); - } else { - Console.WriteLine(""); - } - - _numLines += 2; - } catch (Exception e) { - throw new VectoException("Error during writing progress to output: " + e.Message); - } - } - - private static void PrintTimings(Dictionary<string, double> timings) - { + Console.ResetColor(); + } else { + Console.WriteLine(""); + } + + _numLines += 2; + } catch (Exception e) { + throw new VectoException("Error during writing progress to output: " + e.Message); + } + } + + private static void PrintTimings(Dictionary<string, double> timings) + { Console.Error.WriteLine(); Console.Error.WriteLine(@"---- timing information ----"); - foreach (var timing in timings) { + foreach (var timing in timings) { Console.Error.WriteLine(@"{0,-20}: {1:F2}s", timing.Key, timing.Value / 1000); - } - } - } + } + } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/OutputData/XML/XMLCustomerReport.cs b/VectoCore/VectoCore/OutputData/XML/XMLCustomerReport.cs index f940f7acec828e8a4787108e1b0dba82d60f4974..8742c8467be3c5437720170033726828683d3488 100644 --- a/VectoCore/VectoCore/OutputData/XML/XMLCustomerReport.cs +++ b/VectoCore/VectoCore/OutputData/XML/XMLCustomerReport.cs @@ -29,158 +29,158 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Xml; -using System.Xml.Linq; -using TUGraz.IVT.VectoXML.Writer; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Resources; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.Impl; -using TUGraz.VectoHashing; - -namespace TUGraz.VectoCore.OutputData.XML -{ - public class XMLCustomerReport - { - protected readonly XElement VehiclePart; - - protected XElement InputDataIntegrity; - - protected readonly XElement Results; - - protected readonly XNamespace tns; - protected readonly XNamespace di; - private bool allSuccess = true; - - public XMLCustomerReport() - { - di = "http://www.w3.org/2000/09/xmldsig#"; - tns = "urn:tugraz:ivt:VectoAPI:COCOutput:v0.4"; - VehiclePart = new XElement(tns + XMLNames.Component_Vehicle); - Results = new XElement(tns + "Results"); - } - - public void Initialize(VectoRunData modelData, Segment segment) - { - VehiclePart.Add( - new XElement(tns + XMLNames.Component_Model, modelData.VehicleData.ModelName), - new XElement(tns + XMLNames.Component_Manufacturer, modelData.VehicleData.Manufacturer), - new XElement(tns + XMLNames.Component_ManufacturerAddress, modelData.VehicleData.ManufacturerAddress), - new XElement(tns + XMLNames.Vehicle_VIN, modelData.VehicleData.VIN), - new XElement(tns + XMLNames.Vehicle_VehicleCategory, modelData.VehicleData.LegislativeClass), - new XElement(tns + "VehicleGroup", segment.VehicleClass.GetClassNumber()), - new XElement(tns + XMLNames.Vehicle_AxleConfiguration, modelData.VehicleData.AxleConfiguration.GetName()), - new XElement(tns + XMLNames.Vehicle_GrossVehicleMass, modelData.VehicleData.GrossVehicleWeight.ToXMLFormat(0)), - new XElement(tns + XMLNames.Vehicle_CurbMassChassis, modelData.VehicleData.CurbWeight.ToXMLFormat(0)), - new XElement(tns + "EngineRatedPower", modelData.EngineData.RatedPowerDeclared.ToXMLFormat(0)), - new XElement(tns + "EngineDisplacement", - modelData.EngineData.Displacement.ConvertTo().Cubic.Centi.Meter.ToXMLFormat(0)), - new XElement(tns + XMLNames.Engine_FuelType, modelData.EngineData.FuelType.ToXMLFormat()), - new XElement(tns + "TransmissionMainCertificationMethod", modelData.GearboxData.CertificationMethod.ToXMLFormat()), - new XElement(tns + XMLNames.Gearbox_TransmissionType, modelData.GearboxData.Type.ToXMLFormat()), - new XElement(tns + "GearsCount", modelData.GearboxData.Gears.Count), - new XElement(tns + "Retarder", modelData.Retarder.Type.IsDedicatedComponent()), - new XElement(tns + "AxleRatio", modelData.AxleGearData.AxleGear.Ratio.ToXMLFormat(3)) - ); - InputDataIntegrity = new XElement(tns + "InputDataSignature", - modelData.InputDataHash == null ? CreateDummySig() : new XElement(modelData.InputDataHash)); - } - - private XElement CreateDummySig() - { - return new XElement(di + XMLNames.DI_Signature_Reference, - new XElement(di + XMLNames.DI_Signature_Reference_DigestMethod, - new XAttribute(XMLNames.DI_Signature_Algorithm_Attr, "null")), - new XElement(di + XMLNames.DI_Signature_Reference_DigestValue, "NOT AVAILABLE") - ); - } - - public void AddResult( - DeclarationReport<XMLDeclarationReport.ResultEntry>.ResultContainer<XMLDeclarationReport.ResultEntry> entry) - { - foreach (var resultEntry in entry.ModData) { - allSuccess &= resultEntry.Value.Status == VectoRun.Status.Success; - Results.Add(new XElement(tns + "Result", - new XAttribute("status", resultEntry.Value.Status.ToString().ToLower()), - new XElement(tns + "Mission", entry.Mission.ToXMLFormat()), - GetResults(resultEntry))); - } - } - - private object[] GetResults(KeyValuePair<LoadingType, XMLDeclarationReport.ResultEntry> resultEntry) - { - switch (resultEntry.Value.Status) { - case VectoRun.Status.Pending: - case VectoRun.Status.Running: - return null; // should not happen! - case VectoRun.Status.Success: - return GetSuccessResultEntry(resultEntry.Value); - case VectoRun.Status.Canceled: - case VectoRun.Status.Aborted: - return new object[] { - new XElement("Error", resultEntry.Value.Error) - }; - default: - throw new ArgumentOutOfRangeException(); - } - } - - private object[] GetSuccessResultEntry(XMLDeclarationReport.ResultEntry result) - { - return new object[] { - new XElement(tns + "Payload", new XAttribute("unit", "kg"), result.Payload.ToXMLFormat(0)), - new XElement(tns + "FuelType", result.FuelType.ToXMLFormat()), - new XElement(tns + "AverageSpeed", new XAttribute("unit", "km/h"), result.AverageSpeed.AsKmph.ToXMLFormat(1)), - XMLDeclarationReport.GetResults(result, tns, false).Cast<object>().ToArray() - }; - } - - private XElement GetApplicationInfo() - { - var vectodll = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + "VectoCore.dll").GetName(); - return new XElement(tns + "ApplicationInformation", - new XElement(tns + "SimulationToolVersion", vectodll.Version), - new XElement(tns + "Date", XmlConvert.ToString(DateTime.Now, XmlDateTimeSerializationMode.Utc))); - } - - public void GenerateReport(XElement resultSignature) - { - var xsi = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance"); - var retVal = new XDocument(); - var results = new XElement(Results); - results.AddFirst(new XElement(tns + "Status", allSuccess ? "success" : "error")); - var vehicle = new XElement(VehiclePart); - vehicle.Add(InputDataIntegrity); - retVal.Add(new XElement(tns + "VectoCustomerInformation", - new XAttribute("schemaVersion", "0.4"), - new XAttribute(XNamespace.Xmlns + "xsi", xsi.NamespaceName), - new XAttribute("xmlns", tns), - new XAttribute(XNamespace.Xmlns + "di", di), - new XAttribute(xsi + "schemaLocation", - string.Format("{0} {1}VectoCOC.xsd", tns, AbstractXMLWriter.SchemaLocationBaseUrl)), - new XElement(tns + "Data", - vehicle, - new XElement(tns + "ResultDataSignature", resultSignature), - results, - GetApplicationInfo()) - ) - ); - var stream = new MemoryStream(); - var writer = new StreamWriter(stream); - writer.Write(retVal); - writer.Flush(); - stream.Seek(0, SeekOrigin.Begin); - var h = VectoHash.Load(stream); - Report = h.AddHash(); - } - - public XDocument Report { get; private set; } - } +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Xml; +using System.Xml.Linq; +using TUGraz.IVT.VectoXML.Writer; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Resources; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoHashing; + +namespace TUGraz.VectoCore.OutputData.XML +{ + public class XMLCustomerReport + { + protected readonly XElement VehiclePart; + + protected XElement InputDataIntegrity; + + protected readonly XElement Results; + + protected readonly XNamespace tns; + protected readonly XNamespace di; + private bool allSuccess = true; + + public XMLCustomerReport() + { + di = "http://www.w3.org/2000/09/xmldsig#"; + tns = "urn:tugraz:ivt:VectoAPI:COCOutput:v0.4"; + VehiclePart = new XElement(tns + XMLNames.Component_Vehicle); + Results = new XElement(tns + "Results"); + } + + public void Initialize(VectoRunData modelData, Segment segment) + { + VehiclePart.Add( + new XElement(tns + XMLNames.Component_Model, modelData.VehicleData.ModelName), + new XElement(tns + XMLNames.Component_Manufacturer, modelData.VehicleData.Manufacturer), + new XElement(tns + XMLNames.Component_ManufacturerAddress, modelData.VehicleData.ManufacturerAddress), + new XElement(tns + XMLNames.Vehicle_VIN, modelData.VehicleData.VIN), + new XElement(tns + XMLNames.Vehicle_VehicleCategory, modelData.VehicleData.LegislativeClass), + new XElement(tns + "VehicleGroup", segment.VehicleClass.GetClassNumber()), + new XElement(tns + XMLNames.Vehicle_AxleConfiguration, modelData.VehicleData.AxleConfiguration.GetName()), + new XElement(tns + XMLNames.Vehicle_GrossVehicleMass, modelData.VehicleData.GrossVehicleWeight.ToXMLFormat(0)), + new XElement(tns + XMLNames.Vehicle_CurbMassChassis, modelData.VehicleData.CurbWeight.ToXMLFormat(0)), + new XElement(tns + "EngineRatedPower", modelData.EngineData.RatedPowerDeclared.ToXMLFormat(0)), + new XElement(tns + "EngineDisplacement", + modelData.EngineData.Displacement.ConvertTo().Cubic.Centi.Meter.ToXMLFormat(0)), + new XElement(tns + XMLNames.Engine_FuelType, modelData.EngineData.FuelType.ToXMLFormat()), + new XElement(tns + "TransmissionMainCertificationMethod", modelData.GearboxData.CertificationMethod.ToXMLFormat()), + new XElement(tns + XMLNames.Gearbox_TransmissionType, modelData.GearboxData.Type.ToXMLFormat()), + new XElement(tns + "GearsCount", modelData.GearboxData.Gears.Count), + new XElement(tns + "Retarder", modelData.Retarder.Type.IsDedicatedComponent()), + new XElement(tns + "AxleRatio", modelData.AxleGearData.AxleGear.Ratio.ToXMLFormat(3)) + ); + InputDataIntegrity = new XElement(tns + "InputDataSignature", + modelData.InputDataHash == null ? CreateDummySig() : new XElement(modelData.InputDataHash)); + } + + private XElement CreateDummySig() + { + return new XElement(di + XMLNames.DI_Signature_Reference, + new XElement(di + XMLNames.DI_Signature_Reference_DigestMethod, + new XAttribute(XMLNames.DI_Signature_Algorithm_Attr, "null")), + new XElement(di + XMLNames.DI_Signature_Reference_DigestValue, "NOT AVAILABLE") + ); + } + + public void AddResult( + DeclarationReport<XMLDeclarationReport.ResultEntry>.ResultContainer<XMLDeclarationReport.ResultEntry> entry) + { + foreach (var resultEntry in entry.ModData) { + allSuccess &= resultEntry.Value.Status == VectoRun.Status.Success; + Results.Add(new XElement(tns + "Result", + new XAttribute("status", resultEntry.Value.Status.ToString().ToLower()), + new XElement(tns + "Mission", entry.Mission.ToXMLFormat()), + GetResults(resultEntry))); + } + } + + private object[] GetResults(KeyValuePair<LoadingType, XMLDeclarationReport.ResultEntry> resultEntry) + { + switch (resultEntry.Value.Status) { + case VectoRun.Status.Pending: + case VectoRun.Status.Running: + return null; // should not happen! + case VectoRun.Status.Success: + return GetSuccessResultEntry(resultEntry.Value); + case VectoRun.Status.Canceled: + case VectoRun.Status.Aborted: + return new object[] { + new XElement("Error", resultEntry.Value.Error) + }; + default: + throw new ArgumentOutOfRangeException(); + } + } + + private object[] GetSuccessResultEntry(XMLDeclarationReport.ResultEntry result) + { + return new object[] { + new XElement(tns + "Payload", new XAttribute("unit", "kg"), result.Payload.ToXMLFormat(0)), + new XElement(tns + "FuelType", result.FuelType.ToXMLFormat()), + new XElement(tns + "AverageSpeed", new XAttribute("unit", "km/h"), result.AverageSpeed.AsKmph.ToXMLFormat(1)), + XMLDeclarationReport.GetResults(result, tns, false).Cast<object>().ToArray() + }; + } + + private XElement GetApplicationInfo() + { + var vectodll = Assembly.LoadFrom(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "VectoCore.dll")).GetName(); + return new XElement(tns + "ApplicationInformation", + new XElement(tns + "SimulationToolVersion", vectodll.Version), + new XElement(tns + "Date", XmlConvert.ToString(DateTime.Now, XmlDateTimeSerializationMode.Utc))); + } + + public void GenerateReport(XElement resultSignature) + { + var xsi = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance"); + var retVal = new XDocument(); + var results = new XElement(Results); + results.AddFirst(new XElement(tns + "Status", allSuccess ? "success" : "error")); + var vehicle = new XElement(VehiclePart); + vehicle.Add(InputDataIntegrity); + retVal.Add(new XElement(tns + "VectoCustomerInformation", + new XAttribute("schemaVersion", "0.4"), + new XAttribute(XNamespace.Xmlns + "xsi", xsi.NamespaceName), + new XAttribute("xmlns", tns), + new XAttribute(XNamespace.Xmlns + "di", di), + new XAttribute(xsi + "schemaLocation", + string.Format("{0} {1}VectoCOC.xsd", tns, AbstractXMLWriter.SchemaLocationBaseUrl)), + new XElement(tns + "Data", + vehicle, + new XElement(tns + "ResultDataSignature", resultSignature), + results, + GetApplicationInfo()) + ) + ); + var stream = new MemoryStream(); + var writer = new StreamWriter(stream); + writer.Write(retVal); + writer.Flush(); + stream.Seek(0, SeekOrigin.Begin); + var h = VectoHash.Load(stream); + Report = h.AddHash(); + } + + public XDocument Report { get; private set; } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/OutputData/XML/XMLFullReport.cs b/VectoCore/VectoCore/OutputData/XML/XMLFullReport.cs index 7a3d19ac895970230f4d5f64f8f870ce202ff173..d73824a51c73197ae0896126b11cdbd4c31ffebe 100644 --- a/VectoCore/VectoCore/OutputData/XML/XMLFullReport.cs +++ b/VectoCore/VectoCore/OutputData/XML/XMLFullReport.cs @@ -29,332 +29,332 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Xml; -using System.Xml.Linq; -using TUGraz.IVT.VectoXML.Writer; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Resources; -using TUGraz.VectoCommon.Utils; -using TUGraz.VectoCore.Models.Declaration; -using TUGraz.VectoCore.Models.Simulation.Data; -using TUGraz.VectoCore.Models.Simulation.Impl; -using TUGraz.VectoCore.Models.SimulationComponent.Data; -using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; -using TUGraz.VectoHashing; - -namespace TUGraz.VectoCore.OutputData.XML -{ - public class XMLFullReport - { - protected XElement VehiclePart; - - protected XElement InputDataIntegrity; - - protected XElement Results; - - protected XNamespace tns; - protected XNamespace di; - private bool allSuccess = true; - - public XMLFullReport() - { - di = "http://www.w3.org/2000/09/xmldsig#"; - tns = "urn:tugraz:ivt:VectoAPI:DeclarationOutput:v0.4"; - VehiclePart = new XElement(tns + XMLNames.Component_Vehicle); - Results = new XElement(tns + "Results"); - } - - public void Initialize(VectoRunData modelData, Segment segment) - { - VehiclePart.Add( - new XElement(tns + XMLNames.Vehicle_VIN, modelData.VehicleData.VIN), - new XElement(tns + XMLNames.Vehicle_VehicleCategory, modelData.VehicleData.LegislativeClass), - new XElement(tns + "VehicleGroup", segment.VehicleClass.GetClassNumber()), - new XElement(tns + XMLNames.Vehicle_AxleConfiguration, modelData.VehicleData.AxleConfiguration.GetName()), - new XElement(tns + XMLNames.Vehicle_GrossVehicleMass, modelData.VehicleData.GrossVehicleWeight.ToXMLFormat(0)), - new XElement(tns + XMLNames.Vehicle_CurbMassChassis, modelData.VehicleData.CurbWeight.ToXMLFormat(0)), - new XElement(tns + XMLNames.Vehicle_PTO, modelData.PTO != null), - GetTorqueLimits(modelData.EngineData), - new XElement(tns + XMLNames.Vehicle_Components, - GetEngineDescription(modelData.EngineData), - GetGearboxDescription(modelData.GearboxData), - GetTorqueConverterDescription(modelData.GearboxData.TorqueConverterData), - GetRetarderDescription(modelData.Retarder), - GetAngledriveDescription(modelData.AngledriveData), - GetAxlegearDescription(modelData.AxleGearData), - GetAirDragDescription(modelData.AirdragData), - GetAxleWheelsDescription(modelData.VehicleData), - GetAuxiliariesDescription(modelData.Aux) - ) - ); - InputDataIntegrity = new XElement(tns + "InputDataSignature", - modelData.InputDataHash == null ? CreateDummySig() : new XElement(modelData.InputDataHash)); - } - - private XElement CreateDummySig() - { - return new XElement(di + XMLNames.DI_Signature_Reference, - new XElement(di + XMLNames.DI_Signature_Reference_DigestMethod, - new XAttribute(XMLNames.DI_Signature_Algorithm_Attr, "null")), - new XElement(di + XMLNames.DI_Signature_Reference_DigestValue, "NOT AVAILABLE") - ); - } - - private XElement GetTorqueLimits(CombustionEngineData modelData) - { - var limits = new List<XElement>(); - var maxTorque = modelData.FullLoadCurves[0].MaxTorque; - for (uint i = 1; i < modelData.FullLoadCurves.Count; i++) { - if (!maxTorque.IsEqual(modelData.FullLoadCurves[i].MaxTorque, 1e-3.SI<NewtonMeter>())) { - limits.Add(new XElement(tns + XMLNames.Vehicle_TorqueLimits_Entry, - new XAttribute(XMLNames.Vehicle_TorqueLimits_Entry_Gear_Attr, i), - new XAttribute(XMLNames.Vehicle_TorqueLimits_Entry_MaxTorque_Attr, - modelData.FullLoadCurves[i].MaxTorque.ToXMLFormat(0)))); - } - } - - return limits.Count == 0 - ? null - : new XElement(tns + XMLNames.Vehicle_TorqueLimits, limits.Cast<object>().ToArray()); - } - - private XElement GetEngineDescription(CombustionEngineData engineData) - { - return new XElement(tns + XMLNames.Component_Engine, - GetCommonDescription(engineData), - new XElement(tns + XMLNames.Engine_RatedPower, engineData.RatedPowerDeclared.ToXMLFormat(0)), - new XElement(tns + XMLNames.Engine_IdlingSpeed, engineData.IdleSpeed.AsRPM.ToXMLFormat(0)), - new XElement(tns + XMLNames.Engine_RatedSpeed, engineData.RatedSpeedDeclared.AsRPM.ToXMLFormat(0)), - new XElement(tns + XMLNames.Engine_Displacement, - engineData.Displacement.ConvertTo().Cubic.Centi.Meter.ToXMLFormat(0)), - new XElement(tns + XMLNames.Engine_FuelType, engineData.FuelType.ToXMLFormat()) - ); - } - - private XElement GetGearboxDescription(GearboxData gearboxData) - { - return new XElement(tns + XMLNames.Component_Gearbox, - GetCommonDescription(gearboxData), - new XElement(tns + XMLNames.Gearbox_TransmissionType, gearboxData.Type.ToXMLFormat()), - new XElement(tns + "GearsCount", gearboxData.Gears.Count), - new XElement(tns + "TransmissionRatioFinalGear", gearboxData.Gears.Last().Value.Ratio.ToXMLFormat(3)) - ); - } - - private XElement GetTorqueConverterDescription(TorqueConverterData torqueConverterData) - { - if (torqueConverterData == null) { - return null; - } - return new XElement(tns + XMLNames.Component_TorqueConverter, - GetCommonDescription(torqueConverterData)); - } - - private XElement GetRetarderDescription(RetarderData retarder) - { - return new XElement(tns + XMLNames.Component_Retarder, - new XElement(tns + XMLNames.Vehicle_RetarderType, retarder.Type.ToXMLFormat()), - retarder.Type.IsDedicatedComponent() ? GetCommonDescription(retarder) : null); - } - - private object GetAngledriveDescription(AngledriveData angledriveData) - { - if (angledriveData == null) { - return null; - } - return new XElement(tns + XMLNames.Component_Angledrive, - GetCommonDescription(angledriveData), - new XElement(tns + XMLNames.AngleDrive_Ratio, angledriveData.Angledrive.Ratio)); - } - - private XElement GetAxlegearDescription(AxleGearData axleGearData) - { - return new XElement(tns + XMLNames.Component_Axlegear, - GetCommonDescription(axleGearData), - new XElement(tns + XMLNames.Axlegear_LineType, axleGearData.LineType.ToXMLFormat()), - new XElement(tns + XMLNames.Axlegear_Ratio, axleGearData.AxleGear.Ratio.ToXMLFormat(3))); - } - - private XElement GetAirDragDescription(AirdragData airdragData) - { - if (airdragData.CertificationMethod == CertificationMethod.StandardValues) { - return new XElement(tns + XMLNames.Component_AirDrag, - new XElement(tns + "CertificationMethod", airdragData.CertificationMethod.ToXMLFormat()), - new XElement(tns + "CdxA", airdragData.DeclaredAirdragArea.ToXMLFormat(2)) - ); - } - return new XElement(tns + XMLNames.Component_AirDrag, - new XElement(tns + XMLNames.Component_Model, airdragData.ModelName), - new XElement(tns + "CertificationMethod", airdragData.CertificationMethod.ToXMLFormat()), - new XElement(tns + "CertificationNumber", airdragData.CertificationNumber), - new XElement(tns + XMLNames.DI_Signature_Reference_DigestValue, airdragData.DigestValueInput), - new XElement(tns + "CdxA", airdragData.DeclaredAirdragArea.ToXMLFormat(2)) - ); - } - - private XElement GetAxleWheelsDescription(VehicleData vehicleData) - { - var retVal = new XElement(tns + XMLNames.Component_AxleWheels); - var axleData = vehicleData.AxleData; - for (var i = 0; i < axleData.Count; i++) { - if (axleData[i].AxleType == AxleType.Trailer) { - continue; - } - retVal.Add(GetAxleDescription(i + 1, axleData[i])); - } - - return retVal; - } - - private XElement GetAxleDescription(int i, Axle axle) - { - return new XElement(tns + XMLNames.AxleWheels_Axles_Axle, - new XAttribute(XMLNames.AxleWheels_Axles_Axle_AxleNumber_Attr, i), - new XElement(tns + "TyreDimension", axle.WheelsDimension), - new XElement(tns + "TyreCertificationNumber", axle.CertificationNumber), - new XElement(tns + "TyreRRCDeclared", axle.RollResistanceCoefficient.ToXMLFormat(4)), - new XElement(tns + XMLNames.AxleWheels_Axles_Axle_TwinTyres, axle.TwinTyres)); - } - - private XElement GetAuxiliariesDescription(IEnumerable<VectoRunData.AuxData> aux) - { - var auxData = aux.ToDictionary(a => a.ID); - var auxList = new[] { - AuxiliaryType.Fan, AuxiliaryType.SteeringPump, AuxiliaryType.ElectricSystem, AuxiliaryType.PneumaticSystem, - AuxiliaryType.HVAC - }; - var retVal = new XElement(tns + XMLNames.Component_Auxiliaries); - foreach (var auxId in auxList) { - foreach (var entry in auxData[auxId.Key()].Technology) { - retVal.Add(new XElement(tns + GetTagName(auxId), entry)); - } - } - return retVal; - } - - private string GetTagName(AuxiliaryType auxId) - { - return auxId.ToString() + "Technology"; - } - - private object[] GetCommonDescription(CombustionEngineData data) - { - return new object[] { - new XElement(tns + XMLNames.Component_Model, data.ModelName), - new XElement(tns + "CertificationNumber", data.CertificationNumber), - new XElement(tns + XMLNames.DI_Signature_Reference_DigestValue, data.DigestValueInput) - }; - } - - private object[] GetCommonDescription(SimulationComponentData data) - { - return new object[] { - new XElement(tns + XMLNames.Component_Model, data.ModelName), - new XElement(tns + "CertificationMethod", data.CertificationMethod.ToXMLFormat()), - data.CertificationMethod == CertificationMethod.StandardValues - ? null - : new XElement(tns + "CertificationNumber", data.CertificationNumber), - new XElement(tns + XMLNames.DI_Signature_Reference_DigestValue, data.DigestValueInput) - }; - } - - public void AddResult( - DeclarationReport<XMLDeclarationReport.ResultEntry>.ResultContainer<XMLDeclarationReport.ResultEntry> entry) - { - foreach (var resultEntry in entry.ModData) { - allSuccess &= resultEntry.Value.Status == VectoRun.Status.Success; - Results.Add(new XElement(tns + "Result", - new XAttribute("status", resultEntry.Value.Status.ToString().ToLower()), - new XElement(tns + "Mission", entry.Mission.ToXMLFormat()), - GetResults(resultEntry))); - } - } - - private object[] GetResults(KeyValuePair<LoadingType, XMLDeclarationReport.ResultEntry> resultEntry) - { - switch (resultEntry.Value.Status) { - case VectoRun.Status.Pending: - case VectoRun.Status.Running: - return null; // should not happen! - case VectoRun.Status.Success: - return GetSuccessResultEntry(resultEntry.Value); - case VectoRun.Status.Canceled: - case VectoRun.Status.Aborted: - return new object[] { - new XElement("Error", resultEntry.Value.Error), - new XElement("ErrorDetails", resultEntry.Value.StackTrace), - }; - default: - throw new ArgumentOutOfRangeException(); - } - } - - private object[] GetSuccessResultEntry(XMLDeclarationReport.ResultEntry result) - { - return new object[] { - new XElement(tns + "Distance", new XAttribute("unit", "km"), result.Distance.ToXMLFormat(1)), - new XElement(tns + "SimulationParameters", - new XElement(tns + "TotalVehicleMass", new XAttribute("unit", "kg"), result.TotalVehicleWeight.ToXMLFormat(0)), - new XElement(tns + "Payload", new XAttribute("unit", "kg"), result.Payload.ToXMLFormat(0)), - new XElement(tns + "FuelType", result.FuelType.ToXMLFormat()) - ), - new XElement(tns + "VehiclePerformance", - new XElement(tns + "AverageSpeed", new XAttribute("unit", "km/h"), result.AverageSpeed.AsKmph.ToXMLFormat(1)), - new XElement(tns + "MinSpeed", new XAttribute("unit", "km/h"), result.MinSpeed.AsKmph.ToXMLFormat(1)), - new XElement(tns + "MaxSpeed", new XAttribute("unit", "km/h"), result.MaxSpeed.AsKmph.ToXMLFormat(1)), - new XElement(tns + "MaxDeceleration", new XAttribute("unit", "m/s²"), result.MaxDeceleration.ToXMLFormat(2)), - new XElement(tns + "MaxAcceleration", new XAttribute("unit", "m/s²"), result.MaxAcceleration.ToXMLFormat(2)), - new XElement(tns + "FullLoadDrivingtimePercentage", result.FullLoadPercentage.ToXMLFormat(0)), - new XElement(tns + "GearshiftCount", result.GearshiftCount.ToXMLFormat(0)) - ), - //FC - XMLDeclarationReport.GetResults(result, tns, true).Cast<object>().ToArray() - }; - } - - private XElement GetApplicationInfo() - { - var vectodll = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + "VectoCore.dll").GetName(); - return new XElement(tns + "ApplicationInformation", - new XElement(tns + "SimulationToolVersion", vectodll.Version), - new XElement(tns + "Date", XmlConvert.ToString(DateTime.Now, XmlDateTimeSerializationMode.Utc))); - } - - public void GenerateReport() - { - var xsi = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance"); - var retVal = new XDocument(); - var results = new XElement(Results); - results.AddFirst(new XElement(tns + "Status", allSuccess ? "success" : "error")); - var vehicle = new XElement(VehiclePart); - vehicle.Add(InputDataIntegrity); - retVal.Add(new XElement(tns + "VectoOutput", - new XAttribute("schemaVersion", "0.4"), - new XAttribute(XNamespace.Xmlns + "xsi", xsi.NamespaceName), - new XAttribute("xmlns", tns), - new XAttribute(XNamespace.Xmlns + "di", di), - new XAttribute(xsi + "schemaLocation", - string.Format("{0} {1}VectoOutput.xsd", tns, AbstractXMLWriter.SchemaLocationBaseUrl)), - new XElement(tns + "Data", - vehicle, - results, - GetApplicationInfo()) - ) - ); - var stream = new MemoryStream(); - var writer = new StreamWriter(stream); - writer.Write(retVal); - writer.Flush(); - stream.Seek(0, SeekOrigin.Begin); - var h = VectoHash.Load(stream); - Report = h.AddHash(); - } - - public XDocument Report { get; private set; } - } +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Xml; +using System.Xml.Linq; +using TUGraz.IVT.VectoXML.Writer; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Resources; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.Declaration; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Models.Simulation.Impl; +using TUGraz.VectoCore.Models.SimulationComponent.Data; +using TUGraz.VectoCore.Models.SimulationComponent.Data.Gearbox; +using TUGraz.VectoHashing; + +namespace TUGraz.VectoCore.OutputData.XML +{ + public class XMLFullReport + { + protected XElement VehiclePart; + + protected XElement InputDataIntegrity; + + protected XElement Results; + + protected XNamespace tns; + protected XNamespace di; + private bool allSuccess = true; + + public XMLFullReport() + { + di = "http://www.w3.org/2000/09/xmldsig#"; + tns = "urn:tugraz:ivt:VectoAPI:DeclarationOutput:v0.4"; + VehiclePart = new XElement(tns + XMLNames.Component_Vehicle); + Results = new XElement(tns + "Results"); + } + + public void Initialize(VectoRunData modelData, Segment segment) + { + VehiclePart.Add( + new XElement(tns + XMLNames.Vehicle_VIN, modelData.VehicleData.VIN), + new XElement(tns + XMLNames.Vehicle_VehicleCategory, modelData.VehicleData.LegislativeClass), + new XElement(tns + "VehicleGroup", segment.VehicleClass.GetClassNumber()), + new XElement(tns + XMLNames.Vehicle_AxleConfiguration, modelData.VehicleData.AxleConfiguration.GetName()), + new XElement(tns + XMLNames.Vehicle_GrossVehicleMass, modelData.VehicleData.GrossVehicleWeight.ToXMLFormat(0)), + new XElement(tns + XMLNames.Vehicle_CurbMassChassis, modelData.VehicleData.CurbWeight.ToXMLFormat(0)), + new XElement(tns + XMLNames.Vehicle_PTO, modelData.PTO != null), + GetTorqueLimits(modelData.EngineData), + new XElement(tns + XMLNames.Vehicle_Components, + GetEngineDescription(modelData.EngineData), + GetGearboxDescription(modelData.GearboxData), + GetTorqueConverterDescription(modelData.GearboxData.TorqueConverterData), + GetRetarderDescription(modelData.Retarder), + GetAngledriveDescription(modelData.AngledriveData), + GetAxlegearDescription(modelData.AxleGearData), + GetAirDragDescription(modelData.AirdragData), + GetAxleWheelsDescription(modelData.VehicleData), + GetAuxiliariesDescription(modelData.Aux) + ) + ); + InputDataIntegrity = new XElement(tns + "InputDataSignature", + modelData.InputDataHash == null ? CreateDummySig() : new XElement(modelData.InputDataHash)); + } + + private XElement CreateDummySig() + { + return new XElement(di + XMLNames.DI_Signature_Reference, + new XElement(di + XMLNames.DI_Signature_Reference_DigestMethod, + new XAttribute(XMLNames.DI_Signature_Algorithm_Attr, "null")), + new XElement(di + XMLNames.DI_Signature_Reference_DigestValue, "NOT AVAILABLE") + ); + } + + private XElement GetTorqueLimits(CombustionEngineData modelData) + { + var limits = new List<XElement>(); + var maxTorque = modelData.FullLoadCurves[0].MaxTorque; + for (uint i = 1; i < modelData.FullLoadCurves.Count; i++) { + if (!maxTorque.IsEqual(modelData.FullLoadCurves[i].MaxTorque, 1e-3.SI<NewtonMeter>())) { + limits.Add(new XElement(tns + XMLNames.Vehicle_TorqueLimits_Entry, + new XAttribute(XMLNames.Vehicle_TorqueLimits_Entry_Gear_Attr, i), + new XAttribute(XMLNames.Vehicle_TorqueLimits_Entry_MaxTorque_Attr, + modelData.FullLoadCurves[i].MaxTorque.ToXMLFormat(0)))); + } + } + + return limits.Count == 0 + ? null + : new XElement(tns + XMLNames.Vehicle_TorqueLimits, limits.Cast<object>().ToArray()); + } + + private XElement GetEngineDescription(CombustionEngineData engineData) + { + return new XElement(tns + XMLNames.Component_Engine, + GetCommonDescription(engineData), + new XElement(tns + XMLNames.Engine_RatedPower, engineData.RatedPowerDeclared.ToXMLFormat(0)), + new XElement(tns + XMLNames.Engine_IdlingSpeed, engineData.IdleSpeed.AsRPM.ToXMLFormat(0)), + new XElement(tns + XMLNames.Engine_RatedSpeed, engineData.RatedSpeedDeclared.AsRPM.ToXMLFormat(0)), + new XElement(tns + XMLNames.Engine_Displacement, + engineData.Displacement.ConvertTo().Cubic.Centi.Meter.ToXMLFormat(0)), + new XElement(tns + XMLNames.Engine_FuelType, engineData.FuelType.ToXMLFormat()) + ); + } + + private XElement GetGearboxDescription(GearboxData gearboxData) + { + return new XElement(tns + XMLNames.Component_Gearbox, + GetCommonDescription(gearboxData), + new XElement(tns + XMLNames.Gearbox_TransmissionType, gearboxData.Type.ToXMLFormat()), + new XElement(tns + "GearsCount", gearboxData.Gears.Count), + new XElement(tns + "TransmissionRatioFinalGear", gearboxData.Gears.Last().Value.Ratio.ToXMLFormat(3)) + ); + } + + private XElement GetTorqueConverterDescription(TorqueConverterData torqueConverterData) + { + if (torqueConverterData == null) { + return null; + } + return new XElement(tns + XMLNames.Component_TorqueConverter, + GetCommonDescription(torqueConverterData)); + } + + private XElement GetRetarderDescription(RetarderData retarder) + { + return new XElement(tns + XMLNames.Component_Retarder, + new XElement(tns + XMLNames.Vehicle_RetarderType, retarder.Type.ToXMLFormat()), + retarder.Type.IsDedicatedComponent() ? GetCommonDescription(retarder) : null); + } + + private object GetAngledriveDescription(AngledriveData angledriveData) + { + if (angledriveData == null) { + return null; + } + return new XElement(tns + XMLNames.Component_Angledrive, + GetCommonDescription(angledriveData), + new XElement(tns + XMLNames.AngleDrive_Ratio, angledriveData.Angledrive.Ratio)); + } + + private XElement GetAxlegearDescription(AxleGearData axleGearData) + { + return new XElement(tns + XMLNames.Component_Axlegear, + GetCommonDescription(axleGearData), + new XElement(tns + XMLNames.Axlegear_LineType, axleGearData.LineType.ToXMLFormat()), + new XElement(tns + XMLNames.Axlegear_Ratio, axleGearData.AxleGear.Ratio.ToXMLFormat(3))); + } + + private XElement GetAirDragDescription(AirdragData airdragData) + { + if (airdragData.CertificationMethod == CertificationMethod.StandardValues) { + return new XElement(tns + XMLNames.Component_AirDrag, + new XElement(tns + "CertificationMethod", airdragData.CertificationMethod.ToXMLFormat()), + new XElement(tns + "CdxA", airdragData.DeclaredAirdragArea.ToXMLFormat(2)) + ); + } + return new XElement(tns + XMLNames.Component_AirDrag, + new XElement(tns + XMLNames.Component_Model, airdragData.ModelName), + new XElement(tns + "CertificationMethod", airdragData.CertificationMethod.ToXMLFormat()), + new XElement(tns + "CertificationNumber", airdragData.CertificationNumber), + new XElement(tns + XMLNames.DI_Signature_Reference_DigestValue, airdragData.DigestValueInput), + new XElement(tns + "CdxA", airdragData.DeclaredAirdragArea.ToXMLFormat(2)) + ); + } + + private XElement GetAxleWheelsDescription(VehicleData vehicleData) + { + var retVal = new XElement(tns + XMLNames.Component_AxleWheels); + var axleData = vehicleData.AxleData; + for (var i = 0; i < axleData.Count; i++) { + if (axleData[i].AxleType == AxleType.Trailer) { + continue; + } + retVal.Add(GetAxleDescription(i + 1, axleData[i])); + } + + return retVal; + } + + private XElement GetAxleDescription(int i, Axle axle) + { + return new XElement(tns + XMLNames.AxleWheels_Axles_Axle, + new XAttribute(XMLNames.AxleWheels_Axles_Axle_AxleNumber_Attr, i), + new XElement(tns + "TyreDimension", axle.WheelsDimension), + new XElement(tns + "TyreCertificationNumber", axle.CertificationNumber), + new XElement(tns + "TyreRRCDeclared", axle.RollResistanceCoefficient.ToXMLFormat(4)), + new XElement(tns + XMLNames.AxleWheels_Axles_Axle_TwinTyres, axle.TwinTyres)); + } + + private XElement GetAuxiliariesDescription(IEnumerable<VectoRunData.AuxData> aux) + { + var auxData = aux.ToDictionary(a => a.ID); + var auxList = new[] { + AuxiliaryType.Fan, AuxiliaryType.SteeringPump, AuxiliaryType.ElectricSystem, AuxiliaryType.PneumaticSystem, + AuxiliaryType.HVAC + }; + var retVal = new XElement(tns + XMLNames.Component_Auxiliaries); + foreach (var auxId in auxList) { + foreach (var entry in auxData[auxId.Key()].Technology) { + retVal.Add(new XElement(tns + GetTagName(auxId), entry)); + } + } + return retVal; + } + + private string GetTagName(AuxiliaryType auxId) + { + return auxId.ToString() + "Technology"; + } + + private object[] GetCommonDescription(CombustionEngineData data) + { + return new object[] { + new XElement(tns + XMLNames.Component_Model, data.ModelName), + new XElement(tns + "CertificationNumber", data.CertificationNumber), + new XElement(tns + XMLNames.DI_Signature_Reference_DigestValue, data.DigestValueInput) + }; + } + + private object[] GetCommonDescription(SimulationComponentData data) + { + return new object[] { + new XElement(tns + XMLNames.Component_Model, data.ModelName), + new XElement(tns + "CertificationMethod", data.CertificationMethod.ToXMLFormat()), + data.CertificationMethod == CertificationMethod.StandardValues + ? null + : new XElement(tns + "CertificationNumber", data.CertificationNumber), + new XElement(tns + XMLNames.DI_Signature_Reference_DigestValue, data.DigestValueInput) + }; + } + + public void AddResult( + DeclarationReport<XMLDeclarationReport.ResultEntry>.ResultContainer<XMLDeclarationReport.ResultEntry> entry) + { + foreach (var resultEntry in entry.ModData) { + allSuccess &= resultEntry.Value.Status == VectoRun.Status.Success; + Results.Add(new XElement(tns + "Result", + new XAttribute("status", resultEntry.Value.Status.ToString().ToLower()), + new XElement(tns + "Mission", entry.Mission.ToXMLFormat()), + GetResults(resultEntry))); + } + } + + private object[] GetResults(KeyValuePair<LoadingType, XMLDeclarationReport.ResultEntry> resultEntry) + { + switch (resultEntry.Value.Status) { + case VectoRun.Status.Pending: + case VectoRun.Status.Running: + return null; // should not happen! + case VectoRun.Status.Success: + return GetSuccessResultEntry(resultEntry.Value); + case VectoRun.Status.Canceled: + case VectoRun.Status.Aborted: + return new object[] { + new XElement("Error", resultEntry.Value.Error), + new XElement("ErrorDetails", resultEntry.Value.StackTrace), + }; + default: + throw new ArgumentOutOfRangeException(); + } + } + + private object[] GetSuccessResultEntry(XMLDeclarationReport.ResultEntry result) + { + return new object[] { + new XElement(tns + "Distance", new XAttribute("unit", "km"), result.Distance.ToXMLFormat(1)), + new XElement(tns + "SimulationParameters", + new XElement(tns + "TotalVehicleMass", new XAttribute("unit", "kg"), result.TotalVehicleWeight.ToXMLFormat(0)), + new XElement(tns + "Payload", new XAttribute("unit", "kg"), result.Payload.ToXMLFormat(0)), + new XElement(tns + "FuelType", result.FuelType.ToXMLFormat()) + ), + new XElement(tns + "VehiclePerformance", + new XElement(tns + "AverageSpeed", new XAttribute("unit", "km/h"), result.AverageSpeed.AsKmph.ToXMLFormat(1)), + new XElement(tns + "MinSpeed", new XAttribute("unit", "km/h"), result.MinSpeed.AsKmph.ToXMLFormat(1)), + new XElement(tns + "MaxSpeed", new XAttribute("unit", "km/h"), result.MaxSpeed.AsKmph.ToXMLFormat(1)), + new XElement(tns + "MaxDeceleration", new XAttribute("unit", "m/s²"), result.MaxDeceleration.ToXMLFormat(2)), + new XElement(tns + "MaxAcceleration", new XAttribute("unit", "m/s²"), result.MaxAcceleration.ToXMLFormat(2)), + new XElement(tns + "FullLoadDrivingtimePercentage", result.FullLoadPercentage.ToXMLFormat(0)), + new XElement(tns + "GearshiftCount", result.GearshiftCount.ToXMLFormat(0)) + ), + //FC + XMLDeclarationReport.GetResults(result, tns, true).Cast<object>().ToArray() + }; + } + + private XElement GetApplicationInfo() + { + var vectodll = Assembly.LoadFrom(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "VectoCore.dll")).GetName(); + return new XElement(tns + "ApplicationInformation", + new XElement(tns + "SimulationToolVersion", vectodll.Version), + new XElement(tns + "Date", XmlConvert.ToString(DateTime.Now, XmlDateTimeSerializationMode.Utc))); + } + + public void GenerateReport() + { + var xsi = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance"); + var retVal = new XDocument(); + var results = new XElement(Results); + results.AddFirst(new XElement(tns + "Status", allSuccess ? "success" : "error")); + var vehicle = new XElement(VehiclePart); + vehicle.Add(InputDataIntegrity); + retVal.Add(new XElement(tns + "VectoOutput", + new XAttribute("schemaVersion", "0.4"), + new XAttribute(XNamespace.Xmlns + "xsi", xsi.NamespaceName), + new XAttribute("xmlns", tns), + new XAttribute(XNamespace.Xmlns + "di", di), + new XAttribute(xsi + "schemaLocation", + string.Format("{0} {1}VectoOutput.xsd", tns, AbstractXMLWriter.SchemaLocationBaseUrl)), + new XElement(tns + "Data", + vehicle, + results, + GetApplicationInfo()) + ) + ); + var stream = new MemoryStream(); + var writer = new StreamWriter(stream); + writer.Write(retVal); + writer.Flush(); + stream.Seek(0, SeekOrigin.Begin); + var h = VectoHash.Load(stream); + Report = h.AddHash(); + } + + public XDocument Report { get; private set; } + } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Utils/VectoCSVFile.cs b/VectoCore/VectoCore/Utils/VectoCSVFile.cs index f7c9b8274338b8dc89fb258dcf034756e476cfc1..3a0be33e6e4c4c2195ab1f7c16600c8004d65b3e 100644 --- a/VectoCore/VectoCore/Utils/VectoCSVFile.cs +++ b/VectoCore/VectoCore/Utils/VectoCSVFile.cs @@ -29,217 +29,217 @@ * Martin Rexeis, rexeis@ivt.tugraz.at, IVT, Graz University of Technology */ -using Microsoft.VisualBasic.FileIO; -using System; -using System.Data; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Text.RegularExpressions; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.InputData; -using TUGraz.VectoCommon.Models; -using TUGraz.VectoCommon.Utils; - -namespace TUGraz.VectoCore.Utils -{ - /// <summary> - /// Class for Reading and Writing VECTO CSV Files. - /// </summary> - /// <remarks> - /// The following format applies to all CSV (Comma-separated values) Input Files used in VECTO: - /// List DELIMITER: Comma "," - /// Decimal-Mark: Dot "." - /// Comments: "#" at the beginning of the comment line. Number and position of comment lines is not limited. - /// Header: One header line (not a comment line) at the beginning of the file. - /// All Combinations between max-format and min-format possible. Only "id"-field is used. - /// max: id (name) [unit], id (name) [unit], ... - /// min: id,id,... - /// </remarks> - public static class VectoCSVFile - { - private static readonly Regex HeaderFilter = new Regex(@"\[.*?\]|\<|\>", RegexOptions.Compiled); - private const string Delimiter = ","; - private const string Comment = "#"; - - /// <summary> - /// Reads a CSV file which is stored in Vecto-CSV-Format. - /// </summary> - /// <param name="fileName">the filename</param> - /// <param name="ignoreEmptyColumns">set true, if empty columns should be ignored. default: false.</param> - /// <param name="fullHeader">set true is column names should be preserved. Otherwise units are trimed away. default: false.</param> - /// <returns>A DataTable which represents the CSV File.</returns> - public static TableData Read(string fileName, bool ignoreEmptyColumns = false, bool fullHeader = false) - { - try { - using (var fs = new FileStream(fileName, FileMode.Open)) { - var retVal = new TableData(fileName); - ReadCSV(retVal, fs, ignoreEmptyColumns, fullHeader); - return retVal; - } - } catch (Exception e) { - LogManager.GetLogger(typeof(VectoCSVFile).FullName).Error(e); - throw new VectoException("Error reading file {0}: {1}", fileName, e.Message); - } - } - - /// <summary> - /// Reads a CSV file which is stored in Vecto-CSV-Format. - /// </summary> - /// <param name="stream">the stream to read</param> - /// <param name="ignoreEmptyColumns">set true, if empty columns should be ignored. default: false.</param> - /// <param name="fullHeader">set true is column names should be preserved. Otherwise units are trimed away. default: false.</param> - /// <param name="source"></param> - /// <returns>A DataTable which represents the CSV File.</returns> - public static TableData ReadStream(Stream stream, bool ignoreEmptyColumns = false, bool fullHeader = false, - string source = null) - { - var retVal = new TableData(source, DataSourceType.Embedded); - ReadCSV(retVal, stream, ignoreEmptyColumns, fullHeader); - return retVal; - } - - private static void ReadCSV(DataTable table, Stream stream, bool ignoreEmptyColumns, bool fullHeader) - { - var p = new TextFieldParser(stream) { - TextFieldType = FieldType.Delimited, - Delimiters = new[] { Delimiter }, - CommentTokens = new[] { Comment }, - HasFieldsEnclosedInQuotes = true, - TrimWhiteSpace = true - }; - - string[] colsWithoutComment = { }; - - try { - var fields = p.ReadFields(); - if (fields == null) { - throw new CSVReadException("CSV Read Error: File was empty."); - } - colsWithoutComment = fields - .Select(l => l.Contains(Comment) ? l.Substring(0, l.IndexOf(Comment, StringComparison.Ordinal)) : l) - .ToArray(); - } catch (ArgumentNullException) { - throw new CSVReadException("CSV Read Error: File was empty."); - } - - double tmp; - var columns = colsWithoutComment - .Select(l => fullHeader ? l : HeaderFilter.Replace(l, "")) - .Select(l => l.Trim()) - .Where(col => !double.TryParse(col, NumberStyles.Any, CultureInfo.InvariantCulture, out tmp)) - .Distinct() - .ToList(); - - var firstLineIsData = columns.Count == 0; - - if (firstLineIsData) { - LogManager.GetLogger(typeof(VectoCSVFile).FullName) - .Warn("No valid Data Header found. Interpreting the first line as data line."); - // set the validColumns to: {"0", "1", "2", "3", ...} for all columns in first line. - columns = colsWithoutComment.Select((_, i) => i.ToString()).ToList(); - } - - //var table = new DataTable(); - foreach (var col in columns) { - table.Columns.Add(col); - } - - if (p.EndOfData) { - return; - } - - var lineNumber = 1; - do { - string[] cells = { }; - if (firstLineIsData) { - cells = colsWithoutComment; - } else { - var fields = p.ReadFields(); - if (fields != null) { - cells = fields.Select(l => l.Contains(Comment) ? l.Substring(0, l.IndexOf(Comment, StringComparison.Ordinal)) : l) - .Select(s => s.Trim()) - .ToArray(); - } - } - firstLineIsData = false; - if (table.Columns.Count != cells.Length && !ignoreEmptyColumns) { - throw new CSVReadException( - string.Format("Line {0}: The number of values is not correct. Expected {1} Columns, Got {2} Columns", - lineNumber, table.Columns.Count, cells.Length)); - } - - try { - // ReSharper disable once CoVariantArrayConversion - table.Rows.Add(cells); - } catch (InvalidCastException e) { - throw new CSVReadException( - string.Format("Line {0}: The data format of a value is not correct. {1}", lineNumber, e.Message), e); - } - lineNumber++; - } while (!p.EndOfData); - } - - /// <summary> - /// Writes the datatable to the csv file. - /// Uses the column caption as header (with fallback to column name) for the csv header. - /// </summary> - /// <param name="fileName">Path to the file.</param> - /// <param name="table">The Datatable.</param> - /// <param name="addVersionHeader"></param> - public static void Write(string fileName, DataTable table, bool addVersionHeader = false) - { - using (var sw = new StreamWriter(new FileStream(fileName, FileMode.Create), Encoding.UTF8)) { - Write(sw, table, addVersionHeader); - } - } - - /// <summary> - /// writes the datatable to a csv file. - /// Uses the column caption as header (with fallback to column name) for the csv header. - /// <remarks>Note: the callee has to make suree to close the stream after use.</remarks> - /// </summary> - /// <param name="writer"></param> - /// <param name="table"></param> - /// <param name="addVersionHeader"></param> - public static void Write(StreamWriter writer, DataTable table, bool addVersionHeader = false) - { - if (writer == null) { - return; - } - if (addVersionHeader) { - var vectodll = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + "VectoCore.dll").GetName(); - writer.WriteLine("# VECTO {0} - {1}", vectodll.Version, DateTime.Now.ToString("dd.MM.yyyy HH:mm")); - } - var header = table.Columns.Cast<DataColumn>().Select(col => col.Caption ?? col.ColumnName); - writer.WriteLine(string.Join(Delimiter, header)); - - var columnFormatter = new Func<SI, string>[table.Columns.Count]; - for (var i = 0; i < table.Columns.Count; i++) { - var col = table.Columns[i]; - var decimals = (uint?)col.ExtendedProperties["decimals"]; - var outputFactor = (double?)col.ExtendedProperties["outputFactor"]; - var showUnit = (bool?)col.ExtendedProperties["showUnit"]; - - columnFormatter[i] = item => item.ToOutputFormat(decimals, outputFactor, showUnit); - } - - foreach (DataRow row in table.Rows) { - var items = row.ItemArray; - var formattedList = new string[items.Length]; - for (var i = 0; i < items.Length; i++) { - var si = items[i] as SI; - formattedList[i] = si != null - ? columnFormatter[i](si) - : formattedList[i] = string.Format(CultureInfo.InvariantCulture, "{0}", items[i]); - if (formattedList[i].Contains(Delimiter)) { - formattedList[i] = string.Format("\"{0}\"", formattedList[i]); - } - } - writer.WriteLine(string.Join(Delimiter, formattedList)); - } - } - } +using Microsoft.VisualBasic.FileIO; +using System; +using System.Data; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.InputData; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; + +namespace TUGraz.VectoCore.Utils +{ + /// <summary> + /// Class for Reading and Writing VECTO CSV Files. + /// </summary> + /// <remarks> + /// The following format applies to all CSV (Comma-separated values) Input Files used in VECTO: + /// List DELIMITER: Comma "," + /// Decimal-Mark: Dot "." + /// Comments: "#" at the beginning of the comment line. Number and position of comment lines is not limited. + /// Header: One header line (not a comment line) at the beginning of the file. + /// All Combinations between max-format and min-format possible. Only "id"-field is used. + /// max: id (name) [unit], id (name) [unit], ... + /// min: id,id,... + /// </remarks> + public static class VectoCSVFile + { + private static readonly Regex HeaderFilter = new Regex(@"\[.*?\]|\<|\>", RegexOptions.Compiled); + private const string Delimiter = ","; + private const string Comment = "#"; + + /// <summary> + /// Reads a CSV file which is stored in Vecto-CSV-Format. + /// </summary> + /// <param name="fileName">the filename</param> + /// <param name="ignoreEmptyColumns">set true, if empty columns should be ignored. default: false.</param> + /// <param name="fullHeader">set true is column names should be preserved. Otherwise units are trimed away. default: false.</param> + /// <returns>A DataTable which represents the CSV File.</returns> + public static TableData Read(string fileName, bool ignoreEmptyColumns = false, bool fullHeader = false) + { + try { + using (var fs = new FileStream(fileName, FileMode.Open)) { + var retVal = new TableData(fileName); + ReadCSV(retVal, fs, ignoreEmptyColumns, fullHeader); + return retVal; + } + } catch (Exception e) { + LogManager.GetLogger(typeof(VectoCSVFile).FullName).Error(e); + throw new VectoException("Error reading file {0}: {1}", fileName, e.Message); + } + } + + /// <summary> + /// Reads a CSV file which is stored in Vecto-CSV-Format. + /// </summary> + /// <param name="stream">the stream to read</param> + /// <param name="ignoreEmptyColumns">set true, if empty columns should be ignored. default: false.</param> + /// <param name="fullHeader">set true is column names should be preserved. Otherwise units are trimed away. default: false.</param> + /// <param name="source"></param> + /// <returns>A DataTable which represents the CSV File.</returns> + public static TableData ReadStream(Stream stream, bool ignoreEmptyColumns = false, bool fullHeader = false, + string source = null) + { + var retVal = new TableData(source, DataSourceType.Embedded); + ReadCSV(retVal, stream, ignoreEmptyColumns, fullHeader); + return retVal; + } + + private static void ReadCSV(DataTable table, Stream stream, bool ignoreEmptyColumns, bool fullHeader) + { + var p = new TextFieldParser(stream) { + TextFieldType = FieldType.Delimited, + Delimiters = new[] { Delimiter }, + CommentTokens = new[] { Comment }, + HasFieldsEnclosedInQuotes = true, + TrimWhiteSpace = true + }; + + string[] colsWithoutComment = { }; + + try { + var fields = p.ReadFields(); + if (fields == null) { + throw new CSVReadException("CSV Read Error: File was empty."); + } + colsWithoutComment = fields + .Select(l => l.Contains(Comment) ? l.Substring(0, l.IndexOf(Comment, StringComparison.Ordinal)) : l) + .ToArray(); + } catch (ArgumentNullException) { + throw new CSVReadException("CSV Read Error: File was empty."); + } + + double tmp; + var columns = colsWithoutComment + .Select(l => fullHeader ? l : HeaderFilter.Replace(l, "")) + .Select(l => l.Trim()) + .Where(col => !double.TryParse(col, NumberStyles.Any, CultureInfo.InvariantCulture, out tmp)) + .Distinct() + .ToList(); + + var firstLineIsData = columns.Count == 0; + + if (firstLineIsData) { + LogManager.GetLogger(typeof(VectoCSVFile).FullName) + .Warn("No valid Data Header found. Interpreting the first line as data line."); + // set the validColumns to: {"0", "1", "2", "3", ...} for all columns in first line. + columns = colsWithoutComment.Select((_, i) => i.ToString()).ToList(); + } + + //var table = new DataTable(); + foreach (var col in columns) { + table.Columns.Add(col); + } + + if (p.EndOfData) { + return; + } + + var lineNumber = 1; + do { + string[] cells = { }; + if (firstLineIsData) { + cells = colsWithoutComment; + } else { + var fields = p.ReadFields(); + if (fields != null) { + cells = fields.Select(l => l.Contains(Comment) ? l.Substring(0, l.IndexOf(Comment, StringComparison.Ordinal)) : l) + .Select(s => s.Trim()) + .ToArray(); + } + } + firstLineIsData = false; + if (table.Columns.Count != cells.Length && !ignoreEmptyColumns) { + throw new CSVReadException( + string.Format("Line {0}: The number of values is not correct. Expected {1} Columns, Got {2} Columns", + lineNumber, table.Columns.Count, cells.Length)); + } + + try { + // ReSharper disable once CoVariantArrayConversion + table.Rows.Add(cells); + } catch (InvalidCastException e) { + throw new CSVReadException( + string.Format("Line {0}: The data format of a value is not correct. {1}", lineNumber, e.Message), e); + } + lineNumber++; + } while (!p.EndOfData); + } + + /// <summary> + /// Writes the datatable to the csv file. + /// Uses the column caption as header (with fallback to column name) for the csv header. + /// </summary> + /// <param name="fileName">Path to the file.</param> + /// <param name="table">The Datatable.</param> + /// <param name="addVersionHeader"></param> + public static void Write(string fileName, DataTable table, bool addVersionHeader = false) + { + using (var sw = new StreamWriter(new FileStream(fileName, FileMode.Create), Encoding.UTF8)) { + Write(sw, table, addVersionHeader); + } + } + + /// <summary> + /// writes the datatable to a csv file. + /// Uses the column caption as header (with fallback to column name) for the csv header. + /// <remarks>Note: the callee has to make suree to close the stream after use.</remarks> + /// </summary> + /// <param name="writer"></param> + /// <param name="table"></param> + /// <param name="addVersionHeader"></param> + public static void Write(StreamWriter writer, DataTable table, bool addVersionHeader = false) + { + if (writer == null) { + return; + } + if (addVersionHeader) { + var vectodll = Assembly.LoadFrom(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "VectoCore.dll")).GetName(); + writer.WriteLine("# VECTO {0} - {1}", vectodll.Version, DateTime.Now.ToString("dd.MM.yyyy HH:mm")); + } + var header = table.Columns.Cast<DataColumn>().Select(col => col.Caption ?? col.ColumnName); + writer.WriteLine(string.Join(Delimiter, header)); + + var columnFormatter = new Func<SI, string>[table.Columns.Count]; + for (var i = 0; i < table.Columns.Count; i++) { + var col = table.Columns[i]; + var decimals = (uint?)col.ExtendedProperties["decimals"]; + var outputFactor = (double?)col.ExtendedProperties["outputFactor"]; + var showUnit = (bool?)col.ExtendedProperties["showUnit"]; + + columnFormatter[i] = item => item.ToOutputFormat(decimals, outputFactor, showUnit); + } + + foreach (DataRow row in table.Rows) { + var items = row.ItemArray; + var formattedList = new string[items.Length]; + for (var i = 0; i < items.Length; i++) { + var si = items[i] as SI; + formattedList[i] = si != null + ? columnFormatter[i](si) + : formattedList[i] = string.Format(CultureInfo.InvariantCulture, "{0}", items[i]); + if (formattedList[i].Contains(Delimiter)) { + formattedList[i] = string.Format("\"{0}\"", formattedList[i]); + } + } + writer.WriteLine(string.Join(Delimiter, formattedList)); + } + } + } } \ No newline at end of file