Mercurial > projects > dynamin
comparison dynamin/core/settings.d @ 106:acdbb30fee7e
Port to D2.
Most of the effort was dealing with immutable and const.
author | Jordan Miner <jminer7@gmail.com> |
---|---|
date | Mon, 17 Dec 2012 23:41:50 -0600 |
parents | 73060bc3f004 |
children |
comparison
equal
deleted
inserted
replaced
105:97997a544ac0 | 106:acdbb30fee7e |
---|---|
33 ubyte R; | 33 ubyte R; |
34 ubyte A; | 34 ubyte A; |
35 } | 35 } |
36 } | 36 } |
37 class Color2 { | 37 class Color2 { |
38 Pixel32 ToPixel32() { | 38 Pixel32 toPixel32() { |
39 Pixel32 px; | 39 Pixel32 px; |
40 return px; | 40 return px; |
41 } | 41 } |
42 string ToSetting() { | 42 string toSetting() { |
43 auto px = ToPixel32(); | 43 auto px = toPixel32(); |
44 return format("{}, {}, {}", px.R, px.G, px.B); | 44 return format("{}, {}, {}", px.R, px.G, px.B); |
45 } | 45 } |
46 static Color2 FromSetting(string str) { | 46 static Color2 fromSetting(cstring str) { |
47 // allow "#AB00F2", "171, 0, 242" | 47 // allow "#AB00F2", "171, 0, 242" |
48 return null; | 48 return null; |
49 } | 49 } |
50 } | 50 } |
51 | 51 |
62 "; | 62 "; |
63 unittest { | 63 unittest { |
64 // test saving to the file | 64 // test saving to the file |
65 auto settings = new Settings; | 65 auto settings = new Settings; |
66 settings.loadFromString(test); | 66 settings.loadFromString(test); |
67 test = settings.saveToString(); | 67 test = settings.saveToString().idup; |
68 | 68 |
69 // test reading from the file | 69 // test reading from the file |
70 settings = new Settings; | 70 settings = new Settings; |
71 settings.loadFromString(test); | 71 settings.loadFromString(test); |
72 assert(settings.get("UndoLevels") == "500"); | 72 assert(settings.get("UndoLevels") == "500"); |
98 void loadFromStream(InputStream stream) { | 98 void loadFromStream(InputStream stream) { |
99 auto input = new TextInput(stream); | 99 auto input = new TextInput(stream); |
100 string section = MainSectionName; | 100 string section = MainSectionName; |
101 bool inStartComment = true; | 101 bool inStartComment = true; |
102 int lineNum = 0; | 102 int lineNum = 0; |
103 foreach(string line; input) { | 103 foreach(line; input) { |
104 lineNum++; | 104 lineNum++; |
105 // check for a line with just whitespace | 105 // check for a line with just whitespace |
106 if(line.trim().length == 0) | 106 if(line.trim().length == 0) |
107 continue; | 107 continue; |
108 | 108 |
109 // check for a comment | 109 // check for a comment |
110 if(line.trimLeft().startsWith(";") || | 110 if(line.trimLeft().startsWith(";") || |
111 line.trimLeft().startsWith("#")) { | 111 line.trimLeft().startsWith("#")) { |
112 if(inStartComment) { | 112 if(inStartComment) { |
113 comment.length = comment.length + 1; | 113 comment.length = comment.length + 1; |
114 comment[$-1] = line.trimLeft()[1..$].dup; | 114 comment[$-1] = line.trimLeft()[1..$].idup; |
115 } | 115 } |
116 continue; | 116 continue; |
117 } | 117 } |
118 inStartComment = false; | 118 inStartComment = false; |
119 | 119 |
120 // check for a section header | 120 // check for a section header |
121 if(line.startsWith("[")) { | 121 if(line.startsWith("[")) { |
122 if(!line.endsWith("]") || line.length < 3) | 122 if(!line.endsWith("]") || line.length < 3) |
123 throw new Exception("Invalid section on line " ~ to!(string)(lineNum)); | 123 throw new Exception("Invalid section on line " ~ to!(string)(lineNum)); |
124 section = line[1..$-1].dup; | 124 section = line[1..$-1].idup; |
125 continue; | 125 continue; |
126 } | 126 } |
127 | 127 |
128 // parse key=value line (quickly) | 128 // parse key=value line (quickly) |
129 int eqIndex; | 129 int eqIndex; |
130 for(eqIndex = 0; eqIndex < line.length; ++eqIndex) | 130 for(eqIndex = 0; eqIndex < line.length; ++eqIndex) |
131 if(line[eqIndex] == '=') | 131 if(line[eqIndex] == '=') |
132 break; | 132 break; |
133 if(eqIndex == line.length) | 133 if(eqIndex == line.length) |
134 throw new Exception("Invalid format on line " ~ to!(string)(lineNum)); | 134 throw new Exception("Invalid format on line " ~ to!(string)(lineNum)); |
135 string value = line[eqIndex+1..$].unescape(); | 135 string value = cast(immutable)(line[eqIndex+1..$].unescape()); |
136 sections[section][line[0..eqIndex].dup] = value; | 136 sections[section][line[0..eqIndex].idup] = value; |
137 } | 137 } |
138 } | 138 } |
139 void saveToStream(OutputStream stream) { | 139 void saveToStream(OutputStream stream) { |
140 auto output = new TextOutput(stream); | 140 auto output = new TextOutput(stream); |
141 foreach(line; comment) | 141 foreach(line; comment) |
145 foreach(key, value; sectionData) | 145 foreach(key, value; sectionData) |
146 output(key)('=')(value).newline; // TODO: escape? | 146 output(key)('=')(value).newline; // TODO: escape? |
147 } | 147 } |
148 } | 148 } |
149 public: | 149 public: |
150 const string MainSectionName = "Main"; | 150 enum string MainSectionName = "Main"; |
151 /** | 151 /** |
152 * Parses the specified file. | 152 * Parses the specified file. |
153 */ | 153 */ |
154 void load(string file) { | 154 void load(cstring file) { |
155 scope f = new File(file); | 155 scope f = new File(file); |
156 loadFromStream(f); | 156 loadFromStream(f); |
157 } | 157 } |
158 void loadFromString(string str) { | 158 void loadFromString(cstring str) { |
159 scope a = new Array(str); | 159 auto a = new Array(cast(void[])str); |
160 loadFromStream(a); | 160 loadFromStream(a); |
161 } | 161 } |
162 string saveToString() { | 162 mstring saveToString() { |
163 scope a = new Array(256, 80); | 163 scope a = new Array(256, 80); |
164 saveToStream(a); | 164 saveToStream(a); |
165 return cast(string)a.slice(a.readable); | 165 return cast(mstring)a.slice(a.readable); |
166 } | 166 } |
167 /** | 167 /** |
168 * | 168 * |
169 * Examples: | 169 * Examples: |
170 * ----- | 170 * ----- |
171 * settings.get("UndoLevels"); | 171 * settings.get("UndoLevels"); |
172 * settings.get("TabSize", "RubyMode"); | 172 * settings.get("TabSize", "RubyMode"); |
173 * ----- | 173 * ----- |
174 */ | 174 */ |
175 string get(string name, string section = MainSectionName) { | 175 string get(cstring name, cstring section = MainSectionName) { |
176 auto sect = section in sections; | 176 auto sect = section in sections; |
177 if(sect) { | 177 if(sect) { |
178 auto val = name in *sect; | 178 auto val = name in *sect; |
179 if(val) | 179 if(val) |
180 return *val; | 180 return *val; |
224 static if(is(T == bool)) | 224 static if(is(T == bool)) |
225 return str == "true" || str == "yes" || str == "on"; | 225 return str == "true" || str == "yes" || str == "on"; |
226 else static if(is(T : long)) | 226 else static if(is(T : long)) |
227 return cast(T)to!(T)(str); | 227 return cast(T)to!(T)(str); |
228 else | 228 else |
229 return T.FromSetting(str); | 229 return T.fromSetting(str); |
230 } | 230 } |
231 | 231 |
232 /** | 232 /** |
233 * Examples: | 233 * Examples: |
234 * ----- | 234 * ----- |
236 * setSetting!(int)(settings, "TabSize", 4, "RubyMode"); | 236 * setSetting!(int)(settings, "TabSize", 4, "RubyMode"); |
237 * ----- | 237 * ----- |
238 */ | 238 */ |
239 void setSetting(T)(Settings settings, | 239 void setSetting(T)(Settings settings, |
240 string name, T value, string section = Settings.MainSectionName) { | 240 string name, T value, string section = Settings.MainSectionName) { |
241 string str; | 241 mstring str; |
242 static if(is(T == bool)) | 242 static if(is(T == bool)) |
243 str = value ? "true" : "false"; | 243 str = value ? "true" : "false"; |
244 else static if(is(T : long)) | 244 else static if(is(T : long)) |
245 str = to!(string)(value); | 245 str = to!(mstring)(value); |
246 else | 246 else |
247 str = T.ToSetting(); | 247 str = T.toSetting(); |
248 | 248 |
249 settings.Set(name, str, section); | 249 settings.set(name, str, section); |
250 } | 250 } |
251 | 251 |