blob: 9b978648ee69b4aebbbbaf7028870b9c8fcda412 [file] [log] [blame] [raw]
/* 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;
}
}
}