Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:50:06

0001 // Copyright (c) 2016 Klemens D. Morgenstern
0002 //
0003 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #ifndef BOOST_PROCESS_DETAIL_POSIX_ENVIRONMENT_HPP_
0007 #define BOOST_PROCESS_DETAIL_POSIX_ENVIRONMENT_HPP_
0008 
0009 #include <string>
0010 #include <vector>
0011 #include <unordered_map>
0012 #include <boost/process/detail/config.hpp>
0013 #include <algorithm>
0014 #include <cstdlib>
0015 #include <boost/process/locale.hpp>
0016 
0017 
0018 namespace boost { namespace process { namespace detail { namespace posix {
0019 
0020 template<typename Char>
0021 class native_environment_impl
0022 {
0023     static std::vector<std::basic_string<Char>>  _load()
0024     {
0025         std::vector<std::basic_string<Char>> val;
0026         auto p = environ;
0027         while (*p != nullptr)
0028         {
0029             std::string str = *p;
0030             val.push_back(::boost::process::detail::convert(str));
0031             p++;
0032         }
0033         return val;
0034     }
0035     static std::vector<Char*> _load_var(std::vector<std::basic_string<Char>> & vec)
0036     {
0037         std::vector<Char*> val;
0038         val.resize(vec.size() + 1);
0039         std::transform(vec.begin(), vec.end(), val.begin(),
0040                 [](std::basic_string<Char> & str)
0041                 {
0042                     return &str.front();
0043                 });
0044         val.back() = nullptr;
0045         return val;
0046     }
0047     std::vector<std::basic_string<Char>> _buffer = _load();
0048     std::vector<Char*> _impl = _load_var(_buffer);
0049 public:
0050     using char_type = Char;
0051     using pointer_type = const char_type*;
0052     using string_type = std::basic_string<char_type>;
0053     using native_handle_type = char_type **;
0054 
0055     void reload()
0056     {
0057         _buffer = _load();
0058         _impl = _load_var(_buffer);
0059         _env_impl = _impl.data();
0060     }
0061 
0062     string_type get(const pointer_type id) { return get(string_type(id)); }
0063     void        set(const pointer_type id, const pointer_type value)
0064     {
0065         set(string_type(id), string_type(value));
0066     }
0067     void      reset(const pointer_type id) { reset(string_type(id)); }
0068 
0069     string_type get(const string_type & id)
0070     {
0071         std::string id_c = ::boost::process::detail::convert(id);
0072         std::string g = ::getenv(id_c.c_str());
0073         return ::boost::process::detail::convert(g.c_str());
0074     }
0075     void        set(const string_type & id, const string_type & value)
0076     {
0077         std::string id_c    = ::boost::process::detail::convert(id.c_str());
0078         std::string value_c = ::boost::process::detail::convert(value.c_str());
0079         auto res = ::setenv(id_c.c_str(), value_c.c_str(), true);
0080         if (res != 0)
0081             boost::process::detail::throw_last_error();
0082     }
0083     void      reset(const string_type & id)
0084     {
0085         std::string id_c = ::boost::process::detail::convert(id.c_str());
0086         auto res = ::unsetenv(id_c.c_str());
0087         if (res != 0)
0088             ::boost::process::detail::throw_last_error();
0089     }
0090 
0091     native_environment_impl() = default;
0092     native_environment_impl(const native_environment_impl& ) = delete;
0093     native_environment_impl(native_environment_impl && ) = default;
0094     native_environment_impl & operator=(const native_environment_impl& ) = delete;
0095     native_environment_impl & operator=(native_environment_impl && ) = default;
0096     native_handle_type _env_impl = _impl.data();
0097 
0098     native_handle_type native_handle() const {return _env_impl;}
0099 };
0100 
0101 template<>
0102 class native_environment_impl<char>
0103 {
0104 public:
0105     using char_type = char;
0106     using pointer_type = const char_type*;
0107     using string_type = std::basic_string<char_type>;
0108     using native_handle_type = char_type **;
0109 
0110     void reload() {this->_env_impl = ::environ;}
0111 
0112     string_type get(const pointer_type id) { return getenv(id); }
0113     void        set(const pointer_type id, const pointer_type value)
0114     {
0115         auto res = ::setenv(id, value, 1);
0116         if (res != 0)
0117             boost::process::detail::throw_last_error();
0118         reload();
0119     }
0120     void      reset(const pointer_type id)
0121     {
0122         auto res = ::unsetenv(id);
0123         if (res != 0)
0124             boost::process::detail::throw_last_error();
0125         reload();
0126     }
0127 
0128     string_type get(const string_type & id) {return get(id.c_str());}
0129     void        set(const string_type & id, const string_type & value) {set(id.c_str(), value.c_str()); }
0130     void      reset(const string_type & id) {reset(id.c_str());}
0131 
0132     native_environment_impl() = default;
0133     native_environment_impl(const native_environment_impl& ) = delete;
0134     native_environment_impl(native_environment_impl && ) = default;
0135     native_environment_impl & operator=(const native_environment_impl& ) = delete;
0136     native_environment_impl & operator=(native_environment_impl && ) = default;
0137     native_handle_type _env_impl = environ;
0138 
0139     native_handle_type native_handle() const {return ::environ;}
0140 };
0141 
0142 
0143 
0144 template<typename Char>
0145 struct basic_environment_impl
0146 {
0147     std::vector<std::basic_string<Char>> _data {};
0148     static std::vector<Char*> _load_var(std::vector<std::basic_string<Char>> & data);
0149     std::vector<Char*> _env_arr{_load_var(_data)};
0150 public:
0151     using char_type = Char;
0152     using pointer_type = const char_type*;
0153     using string_type = std::basic_string<char_type>;
0154     using native_handle_type = Char**;
0155     void reload()
0156     {
0157         _env_arr = _load_var(_data);
0158         _env_impl = _env_arr.data();
0159     }
0160 
0161     string_type get(const pointer_type id) {return get(string_type(id));}
0162     void        set(const pointer_type id, const pointer_type value) {set(string_type(id), value);}
0163     void      reset(const pointer_type id)  {reset(string_type(id));}
0164 
0165     string_type get(const string_type & id);
0166     void        set(const string_type & id, const string_type & value);
0167     void      reset(const string_type & id);
0168 
0169     basic_environment_impl(const native_environment_impl<Char> & nei);
0170     basic_environment_impl() = default;
0171     basic_environment_impl(const basic_environment_impl& rhs)
0172         : _data(rhs._data)
0173     {
0174 
0175     }
0176     basic_environment_impl(basic_environment_impl && ) = default;
0177     basic_environment_impl & operator=(const basic_environment_impl& rhs)
0178     {
0179         _data = rhs._data;
0180         _env_arr = _load_var(_data);
0181         _env_impl = &*_env_arr.begin();
0182         return *this;
0183     }
0184     basic_environment_impl & operator=(basic_environment_impl && ) = default;
0185 
0186     template<typename CharR>
0187     explicit inline  basic_environment_impl(
0188                 const basic_environment_impl<CharR>& rhs,
0189                 const ::boost::process::codecvt_type & cv = ::boost::process::codecvt())
0190         : _data(rhs._data.size())
0191     {
0192         std::transform(rhs._data.begin(), rhs._data.end(), _data.begin(),
0193                 [&](const std::basic_string<CharR> & st)
0194                 {
0195                     return ::boost::process::detail::convert(st, cv);
0196                 }
0197 
0198             );
0199         reload();
0200     }
0201 
0202     template<typename CharR>
0203     basic_environment_impl & operator=(const basic_environment_impl<CharR>& rhs)
0204     {
0205         _data = ::boost::process::detail::convert(rhs._data);
0206         _env_arr = _load_var(&*_data.begin());
0207         _env_impl = &*_env_arr.begin();
0208         return *this;
0209     }
0210 
0211     Char ** _env_impl = &*_env_arr.data();
0212 
0213     native_handle_type native_handle() const {return &_data.front();}
0214 };
0215 
0216 
0217 template<typename Char>
0218 basic_environment_impl<Char>::basic_environment_impl(const native_environment_impl<Char> & nei)
0219 {
0220     auto beg = nei.native_handle();
0221 
0222     auto end = beg;
0223     while (*end != nullptr)
0224         end++;
0225     this->_data.assign(beg, end);
0226     reload();
0227 }
0228 
0229 
0230 template<typename Char>
0231 inline auto basic_environment_impl<Char>::get(const string_type &id) -> string_type
0232 {
0233     auto itr = std::find_if(_data.begin(), _data.end(), 
0234             [&](const string_type & st) -> bool
0235             {
0236                 if (st.size() <= id.size())
0237                     return false;
0238                 return std::equal(id.begin(), id.end(), st.begin()) && (st[id.size()] == equal_sign<Char>());
0239             }
0240         );
0241 
0242     if (itr == _data.end())
0243     {
0244         return "";
0245     }
0246     else return
0247         itr->data() + id.size(); //id=Thingy -> +2 points to T
0248 }
0249 
0250 template<typename Char>
0251 inline void basic_environment_impl<Char>::set(const string_type &id, const string_type &value)
0252 {
0253     auto itr = std::find_if(_data.begin(), _data.end(), 
0254         [&](const string_type & st) -> bool
0255         {
0256             if (st.size() <= id.size())
0257                 return false;
0258             return std::equal(id.begin(), id.end(), st.begin()) && (st[id.size()] == equal_sign<Char>());
0259         }
0260     );
0261 
0262     if (itr != _data.end())
0263         *itr = id + equal_sign<Char>() + value;
0264     else 
0265         _data.push_back(id + equal_sign<Char>() + value);
0266 
0267     reload();
0268 }
0269 
0270 template<typename Char>
0271 inline void  basic_environment_impl<Char>::reset(const string_type &id)
0272 {
0273     auto itr = std::find_if(_data.begin(), _data.end(), 
0274         [&](const string_type & st) -> bool
0275         {
0276             if (st.size() <= id.size())
0277                 return false;
0278             return std::equal(id.begin(), id.end(), st.begin()) && (st[id.size()] == equal_sign<Char>());
0279         }
0280     );
0281     if (itr != _data.end())
0282     {
0283         _data.erase(itr);//and remove it    
0284     }
0285     
0286     reload();
0287 
0288 
0289 }
0290 
0291 template<typename Char>
0292 std::vector<Char*> basic_environment_impl<Char>::_load_var(std::vector<std::basic_string<Char>> & data)
0293 {
0294     std::vector<Char*> ret;
0295     ret.reserve(data.size() +1);
0296 
0297     for (auto & val : data)
0298     {
0299         if (val.empty())
0300             val.push_back(0);
0301         ret.push_back(&val.front());
0302     }
0303 
0304     ret.push_back(nullptr);
0305     return ret;
0306 }
0307 
0308 template<typename T> constexpr T env_seperator();
0309 template<> constexpr   char   env_seperator() {return  ':'; }
0310 template<> constexpr  wchar_t env_seperator() {return L':'; }
0311 
0312 
0313 typedef int native_handle_t;
0314 
0315 inline int  get_id()        {return getpid(); }
0316 inline int native_handle()  {return getpid(); }
0317 
0318 }
0319 
0320 }
0321 }
0322 }
0323 
0324 
0325 
0326 
0327 #endif /* BOOST_PROCESS_DETAIL_WINDOWS_ENV_STORAGE_HPP_ */