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