E-MailRelay
genvironment.cpp
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2024 Graeme Walker <graeme_walker@users.sourceforge.net>
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16// ===
17///
18/// \file genvironment.cpp
19///
20
21#include "gdef.h"
22#include "genvironment.h"
23#include "gassert.h"
24#include "gstr.h"
25#include <string>
26#include <algorithm>
27#include <numeric>
28#include <stdexcept>
29
30G::Environment::Environment( const Map & map ) :
31 m_map(map)
32{
33 sanitise( m_map ) ;
34}
35
36void G::Environment::sanitise( Map & map )
37{
38 for( auto p = map.begin() ; p != map.end() ; )
39 {
40 if( (*p).first.empty() || (*p).first.find('\0') != std::string::npos || (*p).second.find('\0') != std::string::npos )
41 p = map.erase( p ) ;
42 else
43 ++p ;
44 }
45}
46
47#ifndef G_LIB_SMALL
48bool G::Environment::add( std::string_view key , std::string_view value )
49{
50 if( !key.empty() && key.find('\0') == std::string::npos && value.find('\0') == std::string::npos )
51 {
52 m_map[sv_to_string(key)] = sv_to_string(value) ;
53 return true ;
54 }
55 else
56 {
57 return false ;
58 }
59}
60#endif
61
62bool G::Environment::contains( const std::string & name ) const
63{
64 return m_map.find(name) != m_map.end() ;
65}
66
67#ifndef G_LIB_SMALL
68std::string G::Environment::value( const std::string & name , const std::string & default_ ) const
69{
70 return contains(name) ? (*m_map.find(name)).second : default_ ;
71}
72#endif
73
74std::string G::Environment::block() const
75{
76 std::size_t n = std::accumulate( m_map.begin() , m_map.end() , std::size_t(0U) ,
77 [](std::size_t n_,const Map::value_type &p_){return n_+p_.first.size()+p_.second.size()+2U;} ) ;
78 std::string result ;
79 result.reserve( n+1U ) ;
80 for( const auto & p : m_map )
81 result.append(p.first).append(1U,'=').append(p.second).append(1U,'\0') ;
82 result.append( 1U , '\0' ) ;
83 return result ;
84}
85
86#ifndef G_LIB_SMALL
87std::wstring G::Environment::block( std::wstring (*fn)(std::string_view) ) const
88{
89 std::size_t n = std::accumulate( m_map.begin() , m_map.end() , std::size_t(0U) ,
90 [](std::size_t n_,const Map::value_type &p_){return n_+p_.first.size()+p_.second.size()+2U;} ) ;
91 std::wstring result ;
92 result.reserve( n+1U ) ;
93 for( const auto & p : m_map )
94 result.append(fn(std::string(p.first).append(1U,L'=').append(p.second))).append(1U,L'\0') ;
95 result.append( 1U , L'\0' ) ;
96 return result ;
97}
98#endif
99
100std::vector<char*> G::Environment::array( const std::string & block )
101{
102 G_ASSERT( block.size() >= 2U && block[block.size()-1U] == 0 && block[block.size()-2U] == 0 ) ;
103 std::vector<char*> result ;
104 if( block.size() >= 2U && block[block.size()-1U] == 0 && block[block.size()-2U] == 0 )
105 {
106 result.reserve( std::count( block.begin() , block.end() , 0 ) ) ;
107 const char * const end = block.data() + block.size() ;
108 for( const char * p = block.data() ; p < end && *p ; p += (std::strlen(p)+1U) )
109 result.push_back( const_cast<char*>(p) ) ;
110 }
111 result.push_back( nullptr ) ;
112 return result ;
113}
114
std::string value(const std::string &name, const std::string &default_={}) const
Returns the value of the given variable in this set.
Environment(const std::map< std::string, std::string > &)
Constructor from a map.
std::string block() const
Returns a contiguous block of memory containing the null-terminated strings with an extra zero byte a...
bool contains(const std::string &name) const
Returns true if the given variable is in this set.
static std::vector< char * > array(const std::string &block)
Returns a pointer array pointing into the given block(), with const-casts.
bool add(std::string_view key, std::string_view value)
Adds an environment variable. Returns false if invalid.