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