14#include <com/sun/star/container/NoSuchElementException.hpp>
15#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
16#include <com/sun/star/lang/DisposedException.hpp>
17#include <com/sun/star/lang/IllegalArgumentException.hpp>
18#include <com/sun/star/reflection/XConstantTypeDescription.hpp>
19#include <com/sun/star/reflection/XConstantsTypeDescription.hpp>
20#include <com/sun/star/reflection/XDump.hpp>
21#include <com/sun/star/uno/Any.hxx>
22#include <com/sun/star/uno/DeploymentException.hpp>
23#include <com/sun/star/uno/Reference.hxx>
24#include <com/sun/star/uno/Sequence.hxx>
25#include <com/sun/star/uno/Type.hxx>
26#include <com/sun/star/uno/TypeClass.hpp>
27#include <com/sun/star/uno/XComponentContext.hpp>
28#include <config_typesizes.h>
34#include <osl/mutex.hxx>
35#include <rtl/ustrbuf.hxx>
36#include <rtl/ustring.hxx>
39#include <typelib/typedescription.h>
40#include <typelib/typedescription.hxx>
41#include <uno/sequence2.h>
50template <
typename T> OUString hex(T value, sal_Int32 width)
52 OUStringBuffer buf(OUString::number(value, 16));
53 while (buf.getLength() < width)
57 return buf.makeStringAndClear();
60css::uno::TypeDescription getTypeDescription(css::uno::Type
const& type)
63 type.getDescription(&d);
64 return css::uno::TypeDescription(d);
68getIdentifier(css::uno::Reference<css::reflection::XConstantTypeDescription>
const& constant)
70 auto const n = constant->getName();
71 auto const i =
n.lastIndexOf(
'.');
72 if (i == -1 || i ==
n.getLength() - 1)
74 throw css::uno::DeploymentException(
"bad constant name " + n);
80dumpBitset(css::uno::Sequence<css::uno::Reference<css::reflection::XConstantTypeDescription>>
const&
86 for (
auto const& i : constants)
89 if ((
i->getConstantValue() >>= c) && std::bitset<64>{ c }.count() == 1 && (a & c) != 0)
99 return a == 0 && !buf.isEmpty() ? buf.makeStringAndClear() : OUString::number(value);
102class Dump :
public cppu::BaseMutex,
public cppu::WeakComponentImplHelper<css::reflection::XDump>
105 explicit Dump(css::uno::Reference<css::uno::XComponentContext>
const& context)
108 "/singletons/com.sun.star.reflection.theTypeDescriptionManager"),
109 css::
uno::UNO_QUERY_THROW)
113 void SAL_CALL disposing()
override
115 osl::MutexGuard g(m_aMutex);
119 OUString SAL_CALL dumpValue(css::uno::Any
const& value)
override
121 switch (
value.getValueTypeClass())
123 case css::uno::TypeClass_VOID:
125 case css::uno::TypeClass_BOOLEAN:
126 return OUString::boolean(
value.get<
bool>());
127 case css::uno::TypeClass_BYTE:
129 case css::uno::TypeClass_SHORT:
130 return OUString::number(
value.get<sal_Int16>());
131 case css::uno::TypeClass_UNSIGNED_SHORT:
132 return OUString::number(
value.get<sal_uInt16>());
133 case css::uno::TypeClass_LONG:
134 return OUString::number(
value.get<sal_Int32>());
135 case css::uno::TypeClass_UNSIGNED_LONG:
136 return OUString::number(
value.get<sal_uInt32>());
137 case css::uno::TypeClass_HYPER:
138 return OUString::number(
value.get<sal_Int64>());
139 case css::uno::TypeClass_UNSIGNED_HYPER:
140 return OUString::number(
value.get<sal_uInt64>());
141 case css::uno::TypeClass_FLOAT:
142 return OUString::number(
value.get<
float>());
143 case css::uno::TypeClass_DOUBLE:
144 return OUString::number(
value.get<
double>());
145 case css::uno::TypeClass_CHAR:
147 case css::uno::TypeClass_STRING:
149 auto const s =
value.get<OUString>();
151 for (sal_Int32 i = 0;
i != s.getLength();)
153 auto const c = s.iterateCodePoints(&i);
154 if (c >= u8
' ' && c <= u8
'~')
156 if (c == u8
'\"' || c == u8
'\\')
162 else if (c <= 0xFFFF)
164 buf.append(
"\\u" + hex(c, 4));
168 buf.append(
"\\U" + hex(c, 8));
171 return "\"" + buf +
"\"";
173 case css::uno::TypeClass_TYPE:
175 case css::uno::TypeClass_SEQUENCE:
177 css::uno::Type
const t(
reinterpret_cast<typelib_IndirectTypeDescription const*
>(
178 getTypeDescription(
value.getValueType()).get())
180 auto const n = getTypeDescription(t).get()->nSize;
181 auto const s = *
static_cast<uno_Sequence* const*
>(
value.getValue());
183 for (sal_Int32 i = 0;
i != s->nElements; ++
i)
189 css::uno::Any
const e(s->elements + i * n, t);
193 return "[" + buf +
"]";
195 case css::uno::TypeClass_ENUM:
197 auto const d = getTypeDescription(
value.getValueType());
198 auto const ed =
reinterpret_cast<typelib_EnumTypeDescription const*
>(
d.get());
199 auto const e = *
static_cast<sal_Int32 const*
>(
value.getValue());
200 for (sal_Int32 i = 0;
i != ed->nEnumValues; ++
i)
202 if (ed->pEnumValues[i] == e)
204 return OUString(ed->ppEnumNames[i]);
207 return OUString::number(e);
209 case css::uno::TypeClass_STRUCT:
210 case css::uno::TypeClass_EXCEPTION:
212 auto const d = getTypeDescription(
value.getValueType());
214 dumpCompoundType(
reinterpret_cast<typelib_CompoundTypeDescription const*
>(
d.get()),
215 value.getValue(), &buf);
216 return "[" + buf +
"]";
218 case css::uno::TypeClass_INTERFACE:
220 auto const p = *
static_cast<void* const*
>(
value.getValue());
221 return p ==
nullptr ? OUString(
"null")
223 + hex(reinterpret_cast<sal_uIntPtr>(
p),
224 SAL_TYPES_SIZEOFPOINTER * 2));
231 OUString SAL_CALL dumpAny(css::uno::Any
const& value)
override
233 return "[" +
value.getValueType().getTypeName() +
": " + dumpValue(value) +
"]";
236 OUString SAL_CALL dumpConstant(OUString
const& constantsGroup,
237 css::uno::Any
const& value)
override
239 css::uno::Reference<css::container::XHierarchicalNameAccess>
manager;
241 osl::MutexGuard g(m_aMutex);
242 if (rBHelper.bDisposed)
244 throw css::lang::DisposedException(
"css.reflection.Dumper");
248 css::uno::Reference<css::reflection::XConstantsTypeDescription> g;
251 manager_->getByHierarchicalName(constantsGroup) >>= g;
253 catch (css::container::NoSuchElementException)
258 throw css::lang::IllegalArgumentException(
"not a constants group: " + constantsGroup,
261 auto const s = g->getConstants();
262 switch (
value.getValueTypeClass())
264 case css::uno::TypeClass_BOOLEAN:
265 for (
auto const& i : s)
267 if (
i->getConstantValue() == value)
272 return OUString::boolean(
value.get<
bool>());
273 case css::uno::TypeClass_BYTE:
274 case css::uno::TypeClass_SHORT:
275 case css::uno::TypeClass_LONG:
276 case css::uno::TypeClass_HYPER:
278 auto const v =
value.get<sal_Int64>();
279 for (
auto const& i : s)
282 if ((
i->getConstantValue() >>= c) && c ==
v)
287 return v >= 0 ? dumpBitset(s, v) : OUString::number(
v);
289 case css::uno::TypeClass_UNSIGNED_SHORT:
290 case css::uno::TypeClass_UNSIGNED_LONG:
291 case css::uno::TypeClass_UNSIGNED_HYPER:
293 auto const v =
value.get<sal_uInt64>();
294 for (
auto const& i : s)
297 if ((
i->getConstantValue() >>= c) && c ==
v)
302 return dumpBitset(s, v);
304 case css::uno::TypeClass_FLOAT:
305 case css::uno::TypeClass_DOUBLE:
307 auto const v =
value.get<
double>();
308 for (
auto const& i : s)
311 if ((
i->getConstantValue() >>= c) && c ==
v)
316 return OUString::number(v);
319 throw css::lang::IllegalArgumentException(
320 "not a numeric type: " +
value.getValueTypeName(), {}, 1);
325 css::uno::Reference<css::container::XHierarchicalNameAccess>
manager_;
327 void dumpCompoundType(typelib_CompoundTypeDescription
const* description,
void const* data,
328 OUStringBuffer* buffer)
330 if (
auto base = description->pBaseTypeDescription)
332 dumpCompoundType(base, data, buffer);
334 for (sal_Int32 i = 0;
i != description->nMembers; ++
i)
336 if (!buffer->isEmpty())
338 buffer->append(
", ");
340 buffer->append(OUString::unacquired(description->ppMemberNames + i) +
": ");
341 css::uno::Type
t(description->ppTypeRefs[i]);
342 css::uno::Any
const m(
static_cast<char const*
>(data) + description->pMemberOffsets[i],
350extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
352 css::uno::Sequence<css::uno::Any>
const& arguments)
354 SAL_WARN_IF(arguments.hasElements(),
"stoc",
"unexpected singleton arguments");
355 return cppu::acquire(
new Dump(context));
rtl::Reference< ParseManager > manager
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_stoc_Dump_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &arguments)
rtl::Reference< Manager > manager_
#define SAL_WARN_IF(condition, area, stream)
struct _typelib_TypeDescription typelib_TypeDescription
rtl::OUString getTypeName(rtl::OUString const &rEnvDcp)
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC OUString getIdentifier(css::uno::Reference< css::deployment::XPackage > const &package)