diff --git a/source/utils.cpp b/source/utils.cpp index c0c6dcc..b4ad2c0 100644 --- a/source/utils.cpp +++ b/source/utils.cpp @@ -9,188 +9,224 @@ #include #include - -std::string to_string(char* contents, size_t size){ - std::string s; - for (size_t i = 0; i < size; i++) { - s = s + contents[i]; - } - return s; +std::string to_string(char *contents, size_t size) +{ + std::string s; + for (size_t i = 0; i < size; i++) + { + s = s + contents[i]; + } + return s; } // Returns true if and only if path is root path -bool is_root_path(const char *path){ - return (strcmp(path, rucio_root_path.c_str()) == 0 || strcmp(path, (rucio_root_path+"/").c_str()) == 0); +bool is_root_path(const char *path) +{ + return (strcmp(path, rucio_root_path.c_str()) == 0 || strcmp(path, (rucio_root_path + "/").c_str()) == 0); } - - // This function returns -1 if path contains no token // 0 if path is root // POSIX format depth in other cases -int path_depth(const char *path, const char token){ +int path_depth(const char *path, const char token) +{ // If path is root return depth=0 immediately - if(is_root_path(path)) { + if (is_root_path(path)) + { return 0; } // Otherwise compute depth - else { + else + { // Count token occurrences auto s = path; int16_t i = 0; size_t size = 0; - for (i = 0; s[i];){ + for (i = 0; s[i];) + { size++; - if(s[i] == token) i++; - else s++; + if (s[i] == token) + i++; + else + s++; } // Remove one to count if just the last char is equal to token (spurious token) // '/scope1' and '/scope1/' should behave the same - if(path[size-1] == token) i--; + if (path[size - 1] == token) + i--; // Returns depth return i; } } -bool is_server_mountpoint(const char *path){ +bool is_server_mountpoint(const char *path) +{ return path_depth(path) == 1; }; // This function returns true is the depth is 1 (e.g. /scope1 or /scope1/) -bool is_main_scope(const char *path){ +bool is_main_scope(const char *path) +{ return path_depth(path) == 2; } -std::vector split(const std::string &s, char delim) { - std::vector elems; - std::stringstream ss(s); - std::string key_or_value; - while(std::getline(ss, key_or_value, delim)) { - elems.emplace_back(key_or_value); - } - return elems; +std::vector split(const std::string &s, char delim) +{ + std::vector elems; + std::stringstream ss(s); + std::string key_or_value; + while (std::getline(ss, key_or_value, delim)) + { + elems.emplace_back(key_or_value); + } + return elems; } -void remove_trailing_token(std::string& path, std::string token){ - if(path.length() - 1 > 0) { - if (path.substr(path.length() - 1) == token) { +void remove_trailing_token(std::string &path, std::string token) +{ + if (path.length() - 1 > 0) + { + if (path.substr(path.length() - 1) == token) + { path.pop_back(); } } } -void remove_leading_token(std::string& path, std::string token){ -// std::cout << "received: " << path < 0) { - if (path.substr(1) == token) { +void remove_leading_token(std::string &path, std::string token) +{ + // std::cout << "received: " << path < 0) + { + if (path.substr(1) == token) + { path.erase(path.begin()); } } } -std::string remove_substring(const std::string& path, const std::string& subs){ +std::string remove_substring(const std::string &path, const std::string &subs) +{ auto path_copy = path; // Search for the rucio root path with trailing "/" - size_t pos = path_copy.find(subs); + size_t pos = path_copy.find(subs); - if (pos != std::string::npos) - { + if (pos != std::string::npos) + { // Erase root path from string - path_copy.erase(pos, subs.length()); - } + path_copy.erase(pos, subs.length()); + } - return path_copy; + return path_copy; } -std::string remove_root_path(const std::string& path){ +std::string remove_root_path(const std::string &path) +{ return remove_substring(path, rucio_root_path); } -std::string extract_server_name(const std::string& path){ +std::string extract_server_name(const std::string &path) +{ auto path_copy = remove_root_path(path); size_t pos = path_copy.find('/'); if (pos != std::string::npos) - { + { // Erase everything after the first "/" - path_copy.erase(pos, path_copy.length()); - } + path_copy.erase(pos, path_copy.length()); + } return std::move(path_copy); } -std::string extract_scope(const std::string& path){ +std::string extract_scope(const std::string &path) +{ auto path_copy = remove_root_path(path); remove_trailing_token(path_copy); - path_copy = remove_substring(path_copy, extract_server_name(path)+'/'); + path_copy = remove_substring(path_copy, extract_server_name(path) + '/'); size_t pos = path_copy.find('/'); if (pos != std::string::npos) - { + { // Erase everything after the first "/" - path_copy.erase(pos, path_copy.length()); - } + path_copy.erase(pos, path_copy.length()); + } return std::move(path_copy); } -std::string extract_name(const std::string& path){ +std::string extract_name(const std::string &path) +{ auto path_copy = path; remove_trailing_token(path_copy); size_t pos = path_copy.find_last_of('/'); if (pos != std::string::npos) - { + { // Erase everything after the first "/" - path_copy.erase(0, pos+1); - } + path_copy.erase(0, pos + 1); + } return std::move(path_copy); } -std::string get_did(const std::string& path){ - return extract_scope(path)+":"+extract_name(path); +std::string get_did(const std::string &path) +{ + return extract_scope(path) + ":" + extract_name(path); } -void split_dids(const std::string &line, std::vector& did_strings){ +void split_dids(const std::string &line, std::vector &did_strings) +{ did_strings.reserve(std::count(line.begin(), line.end(), '{')); std::stringstream stream(line); std::string buffer; - while(getline(stream, buffer, '\n')){ + while (getline(stream, buffer, '\n')) + { coherentize_dids(buffer); - if(not buffer.empty()) { + if (not buffer.empty()) + { did_strings.emplace_back(std::move(buffer)); } } } -void coherentize_dids(std::string &did_string){ - if(did_string.back() != '}'){ - if(did_string_remainder.empty()) { +void coherentize_dids(std::string &did_string) +{ + if (did_string.back() != '}') + { + if (did_string_remainder.empty()) + { did_string_remainder = std::move(did_string); - } else { + } + else + { did_string_remainder.append(std::move(did_string)); } did_string = ""; - }else if(did_string.front() != '{'){ + } + else if (did_string.front() != '{') + { did_string = did_string_remainder + did_string; did_string_remainder = ""; } } -void structurize_did(const std::string& did_str, std::vector& target) { +void structurize_did(const std::string &did_str, std::vector &target) +{ std::vector did_strings_vect; split_dids(did_str, did_strings_vect); - for (auto &sdid : did_strings_vect) { + for (auto &sdid : did_strings_vect) + { - for (const auto &ch : {' ', '}', '{', '"'}) { + for (const auto &ch : {' ', '}', '{', '"'}) + { sdid.erase(std::remove(sdid.begin(), sdid.end(), ch), sdid.end()); } @@ -202,11 +238,16 @@ void structurize_did(const std::string& did_str, std::vector& target) did.scope = key_values[1]; - if (key_values[3] == "FILE") { + if (key_values[3] == "FILE") + { did.type = rucio_data_type::rucio_file; - } else if (key_values[3] == "CONTAINER") { + } + else if (key_values[3] == "CONTAINER") + { did.type = rucio_data_type::rucio_container; - } else if (key_values[3] == "DATASET") { + } + else if (key_values[3] == "DATASET") + { did.type = rucio_data_type::rucio_dataset; } @@ -218,12 +259,15 @@ void structurize_did(const std::string& did_str, std::vector& target) } } -void structurize_container_did(const std::string& did_str, std::vector& target){ +void structurize_container_did(const std::string &did_str, std::vector &target) +{ std::vector did_strings_vect; split_dids(did_str, did_strings_vect); - for (auto &sdid : did_strings_vect) { - for (const auto &ch : {' ', '}', '{', '"'}) { + for (auto &sdid : did_strings_vect) + { + for (const auto &ch : {' ', '}', '{', '"'}) + { sdid.erase(std::remove(sdid.begin(), sdid.end(), ch), sdid.end()); } @@ -235,11 +279,16 @@ void structurize_container_did(const std::string& did_str, std::vector, 2020 +*/ + +#include +#include + +using namespace std; + +TEST(Utils_Test, Test_is_root_path){ + EXPECT_EQ(1, (bool)is_root_path("/")); + EXPECT_EQ(0, (bool)is_root_path("/a")); + EXPECT_EQ(0, (bool)is_root_path("/a/b")); +} + +TEST(Utils_Test, Test_path_depth){ + EXPECT_EQ(0, path_depth("/", '/')); + EXPECT_EQ(1, path_depth("/a",'/')); + EXPECT_EQ(1, path_depth("/a/",'/')); + EXPECT_EQ(2, path_depth("/a/b",'/')); + EXPECT_EQ(6, path_depth("/a/b/c/d/e/f/",'/')); + EXPECT_EQ(-1, path_depth("a", 'a')); +} + +TEST(Utils_Test, Test_string_manipulation){ + EXPECT_EQ("a", extract_server_name("/a/b/c")); + EXPECT_EQ("c", extract_scope("/a/b/c/d")); +} + +TEST(Utils_Test, Test_is_server_mountpoint){ + EXPECT_TRUE(is_server_mountpoint("/server1")); + EXPECT_TRUE(is_server_mountpoint("/server1/")); + EXPECT_FALSE(is_server_mountpoint("/")); + EXPECT_FALSE(is_server_mountpoint("/server1/scope1")); + EXPECT_FALSE(is_server_mountpoint("/server1/scope1/")); + EXPECT_FALSE(is_server_mountpoint("/server1/scope1/name1")); +} + +TEST(Utils_Test, Test_is_main_scope){ + EXPECT_FALSE(is_main_scope("/server1")); + EXPECT_FALSE(is_main_scope("/server1/")); + EXPECT_FALSE(is_main_scope("/")); + EXPECT_TRUE(is_main_scope("/server1/scope1")); + EXPECT_TRUE(is_main_scope("/server1/scope1/")); + EXPECT_FALSE(is_main_scope("/server1/scope1/name1")); +} + +// TEST(Utils_Test, Test_string_manipulation){ +// string test_string = "/server/scope/container/dataset/filename/"; +// EXPECT_NO_THROW(remove_trailing_token(test_string)); +// } + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file