//----------------------------------------------------------------------- // // 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. } } } } } } } }