Skip to content

Commit 9d12c17

Browse files
committed
[main] Rearrange some code in RootObjTree
1 parent 3f2f922 commit 9d12c17

File tree

3 files changed

+48
-40
lines changed

3 files changed

+48
-40
lines changed

main/src/RootObjTree.cxx

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -114,33 +114,52 @@ ROOT::CmdLine::GetMatchingPathsInFile(std::string_view fileName, std::string_vie
114114
return source;
115115
}
116116

117-
ROOT::CmdLine::RootSource ROOT::CmdLine::ParseRootSource(std::string_view sourceRaw, std::uint32_t flags)
117+
ROOT::RResult<std::pair<std::string_view, std::string_view>>
118+
ROOT::CmdLine::SplitIntoFileNameAndPattern(std::string_view sourceRaw)
118119
{
119-
ROOT::CmdLine::RootSource source;
120-
const char *str = sourceRaw.data();
121-
122-
// Handle known URI prefixes
123-
static const char *const specialPrefixes[] = {"http", "https", "root", "gs", "s3"};
124-
for (const char *prefix : specialPrefixes) {
125-
const auto prefixLen = strlen(prefix);
126-
if (strncmp(str, prefix, prefixLen) == 0 && strncmp(str + prefixLen, "://", 3) == 0) {
127-
source.fFileName = std::string(prefix) + "://";
128-
str += prefixLen + 3;
129-
break;
120+
auto prefixIdx = sourceRaw.find("://");
121+
std::string_view::size_type separatorIdx = 0;
122+
if (prefixIdx != std::string_view::npos) {
123+
bool prefixFound = false;
124+
// Handle known URI prefixes
125+
static const char *const specialPrefixes[] = {"http", "https", "root", "gs", "s3"};
126+
auto prefix = sourceRaw.substr(0, prefixIdx);
127+
for (std::string_view knownPrefix : specialPrefixes) {
128+
if (prefix == knownPrefix) {
129+
prefixFound = true;
130+
break;
131+
}
132+
}
133+
if (!prefixFound) {
134+
return R__FAIL("unknown file protocol");
130135
}
136+
separatorIdx = sourceRaw.substr(prefixIdx + 3).find_first_of(':');
137+
if (separatorIdx != std::string_view::npos)
138+
separatorIdx += prefixIdx + 3;
139+
} else {
140+
separatorIdx = sourceRaw.find_first_of(':');
131141
}
132142

133-
auto tokens = ROOT::Split(str, ":");
134-
if (tokens.empty())
135-
return source;
143+
if (separatorIdx != std::string_view::npos) {
144+
return {{sourceRaw.substr(0, separatorIdx), sourceRaw.substr(separatorIdx + 1)}};
145+
}
146+
return {{sourceRaw, std::string_view{}}};
147+
}
136148

137-
source.fFileName += tokens[0];
138-
if (tokens.size() > 1) {
139-
source = ROOT::CmdLine::GetMatchingPathsInFile(source.fFileName, tokens[1], flags);
140-
} else {
141-
source = ROOT::CmdLine::GetMatchingPathsInFile(source.fFileName, "", flags);
149+
ROOT::CmdLine::RootSource ROOT::CmdLine::ParseRootSource(std::string_view sourceRaw, std::uint32_t flags)
150+
{
151+
ROOT::CmdLine::RootSource source;
152+
153+
auto res = SplitIntoFileNameAndPattern(sourceRaw);
154+
if (!res) {
155+
source.fErrors.push_back(res.GetError()->GetReport());
156+
return source;
142157
}
143158

159+
auto [fileName, tokens] = res.Unwrap();
160+
source = ROOT::CmdLine::GetMatchingPathsInFile(fileName, tokens, flags);
161+
162+
assert(source.fErrors.empty() == !!source.fObjectTree.fFile);
144163
return source;
145164
}
146165

main/src/RootObjTree.hxx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,15 @@
1212
#define ROOT_CMDLINE_OBJTREE
1313

1414
#include <cstdint>
15+
#include <iostream>
1516
#include <memory>
1617
#include <string>
1718
#include <vector>
1819

1920
#include <TKey.h>
2021

22+
#include <ROOT/RError.hxx>
23+
2124
class TDirectory;
2225
class TFile;
2326

@@ -50,7 +53,9 @@ inline RootObjNode NodeFromKey(TKey &key)
5053
struct RootObjTree {
5154
// 0th node is the root node
5255
std::vector<RootObjNode> fNodes;
56+
// All nodes in fNodes that are dirs
5357
std::vector<NodeIdx_t> fDirList;
58+
// All nodes in fNodes that are leaves (non-TDirectories)
5459
std::vector<NodeIdx_t> fLeafList;
5560
// The file must be kept alive in order to access the nodes' keys
5661
std::unique_ptr<TFile> fFile;
@@ -85,6 +90,10 @@ enum EGetMatchingPathsFlags {
8590
/// \param flags A bitmask of EGetMatchingPathsFlags
8691
RootSource GetMatchingPathsInFile(std::string_view fileName, std::string_view pattern, std::uint32_t flags);
8792

93+
/// Given a string like "root://file.root:a/b/c", splits it into { "root://file.root", "a/b/c" }.
94+
/// \return An error if the file prefix is unknown (e.g. "foo://file.root"), otherwise the result described above.
95+
ROOT::RResult<std::pair<std::string_view, std::string_view>> SplitIntoFileNameAndPattern(std::string_view sourceRaw);
96+
8897
/// Given a string like "file.root:dir/obj", converts it to a RootSource.
8998
/// The string may start with one of the known file protocols: "http", "https", "root", "gs", "s3"
9099
/// (e.g. "https://file.root").

main/src/rootls.cxx

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -509,26 +509,6 @@ static void PrintChildrenInColumns(std::ostream &stream, const RootObjTree &tree
509509
PrintNodesInColumns(stream, tree, children.begin(), children.end(), flags, indent);
510510
}
511511

512-
static std::string NodeFullPath(const RootObjTree &tree, NodeIdx_t nodeIdx)
513-
{
514-
std::vector<const std::string *> fragments;
515-
const RootObjNode *node = &tree.fNodes[nodeIdx];
516-
NodeIdx_t prevParent;
517-
do {
518-
prevParent = node->fParent;
519-
fragments.push_back(&node->fName);
520-
node = &tree.fNodes[node->fParent];
521-
} while (node->fParent != prevParent);
522-
523-
assert(!fragments.empty());
524-
525-
std::string fullPath = **fragments.rbegin();
526-
for (auto it = std::next(fragments.rbegin()), end = fragments.rend(); it != end; ++it) {
527-
fullPath += '/' + **it;
528-
}
529-
return fullPath;
530-
}
531-
532512
// Main entrypoint of the program
533513
static void RootLs(const RootLsArgs &args, std::ostream &stream = std::cout)
534514
{

0 commit comments

Comments
 (0)