LibreOffice Module comphelper (master)  1
windowsdebugoutput.hxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  */
9 
10 /* Debug output operators for Windows-specific types. For use in SAL_INFO(), SAL_WARN(), and
11  * friends. The exact format of the generated output is not guaranteed to be stable or contain
12  * complete information.
13  */
14 
15 #ifndef INCLUDED_COMPHELPER_WINDOWSDEBUGOUTPUT_HXX
16 #define INCLUDED_COMPHELPER_WINDOWSDEBUGOUTPUT_HXX
17 
18 #include <codecvt>
19 #include <iomanip>
20 #include <ostream>
21 #include <string>
22 #include <vector>
23 
24 #ifdef LIBO_INTERNAL_ONLY
25 #include <prewin.h>
26 #include <postwin.h>
27 #else
28 #include <windows.h>
29 #endif
30 #include <initguid.h>
31 
32 namespace
33 {
34 DEFINE_GUID(IID_IdentityUnmarshal, 0x0000001B, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
35  0x00, 0x46);
36 }
37 
38 template <typename charT, typename traits>
39 inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& stream,
40  const IID& rIid)
41 {
42  LPOLESTR pRiid;
43  if (StringFromIID(rIid, &pRiid) != S_OK)
44  return stream << "?";
45 
46  stream << std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes(
47  std::wstring(pRiid));
48 
49  DWORD nSize;
50  if (RegGetValueW(HKEY_CLASSES_ROOT, std::wstring(L"CLSID\\").append(pRiid).data(), nullptr,
51  RRF_RT_REG_SZ, nullptr, nullptr, &nSize)
52  == ERROR_SUCCESS)
53  {
54  std::vector<wchar_t> sValue(nSize / 2);
55  if (RegGetValueW(HKEY_CLASSES_ROOT, std::wstring(L"CLSID\\").append(pRiid).data(), nullptr,
56  RRF_RT_REG_SZ, nullptr, sValue.data(), &nSize)
57  == ERROR_SUCCESS)
58  {
59  stream << "=\""
60  << std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes(
61  std::wstring(sValue.data()))
62  << "\"";
63  }
64  }
65  else if (RegGetValueW(HKEY_CLASSES_ROOT, std::wstring(L"Interface\\").append(pRiid).data(),
66  nullptr, RRF_RT_REG_SZ, nullptr, nullptr, &nSize)
67  == ERROR_SUCCESS)
68  {
69  std::vector<wchar_t> sValue(nSize / 2);
70  if (RegGetValueW(HKEY_CLASSES_ROOT, std::wstring(L"Interface\\").append(pRiid).data(),
71  nullptr, RRF_RT_REG_SZ, nullptr, sValue.data(), &nSize)
72  == ERROR_SUCCESS)
73  {
74  stream << "=\""
75  << std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes(
76  std::wstring(sValue.data()))
77  << "\"";
78  }
79  }
80  else
81  {
82  // Special case well-known interfaces that pop up a lot, but which don't have their name in
83  // the Registry.
84 
85  if (IsEqualIID(rIid, IID_IMarshal))
86  stream << "=\"IMarshal\"";
87  else if (IsEqualIID(rIid, IID_IMarshal2))
88  stream << "=\"IMarshal2\"";
89  else if (IsEqualIID(rIid, IID_INoMarshal))
90  stream << "=\"INoMarshal\"";
91  else if (IsEqualIID(rIid, IID_IdentityUnmarshal))
92  stream << "=\"IdentityUnmarshal\"";
93  else if (IsEqualIID(rIid, IID_IFastRundown))
94  stream << "=\"IFastRundown\"";
95  else if (IsEqualIID(rIid, IID_IStdMarshalInfo))
96  stream << "=\"IStdMarshalInfo\"";
97  else if (IsEqualIID(rIid, IID_IAgileObject))
98  stream << "=\"IAgileObject\"";
99  else if (IsEqualIID(rIid, IID_IExternalConnection))
100  stream << "=\"IExternalConnection\"";
101  else if (IsEqualIID(rIid, IID_ICallFactory))
102  stream << "=\"ICallFactory\"";
103  }
104 
105  CoTaskMemFree(pRiid);
106  return stream;
107 }
108 
109 template <typename charT, typename traits>
110 inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& stream,
111  const VARIANT& rVariant)
112 {
113  if (rVariant.vt & VT_VECTOR)
114  stream << "VECTOR:";
115  if (rVariant.vt & VT_ARRAY)
116  stream << "ARRAY:";
117  if (rVariant.vt & VT_BYREF)
118  stream << "BYREF:";
119 
120  switch (rVariant.vt & ~(VT_VECTOR | VT_ARRAY | VT_BYREF))
121  {
122  case VT_EMPTY:
123  stream << "EMPTY";
124  break;
125  case VT_NULL:
126  stream << "NULL";
127  break;
128  case VT_I2:
129  stream << "I2";
130  break;
131  case VT_I4:
132  stream << "I4";
133  break;
134  case VT_R4:
135  stream << "R4";
136  break;
137  case VT_R8:
138  stream << "R8";
139  break;
140  case VT_CY:
141  stream << "CY";
142  break;
143  case VT_DATE:
144  stream << "DATE";
145  break;
146  case VT_BSTR:
147  stream << "BSTR";
148  break;
149  case VT_DISPATCH:
150  stream << "DISPATCH";
151  break;
152  case VT_ERROR:
153  stream << "ERROR";
154  break;
155  case VT_BOOL:
156  stream << "BOOL";
157  break;
158  case VT_VARIANT:
159  stream << "VARIANT";
160  break;
161  case VT_UNKNOWN:
162  stream << "UNKNOWN";
163  break;
164  case VT_DECIMAL:
165  stream << "DECIMAL";
166  break;
167  case VT_I1:
168  stream << "I1";
169  break;
170  case VT_UI1:
171  stream << "UI1";
172  break;
173  case VT_UI2:
174  stream << "UI2";
175  break;
176  case VT_UI4:
177  stream << "UI4";
178  break;
179  case VT_I8:
180  stream << "I8";
181  break;
182  case VT_UI8:
183  stream << "UI8";
184  break;
185  case VT_INT:
186  stream << "INT";
187  break;
188  case VT_UINT:
189  stream << "UINT";
190  break;
191  case VT_VOID:
192  stream << "VOID";
193  break;
194  case VT_HRESULT:
195  stream << "HRESULT";
196  break;
197  case VT_PTR:
198  stream << "PTR";
199  break;
200  case VT_SAFEARRAY:
201  stream << "SAFEARRAY";
202  break;
203  case VT_CARRAY:
204  stream << "CARRAY";
205  break;
206  case VT_USERDEFINED:
207  stream << "USERDEFINED";
208  break;
209  case VT_LPSTR:
210  stream << "LPSTR";
211  break;
212  case VT_LPWSTR:
213  stream << "LPWSTR";
214  break;
215  case VT_RECORD:
216  stream << "RECORD";
217  break;
218  case VT_INT_PTR:
219  stream << "INT_PTR";
220  break;
221  case VT_UINT_PTR:
222  stream << "UINT_PTR";
223  break;
224  case VT_FILETIME:
225  stream << "FILETIME";
226  break;
227  case VT_BLOB:
228  stream << "BLOB";
229  break;
230  case VT_STREAM:
231  stream << "STREAM";
232  break;
233  case VT_STORAGE:
234  stream << "STORAGE";
235  break;
236  case VT_STREAMED_OBJECT:
237  stream << "STREAMED_OBJECT";
238  break;
239  case VT_STORED_OBJECT:
240  stream << "STORED_OBJECT";
241  break;
242  case VT_BLOB_OBJECT:
243  stream << "BLOB_OBJECT";
244  break;
245  case VT_CF:
246  stream << "CF";
247  break;
248  case VT_CLSID:
249  stream << "CLSID";
250  break;
251  case VT_VERSIONED_STREAM:
252  stream << "VERSIONED_STREAM";
253  break;
254  case VT_BSTR_BLOB:
255  stream << "BSTR_BLOB";
256  break;
257  default:
258  stream << rVariant.vt;
259  break;
260  }
261  if (rVariant.vt == VT_EMPTY || rVariant.vt == VT_NULL || rVariant.vt == VT_VOID)
262  return stream;
263  stream << ":";
264 
265  std::ios_base::fmtflags flags;
266  std::streamsize width;
267  charT fill;
268 
269  if (rVariant.vt & VT_BYREF)
270  {
271  stream << rVariant.byref << ":";
272  if (rVariant.byref == nullptr)
273  return stream;
274  if ((rVariant.vt & VT_TYPEMASK) == VT_VOID || (rVariant.vt & VT_TYPEMASK) == VT_USERDEFINED)
275  return stream;
276  stream << ":";
277  switch (rVariant.vt & VT_TYPEMASK)
278  {
279  case VT_I2:
280  stream << *static_cast<short*>(rVariant.byref);
281  break;
282  case VT_I4:
283  stream << *static_cast<int*>(rVariant.byref);
284  break;
285  case VT_R4:
286  stream << *static_cast<float*>(rVariant.byref);
287  break;
288  case VT_R8:
289  stream << *static_cast<double*>(rVariant.byref);
290  break;
291  case VT_CY:
292  stream << static_cast<CY*>(rVariant.byref)->int64;
293  break;
294  case VT_DATE:
295  stream << *static_cast<double*>(rVariant.byref);
296  break; // FIXME
297  case VT_BSTR:
298  stream << std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes(
299  *static_cast<OLECHAR**>(rVariant.byref));
300  break;
301  case VT_DISPATCH:
302  stream << rVariant.byref;
303  break;
304  case VT_ERROR:
305  case VT_HRESULT:
306  flags = stream.flags();
307  stream << std::hex << *static_cast<int*>(rVariant.byref);
308  stream.setf(flags);
309  break;
310  case VT_BOOL:
311  stream << (*static_cast<VARIANT_BOOL*>(rVariant.byref) ? "YES" : "NO");
312  break;
313  case VT_VARIANT:
314  stream << *static_cast<VARIANT*>(rVariant.byref);
315  break;
316  case VT_UNKNOWN:
317  stream << *static_cast<IUnknown**>(rVariant.byref);
318  break;
319  case VT_DECIMAL:
320  flags = stream.flags();
321  width = stream.width();
322  fill = stream.fill();
323  stream << std::hex << std::setw(8) << std::setfill('0')
324  << static_cast<DECIMAL*>(rVariant.byref)->Hi32;
325  stream << std::setw(16) << static_cast<DECIMAL*>(rVariant.byref)->Lo64;
326  stream.setf(flags);
327  stream << std::setw(width) << std::setfill(fill);
328  break;
329  case VT_I1:
330  stream << static_cast<int>(*static_cast<char*>(rVariant.byref));
331  break;
332  case VT_UI1:
333  stream << static_cast<unsigned int>(*static_cast<unsigned char*>(rVariant.byref));
334  break;
335  case VT_UI2:
336  stream << *static_cast<unsigned short*>(rVariant.byref);
337  break;
338  case VT_UI4:
339  stream << *static_cast<unsigned int*>(rVariant.byref);
340  break;
341  case VT_I8:
342  stream << *static_cast<long long*>(rVariant.byref);
343  break;
344  case VT_UI8:
345  stream << *static_cast<unsigned long long*>(rVariant.byref);
346  break;
347  case VT_INT:
348  stream << *static_cast<int*>(rVariant.byref);
349  break;
350  case VT_UINT:
351  stream << *static_cast<unsigned int*>(rVariant.byref);
352  break;
353  case VT_INT_PTR:
354  stream << *static_cast<intptr_t*>(rVariant.byref);
355  break;
356  case VT_UINT_PTR:
357  stream << *static_cast<uintptr_t*>(rVariant.byref);
358  break;
359  case VT_PTR:
360  case VT_CARRAY:
361  stream << *static_cast<void**>(rVariant.byref);
362  break;
363  case VT_SAFEARRAY:
364  break; // FIXME
365  case VT_LPSTR:
366  stream << *static_cast<char**>(rVariant.byref);
367  break;
368  case VT_LPWSTR:
369  stream << std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes(
370  std::wstring(*static_cast<wchar_t**>(rVariant.byref)));
371  break;
372  case VT_FILETIME:
373  break; // FIXME
374  case VT_BLOB:
375  break; // FIXME
376  case VT_STREAM:
377  break; // FIXME
378  case VT_STORAGE:
379  break; // FIXME
380  case VT_STREAMED_OBJECT:
381  break; // FIXME
382  case VT_STORED_OBJECT:
383  break; // FIXME
384  case VT_BLOB_OBJECT:
385  break; // FIXME
386  case VT_CF:
387  break; // FIXME
388  case VT_CLSID:
389  stream << *static_cast<IID*>(rVariant.byref);
390  break;
391  case VT_VERSIONED_STREAM:
392  break; // FIXME
393  case VT_BSTR_BLOB:
394  break; // FIXME
395  default:
396  stream << "?(" << (rVariant.vt & VT_TYPEMASK) << ")";
397  break;
398  }
399  return stream;
400  }
401 
402  switch (rVariant.vt & VT_TYPEMASK)
403  {
404  case VT_I2:
405  stream << rVariant.iVal;
406  break;
407  case VT_I4:
408  stream << rVariant.lVal;
409  break;
410  case VT_R4:
411  stream << rVariant.fltVal;
412  break;
413  case VT_R8:
414  stream << rVariant.dblVal;
415  break;
416  case VT_CY:
417  stream << rVariant.cyVal.int64;
418  break;
419  case VT_DATE:
420  stream << static_cast<double>(rVariant.date);
421  break; // FIXME
422  case VT_BSTR:
423  if (rVariant.bstrVal == nullptr)
424  stream << "(null)";
425  else
426  stream << std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes(
427  rVariant.bstrVal);
428  break;
429  case VT_DISPATCH:
430  stream << rVariant.pdispVal;
431  break;
432  case VT_ERROR:
433  case VT_HRESULT:
434  flags = stream.flags();
435  stream << std::hex << rVariant.lVal;
436  stream.setf(flags);
437  break;
438  case VT_BOOL:
439  stream << (rVariant.boolVal ? "YES" : "NO");
440  break;
441  case VT_UNKNOWN:
442  stream << rVariant.punkVal;
443  break;
444  case VT_DECIMAL:
445  flags = stream.flags();
446  width = stream.width();
447  fill = stream.fill();
448  stream << std::hex << std::setw(8) << std::setfill('0') << rVariant.decVal.Hi32;
449  stream << std::setw(16) << rVariant.decVal.Lo64;
450  stream.setf(flags);
451  stream << std::setw(width) << std::setfill(fill);
452  break;
453  case VT_I1:
454  stream << static_cast<int>(rVariant.bVal);
455  break;
456  case VT_UI1:
457  stream << static_cast<unsigned int>(rVariant.bVal);
458  break;
459  case VT_UI2:
460  stream << static_cast<unsigned short>(rVariant.iVal);
461  break;
462  case VT_UI4:
463  stream << static_cast<unsigned int>(rVariant.lVal);
464  break;
465  case VT_I8:
466  stream << rVariant.llVal;
467  break;
468  case VT_UI8:
469  stream << static_cast<unsigned long long>(rVariant.llVal);
470  break;
471  case VT_INT:
472  stream << rVariant.lVal;
473  break;
474  case VT_UINT:
475  stream << static_cast<unsigned int>(rVariant.lVal);
476  break;
477  case VT_INT_PTR:
478  stream << reinterpret_cast<intptr_t>(rVariant.plVal);
479  break;
480  case VT_UINT_PTR:
481  stream << reinterpret_cast<uintptr_t>(rVariant.plVal);
482  break;
483  case VT_PTR:
484  case VT_CARRAY:
485  stream << rVariant.byref;
486  break;
487  case VT_SAFEARRAY:
488  break; // FIXME
489  case VT_LPSTR:
490  stream << rVariant.bstrVal;
491  break;
492  case VT_LPWSTR:
493  stream << std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>().to_bytes(
494  std::wstring(static_cast<wchar_t*>(rVariant.byref)));
495  break;
496  case VT_FILETIME:
497  break; // FIXME
498  case VT_BLOB:
499  break; // FIXME
500  case VT_STREAM:
501  break; // FIXME
502  case VT_STORAGE:
503  break; // FIXME
504  case VT_STREAMED_OBJECT:
505  break; // FIXME
506  case VT_STORED_OBJECT:
507  break; // FIXME
508  case VT_BLOB_OBJECT:
509  break; // FIXME
510  case VT_CF:
511  break; // FIXME
512  case VT_VERSIONED_STREAM:
513  break; // FIXME
514  case VT_BSTR_BLOB:
515  break; // FIXME
516  default:
517  stream << "?(" << (rVariant.vt & VT_TYPEMASK) << ")";
518  break;
519  }
520  return stream;
521 }
522 
523 #endif // INCLUDED_COMPHELPER_WINDOWSDEBUGOUTPUT_HXX
524 
525 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
#define VT_BLOB
#define VT_STREAMED_OBJECT
#define VT_R8
#define VT_UINT
#define VT_UI8
#define VT_I4
#define VT_ARRAY
#define VT_TYPEMASK
#define VT_UI2
#define VT_DATE
#define VT_STORED_OBJECT
#define VT_DECIMAL
#define VT_I1
#define VT_BSTR
#define VT_NULL
#define VT_BOOL
#define VT_INT
#define VT_CY
#define VT_CLSID
#define VT_LPSTR
#define VT_I8
#define VT_STORAGE
#define VT_STREAM
#define VT_ERROR
exports com.sun.star.chart2. data
Reference< XOutputStream > stream
#define VT_EMPTY
#define VT_R4
#define VT_FILETIME
#define VT_CF
#define VT_LPWSTR
DEFINE_GUID(OID_ServiceManager, 0x82154420, 0xfbf, 0x11d4, 0x83, 0x13, 0x0, 0x50, 0x4, 0x52, 0x6a, 0xb4)
#define VT_BYREF
#define VT_UI1
#define VT_BLOB_OBJECT
#define VT_VECTOR
#define VT_VARIANT
#define VT_UI4
#define VT_I2