| /* Copyright 2015-2022 Rivoreo |
| |
| Permission is hereby granted, free of charge, to any person obtaining |
| a copy of this software and associated documentation files (the |
| "Software"), to deal in the Software without restriction, including |
| without limitation the rights to use, copy, modify, merge, publish, |
| distribute, sublicense, and/or sell copies of the Software, and to |
| permit persons to whom the Software is furnished to do so, subject to |
| the following conditions: |
| |
| The above copyright notice and this permission notice shall be |
| included in all copies or substantial portions of the Software. |
| |
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE |
| FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF |
| CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
| WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| */ |
| |
| using System; |
| using System.IO; |
| using System.Collections.Generic; |
| using System.Text.RegularExpressions; |
| |
| namespace Rivoreo.Configurations { |
| public class FlatConfiguration : Configuration { |
| private FlatConfiguration() { |
| dictionary = new Dictionary<String, String>(); |
| } |
| |
| public static FlatConfiguration CreateFromTextReader(TextReader reader) { |
| //readonly char[] separators = new char[] { ' ', '=' }; |
| FlatConfiguration config = new FlatConfiguration(); |
| String line; |
| while((line = reader.ReadLine()) != null) { |
| line = line.Trim(); |
| if(line[0] == '#') continue; |
| int i = line.IndexOf('='); |
| if(i < 0) i = line.IndexOf(' '); |
| if(i < 1) continue; |
| String key = line.Remove(i).Trim(); |
| String value = line.Substring(i + 1).Trim(); |
| //dictionary.Add(key, value); |
| config.dictionary[key] = value; |
| } |
| return config; |
| } |
| |
| public static FlatConfiguration CreateFromStream(Stream stream) { |
| using(StreamReader reader = new StreamReader(stream)) { |
| FlatConfiguration config = CreateFromTextReader(reader); |
| config.stream = stream; |
| return config; |
| } |
| } |
| |
| public static FlatConfiguration CreateFromFile(String path) { |
| FlatConfiguration config; |
| using(Stream stream = File.Open(path, FileMode.OpenOrCreate, FileAccess.Read)) { |
| config = CreateFromStream(stream); |
| config.stream = null; |
| } |
| config.file_path = path; |
| return config; |
| } |
| |
| private static readonly Regex double_value_regex = new Regex("^[0-9]+(\\.[0-9]+)?[Dd]$"); |
| private static readonly Regex float_value_regex = new Regex("^[0-9]+(\\.[0-9]+)?[Ff]$"); |
| |
| private Dictionary<String, String> dictionary; |
| private bool is_modified; |
| private Stream stream; |
| private String file_path; |
| |
| public bool GetBoolean(String key, bool default_value) { |
| String s; |
| if(dictionary.TryGetValue(key, out s)) { |
| bool value; |
| if(Boolean.TryParse(s, out value)) return value; |
| if(s.Equals("off", StringComparison.CurrentCultureIgnoreCase) || s.Equals("no", StringComparison.CurrentCultureIgnoreCase)) return false; |
| if(s.Equals("on", StringComparison.CurrentCultureIgnoreCase) || s.Equals("yes", StringComparison.CurrentCultureIgnoreCase)) return true; |
| } |
| return default_value; |
| } |
| |
| public int GetInt32(String key, int default_value) { |
| String s; |
| if(dictionary.TryGetValue(key, out s)) { |
| int value; |
| if(Int32.TryParse(s, out value)) return value; |
| } |
| return default_value; |
| } |
| |
| public long GetInt64(String key, long default_value) { |
| String s; |
| if(dictionary.TryGetValue(key, out s)) { |
| long value; |
| if(Int64.TryParse(s, out value)) return value; |
| } |
| return default_value; |
| } |
| |
| public float GetFloat32(String key, float default_value) { |
| String s; |
| if(dictionary.TryGetValue(key, out s)) { |
| float value; |
| if(Single.TryParse(s, out value)) return value; |
| } |
| return default_value; |
| } |
| |
| public double GetFloat64(String key, double default_value) { |
| String s; |
| if(dictionary.TryGetValue(key, out s)) { |
| double value; |
| if(Double.TryParse(s, out value)) return value; |
| } |
| return default_value; |
| } |
| |
| public String GetString(String key, String default_value) { |
| String s; |
| if(dictionary.TryGetValue(key, out s)) return s; |
| return default_value; |
| } |
| |
| public Configuration GetChild(String key, bool create_if_nonexist) { |
| throw new NotSupportedException("FlatConfiguration doesn't support hierarchies"); |
| } |
| |
| private static Object guess_type(String s, Type hint) { |
| bool boolean_value; |
| if(Boolean.TryParse(s, out boolean_value)) return boolean_value; |
| if(s.Equals("off", StringComparison.CurrentCultureIgnoreCase) || s.Equals("no", StringComparison.CurrentCultureIgnoreCase)) return false; |
| if(s.Equals("on", StringComparison.CurrentCultureIgnoreCase) || s.Equals("yes", StringComparison.CurrentCultureIgnoreCase)) return true; |
| if(!hint.Equals(typeof(long))) { |
| int value; |
| if(Int32.TryParse(s, out value)) return value; |
| } |
| long int64_value; |
| if(Int64.TryParse(s, out int64_value)) return int64_value; |
| if(double_value_regex.IsMatch(s)) { |
| double value; |
| if(Double.TryParse(s, out value)) return value; |
| } else if(float_value_regex.IsMatch(s)) { |
| float value; |
| if(Single.TryParse(s, out value)) return value; |
| } |
| try { |
| return hint == typeof(float) ? Single.Parse(s) : Double.Parse(s); |
| } catch(FormatException) { |
| return s; |
| } |
| } |
| |
| //public GetAll(Type type); |
| |
| public void Set(String key, bool value) { |
| dictionary[key] = Convert.ToString(value); |
| is_modified = true; |
| } |
| |
| public void Set(String key, int value) { |
| dictionary[key] = Convert.ToString(value); |
| is_modified = true; |
| } |
| |
| public void Set(String key, long value) { |
| dictionary[key] = Convert.ToString(value); |
| is_modified = true; |
| } |
| |
| public void Set(String key, float value) { |
| dictionary[key] = Convert.ToString(value); |
| is_modified = true; |
| } |
| |
| public void Set(String key, double value) { |
| dictionary[key] = Convert.ToString(value); |
| is_modified = true; |
| } |
| |
| public void Set(String key, String value) { |
| dictionary[key] = value; |
| is_modified = true; |
| } |
| |
| public void Set(String key, Configuration value) { |
| throw new NotSupportedException("FlatConfiguration doesn't support hierarchies"); |
| } |
| |
| private void write(Stream stream) { |
| using(StreamWriter writer = new StreamWriter(stream)) { |
| foreach(KeyValuePair<String, String> kvp in dictionary) { |
| writer.WriteLine("{0}={1}", kvp.Key, kvp.Value); |
| } |
| } |
| } |
| |
| public void Save() { |
| if(!is_modified) return; |
| Exception saved_exception = null; |
| if(this.stream != null) try { |
| write(this.stream); |
| stream.Flush(); |
| return; |
| } catch(IOException e) { |
| saved_exception = e; |
| } |
| if(file_path != null) { |
| using(Stream stream = File.Open(file_path, FileMode.Create, FileAccess.Write)) { |
| write(stream); |
| } |
| return; |
| } |
| throw saved_exception == null ? |
| new IOException("Configuration file path not known") : saved_exception; |
| } |
| } |
| } |