Project
Loading...
Searching...
No Matches
StringUtils.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
13#include <cstdlib>
14#include <filesystem>
15#ifndef GPUCA_STANDALONE
16#include <TGrid.h>
17#include <fmt/format.h>
18#endif
19#include <unistd.h>
20#include <cstring>
21
22using namespace o2::utils;
23
24std::vector<std::string> Str::tokenize(const std::string& src, char delim, bool trimToken, bool skipEmpty)
25{
26 std::stringstream ss(src);
27 std::string token;
28 std::vector<std::string> tokens;
29
30 while (std::getline(ss, token, delim)) {
31 if (trimToken) {
32 trim(token);
33 }
34 if (!token.empty() || !skipEmpty) {
35 tokens.push_back(std::move(token));
36 }
37 }
38 return tokens;
39}
40
41std::vector<std::string> Str::tokenize(const std::string& src, const std::string& delim, bool trimToken, bool skipEmpty)
42{
43 std::string inptStr{src};
44 char* input = inptStr.data();
45 auto mystrtok = [&]() -> char* {
46 input += std::strspn(input, delim.c_str());
47 if (*input == '\0') {
48 return nullptr;
49 }
50 char* const token = input;
51 input += std::strcspn(input, delim.c_str());
52 if (*input != '\0') {
53 *input++ = '\0';
54 }
55 return token;
56 };
57 std::vector<std::string> tokens;
58 while (*input != '\0') {
59 std::string token = mystrtok();
60 if (trimToken) {
61 trim(token);
62 }
63 if (!token.empty() || !skipEmpty) {
64 tokens.push_back(std::move(token));
65 }
66 }
67 return tokens;
68}
69
70// replace all occurencies of from by to, return count
71int Str::replaceAll(std::string& s, const std::string& from, const std::string& to)
72{
73 int count = 0;
74 size_t pos = 0;
75 while ((pos = s.find(from, pos)) != std::string::npos) {
76 s.replace(pos, from.length(), to);
77 pos += to.length(); // Handles case where 'to' is a substring of 'from'
78 count++;
79 }
80 return count;
81}
82
83// generate random string of given lenght, suitable for file names
84std::string Str::getRandomString(int lenght)
85{
86 int pid = (int)getpid();
87 auto nextAllowed = [pid]() {
88 constexpr char chars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
89 constexpr size_t L = sizeof(chars) - 1;
90 int rn = std::rand() | pid;
91 return chars[rn % L];
92 };
93 std::string str(lenght, 0);
94 std::generate_n(str.begin(), lenght, nextAllowed);
95 return str;
96}
97
98bool Str::pathExists(const std::string_view p)
99{
100 return p.compare(0, 8, "alien://") ? std::filesystem::exists(std::string{p}) : true; // we don't validate alien paths
101}
102
103bool Str::pathIsDirectory(const std::string_view p)
104{
105 return std::filesystem::is_directory(std::string{p});
106}
107
108std::string Str::getFullPath(const std::string_view p)
109{
110 return std::filesystem::canonical(std::string{p}).string();
111}
112
113#ifndef GPUCA_STANDALONE
114std::string Str::rectifyDirectory(const std::string_view p)
115{
116 std::string dir(p);
117 if (dir.empty() || dir == "none") {
118 dir = "";
119 } else {
120 if (p.compare(0, 8, "alien://") == 0) {
121 if (!gGrid && !TGrid::Connect("alien://")) {
122 throw std::runtime_error(fmt::format("failed to initialize alien for {}", dir));
123 }
124 // for root or raw files do not treat as directory
125 if (dir.back() != '/' && !(endsWith(dir, ".root") || endsWith(dir, ".raw") || endsWith(dir, ".tf"))) {
126 dir += '/';
127 }
128 } else {
129 dir = getFullPath(dir);
130 if (!pathIsDirectory(dir)) {
131 throw std::runtime_error(fmt::format("{} is not an accessible directory", dir));
132 } else {
133 if (dir.back() != '/') {
134 dir += '/';
135 }
136 }
137 }
138 }
139 return dir;
140}
141#endif
142
143// Create unique non-existing path name starting with prefix. Loose equivalent of boost::filesystem::unique_path()
144// The prefix can be either existing directory or just a string to add in front of the random part
145// in absence of such a function in std::filesystem
146std::string Str::create_unique_path(const std::string_view prefix, int length)
147{
148 std::string path;
149 bool needSlash = pathIsDirectory(prefix) && !prefix.empty() && prefix.back() != '/';
150 do {
151 path = concat_string(prefix, needSlash ? "/" : "", getRandomString(length));
152 } while (pathExists(path));
153
154 return path;
155}
uint16_t pos
Definition RawData.h:3
uint16_t pid
Definition RawData.h:2
GLenum src
Definition glcorearb.h:1767
GLint GLsizei count
Definition glcorearb.h:399
GLuint GLsizei GLsizei * length
Definition glcorearb.h:790
GLsizei const GLchar *const * path
Definition glcorearb.h:3591
static bool pathIsDirectory(const std::string_view p)
static void trim(std::string &s)
Definition StringUtils.h:70
static std::string rectifyDirectory(const std::string_view p)
static bool pathExists(const std::string_view p)
static std::vector< std::string > tokenize(const std::string &src, char delim, bool trimToken=true, bool skipEmpty=true)
static int replaceAll(std::string &s, const std::string &from, const std::string &to)
static std::string concat_string(Ts const &... ts)
static std::string getFullPath(const std::string_view p)
static std::string create_unique_path(const std::string_view prefix="", int length=16)
static bool endsWith(const std::string &s, const std::string &ending)
static std::string getRandomString(int length)
const std::string str