PageRenderTime 58ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

/zzzCode/3rdParty/poco/Foundation/src/Format.cpp

https://bitbucket.org/zhexiwang/zzz
C++ | 404 lines | 325 code | 45 blank | 34 comment | 83 complexity | 5202ed56fd73d8841531b282b2a06044 MD5 | raw file
  1. //
  2. // Format.cpp
  3. //
  4. // $Id: //poco/1.4/Foundation/src/Format.cpp#7 $
  5. //
  6. // Library: Foundation
  7. // Package: Core
  8. // Module: Format
  9. //
  10. // Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
  11. // and Contributors.
  12. //
  13. // Permission is hereby granted, free of charge, to any person or organization
  14. // obtaining a copy of the software and accompanying documentation covered by
  15. // this license (the "Software") to use, reproduce, display, distribute,
  16. // execute, and transmit the Software, and to prepare derivative works of the
  17. // Software, and to permit third-parties to whom the Software is furnished to
  18. // do so, all subject to the following:
  19. //
  20. // The copyright notices in the Software and this entire statement, including
  21. // the above license grant, this restriction and the following disclaimer,
  22. // must be included in all copies of the Software, in whole or in part, and
  23. // all derivative works of the Software, unless such copies or derivative
  24. // works are solely in the form of machine-executable object code generated by
  25. // a source language processor.
  26. //
  27. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  28. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  29. // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
  30. // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
  31. // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
  32. // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  33. // DEALINGS IN THE SOFTWARE.
  34. //
  35. #include "Poco/Format.h"
  36. #include "Poco/Exception.h"
  37. #include "Poco/Ascii.h"
  38. #include <sstream>
  39. #if !defined(POCO_NO_LOCALE)
  40. #include <locale>
  41. #endif
  42. #include <cstddef>
  43. namespace Poco {
  44. namespace
  45. {
  46. void parseFlags(std::ostream& str, std::string::const_iterator& itFmt, const std::string::const_iterator& endFmt)
  47. {
  48. bool isFlag = true;
  49. while (isFlag && itFmt != endFmt)
  50. {
  51. switch (*itFmt)
  52. {
  53. case '-': str.setf(std::ios::left); ++itFmt; break;
  54. case '+': str.setf(std::ios::showpos); ++itFmt; break;
  55. case '0': str.fill('0'); str.setf(std::ios::internal); ++itFmt; break;
  56. case '#': str.setf(std::ios::showpoint | std::ios::showbase); ++itFmt; break;
  57. default: isFlag = false; break;
  58. }
  59. }
  60. }
  61. void parseWidth(std::ostream& str, std::string::const_iterator& itFmt, const std::string::const_iterator& endFmt)
  62. {
  63. int width = 0;
  64. while (itFmt != endFmt && Ascii::isDigit(*itFmt))
  65. {
  66. width = 10*width + *itFmt - '0';
  67. ++itFmt;
  68. }
  69. if (width != 0) str.width(width);
  70. }
  71. void parsePrec(std::ostream& str, std::string::const_iterator& itFmt, const std::string::const_iterator& endFmt)
  72. {
  73. if (itFmt != endFmt && *itFmt == '.')
  74. {
  75. ++itFmt;
  76. int prec = 0;
  77. while (itFmt != endFmt && Ascii::isDigit(*itFmt))
  78. {
  79. prec = 10*prec + *itFmt - '0';
  80. ++itFmt;
  81. }
  82. if (prec >= 0) str.precision(prec);
  83. }
  84. }
  85. char parseMod(std::string::const_iterator& itFmt, const std::string::const_iterator& endFmt)
  86. {
  87. char mod = 0;
  88. if (itFmt != endFmt)
  89. {
  90. switch (*itFmt)
  91. {
  92. case 'l':
  93. case 'h':
  94. case 'L':
  95. case '?': mod = *itFmt++; break;
  96. }
  97. }
  98. return mod;
  99. }
  100. std::size_t parseIndex(std::string::const_iterator& itFmt, const std::string::const_iterator& endFmt)
  101. {
  102. int index = 0;
  103. while (itFmt != endFmt && Ascii::isDigit(*itFmt))
  104. {
  105. index = 10*index + *itFmt - '0';
  106. ++itFmt;
  107. }
  108. if (itFmt != endFmt && *itFmt == ']') ++itFmt;
  109. return index;
  110. }
  111. void prepareFormat(std::ostream& str, char type)
  112. {
  113. switch (type)
  114. {
  115. case 'd':
  116. case 'i': str << std::dec; break;
  117. case 'o': str << std::oct; break;
  118. case 'x': str << std::hex; break;
  119. case 'X': str << std::hex << std::uppercase; break;
  120. case 'e': str << std::scientific; break;
  121. case 'E': str << std::scientific << std::uppercase; break;
  122. case 'f': str << std::fixed; break;
  123. }
  124. }
  125. void writeAnyInt(std::ostream& str, const Any& any)
  126. {
  127. if (any.type() == typeid(char))
  128. str << static_cast<int>(AnyCast<char>(any));
  129. else if (any.type() == typeid(signed char))
  130. str << static_cast<int>(AnyCast<signed char>(any));
  131. else if (any.type() == typeid(unsigned char))
  132. str << static_cast<unsigned>(AnyCast<unsigned char>(any));
  133. else if (any.type() == typeid(short))
  134. str << AnyCast<short>(any);
  135. else if (any.type() == typeid(unsigned short))
  136. str << AnyCast<unsigned short>(any);
  137. else if (any.type() == typeid(int))
  138. str << AnyCast<int>(any);
  139. else if (any.type() == typeid(unsigned int))
  140. str << AnyCast<unsigned int>(any);
  141. else if (any.type() == typeid(long))
  142. str << AnyCast<long>(any);
  143. else if (any.type() == typeid(unsigned long))
  144. str << AnyCast<unsigned long>(any);
  145. else if (any.type() == typeid(Int64))
  146. str << AnyCast<Int64>(any);
  147. else if (any.type() == typeid(UInt64))
  148. str << AnyCast<UInt64>(any);
  149. else if (any.type() == typeid(bool))
  150. str << AnyCast<bool>(any);
  151. }
  152. void formatOne(std::string& result, std::string::const_iterator& itFmt, const std::string::const_iterator& endFmt, std::vector<Any>::const_iterator& itVal)
  153. {
  154. std::ostringstream str;
  155. #if !defined(POCO_NO_LOCALE)
  156. str.imbue(std::locale::classic());
  157. #endif
  158. try
  159. {
  160. parseFlags(str, itFmt, endFmt);
  161. parseWidth(str, itFmt, endFmt);
  162. parsePrec(str, itFmt, endFmt);
  163. char mod = parseMod(itFmt, endFmt);
  164. if (itFmt != endFmt)
  165. {
  166. char type = *itFmt++;
  167. prepareFormat(str, type);
  168. switch (type)
  169. {
  170. case 'b':
  171. str << AnyCast<bool>(*itVal++);
  172. break;
  173. case 'c':
  174. str << AnyCast<char>(*itVal++);
  175. break;
  176. case 'd':
  177. case 'i':
  178. switch (mod)
  179. {
  180. case 'l': str << AnyCast<long>(*itVal++); break;
  181. case 'L': str << AnyCast<Int64>(*itVal++); break;
  182. case 'h': str << AnyCast<short>(*itVal++); break;
  183. case '?': writeAnyInt(str, *itVal++); break;
  184. default: str << AnyCast<int>(*itVal++); break;
  185. }
  186. break;
  187. case 'o':
  188. case 'u':
  189. case 'x':
  190. case 'X':
  191. switch (mod)
  192. {
  193. case 'l': str << AnyCast<unsigned long>(*itVal++); break;
  194. case 'L': str << AnyCast<UInt64>(*itVal++); break;
  195. case 'h': str << AnyCast<unsigned short>(*itVal++); break;
  196. case '?': writeAnyInt(str, *itVal++); break;
  197. default: str << AnyCast<unsigned>(*itVal++); break;
  198. }
  199. break;
  200. case 'e':
  201. case 'E':
  202. case 'f':
  203. switch (mod)
  204. {
  205. case 'l': str << AnyCast<long double>(*itVal++); break;
  206. case 'L': str << AnyCast<long double>(*itVal++); break;
  207. case 'h': str << AnyCast<float>(*itVal++); break;
  208. default: str << AnyCast<double>(*itVal++); break;
  209. }
  210. break;
  211. case 's':
  212. str << RefAnyCast<std::string>(*itVal++);
  213. break;
  214. case 'z':
  215. str << AnyCast<std::size_t>(*itVal++);
  216. break;
  217. case 'I':
  218. case 'D':
  219. default:
  220. str << type;
  221. }
  222. }
  223. }
  224. catch (Poco::BadCastException&)
  225. {
  226. str << "[ERRFMT]";
  227. }
  228. result.append(str.str());
  229. }
  230. }
  231. std::string format(const std::string& fmt, const Any& value)
  232. {
  233. std::string result;
  234. format(result, fmt, value);
  235. return result;
  236. }
  237. std::string format(const std::string& fmt, const Any& value1, const Any& value2)
  238. {
  239. std::string result;
  240. format(result, fmt, value1, value2);
  241. return result;
  242. }
  243. std::string format(const std::string& fmt, const Any& value1, const Any& value2, const Any& value3)
  244. {
  245. std::string result;
  246. format(result, fmt, value1, value2, value3);
  247. return result;
  248. }
  249. std::string format(const std::string& fmt, const Any& value1, const Any& value2, const Any& value3, const Any& value4)
  250. {
  251. std::string result;
  252. format(result, fmt, value1, value2, value3, value4);
  253. return result;
  254. }
  255. std::string format(const std::string& fmt, const Any& value1, const Any& value2, const Any& value3, const Any& value4, const Any& value5)
  256. {
  257. std::string result;
  258. format(result, fmt, value1, value2, value3, value4, value5);
  259. return result;
  260. }
  261. 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)
  262. {
  263. std::string result;
  264. format(result, fmt, value1, value2, value3, value4, value5, value6);
  265. return result;
  266. }
  267. void format(std::string& result, const std::string& fmt, const Any& value)
  268. {
  269. std::vector<Any> args;
  270. args.push_back(value);
  271. format(result, fmt, args);
  272. }
  273. void format(std::string& result, const std::string& fmt, const Any& value1, const Any& value2)
  274. {
  275. std::vector<Any> args;
  276. args.push_back(value1);
  277. args.push_back(value2);
  278. format(result, fmt, args);
  279. }
  280. void format(std::string& result, const std::string& fmt, const Any& value1, const Any& value2, const Any& value3)
  281. {
  282. std::vector<Any> args;
  283. args.push_back(value1);
  284. args.push_back(value2);
  285. args.push_back(value3);
  286. format(result, fmt, args);
  287. }
  288. void format(std::string& result, const std::string& fmt, const Any& value1, const Any& value2, const Any& value3, const Any& value4)
  289. {
  290. std::vector<Any> args;
  291. args.push_back(value1);
  292. args.push_back(value2);
  293. args.push_back(value3);
  294. args.push_back(value4);
  295. format(result, fmt, args);
  296. }
  297. void format(std::string& result, const std::string& fmt, const Any& value1, const Any& value2, const Any& value3, const Any& value4, const Any& value5)
  298. {
  299. std::vector<Any> args;
  300. args.push_back(value1);
  301. args.push_back(value2);
  302. args.push_back(value3);
  303. args.push_back(value4);
  304. args.push_back(value5);
  305. format(result, fmt, args);
  306. }
  307. 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)
  308. {
  309. std::vector<Any> args;
  310. args.push_back(value1);
  311. args.push_back(value2);
  312. args.push_back(value3);
  313. args.push_back(value4);
  314. args.push_back(value5);
  315. args.push_back(value6);
  316. format(result, fmt, args);
  317. }
  318. void format(std::string& result, const std::string& fmt, const std::vector<Any>& values)
  319. {
  320. std::string::const_iterator itFmt = fmt.begin();
  321. std::string::const_iterator endFmt = fmt.end();
  322. std::vector<Any>::const_iterator itVal = values.begin();
  323. std::vector<Any>::const_iterator endVal = values.end();
  324. while (itFmt != endFmt)
  325. {
  326. switch (*itFmt)
  327. {
  328. case '%':
  329. ++itFmt;
  330. if (itFmt != endFmt && itVal != endVal)
  331. {
  332. if (*itFmt == '[')
  333. {
  334. ++itFmt;
  335. std::size_t index = parseIndex(itFmt, endFmt);
  336. if (index < values.size())
  337. {
  338. std::vector<Any>::const_iterator it = values.begin() + index;
  339. formatOne(result, itFmt, endFmt, it);
  340. }
  341. else throw InvalidArgumentException("format argument index out of range", fmt);
  342. }
  343. else
  344. {
  345. formatOne(result, itFmt, endFmt, itVal);
  346. }
  347. }
  348. else if (itFmt != endFmt)
  349. {
  350. result += *itFmt++;
  351. }
  352. break;
  353. default:
  354. result += *itFmt;
  355. ++itFmt;
  356. }
  357. }
  358. }
  359. } // namespace Poco