XRootD
XrdPfcPathParseTools.hh
Go to the documentation of this file.
1 #ifndef __XRDPFC_PATHPARSETOOLS_HH__
2 #define __XRDPFC_PATHPARSETOOLS_HH__
3 
4 #include <string>
5 #include <vector>
6 
7 #include <cstdio>
8 #include <cstring>
9 
10 namespace XrdPfc {
11 
13 {
14  char *f_str;
15  const char *f_delim;
16  char *f_state;
17  bool f_first;
18 
19  SplitParser(const std::string &s, const char *d) :
20  f_str(strdup(s.c_str())), f_delim(d), f_state(0), f_first(true)
21  {}
22  ~SplitParser() { free(f_str); }
23 
24  char* get_token()
25  {
26  if (f_first) { f_first = false; return strtok_r(f_str, f_delim, &f_state); }
27  else { return strtok_r(0, f_delim, &f_state); }
28  }
29 
31  {
32  if (f_first) { return f_str; }
33  else { *(f_state - 1) = f_delim[0]; return f_state - 1; }
34  }
35 
36  char *get_reminder()
37  {
38  return f_first ? f_str : f_state;
39  }
40 
41  int fill_argv(std::vector<char*> &argv)
42  {
43  if (!f_first) return 0;
44  int dcnt = 0; { char *p = f_str; while (*p) { if (*(p++) == f_delim[0]) ++dcnt; } }
45  argv.reserve(dcnt + 1);
46  int argc = 0;
47  char *i = strtok_r(f_str, f_delim, &f_state);
48  while (i)
49  {
50  ++argc;
51  argv.push_back(i);
52  // printf(" arg %d : '%s'\n", argc, i);
53  i = strtok_r(0, f_delim, &f_state);
54  }
55  return argc;
56  }
57 };
58 
59 struct PathTokenizer : private SplitParser
60 {
61  std::vector<const char*> m_dirs;
62  const char *m_reminder;
63  int m_n_dirs;
64 
65  PathTokenizer(const std::string &path, int max_depth, bool parse_as_lfn) :
66  SplitParser(path, "/"),
67  m_reminder (0),
68  m_n_dirs (0)
69  {
70  // max_depth - maximum number of directories to extract. If < 0, all path elements
71  // are extracted (well, up to 4096). The rest is in m_reminder.
72  // If parse_as_lfn is true store final token into m_reminder, regardless of maxdepth.
73  // This assumes the last token is a file name (and full path is lfn, including the file name).
74 
75  if (max_depth < 0)
76  max_depth = 4096;
77  m_dirs.reserve(std::min(8, max_depth));
78 
79  char *t = 0;
80  for (int i = 0; i < max_depth; ++i)
81  {
82  t = get_token();
83  if (t == 0) break;
84  m_dirs.emplace_back(t);
85  }
86  if (parse_as_lfn && *get_reminder() == 0 && ! m_dirs.empty())
87  {
88  m_reminder = m_dirs.back();
89  m_dirs.pop_back();
90  }
91  else
92  {
94  }
95  m_n_dirs = (int) m_dirs.size();
96  }
97 
98  int get_n_dirs()
99  {
100  return m_n_dirs;
101  }
102 
103  const char *get_dir(int pos)
104  {
105  if (pos >= m_n_dirs) return 0;
106  return m_dirs[pos];
107  }
108 
109  std::string make_path()
110  {
111  std::string res;
112  for (std::vector<const char*>::iterator i = m_dirs.begin(); i != m_dirs.end(); ++i)
113  {
114  res += "/";
115  res += *i;
116  }
117  if (m_reminder != 0)
118  {
119  res += "/";
120  res += m_reminder;
121  }
122  return res;
123  }
124 
125  void print_debug()
126  {
127  printf("PathTokenizer::print_debug size=%d\n", m_n_dirs);
128  for (int i = 0; i < m_n_dirs; ++i)
129  {
130  printf(" %2d: %s\n", i, m_dirs[i]);
131  }
132  printf(" rem: %s\n", m_reminder);
133  }
134 };
135 
136 }
137 
138 #endif
Definition: XrdPfc.hh:41
PathTokenizer(const std::string &path, int max_depth, bool parse_as_lfn)
std::vector< const char * > m_dirs
const char * get_dir(int pos)
SplitParser(const std::string &s, const char *d)
int fill_argv(std::vector< char * > &argv)