1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
3 * This file is part of the LibreOffice project.
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/.
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.
15 #ifndef INCLUDED_COMPHELPER_WINDOWSDEBUGOUTPUT_HXX
16 #define INCLUDED_COMPHELPER_WINDOWSDEBUGOUTPUT_HXX
24 #ifdef LIBO_INTERNAL_ONLY
34 DEFINE_GUID(IID_IdentityUnmarshal
, 0x0000001B, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
38 template <typename charT
, typename traits
>
39 inline std::basic_ostream
<charT
, traits
>& operator<<(std::basic_ostream
<charT
, traits
>& stream
,
43 if (StringFromIID(rIid
, &pRiid
) != S_OK
)
46 stream
<< std::wstring_convert
<std::codecvt_utf8
<wchar_t>, wchar_t>().to_bytes(
50 if (RegGetValueW(HKEY_CLASSES_ROOT
, std::wstring(L
"CLSID\\").append(pRiid
).data(), nullptr,
51 RRF_RT_REG_SZ
, nullptr, nullptr, &nSize
)
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
)
60 << std::wstring_convert
<std::codecvt_utf8
<wchar_t>, wchar_t>().to_bytes(
61 std::wstring(sValue
.data()))
65 else if (RegGetValueW(HKEY_CLASSES_ROOT
, std::wstring(L
"Interface\\").append(pRiid
).data(),
66 nullptr, RRF_RT_REG_SZ
, nullptr, nullptr, &nSize
)
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
)
75 << std::wstring_convert
<std::codecvt_utf8
<wchar_t>, wchar_t>().to_bytes(
76 std::wstring(sValue
.data()))
82 // Special case well-known interfaces that pop up a lot, but which don't have their name in
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\"";
105 CoTaskMemFree(pRiid
);
109 template <typename charT
, typename traits
>
110 inline std::basic_ostream
<charT
, traits
>& operator<<(std::basic_ostream
<charT
, traits
>& stream
,
111 const VARIANT
& rVariant
)
113 if (rVariant
.vt
& VT_VECTOR
)
115 if (rVariant
.vt
& VT_ARRAY
)
117 if (rVariant
.vt
& VT_BYREF
)
120 switch (rVariant
.vt
& ~(VT_VECTOR
| VT_ARRAY
| VT_BYREF
))
150 stream
<< "DISPATCH";
201 stream
<< "SAFEARRAY";
207 stream
<< "USERDEFINED";
222 stream
<< "UINT_PTR";
225 stream
<< "FILETIME";
236 case VT_STREAMED_OBJECT
:
237 stream
<< "STREAMED_OBJECT";
239 case VT_STORED_OBJECT
:
240 stream
<< "STORED_OBJECT";
243 stream
<< "BLOB_OBJECT";
251 case VT_VERSIONED_STREAM
:
252 stream
<< "VERSIONED_STREAM";
255 stream
<< "BSTR_BLOB";
258 stream
<< rVariant
.vt
;
261 if (rVariant
.vt
== VT_EMPTY
|| rVariant
.vt
== VT_NULL
|| rVariant
.vt
== VT_VOID
)
265 std::ios_base::fmtflags flags
;
266 std::streamsize width
;
269 if (rVariant
.vt
& VT_BYREF
)
271 stream
<< rVariant
.byref
<< ":";
272 if (rVariant
.byref
== nullptr)
274 if ((rVariant
.vt
& VT_TYPEMASK
) == VT_VOID
|| (rVariant
.vt
& VT_TYPEMASK
) == VT_USERDEFINED
)
277 switch (rVariant
.vt
& VT_TYPEMASK
)
280 stream
<< *static_cast<short*>(rVariant
.byref
);
283 stream
<< *static_cast<int*>(rVariant
.byref
);
286 stream
<< *static_cast<float*>(rVariant
.byref
);
289 stream
<< *static_cast<double*>(rVariant
.byref
);
292 stream
<< static_cast<CY
*>(rVariant
.byref
)->int64
;
295 stream
<< *static_cast<double*>(rVariant
.byref
);
298 stream
<< std::wstring_convert
<std::codecvt_utf8
<wchar_t>, wchar_t>().to_bytes(
299 *static_cast<OLECHAR
**>(rVariant
.byref
));
302 stream
<< rVariant
.byref
;
306 flags
= stream
.flags();
307 stream
<< std::hex
<< *static_cast<int*>(rVariant
.byref
);
311 stream
<< (*static_cast<VARIANT_BOOL
*>(rVariant
.byref
) ? "YES" : "NO");
314 stream
<< *static_cast<VARIANT
*>(rVariant
.byref
);
317 stream
<< *static_cast<IUnknown
**>(rVariant
.byref
);
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
;
327 stream
<< std::setw(width
) << std::setfill(fill
);
330 stream
<< static_cast<int>(*static_cast<char*>(rVariant
.byref
));
333 stream
<< static_cast<unsigned int>(*static_cast<unsigned char*>(rVariant
.byref
));
336 stream
<< *static_cast<unsigned short*>(rVariant
.byref
);
339 stream
<< *static_cast<unsigned int*>(rVariant
.byref
);
342 stream
<< *static_cast<long long*>(rVariant
.byref
);
345 stream
<< *static_cast<unsigned long long*>(rVariant
.byref
);
348 stream
<< *static_cast<int*>(rVariant
.byref
);
351 stream
<< *static_cast<unsigned int*>(rVariant
.byref
);
354 stream
<< *static_cast<intptr_t*>(rVariant
.byref
);
357 stream
<< *static_cast<uintptr_t*>(rVariant
.byref
);
361 stream
<< *static_cast<void**>(rVariant
.byref
);
366 stream
<< *static_cast<char**>(rVariant
.byref
);
369 stream
<< std::wstring_convert
<std::codecvt_utf8
<wchar_t>, wchar_t>().to_bytes(
370 std::wstring(*static_cast<wchar_t**>(rVariant
.byref
)));
380 case VT_STREAMED_OBJECT
:
382 case VT_STORED_OBJECT
:
389 stream
<< *static_cast<IID
*>(rVariant
.byref
);
391 case VT_VERSIONED_STREAM
:
396 stream
<< "?(" << (rVariant
.vt
& VT_TYPEMASK
) << ")";
402 switch (rVariant
.vt
& VT_TYPEMASK
)
405 stream
<< rVariant
.iVal
;
408 stream
<< rVariant
.lVal
;
411 stream
<< rVariant
.fltVal
;
414 stream
<< rVariant
.dblVal
;
417 stream
<< rVariant
.cyVal
.int64
;
420 stream
<< static_cast<double>(rVariant
.date
);
423 if (rVariant
.bstrVal
== nullptr)
426 stream
<< std::wstring_convert
<std::codecvt_utf8
<wchar_t>, wchar_t>().to_bytes(
430 stream
<< rVariant
.pdispVal
;
434 flags
= stream
.flags();
435 stream
<< std::hex
<< rVariant
.lVal
;
439 stream
<< (rVariant
.boolVal
? "YES" : "NO");
442 stream
<< rVariant
.punkVal
;
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
;
451 stream
<< std::setw(width
) << std::setfill(fill
);
454 stream
<< static_cast<int>(rVariant
.bVal
);
457 stream
<< static_cast<unsigned int>(rVariant
.bVal
);
460 stream
<< static_cast<unsigned short>(rVariant
.iVal
);
463 stream
<< static_cast<unsigned int>(rVariant
.lVal
);
466 stream
<< rVariant
.llVal
;
469 stream
<< static_cast<unsigned long long>(rVariant
.llVal
);
472 stream
<< rVariant
.lVal
;
475 stream
<< static_cast<unsigned int>(rVariant
.lVal
);
478 stream
<< reinterpret_cast<intptr_t>(rVariant
.plVal
);
481 stream
<< reinterpret_cast<uintptr_t>(rVariant
.plVal
);
485 stream
<< rVariant
.byref
;
490 stream
<< std::wstring_convert
<std::codecvt_utf8
<wchar_t>, wchar_t>().to_bytes(
494 stream
<< std::wstring_convert
<std::codecvt_utf8
<wchar_t>, wchar_t>().to_bytes(
495 std::wstring(static_cast<wchar_t*>(rVariant
.byref
)));
505 case VT_STREAMED_OBJECT
:
507 case VT_STORED_OBJECT
:
513 case VT_VERSIONED_STREAM
:
518 stream
<< "?(" << (rVariant
.vt
& VT_TYPEMASK
) << ")";
524 inline std::string
DMPAPER_to_string(int dmpaper
)
530 case DMPAPER_LETTERSMALL
:
531 return "LETTERSMALL";
532 case DMPAPER_TABLOID
:
538 case DMPAPER_STATEMENT
:
540 case DMPAPER_EXECUTIVE
:
546 case DMPAPER_A4SMALL
:
590 case DMPAPER_ENV_C65
:
598 case DMPAPER_ENV_ITALY
:
600 case DMPAPER_ENV_MONARCH
:
601 return "ENV_MONARCH";
602 case DMPAPER_ENV_PERSONAL
:
603 return "ENV_PERSONAL";
604 case DMPAPER_FANFOLD_US
:
606 case DMPAPER_FANFOLD_STD_GERMAN
:
607 return "FANFOLD_STD_GERMAN";
608 case DMPAPER_FANFOLD_LGL_GERMAN
:
609 return "FANFOLD_LGL_GERMAN";
612 case DMPAPER_JAPANESE_POSTCARD
:
613 return "JAPANESE_POSTCARD";
620 case DMPAPER_ENV_INVITE
:
622 case DMPAPER_RESERVED_48
:
623 return "RESERVED_48";
624 case DMPAPER_RESERVED_49
:
625 return "RESERVED_49";
626 case DMPAPER_LETTER_EXTRA
:
627 return "LETTER_EXTRA";
628 case DMPAPER_LEGAL_EXTRA
:
629 return "LEGAL_EXTRA";
630 case DMPAPER_TABLOID_EXTRA
:
631 return "TABLOID_EXTRA";
632 case DMPAPER_A4_EXTRA
:
634 case DMPAPER_LETTER_TRANSVERSE
:
635 return "LETTER_TRANSVERSE";
636 case DMPAPER_A4_TRANSVERSE
:
637 return "A4_TRANSVERSE";
638 case DMPAPER_LETTER_EXTRA_TRANSVERSE
:
639 return "LETTER_EXTRA_TRANSVERSE";
644 case DMPAPER_LETTER_PLUS
:
645 return "LETTER_PLUS";
646 case DMPAPER_A4_PLUS
:
648 case DMPAPER_A5_TRANSVERSE
:
649 return "A5_TRANSVERSE";
650 case DMPAPER_B5_TRANSVERSE
:
651 return "B5_TRANSVERSE";
652 case DMPAPER_A3_EXTRA
:
654 case DMPAPER_A5_EXTRA
:
656 case DMPAPER_B5_EXTRA
:
660 case DMPAPER_A3_TRANSVERSE
:
661 return "A3_TRANSVERSE";
662 case DMPAPER_A3_EXTRA_TRANSVERSE
:
663 return "A3_EXTRA_TRANSVERSE";
664 case DMPAPER_DBL_JAPANESE_POSTCARD
:
665 return "DBL_JAPANESE_POSTCARD";
668 case DMPAPER_JENV_KAKU2
:
670 case DMPAPER_JENV_KAKU3
:
672 case DMPAPER_JENV_CHOU3
:
674 case DMPAPER_JENV_CHOU4
:
676 case DMPAPER_LETTER_ROTATED
:
677 return "LETTER_ROTATED";
678 case DMPAPER_A3_ROTATED
:
680 case DMPAPER_A4_ROTATED
:
682 case DMPAPER_A5_ROTATED
:
684 case DMPAPER_B4_JIS_ROTATED
:
685 return "B4_JIS_ROTATED";
686 case DMPAPER_B5_JIS_ROTATED
:
687 return "B5_JIS_ROTATED";
688 case DMPAPER_JAPANESE_POSTCARD_ROTATED
:
689 return "JAPANESE_POSTCARD_ROTATED";
690 case DMPAPER_DBL_JAPANESE_POSTCARD_ROTATED
:
691 return "DBL_JAPANESE_POSTCARD_ROTATED";
692 case DMPAPER_A6_ROTATED
:
694 case DMPAPER_JENV_KAKU2_ROTATED
:
695 return "JENV_KAKU2_ROTATED";
696 case DMPAPER_JENV_KAKU3_ROTATED
:
697 return "JENV_KAKU3_ROTATED";
698 case DMPAPER_JENV_CHOU3_ROTATED
:
699 return "JENV_CHOU3_ROTATED";
700 case DMPAPER_JENV_CHOU4_ROTATED
:
701 return "JENV_CHOU4_ROTATED";
704 case DMPAPER_B6_JIS_ROTATED
:
705 return "B6_JIS_ROTATED";
708 case DMPAPER_JENV_YOU4
:
710 case DMPAPER_JENV_YOU4_ROTATED
:
711 return "JENV_YOU4_ROTATED";
716 case DMPAPER_P32KBIG
:
736 case DMPAPER_PENV_10
:
738 case DMPAPER_P16K_ROTATED
:
739 return "P16K_ROTATED";
740 case DMPAPER_P32K_ROTATED
:
741 return "P32K_ROTATED";
742 case DMPAPER_P32KBIG_ROTATED
:
743 return "P32KBIG_ROTATED";
744 case DMPAPER_PENV_1_ROTATED
:
745 return "PENV_1_ROTATED";
746 case DMPAPER_PENV_2_ROTATED
:
747 return "PENV_2_ROTATED";
748 case DMPAPER_PENV_3_ROTATED
:
749 return "PENV_3_ROTATED";
750 case DMPAPER_PENV_4_ROTATED
:
751 return "PENV_4_ROTATED";
752 case DMPAPER_PENV_5_ROTATED
:
753 return "PENV_5_ROTATED";
754 case DMPAPER_PENV_6_ROTATED
:
755 return "PENV_6_ROTATED";
756 case DMPAPER_PENV_7_ROTATED
:
757 return "PENV_7_ROTATED";
758 case DMPAPER_PENV_8_ROTATED
:
759 return "PENV_8_ROTATED";
760 case DMPAPER_PENV_9_ROTATED
:
761 return "PENV_9_ROTATED";
762 case DMPAPER_PENV_10_ROTATED
:
763 return "PENV_10_ROTATED";
765 return "?" + std::to_string(dmpaper
);
769 inline std::string
DC_PAPERSIZE_array_to_string(POINT
* pPaperSizes
, DWORD nCount
)
773 for (DWORD i
= 0; i
< nCount
; i
++)
778 result
+= std::to_string(std::lround(pPaperSizes
[i
].x
/ 10.0)) + "x"
779 + std::to_string(std::lround(pPaperSizes
[i
].y
/ 10.0));
782 // WIP. Printer::GetPaperName() should really be inline in <i18nutil/paper.hxx> or
783 // something, so that it can be used anywhere. We can't depend on vcl in this file as we
784 // might be included in modules that precede vcl.
785 PaperInfo
paperInfo(pPaperSizes
[i
].x
* 10, pPaperSizes
[i
].y
* 10);
786 paperInfo
.doSloppyFit(true);
787 if (paperInfo
.getPaper() != PAPER_USER
)
788 result
+= "(" + std::string(Printer::GetPaperName(paperInfo
.getPaper()).toUtf8().getStr()) + ")";
794 #endif // INCLUDED_COMPHELPER_WINDOWSDEBUGOUTPUT_HXX
796 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */