void read_ini(std::basic_istream< typename Ptree::key_type::value_type> &stream, Ptree &pt) { typedef typename Ptree::key_type::value_type Ch; typedef std::basic_string<Ch> Str; const Ch semicolon = stream.widen(';'); const Ch hash = stream.widen('#'); const Ch lbracket = stream.widen('['); const Ch rbracket = stream.widen(']'); Ptree local; unsigned long line_no = 0; Ptree *section = 0; Str line; // For all lines while (stream.good()) { // Get line from stream ++line_no; std::getline(stream, line); if (!stream.good() && !stream.eof()) BOOST_PROPERTY_TREE_THROW(ini_parser_error( "read error", "", line_no)); // If line is non-empty line = property_tree::detail::trim(line, stream.getloc()); if (!line.empty()) { // Comment, section or key? if (line[0] == semicolon || line[0] == hash) { // Ignore comments } else if (line[0] == lbracket) { // If the previous section was empty, drop it again. if (section && section->empty()) local.pop_back(); typename Str::size_type end = line.find(rbracket); if (end == Str::npos) BOOST_PROPERTY_TREE_THROW(ini_parser_error( "unmatched '['", "", line_no)); Str key = property_tree::detail::trim( line.substr(1, end - 1), stream.getloc()); if (local.find(key) != local.not_found()) BOOST_PROPERTY_TREE_THROW(ini_parser_error( "duplicate section name", "", line_no)); section = &local.push_back( std::make_pair(key, Ptree()))->second; } else { Ptree &container = section ? *section : local; typename Str::size_type eqpos = line.find(Ch('=')); if (eqpos == Str::npos) BOOST_PROPERTY_TREE_THROW(ini_parser_error( "'=' character not found in line", "", line_no)); if (eqpos == 0) BOOST_PROPERTY_TREE_THROW(ini_parser_error( "key expected", "", line_no)); Str key = property_tree::detail::trim( line.substr(0, eqpos), stream.getloc()); Str data = property_tree::detail::trim( line.substr(eqpos + 1, Str::npos), stream.getloc()); if (container.find(key) != container.not_found()) BOOST_PROPERTY_TREE_THROW(ini_parser_error( "duplicate key name", "", line_no)); container.push_back(std::make_pair(key, Ptree(data))); } } } // If the last section was empty, drop it again. if (section && section->empty()) local.pop_back(); // Swap local ptree with result ptree pt.swap(local); }