virtual bool load(const char *filename) { string data; if(data.readfile(filename) == true) { data.replace("\r", ""); lstring line; line.split("\n", data); for(unsigned i = 0; i < line.size(); i++) { if(auto position = qstrpos(line[i], "#")) line[i][position()] = 0; if(!qstrpos(line[i], " = ")) continue; lstring part; part.qsplit(" = ", line[i]); part[0].trim(); part[1].trim(); for(unsigned n = 0; n < list.size(); n++) { if(part[0] == list[n].name) { list[n].set(part[1]); break; } } } return true; } else { return false; } }
void attach(T &data, const char *name, const char *desc = "") { unsigned n = list.size(); list[n].data = (uintptr_t)&data; list[n].name = name; list[n].desc = desc; if(configuration_traits::is_boolean<T>::value) list[n].type = boolean_t; else if(configuration_traits::is_signed<T>::value) list[n].type = signed_t; else if(configuration_traits::is_unsigned<T>::value) list[n].type = unsigned_t; else if(configuration_traits::is_double<T>::value) list[n].type = double_t; else if(configuration_traits::is_string<T>::value) list[n].type = string_t; else list[n].type = unknown_t; }
virtual bool save(const char *filename) const { file fp; if(fp.open(filename, file::mode::write)) { for(unsigned i = 0; i < list.size(); i++) { string output; output << list[i].name << " = " << list[i].get(); if(list[i].desc != "") output << " # " << list[i].desc; output << "\r\n"; fp.print(output); } fp.close(); return true; } else { return false; } }
inline bool xml_element::parse_body(const char *&data) { while(true) { if(!*data) return false; if(*data++ != '<') continue; if(*data == '/') return false; if(strbegin(data, "!DOCTYPE") == true) { parse_doctype(data); return true; } if(strbegin(data, "!--")) { if(optional<unsigned> offset = strpos(data, "-->")) { data += offset() + 3; continue; } else { throw "..."; } } if(strbegin(data, "![CDATA[")) { if(optional<unsigned> offset = strpos(data, "]]>")) { data += offset() + 3; continue; } else { throw "..."; } } optional<unsigned> offset = strpos(data, ">"); if(!offset) throw "..."; string tag = substr(data, 0, offset()); data += offset() + 1; const char *content_begin = data; bool self_terminating = false; if(strend(tag, "?") == true) { self_terminating = true; tag.rtrim_once("?"); } else if(strend(tag, "/") == true) { self_terminating = true; tag.rtrim_once("/"); } parse_head(tag); if(self_terminating) return true; while(*data) { unsigned index = element.size(); xml_element node; if(node.parse_body(data) == false) { if(*data == '/') { signed length = data - content_begin - 1; if(length > 0) content = substr(content_begin, 0, length); data++; optional<unsigned> offset = strpos(data, ">"); if(!offset) throw "..."; tag = substr(data, 0, offset()); data += offset() + 1; tag.replace("\t", " "); tag.replace("\r", " "); tag.replace("\n", " "); while(strpos(tag, " ")) tag.replace(" ", " "); tag.rtrim(); if(name != tag) throw "..."; return true; } } else { element.append(node); } } } }