patternformatter.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894
  1. /******************************************************************************
  2. *
  3. * package: Log4Qt
  4. * file: patternformatter.cpp
  5. * created: September 2007
  6. * author: Martin Heinrich
  7. *
  8. *
  9. * changes Feb 2009, Martin Heinrich
  10. * - Fixed VS 2008 unreferenced formal parameter warning by using
  11. * Q_UNUSED in LiteralPatternConverter::convert.
  12. *
  13. *
  14. * Copyright 2007 - 2009 Martin Heinrich
  15. *
  16. * Licensed under the Apache License, Version 2.0 (the "License");
  17. * you may not use this file except in compliance with the License.
  18. * You may obtain a copy of the License at
  19. *
  20. * http://www.apache.org/licenses/LICENSE-2.0
  21. *
  22. * Unless required by applicable law or agreed to in writing, software
  23. * distributed under the License is distributed on an "AS IS" BASIS,
  24. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  25. * See the License for the specific language governing permissions and
  26. * limitations under the License.
  27. *
  28. ******************************************************************************/
  29. /******************************************************************************
  30. * Dependencies
  31. ******************************************************************************/
  32. #include "log4qt/helpers/patternformatter.h"
  33. #include <QtCore/QString>
  34. #include <QtCore/QDebug>
  35. #include <limits.h>
  36. #include "log4qt/helpers/datetime.h"
  37. #include "log4qt/helpers/logerror.h"
  38. #include "log4qt/layout.h"
  39. #include "log4qt/logger.h"
  40. #include "log4qt/loggingevent.h"
  41. namespace Log4Qt
  42. {
  43. /**************************************************************************
  44. *Declarations
  45. **************************************************************************/
  46. /*!
  47. * \brief The class FormattingInfo stores the formatting modifier for a
  48. * pattern converter.
  49. *
  50. * \sa PatternConverter
  51. */
  52. class FormattingInfo
  53. {
  54. public:
  55. FormattingInfo()
  56. { clear(); }
  57. // FormattingInfo(const FormattingInfo &rOther); // Use compiler default
  58. // virtual ~FormattingInfo(); // Use compiler default
  59. // FormattingInfo &operator=(const FormattingInfo &rOther); // Use compiler default
  60. void clear();
  61. static QString intToString(int i);
  62. public:
  63. int mMinLength;
  64. int mMaxLength;
  65. bool mLeftAligned;
  66. };
  67. /*!
  68. * \brief The class PatternConverter is the abstract base class for all
  69. * pattern converters.
  70. *
  71. * PatternConverter handles the minimum and maximum modifier for a
  72. * conversion character. The actual conversion is by calling the
  73. * convert() member function of the derived class.
  74. *
  75. * \sa PatternLayout::format()
  76. */
  77. class PatternConverter
  78. {
  79. public:
  80. PatternConverter(const FormattingInfo &rFormattingInfo = FormattingInfo()) :
  81. mFormattingInfo(rFormattingInfo)
  82. {};
  83. virtual ~PatternConverter()
  84. {};
  85. private:
  86. PatternConverter(const PatternConverter &rOther); // Not implemented
  87. PatternConverter &operator=(const PatternConverter &rOther); // Not implemented
  88. public:
  89. void format(QString &rFormat, const LoggingEvent &rLoggingEvent) const;
  90. protected:
  91. virtual QString convert(const LoggingEvent &rLoggingEvent) const = 0;
  92. #ifndef QT_NO_DEBUG_STREAM
  93. virtual QDebug debug(QDebug &rDebug) const = 0;
  94. friend QDebug operator<<(QDebug, const PatternConverter &rPatternConverter);
  95. #endif
  96. protected:
  97. FormattingInfo mFormattingInfo;
  98. };
  99. /*!
  100. * \brief The class BasicPatternConverter converts several members of a
  101. * LoggingEvent to a string.
  102. *
  103. * BasicPatternConverter is used by PatternLayout to convert members that
  104. * do not reuquire additional formatting to a string as part of formatting
  105. * the LoggingEvent. It handles the following conversion characters:
  106. * 'm', 'p', 't', 'x'
  107. *
  108. * \sa PatternLayout::format()
  109. * \sa PatternConverter::format()
  110. */
  111. class BasicPatternConverter : public PatternConverter
  112. {
  113. public:
  114. enum Type {
  115. MESSAGE_CONVERTER,
  116. NDC_CONVERTER,
  117. LEVEL_CONVERTER,
  118. THREAD_CONVERTER,
  119. };
  120. public:
  121. BasicPatternConverter(const FormattingInfo &rFormattingInfo,
  122. Type type) :
  123. PatternConverter(rFormattingInfo),
  124. mType(type)
  125. {};
  126. // virtual ~BasicPatternConverter(); // Use compiler default
  127. private:
  128. BasicPatternConverter(const BasicPatternConverter &rOther); // Not implemented
  129. BasicPatternConverter &operator=(const BasicPatternConverter &rOther); // Not implemented
  130. protected:
  131. virtual QString convert(const LoggingEvent &rLoggingEvent) const;
  132. #ifndef QT_NO_DEBUG_STREAM
  133. virtual QDebug debug(QDebug &rDebug) const;
  134. #endif
  135. private:
  136. Type mType;
  137. };
  138. /*!
  139. * \brief The class DatePatternConverter converts the time stamp of a
  140. * LoggingEvent to a string.
  141. *
  142. * DatePatternConverter is used by PatternLayout to convert the time stamp
  143. * of a LoggingEvent to a string as part of formatting the LoggingEvent.
  144. * It handles the 'd' and 'r' conversion character.
  145. *
  146. * \sa PatternLayout::format()
  147. * \sa PatternConverter::format()
  148. */
  149. class DatePatternConverter : public PatternConverter
  150. {
  151. public:
  152. DatePatternConverter(const FormattingInfo &rFormattingInfo,
  153. const QString &rFormat) :
  154. PatternConverter(rFormattingInfo),
  155. mFormat(rFormat)
  156. {};
  157. // virtual ~DatePatternConverter(); // Use compiler default
  158. private:
  159. DatePatternConverter(const DatePatternConverter &rOther); // Not implemented
  160. DatePatternConverter &operator=(const DatePatternConverter &rOther); // Not implemented
  161. protected:
  162. virtual QString convert(const LoggingEvent &rLoggingEvent) const;
  163. #ifndef QT_NO_DEBUG_STREAM
  164. virtual QDebug debug(QDebug &rDebug) const;
  165. #endif
  166. private:
  167. QString mFormat;
  168. };
  169. /*!
  170. * \brief The class LiteralPatternConverter provides string literals.
  171. *
  172. * LiteralPatternConverter is used by PatternLayout to embed string
  173. * literals as part of formatting the LoggingEvent. It handles string
  174. * literals and the 'n' conversion character.
  175. *
  176. * \sa PatternLayout::format()
  177. * \sa PatternConverter::format()
  178. */
  179. class LiteralPatternConverter : public PatternConverter
  180. {
  181. public:
  182. LiteralPatternConverter(const QString &rLiteral) :
  183. PatternConverter(),
  184. mLiteral(rLiteral)
  185. {};
  186. // virtual ~LiteralPatternConverter(); // Use compiler default
  187. private:
  188. LiteralPatternConverter(const LiteralPatternConverter &rOther); // Not implemented
  189. LiteralPatternConverter &operator=(const LiteralPatternConverter &rOther); // Not implemented
  190. protected:
  191. virtual QString convert(const LoggingEvent &rLoggingEvent) const;
  192. #ifndef QT_NO_DEBUG_STREAM
  193. virtual QDebug debug(QDebug &rDebug) const;
  194. #endif
  195. private:
  196. QString mLiteral;
  197. };
  198. /*!
  199. * \brief The class LoggerPatternConverter converts the Logger name of a
  200. * LoggingEvent to a string.
  201. *
  202. * LoggerPatternConverter is used by PatternLayout to convert the Logger
  203. * name of a LoggingEvent to a string as part of formatting the
  204. * LoggingEvent. It handles the 'c' conversion character.
  205. *
  206. * \sa PatternLayout::format()
  207. * \sa PatternConverter::format()
  208. */
  209. class LoggerPatternConverter : public PatternConverter
  210. {
  211. public:
  212. LoggerPatternConverter(const FormattingInfo &rFormattingInfo,
  213. int precision) :
  214. PatternConverter(rFormattingInfo),
  215. mPrecision(precision)
  216. {};
  217. // virtual ~LoggerPatternConverter(); // Use compiler default
  218. private:
  219. LoggerPatternConverter(const LoggerPatternConverter &rOther); // Not implemented
  220. LoggerPatternConverter &operator=(const LoggerPatternConverter &rOther); // Not implemented
  221. protected:
  222. virtual QString convert(const LoggingEvent &rLoggingEvent) const;
  223. #ifndef QT_NO_DEBUG_STREAM
  224. virtual QDebug debug(QDebug &rDebug) const;
  225. #endif
  226. private:
  227. int mPrecision;
  228. };
  229. /*!
  230. * \brief The class MDCPatternConverter converts the MDC data of a
  231. * LoggingEvent to a string.
  232. *
  233. * MDCPatternConverter is used by PatternLayout to convert the MDC data of
  234. * a LoggingEvent to a string as part of formatting the LoggingEvent. It
  235. * handles the 'X' conversion character.
  236. *
  237. * \sa PatternLayout::format()
  238. * \sa PatternConverter::format()
  239. */
  240. class MDCPatternConverter : public PatternConverter
  241. {
  242. public:
  243. MDCPatternConverter(const FormattingInfo &rFormattingInfo,
  244. const QString &rKey) :
  245. PatternConverter(rFormattingInfo),
  246. mKey(rKey)
  247. {};
  248. // virtual ~MDCPatternConverter(); // Use compiler default
  249. private:
  250. MDCPatternConverter(const MDCPatternConverter &rOther); // Not implemented
  251. MDCPatternConverter &operator=(const MDCPatternConverter &rOther); // Not implemented
  252. protected:
  253. virtual QString convert(const LoggingEvent &rLoggingEvent) const;
  254. #ifndef QT_NO_DEBUG_STREAM
  255. virtual QDebug debug(QDebug &rDebug) const;
  256. #endif
  257. private:
  258. QString mKey;
  259. };
  260. #ifndef QT_NO_DEBUG_STREAM
  261. QDebug operator<<(QDebug, const FormattingInfo &rFormattingInfo);
  262. #endif
  263. #ifndef QT_NO_DEBUG_STREAM
  264. QDebug operator<<(QDebug, const PatternConverter &rPatternConverter);
  265. #endif
  266. /**************************************************************************
  267. * C helper functions
  268. **************************************************************************/
  269. LOG4QT_DECLARE_STATIC_LOGGER(logger, Log4Qt::PatternFormatter)
  270. /**************************************************************************
  271. * Class implementation: PatternFormatter
  272. **************************************************************************/
  273. PatternFormatter::PatternFormatter(const QString &rPattern) :
  274. mIgnoreCharacters(QLatin1String("CFlLM")),
  275. mConversionCharacters(QLatin1String("cdmprtxX")),
  276. mOptionCharacters(QLatin1String("cd")),
  277. mPattern(rPattern),
  278. mPatternConverters()
  279. {
  280. parse();
  281. }
  282. PatternFormatter::~PatternFormatter()
  283. {
  284. PatternConverter *p_converter;
  285. Q_FOREACH(p_converter, mPatternConverters)
  286. delete p_converter;
  287. }
  288. QString PatternFormatter::format(const LoggingEvent &rLoggingEvent) const
  289. {
  290. QString result;
  291. PatternConverter *p_converter;
  292. Q_FOREACH(p_converter, mPatternConverters)
  293. p_converter->format(result, rLoggingEvent);
  294. return result;
  295. }
  296. bool PatternFormatter::addDigit(const QChar &rDigit,
  297. int &rValue)
  298. {
  299. if (!rDigit.isDigit())
  300. return false;
  301. int digit_value = rDigit.digitValue();
  302. if (rValue > (INT_MAX - digit_value) / 10)
  303. rValue = INT_MAX;
  304. else
  305. rValue = rValue * 10 + digit_value;
  306. return true;
  307. }
  308. void PatternFormatter::createConverter(const QChar &rChar,
  309. const FormattingInfo &rFormattingInfo,
  310. const QString &rOption)
  311. {
  312. Q_ASSERT_X(mConversionCharacters.indexOf(rChar) >= 0, "PatternFormatter::createConverter", "Unknown conversion character" );
  313. LogError e("Creating Converter for character '%1' min %2, max %3, left %4 and option '%5'");
  314. e << QString(rChar)
  315. << FormattingInfo::intToString(rFormattingInfo.mMinLength)
  316. << FormattingInfo::intToString(rFormattingInfo.mMaxLength)
  317. << rFormattingInfo.mLeftAligned
  318. << rOption;
  319. logger()->trace(e);
  320. switch (rChar.toLatin1())
  321. {
  322. case 'c':
  323. mPatternConverters << new LoggerPatternConverter(rFormattingInfo,
  324. parseIntegerOption(rOption));
  325. break;
  326. case 'd':
  327. {
  328. QString option = rOption;
  329. if (rOption.isEmpty())
  330. option = QLatin1String("ISO8601");
  331. mPatternConverters << new DatePatternConverter(rFormattingInfo,
  332. option);
  333. break;
  334. }
  335. case 'm':
  336. mPatternConverters << new BasicPatternConverter(rFormattingInfo,
  337. BasicPatternConverter::MESSAGE_CONVERTER);
  338. break;
  339. case 'p':
  340. mPatternConverters << new BasicPatternConverter(rFormattingInfo,
  341. BasicPatternConverter::LEVEL_CONVERTER);
  342. break;
  343. case 'r':
  344. mPatternConverters << new DatePatternConverter(rFormattingInfo,
  345. QLatin1String("TIME_RELATIVE"));
  346. break;
  347. case 't':
  348. mPatternConverters << new BasicPatternConverter(rFormattingInfo,
  349. BasicPatternConverter::THREAD_CONVERTER);
  350. break;
  351. case 'x':
  352. mPatternConverters << new BasicPatternConverter(rFormattingInfo,
  353. BasicPatternConverter::NDC_CONVERTER);
  354. break;
  355. case 'X':
  356. mPatternConverters << new MDCPatternConverter(rFormattingInfo,
  357. rOption);
  358. break;
  359. default:
  360. Q_ASSERT_X(false, "PatternFormatter::createConverter", "Unknown pattern character");
  361. }
  362. }
  363. void PatternFormatter::createLiteralConverter(const QString &rLiteral)
  364. {
  365. logger()->trace("Creating literal LiteralConverter with Literal '%1'",
  366. rLiteral);
  367. mPatternConverters << new LiteralPatternConverter(rLiteral);
  368. }
  369. void PatternFormatter::parse()
  370. {
  371. enum State {
  372. LITERAL_STATE,
  373. ESCAPE_STATE,
  374. MIN_STATE,
  375. DOT_STATE,
  376. MAX_STATE,
  377. CHARACTER_STATE,
  378. POSSIBLEOPTION_STATE,
  379. OPTION_STATE
  380. };
  381. int i = 0;
  382. QChar c;
  383. char ch;
  384. State state = LITERAL_STATE;
  385. FormattingInfo formatting_info;
  386. QString literal;
  387. int converter_start;
  388. int option_start;
  389. while (i < mPattern.length())
  390. {
  391. // i points to the current character
  392. // c contains the current character
  393. // ch contains the Latin1 equivalent of the current character
  394. // i is incremented at the end of the loop to consume the character
  395. // continue is used to change state without consuming the character
  396. c = mPattern.at(i);
  397. ch = c.toLatin1();
  398. switch (state)
  399. {
  400. case LITERAL_STATE:
  401. if (ch == '%')
  402. {
  403. formatting_info.clear();
  404. converter_start = i;
  405. state = ESCAPE_STATE;
  406. } else
  407. literal += c;
  408. break;
  409. case ESCAPE_STATE:
  410. if (ch == '%')
  411. {
  412. literal += c;
  413. state = LITERAL_STATE;
  414. }
  415. else if (ch == 'n')
  416. {
  417. literal += Layout::endOfLine();
  418. state = LITERAL_STATE;
  419. }
  420. else
  421. {
  422. if (!literal.isEmpty())
  423. {
  424. createLiteralConverter(literal);
  425. literal.clear();
  426. }
  427. if (ch == '-')
  428. formatting_info.mLeftAligned = true;
  429. else if (c.isDigit())
  430. {
  431. formatting_info.mMinLength = c.digitValue();
  432. state = MIN_STATE;
  433. }
  434. else if (ch == '.')
  435. state = DOT_STATE;
  436. else
  437. {
  438. state = CHARACTER_STATE;
  439. continue;
  440. }
  441. }
  442. break;
  443. case MIN_STATE:
  444. if (!addDigit(c, formatting_info.mMinLength))
  445. {
  446. if (ch == '.')
  447. state = DOT_STATE;
  448. else
  449. {
  450. state = CHARACTER_STATE;
  451. continue;
  452. }
  453. }
  454. break;
  455. case DOT_STATE:
  456. if (c.isDigit())
  457. {
  458. formatting_info.mMaxLength = c.digitValue();
  459. state = MAX_STATE;
  460. }
  461. else
  462. {
  463. LogError e = LOG4QT_ERROR(QT_TR_NOOP("Found character '%1' where digit was expected."),
  464. LAYOUT_EXPECTED_DIGIT_ERROR,
  465. "Log4Qt::PatternFormatter");
  466. e << QString(c);
  467. logger()->error(e);
  468. }
  469. break;
  470. case MAX_STATE:
  471. if (!addDigit(c, formatting_info.mMaxLength))
  472. {
  473. state = CHARACTER_STATE;
  474. continue;
  475. }
  476. break;
  477. case CHARACTER_STATE:
  478. if (mIgnoreCharacters.indexOf(c) >= 0)
  479. state = LITERAL_STATE;
  480. else if (mOptionCharacters.indexOf(c) >= 0)
  481. state = POSSIBLEOPTION_STATE;
  482. else if (mConversionCharacters.indexOf(c) >= 0)
  483. {
  484. createConverter(c, formatting_info);
  485. state = LITERAL_STATE;
  486. }
  487. else
  488. {
  489. logger()->warn("Invalid conversion character '%1' at %2 in pattern '%3'",
  490. c, i, mPattern);
  491. createLiteralConverter(mPattern.mid(converter_start, i - converter_start + 1));
  492. state = LITERAL_STATE;
  493. }
  494. break;
  495. case POSSIBLEOPTION_STATE:
  496. if (ch == '{')
  497. {
  498. option_start = i;
  499. state = OPTION_STATE;
  500. }
  501. else
  502. {
  503. createConverter(mPattern.at(i - 1),
  504. formatting_info);
  505. state = LITERAL_STATE;
  506. continue;
  507. }
  508. break;
  509. case OPTION_STATE:
  510. if (ch == '}')
  511. {
  512. createConverter(mPattern.at(option_start - 1),
  513. formatting_info,
  514. mPattern.mid(option_start + 1, i - option_start - 1));
  515. state = LITERAL_STATE;
  516. }
  517. break;
  518. default:
  519. Q_ASSERT_X(false, "PatternFormatter::parse()", "Unknown parsing state constant");
  520. state = LITERAL_STATE;
  521. }
  522. i++;
  523. }
  524. if (state != LITERAL_STATE)
  525. {
  526. logger()->warn("Unexptected end of pattern '%1'", mPattern);
  527. if (state == ESCAPE_STATE)
  528. literal += c;
  529. else
  530. literal += mPattern.mid(converter_start);
  531. }
  532. if (!literal.isEmpty())
  533. createLiteralConverter(literal);
  534. }
  535. int PatternFormatter::parseIntegerOption(const QString &rOption)
  536. {
  537. if (rOption.isEmpty())
  538. return 0;
  539. bool ok;
  540. int result = rOption.toInt(&ok);
  541. if (!ok)
  542. {
  543. LogError e = LOG4QT_ERROR(QT_TR_NOOP("Option '%1' cannot be converted into an integer"),
  544. LAYOUT_OPTION_IS_NOT_INTEGER_ERROR,
  545. "Log4Qt::PatterFormatter");
  546. e << rOption;
  547. logger()->error(e);
  548. }
  549. if (result < 0)
  550. {
  551. LogError e = LOG4QT_ERROR(QT_TR_NOOP("Option %1 isn't a positive integer"),
  552. LAYOUT_INTEGER_IS_NOT_POSITIVE_ERROR,
  553. "Log4Qt::PatterFormatter");
  554. e << result;
  555. logger()->error(e);
  556. result = 0;
  557. }
  558. return result;
  559. }
  560. /**************************************************************************
  561. * Class implementation: FormattingInfo
  562. **************************************************************************/
  563. void FormattingInfo::clear()
  564. {
  565. mMinLength = 0;
  566. mMaxLength = INT_MAX;
  567. mLeftAligned = false;
  568. };
  569. QString FormattingInfo::intToString(int i)
  570. {
  571. if (i == INT_MAX)
  572. return QLatin1String("INT_MAX");
  573. else
  574. return QString::number(i);
  575. }
  576. /**************************************************************************
  577. * Class implementation: PatternConverter
  578. **************************************************************************/
  579. void PatternConverter::format(QString &rFormat, const LoggingEvent &rLoggingEvent) const
  580. {
  581. const QLatin1Char space(' ');
  582. QString s = convert(rLoggingEvent);
  583. if (s.length() > mFormattingInfo.mMaxLength)
  584. rFormat += s.left(mFormattingInfo.mMaxLength);
  585. else if (mFormattingInfo.mLeftAligned)
  586. rFormat += s.leftJustified(mFormattingInfo.mMinLength, space, false);
  587. else
  588. rFormat += s.rightJustified(mFormattingInfo.mMinLength, space, false);
  589. }
  590. /**************************************************************************
  591. * Class implementation: BasicPatternConverter
  592. **************************************************************************/
  593. QString BasicPatternConverter::convert(const LoggingEvent &rLoggingEvent) const
  594. {
  595. switch (mType)
  596. {
  597. case MESSAGE_CONVERTER:
  598. return rLoggingEvent.message();
  599. break;
  600. case NDC_CONVERTER:
  601. return rLoggingEvent.ndc();
  602. break;
  603. case LEVEL_CONVERTER:
  604. return rLoggingEvent.level().toString();
  605. break;
  606. case THREAD_CONVERTER:
  607. return rLoggingEvent.threadName();
  608. break;
  609. default:
  610. Q_ASSERT_X(false, "BasicPatternConverter::convert()", "Unkown type constant");
  611. return QString();
  612. }
  613. }
  614. QDebug BasicPatternConverter::debug(QDebug &rDebug) const
  615. {
  616. QString type;
  617. switch (mType)
  618. {
  619. case MESSAGE_CONVERTER:
  620. type = QLatin1String("MESSAGE_CONVERTER");
  621. break;
  622. case NDC_CONVERTER:
  623. type = QLatin1String("NDC_CONVERTER");
  624. break;
  625. case LEVEL_CONVERTER:
  626. type = QLatin1String("LEVEL_CONVERTER");
  627. break;
  628. case THREAD_CONVERTER:
  629. type = QLatin1String("THREAD_CONVERTER");
  630. break;
  631. default:
  632. Q_ASSERT_X(false, "BasicPatternConverter::debug()", "Unkown type constant");
  633. }
  634. rDebug.nospace() << "BasicPatternConverter("
  635. << mFormattingInfo
  636. << "type:" << type
  637. << ")";
  638. return rDebug.space();
  639. }
  640. /**************************************************************************
  641. * Class implementation: DatePatternConverter
  642. **************************************************************************/
  643. QString DatePatternConverter::convert(const LoggingEvent &rLoggingEvent) const
  644. {
  645. return DateTime::fromMilliSeconds(rLoggingEvent.timeStamp()).toString(mFormat);
  646. }
  647. QDebug DatePatternConverter::debug(QDebug &rDebug) const
  648. {
  649. rDebug.nospace() << "DatePatternConverter("
  650. << mFormattingInfo
  651. << "format:" << mFormat
  652. << ")";
  653. return rDebug.space();
  654. }
  655. /**************************************************************************
  656. * Class implementation: LiteralPatternConverter
  657. **************************************************************************/
  658. QString LiteralPatternConverter::convert(const LoggingEvent &rLoggingEvent) const
  659. {
  660. Q_UNUSED(rLoggingEvent);
  661. return mLiteral;
  662. };
  663. QDebug LiteralPatternConverter::debug(QDebug &rDebug) const
  664. {
  665. rDebug.nospace() << "LiteralPatternConverter("
  666. << mFormattingInfo
  667. << "literal:" << mLiteral
  668. << ")";
  669. return rDebug.space();
  670. }
  671. /**************************************************************************
  672. * Class implementation: LoggerPatternConverter
  673. **************************************************************************/
  674. QString LoggerPatternConverter::convert(const LoggingEvent &rLoggingEvent) const
  675. {
  676. if (!rLoggingEvent.logger())
  677. return QString();
  678. QString name = rLoggingEvent.logger()->name();
  679. if (mPrecision <= 0 || (name.isEmpty()))
  680. return name;
  681. const QString separator(QLatin1String("::"));
  682. int i = mPrecision;
  683. int begin = name.length();
  684. while ((i > 0) && (begin >= 0))
  685. {
  686. begin = name.lastIndexOf(separator, begin - name.length() - 1);
  687. i--;
  688. }
  689. if (begin < 0)
  690. begin = 0;
  691. else
  692. begin += 2;
  693. return name.mid(begin);
  694. }
  695. QDebug LoggerPatternConverter::debug(QDebug &rDebug) const
  696. {
  697. rDebug.nospace() << "LoggerPatternConverter("
  698. << mFormattingInfo
  699. << "precision:" << mPrecision
  700. << ")";
  701. return rDebug.space();
  702. }
  703. /******************************************************************************
  704. * Class implementation: MDCPatternConverter
  705. ******************************************************************************/
  706. QString MDCPatternConverter::convert(const LoggingEvent &rLoggingEvent) const
  707. {
  708. return rLoggingEvent.mdc().value(mKey);
  709. };
  710. QDebug MDCPatternConverter::debug(QDebug &rDebug) const
  711. {
  712. rDebug.nospace() << "MDCPatternConverter("
  713. << mFormattingInfo
  714. << "key:" << mKey
  715. << ")";
  716. return rDebug.space();
  717. }
  718. /**************************************************************************
  719. * Implementation: Operators, Helper
  720. **************************************************************************/
  721. #ifndef QT_NO_DEBUG_STREAM
  722. QDebug operator<<(QDebug debug, const PatternFormatter &rPatternFormatter)
  723. {
  724. debug.nospace() << "PatternFormatter("
  725. << "pattern:" << rPatternFormatter.mPattern << " "
  726. << "converters:(";
  727. int i;
  728. for (i = 0; i < rPatternFormatter.mPatternConverters.size(); i++)
  729. {
  730. if (i > 0)
  731. debug.nospace() << ", ";
  732. debug.nospace() << *rPatternFormatter.mPatternConverters.at(i);
  733. }
  734. debug.nospace() << ") )";
  735. return debug.space();
  736. }
  737. #endif
  738. #ifndef QT_NO_DEBUG_STREAM
  739. QDebug operator<<(QDebug debug, const FormattingInfo &rFormattingInfo)
  740. {
  741. debug.nospace() << "FormattingInfo("
  742. << "min:" << FormattingInfo::intToString(rFormattingInfo.mMinLength) << " "
  743. << "max:" << FormattingInfo::intToString(rFormattingInfo.mMaxLength) << " "
  744. << "left:" << rFormattingInfo.mLeftAligned
  745. << ")";
  746. return debug.space();
  747. }
  748. #endif // QT_NO_DEBUG_STREAM
  749. #ifndef QT_NO_DEBUG_STREAM
  750. QDebug operator<<(QDebug debug, const PatternConverter &rPatternConverter)
  751. {
  752. return rPatternConverter.debug(debug);
  753. }
  754. #endif // QT_NO_DEBUG_STREAM
  755. } // namespace Log4Qt