ECDebugPrint.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. /*
  2. * Copyright 2005 - 2016 Zarafa and its licensors
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Affero General Public License, version 3,
  6. * as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU Affero General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Affero General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. *
  16. */
  17. #ifndef ECDebugPrint_INCLUDED
  18. #define ECDebugPrint_INCLUDED
  19. // @todo: Cleanup 'n' Document
  20. #include <kopano/zcdefs.h>
  21. #include <mapidefs.h>
  22. #include <kopano/stringutil.h>
  23. #include <kopano/ECDebug.h>
  24. namespace KC {
  25. class ECDebugPrintBase {
  26. public:
  27. enum DerefMode {
  28. Deref,
  29. NoDeref
  30. };
  31. };
  32. template<typename string_type, ECDebugPrintBase::DerefMode deref_mode>
  33. class ECDebugPrint;
  34. namespace details {
  35. template<typename string_type>
  36. class conversion_helpers {
  37. };
  38. template<>
  39. class conversion_helpers<std::string> {
  40. public:
  41. static std::string& convert_from(std::string &s) {return s;}
  42. static std::string convert_from(const std::wstring &s);
  43. static std::string stringify(unsigned int x) {
  44. return ::stringify(x, true) + "(" + ::stringify(x, false) + ")";
  45. }
  46. static std::string stringify(LPCVOID lpVoid);
  47. static std::string bin2hex(ULONG cbData, LPBYTE lpData) {
  48. return ::bin2hex(cbData, lpData);
  49. }
  50. static const std::string strNULL;
  51. static const std::string strCOMMA;
  52. };
  53. template<>
  54. class conversion_helpers<std::wstring> {
  55. public:
  56. static std::wstring convert_from(const std::string &s);
  57. static std::wstring& convert_from(std::wstring &s) {return s;}
  58. static std::wstring stringify(unsigned int x) {
  59. return ::wstringify(x, true) + L"(" + ::wstringify(x, false) + L")";
  60. }
  61. static std::wstring stringify(LPCVOID lpVoid);
  62. static std::wstring bin2hex(ULONG cbData, LPBYTE lpData) {
  63. return ::bin2hexw(cbData, lpData);
  64. }
  65. static const std::wstring strNULL;
  66. static const std::wstring strCOMMA;
  67. };
  68. template<typename string_type, typename T, ECDebugPrintBase::DerefMode deref_mode>
  69. class defaultPrinter {
  70. };
  71. template<typename string_type, typename T, ECDebugPrintBase::DerefMode deref_mode>
  72. class defaultPrinter<string_type, T*, deref_mode> {
  73. T* m_lpa;
  74. public:
  75. defaultPrinter(T* lpa): m_lpa(lpa) {}
  76. string_type toString() const {
  77. if (deref_mode == ECDebugPrintBase::NoDeref || m_lpa == NULL)
  78. return ECDebugPrint<string_type, deref_mode>::toString(reinterpret_cast<LPVOID>(m_lpa));
  79. else
  80. return ECDebugPrint<string_type, ECDebugPrintBase::NoDeref>::toString(*m_lpa); // Never dereference twice
  81. }
  82. };
  83. template<typename string_type, typename T, ECDebugPrintBase::DerefMode deref_mode>
  84. class defaultPrinter<string_type, std::basic_string<T>, deref_mode > {
  85. const std::basic_string<T> &m_str;
  86. public:
  87. defaultPrinter(const std::basic_string<T> &str): m_str(str) {}
  88. string_type toString() const {
  89. return conversion_helpers<string_type>::convert_from(m_str);
  90. }
  91. };
  92. template<ECDebugPrintBase::DerefMode deref_mode, typename string_type, typename T>
  93. defaultPrinter<string_type, T, deref_mode> makeDefaultPrinter(T& a) {
  94. return defaultPrinter<string_type, T, deref_mode>(a);
  95. }
  96. template<typename string_type, typename T1, typename T2, ECDebugPrintBase::DerefMode deref_mode>
  97. class defaultPrinter2 {
  98. };
  99. template<typename string_type, typename T1, typename T2, ECDebugPrintBase::DerefMode deref_mode>
  100. class defaultPrinter2<string_type, T1*, T2**, deref_mode> {
  101. T1* m_lpa1;
  102. T2** m_lppa2;
  103. public:
  104. defaultPrinter2(T1* lpa1, T2** lppa2): m_lpa1(lpa1), m_lppa2(lppa2) {}
  105. string_type toString() const {
  106. if (deref_mode == ECDebugPrintBase::NoDeref || m_lpa1 == NULL || m_lppa2 == NULL)
  107. return "(" + ECDebugPrint<string_type, deref_mode>::toString(reinterpret_cast<LPVOID>(m_lpa1)) +
  108. "," + ECDebugPrint<string_type, deref_mode>::toString(reinterpret_cast<LPVOID>(m_lppa2)) + ")";
  109. else
  110. return ECDebugPrint<string_type, ECDebugPrintBase::NoDeref>::toString(*m_lpa1, *m_lppa2);
  111. }
  112. };
  113. template<ECDebugPrintBase::DerefMode deref_mode, typename string_type, typename T1, typename T2>
  114. defaultPrinter2<string_type, T1, T2, deref_mode> makeDefaultPrinter2(T1& a1, T2& a2) {
  115. return defaultPrinter2<string_type, T1, T2, deref_mode>(a1, a2);
  116. }
  117. } // namespace details
  118. class RecurrencePattern; // Forward declarations
  119. class TimezoneDefinition;
  120. template<typename string_type, ECDebugPrintBase::DerefMode deref_mode>
  121. class ECDebugPrint _kc_final : public ECDebugPrintBase {
  122. public:
  123. typedef details::conversion_helpers<string_type> helpers;
  124. static string_type& toString(string_type &str) {
  125. return str;
  126. }
  127. template <typename T>
  128. static string_type toString(T& a, typename std::enable_if<!std::is_convertible<T, IUnknown *>::value>::type * = nullptr)
  129. {
  130. return details::makeDefaultPrinter<deref_mode, string_type>(a).toString();
  131. }
  132. template <typename T1, typename T2>
  133. static string_type toString(T1& a1, T2& a2) {
  134. return details::makeDefaultPrinter2<deref_mode, string_type>(a1, a2).toString();
  135. }
  136. static string_type toString(unsigned int ulValue) {
  137. return helpers::stringify(ulValue);
  138. }
  139. static string_type toString(WORD ulValue) {
  140. return helpers::stringify(ulValue);
  141. }
  142. static string_type toString(HRESULT hr) {
  143. return helpers::stringify(hr);
  144. }
  145. static string_type toString(const IID &refiid) {
  146. string_type idd = DBGGUIDToString(refiid);
  147. return helpers::convert_from(idd);
  148. }
  149. static string_type toString(LPCIID lpciid) {
  150. return lpciid == NULL ? helpers::strNULL : toString(*lpciid);
  151. }
  152. static string_type toString(LPGUID lpguid) {
  153. if (lpguid == NULL)
  154. return helpers::strNULL;
  155. std::string guidstring = DBGGUIDToString(*lpguid);
  156. return helpers::convert_from(guidstring);
  157. }
  158. static string_type toString(LPVOID lpVoid) {
  159. return helpers::stringify(lpVoid);
  160. }
  161. static string_type toString(LPCVOID lpVoid) {
  162. return helpers::stringify(lpVoid);
  163. }
  164. static string_type toString(LPUNKNOWN lpUnk) {
  165. return helpers::stringify(reinterpret_cast<LPVOID>(lpUnk));
  166. }
  167. static string_type toString(LPSPropValue lpsPropValue) {
  168. std::string propname = PropNameFromPropArray(1, lpsPropValue);
  169. return helpers::convert_from(propname);
  170. }
  171. static string_type toString(ULONG *lpcValues, LPSPropValue *lppPropArray) {
  172. return toString(reinterpret_cast<LPVOID>(lpcValues)) + helpers::strCOMMA + toString(reinterpret_cast<LPVOID>(lppPropArray));
  173. }
  174. static string_type toString(ULONG *lpcbData, LPBYTE *lppData) {
  175. return toString(reinterpret_cast<LPVOID>(lpcbData)) + helpers::strCOMMA + toString(reinterpret_cast<LPVOID>(lppData));
  176. }
  177. static string_type toString(ULONG cValues, LPSPropValue lpPropArray) {
  178. std::string propname = PropNameFromPropArray(cValues, lpPropArray);
  179. return helpers::convert_from(propname);
  180. }
  181. static string_type toString(ULONG cValues, LPSPropValue lpPropArray, LPSPropProblemArray*) {
  182. return toString(cValues, lpPropArray);
  183. }
  184. static string_type toString(LPSPropTagArray lpPropTagArray) {
  185. if (lpPropTagArray == NULL)
  186. return helpers::strNULL;
  187. std::string propname = PropNameFromPropTagArray(lpPropTagArray);
  188. return helpers::convert_from(propname);
  189. }
  190. static string_type toString(ULONG ciidExclude, LPCIID rgiidExclude) {
  191. return string_type();
  192. }
  193. static string_type toString(ULONG cNames, const MAPINAMEID **ppNames) {
  194. std::string mapiname = MapiNameIdListToString(cNames, ppNames);
  195. return helpers::convert_from(mapiname);
  196. }
  197. static string_type toString(ULONG cbData, LPBYTE lpData) {
  198. return helpers::bin2hex(cbData, lpData);
  199. }
  200. static string_type toString(LPSRestriction lpRestrict) {
  201. std::string restrictionstring = RestrictionToString(lpRestrict);
  202. return helpers::convert_from(restrictionstring);
  203. }
  204. static string_type toString(const SSortOrderSet *lpSortOrderSet)
  205. {
  206. std::string sortorderstring = SortOrderSetToString(lpSortOrderSet);
  207. return helpers::convert_from(sortorderstring);
  208. }
  209. static string_type toString(LPMAPIERROR lpError) {
  210. return toString(reinterpret_cast<LPVOID>(lpError));
  211. }
  212. static string_type toString(LPSRowSet lpRowSet) {
  213. std::string rowsetstring = RowSetToString(lpRowSet);
  214. return helpers::convert_from(rowsetstring);
  215. }
  216. static string_type toString(LPROWLIST lpRowList) {
  217. std::string rowliststring = RowListToString(lpRowList);
  218. return helpers::convert_from(rowliststring);
  219. }
  220. static string_type toString(LPACTION lpAction) {
  221. std::string actionstring = ActionToString(lpAction);
  222. return helpers::convert_from(actionstring);
  223. }
  224. static string_type toString(LPSPropProblemArray lpPropblemArray) {
  225. std::string problemstring = ProblemArrayToString(lpPropblemArray);
  226. return helpers::convert_from(problemstring);
  227. }
  228. static string_type toString(ULONG cbEntryID, LPENTRYID lpEntryID) {
  229. return helpers::bin2hex(cbEntryID, (LPBYTE)lpEntryID);
  230. }
  231. static string_type toString(MAPIUID uid) {
  232. return helpers::bin2hex(sizeof(MAPIUID), (LPBYTE)&uid);
  233. }
  234. static string_type toString(LPTSTR data) {
  235. return (char *)data;
  236. }
  237. static string_type toString(LARGE_INTEGER li) {
  238. string_type listring = stringify_int64(li.QuadPart);
  239. return helpers::convert_from(listring);
  240. }
  241. static string_type toString(ULARGE_INTEGER li) {
  242. string_type listring = stringify_int64(li.QuadPart);
  243. return helpers::convert_from(listring);
  244. }
  245. static string_type toString(LPCTSTR str) {
  246. return helpers::convert_from(str);
  247. }
  248. static string_type toString(LPMAPINAMEID) {
  249. string_type errorstring("LPMAPINAMEID (not implemented)");
  250. return helpers::convert_from(errorstring);
  251. }
  252. static string_type toString(LPADRLIST) {
  253. string_type errorstring("LPADRLIST (not implemented)");
  254. return helpers::convert_from(errorstring);
  255. }
  256. static string_type toString(RecurrencePattern* p) {
  257. string_type errorstring("RecurrencePattern (not implemented)");
  258. return helpers::convert_from(errorstring);
  259. }
  260. static string_type toString(TimezoneDefinition*) {
  261. string_type errorstring("TimezoneDefinition (not implemented)");
  262. return helpers::convert_from(errorstring);
  263. }
  264. static string_type toString(FILETIME) {
  265. string_type errorstring("FILETIME (not implemented)");
  266. return helpers::convert_from(errorstring);
  267. }
  268. static string_type toString(STATSTG) {
  269. string_type errorstring("STATSTG (not implemented)");
  270. return helpers::convert_from(errorstring);
  271. }
  272. };
  273. } /* namespace */
  274. #endif // ndef ECDebugPrint_INCLUDED