Renderer, ...: use PixelRect::GetCenter()
[xcsoar.git] / src / Profile / ProfileMap.cpp
blob5d9acc81de5ed5173436a45844c9d1c6414cae00
1 /*
2 Copyright_License {
4 XCSoar Glide Computer - http://www.xcsoar.org/
5 Copyright (C) 2000-2013 The XCSoar Project
6 A detailed list of copyright holders can be found in the file "AUTHORS".
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include "Profile/ProfileMap.hpp"
25 #include "IO/KeyValueFileWriter.hpp"
26 #include "Util/StringUtil.hpp"
27 #include "Util/NumberParser.hpp"
28 #include "Util/Macros.hpp"
30 #include <map>
31 #include <string>
33 #ifdef _UNICODE
34 #include <windows.h>
35 #endif
37 namespace Profile {
38 typedef std::map<std::string, std::string> map_t;
40 static map_t map;
41 static bool modified;
44 bool
45 Profile::IsModified()
47 return modified;
50 void
51 Profile::SetModified(bool _modified)
53 modified = _modified;
56 const char *
57 Profile::Get(const char *key, const char *default_value)
59 map_t::const_iterator it = map.find(key);
60 if (it == map.end())
61 return default_value;
63 return it->second.c_str();
66 bool
67 Profile::Get(const char *key, TCHAR *value, size_t max_size)
69 map_t::const_iterator it = map.find(key);
70 if (it == map.end()) {
71 value[0] = _T('\0');
72 return false;
75 const char *src = it->second.c_str();
77 #ifdef _UNICODE
78 int result = MultiByteToWideChar(CP_UTF8, 0, src, -1,
79 value, max_size);
80 return result > 0;
81 #else
82 if (!ValidateUTF8(src))
83 return false;
85 CopyString(value, src, max_size);
86 return true;
87 #endif
90 bool
91 Profile::Get(const char *key, int &value)
93 // Try to read the profile map
94 const char *str = Get(key);
95 if (str == NULL)
96 return false;
98 // Parse the string for a number
99 char *endptr;
100 int tmp = ParseInt(str, &endptr, 0);
101 if (endptr == str)
102 return false;
104 // Save parsed value to output parameter value and return success
105 value = tmp;
106 return true;
109 bool
110 Profile::Get(const char *key, short &value)
112 // Try to read the profile map
113 const char *str = Get(key);
114 if (str == NULL)
115 return false;
117 // Parse the string for a number
118 char *endptr;
119 short tmp = ParseInt(str, &endptr, 0);
120 if (endptr == str)
121 return false;
123 // Save parsed value to output parameter value and return success
124 value = tmp;
125 return true;
128 bool
129 Profile::Get(const char *key, bool &value)
131 // Try to read the profile map
132 const char *str = Get(key);
133 if (str == NULL)
134 return false;
136 // Save value to output parameter value and return success
137 value = (str[0] != '0');
138 return true;
141 bool
142 Profile::Get(const char *key, unsigned &value)
144 // Try to read the profile map
145 const char *str = Get(key);
146 if (str == NULL)
147 return false;
149 // Parse the string for a unsigned number
150 char *endptr;
151 unsigned tmp = ParseUnsigned(str, &endptr, 0);
152 if (endptr == str)
153 return false;
155 // Save parsed value to output parameter value and return success
156 value = tmp;
157 return true;
160 bool
161 Profile::Get(const char *key, uint16_t &value)
163 unsigned value32;
164 if (!Get(key, value32) || value32 >= 0x10000)
165 return false;
167 value = (uint16_t)value32;
168 return true;
171 bool
172 Profile::Get(const char *key, uint8_t &value)
174 unsigned value32;
175 if (!Get(key, value32) || value32 >= 0x100)
176 return false;
178 value = (uint8_t)value32;
179 return true;
182 bool
183 Profile::Get(const char *key, fixed &value)
185 // Try to read the profile map
186 const char *str = Get(key);
187 if (str == nullptr)
188 return false;
190 // Parse the string for a floating point number
191 char *endptr;
192 double tmp = ParseDouble(str, &endptr);
193 if (endptr == str)
194 return false;
196 // Save parsed value to output parameter value and return success
197 value = fixed(tmp);
198 return true;
201 void
202 Profile::Set(const char *key, const char *value)
204 auto i = map.insert(std::make_pair(key, value));
205 if (!i.second) {
206 /* exists already */
208 if (i.first->second.compare(value) == 0)
209 /* not modified, don't set the "modified" flag */
210 return;
212 i.first->second.assign(value);
215 modified = true;
218 #ifdef _UNICODE
220 void
221 Profile::Set(const char *key, const TCHAR *value)
223 char buffer[MAX_PATH];
224 int length = WideCharToMultiByte(CP_UTF8, 0, value, -1,
225 buffer, ARRAY_SIZE(buffer),
226 nullptr, nullptr);
227 if (length <= 0)
228 return;
230 Set(key, buffer);
233 #endif
235 void
236 Profile::Set(const char *key, int value)
238 char tmp[50];
239 sprintf(tmp, "%d", value);
240 return Set(key, tmp);
243 void
244 Profile::Set(const char *key, long value)
246 char tmp[50];
247 sprintf(tmp, "%ld", value);
248 return Set(key, tmp);
251 void
252 Profile::Set(const char *key, unsigned value)
254 char tmp[50];
255 sprintf(tmp, "%u", value);
256 return Set(key, tmp);
259 void
260 Profile::Set(const char *key, fixed value)
262 char tmp[50];
263 sprintf(tmp, "%f", (double)value);
264 return Set(key, tmp);
267 bool
268 Profile::Exists(const char *key)
270 return map.find(key) != map.end();
273 void
274 Profile::Export(KeyValueFileWriter &writer)
276 // Iterate through the profile maps
277 for (auto it_str = map.begin(); it_str != map.end(); it_str++)
278 /* ignore the "Vega*" values; the Vega driver abuses the profile
279 to pass messages between the driver and the user interface */
280 if (strncmp(it_str->first.c_str(), "Vega", 4) != 0)
281 writer.Write(it_str->first.c_str(), it_str->second.c_str());
284 void
285 Profile::Clear()
287 map.clear();