25 #ifndef INCLUDED_PathParseAndRetrieve_h_GUID_C451663C_0711_4B85_2011_61D26E5C237C
26 #define INCLUDED_PathParseAndRetrieve_h_GUID_C451663C_0711_4B85_2011_61D26E5C237C
34 #include <boost/assert.hpp>
35 #include <boost/algorithm/string/find_iterator.hpp>
36 #include <boost/algorithm/string/finder.hpp>
37 #include <boost/range/adaptor/sliced.hpp>
46 template <
typename Node>
47 Node *operator()(Node *node, std::string
const &component)
const {
48 return &(node->getOrCreateChildByName(component));
53 template <
typename Node>
54 Node
const *operator()(Node
const *node,
55 std::string
const &component)
const {
56 return &(node->getChildByName(component));
59 enum ParentPolicy { GETPARENT_PERMIT, GETPARENT_DENY };
60 enum AbsolutePolicy { ABSOLUTEPATH_PERMIT, ABSOLUTEPATH_DENY };
62 template <
typename GetChildFunctor,
typename Node>
63 inline Node &treePathRetrieveImplementation(
64 GetChildFunctor f, Node &node, std::string path,
65 ParentPolicy permitParent = GETPARENT_DENY,
66 AbsolutePolicy permitAbsolute = ABSOLUTEPATH_PERMIT) {
74 if (path.at(0) == getPathSeparatorCharacter()) {
75 if (ABSOLUTEPATH_PERMIT != permitAbsolute) {
76 throw exceptions::ForbiddenAbsolutePath();
79 while (!ret->isRoot()) {
80 ret = ret->getParent();
87 path.erase(begin(path));
91 if (path.back() == getPathSeparatorCharacter()) {
99 auto begin = boost::algorithm::make_split_iterator(
104 auto end = decltype(begin)();
108 std::string component;
112 for (
auto rangeIt : boost::make_iterator_range(begin, end)) {
114 component = boost::copy_range<std::string>(rangeIt);
117 if (component.empty()) {
119 throw exceptions::EmptyPathComponent(path);
120 }
else if (component ==
".") {
124 }
else if (component ==
"..") {
127 if (GETPARENT_PERMIT != permitParent) {
128 throw exceptions::ForbiddenParentPath();
131 throw exceptions::ImpossibleParentPath();
133 ret = ret->getParent();
136 ret = f(ret, component);
164 template <
typename ValueType>
165 inline util::TreeNode<ValueType> &
167 bool permitParent =
false) {
168 return detail::treePathRetrieveImplementation(
170 permitParent ? detail::GETPARENT_PERMIT : detail::GETPARENT_DENY);
177 template <
typename ValueType>
178 inline util::TreeNode<ValueType>
const &
180 bool permitParent =
false) {
181 return detail::treePathRetrieveImplementation(
183 permitParent ? detail::GETPARENT_PERMIT : detail::GETPARENT_DENY);
199 template <
typename ValueType>
200 inline util::TreeNode<ValueType> &
202 std::string
const &path) {
203 BOOST_ASSERT_MSG(root.isRoot(),
"Must pass the root node!");
210 if (path.at(0) != getPathSeparatorCharacter()) {
218 template <
typename ValueType>
219 inline util::TreeNode<ValueType>
const &
221 std::string
const &path) {
222 BOOST_ASSERT_MSG(root.isRoot(),
"Must pass the root node!");
229 if (path.at(0) != getPathSeparatorCharacter()) {
238 #endif // INCLUDED_PathParseAndRetrieve_h_GUID_C451663C_0711_4B85_2011_61D26E5C237C
util::TreeNode< ValueType > & treePathRetrieve(util::TreeNode< ValueType > &node, std::string path, bool permitParent=false)
Internal method for parsing a path and getting or creating the nodes along it.
Thrown when attempting to use a path with no leading slash where an absolute path is required...
Thrown when attempting to use an empty path.
util::TreeNode< ValueType > & pathParseAndRetrieve(util::TreeNode< ValueType > &root, std::string const &path)
Internal method for parsing a path and getting or creating the nodes along it.
const char * getPathSeparator()
Gets the path separator - a slash - as a null-terminated string.