E-MailRelay

genvironment.cpp
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2021 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 "gstr.h"
24#include <algorithm>
25#include <stdexcept>
26
27 G::Environment::Environment()
28{
29 setup() ;
30}
31
32 G::Environment::Environment( const std::map<std::string,std::string> & map ) :
33 m_map(map)
34{
35 setup() ;
36}
37
38 G::Environment::Environment( const Environment & other ) :
39 m_map(other.m_map)
40{
41 setup() ;
42}
43
44 G::Environment::Environment( Environment && other ) noexcept :
45 m_map(std::move(other.m_map)) ,
46 m_list(std::move(other.m_list)) ,
47 m_pointers(std::move(other.m_pointers)) ,
48 m_block(std::move(other.m_block))
49{
50}
51
52 void G::Environment::swap( Environment & other ) noexcept
53{
54 m_map.swap( other.m_map ) ;
55 m_list.swap( other.m_list ) ;
56 m_pointers.swap( other.m_pointers ) ;
57 std::swap( m_block , other.m_block ) ;
58}
59
60 bool G::Environment::valid() const
61{
62 return
63 m_map.size() == m_list.size() &&
64 (m_list.size()+1U) == m_pointers.size() &&
65 ( m_list.empty() || m_pointers.at(0U) == m_list.at(0U).c_str() ) ;
66}
67
68 G::Environment & G::Environment::operator=( const Environment & other )
69{
70 Environment(other).swap( *this ) ;
71 return *this ;
72}
73
74 G::Environment & G::Environment::operator=( Environment && other ) noexcept
75{
76 Environment(std::move(other)).swap( *this ) ;
77 return *this ;
78}
79
80 void G::Environment::setup()
81{
82 setList() ;
83 setPointers() ;
84 setBlock() ;
85}
86
87 void G::Environment::setList()
88{
89 m_list.clear() ;
90 m_list.reserve( m_map.size() ) ;
91 StringArray keys = Str::keys( m_map ) ;
92 std::sort( keys.begin() , keys.end() ) ;
93 for( const auto & key : keys )
94 {
95 m_list.push_back( key + "=" + (*m_map.find(key)).second ) ;
96 }
97}
98
99 void G::Environment::setPointers()
100{
101 m_pointers.clear() ;
102 m_pointers.reserve( m_list.size() + 1U ) ;
103 for( const auto & s : m_list )
104 m_pointers.push_back( const_cast<char*>(s.c_str()) ) ;
105 m_pointers.push_back( nullptr ) ;
106}
107
108 void G::Environment::setBlock()
109{
110 std::size_t n = 0U ;
111 for( auto & s : m_list )
112 n += (s.size()+1U) ;
113 m_block.reserve( n + 1U ) ;
114 for( auto & s : m_list )
115 {
116 m_block.append( s ) ;
117 m_block.append( 1U , '\0' ) ;
118 }
119 m_block.append( 1U , '\0' ) ;
120}
121
122 void G::Environment::add( const std::string & name , const std::string & value )
123{
124 if( name.find('=') != std::string::npos ) throw std::runtime_error( "invalid environment variable [" + name + "]" ) ;
125 m_map.insert( std::make_pair(name,value) ) ;
126 setup() ;
127}
128
129 void G::Environment::set( const std::string & name , const std::string & value )
130{
131 m_map[name] = value ;
132 setup() ;
133}
134
135 char ** G::Environment::v() const noexcept
136{
137 return const_cast<char**>(&m_pointers[0]) ;
138}
139
140 const char * G::Environment::ptr() const noexcept
141{
142 return m_block.data() ;
143}
144
145 bool G::Environment::contains( const std::string & name ) const
146{
147 return m_map.find(name) != m_map.end() ;
148}
149
150std::string G::Environment::value( const std::string & name , const std::string & default_ ) const
151{
152 return contains(name) ? (*m_map.find(name)).second : default_ ;
153}
154
G::Environment
Holds a set of environment variables and also provides static methods to wrap getenv() and putenv().
Definition: genvironment.h:39
G::Environment::valid
bool valid() const
Returns true if the class invariants are satisfied.
Definition: genvironment.cpp:60
G::Environment::Environment
Environment(const std::map< std::string, std::string > &)
Constructor from a map.
Definition: genvironment.cpp:32
G::Environment::value
std::string value(const std::string &name, const std::string &default_=std::string()) const
Returns the value of the given variable in this set.
Definition: genvironment.cpp:150
G::Environment::add
void add(const std::string &name, const std::string &value)
Adds a variable to this set.
Definition: genvironment.cpp:122
G::Environment::ptr
const char * ptr() const noexcept
Returns a contiguous block of memory containing the null-terminated strings with an extra zero byte a...
Definition: genvironment.cpp:140
G::Environment::set
void set(const std::string &name, const std::string &value)
Inserts or updates a variable in this set.
Definition: genvironment.cpp:129
G::Environment::operator=
Environment & operator=(const Environment &)
Assigment operator.
Definition: genvironment.cpp:68
G::Environment::contains
bool contains(const std::string &name) const
Returns true if the given variable is in this set.
Definition: genvironment.cpp:145
G::Environment::v
char ** v() const noexcept
Returns a null-terminated array of pointers.
Definition: genvironment.cpp:135
G::Str::keys
static StringArray keys(const StringMap &string_map)
Extracts the keys from a map of strings.
Definition: gstr.cpp:1246
genvironment.h
gstr.h
G::StringArray
std::vector< std::string > StringArray
A std::vector of std::strings.
Definition: gstrings.h:31