E-MailRelay
gmapfile.h
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 gmapfile.h
19///
20
21#ifndef G_MAP_FILE_H
22#define G_MAP_FILE_H
23
24#include "gdef.h"
25#include "gpath.h"
26#include "gstringarray.h"
27#include "gstringmap.h"
28#include "gstringview.h"
29#include "gexception.h"
30#include "goptions.h"
31#include "goptionvalue.h"
32#include "goptionmap.h"
33#include <string>
34#include <utility>
35#include <iostream>
36#include <vector>
37
38namespace G
39{
40 class MapFile ;
41}
42
43//| \class G::MapFile
44/// A class for reading, writing and editing key=value files,
45/// supporting variable expansion of percent-key-percent values,
46/// comments, creation of backup files, and logging.
47///
48/// Also supports initialisation from a G::OptionMap, containing
49/// G::OptionValue values. See also G::OptionParser.
50///
51/// Values containing whitespace are/can-be simply quoted with
52/// initial and terminal double-quote characters, but with no
53/// special handling of escapes or embedded quotes. For full
54/// transparency values must not start with whitespace or '=',
55/// must not end with whitespace, must not start-and-end with
56/// double-quotes, must not contain commas, and should not
57/// contain percent characters if using expand() methods.
58///
60{
61public:
62 struct Error : public Exception /// Exception class for G::MapFile.
63 {
65 } ;
66
68 ///< Constructor for an empty map.
69
70 explicit MapFile( const StringMap & map ) ;
71 ///< Constructor that initialises from a string map.
72
73 explicit MapFile( const OptionMap & map , std::string_view yes = {} ) ;
74 ///< Constructor that initialises from an option value map,
75 ///< typically parsed out from a command-line. Unvalued 'on'
76 ///< options in the option value map are loaded into this
77 ///< mapfile object with a value given by the 'yes' parameter,
78 ///< whereas unvalued 'off' options are not loaded at all.
79 ///< Multi-valued options are loaded as a comma-separated
80 ///< list.
81
82 explicit MapFile( const Path & , std::string_view kind = {} ) ;
83 ///< Constructor that reads from a file. Lines can have a key
84 ///< and no value (see booleanValue()). Comments must be at
85 ///< the start of the line. Values are left and right-trimmed,
86 ///< but can otherwise contain whitespace. The trailing parameter
87 ///< is used in error messages to describe the kind of file,
88 ///< defaulting to "map".
89
90 MapFile( const Path & , std::string_view kind , std::nothrow_t ) ;
91 ///< A non-throwing overload that reads from a file and
92 ///< ignores any errors.
93
94 explicit MapFile( std::istream & ) ;
95 ///< Constructor that reads from a stream.
96
97 const StringArray & keys() const ;
98 ///< Returns a reference to the internal ordered list of keys.
99
100 void add( std::string_view key , std::string_view value , bool clear = false ) ;
101 ///< Adds or updates a single item in the map.
102 ///< If updating then by default the new value
103 ///< is appended with a comma separator.
104
105 bool update( std::string_view key , std::string_view value ) ;
106 ///< Updates an existing value. Returns false if not
107 ///< found.
108
109 bool remove( std::string_view key ) ;
110 ///< Removes a value (if it exists).
111
112 void writeItem( std::ostream & , std::string_view key ) const ;
113 ///< Writes a single item from this map to the stream.
114
115 static void writeItem( std::ostream & , std::string_view key , std::string_view value ) ;
116 ///< Writes an arbitrary item to the stream.
117
118 Path editInto( const Path & path , bool make_backup , bool do_throw = true ) const ;
119 ///< Edits an existing file so that its contents reflect
120 ///< this map. Returns the path of the backup file, if
121 ///< created.
122
123 bool contains( std::string_view key ) const ;
124 ///< Returns true if the map contains the given key.
125
126 Path pathValue( std::string_view key ) const ;
127 ///< Returns a mandatory path value from the map.
128 ///< Throws if it does not exist.
129
130 Path pathValue( std::string_view key , const Path & default_ ) const ;
131 ///< Returns a path value from the map.
132
133 unsigned int numericValue( std::string_view key , unsigned int default_ ) const ;
134 ///< Returns a numeric value from the map.
135
136 std::string value( std::string_view key , std::string_view default_ = {} ) const ;
137 ///< Returns a string value from the map. Returns the default
138 ///< if there is no such key or if the value is empty.
139
140 bool valueContains( std::string_view key , std::string_view token , std::string_view default_ = {} ) const ;
141 ///< Returns true if value(key,default_) contains the given
142 ///< comma-separated token.
143
144 bool booleanValue( std::string_view key , bool default_ ) const ;
145 ///< Returns a boolean value from the map. Returns true if
146 ///< the key exists with an empty value. Returns the default
147 ///< if no such key.
148
149 const StringMap & map() const ;
150 ///< Returns a reference to the internal map.
151
152 void log( const std::string & prefix = {} ) const ;
153 ///< Logs the contents.
154
155 std::string expand( std::string_view value ) const ;
156 ///< Does one-pass variable substitution for the given string.
157 ///< Sub-strings like "%xyz%" are replaced by 'value("xyz")'
158 ///< and "%%" is replaced by "%". If there is no appropriate
159 ///< value in the map then the sub-string is left alone
160 ///< (so "%xyz%" remains as "%xyz%" if there is no "xyz"
161 ///< map item).
162
163 Path expandedPathValue( std::string_view key ) const ;
164 ///< Returns a mandatory path value from the map
165 ///< with expand(). Throws if it does not exist.
166
167 Path expandedPathValue( std::string_view key , const Path & default_ ) const ;
168 ///< Returns a path value from the map with expand().
169
170private:
171 using List = std::vector<std::string> ;
172 void readFromFile( const Path & , std::string_view , bool do_throw = true ) ;
173 void readFromStream( std::istream & ss ) ;
174 List readLines( const Path & , std::string_view , bool do_throw ) const ;
175 static std::pair<std::string_view,std::string_view> split( std::string_view ) ;
176 static std::string join( std::string_view , std::string_view ) ;
177 static std::string quote( const std::string & ) ;
178 bool expand_( std::string & ) const ;
179 std::string mandatoryValue( std::string_view ) const ;
180 static bool valued( const std::string & ) ;
181 static bool commentedOut( const std::string & ) ;
182 static std::string strkind( std::string_view ) ;
183 static std::string strpath( const Path & ) ;
184 static Error readError( const Path & , std::string_view ) ;
185 static Error writeError( const Path & , std::string_view = {} ) ;
186 static Error missingValueError( const Path & , const std::string & , const std::string & ) ;
187 StringMap::const_iterator find( std::string_view ) const ;
188 StringMap::iterator find( std::string_view ) ;
189 static Path toPath( std::string_view ) ;
190
191private:
192 Path m_path ; // if any
193 std::string m_kind ;
194 StringMap m_map ;
195 StringArray m_keys ; // kept in input order
196} ;
197
198#endif
A general-purpose exception class derived from std::exception and containing an error message.
Definition: gexception.h:64
Exception(std::initializer_list< std::string_view >)
Constructor.
Definition: gexception.cpp:25
A class for reading, writing and editing key=value files, supporting variable expansion of percent-ke...
Definition: gmapfile.h:60
bool remove(std::string_view key)
Removes a value (if it exists).
Definition: gmapfile.cpp:357
unsigned int numericValue(std::string_view key, unsigned int default_) const
Returns a numeric value from the map.
Definition: gmapfile.cpp:352
Path expandedPathValue(std::string_view key) const
Returns a mandatory path value from the map with expand().
Definition: gmapfile.cpp:327
std::string value(std::string_view key, std::string_view default_={}) const
Returns a string value from the map.
Definition: gmapfile.cpp:297
bool valueContains(std::string_view key, std::string_view token, std::string_view default_={}) const
Returns true if value(key,default_) contains the given comma-separated token.
Definition: gmapfile.cpp:303
bool update(std::string_view key, std::string_view value)
Updates an existing value.
Definition: gmapfile.cpp:461
std::string expand(std::string_view value) const
Does one-pass variable substitution for the given string.
Definition: gmapfile.cpp:373
bool booleanValue(std::string_view key, bool default_) const
Returns a boolean value from the map.
Definition: gmapfile.cpp:280
const StringMap & map() const
Returns a reference to the internal map.
Definition: gmapfile.cpp:490
Path editInto(const Path &path, bool make_backup, bool do_throw=true) const
Edits an existing file so that its contents reflect this map.
Definition: gmapfile.cpp:222
void add(std::string_view key, std::string_view value, bool clear=false)
Adds or updates a single item in the map.
Definition: gmapfile.cpp:443
bool contains(std::string_view key) const
Returns true if the map contains the given key.
Definition: gmapfile.cpp:485
MapFile()
Constructor for an empty map.
const StringArray & keys() const
Returns a reference to the internal ordered list of keys.
Definition: gmapfile.cpp:495
void writeItem(std::ostream &, std::string_view key) const
Writes a single item from this map to the stream.
Definition: gmapfile.cpp:207
void log(const std::string &prefix={}) const
Logs the contents.
Definition: gmapfile.cpp:191
Path pathValue(std::string_view key) const
Returns a mandatory path value from the map.
Definition: gmapfile.cpp:337
A multimap-like container for command-line options and their values.
Definition: goptionmap.h:44
A Path object represents a file system path.
Definition: gpath.h:82
Low-level classes.
Definition: garg.h:36
std::vector< std::string > StringArray
A std::vector of std::strings.
Definition: gstringarray.h:30
std::map< std::string, std::string > StringMap
A std::map of std::strings.
Definition: gstringmap.h:30
Exception class for G::MapFile.
Definition: gmapfile.h:63