Skip to content

Commit 5ac032a

Browse files
committed
[net] Rework open mode parsing in TNetXNGFile
The parsing of the opening mode string option to create the corresponding XRootD opening mode flag assumes the string option is a single word. Given that the input open mode string may not contain just one word, e.g. because of the internal extra option `_WITHOUT_GLOBALREGISTRATION`, rework the parsing logic by * Tokenizing the input open mode string. * Returning early in case a token corresponds to one of the accepted words. * In all other cases, return success (0) or failure (-1) depending on whether the `assumeRead` parameter is true or false.
1 parent da5fba1 commit 5ac032a

1 file changed

Lines changed: 23 additions & 9 deletions

File tree

net/netxng/src/TNetXNGFile.cxx

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
#include <XrdVersion.hh>
3434
#include <iostream>
3535

36+
#include <ROOT/StringUtils.hxx>
37+
3638
namespace {
3739

3840
Int_t ParseOpenMode(Option_t *in, TString &modestr, int &mode, Bool_t assumeRead);
@@ -177,7 +179,7 @@ TNetXNGFile::TNetXNGFile(const char *url, const char *lurl, Option_t *mode, cons
177179
fReadvIorMax = 2097136;
178180
fReadvIovMax = 1024;
179181

180-
if (ParseOpenMode(mode, fOption, fMode, kTRUE)<0) {
182+
if (ParseOpenMode(mode, fOption, fMode, kTRUE) < 0) {
181183
Error("Open", "could not parse open mode %s", mode);
182184
MakeZombie();
183185
return;
@@ -708,19 +710,31 @@ Int_t ParseOpenMode(Option_t *in, TString &modestr, int &mode, Bool_t assumeRead
708710
using namespace XrdCl;
709711
modestr = ToUpper(TString(in));
710712

711-
if (modestr == "NEW" || modestr == "CREATE") mode = OpenFlags::New;
712-
else if (modestr == "RECREATE") mode = OpenFlags::Delete;
713-
else if (modestr == "UPDATE") mode = OpenFlags::Update;
714-
else if (modestr == "READ") mode = OpenFlags::Read;
715-
else {
716-
if (!assumeRead) {
717-
return -1;
713+
const static std::unordered_map<std::string, OpenFlags::Flags> strToFlagMap{{"CREATE", OpenFlags::New},
714+
{"NEW", OpenFlags::New},
715+
{"READ", OpenFlags::Read},
716+
{"RECREATE", OpenFlags::Delete},
717+
{"UPDATE", OpenFlags::Update}};
718+
719+
const auto tokens = ROOT::Split(modestr, "_ ", /*skipEmpty*/ true);
720+
for (const auto &token : tokens) {
721+
if (auto it = strToFlagMap.find(token); it != strToFlagMap.end()) {
722+
// Though unnecessary, we substitute the current value of modestr with the specific valid value just found.
723+
// This is done for backwards compatibility: some other code in TFile may rely on the open mode to be exactly
724+
// one of the valid values.
725+
modestr = token;
726+
mode = it->second;
727+
return 0;
718728
}
729+
}
730+
731+
if (assumeRead) {
719732
modestr = "READ";
720733
mode = OpenFlags::Read;
734+
return 0;
721735
}
722736

723-
return 0;
737+
return -1;
724738
}
725739

726740
} // namespace

0 commit comments

Comments
 (0)