@@ -97,6 +97,7 @@ NXObject::NXObject(::NeXus::File *fileID, NXClass const *parent, const std::stri
97
97
NXObject::NXObject (std::shared_ptr<::NeXus::File> fileID, NXClass const *parent, const std::string &name)
98
98
: m_fileID(fileID), m_open(false ) {
99
99
if (parent && !name.empty ()) {
100
+ m_path_parent = parent->path ();
100
101
m_path = parent->path () + " /" + name;
101
102
}
102
103
}
@@ -147,8 +148,8 @@ void NXObject::getAttributes() {
147
148
NXClass::NXClass (const NXClass &parent, const std::string &name) : NXObject(parent.m_fileID, &parent, name) { clear (); }
148
149
149
150
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 );
152
153
}
153
154
154
155
void NXClass::readAllInfo () {
@@ -218,9 +219,57 @@ void NXClass::clear() {
218
219
m_datasets.reset (new std::vector<NXInfo>);
219
220
}
220
221
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 ¤t, 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
+
221
254
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
+
222
259
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
+
224
273
return value;
225
274
}
226
275
@@ -346,12 +395,16 @@ void NXDataSet::open() {
346
395
size_t i = m_path.find_last_of (' /' );
347
396
if (i == std::string::npos || i == 0 )
348
397
return ; // we are in the root group, assume it is open
398
+ std::string path_before = m_fileID->getPath ();
349
399
std::string group_path = m_path.substr (0 , i);
350
400
m_fileID->openPath (group_path);
351
401
m_fileID->openData (name ());
352
402
m_info = NXInfo (m_fileID->getInfo (), name ());
353
403
getAttributes ();
404
+ // go back to where the file was before
354
405
m_fileID->closeData ();
406
+ if (!path_before.empty ())
407
+ m_fileID->openPath (path_before);
355
408
}
356
409
357
410
void NXDataSet::openLocal () {
0 commit comments