Mantid
Loading...
Searching...
No Matches
NexusAddress.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2007 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7
9
10#include <filesystem>
11#include <string>
12
13namespace Mantid::Nexus {
14
15namespace {
16std::filesystem::path const nxroot("/");
17
18std::filesystem::path cleanup(std::string const &s) {
19 std::filesystem::path ret(s);
20 if (ret == nxroot) {
21 // the root path is already clean
22 } else if (s.back() == '/') {
23 // make sure no entries end in "/" -- this confuses path location
24 ret = s.substr(0, s.size() - 1);
25 }
26 if (s.starts_with("//")) {
27 ret = s.substr(1);
28 }
29 // cast as lexically normal
30 return ret.lexically_normal();
31}
32
33std::filesystem::path cleanup(std::filesystem::path const &p) { return cleanup(p.string()); }
34
35} // namespace
36
37NexusAddress::NexusAddress(std::filesystem::path const &path)
38 : m_path(cleanup(path)), m_resolved_path(m_path.generic_string()) {}
39
40NexusAddress::NexusAddress(std::string const &path) : m_path(cleanup(path)), m_resolved_path(m_path.generic_string()) {}
41
42NexusAddress::NexusAddress(char const *const path) : NexusAddress(std::string(path)) {}
43
44NexusAddress::NexusAddress() : m_path(nxroot), m_resolved_path(m_path.generic_string()) {}
45
46NexusAddress &NexusAddress::operator=(std::string const &s) {
47 m_path = cleanup(s);
48 m_resolved_path = std::string(m_path.generic_string());
49 return *this;
50}
51
52bool NexusAddress::operator==(NexusAddress const &p) const { return m_path == p.m_path; }
53
54bool NexusAddress::operator==(std::string const &s) const { return m_resolved_path == s; }
55
56bool NexusAddress::operator==(char const *const s) const { return m_resolved_path == std::string(s); }
57
58bool NexusAddress::operator!=(NexusAddress const &p) const { return m_path != p.m_path; }
59
60bool NexusAddress::operator!=(std::string const &s) const { return m_resolved_path != s; }
61
62bool NexusAddress::operator!=(char const *const s) const { return m_resolved_path != std::string(s); }
63
64NexusAddress NexusAddress::operator/(std::string const &s) const { return *this / NexusAddress(s); }
65
66NexusAddress NexusAddress::operator/(char const *const s) const { return *this / NexusAddress(s); }
67
69 return NexusAddress(m_path / p.m_path.relative_path());
70}
71
72NexusAddress &NexusAddress::operator/=(std::string const &s) { return *this /= NexusAddress(s); }
73
74NexusAddress &NexusAddress::operator/=(char const *const s) { return *this /= NexusAddress(s); }
75
77 m_path = cleanup(m_path / p.m_path);
78 m_resolved_path = std::string(m_path.generic_string());
79 return *this;
80}
81
82bool NexusAddress::isAbsolute() const { return *m_path.begin() == nxroot; }
83
84bool NexusAddress::isRoot() const { return (m_path == nxroot); }
85
87
89
90NexusAddress NexusAddress::stem() const { return NexusAddress(m_path.filename()); }
91
93
94std::string NexusAddress::operator+(std::string const &s) const { return m_resolved_path + s; }
95
96std::string NexusAddress::operator+(char const s[]) const { return m_resolved_path + s; }
97
98std::vector<std::string> NexusAddress::parts() const {
99 std::vector<std::string> names;
100 for (auto it = m_path.begin(); it != m_path.end(); it++) {
101 if (*it != nxroot) {
102 names.push_back(it->generic_string());
103 }
104 }
105 return names;
106}
107
108bool NexusAddress::hasChild(std::string const &child) const {
109 // if child is empty
110 if (child.empty() || m_resolved_path == child)
111 return false;
112
113 // if at root, must check specially
114 if (isRoot()) {
115 // child must be "/something" and not contain another '/'
116 if (child.size() < 2 || child[0] != '/' || child.find('/', 1) != std::string::npos)
117 return false;
118 return true;
119 }
120
121 // parent must be a prefix, followed by a single '/'
122 std::size_t const parent_size = m_resolved_path.size();
123 if (child.size() <= parent_size + 1)
124 return false;
125 if (child.compare(0, parent_size, m_resolved_path) != 0)
126 return false;
127 if (child[parent_size] != '/')
128 return false;
129
130 // there must be no further '/' after the immediate child
131 auto next_slash = child.find('/', parent_size + 1);
132 return next_slash == std::string::npos;
133}
134
135} // namespace Mantid::Nexus
136
137bool operator==(std::string const &s, Mantid::Nexus::NexusAddress const &p) { return s == p.string(); }
138
139bool operator!=(std::string const &s, Mantid::Nexus::NexusAddress const &p) { return s != p.string(); }
140
141std::string operator+(std::string const &s, Mantid::Nexus::NexusAddress const &p) { return s + p.string(); }
142
143std::string operator+(char const s[], Mantid::Nexus::NexusAddress const &p) { return s + p.string(); }
144
145std::ostream &operator<<(std::ostream &os, Mantid::Nexus::NexusAddress const &p) {
146 os << p.string();
147 return os;
148}
This simple class encapsulates some methods for working with paths inside a Nexus file.
std::string operator+(std::string const &s) const
bool operator==(NexusAddress const &p) const
std::vector< std::string > parts() const
std::filesystem::path m_path
standard filesystem path
bool hasChild(std::string const &p) const
NexusAddress & operator/=(std::string const &s)
NexusAddress parent_path() const
NexusAddress & operator=(NexusAddress const &nd)=default
NexusAddress operator/(std::string const &s) const
static NexusAddress root()
NexusAddress fromRoot() const
NexusAddress stem() const
bool operator!=(NexusAddress const &p) const
std::string const & string() const
MANTID_API_DLL std::ostream & operator<<(std::ostream &, const AlgorithmHistory &)
Prints a text representation.
MatrixWorkspace_sptr MANTID_API_DLL operator+(const MatrixWorkspace_sptr &lhs, const MatrixWorkspace_sptr &rhs)
Adds two workspaces.
Header for a base Nexus::Exception.
STL namespace.
constexpr bool operator==(const wide_integer< Bits, Signed > &lhs, const wide_integer< Bits2, Signed2 > &rhs)
constexpr bool operator!=(const wide_integer< Bits, Signed > &lhs, const wide_integer< Bits2, Signed2 > &rhs)