void IniConfig::Read(const FileSystem::FileData &data) { StringRange buffer = data.AsStringRange(); buffer = buffer.StripUTF8BOM(); while (!buffer.Empty()) { StringRange line = buffer.ReadLine().StripSpace(); // if the line is a comment, skip it if (line.Empty() || (line[0] == '#')) continue; const char *kend = line.FindChar('='); // if there's no '=' sign, skip the line if (kend == line.end) { fprintf(stderr, "WARNING: ignoring invalid line in config file:\n '%.*s'\n", int(line.Size()), line.begin); continue; } StringRange key(line.begin, kend); StringRange value(kend + 1, line.end); // strip whitespace key.end = key.RFindNonSpace(); value = value.StripSpace(); m_map[key.ToString()] = value.ToString(); } }
static void normalise_path(std::string &result, const StringRange &path) { StringRange part(path.begin, path.end); if (!path.Empty() && (path[0] == '/')) { result += '/'; ++part.begin; } const size_t initial_result_length = result.size(); while (true) { part.end = part.FindChar('/'); // returns part.end if the char is not found if (part.Empty() || (part == ".")) { // skip this part } else if (part == "..") { // pop the last component if (result.size() <= initial_result_length) throw std::invalid_argument(path.ToString()); size_t pos = result.rfind('/'); if (pos == std::string::npos) { pos = 0; } assert(pos >= initial_result_length); result.erase(pos); } else { // push the new component if (result.size() > initial_result_length) result += '/'; result.append(part.begin, part.Size()); } if (part.end == path.end) { break; } assert(*part.end == '/'); part.begin = part.end + 1; part.end = path.end; } }
void IniConfig::Read(const FileSystem::FileData &data) { StringRange buffer = data.AsStringRange(); buffer = buffer.StripUTF8BOM(); std::string section_name; MapType *section_map = 0; while (!buffer.Empty()) { StringRange line = buffer.ReadLine().StripSpace(); // if the line is a comment, skip it if (line.Empty() || (line[0] == '#')) continue; // check for a section header if ((line.Size() >= 2) && (line[0] == '[') && (line.end[-1] == ']')) { ++line.begin; --line.end; section_name = line.ToString(); section_map = 0; continue; } const char *kend = line.FindChar('='); // if there's no '=' sign, skip the line if (kend == line.end) { Output("WARNING: ignoring invalid line in config file:\n '%.*s'\n", int(line.Size()), line.begin); continue; } StringRange key(line.begin, kend); StringRange value(kend + 1, line.end); // strip whitespace key.end = key.RFindNonSpace(); value = value.StripSpace(); if (!section_map) section_map = &m_map[section_name]; (*section_map)[key.ToString()] = value.ToString(); } }
float IniConfig::Float(const std::string §ion, const std::string &key, float defval) const { SectionMapType::const_iterator secIt = m_map.find(section); if (secIt == m_map.end()) return defval; MapType::const_iterator it = secIt->second.find(key); if (it == secIt->second.end()) return defval; const StringRange val = StringRange(it->second.c_str(), it->second.size()).StripSpace(); if (val.Empty()) return defval; char *end = 0; float x = strtod(val.begin, &end); if (end != val.end) return defval; return x; }