//-----------------------------------------------------------------------
//
// 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");
}
}
}