forked from IronLanguages/ironpython3
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathIniParser.cs
More file actions
136 lines (108 loc) · 5.05 KB
/
IniParser.cs
File metadata and controls
136 lines (108 loc) · 5.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.IO;
namespace IronPythonTest.Util {
using Section = Dictionary<string, string>;
using OptionStore = Dictionary<string, Dictionary<string, string>>;
public class IniParser {
private OptionStore options;
public IniParser(Stream source) {
this.options = Parse(new StreamReader(source).ReadLines());
}
public string GetValue(string sectionName, string key) {
return GetValue(sectionName, key, null);
}
public string GetValue(string sectionName, string key, string @default) {
sectionName = string.IsNullOrEmpty(sectionName) ? "DEFAULT" : sectionName;
string value;
while ((sectionName = GetParentSection(sectionName, out Section section)) != null) {
if (section.TryGetValue(key, out value)) {
return value;
}
}
return options["DEFAULT"].TryGetValue(key, out value) ? value : @default;
}
private string GetParentSection(string sectionName, out Section section) {
var idx = sectionName.LastIndexOf('.');
var newSectionName = idx == -1 ? null : sectionName.Substring(0, idx);
return options.TryGetValue(sectionName, out section) || newSectionName == null ? newSectionName : GetParentSection(newSectionName, out section);
}
public bool GetBool(string sectionName, string key) {
return GetValue(sectionName, key).AsBool();
}
public bool GetBool(string sectionName, string key, bool @default) {
return GetValue(sectionName, key, @default ? "t" : "f").AsBool();
}
public int GetInt(string sectionName, string key) {
return GetValue(sectionName, key).AsInt();
}
public int GetInt(string sectionName, string key, int @default) {
return GetValue(sectionName, key, @default.ToString()).AsInt();
}
public TEnum GetEnum<TEnum>(string sectionName, string key) {
return this.GetValue(sectionName, key).AsEnum<TEnum>();
}
public TEnum GetEnum<TEnum>(string sectionName, string key, TEnum @default) {
return this.GetValue(sectionName, key, @default.ToString()).AsEnum<TEnum>();
}
private static OptionStore Parse(IEnumerable<string> lines) {
Section currentSection = new Section();
OptionStore options = new OptionStore(StringComparer.OrdinalIgnoreCase) { { "DEFAULT", currentSection } };
foreach (var rawline in lines) {
string line = rawline.Split(new [] { ';', '#' }, 2)[0].Trim();
if (string.IsNullOrEmpty(line)) continue;
//if (line.StartsWith('[', StringComparison.Ordinal) && line.EndsWith(']', StringComparison.Ordinal)) {
if (line.Length >= 2 && line[0] == '[' && line[line.Length - 1] == ']') {
var sectionName = line.Substring(1, line.Length - 2);
if (!options.TryGetValue(sectionName, out currentSection)) {
currentSection = new Section();
options.Add(sectionName, currentSection);
}
} else {
var result = line.Split(new [] {'='}, 2);
var key = result[0].Trim();
var value = result.Length > 1 ? result[1] : "1";
currentSection.Add(key, value);
}
}
return options;
}
}
internal static class TextReaderExtensions {
public static IEnumerable<string> ReadLines(this TextReader tr) {
string line;
while ((line = tr.ReadLine()) != null) {
yield return line;
}
}
}
internal static class StringExtensions {
private static HashSet<string> Truthy = new HashSet<string> { "1", "t", "true", "y", "yes" };
private static HashSet<string> Falsey = new HashSet<string> { "0", "f", "false", "n", "no" };
public static bool AsBool(this string s) {
if (s == null) {
throw new ArgumentNullException(nameof(s));
}
var l = s.ToLowerInvariant();
if (Truthy.Contains(l)) {
return true;
} else if (Falsey.Contains(l)) {
return false;
} else {
throw new ArgumentException(string.Format("'{0}' is neither true nor false.", s));
}
}
public static int AsInt(this string s) {
if(s == null) {
throw new ArgumentNullException(nameof(s));
}
return int.Parse(s);
}
public static TEnum AsEnum<TEnum>(this string s) {
return (TEnum)Enum.Parse(typeof(TEnum), s);
}
}
}