rmsoft1

INIFile.cs

May 9th, 2018
236
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 20.63 KB | None | 0 0
  1. //https://rms0.org?a=r1
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.IO;
  7. using System.Net;
  8. namespace RMSoftware.IO
  9. {
  10.     /// <summary>
  11.     /// Provides a configuration system that reads and writes in the INI File language.
  12.     /// Supports reading from internet resources.
  13.     /// </summary>
  14.     public class INIFile
  15.     {
  16.         #region internal
  17.         string FilePath;
  18.         List<string> lines = new List<string>();
  19.         bool busy = false;
  20.         bool _GeneratedNewFile = false;
  21.         bool FromInternet = false;
  22.         bool Streamed = false;
  23.         /// <summary>
  24.         /// Returns the local filename and location.
  25.         /// </summary>
  26.         /// <exception cref="System.InvalidOperationException"></exception>
  27.         /// <returns></returns>
  28.         public string GetFileName()
  29.         {
  30.             if (FromInternet)
  31.             {
  32.                 throw new InvalidOperationException("Attempted to return a local file while using an internet resource.");
  33.             }
  34.             return FilePath;
  35.         }
  36.         #endregion
  37.  
  38.         #region public
  39.         public List<INICategory> Categories = new List<INICategory>();
  40.         /// <summary>
  41.         /// Returns true if a new file had to be created.
  42.         /// </summary>
  43.         public bool GeneratedNewFile { get { return _GeneratedNewFile; } }
  44.         #endregion
  45.  
  46.         public INIFile(string pathOrURL)
  47.         {
  48.             _GeneratedNewFile = false;
  49.             FromInternet = (pathOrURL.StartsWith("http://") || pathOrURL.StartsWith("https://"));
  50.             if (!FromInternet)
  51.             {
  52.                 FilePath = pathOrURL;
  53.                 VerifyFile(pathOrURL);
  54.                 readFromFile(pathOrURL);
  55.             }
  56.             if (FromInternet)
  57.             {
  58.                 readFromInternet(pathOrURL);
  59.             }
  60.  
  61.             ProcessLines();
  62.            
  63.         }
  64.  
  65.  
  66.        
  67.         public INIFile(byte[] rawData)
  68.         {
  69.  
  70.             Streamed = true;
  71.             using (MemoryStream dataStream = new MemoryStream(rawData))
  72.             {
  73.                 using (StreamReader sr = new StreamReader(dataStream))
  74.                 {
  75.                     string line = "";
  76.                     while (true)
  77.                     {
  78.                         line = sr.ReadLine();
  79.                         if (line != null)
  80.                         {
  81.                             if (!line.StartsWith("#") && !line.StartsWith(";"))
  82.                             {
  83.                                 if (!string.IsNullOrWhiteSpace(line))
  84.                                 {
  85.                                     lines.Add(line);
  86.                                 }
  87.                             }
  88.                         }
  89.                         if (sr.EndOfStream)
  90.                         {
  91.                             break;
  92.                         }
  93.                     }
  94.                 }
  95.  
  96.             }
  97.             ProcessLines();
  98.  
  99.         }
  100.  
  101.         #region Public Methods
  102.         /// <summary>
  103.         /// Creates a new INI entry in an existing category. If the category doesn't exist, an argument exception is thrown.
  104.         /// If the entry exists in that category, an argument exception is thrown.
  105.         /// </summary>
  106.         /// <param name="category">The name of the category to place entry (Enter it without the brackets '[]' please.)</param>
  107.         /// <param name="entry">The name of the new entry</param>
  108.         /// <param name="entryValue">The value for the entry.</param>
  109.         /// <exception cref="ArgumentException"></exception>
  110.         /// <exception cref="ArgumentNullException"></exception>
  111.         /// <exception cref="InvalidOperationException"></exception>
  112.         public void CreateEntry(string category, string entry, object entryValue)
  113.         {
  114.             if (FromInternet || Streamed)
  115.             {
  116.                 throw (new InvalidOperationException("You Cannot modify stream"));
  117.             }
  118.             if (string.IsNullOrWhiteSpace(category))
  119.             {
  120.                 throw (new ArgumentNullException("The category must be contain at least one non-whitespace character."));
  121.             }
  122.             if (string.IsNullOrWhiteSpace(entry))
  123.             {
  124.                 throw (new ArgumentNullException("The entry name must be contain at least one non-whitespace character."));
  125.             }
  126.             INICategory cat = GetCategoryByName(category);
  127.             if (cat == null)
  128.             {
  129.                 throw (new ArgumentException("The category doesn't exist. Please check your spelling and casing."));
  130.             }
  131.             foreach (INIEntry item in cat.Entries)
  132.             {
  133.                 if (item.Name == entry)
  134.                 {
  135.                     throw (new ArgumentException("The entry you specified already exists."));
  136.                 }
  137.             }
  138.             cat.Entries.Add(new INIEntry(entry, entryValue.ToString()));
  139.  
  140.         }
  141.  
  142.         /// <summary>
  143.         /// Creates a new INI Category
  144.         /// </summary>
  145.         /// <param name="category">The name of the new category. (Enter it without the brackets '[]' please.)</param>
  146.         /// <exception cref="ArgumentException"></exception>
  147.         /// <exception cref="ArgumentNullException"></exception>
  148.         public void CreateCategory(string c)
  149.         {
  150.             string category = c.ToLower();
  151.             if (FromInternet || Streamed)
  152.             {
  153.                 throw (new InvalidOperationException("You Cannot modify stream"));
  154.             }
  155.             if (string.IsNullOrWhiteSpace(category))
  156.             {
  157.                 throw (new ArgumentNullException("The category must be contain at least one non-whitespace character."));
  158.             }
  159.             foreach (INICategory item in Categories)
  160.             {
  161.                 if (item.Name == category)
  162.                 {
  163.                     throw (new ArgumentException("That category already exists"));
  164.                 }
  165.             }
  166.             Categories.Add(new INICategory(category));
  167.         }
  168.  
  169.         /// <summary>
  170.         /// Deletes INI entry in an existing category. If the category doesn't exist, an argument exception is thrown.
  171.         /// If the entry Doesn't exists in that category, an argument exception is thrown.
  172.         /// </summary>
  173.         /// <param name="category">The name of the category to remove entry from (Enter it without the brackets '[]' please.)</param>
  174.         /// <param name="entry">The name of the entry</param>
  175.         /// <exception cref="ArgumentException"></exception>
  176.         /// <exception cref="ArgumentNullException"></exception>
  177.         public void DeleteEntry(string category, string entry)
  178.         {
  179.             if (FromInternet || Streamed)
  180.             {
  181.                 throw (new InvalidOperationException("You Cannot modify stream"));
  182.             }
  183.             if (string.IsNullOrWhiteSpace(category))
  184.             {
  185.                 throw (new ArgumentNullException("The category must be contain at least one non-whitespace character."));
  186.             }
  187.             if (string.IsNullOrWhiteSpace(entry))
  188.             {
  189.                 throw (new ArgumentNullException("The entry name must be contain at least one non-whitespace character."));
  190.             }
  191.             INICategory cat = GetCategoryByName(category);
  192.             if (cat == null)
  193.             {
  194.                 throw (new ArgumentException("The category doesn't exist. Please check your spelling and casing."));
  195.             }
  196.             cat.Entries.Remove(cat.GetEntryByName(entry));
  197.  
  198.         }
  199.  
  200.         /// <summary>
  201.         /// Deletes an INI Category
  202.         /// </summary>
  203.         /// <param name="category">The name of the category to delete. (Enter it without the brackets '[]' please.)</param>
  204.         /// <exception cref="ArgumentException"></exception>
  205.         /// <exception cref="ArgumentNullException"></exception>
  206.         public void DeleteCategory(string c)
  207.         {
  208.             string category = c.ToLower();
  209.             if (FromInternet || Streamed)
  210.             {
  211.                 throw (new InvalidOperationException("You Cannot modify stream"));
  212.             }
  213.             if (string.IsNullOrWhiteSpace(category))
  214.             {
  215.                 throw (new ArgumentNullException("The category must be contain at least one non-whitespace character."));
  216.             }
  217.             Categories.Remove(GetCategoryByName(category));
  218.         }
  219.  
  220.         /// <summary>
  221.         /// Writes the configuration to disk.
  222.         /// </summary>
  223.         public void SaveConfiguration()
  224.         {
  225.             if (FromInternet || Streamed)
  226.             {
  227.                 throw (new InvalidOperationException("Internet or streamed configurations cannot be saved. Read Only."));
  228.             }
  229.             if (busy)
  230.             {
  231.                 return;
  232.             }
  233.             busy = true;
  234.             VerifyFile(FilePath);
  235.             int index = 0;
  236.             using (FileStream fs = new FileStream(FilePath,FileMode.Truncate,FileAccess.Write))
  237.             {
  238.                 using(StreamWriter sw = new StreamWriter(fs))
  239.                 {
  240.                     sw.WriteLine("#File Generated by the RMSoftware.IO Library.");
  241.                     sw.WriteLine("#Creation Timestamp: {0}", DateTime.Now.ToString());
  242.                     sw.WriteLine();
  243.                     foreach (INICategory item in Categories)
  244.                     {
  245.                         if (index > 0)
  246.                         {
  247.                             sw.WriteLine();
  248.                         }
  249.                         sw.WriteLine(item.ToString());
  250.                         index++;
  251.                         foreach (INIEntry entry in item.Entries)
  252.                         {
  253.                             sw.WriteLine(entry.ToString());
  254.                         }
  255.                     }
  256.                 }
  257.             }
  258.             busy = false;
  259.         }
  260.  
  261.  
  262.         /// <summary>
  263.         /// Checks for the existence of a specified category. if none is found, returns false.
  264.         /// </summary>
  265.         /// <param name="category"></param>
  266.         /// <returns></returns>
  267.         public bool CheckForCategory(string category)
  268.         {
  269.             if (GetCategoryByName(category) == null)
  270.             {
  271.                 return false;
  272.             }
  273.             else
  274.             {
  275.                 return true;
  276.             }
  277.         }
  278.  
  279.  
  280.         public INICategory GetCategoryByName(string name)
  281.         {
  282.             foreach (INICategory item in Categories)
  283.             {
  284.                 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.
  285.                 {
  286.                     return item;
  287.                 }
  288.             }
  289.             return null; //instead of errors.
  290.             //throw (new ArgumentException("The name provided did not match any categories available."));
  291.         }
  292.         #endregion
  293.  
  294.         #region Private Methods
  295.         private void VerifyFile(string path)
  296.         {
  297.             string pathfull = Path.GetFullPath(path);
  298.             if (!Directory.Exists(Path.GetDirectoryName(pathfull))) //The directory does not exist. Impossible for the file to exist.
  299.             {
  300.                 //Console.WriteLine("DIRECTORY NOT FOUND. " + Path.GetDirectoryName(path));
  301.  
  302.                 Directory.CreateDirectory(Path.GetDirectoryName(pathfull));
  303.  
  304.                 //Console.WriteLine("FILE NOT FOUND. " + Path.GetFileName(path));
  305.                 FileStream fs = File.Create(pathfull);
  306.                 fs.Close();
  307.                 _GeneratedNewFile = true;
  308.             }
  309.             else//The directory exists
  310.             {
  311.                 //Console.WriteLine("DIRECTORY FOUND. " + Path.GetDirectoryName(path));
  312.                 if (!File.Exists(pathfull)) //and the file does not exist.
  313.                 {
  314.                     //Console.WriteLine("FILE NOT FOUND. " + Path.GetFileName(path));
  315.                     FileStream fs = File.Create(pathfull);
  316.                     fs.Close();
  317.                     _GeneratedNewFile = true;
  318.                 }
  319.                 else
  320.                 {
  321.                     //Console.WriteLine("FILE FOUND. " + Path.GetFileName(path));
  322.                 }
  323.             }
  324.         }
  325.         void readFromFile(string fromPath)
  326.         {
  327.            
  328.             using (FileStream fs = new FileStream(fromPath, FileMode.Open))
  329.             {
  330.                 using (StreamReader sr = new StreamReader(fs))
  331.                 {
  332.                     string line = "";
  333.                     while (true)
  334.                     {
  335.                         line = sr.ReadLine();
  336.                         if (line != null)
  337.                         {
  338.                             if (!line.StartsWith("#") && !line.StartsWith(";"))
  339.                             {
  340.                                 if (!string.IsNullOrWhiteSpace(line))
  341.                                 {
  342.                                     lines.Add(line);
  343.                                 }
  344.                             }
  345.                         }
  346.                         if (sr.EndOfStream)
  347.                         {
  348.                             break;
  349.                         }
  350.                     }
  351.                 }
  352.             }
  353.         }
  354.  
  355.         /// <summary>
  356.         /// Reads from internet resource
  357.         /// </summary>
  358.         /// <exception cref="WebException">Thrown if we can't connect.</exception>
  359.         /// <param name="URL"></param>
  360.         void readFromInternet(string URL)
  361.         {
  362.             try
  363.             {
  364.                 WebRequest iniRequest = WebRequest.Create(URL);
  365.                 using (Stream Response = iniRequest.GetResponse().GetResponseStream())
  366.                 {
  367.                     using (StreamReader sr = new StreamReader(Response))
  368.                     {
  369.                         string line = "";
  370.                         while (true)
  371.                         {
  372.                             line = sr.ReadLine();
  373.                             if (line != null)
  374.                             {
  375.                                 if (!line.StartsWith("#"))
  376.                                 {
  377.                                     if (!string.IsNullOrWhiteSpace(line))
  378.                                     {
  379.                                         lines.Add(line);
  380.                                     }
  381.                                 }
  382.                             }
  383.                             if (sr.EndOfStream)
  384.                             {
  385.                                 break;
  386.                             }
  387.                         }
  388.                     }
  389.                 }
  390.             }
  391.             catch (WebException exc)
  392.             {
  393.                
  394.                 throw exc;
  395.             }
  396.            
  397.         }
  398.  
  399.         void ProcessLines()
  400.         {
  401.             int catIndex = -1;
  402.             if (lines.Count == 0)
  403.             {
  404.                 return;
  405.             }
  406.  
  407.             foreach (string line in lines)
  408.             {
  409.                 if (line.StartsWith("[") && line.EndsWith("]"))
  410.                 {
  411.                     string name = line.Replace("[", "").Replace("]", "");
  412.                     Categories.Add(new INICategory(name));
  413.                     catIndex++;
  414.                 }
  415.                 else
  416.                 {
  417.                     string[] splittedString = line.Split('=');
  418.                     string name = splittedString[0];
  419.                     string v = splittedString[1];
  420.                     if (splittedString.Length > 2)
  421.                     {
  422.                         for (int i = 2; i < splittedString.Length; i++)
  423.                         {
  424.                             v += "=" + splittedString[i];
  425.                         }
  426.                     }
  427.                     Categories[catIndex].Entries.Add(new INIEntry(name, v));
  428.                 }
  429.             }
  430.         }
  431.         #endregion
  432.  
  433.     }
  434.     /// <summary>
  435.     /// Category within INI file. appears as: [Category1]
  436.     /// </summary>
  437.     public class INICategory
  438.     {
  439.         public string Name {get;set;}
  440.         public List<INIEntry> Entries = new List<INIEntry>();
  441.         /// <summary>
  442.         /// Returns how this would look inside an INI file.
  443.         /// </summary>
  444.         /// <returns></returns>
  445.         public override string ToString()
  446.         {
  447.             return "["+Name+"]";
  448.         }
  449.         /// <summary>
  450.         /// Creates a new category with several objects.
  451.         /// </summary>
  452.         /// <param name="name">The name of the category</param>
  453.         /// <param name="entries">A collection of entries in a category. </param>
  454.         public INICategory(string name)
  455.         {
  456.             this.Name = name;
  457.         }
  458.  
  459.         /// <summary>
  460.         /// Checks for the existence of an entry. if not found, returns false.
  461.         /// </summary>
  462.         /// <param name="entry"></param>
  463.         /// <returns></returns>
  464.         public bool CheckForEntry(string entry)
  465.         {
  466.             if (GetEntryByName(entry) == null)
  467.             {
  468.                 return false;
  469.             }
  470.             else
  471.             {
  472.                 return true;
  473.             }
  474.         }
  475.  
  476.         public INIEntry GetEntryByName(string name)
  477.         {
  478.             foreach (INIEntry item in Entries)
  479.             {
  480.                 if (item.Name == name)
  481.                 {
  482.                     return item;
  483.                 }
  484.             }
  485.             //throw (new ArgumentException("The name provided did not match any entries available."));
  486.             return null;//rather than errors;
  487.         }
  488.  
  489.     }
  490.     /// <summary>
  491.     /// Entry inside a category appears as Entry1=hello
  492.     /// </summary>
  493.     public class INIEntry
  494.     {
  495.         /// <summary>
  496.         /// Get and set the name for the entry
  497.         /// </summary>
  498.         public string Name { get; set; }
  499.         /// <summary>
  500.         /// Get and set the value of the entry.
  501.         /// </summary>
  502.         string Value {get;set;}
  503.         /// <summary>
  504.         /// Returns how this would look inside an INI file.
  505.         /// </summary>
  506.         /// <returns></returns>
  507.         public override string ToString()
  508.         {
  509.             return Name + "=" + Value;
  510.         }
  511.  
  512.         public int GetAsInteger()
  513.         {
  514.             try
  515.             {
  516.                 return int.Parse(Value);
  517.             }
  518.             catch (Exception)
  519.             {
  520.                
  521.                 throw;
  522.             }
  523.         }
  524.         public double GetAsDouble()
  525.         {
  526.             try
  527.             {
  528.                 return double.Parse(Value);
  529.             }
  530.             catch (Exception)
  531.             {
  532.  
  533.                 throw;
  534.             }
  535.         }
  536.         public long GetAslong()
  537.         {
  538.             try
  539.             {
  540.                 return long.Parse(Value);
  541.             }
  542.             catch (Exception)
  543.             {
  544.  
  545.                 throw;
  546.             }
  547.         }
  548.         public ulong GetAsUlong()
  549.         {
  550.             try
  551.             {
  552.                 return ulong.Parse(Value);
  553.             }
  554.             catch (Exception)
  555.             {
  556.  
  557.                 throw;
  558.             }
  559.         }
  560.         public bool GetAsBool()
  561.         {
  562.             try
  563.             {
  564.                 return bool.Parse(Value);
  565.             }
  566.             catch (Exception)
  567.             {
  568.  
  569.                 throw;
  570.             }
  571.         }
  572.         public byte GetAsByte()
  573.         {
  574.             try
  575.             {
  576.                 return byte.Parse(Value);
  577.             }
  578.             catch (Exception)
  579.             {
  580.  
  581.                 throw;
  582.             }
  583.         }
  584.         public string GetAsString()
  585.         {
  586.             return Value;
  587.         }
  588.  
  589.         public void SetValue(int value)
  590.         {
  591.             Value = value.ToString();
  592.         }
  593.         public void SetValue(double value)
  594.         {
  595.             Value = value.ToString();
  596.         }
  597.         public void SetValue(long value)
  598.         {
  599.             Value = value.ToString();
  600.         }
  601.         public void SetValue(bool value)
  602.         {
  603.             Value = value.ToString();
  604.         }
  605.         public void SetValue(byte value)
  606.         {
  607.             Value = value.ToString();
  608.         }
  609.         public void SetValue(string value)
  610.         {
  611.             Value = value;
  612.         }
  613.         /// <summary>
  614.         /// Creates an INI Entry.
  615.         /// </summary>
  616.         /// <param name="name">The name for the entry</param>
  617.         /// <param name="value">The value of the entry.</param>
  618.         public INIEntry(string name, string value)
  619.         {
  620.             Name = name;
  621.             Value = value;
  622.         }
  623.     }
  624. }
Advertisement
Add Comment
Please, Sign In to add comment