rmsoft1 icon

INIFile.cs

rmsoft1 | PRO | 05/09/18 09:42:32 PM UTC | 0 ⭐ | 198 👁️ | Never ⏰ | []
C# |

20.63 KB

|

None

|

0 👍

/

0 👎

//https://rms0.org?a=r1
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
namespace RMSoftware.IO
{
    /// <summary>
    /// Provides a configuration system that reads and writes in the INI File language.
    /// Supports reading from internet resources.
    /// </summary>
    public class INIFile
    {
        #region internal
        string FilePath;
        List<string> lines = new List<string>();
        bool busy = false;
        bool _GeneratedNewFile = false;
        bool FromInternet = false;
        bool Streamed = false;
        /// <summary>
        /// Returns the local filename and location.
        /// </summary>
        /// <exception cref="System.InvalidOperationException"></exception>
        /// <returns></returns>
        public string GetFileName()
        {
            if (FromInternet)
            {
                throw new InvalidOperationException("Attempted to return a local file while using an internet resource.");
            }
            return FilePath;
        }
        #endregion
 
        #region public
        public List<INICategory> Categories = new List<INICategory>();
        /// <summary>
        /// Returns true if a new file had to be created.
        /// </summary>
        public bool GeneratedNewFile { get { return _GeneratedNewFile; } }
        #endregion
 
        public INIFile(string pathOrURL)
        {
            _GeneratedNewFile = false;
            FromInternet = (pathOrURL.StartsWith("http://") || pathOrURL.StartsWith("https://"));
            if (!FromInternet)
            {
                FilePath = pathOrURL;
                VerifyFile(pathOrURL);
                readFromFile(pathOrURL);
            }
            if (FromInternet)
            {
                readFromInternet(pathOrURL);
            }
 
            ProcessLines();
            
        }
 
 
        
        public INIFile(byte[] rawData)
        {
 
            Streamed = true;
            using (MemoryStream dataStream = new MemoryStream(rawData))
            {
                using (StreamReader sr = new StreamReader(dataStream))
                {
                    string line = "";
                    while (true)
                    {
                        line = sr.ReadLine();
                        if (line != null)
                        {
                            if (!line.StartsWith("#") && !line.StartsWith(";"))
                            {
                                if (!string.IsNullOrWhiteSpace(line))
                                {
                                    lines.Add(line);
                                }
                            }
                        }
                        if (sr.EndOfStream)
                        {
                            break;
                        }
                    }
                }
 
            }
            ProcessLines();
 
        }
 
        #region Public Methods
        /// <summary>
        /// Creates a new INI entry in an existing category. If the category doesn't exist, an argument exception is thrown.
        /// If the entry exists in that category, an argument exception is thrown.
        /// </summary>
        /// <param name="category">The name of the category to place entry (Enter it without the brackets '[]' please.)</param>
        /// <param name="entry">The name of the new entry</param>
        /// <param name="entryValue">The value for the entry.</param>
        /// <exception cref="ArgumentException"></exception>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="InvalidOperationException"></exception>
        public void CreateEntry(string category, string entry, object entryValue)
        {
            if (FromInternet || Streamed)
            {
                throw (new InvalidOperationException("You Cannot modify stream"));
            }
            if (string.IsNullOrWhiteSpace(category))
            {
                throw (new ArgumentNullException("The category must be contain at least one non-whitespace character."));
            }
            if (string.IsNullOrWhiteSpace(entry))
            {
                throw (new ArgumentNullException("The entry name must be contain at least one non-whitespace character."));
            }
            INICategory cat = GetCategoryByName(category);
            if (cat == null)
            {
                throw (new ArgumentException("The category doesn't exist. Please check your spelling and casing."));
            }
            foreach (INIEntry item in cat.Entries)
            {
                if (item.Name == entry)
                {
                    throw (new ArgumentException("The entry you specified already exists."));
                }
            }
            cat.Entries.Add(new INIEntry(entry, entryValue.ToString()));
 
        }
 
        /// <summary>
        /// Creates a new INI Category
        /// </summary>
        /// <param name="category">The name of the new category. (Enter it without the brackets '[]' please.)</param>
        /// <exception cref="ArgumentException"></exception>
        /// <exception cref="ArgumentNullException"></exception>
        public void CreateCategory(string c)
        {
            string category = c.ToLower();
            if (FromInternet || Streamed)
            {
                throw (new InvalidOperationException("You Cannot modify stream"));
            }
            if (string.IsNullOrWhiteSpace(category))
            {
                throw (new ArgumentNullException("The category must be contain at least one non-whitespace character."));
            }
            foreach (INICategory item in Categories)
            {
                if (item.Name == category)
                {
                    throw (new ArgumentException("That category already exists"));
                }
            }
            Categories.Add(new INICategory(category));
        }
 
        /// <summary>
        /// Deletes INI entry in an existing category. If the category doesn't exist, an argument exception is thrown.
        /// If the entry Doesn't exists in that category, an argument exception is thrown.
        /// </summary>
        /// <param name="category">The name of the category to remove entry from (Enter it without the brackets '[]' please.)</param>
        /// <param name="entry">The name of the entry</param>
        /// <exception cref="ArgumentException"></exception>
        /// <exception cref="ArgumentNullException"></exception>
        public void DeleteEntry(string category, string entry)
        {
            if (FromInternet || Streamed)
            {
                throw (new InvalidOperationException("You Cannot modify stream"));
            }
            if (string.IsNullOrWhiteSpace(category))
            {
                throw (new ArgumentNullException("The category must be contain at least one non-whitespace character."));
            }
            if (string.IsNullOrWhiteSpace(entry))
            {
                throw (new ArgumentNullException("The entry name must be contain at least one non-whitespace character."));
            }
            INICategory cat = GetCategoryByName(category);
            if (cat == null)
            {
                throw (new ArgumentException("The category doesn't exist. Please check your spelling and casing."));
            }
            cat.Entries.Remove(cat.GetEntryByName(entry));
 
        }
 
        /// <summary>
        /// Deletes an INI Category
        /// </summary>
        /// <param name="category">The name of the category to delete. (Enter it without the brackets '[]' please.)</param>
        /// <exception cref="ArgumentException"></exception>
        /// <exception cref="ArgumentNullException"></exception>
        public void DeleteCategory(string c)
        {
            string category = c.ToLower();
            if (FromInternet || Streamed)
            {
                throw (new InvalidOperationException("You Cannot modify stream"));
            }
            if (string.IsNullOrWhiteSpace(category))
            {
                throw (new ArgumentNullException("The category must be contain at least one non-whitespace character."));
            }
            Categories.Remove(GetCategoryByName(category));
        }
 
        /// <summary>
        /// Writes the configuration to disk.
        /// </summary>
        public void SaveConfiguration()
        {
            if (FromInternet || Streamed)
            {
                throw (new InvalidOperationException("Internet or streamed configurations cannot be saved. Read Only."));
            }
            if (busy)
            {
                return;
            }
            busy = true;
            VerifyFile(FilePath);
            int index = 0;
            using (FileStream fs = new FileStream(FilePath,FileMode.Truncate,FileAccess.Write))
            {
                using(StreamWriter sw = new StreamWriter(fs))
                {
                    sw.WriteLine("#File Generated by the RMSoftware.IO Library.");
                    sw.WriteLine("#Creation Timestamp: {0}", DateTime.Now.ToString());
                    sw.WriteLine();
                    foreach (INICategory item in Categories)
                    {
                        if (index > 0)
                        {
                            sw.WriteLine();
                        }
                        sw.WriteLine(item.ToString());
                        index++;
                        foreach (INIEntry entry in item.Entries)
                        {
                            sw.WriteLine(entry.ToString());
                        }
                    }
                }
            }
            busy = false;
        }
 
 
        /// <summary>
        /// Checks for the existence of a specified category. if none is found, returns false.
        /// </summary>
        /// <param name="category"></param>
        /// <returns></returns>
        public bool CheckForCategory(string category)
        {
            if (GetCategoryByName(category) == null)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
 
 
        public INICategory GetCategoryByName(string name)
        {
            foreach (INICategory item in Categories)
            {
                if (item.Name.ToLower() == name.ToLower())//case doesn't matter anymore it defaults to lowercase... so If something is added and it already exists in another case style, it will return the item.
                {
                    return item;
                }
            }
            return null; //instead of errors.
            //throw (new ArgumentException("The name provided did not match any categories available."));
        }
        #endregion
 
        #region Private Methods
        private void VerifyFile(string path)
        {
            string pathfull = Path.GetFullPath(path);
            if (!Directory.Exists(Path.GetDirectoryName(pathfull))) //The directory does not exist. Impossible for the file to exist.
            {
                //Console.WriteLine("DIRECTORY NOT FOUND. " + Path.GetDirectoryName(path));
 
                Directory.CreateDirectory(Path.GetDirectoryName(pathfull));
 
                //Console.WriteLine("FILE NOT FOUND. " + Path.GetFileName(path));
                FileStream fs = File.Create(pathfull);
                fs.Close();
                _GeneratedNewFile = true;
            }
            else//The directory exists
            {
                //Console.WriteLine("DIRECTORY FOUND. " + Path.GetDirectoryName(path));
                if (!File.Exists(pathfull)) //and the file does not exist.
                {
                    //Console.WriteLine("FILE NOT FOUND. " + Path.GetFileName(path));
                    FileStream fs = File.Create(pathfull);
                    fs.Close();
                    _GeneratedNewFile = true;
                }
                else
                {
                    //Console.WriteLine("FILE FOUND. " + Path.GetFileName(path));
                }
            }
        }
        void readFromFile(string fromPath)
        {
            
            using (FileStream fs = new FileStream(fromPath, FileMode.Open))
            {
                using (StreamReader sr = new StreamReader(fs))
                {
                    string line = "";
                    while (true)
                    {
                        line = sr.ReadLine();
                        if (line != null)
                        {
                            if (!line.StartsWith("#") && !line.StartsWith(";"))
                            {
                                if (!string.IsNullOrWhiteSpace(line))
                                {
                                    lines.Add(line);
                                }
                            }
                        }
                        if (sr.EndOfStream)
                        {
                            break;
                        }
                    }
                }
            }
        }
 
        /// <summary>
        /// Reads from internet resource
        /// </summary>
        /// <exception cref="WebException">Thrown if we can't connect.</exception>
        /// <param name="URL"></param>
        void readFromInternet(string URL)
        {
            try
            {
                WebRequest iniRequest = WebRequest.Create(URL);
                using (Stream Response = iniRequest.GetResponse().GetResponseStream())
                {
                    using (StreamReader sr = new StreamReader(Response))
                    {
                        string line = "";
                        while (true)
                        {
                            line = sr.ReadLine();
                            if (line != null)
                            {
                                if (!line.StartsWith("#"))
                                {
                                    if (!string.IsNullOrWhiteSpace(line))
                                    {
                                        lines.Add(line);
                                    }
                                }
                            }
                            if (sr.EndOfStream)
                            {
                                break;
                            }
                        }
                    }
                }
            }
            catch (WebException exc)
            {
                
                throw exc;
            }
            
        }
 
        void ProcessLines()
        {
            int catIndex = -1;
            if (lines.Count == 0)
            {
                return;
            }
 
            foreach (string line in lines)
            {
                if (line.StartsWith("[") && line.EndsWith("]"))
                {
                    string name = line.Replace("[", "").Replace("]", "");
                    Categories.Add(new INICategory(name));
                    catIndex++;
                }
                else
                {
                    string[] splittedString = line.Split('=');
                    string name = splittedString[0];
                    string v = splittedString[1];
                    if (splittedString.Length > 2)
                    {
                        for (int i = 2; i < splittedString.Length; i++)
                        {
                            v += "=" + splittedString[i];
                        }
                    }
                    Categories[catIndex].Entries.Add(new INIEntry(name, v));
                }
            }
        }
        #endregion
 
    }
    /// <summary>
    /// Category within INI file. appears as: [Category1]
    /// </summary>
    public class INICategory
    {
        public string Name {get;set;}
        public List<INIEntry> Entries = new List<INIEntry>();
        /// <summary>
        /// Returns how this would look inside an INI file.
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return "["+Name+"]";
        }
        /// <summary>
        /// Creates a new category with several objects.
        /// </summary>
        /// <param name="name">The name of the category</param>
        /// <param name="entries">A collection of entries in a category. </param>
        public INICategory(string name)
        {
            this.Name = name;
        }
 
        /// <summary>
        /// Checks for the existence of an entry. if not found, returns false.
        /// </summary>
        /// <param name="entry"></param>
        /// <returns></returns>
        public bool CheckForEntry(string entry)
        {
            if (GetEntryByName(entry) == null)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
 
        public INIEntry GetEntryByName(string name)
        {
            foreach (INIEntry item in Entries)
            {
                if (item.Name == name)
                {
                    return item;
                }
            }
            //throw (new ArgumentException("The name provided did not match any entries available."));
            return null;//rather than errors;
        }
 
    }
    /// <summary>
    /// Entry inside a category appears as Entry1=hello
    /// </summary>
    public class INIEntry
    {
        /// <summary>
        /// Get and set the name for the entry
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// Get and set the value of the entry.
        /// </summary>
        string Value {get;set;}
        /// <summary>
        /// Returns how this would look inside an INI file.
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return Name + "=" + Value;
        }
 
        public int GetAsInteger()
        {
            try
            {
                return int.Parse(Value);
            }
            catch (Exception)
            {
                
                throw;
            }
        }
        public double GetAsDouble()
        {
            try
            {
                return double.Parse(Value);
            }
            catch (Exception)
            {
 
                throw;
            }
        }
        public long GetAslong()
        {
            try
            {
                return long.Parse(Value);
            }
            catch (Exception)
            {
 
                throw;
            }
        }
        public ulong GetAsUlong()
        {
            try
            {
                return ulong.Parse(Value);
            }
            catch (Exception)
            {
 
                throw;
            }
        }
        public bool GetAsBool()
        {
            try
            {
                return bool.Parse(Value);
            }
            catch (Exception)
            {
 
                throw;
            }
        }
        public byte GetAsByte()
        {
            try
            {
                return byte.Parse(Value);
            }
            catch (Exception)
            {
 
                throw;
            }
        }
        public string GetAsString()
        {
            return Value;
        }
 
        public void SetValue(int value)
        {
            Value = value.ToString();
        }
        public void SetValue(double value)
        {
            Value = value.ToString();
        }
        public void SetValue(long value)
        {
            Value = value.ToString();
        }
        public void SetValue(bool value)
        {
            Value = value.ToString();
        }
        public void SetValue(byte value)
        {
            Value = value.ToString();
        }
        public void SetValue(string value)
        {
            Value = value;
        }
        /// <summary>
        /// Creates an INI Entry.
        /// </summary>
        /// <param name="name">The name for the entry</param>
        /// <param name="value">The value of the entry.</param>
        public INIEntry(string name, string value)
        {
            Name = name; 
            Value = value;
        }
    }
}

Comments