PageRenderTime 50ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/labo/2009.08.17/poco-1.3.5/Foundation/src/Format.cpp

http://mingw-lib.googlecode.com/
C++ | 375 lines | 283 code | 45 blank | 47 comment | 73 complexity | fe2251359f38ac25a64ac7bd6607f0ee MD5 | raw file
Possible License(s): GPL-2.0, GPL-3.0, MPL-2.0-no-copyleft-exception
  1. //
  2. // Format.cpp
  3. //
  4. // $Id: //poco/1.3/Foundation/src/Format.cpp#6 $
  5. //
  6. // Library: Foundation
  7. // Package: Core
  8. // Module: Format
  9. //
  10. // Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
  11. // All rights reserved.
  12. //
  13. // Redistribution and use in source and binary forms, with or without
  14. // modification, are permitted provided that the following conditions
  15. // are met:
  16. //
  17. // 1. Redistributions of source code must retain the above copyright
  18. // notice, this list of conditions and the following disclaimer.
  19. //
  20. // 2. Redistributions in binary form must reproduce the above copyright
  21. // notice, this list of conditions and the following disclaimer in the
  22. // documentation and/or other materials provided with the distribution.
  23. //
  24. // 3. Redistributions in any form must be accompanied by information on
  25. // how to obtain complete source code for this software and any
  26. // accompanying software that uses this software. The source code
  27. // must either be included in the distribution or be available for no
  28. // more than the cost of distribution plus a nominal fee, and must be
  29. // freely redistributable under reasonable conditions. For an
  30. // executable file, complete source code means the source code for all
  31. // modules it contains. It does not include source code for modules or
  32. // files that typically accompany the major components of the operating
  33. // system on which the executable file runs.
  34. //
  35. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  36. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  37. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  38. // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  39. // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  40. // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  41. // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42. // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  43. // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  44. // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  45. // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  46. // POSSIBILITY OF SUCH DAMAGE.
  47. //
  48. #include "Poco/Format.h"
  49. #include "Poco/Exception.h"
  50. #include <sstream>
  51. #include <cctype>
  52. #include <cstddef>
  53. namespace Poco {
  54. namespace
  55. {
  56. void parseFlags(std::ostream& str, std::string::const_iterator& itFmt, const std::string::const_iterator& endFmt)
  57. {
  58. bool isFlag = true;
  59. while (isFlag && itFmt != endFmt)
  60. {
  61. switch (*itFmt)
  62. {
  63. case '-': str.setf(std::ios::left); ++itFmt; break;
  64. case '+': str.setf(std::ios::showpos); ++itFmt; break;
  65. case '0': str.fill('0'); ++itFmt; break;
  66. case '#': str.setf(std::ios::showpoint | std::ios_base::showbase); ++itFmt; break;
  67. default: isFlag = false; break;
  68. }
  69. }
  70. }
  71. void parseWidth(std::ostream& str, std::string::const_iterator& itFmt, const std::string::const_iterator& endFmt)
  72. {
  73. int width = 0;
  74. while (itFmt != endFmt && std::isdigit(*itFmt))
  75. {
  76. width = 10*width + *itFmt - '0';
  77. ++itFmt;
  78. }
  79. if (width != 0) str.width(width);
  80. }
  81. void parsePrec(std::ostream& str, std::string::const_iterator& itFmt, const std::string::const_iterator& endFmt)
  82. {
  83. if (itFmt != endFmt && *itFmt == '.')
  84. {
  85. ++itFmt;
  86. int prec = 0;
  87. while (itFmt != endFmt && std::isdigit(*itFmt))
  88. {
  89. prec = 10*prec + *itFmt - '0';
  90. ++itFmt;
  91. }
  92. if (prec != 0) str.precision(prec);
  93. }
  94. }
  95. char parseMod(std::string::const_iterator& itFmt, const std::string::const_iterator& endFmt)
  96. {
  97. char mod = 0;
  98. if (itFmt != endFmt)
  99. {
  100. switch (*itFmt)
  101. {
  102. case 'l':
  103. case 'h':
  104. case 'L':
  105. case '?': mod = *itFmt++; break;
  106. }
  107. }
  108. return mod;
  109. }
  110. void prepareFormat(std::ostream& str, char type)
  111. {
  112. switch (type)
  113. {
  114. case 'd':
  115. case 'i': str << std::dec; break;
  116. case 'o': str << std::oct; break;
  117. case 'x': str << std::hex; break;
  118. case 'X': str << std::hex << std::uppercase; break;
  119. case 'e': str << std::scientific; break;
  120. case 'E': str << std::scientific << std::uppercase; break;
  121. case 'f': str << std::fixed; break;
  122. }
  123. }
  124. void writeAnyInt(std::ostream& str, const Any& any)
  125. {
  126. if (any.type() == typeid(char))
  127. str << static_cast<int>(AnyCast<char>(any));
  128. else if (any.type() == typeid(signed char))
  129. str << static_cast<int>(AnyCast<signed char>(any));
  130. else if (any.type() == typeid(unsigned char))
  131. str << static_cast<unsigned>(AnyCast<unsigned char>(any));
  132. else if (any.type() == typeid(short))
  133. str << AnyCast<short>(any);
  134. else if (any.type() == typeid(unsigned short))
  135. str << AnyCast<unsigned short>(any);
  136. else if (any.type() == typeid(int))
  137. str << AnyCast<int>(any);
  138. else if (any.type() == typeid(unsigned int))
  139. str << AnyCast<unsigned int>(any);
  140. else if (any.type() == typeid(long))
  141. str << AnyCast<long>(any);
  142. else if (any.type() == typeid(unsigned long))
  143. str << AnyCast<unsigned long>(any);
  144. else if (any.type() == typeid(Int64))
  145. str << AnyCast<Int64>(any);
  146. else if (any.type() == typeid(UInt64))
  147. str << AnyCast<UInt64>(any);
  148. else if (any.type() == typeid(bool))
  149. str << AnyCast<bool>(any);
  150. }
  151. void formatOne(std::string& result, std::string::const_iterator& itFmt, const std::string::const_iterator& endFmt, std::vector<Any>::const_iterator& itVal)
  152. {
  153. std::ostringstream str;
  154. parseFlags(str, itFmt, endFmt);
  155. parseWidth(str, itFmt, endFmt);
  156. parsePrec(str, itFmt, endFmt);
  157. char mod = parseMod(itFmt, endFmt);
  158. if (itFmt != endFmt)
  159. {
  160. char type = *itFmt++;
  161. prepareFormat(str, type);
  162. switch (type)
  163. {
  164. case 'b':
  165. str << AnyCast<bool>(*itVal++);
  166. break;
  167. case 'c':
  168. str << AnyCast<char>(*itVal++);
  169. break;
  170. case 'd':
  171. case 'i':
  172. switch (mod)
  173. {
  174. case 'l': str << AnyCast<long>(*itVal++); break;
  175. case 'L': str << AnyCast<Int64>(*itVal++); break;
  176. case 'h': str << AnyCast<short>(*itVal++); break;
  177. case '?': writeAnyInt(str, *itVal++); break;
  178. default: str << AnyCast<int>(*itVal++); break;
  179. }
  180. break;
  181. case 'o':
  182. case 'u':
  183. case 'x':
  184. case 'X':
  185. switch (mod)
  186. {
  187. case 'l': str << AnyCast<unsigned long>(*itVal++); break;
  188. case 'L': str << AnyCast<UInt64>(*itVal++); break;
  189. case 'h': str << AnyCast<unsigned short>(*itVal++); break;
  190. case '?': writeAnyInt(str, *itVal++); break;
  191. default: str << AnyCast<unsigned>(*itVal++); break;
  192. }
  193. break;
  194. case 'e':
  195. case 'E':
  196. case 'f':
  197. switch (mod)
  198. {
  199. case 'l': str << AnyCast<long double>(*itVal++); break;
  200. case 'L': str << AnyCast<long double>(*itVal++); break;
  201. case 'h': str << AnyCast<float>(*itVal++); break;
  202. default: str << AnyCast<double>(*itVal++); break;
  203. }
  204. break;
  205. case 's':
  206. str << RefAnyCast<std::string>(*itVal++);
  207. break;
  208. case 'z':
  209. str << AnyCast<std::size_t>(*itVal++);
  210. break;
  211. case 'I':
  212. case 'D':
  213. default:
  214. str << type;
  215. }
  216. }
  217. result.append(str.str());
  218. }
  219. }
  220. std::string format(const std::string& fmt, const Any& value)
  221. {
  222. std::string result;
  223. format(result, fmt, value);
  224. return result;
  225. }
  226. std::string format(const std::string& fmt, const Any& value1, const Any& value2)
  227. {
  228. std::string result;
  229. format(result, fmt, value1, value2);
  230. return result;
  231. }
  232. std::string format(const std::string& fmt, const Any& value1, const Any& value2, const Any& value3)
  233. {
  234. std::string result;
  235. format(result, fmt, value1, value2, value3);
  236. return result;
  237. }
  238. std::string format(const std::string& fmt, const Any& value1, const Any& value2, const Any& value3, const Any& value4)
  239. {
  240. std::string result;
  241. format(result, fmt, value1, value2, value3, value4);
  242. return result;
  243. }
  244. std::string format(const std::string& fmt, const Any& value1, const Any& value2, const Any& value3, const Any& value4, const Any& value5)
  245. {
  246. std::string result;
  247. format(result, fmt, value1, value2, value3, value4, value5);
  248. return result;
  249. }
  250. std::string format(const std::string& fmt, const Any& value1, const Any& value2, const Any& value3, const Any& value4, const Any& value5, const Any& value6)
  251. {
  252. std::string result;
  253. format(result, fmt, value1, value2, value3, value4, value5, value6);
  254. return result;
  255. }
  256. void format(std::string& result, const std::string& fmt, const Any& value)
  257. {
  258. std::vector<Any> args;
  259. args.push_back(value);
  260. format(result, fmt, args);
  261. }
  262. void format(std::string& result, const std::string& fmt, const Any& value1, const Any& value2)
  263. {
  264. std::vector<Any> args;
  265. args.push_back(value1);
  266. args.push_back(value2);
  267. format(result, fmt, args);
  268. }
  269. void format(std::string& result, const std::string& fmt, const Any& value1, const Any& value2, const Any& value3)
  270. {
  271. std::vector<Any> args;
  272. args.push_back(value1);
  273. args.push_back(value2);
  274. args.push_back(value3);
  275. format(result, fmt, args);
  276. }
  277. void format(std::string& result, const std::string& fmt, const Any& value1, const Any& value2, const Any& value3, const Any& value4)
  278. {
  279. std::vector<Any> args;
  280. args.push_back(value1);
  281. args.push_back(value2);
  282. args.push_back(value3);
  283. args.push_back(value4);
  284. format(result, fmt, args);
  285. }
  286. void format(std::string& result, const std::string& fmt, const Any& value1, const Any& value2, const Any& value3, const Any& value4, const Any& value5)
  287. {
  288. std::vector<Any> args;
  289. args.push_back(value1);
  290. args.push_back(value2);
  291. args.push_back(value3);
  292. args.push_back(value4);
  293. args.push_back(value5);
  294. format(result, fmt, args);
  295. }
  296. void format(std::string& result, const std::string& fmt, const Any& value1, const Any& value2, const Any& value3, const Any& value4, const Any& value5, const Any& value6)
  297. {
  298. std::vector<Any> args;
  299. args.push_back(value1);
  300. args.push_back(value2);
  301. args.push_back(value3);
  302. args.push_back(value4);
  303. args.push_back(value5);
  304. args.push_back(value6);
  305. format(result, fmt, args);
  306. }
  307. void format(std::string& result, const std::string& fmt, const std::vector<Any>& values)
  308. {
  309. std::string::const_iterator itFmt = fmt.begin();
  310. std::string::const_iterator endFmt = fmt.end();
  311. std::vector<Any>::const_iterator itVal = values.begin();
  312. std::vector<Any>::const_iterator endVal = values.end();
  313. while (itFmt != endFmt)
  314. {
  315. switch (*itFmt)
  316. {
  317. case '%':
  318. ++itFmt;
  319. if (itFmt != endFmt && itVal != endVal)
  320. formatOne(result, itFmt, endFmt, itVal);
  321. else if (itFmt != endFmt)
  322. result += *itFmt++;
  323. break;
  324. default:
  325. result += *itFmt;
  326. ++itFmt;
  327. }
  328. }
  329. }
  330. } // namespace Poco