ManaPlus
Data Structures | Namespaces | Functions | Variables
unitsdb.cpp File Reference

(986a3bf)

#include "resources/db/unitsdb.h"
#include "configuration.h"
#include "const/resources/currency.h"
#include "utils/cast.h"
#include "utils/checkutils.h"
#include "utils/stdmove.h"
#include "resources/beingcommon.h"
#include <climits>
#include "debug.h"

Go to the source code of this file.

Data Structures

struct  anonymous_namespace{unitsdb.cpp}::UnitLevel
 
struct  anonymous_namespace{unitsdb.cpp}::UnitDescription
 

Namespaces

 anonymous_namespace{unitsdb.cpp}
 

Functions

static std::string formatUnit (const int value, const UnitDescription &ud)
 
static std::string splitNumber (std::string str, const std::string &separator)
 
static UnitDescription loadUnit (xmlNodePtr node)
 
static void loadCurrencies (xmlNodePtr parentNode)
 

Variables

UnitDescription anonymous_namespace{unitsdb.cpp}::defaultCurrency
 
UnitDescription anonymous_namespace{unitsdb.cpp}::defaultWeight
 
std::map< std::string, UnitDescription > anonymous_namespace{unitsdb.cpp}::mCurrencies
 

Function Documentation

◆ formatUnit()

static std::string formatUnit ( const int  value,
const UnitDescription &  ud 
)
static

Definition at line 247 of file unitsdb.cpp.

249 {
250  UnitLevel ul;
251 
252  // Shortcut for 0; do the same for values less than 0 (for now)
253  if (value <= 0)
254  {
255  ul = ud.levels[0];
256  return strprintf("0%s", ul.symbol.c_str());
257  }
258 
259  double amount = ud.conversion * value;
260  const unsigned int sz = CAST_U32(ud.levels.size());
261 
262  // If only the first level is needed, act like mix if false
263  if (ud.mix && !ud.levels.empty() && ud.levels[1].count < amount)
264  {
265  std::string output;
266  UnitLevel pl = ud.levels[0];
267  ul = ud.levels[1];
268  int levelAmount = CAST_S32(amount);
269  int nextAmount = 0;
270 
271  if (ul.count != 0)
272  levelAmount /= ul.count;
273 
274  amount -= static_cast<double>(levelAmount * ul.count);
275 
276  if (amount > 0)
277  {
278  output = splitNumber(strprintf("%.*f", pl.round,
279  amount), pl.separator).append(pl.symbol);
280  }
281 
282  for (unsigned int i = 2; i < sz; i++)
283  {
284  pl = ul;
285  ul = ud.levels[i];
286 
287  if (ul.count != 0)
288  {
289  nextAmount = levelAmount / ul.count;
290  levelAmount %= ul.count;
291  }
292 
293  if (levelAmount > 0)
294  {
295  output = splitNumber(strprintf("%d", levelAmount),
296  pl.separator).append(pl.symbol).append(output);
297  }
298 
299  if (nextAmount == 0)
300  break;
301  levelAmount = nextAmount;
302  }
303 
304  return output;
305  }
306 
307  ul.round = 0;
308  for (unsigned int i = 0; i < sz; i++)
309  {
310  ul = ud.levels[i];
311  if (amount < ul.count && ul.count > 0)
312  {
313  ul = ud.levels[i - 1];
314  break;
315  }
316  if (ul.count != 0)
317  amount /= ul.count;
318  }
319 
320  return splitNumber(strprintf("%.*f", ul.round, amount),
321  ul.separator).append(ul.symbol);
322 }
#define CAST_S32
Definition: cast.h:30
#define CAST_U32
Definition: cast.h:31
std::string strprintf(const char *const format,...)
static std::string splitNumber(std::string str, const std::string &separator)
Definition: unitsdb.cpp:362

References CAST_S32, CAST_U32, splitNumber(), and strprintf().

Referenced by UnitsDb::formatCurrency(), UnitsDb::formatCurrency64(), and UnitsDb::formatWeight().

◆ loadCurrencies()

static void loadCurrencies ( xmlNodePtr  parentNode)
static

Definition at line 181 of file unitsdb.cpp.

182 {
183  for_each_xml_child_node(node, parentNode)
184  {
185  if (xmlNameEqual(node, "unit"))
186  {
187  const std::string name = XML::getProperty(node, "name", "");
188  if (name.empty())
189  {
190  reportAlways("Error: unknown currency name.")
191  continue;
192  }
193  mCurrencies[name] = loadUnit(node);
194  if (name == DEFAULT_CURRENCY)
196  }
197  }
198 }
#define reportAlways(...)
Definition: checkutils.h:253
const std::string DEFAULT_CURRENCY
Definition: currency.h:27
if(!vert) return
#define for_each_xml_child_node(var, parent)
Definition: libxml.h:161
int getProperty(const xmlNodePtr node, const char *const name, int def)
Definition: libxml.cpp:174
std::map< std::string, UnitDescription > mCurrencies
Definition: unitsdb.cpp:64
UnitDescription defaultCurrency
Definition: unitsdb.cpp:61
static UnitDescription loadUnit(xmlNodePtr node)
Definition: unitsdb.cpp:126

References DEFAULT_CURRENCY, anonymous_namespace{unitsdb.cpp}::defaultCurrency, for_each_xml_child_node, XML::getProperty(), loadUnit(), anonymous_namespace{unitsdb.cpp}::mCurrencies, and reportAlways.

Referenced by UnitsDb::loadXmlFile().

◆ loadUnit()

static UnitDescription loadUnit ( xmlNodePtr  node)
static

Definition at line 126 of file unitsdb.cpp.

127 {
128  UnitDescription ud;
129  int level = 1;
130  ud.conversion = XML::getProperty(node, "conversion", 1);
131  ud.mix = XML::getProperty(node, "mix", "no") == "yes";
132 
133  UnitLevel bu;
134  bu.symbol = XML::getProperty(node, "base", "¤");
135  bu.count = 1;
136  bu.round = XML::getProperty(node, "round", 2);
137  bu.separator = XML::getProperty(node, "separator", " ");
138 
139  ud.levels.push_back(bu);
140 
141  for_each_xml_child_node(uLevel, node)
142  {
143  if (xmlNameEqual(uLevel, "level"))
144  {
145  const UnitLevel ul =
146  {
147  XML::getProperty(uLevel, "symbol",
148  strprintf("¤%d", level)),
149  XML::getProperty(uLevel, "count", -1),
150  XML::getProperty(uLevel, "round", bu.round),
151  XML::getProperty(uLevel, "separator", bu.separator)
152  };
153 
154  if (ul.count > 0)
155  {
156  ud.levels.push_back(ul);
157  level++;
158  }
159  else
160  {
161  logger->log("Error bad unit count: %d for %s in %s",
162  ul.count,
163  ul.symbol.c_str(),
164  bu.symbol.c_str());
165  }
166  }
167  }
168 
169  // Add one more level for saftey
170  const UnitLevel lev =
171  {
172  "",
173  INT_MAX,
174  0,
175  ""
176  };
177  ud.levels.push_back(lev);
178  return ud;
179 }
void log(const char *const log_text,...)
Definition: logger.cpp:269
Logger * logger
Definition: logger.cpp:89

References for_each_xml_child_node, XML::getProperty(), Logger::log(), logger, and strprintf().

Referenced by loadCurrencies(), and UnitsDb::loadXmlFile().

◆ splitNumber()

static std::string splitNumber ( std::string  str,
const std::string &  separator 
)
static

Definition at line 362 of file unitsdb.cpp.

364 {
365  std::string lastPart;
366  const size_t point = str.find('.');
367  if (point != std::string::npos)
368  {
369  lastPart = str.substr(point);
370  str = str.substr(0, point);
371  }
372  std::string result;
373 
374  if (!str.empty())
375  {
376  size_t sz = str.size();
377  while (sz >= 3)
378  {
379  if (sz >= 6)
380  {
381  result = std::string(separator).append(str.substr(
382  sz - 3)).append(result);
383  }
384  else
385  {
386  result = str.substr(sz - 3).append(result);
387  }
388  str = str.substr(0, str.size() - 3);
389  sz = str.size();
390  }
391  if (!str.empty())
392  {
393  if (!result.empty())
394  result = std::string(str).append(separator).append(result);
395  else
396  result = STD_MOVE(str);
397  }
398  }
399 
400  return result + lastPart;
401 }
#define STD_MOVE(var)
Definition: stdmove.h:28

References STD_MOVE.

Referenced by formatUnit().