LibreOffice Module comphelper (master) 1
anytohash.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20
22
23#include <o3tl/hash_combine.hxx>
24#include <typelib/typedescription.hxx>
25
26#include <com/sun/star/uno/Sequence.hxx>
27
29
30using namespace ::com::sun::star;
31using ::com::sun::star::uno::TypeDescription;
32using ::comphelper::detail::TypeDescriptionRef;
33
34namespace comphelper {
35namespace {
36
37std::optional<size_t> hashValue( size_t hash,
38 void const * val, typelib_TypeDescriptionReference * typeRef )
39{
40 o3tl::hash_combine( hash, typeRef->eTypeClass );
41 if (typeRef->eTypeClass == typelib_TypeClass_VOID) {
42 return hash;
43 }
44 assert(val != nullptr);
45
46 switch (typeRef->eTypeClass) {
47 case typelib_TypeClass_INTERFACE: {
48 return std::nullopt; // not implemented
49 }
50 case typelib_TypeClass_STRUCT:
51 case typelib_TypeClass_EXCEPTION: {
52 TypeDescription typeDescr( typeRef );
53 if (!typeDescr.is())
54 typeDescr.makeComplete();
55 if (!typeDescr.is())
56 return std::nullopt;
57
58 typelib_CompoundTypeDescription * compType =
59 reinterpret_cast< typelib_CompoundTypeDescription * >(
60 typeDescr.get() );
61 sal_Int32 nDescr = compType->nMembers;
62
63 if (compType->pBaseTypeDescription) {
64 std::optional<size_t> tmpHash = hashValue(
65 hash, val, reinterpret_cast<
67 compType->pBaseTypeDescription)->pWeakRef);
68 if(!tmpHash.has_value())
69 return std::nullopt;
70 hash = *tmpHash;
71 }
72
73 typelib_TypeDescriptionReference ** ppTypeRefs =
74 compType->ppTypeRefs;
75 sal_Int32 * memberOffsets = compType->pMemberOffsets;
76
77 for ( sal_Int32 nPos = 0; nPos < nDescr; ++nPos )
78 {
79 TypeDescriptionRef memberType( ppTypeRefs[ nPos ] );
80 if (!memberType.is())
81 return std::nullopt;
82
83 std::optional<size_t> tmpHash = hashValue( hash,
84 static_cast< char const * >(
85 val ) + memberOffsets[ nPos ],
86 memberType->pWeakRef );
87 if(!tmpHash.has_value())
88 return std::nullopt;
89 hash = *tmpHash;
90 }
91 break;
92 }
93 case typelib_TypeClass_SEQUENCE: {
94 TypeDescriptionRef typeDescr( typeRef );
95 if (!typeDescr.is())
96 return std::nullopt;
97
98 typelib_TypeDescriptionReference * elementTypeRef =
99 reinterpret_cast<
100 typelib_IndirectTypeDescription * >(typeDescr.get())->pType;
101 TypeDescriptionRef elementTypeDescr( elementTypeRef );
102 if (!elementTypeDescr.is())
103 return std::nullopt;
104
105 sal_Int32 nElementSize = elementTypeDescr->nSize;
106 uno_Sequence * seq =
107 *static_cast< uno_Sequence * const * >(val);
108 sal_Int32 nElements = seq->nElements;
109
110 if (nElements > 0)
111 {
112 char const * pElements = seq->elements;
113 for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
114 {
115 std::optional<size_t> tmpHash = hashValue( hash,
116 pElements + (nElementSize * nPos),
117 elementTypeDescr->pWeakRef );
118 if(!tmpHash.has_value())
119 return std::nullopt;
120 hash = *tmpHash;
121 }
122 }
123 break;
124 }
125 case typelib_TypeClass_ANY: {
126 uno_Any const * pAny = static_cast< uno_Any const * >(val);
127 return hashValue( hash, pAny->pData, pAny->pType );
128 }
129 case typelib_TypeClass_TYPE: {
130 OUString const & str = OUString::unacquired(
131 &(*static_cast<
132 typelib_TypeDescriptionReference * const * >(val)
133 )->pTypeName );
134 o3tl::hash_combine( hash, str.hashCode() );
135 break;
136 }
137 case typelib_TypeClass_STRING: {
138 OUString const & str = OUString::unacquired(
139 static_cast< rtl_uString * const * >(val) );
140 o3tl::hash_combine( hash, str.hashCode() );
141 break;
142 }
143 case typelib_TypeClass_ENUM: {
144 TypeDescription typeDescr( typeRef );
145 if (!typeDescr.is())
146 typeDescr.makeComplete();
147 if (!typeDescr.is())
148 return std::nullopt;
149
150 o3tl::hash_combine( hash, *static_cast< int const * >(val));
151 break;
152 }
153 case typelib_TypeClass_BOOLEAN:
154 if (*static_cast< sal_Bool const * >(val))
155 o3tl::hash_combine( hash, true );
156 else
157 o3tl::hash_combine( hash, false );
158 break;
159 case typelib_TypeClass_CHAR: {
160 o3tl::hash_combine( hash, *static_cast< sal_Unicode const * >(val));
161 break;
162 }
163 case typelib_TypeClass_FLOAT:
164 o3tl::hash_combine( hash, *static_cast< float const * >(val) );
165 break;
166 case typelib_TypeClass_DOUBLE:
167 o3tl::hash_combine( hash, *static_cast< double const * >(val) );
168 break;
169 case typelib_TypeClass_BYTE:
170 o3tl::hash_combine( hash, *static_cast< sal_Int8 const * >(val) );
171 break;
172 case typelib_TypeClass_SHORT:
173 o3tl::hash_combine( hash, *static_cast< sal_Int16 const * >(val) );
174 break;
175 case typelib_TypeClass_UNSIGNED_SHORT:
176 o3tl::hash_combine( hash, *static_cast< sal_uInt16 const * >(val) );
177 break;
178 case typelib_TypeClass_LONG:
179 o3tl::hash_combine( hash, *static_cast< sal_Int32 const * >(val) );
180 break;
181 case typelib_TypeClass_UNSIGNED_LONG:
182 o3tl::hash_combine( hash, *static_cast< sal_uInt32 const * >(val) );
183 break;
184 case typelib_TypeClass_HYPER:
185 o3tl::hash_combine( hash, *static_cast< sal_Int64 const * >(val) );
186 break;
187 case typelib_TypeClass_UNSIGNED_HYPER:
188 o3tl::hash_combine( hash, *static_cast< sal_uInt64 const * >(val) );
189 break;
190// case typelib_TypeClass_UNKNOWN:
191// case typelib_TypeClass_SERVICE:
192// case typelib_TypeClass_MODULE:
193 default:
194 return std::nullopt;
195 }
196 return hash;
197}
198
199} // anon namespace
200
201
202std::optional<size_t> anyToHash( uno::Any const & value )
203{
204 size_t hash = 0;
205 return hashValue( hash, value.getValue(), value.getValueTypeRef());
206}
207
208} // namespace comphelper
209
210/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Any value
sal_Int32 nElements
sal_uInt16 nPos
struct _typelib_TypeDescription typelib_TypeDescription
struct _uno_Any uno_Any
std::optional< size_t > anyToHash(uno::Any const &value)
Definition: anytohash.cxx:202
std::enable_if_t<(sizeof(N)==4)> hash_combine(N &nSeed, T const *pValue, size_t nCount)
unsigned char sal_Bool
sal_uInt16 sal_Unicode
signed char sal_Int8