diff options
author | elfmz <fenix1905@tut.by> | 2022-09-06 23:53:52 +0300 |
---|---|---|
committer | elfmz <fenix1905@tut.by> | 2022-09-07 00:41:19 +0300 |
commit | 6203953dd76218dcdd9fdf39dcfcc17397d733c5 (patch) | |
tree | f944be06b46cfb0bb27ff2a2c7fa3f90a136d0cd /utils | |
parent | 398b4dc626aa9f00c02941afae2e588e50871b19 (diff) |
multiarc - yet more refactoring and optimizations
Diffstat (limited to 'utils')
-rw-r--r-- | utils/CMakeLists.txt | 1 | ||||
-rw-r--r-- | utils/include/PathParts.h | 51 | ||||
-rw-r--r-- | utils/include/utils.h | 11 | ||||
-rw-r--r-- | utils/src/PathParts.cpp | 51 |
4 files changed, 114 insertions, 0 deletions
diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index 984efab8..44333da9 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -29,6 +29,7 @@ set(SOURCES src/FSNotify.cpp src/TestPath.cpp src/PipeIPC.cpp + src/PathParts.cpp ) add_library (utils ${SOURCES}) diff --git a/utils/include/PathParts.h b/utils/include/PathParts.h new file mode 100644 index 00000000..f5aeae5d --- /dev/null +++ b/utils/include/PathParts.h @@ -0,0 +1,51 @@ +#pragma once +#include <vector> +#include <string> +#include <map> + +struct PathParts : std::vector<std::string> +{ + void Traverse(const std::string &path); + + std::string Join() const; + bool Starts(PathParts &root) const; +}; + +/// + +template <class PathNodeAttributesT> struct PathNode; + +template <class PathNodeAttributesT> + struct PathNode : PathNodeAttributesT, std::map<std::string, PathNode<PathNodeAttributesT> > +{ + PathNode<PathNodeAttributesT> *Find(PathParts::const_iterator root, PathParts::const_iterator edge) + { + if (root == edge) + return this; + + auto it = std::map<std::string, PathNode<PathNodeAttributesT> >::find(*root); + if (it == std::map<std::string, PathNode<PathNodeAttributesT> >::end()) + return nullptr; + + ++root; + return it->second.Find(root, edge); + } + + PathNode<PathNodeAttributesT> *Ensure(PathParts::const_iterator root, PathParts::const_iterator edge) + { + if (root == edge) + return this; + + auto &subnode = std::map<std::string, PathNode<PathNodeAttributesT> >::operator[](*root); + + ++root; + return subnode.Ensure(root, edge); + } + + void Clear() + { + std::map<std::string, PathNode<PathNodeAttributesT> >::clear(); + PathNodeAttributesT::operator =(PathNodeAttributesT()); + } +}; + diff --git a/utils/include/utils.h b/utils/include/utils.h index edd1c68e..5e305730 100644 --- a/utils/include/utils.h +++ b/utils/include/utils.h @@ -317,4 +317,15 @@ template <class STRING_T, typename ARRAY_T> return s.size() == l && s.compare(0, std::string::npos, a, l) == 0; } +template <typename ARRAY_T, class CHAR_T> + void ArrayCpyZ(ARRAY_T &dst, const CHAR_T *src) +{ + static_assert ( sizeof(dst) != sizeof(void *), "ArrayCpyZ should be used with arrays but not pointers"); + size_t i; + for (i = 0; src[i] && i + 1 < ARRAYSIZE(dst); ++i) { + dst[i] = src[i]; + } + dst[i] = 0; +} + #define DBGLINE fprintf(stderr, "%d %d @%s\n", getpid(), __LINE__, __FILE__) diff --git a/utils/src/PathParts.cpp b/utils/src/PathParts.cpp new file mode 100644 index 00000000..94b834ee --- /dev/null +++ b/utils/src/PathParts.cpp @@ -0,0 +1,51 @@ +#include "PathParts.h" +#include "utils.h" + +void PathParts::Traverse(const std::string &path) +{ + size_t i = size(); + StrExplode(*this, path, "/"); + while (i < size()) { + if (operator[](i) == ".") { + erase(begin() + i); + + } else if (operator[](i) == "..") { + erase(begin() + i); + if (i != 0) { + erase(begin() + i - 1); + --i; + } else { + fprintf(stderr, "PathParts::Traverse: impossible <..> in '%s'\n", path.c_str()); + } + } else { + ++i; + } + } +} + +bool PathParts::Starts(PathParts &root) const +{ + if (size() < root.size()) { + return false; + } + + for (size_t i = 0; i != root.size(); ++i) { + if (operator[](i) != root[i]) { + return false; + } + } + + return true; +} + +std::string PathParts::Join() const +{ + std::string out; + for (const auto &p : *this) { + if (!out.empty()) { + out+= '/'; + } + out+= p; + } + return out; +} |