//----------------------------------------------------------------------- // // Copyright © 2012 Nils Hammar. All rights reserved. // //----------------------------------------------------------------------- /* * Software to access vehicle information via the OBD-II connector. * * Copyright © 2012 Nils Hammar * * 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 . * * Alternative licensing is possible, see the licensing document. * * The above text may not be removed or modified. */ namespace DataSource.FileAccess { using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Windows.Forms; using System.Xml.Serialization; using global::SharedObjects; using global::SharedObjects.DataMgmt; using global::SharedObjects.Misc; /// /// Access class for pidgroups file. /// public class PidGroupFileAccess : XmlParserHelper { /// /// Name of file. /// private string fileName; /// /// Gets List of all known pid groups. /// private List pidgrouplistInt = new List(); /// /// Gets List of all known pid groups. /// public IList pidgrouplist { get { return this.pidgrouplistInt; } } /// /// Gets List of pidgroups reduced depending on selected unit category /// so that only the selected category (metric or imperial) will be /// provided. /// private List restrictedPidgrouplistInt = new List(); /// /// Gets List of pidgroups reduced depending on selected unit category /// so that only the selected category (metric or imperial) will be /// provided. /// public IList restrictedPidgrouplist { get { return this.restrictedPidgrouplistInt; } } /// /// Preferences data. /// private IPreferences iPreferences; /// /// Data source interface instance. /// private IDataSource iDataSource; /// /// Initializes a new instance of the class. /// /// Preferences data. /// Logger instance. /// Data source interface instance. /// Pid group file name. /// Data file directory path. public PidGroupFileAccess(IPreferences iPreferences, ILogging iLogging, IDataSource iDataSource, string fileName, string dataFileDir) : base(iLogging, dataFileDir) { this.iPreferences = iPreferences; this.iDataSource = iDataSource; this.fileName = fileName; } /// /// Duplicate the given object into a new object. /// /// Object to duplicate. /// New object which is a copy of the old. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "Reviewed.")] public static XmlClass.pidgroup duplicate(XmlClass.pidgroup oldItem) { XmlClass.pidgroup newItem = null; if (oldItem != null) { XmlSerializer xms = new XmlSerializer(oldItem.GetType()); using (Stream stream = new MemoryStream()) { try { xms.Serialize(stream, oldItem); stream.Seek(0, SeekOrigin.Begin); newItem = (XmlClass.pidgroup)xms.Deserialize(stream); } finally { stream.Close(); } } } return newItem; } /// /// Save the current list to file. /// /// 'true' when successful. public bool save() { bool success = false; XmlSerializer xms = new XmlSerializer(this.pidgrouplistInt.GetType()); xms.UnknownNode += new XmlNodeEventHandler(xms_UnknownNode); xms.UnknownAttribute += new XmlAttributeEventHandler(xms_UnknownAttribute); xms.UnknownElement += new XmlElementEventHandler(xms_UnknownElement); xms.UnreferencedObject += new UnreferencedObjectEventHandler(xms_UnreferencedObject); TextWriter writer = null; try { writer = new StreamWriter(this.dataFileDir + this.fileName); xms.Serialize(writer, this.pidgrouplistInt); success = true; } catch (Exception ex) { MessageBox.Show( ex.Message, "Save failed", MessageBoxButtons.OK, MessageBoxIcon.Hand); } finally { if (writer != null) { writer.Close(); } } return success; } /// /// Load data from file into the current list. /// public void load() { this.iLogging.appendText("Loading PID Groups." + "\r\n"); this.pidgrouplistInt = new List(); XmlSerializer xms = new XmlSerializer(this.pidgrouplistInt.GetType()); xms.UnknownNode += new XmlNodeEventHandler(xms_UnknownNode); xms.UnknownAttribute += new XmlAttributeEventHandler(xms_UnknownAttribute); xms.UnknownElement += new XmlElementEventHandler(xms_UnknownElement); xms.UnreferencedObject += new UnreferencedObjectEventHandler(xms_UnreferencedObject); StreamReader sr = null; try { sr = new StreamReader(this.dataFileDir + this.fileName); this.pidgrouplistInt = (List)xms.Deserialize(sr); } catch (Exception ex) { MessageBox.Show( ex.Message, "Load failed", MessageBoxButtons.OK, MessageBoxIcon.Hand); } finally { if (sr != null) { sr.Close(); } } int numPids = 0; int numSensors = 0; this.pidgrouplistInt.Sort(Utils.pidgroups_sorter); this.restrictedPidgrouplistInt = new List(); foreach (XmlClass.pidgroup group in this.pidgrouplistInt) { numPids += group.pids.Count; group.sortPids(); foreach (XmlClass.pidgroup.pidlist listItem in group.pids) { numSensors += listItem.sensors.Count; listItem.sortSensors(); } } int numFPids = numPids; int numFSensors = numSensors; foreach (XmlClass.pidgroup group in this.pidgrouplistInt) { this.restrictedPidgrouplistInt.Add(duplicate(group)); } // Category 0 means that we want all unit categories no matter what. if (this.iPreferences.selectedUnitCategory > 0) { this.iLogging.appendText("Selecting preferred units for category " + this.iPreferences.selectedUnitCategory + "\r\n"); foreach (XmlClass.pidgroup group in this.restrictedPidgrouplistInt) { this.iLogging.appendText("Processing group '" + group.name + "' with " + group.pids.Count + " pids.\r\n"); foreach (XmlClass.pidgroup.pidlist listItem in group.pids) { XmlClass.pidgroup.pidlist.sensordata[] sensorArray = listItem.sensors.ToArray(); foreach (XmlClass.pidgroup.pidlist.sensordata sensor in sensorArray) { if (sensor != null && sensor.unit != null) { XmlClass.unititem thisunit = null; foreach (XmlClass.unititem unit in this.iDataSource.units) { if (sensor.unit.Equals(unit.name)) { thisunit = unit; break; } } if (thisunit != null && thisunit.category > 0 && thisunit.category != this.iPreferences.selectedUnitCategory) { if (listItem.sensors.Remove(sensor)) { numFSensors--; } else { this.iLogging.appendText("Failed to remove unit '" + thisunit.name + "'\r\n"); } } } } } } } this.iLogging.appendText(this.pidgrouplistInt.Count + " PID Groups with a total of " + numPids + " and " + numSensors + " sensors Loaded from XML file." + "\r\n"); this.iLogging.appendText(this.restrictedPidgrouplistInt.Count + " Filtered PID Groups with a total of " + numFPids + " and " + numFSensors + " sensors Loaded from XML file." + "\r\n"); } } }