libpniio
nxlink.hpp
Go to the documentation of this file.
1 //
2 // (c) Copyright 2013 DESY, Eugen Wintersberger <eugen.wintersberger@desy.de>
3 //
4 // This file is part of libpniio.
5 //
6 // libpniio is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // libpniio is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with libpniio. If not, see <http://www.gnu.org/licenses/>.
18 // ===========================================================================
19 //
20 // Created on: Jul 22, 2013
21 // Author: Eugen Wintersberger <eugen.wintersberger@desy.de>
22 //
23 
24 #pragma once
25 
26 #include <boost/filesystem.hpp>
27 #include "nxobject_traits.hpp"
28 #include "nxpath/nxpath.hpp"
29 #include "nxpath/utils.hpp"
30 #include "nxlink_type.hpp"
31 #include "algorithms/get_path.hpp"
33 
34 
35 namespace pni{
36 namespace io{
37 namespace nx{
38 
39  //internal function - should not show up in the official documentation
40  //
41  // This function throws value_error when the target path contains
42  // intermediate ..!
43  void __check_target_path(const nxpath &target);
44 
45  //------------------------------------------------------------------------
56 
63 
73  template<
86  template<nximp_code> class GTYPE,
87  nximp_code IMPID
88  >
89  void link(const nxpath &target,const GTYPE<IMPID> &g,
90  const pni::core::string &name)
91  {
92 
93  //determine the utility class perfroming linking
95 
96 
97  if(has_file_section(target))
98  {
99  __check_target_path(target);
100  //create an external link
101  link_type::create_external_link(target,g.imp(),name);
102  }
103  else
104  {
105  nxpath real_target = target;
106 
107  if(!is_absolute(real_target))
108  {
109  GTYPE<IMPID> parent = g;
110  while(real_target.front().first=="..")
111  {
112  parent = parent.parent();
113  real_target.pop_front();
114  }
115 
116  real_target = join(nxpath::from_string(get_path(parent)),real_target);
117  }
118 
119  //the target path must not contain any element with ..
120  __check_target_path(real_target);
121 
122  //create an internal link
123  link_type::create_internal_link(real_target,g.imp(),name);
124  }
125  }
126 
127  //-------------------------------------------------------------------------
144  template<typename GTYPE>
145  void link(const pni::core::string &target,const GTYPE &g,
146  const pni::core::string &name)
147  {
148  nxpath path = nxpath::from_string(target);
149  link(path,g,name);
150  }
151 
152  //-------------------------------------------------------------------------
169  template<typename GTYPE>
170  void link(const char *target,const GTYPE &g,const pni::core::string &name)
171  {
172  link(pni::core::string(target),g,name);
173  }
174 
175  //-------------------------------------------------------------------------
203  template<
204  typename STYPE,
205  typename GTYPE
206  >
207  void link(const STYPE &target,const GTYPE &g,const pni::core::string &name)
208  {
209  link(get_path(target),g,name);
210  }
211 
212  //-------------------------------------------------------------------------
229  template<
230  template<nximp_code> class GTYPE,
231  nximp_code IMPID
232  >
233  auto link_type(const GTYPE<IMPID> &parent,const pni::core::string &name)
234  -> nxlink_type
235  {
237 
238  return link_type::link_type(parent.imp(),name);
239  }
240 
241  //-------------------------------------------------------------------------
260  template<
261  template<nximp_code> class GTYPE,
262  nximp_code IMPID
263  >
264  auto link_name(const GTYPE<IMPID> &parent,size_t index)
265  -> pni::core::string
266  {
268 
269  return link_type::link_name(parent.imp(),index);
270  }
271  //-------------------------------------------------------------------------
289  template<
290  template<nximp_code> class GTYPE,
291  nximp_code IMPID
292  >
293  auto link_target(const GTYPE<IMPID> &parent,const pni::core::string &lname)
294  -> nxpath
295  {
297 
298  return link_type::link_target(parent.imp(),lname);
299  }
300 
301  //-------------------------------------------------------------------------
320  template<
321  template<nximp_code> class GTYPE,
322  nximp_code IMPID
323  >
324  auto link_target(const GTYPE<IMPID> &parent,size_t index) -> nxpath
325  {
326  return link_target(parent,link_name(parent,index));
327  }
328 
329 
330  //-------------------------------------------------------------------------
349  template<typename GTYPE>
350  bool is_external_link(const GTYPE &parent,const pni::core::string &name)
351  {
352  return link_type(parent,name)==nxlink_type::EXTERNAL;
353  }
354 
355  //-------------------------------------------------------------------------
374  template<typename GTYPE>
375  bool is_soft_link(const GTYPE &parent,const pni::core::string &name)
376  {
377  return link_type(parent,name) == nxlink_type::SOFT;
378  }
379 
380  //-------------------------------------------------------------------------
399  template<typename GTYPE>
400  bool is_hard_link(const GTYPE &parent,const pni::core::string &name)
401  {
402  return link_type(parent,name) == nxlink_type::HARD;
403  }
404 
405  //------------------------------------------------------------------------
406  template<
407  template<nximp_code> class GTYPE,
408  nximp_code IMPID
409  >
410  auto link_status(const GTYPE<IMPID> parent,
411  const pni::core::string &lname)
412  -> nxlink_status
413  {
414  using namespace boost::filesystem;
415  using file_type = typename nxobject_trait<IMPID>::file_type;
416 
417  auto target = link_target(parent,lname);
418 
419  switch(link_type(parent,lname))
420  {
421  case nxlink_type::HARD:
422  return nxlink_status::VALID;
423  case nxlink_type::SOFT:
424  try
425  {
426  auto object = get_object(parent,target);
427  return nxlink_status::VALID;
428  }
429  catch(...)
430  {
431  return nxlink_status::INVALID;
432  }
433  break;
435  //check if the file exists
436  if(!exists(path(target.filename())))
437  return nxlink_status::INVALID;
438 
439  try
440  {
441  //check if the referenced object exists
442  auto f = file_type::open_file(target.filename());
443  auto o = get_object(f.root(),target);
444  return nxlink_status::VALID;
445  }
446  catch(...)
447  {
448  return nxlink_status::INVALID;
449  }
450  break;
451  default:
452  return nxlink_status::INVALID;
453  }
454 
455  return nxlink_status::INVALID;
456  }
457 
458 //end of namespace
459 }
460 }
461 }
nxpath join(const nxpath &a, const nxpath &b)
Definition: nxpath/utils.cpp:142
bool is_soft_link(const GTYPE &parent, const pni::core::string &name)
return true if link is soft
Definition: nxlink.hpp:375
static nxpath from_string(const pni::core::string &input)
create path from string
Definition: nxpath.cpp:52
bool has_file_section(const nxpath &p)
Definition: nxpath/utils.cpp:83
void pop_front()
last element from path
Definition: nxpath.cpp:120
element_type front() const
get last element
Definition: nxpath/nxpath.hpp:207
nexus object traits
Definition: nxobject_traits.hpp:44
auto link_type(const GTYPE< IMPID > &parent, const pni::core::string &name) -> nxlink_type
return link type
Definition: nxlink.hpp:233
auto link_status(const GTYPE< IMPID > parent, const pni::core::string &lname) -> nxlink_status
Definition: nxlink.hpp:410
void __check_target_path(const nxpath &target)
Definition: nxlink.cpp:27
nxlink_type
Nexus link type.
Definition: nxlink_type.hpp:51
auto link_target(const GTYPE< IMPID > &parent, const pni::core::string &lname) -> nxpath
get link target
Definition: nxlink.hpp:293
denotes a soft link
Definition: cbf_reader.hpp:41
nxlink_status
Nexus link status.
Definition: nxlink_type.hpp:76
auto link_name(const GTYPE< IMPID > &parent, size_t index) -> pni::core::string
get link name
Definition: nxlink.hpp:264
denotes an external link
bool is_absolute(const nxpath &p)
Definition: nxpath/utils.cpp:107
nximp_code
implementation codes
Definition: nximp_code.hpp:40
auto link_target(const GTYPE< IMPID > &parent, size_t index) -> nxpath
get link target
Definition: nxlink.hpp:324
auto get_object(const OTYPE &o, const PATHT &path) -> decltype(get_parent(o))
retrieve an object from path
Definition: get_object.hpp:62
the link is resolvable
denotes a hard link
bool is_external_link(const GTYPE &parent, const pni::core::string &name)
return true if link is external
Definition: nxlink.hpp:350
Nexus path class.
Definition: nxpath/nxpath.hpp:60
bool is_hard_link(const GTYPE &parent, const pni::core::string &name)
return true if link is hard
Definition: nxlink.hpp:400
pni::core::string get_path(const OTYPE< IMPID > &o)
get object path
Definition: get_path.hpp:59
void link(const nxpath &target, const GTYPE< IMPID > &g, const pni::core::string &name)
create a link
Definition: nxlink.hpp:89