//-----------------------------------------------------------------------
//
// 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.Collections.Generic;
using System.Globalization;
using System.IO;
using global::SharedObjects;
///
/// Access class for OBD codes.
///
public class ObdCodeFileAccess : XmlParserHelper
{
///
/// Gets Name of file.
///
public string fileName { get; private set; }
///
/// Gets Dictionary of supported OBD codes.
///
public SortedDictionary obdcodes { get; private set; }
///
/// Initializes a new instance of the class.
///
/// Initiate access to OBD codes.
///
///
/// Logging interface.
/// 'true' if a new empty OBD list is to be created.
/// Data file directory path.
public ObdCodeFileAccess(ILogging iLogging, bool newList, string dataFileDir)
: base(iLogging, dataFileDir)
{
if (newList)
{
this.obdcodes = new SortedDictionary();
}
else
{
this.obdcodes = null;
}
this.fileName = null;
}
///
/// Initializes a new instance of the class.
///
/// Create a new instance based on an existing dictionary of codes.
///
///
/// Logging interface.
/// Existing dictionary
/// Data file directory path.
public ObdCodeFileAccess(ILogging iLogging, SortedDictionary addCodes, string dataFileDir)
: base(iLogging, dataFileDir)
{
this.obdcodes = new SortedDictionary(addCodes);
this.fileName = null;
}
///
/// Adds codes from the given dictionary to the current if
/// the code does not already exist.
///
/// Existing dictionary, may be 'null' in which case nothing happens.
public void addCodes(SortedDictionary additionalCodes)
{
if (this.obdcodes == null)
{
this.obdcodes = new SortedDictionary();
}
if (additionalCodes != null)
{
foreach (string key in additionalCodes.Keys)
{
if (!this.obdcodes.ContainsKey(key))
{
this.obdcodes.Add(key, additionalCodes[key]);
}
}
}
}
///
/// Add one single code, create code list if empty.
///
/// OBD code name, e.g. P0420
/// Description of OBD code.
public void add(string code, string description)
{
if (this.obdcodes == null)
{
this.obdcodes = new SortedDictionary();
}
this.obdcodes.Add(code, description);
}
///
/// Save codes to the same file as they were loaded from.
/// (Overwrites file)
///
public void save()
{
this.save(this.fileName);
}
///
/// Save codes to the given file.
///
/// File name
public void save(string saveFileName)
{
this.iLogging.appendText("Saving OBD codes to file : " + saveFileName + "\r\n");
if (saveFileName == Path.GetFileName(saveFileName))
{
saveFileName = this.dataFileDir + saveFileName;
}
StreamWriter sw = null;
try
{
sw = new StreamWriter(saveFileName);
foreach (string key in this.obdcodes.Keys)
{
sw.WriteLine(key + " " + this.obdcodes[key]);
}
}
finally
{
if (sw != null)
{
sw.Close();
}
}
}
///
/// Load OBD codes from a file with the given name.
///
/// Name and optionally path to file.
/// The file given is a specific file to open, not the standard file(s) for the application.
public void loadObdCodes(string codefile, bool specificFile)
{
using (StreamReader sr = this.openInFile(codefile, specificFile))
{
if (sr != null)
{
try
{
this.loadCodes(sr);
}
finally
{
closeInFile(sr);
}
}
}
}
///
/// Close in file.
///
/// Stream to close
private static void closeInFile(StreamReader sr)
{
try
{
if (sr != null)
{
sr.Close();
sr = null;
}
}
catch
{
}
}
///
/// Tries to open the file from one of three different locations:
///
///
/// #
/// Directory
///
/// -
/// 1.
/// Current Directory.
///
/// -
/// 2.
/// Common Application Data Directory.
///
/// -
/// 3.
/// Application Binary directory (last resort).
///
///
///
/// File containing OBD codes.
/// The file given is a specific file to open, not the standard file(s) for the application.
/// Stream reader instance for the file.
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Reviewed.")]
private StreamReader openInFile(string codefile, bool specificFile)
{
StreamReader sr = null;
string basename = Path.GetFileName(codefile);
string codeBase = System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase;
string dir = System.IO.Path.GetDirectoryName(codeBase);
string progdirFilename = dir + "\\" + basename;
this.iLogging.appendText("Loading OBD data from file.\r\n");
try
{
if (specificFile)
{
sr = new StreamReader(codefile);
this.fileName = codefile;
}
else
{
try
{
sr = new StreamReader(this.dataFileDir + basename);
this.fileName = this.dataFileDir + basename;
}
catch
{
sr = new StreamReader(progdirFilename);
this.fileName = progdirFilename;
}
}
this.iLogging.appendText("Found OBD codes in file : " + this.fileName + "\r\n");
}
catch
{
}
return sr;
}
///
/// Load the OBD codes from file.
///
/// Stream to read from.
private void loadCodes(StreamReader sr)
{
string line = string.Empty;
this.obdcodes = new SortedDictionary();
while ((line = sr.ReadLine()) != null)
{
if (line.Length > 0 && !line.StartsWith(";"))
{
int n = line.IndexOf(' ');
if (n > 0)
{
string code = line.Substring(0, n);
code = code.ToUpper(CultureInfo.InvariantCulture);
if (!this.obdcodes.ContainsKey(code))
{
try
{
this.obdcodes.Add(code, line.Substring(n + 1));
}
catch
{
// Ignore, discard duplicates.
}
}
}
}
}
}
}
}