Skip to content

Commit e4dad36

Browse files
Put the file back to the position it was in before creating classes
1 parent 411ac4a commit e4dad36

File tree

2 files changed

+60
-6
lines changed

2 files changed

+60
-6
lines changed

Framework/Nexus/inc/MantidNexus/NexusClasses.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,9 @@ class MANTID_NEXUS_DLL NXObject {
110110
std::shared_ptr<::NeXus::File> m_fileID;
111111

112112
protected:
113-
std::string m_path; ///< Keeps the absolute path to the object
114-
bool m_open; ///< Set to true if the object has been open
113+
std::string m_path; ///< Keeps the absolute path to the object
114+
std::string m_path_parent; ///< Absolute path of the parent this object should reset to
115+
bool m_open; ///< Set to true if the object has been open
115116
private:
116117
NXObject(); ///< Private default constructor
117118
void getAttributes();
@@ -462,7 +463,7 @@ class MANTID_NEXUS_DLL NXClass : public NXObject {
462463
* @param name :: The name of the NXClass relative to its parent
463464
*/
464465
NXClass(NXClass const &parent, std::string const &name);
465-
virtual ~NXClass();
466+
virtual ~NXClass() override;
466467
/// The NX class identifier
467468
std::string NX_class() const override { return "NXClass"; }
468469

Framework/Nexus/src/NexusClasses.cpp

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ NXObject::NXObject(::NeXus::File *fileID, NXClass const *parent, const std::stri
9797
NXObject::NXObject(std::shared_ptr<::NeXus::File> fileID, NXClass const *parent, const std::string &name)
9898
: m_fileID(fileID), m_open(false) {
9999
if (parent && !name.empty()) {
100+
m_path_parent = parent->path();
100101
m_path = parent->path() + "/" + name;
101102
}
102103
}
@@ -147,8 +148,8 @@ void NXObject::getAttributes() {
147148
NXClass::NXClass(const NXClass &parent, const std::string &name) : NXObject(parent.m_fileID, &parent, name) { clear(); }
148149

149150
NXClass::~NXClass() {
150-
if (m_open)
151-
m_fileID->closeGroup();
151+
if (m_open && (!m_path_parent.empty()))
152+
m_fileID->openPath(m_path_parent);
152153
}
153154

154155
void NXClass::readAllInfo() {
@@ -218,9 +219,57 @@ void NXClass::clear() {
218219
m_datasets.reset(new std::vector<NXInfo>);
219220
}
220221

222+
namespace {
223+
/**
224+
* This assumes that the last "element" of the current path can overlap with the first "element" of the requested path
225+
* and removes duplication.
226+
*/
227+
std::pair<std::string, std::string> splitPath(const std::string &current, const std::string &requested) {
228+
// return early if it is already split
229+
if (requested.find("/") == std::string::npos)
230+
return std::pair<std::string, std::string>{current, requested};
231+
232+
// decompose the two components to see if the inner element overlaps
233+
const auto currentLastPos = current.rfind("/");
234+
const auto currentLast = (currentLastPos == std::string::npos) ? std::string("") : current.substr(currentLastPos + 1);
235+
236+
const auto requestedFirstPos = requested.find("/");
237+
const auto requestedFirst =
238+
(requestedFirstPos == std::string::npos) ? std::string("") : requested.substr(0, requestedFirstPos);
239+
240+
// construct the effective path
241+
std::string fullPath;
242+
if (currentLast == requestedFirst) {
243+
fullPath = current + requested.substr(requestedFirstPos);
244+
} else {
245+
fullPath = current + "/" + requested;
246+
}
247+
248+
// last / is the division between path and data
249+
const auto last = fullPath.rfind("/");
250+
return std::pair<std::string, std::string>{fullPath.substr(0, last), fullPath.substr(last + 1)};
251+
}
252+
} // namespace
253+
221254
std::string NXClass::getString(const std::string &name) const {
255+
const std::string oldPath = m_fileID->getPath();
256+
// split the input into group and name
257+
auto pathParts = splitPath(oldPath, name);
258+
222259
std::string value;
223-
m_fileID->readData(name, value);
260+
261+
// open the containing group
262+
m_fileID->openPath(pathParts.first);
263+
264+
// read the value
265+
try {
266+
m_fileID->readData(name, value);
267+
} catch (const ::NeXus::Exception &) {
268+
m_fileID->openPath(oldPath); // go back to original location
269+
throw; // rethrow the exception
270+
}
271+
m_fileID->openPath(oldPath); // go back to original location
272+
224273
return value;
225274
}
226275

@@ -346,12 +395,16 @@ void NXDataSet::open() {
346395
size_t i = m_path.find_last_of('/');
347396
if (i == std::string::npos || i == 0)
348397
return; // we are in the root group, assume it is open
398+
std::string path_before = m_fileID->getPath();
349399
std::string group_path = m_path.substr(0, i);
350400
m_fileID->openPath(group_path);
351401
m_fileID->openData(name());
352402
m_info = NXInfo(m_fileID->getInfo(), name());
353403
getAttributes();
404+
// go back to where the file was before
354405
m_fileID->closeData();
406+
if (!path_before.empty())
407+
m_fileID->openPath(path_before);
355408
}
356409

357410
void NXDataSet::openLocal() {

0 commit comments

Comments
 (0)