Line data Source code
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 : #include <sal/config.h>
21 :
22 : #include <cstring>
23 : #include <memory>
24 : #include <new>
25 :
26 : #include <string.h>
27 : #include <sal/types.h>
28 : #include <osl/endian.h>
29 : #include <osl/diagnose.h>
30 : #include <registry/reflread.hxx>
31 : #include <sal/log.hxx>
32 :
33 : #include "registry/typereg_reader.hxx"
34 : #include "registry/version.h"
35 :
36 : #include "reflcnst.hxx"
37 :
38 : #include <cstddef>
39 :
40 : static const sal_Char NULL_STRING[1] = { 0 };
41 : static const sal_Unicode NULL_WSTRING[1] = { 0 };
42 :
43 : const sal_uInt32 magic = 0x12345678;
44 : const sal_uInt16 minorVersion = 0x0000;
45 : const sal_uInt16 majorVersion = 0x0001;
46 :
47 : /**************************************************************************
48 :
49 : class BlopObject
50 :
51 : holds any data in a flat memory buffer
52 :
53 : **************************************************************************/
54 :
55 : class BlopObject
56 : {
57 : public:
58 : struct BoundsError {};
59 :
60 : const sal_uInt8* m_pBuffer;
61 : sal_uInt32 m_bufferLen;
62 : bool m_isCopied;
63 :
64 : BlopObject(const sal_uInt8* buffer, sal_uInt32 len, bool copyBuffer);
65 : // throws std::bad_alloc
66 :
67 : ~BlopObject();
68 :
69 0 : inline sal_uInt8 readBYTE(sal_uInt32 index) const
70 : {
71 0 : if (index >= m_bufferLen) {
72 0 : throw BoundsError();
73 : }
74 0 : return m_pBuffer[index];
75 : }
76 :
77 0 : inline sal_Int16 readINT16(sal_uInt32 index) const
78 : {
79 0 : if (m_bufferLen < 2 || index >= m_bufferLen - 1) {
80 0 : throw BoundsError();
81 : }
82 0 : return ((m_pBuffer[index] << 8) | (m_pBuffer[index+1] << 0));
83 : }
84 :
85 0 : inline sal_uInt16 readUINT16(sal_uInt32 index) const
86 : {
87 0 : if (m_bufferLen < 2 || index >= m_bufferLen - 1) {
88 0 : throw BoundsError();
89 : }
90 0 : return ((m_pBuffer[index] << 8) | (m_pBuffer[index+1] << 0));
91 : }
92 :
93 0 : inline sal_Int32 readINT32(sal_uInt32 index) const
94 : {
95 0 : if (m_bufferLen < 4 || index >= m_bufferLen - 3) {
96 0 : throw BoundsError();
97 : }
98 : return (
99 0 : (m_pBuffer[index] << 24) |
100 0 : (m_pBuffer[index+1] << 16) |
101 0 : (m_pBuffer[index+2] << 8) |
102 0 : (m_pBuffer[index+3] << 0)
103 0 : );
104 : }
105 :
106 0 : inline sal_uInt32 readUINT32(sal_uInt32 index) const
107 : {
108 0 : if (m_bufferLen < 4 || index >= m_bufferLen - 3) {
109 0 : throw BoundsError();
110 : }
111 : return (
112 0 : (m_pBuffer[index] << 24) |
113 0 : (m_pBuffer[index+1] << 16) |
114 0 : (m_pBuffer[index+2] << 8) |
115 0 : (m_pBuffer[index+3] << 0)
116 0 : );
117 : }
118 :
119 0 : inline sal_Int64 readINT64(sal_uInt32 index) const
120 : {
121 0 : if (m_bufferLen < 8 || index >= m_bufferLen - 7) {
122 0 : throw BoundsError();
123 : }
124 : return (
125 0 : ((sal_Int64)m_pBuffer[index] << 56) |
126 0 : ((sal_Int64)m_pBuffer[index+1] << 48) |
127 0 : ((sal_Int64)m_pBuffer[index+2] << 40) |
128 0 : ((sal_Int64)m_pBuffer[index+3] << 32) |
129 0 : ((sal_Int64)m_pBuffer[index+4] << 24) |
130 0 : ((sal_Int64)m_pBuffer[index+5] << 16) |
131 0 : ((sal_Int64)m_pBuffer[index+6] << 8) |
132 0 : ((sal_Int64)m_pBuffer[index+7] << 0)
133 0 : );
134 : }
135 :
136 0 : inline sal_uInt64 readUINT64(sal_uInt32 index) const
137 : {
138 0 : if (m_bufferLen < 8 || index >= m_bufferLen - 7) {
139 0 : throw BoundsError();
140 : }
141 : return (
142 0 : ((sal_uInt64)m_pBuffer[index] << 56) |
143 0 : ((sal_uInt64)m_pBuffer[index+1] << 48) |
144 0 : ((sal_uInt64)m_pBuffer[index+2] << 40) |
145 0 : ((sal_uInt64)m_pBuffer[index+3] << 32) |
146 0 : ((sal_uInt64)m_pBuffer[index+4] << 24) |
147 0 : ((sal_uInt64)m_pBuffer[index+5] << 16) |
148 0 : ((sal_uInt64)m_pBuffer[index+6] << 8) |
149 0 : ((sal_uInt64)m_pBuffer[index+7] << 0)
150 0 : );
151 : }
152 : };
153 :
154 0 : BlopObject::BlopObject(const sal_uInt8* buffer, sal_uInt32 len, bool copyBuffer)
155 : : m_bufferLen(len)
156 0 : , m_isCopied(copyBuffer)
157 : {
158 0 : if (m_isCopied)
159 : {
160 0 : m_pBuffer = 0;
161 0 : sal_uInt8* newBuffer = new sal_uInt8[len];
162 0 : memcpy(newBuffer, buffer, len);
163 0 : m_pBuffer = newBuffer;
164 : }
165 : else
166 : {
167 0 : m_pBuffer = buffer;
168 : }
169 0 : }
170 :
171 0 : BlopObject::~BlopObject()
172 : {
173 0 : if (m_isCopied)
174 : {
175 0 : delete[] m_pBuffer;
176 : }
177 0 : }
178 :
179 : /**************************************************************************
180 :
181 : class StringCache
182 :
183 : **************************************************************************/
184 :
185 : class StringCache
186 : {
187 : public:
188 : sal_Unicode** m_stringTable;
189 : sal_uInt16 m_numOfStrings;
190 : sal_uInt16 m_stringsCopied;
191 :
192 : StringCache(sal_uInt16 size); // throws std::bad_alloc
193 : ~StringCache();
194 :
195 : const sal_Unicode* getString(sal_uInt16 index);
196 : sal_uInt16 createString(const sal_uInt8* buffer); // throws std::bad_alloc
197 : };
198 :
199 0 : StringCache::StringCache(sal_uInt16 size)
200 : : m_stringTable(NULL)
201 : , m_numOfStrings(size)
202 0 : , m_stringsCopied(0)
203 : {
204 0 : m_stringTable = new sal_Unicode*[m_numOfStrings];
205 :
206 0 : for (sal_uInt16 i = 0; i < m_numOfStrings; i++)
207 : {
208 0 : m_stringTable[i] = NULL;
209 : }
210 0 : }
211 :
212 0 : StringCache::~StringCache()
213 : {
214 0 : if (m_stringTable)
215 : {
216 0 : for (sal_uInt16 i = 0; i < m_stringsCopied; i++)
217 : {
218 0 : delete[] m_stringTable[i];
219 : }
220 :
221 0 : delete[] m_stringTable;
222 : }
223 0 : }
224 :
225 0 : const sal_Unicode* StringCache::getString(sal_uInt16 index)
226 : {
227 0 : if ((index > 0) && (index <= m_stringsCopied))
228 0 : return m_stringTable[index - 1];
229 : else
230 0 : return NULL;
231 : }
232 :
233 0 : sal_uInt16 StringCache::createString(const sal_uInt8* buffer)
234 : {
235 0 : if (m_stringsCopied < m_numOfStrings)
236 : {
237 0 : sal_uInt32 len = UINT16StringLen(buffer);
238 :
239 0 : m_stringTable[m_stringsCopied] = new sal_Unicode[len + 1];
240 :
241 0 : readString(buffer, m_stringTable[m_stringsCopied], (len + 1) * sizeof(sal_Unicode));
242 :
243 0 : return ++m_stringsCopied;
244 : }
245 : else
246 0 : return 0;
247 : }
248 :
249 : /**************************************************************************
250 :
251 : class ConstantPool
252 :
253 : **************************************************************************/
254 :
255 : class ConstantPool : public BlopObject
256 : {
257 : public:
258 :
259 : sal_uInt16 m_numOfEntries;
260 : sal_Int32* m_pIndex; // index values may be < 0 for cached string constants
261 :
262 : StringCache* m_pStringCache;
263 :
264 0 : ConstantPool(const sal_uInt8* buffer, sal_uInt32 len, sal_uInt16 numEntries)
265 : : BlopObject(buffer, len, false)
266 : , m_numOfEntries(numEntries)
267 : , m_pIndex(NULL)
268 0 : , m_pStringCache(NULL)
269 : {
270 0 : }
271 :
272 : ~ConstantPool();
273 :
274 : sal_uInt32 parseIndex(); // throws std::bad_alloc
275 :
276 : CPInfoTag readTag(sal_uInt16 index);
277 :
278 : const sal_Char* readUTF8NameConstant(sal_uInt16 index);
279 : bool readBOOLConstant(sal_uInt16 index);
280 : sal_Int8 readBYTEConstant(sal_uInt16 index);
281 : sal_Int16 readINT16Constant(sal_uInt16 index);
282 : sal_uInt16 readUINT16Constant(sal_uInt16 index);
283 : sal_Int32 readINT32Constant(sal_uInt16 index);
284 : sal_uInt32 readUINT32Constant(sal_uInt16 index);
285 : sal_Int64 readINT64Constant(sal_uInt16 index);
286 : sal_uInt64 readUINT64Constant(sal_uInt16 index);
287 : float readFloatConstant(sal_uInt16 index);
288 : double readDoubleConstant(sal_uInt16 index);
289 : const sal_Unicode* readStringConstant(sal_uInt16 index);
290 : // throws std::bad_alloc
291 : void readUIK(sal_uInt16 index, RTUik* uik);
292 : };
293 :
294 0 : ConstantPool::~ConstantPool()
295 : {
296 0 : delete[] m_pIndex;
297 0 : delete m_pStringCache;
298 0 : }
299 :
300 0 : sal_uInt32 ConstantPool::parseIndex()
301 : {
302 0 : if (m_pIndex)
303 : {
304 0 : delete[] m_pIndex;
305 0 : m_pIndex = NULL;
306 : }
307 :
308 0 : if (m_pStringCache)
309 : {
310 0 : delete m_pStringCache;
311 0 : m_pStringCache = NULL;
312 : }
313 :
314 0 : sal_uInt32 offset = 0;
315 0 : sal_uInt16 numOfStrings = 0;
316 :
317 0 : if (m_numOfEntries)
318 : {
319 0 : m_pIndex = new sal_Int32[m_numOfEntries];
320 :
321 0 : for (int i = 0; i < m_numOfEntries; i++)
322 : {
323 0 : m_pIndex[i] = offset;
324 :
325 0 : offset += readUINT32(offset);
326 :
327 0 : if ( ((CPInfoTag) readUINT16(m_pIndex[i] + CP_OFFSET_ENTRY_TAG)) ==
328 : CP_TAG_CONST_STRING )
329 : {
330 0 : numOfStrings++;
331 : }
332 :
333 : }
334 : }
335 :
336 0 : if (numOfStrings)
337 : {
338 0 : m_pStringCache = new StringCache(numOfStrings);
339 : }
340 :
341 0 : m_bufferLen = offset;
342 :
343 0 : return offset;
344 : }
345 :
346 0 : CPInfoTag ConstantPool::readTag(sal_uInt16 index)
347 : {
348 0 : CPInfoTag tag = CP_TAG_INVALID;
349 :
350 0 : if (m_pIndex && (index > 0) && (index <= m_numOfEntries))
351 : {
352 0 : tag = (CPInfoTag) readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG);
353 : }
354 :
355 0 : return tag;
356 : }
357 :
358 0 : const sal_Char* ConstantPool::readUTF8NameConstant(sal_uInt16 index)
359 : {
360 0 : const sal_Char* aName = NULL_STRING;
361 :
362 0 : if (m_pIndex && (index > 0) && (index <= m_numOfEntries))
363 : {
364 0 : if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_UTF8_NAME)
365 : {
366 0 : sal_uInt32 n = m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA;
367 0 : if (n < m_bufferLen
368 0 : && std::memchr(m_pBuffer + n, 0, m_bufferLen - n) != nullptr)
369 : {
370 0 : aName = reinterpret_cast<const char*>(m_pBuffer + n);
371 : }
372 : }
373 : }
374 :
375 0 : return aName;
376 : }
377 :
378 0 : bool ConstantPool::readBOOLConstant(sal_uInt16 index)
379 : {
380 0 : bool aBool = false;
381 :
382 0 : if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
383 : {
384 0 : if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_BOOL)
385 : {
386 0 : aBool = readBYTE(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA) != 0;
387 : }
388 : }
389 :
390 0 : return aBool;
391 : }
392 :
393 0 : sal_Int8 ConstantPool::readBYTEConstant(sal_uInt16 index)
394 : {
395 0 : sal_Int8 aByte = 0;
396 :
397 0 : if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
398 : {
399 0 : if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_BYTE)
400 : {
401 : aByte = static_cast< sal_Int8 >(
402 0 : readBYTE(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA));
403 : }
404 : }
405 :
406 0 : return aByte;
407 : }
408 :
409 0 : sal_Int16 ConstantPool::readINT16Constant(sal_uInt16 index)
410 : {
411 0 : sal_Int16 aINT16 = 0;
412 :
413 0 : if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
414 : {
415 0 : if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_INT16)
416 : {
417 0 : aINT16 = readINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
418 : }
419 : }
420 :
421 0 : return aINT16;
422 : }
423 :
424 0 : sal_uInt16 ConstantPool::readUINT16Constant(sal_uInt16 index)
425 : {
426 0 : sal_uInt16 asal_uInt16 = 0;
427 :
428 0 : if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
429 : {
430 0 : if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_UINT16)
431 : {
432 0 : asal_uInt16 = readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
433 : }
434 : }
435 :
436 0 : return asal_uInt16;
437 : }
438 :
439 0 : sal_Int32 ConstantPool::readINT32Constant(sal_uInt16 index)
440 : {
441 0 : sal_Int32 aINT32 = 0;
442 :
443 0 : if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
444 : {
445 0 : if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_INT32)
446 : {
447 0 : aINT32 = readINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
448 : }
449 : }
450 :
451 0 : return aINT32;
452 : }
453 :
454 0 : sal_uInt32 ConstantPool::readUINT32Constant(sal_uInt16 index)
455 : {
456 0 : sal_uInt32 aUINT32 = 0;
457 :
458 0 : if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
459 : {
460 0 : if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_UINT32)
461 : {
462 0 : aUINT32 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
463 : }
464 : }
465 :
466 0 : return aUINT32;
467 : }
468 :
469 0 : sal_Int64 ConstantPool::readINT64Constant(sal_uInt16 index)
470 : {
471 0 : sal_Int64 aINT64 = 0;
472 :
473 0 : if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
474 : {
475 0 : if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_INT64)
476 : {
477 0 : aINT64 = readINT64(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
478 : }
479 : }
480 :
481 0 : return aINT64;
482 : }
483 :
484 0 : sal_uInt64 ConstantPool::readUINT64Constant(sal_uInt16 index)
485 : {
486 0 : sal_uInt64 aUINT64 = 0;
487 :
488 0 : if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
489 : {
490 0 : if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_UINT64)
491 : {
492 0 : aUINT64 = readUINT64(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
493 : }
494 : }
495 :
496 0 : return aUINT64;
497 : }
498 :
499 0 : float ConstantPool::readFloatConstant(sal_uInt16 index)
500 : {
501 : union
502 : {
503 : float v;
504 : sal_uInt32 b;
505 0 : } x = { 0.0f };
506 :
507 0 : if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
508 : {
509 0 : if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_FLOAT)
510 : {
511 : #ifdef REGTYPE_IEEE_NATIVE
512 0 : x.b = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
513 : #else
514 : # error no IEEE
515 : #endif
516 : }
517 : }
518 :
519 0 : return x.v;
520 : }
521 :
522 0 : double ConstantPool::readDoubleConstant(sal_uInt16 index)
523 : {
524 : union
525 : {
526 : double v;
527 : struct
528 : {
529 : sal_uInt32 b1;
530 : sal_uInt32 b2;
531 : } b;
532 0 : } x = { 0.0 };
533 :
534 0 : if (m_pIndex && (index> 0) && (index <= m_numOfEntries))
535 : {
536 0 : if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_DOUBLE)
537 : {
538 :
539 : #ifdef REGTYPE_IEEE_NATIVE
540 : # ifdef OSL_BIGENDIAN
541 : x.b.b1 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
542 : x.b.b2 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA + sizeof(sal_uInt32));
543 : # else
544 0 : x.b.b1 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA + sizeof(sal_uInt32));
545 0 : x.b.b2 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA);
546 : # endif
547 : #else
548 : # error no IEEE
549 : #endif
550 : }
551 : }
552 :
553 0 : return x.v;
554 : }
555 :
556 0 : const sal_Unicode* ConstantPool::readStringConstant(sal_uInt16 index)
557 : {
558 0 : const sal_Unicode* aString = NULL_WSTRING;
559 :
560 0 : if (m_pIndex && (index> 0) && (index <= m_numOfEntries) && m_pStringCache)
561 : {
562 0 : if (m_pIndex[index - 1] >= 0)
563 : {
564 : // create cached string now
565 :
566 0 : if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_STRING)
567 : {
568 0 : sal_uInt32 n = m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA;
569 0 : if (n >= m_bufferLen
570 0 : || (std::memchr(m_pBuffer + n, 0, m_bufferLen - n)
571 : == nullptr))
572 : {
573 0 : throw BoundsError();
574 : }
575 0 : m_pIndex[index - 1] = -1 * m_pStringCache->createString(m_pBuffer + n);
576 : }
577 : }
578 :
579 0 : aString = m_pStringCache->getString((sal_uInt16) (m_pIndex[index - 1] * -1));
580 : }
581 :
582 0 : return aString;
583 : }
584 :
585 0 : void ConstantPool::readUIK(sal_uInt16 index, RTUik* uik)
586 : {
587 0 : if (index == 0)
588 : {
589 0 : uik->m_Data1 = 0;
590 0 : uik->m_Data2 = 0;
591 0 : uik->m_Data3 = 0;
592 0 : uik->m_Data4 = 0;
593 0 : uik->m_Data5 = 0;
594 : }
595 0 : else if (m_pIndex && (index <= m_numOfEntries))
596 : {
597 0 : if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_UIK)
598 : {
599 0 : uik->m_Data1 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_UIK1);
600 0 : uik->m_Data2 = readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_UIK2);
601 0 : uik->m_Data3 = readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_UIK3);
602 0 : uik->m_Data4 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_UIK4);
603 0 : uik->m_Data5 = readUINT32(m_pIndex[index - 1] + CP_OFFSET_ENTRY_UIK5);
604 : }
605 : }
606 0 : }
607 :
608 : /**************************************************************************
609 :
610 : class FieldList
611 :
612 : **************************************************************************/
613 :
614 0 : class FieldList : public BlopObject
615 : {
616 : public:
617 :
618 : sal_uInt16 m_numOfEntries;
619 : sal_uInt16 m_numOfFieldEntries;
620 : size_t m_FIELD_ENTRY_SIZE;
621 : ConstantPool* m_pCP;
622 :
623 0 : FieldList(const sal_uInt8* buffer, sal_uInt32 len, sal_uInt16 numEntries, ConstantPool* pCP)
624 : : BlopObject(buffer, len, false)
625 : , m_numOfEntries(numEntries)
626 0 : , m_pCP(pCP)
627 : {
628 0 : if ( m_numOfEntries > 0 )
629 : {
630 0 : m_numOfFieldEntries = readUINT16(0);
631 0 : m_FIELD_ENTRY_SIZE = m_numOfFieldEntries * sizeof(sal_uInt16);
632 : } else
633 : {
634 0 : m_numOfFieldEntries = 0;
635 0 : m_FIELD_ENTRY_SIZE = 0;
636 : }
637 0 : }
638 :
639 0 : sal_uInt32 parseIndex() { return ((m_numOfEntries ? sizeof(sal_uInt16) : 0) + (m_numOfEntries * m_FIELD_ENTRY_SIZE));}
640 :
641 : const sal_Char* getFieldName(sal_uInt16 index);
642 : const sal_Char* getFieldType(sal_uInt16 index);
643 : RTFieldAccess getFieldAccess(sal_uInt16 index);
644 : RTValueType getFieldConstValue(sal_uInt16 index, RTConstValueUnion* value);
645 : // throws std::bad_alloc
646 : const sal_Char* getFieldDoku(sal_uInt16 index);
647 : const sal_Char* getFieldFileName(sal_uInt16 index);
648 : };
649 :
650 :
651 0 : const sal_Char* FieldList::getFieldName(sal_uInt16 index)
652 : {
653 0 : const sal_Char* aName = NULL;
654 :
655 0 : if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
656 : {
657 : try {
658 0 : aName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_NAME));
659 0 : } catch (BlopObject::BoundsError &) {
660 : SAL_WARN("registry", "bad data");
661 : }
662 : }
663 :
664 0 : return aName;
665 : }
666 :
667 0 : const sal_Char* FieldList::getFieldType(sal_uInt16 index)
668 : {
669 0 : const sal_Char* aName = NULL;
670 :
671 0 : if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
672 : {
673 : try {
674 0 : aName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_TYPE));
675 0 : } catch (BlopObject::BoundsError &) {
676 : SAL_WARN("registry", "bad data");
677 : }
678 : }
679 :
680 0 : return aName;
681 : }
682 :
683 0 : RTFieldAccess FieldList::getFieldAccess(sal_uInt16 index)
684 : {
685 0 : RTFieldAccess aAccess = RTFieldAccess::INVALID;
686 :
687 0 : if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
688 : {
689 : try {
690 0 : aAccess = (RTFieldAccess) readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_ACCESS);
691 0 : } catch (BlopObject::BoundsError &) {
692 : SAL_WARN("registry", "bad data");
693 : }
694 : }
695 :
696 0 : return aAccess;
697 : }
698 :
699 0 : RTValueType FieldList::getFieldConstValue(sal_uInt16 index, RTConstValueUnion* value)
700 : {
701 0 : RTValueType ret = RT_TYPE_NONE;
702 : try {
703 0 : if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
704 : {
705 0 : sal_uInt16 cpIndex = readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_VALUE);
706 0 : switch (m_pCP->readTag(cpIndex))
707 : {
708 : case CP_TAG_CONST_BOOL:
709 0 : value->aBool = m_pCP->readBOOLConstant(cpIndex);
710 0 : ret = RT_TYPE_BOOL;
711 0 : break;
712 : case CP_TAG_CONST_BYTE:
713 0 : value->aByte = m_pCP->readBYTEConstant(cpIndex);
714 0 : ret = RT_TYPE_BYTE;
715 0 : break;
716 : case CP_TAG_CONST_INT16:
717 0 : value->aShort = m_pCP->readINT16Constant(cpIndex);
718 0 : ret = RT_TYPE_INT16;
719 0 : break;
720 : case CP_TAG_CONST_UINT16:
721 0 : value->aUShort = m_pCP->readUINT16Constant(cpIndex);
722 0 : ret = RT_TYPE_UINT16;
723 0 : break;
724 : case CP_TAG_CONST_INT32:
725 0 : value->aLong = m_pCP->readINT32Constant(cpIndex);
726 0 : ret = RT_TYPE_INT32;
727 0 : break;
728 : case CP_TAG_CONST_UINT32:
729 0 : value->aULong = m_pCP->readUINT32Constant(cpIndex);
730 0 : ret = RT_TYPE_UINT32;
731 0 : break;
732 : case CP_TAG_CONST_INT64:
733 0 : value->aHyper = m_pCP->readINT64Constant(cpIndex);
734 0 : ret = RT_TYPE_INT64;
735 0 : break;
736 : case CP_TAG_CONST_UINT64:
737 0 : value->aUHyper = m_pCP->readUINT64Constant(cpIndex);
738 0 : ret = RT_TYPE_UINT64;
739 0 : break;
740 : case CP_TAG_CONST_FLOAT:
741 0 : value->aFloat = m_pCP->readFloatConstant(cpIndex);
742 0 : ret = RT_TYPE_FLOAT;
743 0 : break;
744 : case CP_TAG_CONST_DOUBLE:
745 0 : value->aDouble = m_pCP->readDoubleConstant(cpIndex);
746 0 : ret = RT_TYPE_DOUBLE;
747 0 : break;
748 : case CP_TAG_CONST_STRING:
749 0 : value->aString = m_pCP->readStringConstant(cpIndex);
750 0 : ret = RT_TYPE_STRING;
751 0 : break;
752 : default:
753 0 : break;
754 : }
755 : }
756 0 : } catch (BlopObject::BoundsError &) {
757 : SAL_WARN("registry", "bad data");
758 : }
759 0 : return ret;
760 : }
761 :
762 0 : const sal_Char* FieldList::getFieldDoku(sal_uInt16 index)
763 : {
764 0 : const sal_Char* aDoku = NULL;
765 :
766 0 : if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
767 : {
768 : try {
769 0 : aDoku = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_DOKU));
770 0 : } catch (BlopObject::BoundsError &) {
771 : SAL_WARN("registry", "bad data");
772 : }
773 : }
774 :
775 0 : return aDoku;
776 : }
777 :
778 0 : const sal_Char* FieldList::getFieldFileName(sal_uInt16 index)
779 : {
780 0 : const sal_Char* aFileName = NULL;
781 :
782 0 : if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
783 : {
784 : try {
785 0 : aFileName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_FILENAME));
786 0 : } catch (BlopObject::BoundsError &) {
787 : SAL_WARN("registry", "bad data");
788 : }
789 : }
790 :
791 0 : return aFileName;
792 : }
793 :
794 : /**************************************************************************
795 :
796 : class ReferenceList
797 :
798 : **************************************************************************/
799 :
800 0 : class ReferenceList : public BlopObject
801 : {
802 : public:
803 :
804 : sal_uInt16 m_numOfEntries;
805 : sal_uInt16 m_numOfReferenceEntries;
806 : size_t m_REFERENCE_ENTRY_SIZE;
807 : ConstantPool* m_pCP;
808 :
809 0 : ReferenceList(const sal_uInt8* buffer, sal_uInt32 len, sal_uInt16 numEntries, ConstantPool* pCP)
810 : : BlopObject(buffer, len, false)
811 : , m_numOfEntries(numEntries)
812 0 : , m_pCP(pCP)
813 : {
814 0 : if ( m_numOfEntries > 0 )
815 : {
816 0 : m_numOfReferenceEntries = readUINT16(0);
817 0 : m_REFERENCE_ENTRY_SIZE = m_numOfReferenceEntries * sizeof(sal_uInt16);
818 : } else
819 : {
820 0 : m_numOfReferenceEntries = 0;
821 0 : m_REFERENCE_ENTRY_SIZE = 0;
822 : }
823 0 : }
824 :
825 : const sal_Char* getReferenceName(sal_uInt16 index);
826 : RTReferenceType getReferenceType(sal_uInt16 index);
827 : const sal_Char* getReferenceDoku(sal_uInt16 index);
828 : RTFieldAccess getReferenceAccess(sal_uInt16 index);
829 : };
830 :
831 :
832 0 : const sal_Char* ReferenceList::getReferenceName(sal_uInt16 index)
833 : {
834 0 : const sal_Char* aName = NULL;
835 :
836 0 : if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
837 : {
838 : try {
839 0 : aName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_NAME));
840 0 : } catch (BlopObject::BoundsError &) {
841 : SAL_WARN("registry", "bad data");
842 : }
843 : }
844 :
845 0 : return aName;
846 : }
847 :
848 0 : RTReferenceType ReferenceList::getReferenceType(sal_uInt16 index)
849 : {
850 0 : RTReferenceType refType = RTReferenceType::INVALID;
851 :
852 0 : if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
853 : {
854 : try {
855 0 : refType = (RTReferenceType) readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_TYPE);
856 0 : } catch (BlopObject::BoundsError &) {
857 : SAL_WARN("registry", "bad data");
858 : }
859 : }
860 :
861 0 : return refType;
862 : }
863 :
864 0 : const sal_Char* ReferenceList::getReferenceDoku(sal_uInt16 index)
865 : {
866 0 : const sal_Char* aDoku = NULL;
867 :
868 0 : if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
869 : {
870 : try {
871 0 : aDoku = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_DOKU));
872 0 : } catch (BlopObject::BoundsError &) {
873 : SAL_WARN("registry", "bad data");
874 : }
875 : }
876 :
877 0 : return aDoku;
878 : }
879 :
880 0 : RTFieldAccess ReferenceList::getReferenceAccess(sal_uInt16 index)
881 : {
882 0 : RTFieldAccess aAccess = RTFieldAccess::INVALID;
883 :
884 0 : if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
885 : {
886 : try {
887 0 : aAccess = (RTFieldAccess) readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_ACCESS);
888 0 : } catch (BlopObject::BoundsError &) {
889 : SAL_WARN("registry", "bad data");
890 : }
891 : }
892 :
893 0 : return aAccess;
894 : }
895 :
896 : /**************************************************************************
897 :
898 : class MethodList
899 :
900 : **************************************************************************/
901 :
902 : class MethodList : public BlopObject
903 : {
904 : public:
905 :
906 : sal_uInt16 m_numOfEntries;
907 : sal_uInt16 m_numOfMethodEntries;
908 : sal_uInt16 m_numOfParamEntries;
909 : size_t m_PARAM_ENTRY_SIZE;
910 : sal_uInt32* m_pIndex;
911 : ConstantPool* m_pCP;
912 :
913 0 : MethodList(const sal_uInt8* buffer, sal_uInt32 len, sal_uInt16 numEntries, ConstantPool* pCP)
914 : : BlopObject(buffer, len, false)
915 : , m_numOfEntries(numEntries)
916 : , m_pIndex(NULL)
917 0 : , m_pCP(pCP)
918 : {
919 0 : if ( m_numOfEntries > 0 )
920 : {
921 0 : m_numOfMethodEntries = readUINT16(0);
922 0 : m_numOfParamEntries = readUINT16(sizeof(sal_uInt16));
923 0 : m_PARAM_ENTRY_SIZE = m_numOfParamEntries * sizeof(sal_uInt16);
924 : } else
925 : {
926 0 : m_numOfMethodEntries = 0;
927 0 : m_numOfParamEntries = 0;
928 0 : m_PARAM_ENTRY_SIZE = 0;
929 : }
930 0 : }
931 :
932 : ~MethodList();
933 :
934 : sal_uInt32 parseIndex(); // throws std::bad_alloc
935 :
936 : const sal_Char* getMethodName(sal_uInt16 index);
937 : sal_uInt16 getMethodParamCount(sal_uInt16 index);
938 : const sal_Char* getMethodParamType(sal_uInt16 index, sal_uInt16 paramIndex);
939 : const sal_Char* getMethodParamName(sal_uInt16 index, sal_uInt16 paramIndex);
940 : RTParamMode getMethodParamMode(sal_uInt16 index, sal_uInt16 paramIndex);
941 : sal_uInt16 getMethodExcCount(sal_uInt16 index);
942 : const sal_Char* getMethodExcType(sal_uInt16 index, sal_uInt16 excIndex);
943 : const sal_Char* getMethodReturnType(sal_uInt16 index);
944 : RTMethodMode getMethodMode(sal_uInt16 index);
945 : const sal_Char* getMethodDoku(sal_uInt16 index);
946 :
947 : private:
948 : sal_uInt16 calcMethodParamIndex( const sal_uInt16 index );
949 : };
950 :
951 0 : MethodList::~MethodList()
952 : {
953 0 : if (m_pIndex) delete[] m_pIndex;
954 0 : }
955 :
956 0 : sal_uInt16 MethodList::calcMethodParamIndex( const sal_uInt16 index )
957 : {
958 0 : return (METHOD_OFFSET_PARAM_COUNT + sizeof(sal_uInt16) + (index * m_PARAM_ENTRY_SIZE));
959 : }
960 :
961 0 : sal_uInt32 MethodList::parseIndex()
962 : {
963 0 : if (m_pIndex)
964 : {
965 0 : delete[] m_pIndex;
966 0 : m_pIndex = NULL;
967 : }
968 :
969 0 : sal_uInt32 offset = 0;
970 :
971 0 : if (m_numOfEntries)
972 : {
973 0 : offset = 2 * sizeof(sal_uInt16);
974 0 : m_pIndex = new sal_uInt32[m_numOfEntries];
975 :
976 0 : for (int i = 0; i < m_numOfEntries; i++)
977 : {
978 0 : m_pIndex[i] = offset;
979 :
980 0 : offset += readUINT16(offset);
981 : }
982 : }
983 :
984 0 : return offset;
985 : }
986 :
987 0 : const sal_Char* MethodList::getMethodName(sal_uInt16 index)
988 : {
989 0 : const sal_Char* aName = NULL;
990 :
991 0 : if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
992 : {
993 : try {
994 0 : aName = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_NAME));
995 0 : } catch (BlopObject::BoundsError &) {
996 : SAL_WARN("registry", "bad data");
997 : }
998 : }
999 :
1000 0 : return aName;
1001 : }
1002 :
1003 0 : sal_uInt16 MethodList::getMethodParamCount(sal_uInt16 index)
1004 : {
1005 0 : sal_uInt16 aCount = 0;
1006 :
1007 0 : if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
1008 : {
1009 : try {
1010 0 : aCount = readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT);
1011 0 : } catch (BlopObject::BoundsError &) {
1012 : SAL_WARN("registry", "bad data");
1013 : }
1014 : }
1015 :
1016 0 : return aCount;
1017 : }
1018 :
1019 0 : const sal_Char* MethodList::getMethodParamType(sal_uInt16 index, sal_uInt16 paramIndex)
1020 : {
1021 0 : const sal_Char* aName = NULL;
1022 : try {
1023 0 : if ((m_numOfEntries > 0) &&
1024 0 : (index <= m_numOfEntries) &&
1025 0 : (paramIndex <= readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT)))
1026 : {
1027 : aName = m_pCP->readUTF8NameConstant(
1028 : readUINT16(
1029 0 : m_pIndex[index] +
1030 0 : calcMethodParamIndex(paramIndex) +
1031 0 : PARAM_OFFSET_TYPE));
1032 : }
1033 0 : } catch (BlopObject::BoundsError &) {
1034 : SAL_WARN("registry", "bad data");
1035 : }
1036 0 : return aName;
1037 : }
1038 :
1039 0 : const sal_Char* MethodList::getMethodParamName(sal_uInt16 index, sal_uInt16 paramIndex)
1040 : {
1041 0 : const sal_Char* aName = NULL;
1042 : try {
1043 0 : if ((m_numOfEntries > 0) &&
1044 0 : (index <= m_numOfEntries) &&
1045 0 : (paramIndex <= readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT)))
1046 : {
1047 : aName = m_pCP->readUTF8NameConstant(
1048 : readUINT16(
1049 0 : m_pIndex[index] +
1050 0 : calcMethodParamIndex(paramIndex) +
1051 0 : PARAM_OFFSET_NAME));
1052 : }
1053 0 : } catch (BlopObject::BoundsError &) {
1054 : SAL_WARN("registry", "bad data");
1055 : }
1056 0 : return aName;
1057 : }
1058 :
1059 0 : RTParamMode MethodList::getMethodParamMode(sal_uInt16 index, sal_uInt16 paramIndex)
1060 : {
1061 0 : RTParamMode aMode = RT_PARAM_INVALID;
1062 : try {
1063 0 : if ((m_numOfEntries > 0) &&
1064 0 : (index <= m_numOfEntries) &&
1065 0 : (paramIndex <= readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT)))
1066 : {
1067 : aMode = (RTParamMode) readUINT16(
1068 0 : m_pIndex[index] +
1069 0 : calcMethodParamIndex(paramIndex) +
1070 0 : PARAM_OFFSET_MODE);
1071 : }
1072 0 : } catch (BlopObject::BoundsError &) {
1073 : SAL_WARN("registry", "bad data");
1074 : }
1075 0 : return aMode;
1076 : }
1077 :
1078 0 : sal_uInt16 MethodList::getMethodExcCount(sal_uInt16 index)
1079 : {
1080 0 : sal_uInt16 aCount = 0;
1081 :
1082 0 : if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
1083 : {
1084 : try {
1085 0 : aCount = readUINT16(m_pIndex[index] + calcMethodParamIndex(readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT)));
1086 0 : } catch (BlopObject::BoundsError &) {
1087 : SAL_WARN("registry", "bad data");
1088 : }
1089 : }
1090 :
1091 0 : return aCount;
1092 : }
1093 :
1094 0 : const sal_Char* MethodList::getMethodExcType(sal_uInt16 index, sal_uInt16 excIndex)
1095 : {
1096 0 : const sal_Char* aName = NULL;
1097 :
1098 0 : if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
1099 : {
1100 : try {
1101 0 : sal_uInt32 excOffset = m_pIndex[index] + calcMethodParamIndex(readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT));
1102 0 : if (excIndex <= readUINT16(excOffset))
1103 : {
1104 : aName = m_pCP->readUTF8NameConstant(
1105 : readUINT16(
1106 : excOffset +
1107 : sizeof(sal_uInt16) +
1108 0 : (excIndex * sizeof(sal_uInt16))));
1109 : }
1110 0 : } catch (BlopObject::BoundsError &) {
1111 : SAL_WARN("registry", "bad data");
1112 : }
1113 : }
1114 :
1115 0 : return aName;
1116 : }
1117 :
1118 0 : const sal_Char* MethodList::getMethodReturnType(sal_uInt16 index)
1119 : {
1120 0 : const sal_Char* aName = NULL;
1121 :
1122 0 : if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
1123 : {
1124 : try {
1125 0 : aName = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_RETURN));
1126 0 : } catch (BlopObject::BoundsError &) {
1127 : SAL_WARN("registry", "bad data");
1128 : }
1129 : }
1130 :
1131 0 : return aName;
1132 : }
1133 :
1134 0 : RTMethodMode MethodList::getMethodMode(sal_uInt16 index)
1135 : {
1136 0 : RTMethodMode aMode = RTMethodMode::INVALID;
1137 :
1138 0 : if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
1139 : {
1140 : try {
1141 0 : aMode = (RTMethodMode) readUINT16(m_pIndex[index] + METHOD_OFFSET_MODE);
1142 0 : } catch (BlopObject::BoundsError &) {
1143 : SAL_WARN("registry", "bad data");
1144 : }
1145 : }
1146 :
1147 0 : return aMode;
1148 : }
1149 :
1150 0 : const sal_Char* MethodList::getMethodDoku(sal_uInt16 index)
1151 : {
1152 0 : const sal_Char* aDoku = NULL;
1153 :
1154 0 : if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
1155 : {
1156 : try {
1157 0 : aDoku = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_DOKU));
1158 0 : } catch (BlopObject::BoundsError &) {
1159 : SAL_WARN("registry", "bad data");
1160 : }
1161 : }
1162 :
1163 0 : return aDoku;
1164 : }
1165 :
1166 : /**************************************************************************
1167 :
1168 : class TypeRegistryEntry
1169 :
1170 : **************************************************************************/
1171 :
1172 0 : class TypeRegistryEntry: public BlopObject {
1173 : public:
1174 : std::unique_ptr<ConstantPool> m_pCP;
1175 : std::unique_ptr<FieldList> m_pFields;
1176 : std::unique_ptr<MethodList> m_pMethods;
1177 : std::unique_ptr<ReferenceList> m_pReferences;
1178 : sal_uInt32 m_refCount;
1179 : sal_uInt16 m_nSuperTypes;
1180 : sal_uInt32 m_offset_SUPERTYPES;
1181 :
1182 : TypeRegistryEntry(
1183 : const sal_uInt8* buffer, sal_uInt32 len, bool copyBuffer);
1184 : // throws std::bad_alloc
1185 :
1186 : typereg_Version getVersion() const;
1187 : };
1188 :
1189 0 : TypeRegistryEntry::TypeRegistryEntry(
1190 : const sal_uInt8* buffer, sal_uInt32 len, bool copyBuffer):
1191 : BlopObject(buffer, len, copyBuffer), m_refCount(1), m_nSuperTypes(0),
1192 0 : m_offset_SUPERTYPES(0)
1193 : {
1194 0 : std::size_t const entrySize = sizeof(sal_uInt16);
1195 0 : sal_uInt16 nHeaderEntries = readUINT16(OFFSET_N_ENTRIES);
1196 0 : sal_uInt32 offset_N_SUPERTYPES = OFFSET_N_ENTRIES + entrySize + (nHeaderEntries * entrySize); // cannot overflow
1197 0 : m_offset_SUPERTYPES = offset_N_SUPERTYPES + entrySize; // cannot overflow
1198 0 : m_nSuperTypes = readUINT16(offset_N_SUPERTYPES);
1199 :
1200 0 : sal_uInt32 offset_CP_SIZE = m_offset_SUPERTYPES + (m_nSuperTypes * entrySize); // cannot overflow
1201 0 : sal_uInt32 offset_CP = offset_CP_SIZE + entrySize; // cannot overflow
1202 :
1203 0 : if (offset_CP > m_bufferLen) {
1204 0 : throw BoundsError();
1205 : }
1206 : m_pCP.reset(
1207 : new ConstantPool(
1208 : m_pBuffer + offset_CP, m_bufferLen - offset_CP,
1209 0 : readUINT16(offset_CP_SIZE)));
1210 :
1211 0 : sal_uInt32 offset = offset_CP + m_pCP->parseIndex(); //TODO: overflow
1212 :
1213 : assert(m_bufferLen >= entrySize);
1214 0 : if (offset > m_bufferLen - entrySize) {
1215 0 : throw BoundsError();
1216 : }
1217 : m_pFields.reset(
1218 : new FieldList(
1219 0 : m_pBuffer + offset + entrySize, m_bufferLen - (offset + entrySize),
1220 0 : readUINT16(offset), m_pCP.get()));
1221 :
1222 0 : offset += sizeof(sal_uInt16) + m_pFields->parseIndex(); //TODO: overflow
1223 :
1224 : assert(m_bufferLen >= entrySize);
1225 0 : if (offset > m_bufferLen - entrySize) {
1226 0 : throw BoundsError();
1227 : }
1228 : m_pMethods.reset(
1229 : new MethodList(
1230 0 : m_pBuffer + offset + entrySize, m_bufferLen - (offset + entrySize),
1231 0 : readUINT16(offset), m_pCP.get()));
1232 :
1233 0 : offset += sizeof(sal_uInt16) + m_pMethods->parseIndex(); //TODO: overflow
1234 :
1235 : assert(m_bufferLen >= entrySize);
1236 0 : if (offset > m_bufferLen - entrySize) {
1237 0 : throw BoundsError();
1238 : }
1239 : m_pReferences.reset(
1240 : new ReferenceList(
1241 0 : m_pBuffer + offset + entrySize, m_bufferLen - (offset + entrySize),
1242 0 : readUINT16(offset), m_pCP.get()));
1243 0 : }
1244 :
1245 0 : typereg_Version TypeRegistryEntry::getVersion() const {
1246 : // Assumes two's complement arithmetic with modulo-semantics:
1247 0 : return static_cast< typereg_Version >(readUINT32(OFFSET_MAGIC) - magic);
1248 : }
1249 :
1250 : /**************************************************************************
1251 :
1252 : C-API
1253 :
1254 : **************************************************************************/
1255 :
1256 0 : bool TYPEREG_CALLTYPE typereg_reader_create(
1257 : void const * buffer, sal_uInt32 length, bool copy,
1258 : typereg_Version maxVersion, void ** result)
1259 : {
1260 0 : if (length < OFFSET_CP || length > SAL_MAX_UINT32) {
1261 0 : *result = 0;
1262 0 : return true;
1263 : }
1264 0 : std::unique_ptr< TypeRegistryEntry > entry;
1265 : try {
1266 : try {
1267 : entry.reset(
1268 : new TypeRegistryEntry(
1269 : static_cast< sal_uInt8 const * >(buffer),
1270 0 : static_cast< sal_uInt32 >(length), copy));
1271 0 : } catch (std::bad_alloc &) {
1272 0 : return false;
1273 : }
1274 0 : if (entry->readUINT32(OFFSET_SIZE) != length) {
1275 0 : *result = 0;
1276 0 : return true;
1277 : }
1278 0 : typereg_Version version = entry->getVersion();;
1279 0 : if (version < TYPEREG_VERSION_0 || version > maxVersion) {
1280 0 : *result = 0;
1281 0 : return true;
1282 : }
1283 0 : *result = entry.release();
1284 0 : return true;
1285 0 : } catch (BlopObject::BoundsError &) {
1286 : SAL_WARN("registry", "bad data");
1287 0 : return false;
1288 0 : }
1289 : }
1290 :
1291 0 : static TypeReaderImpl TYPEREG_CALLTYPE createEntry(const sal_uInt8* buffer, sal_uInt32 len, bool copyBuffer)
1292 : {
1293 : void * handle;
1294 0 : typereg_reader_create(buffer, len, copyBuffer, TYPEREG_VERSION_1, &handle);
1295 0 : return handle;
1296 : }
1297 :
1298 0 : void TYPEREG_CALLTYPE typereg_reader_acquire(void * hEntry)
1299 : {
1300 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1301 :
1302 0 : if (pEntry != NULL)
1303 0 : pEntry->m_refCount++;
1304 0 : }
1305 :
1306 0 : void TYPEREG_CALLTYPE typereg_reader_release(void * hEntry)
1307 : {
1308 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1309 :
1310 0 : if (pEntry != NULL)
1311 : {
1312 0 : if (--pEntry->m_refCount == 0)
1313 0 : delete pEntry;
1314 : }
1315 0 : }
1316 :
1317 0 : typereg_Version TYPEREG_CALLTYPE typereg_reader_getVersion(void * handle) {
1318 0 : if (handle != nullptr) {
1319 : try {
1320 0 : return static_cast< TypeRegistryEntry * >(handle)->getVersion();
1321 0 : } catch (BlopObject::BoundsError &) {
1322 : SAL_WARN("registry", "bad data");
1323 : }
1324 : }
1325 0 : return TYPEREG_VERSION_0;
1326 : }
1327 :
1328 0 : static sal_uInt16 TYPEREG_CALLTYPE getMinorVersion(TypeReaderImpl hEntry)
1329 : {
1330 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1331 0 : if (pEntry != nullptr) {
1332 : try {
1333 0 : return pEntry->readUINT16(OFFSET_MINOR_VERSION);
1334 0 : } catch (BlopObject::BoundsError &) {
1335 : SAL_WARN("registry", "bad data");
1336 : }
1337 : }
1338 0 : return 0;
1339 : }
1340 :
1341 0 : static sal_uInt16 TYPEREG_CALLTYPE getMajorVersion(TypeReaderImpl hEntry)
1342 : {
1343 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1344 0 : if (pEntry != nullptr) {
1345 : try {
1346 0 : return pEntry->readUINT16(OFFSET_MAJOR_VERSION);
1347 0 : } catch (BlopObject::BoundsError &) {
1348 : SAL_WARN("registry", "bad data");
1349 : }
1350 : }
1351 0 : return 0;
1352 : }
1353 :
1354 0 : RTTypeClass TYPEREG_CALLTYPE typereg_reader_getTypeClass(void * hEntry)
1355 : {
1356 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1357 0 : if (pEntry != nullptr) {
1358 : try {
1359 : return (RTTypeClass)
1360 0 : (pEntry->readUINT16(OFFSET_TYPE_CLASS) & ~RT_TYPE_PUBLISHED);
1361 0 : } catch (BlopObject::BoundsError &) {
1362 : SAL_WARN("registry", "bad data");
1363 : }
1364 : }
1365 0 : return RT_TYPE_INVALID;
1366 : }
1367 :
1368 0 : bool TYPEREG_CALLTYPE typereg_reader_isPublished(void * hEntry)
1369 : {
1370 0 : TypeRegistryEntry * entry = static_cast< TypeRegistryEntry * >(hEntry);
1371 0 : if (entry != nullptr) {
1372 : try {
1373 0 : return (entry->readUINT16(OFFSET_TYPE_CLASS) & RT_TYPE_PUBLISHED) != 0;
1374 0 : } catch (BlopObject::BoundsError &) {
1375 : SAL_WARN("registry", "bad data");
1376 : }
1377 : }
1378 0 : return false;
1379 : }
1380 :
1381 0 : void TYPEREG_CALLTYPE typereg_reader_getTypeName(void * hEntry, rtl_uString** pTypeName)
1382 : {
1383 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1384 0 : if (pEntry != nullptr) {
1385 : try {
1386 0 : const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(OFFSET_THIS_TYPE));
1387 : rtl_string2UString(
1388 : pTypeName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1389 0 : RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1390 0 : return;
1391 0 : } catch (BlopObject::BoundsError &) {
1392 : SAL_WARN("registry", "bad data");
1393 : }
1394 : }
1395 0 : rtl_uString_new(pTypeName);
1396 : }
1397 :
1398 :
1399 0 : static void TYPEREG_CALLTYPE getSuperTypeName(TypeReaderImpl hEntry, rtl_uString** pSuperTypeName)
1400 : {
1401 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1402 0 : if (pEntry != nullptr && pEntry->m_nSuperTypes != 0) {
1403 : try {
1404 0 : const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(pEntry->m_offset_SUPERTYPES )); //+ (index * sizeof(sal_uInt16))));
1405 : rtl_string2UString(
1406 : pSuperTypeName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1407 0 : RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1408 0 : return;
1409 0 : } catch (BlopObject::BoundsError &) {
1410 : SAL_WARN("registry", "bad data");
1411 : }
1412 : }
1413 0 : rtl_uString_new(pSuperTypeName);
1414 : }
1415 :
1416 0 : static void TYPEREG_CALLTYPE getUik(TypeReaderImpl hEntry, RTUik* uik)
1417 : {
1418 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1419 :
1420 0 : if (pEntry != NULL)
1421 : {
1422 : try {
1423 0 : pEntry->m_pCP->readUIK(pEntry->readUINT16(OFFSET_UIK), uik);
1424 0 : } catch (BlopObject::BoundsError &) {
1425 : SAL_WARN("registry", "bad data");
1426 : }
1427 : }
1428 0 : }
1429 :
1430 0 : void TYPEREG_CALLTYPE typereg_reader_getDocumentation(void * hEntry, rtl_uString** pDoku)
1431 : {
1432 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1433 0 : if (pEntry != nullptr) {
1434 : try {
1435 0 : const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(OFFSET_DOKU));
1436 : rtl_string2UString(
1437 : pDoku, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1438 0 : RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1439 0 : return;
1440 0 : } catch (BlopObject::BoundsError &) {
1441 : SAL_WARN("registry", "bad data");
1442 : }
1443 : }
1444 0 : rtl_uString_new(pDoku);
1445 : }
1446 :
1447 0 : void TYPEREG_CALLTYPE typereg_reader_getFileName(void * hEntry, rtl_uString** pFileName)
1448 : {
1449 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1450 0 : if (pEntry != nullptr) {
1451 : try {
1452 0 : const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(OFFSET_FILENAME));
1453 : rtl_string2UString(
1454 : pFileName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1455 0 : RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1456 0 : return;
1457 0 : } catch (BlopObject::BoundsError &) {
1458 : SAL_WARN("registry", "bad data");
1459 : }
1460 : }
1461 0 : rtl_uString_new(pFileName);
1462 : }
1463 :
1464 :
1465 0 : sal_uInt16 TYPEREG_CALLTYPE typereg_reader_getFieldCount(void * hEntry)
1466 : {
1467 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1468 :
1469 0 : if (pEntry == NULL) return 0;
1470 :
1471 0 : return pEntry->m_pFields->m_numOfEntries;
1472 : }
1473 :
1474 0 : static sal_uInt32 TYPEREG_CALLTYPE getFieldCount(TypeReaderImpl hEntry)
1475 : {
1476 0 : return typereg_reader_getFieldCount(hEntry);
1477 : }
1478 :
1479 0 : void TYPEREG_CALLTYPE typereg_reader_getFieldName(void * hEntry, rtl_uString** pFieldName, sal_uInt16 index)
1480 : {
1481 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1482 :
1483 0 : if (pEntry == NULL)
1484 : {
1485 0 : rtl_uString_new(pFieldName);
1486 0 : return;
1487 : }
1488 0 : const sal_Char* pTmp = pEntry->m_pFields->getFieldName(index);
1489 : rtl_string2UString(
1490 : pFieldName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1491 0 : RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1492 : }
1493 :
1494 0 : void TYPEREG_CALLTYPE typereg_reader_getFieldTypeName(void * hEntry, rtl_uString** pFieldType, sal_uInt16 index)
1495 : {
1496 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1497 :
1498 0 : if (pEntry == NULL)
1499 : {
1500 0 : rtl_uString_new(pFieldType);
1501 0 : return;
1502 : }
1503 :
1504 0 : const sal_Char* pTmp = pEntry->m_pFields->getFieldType(index);
1505 : rtl_string2UString(
1506 : pFieldType, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1507 0 : RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1508 : }
1509 :
1510 0 : RTFieldAccess TYPEREG_CALLTYPE typereg_reader_getFieldFlags(void * hEntry, sal_uInt16 index)
1511 : {
1512 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1513 :
1514 0 : if (pEntry == NULL) return RTFieldAccess::INVALID;
1515 :
1516 0 : return pEntry->m_pFields->getFieldAccess(index);
1517 : }
1518 :
1519 0 : bool TYPEREG_CALLTYPE typereg_reader_getFieldValue(
1520 : void * hEntry, sal_uInt16 index, RTValueType * type,
1521 : RTConstValueUnion * value)
1522 : {
1523 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1524 :
1525 0 : if (pEntry == NULL) {
1526 0 : *type = RT_TYPE_NONE;
1527 0 : return true;
1528 : }
1529 :
1530 : try {
1531 0 : *type = pEntry->m_pFields->getFieldConstValue(index, value);
1532 0 : } catch (std::bad_alloc &) {
1533 0 : return false;
1534 : }
1535 0 : return true;
1536 : }
1537 :
1538 0 : static RTValueType TYPEREG_CALLTYPE getFieldConstValue(TypeReaderImpl hEntry, sal_uInt16 index, RTConstValueUnion* value)
1539 : {
1540 0 : RTValueType t = RT_TYPE_NONE;
1541 0 : typereg_reader_getFieldValue(hEntry, index, &t, value);
1542 0 : return t;
1543 : }
1544 :
1545 0 : void TYPEREG_CALLTYPE typereg_reader_getFieldDocumentation(void * hEntry, rtl_uString** pDoku, sal_uInt16 index)
1546 : {
1547 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1548 :
1549 0 : if (pEntry == NULL)
1550 : {
1551 0 : rtl_uString_new(pDoku);
1552 0 : return;
1553 : }
1554 :
1555 0 : const sal_Char* pTmp = pEntry->m_pFields->getFieldDoku(index);
1556 : rtl_string2UString(
1557 : pDoku, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1558 0 : RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1559 : }
1560 :
1561 0 : void TYPEREG_CALLTYPE typereg_reader_getFieldFileName(void * hEntry, rtl_uString** pFieldFileName, sal_uInt16 index)
1562 : {
1563 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1564 :
1565 0 : if (pEntry == NULL)
1566 : {
1567 0 : rtl_uString_new(pFieldFileName);
1568 0 : return;
1569 : }
1570 :
1571 0 : const sal_Char* pTmp = pEntry->m_pFields->getFieldFileName(index);
1572 : rtl_string2UString(
1573 : pFieldFileName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1574 0 : RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1575 : }
1576 :
1577 :
1578 0 : sal_uInt16 TYPEREG_CALLTYPE typereg_reader_getMethodCount(void * hEntry)
1579 : {
1580 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1581 :
1582 0 : if (pEntry == NULL) return 0;
1583 :
1584 0 : return pEntry->m_pMethods->m_numOfEntries;
1585 : }
1586 :
1587 0 : static sal_uInt32 TYPEREG_CALLTYPE getMethodCount(TypeReaderImpl hEntry)
1588 : {
1589 0 : return typereg_reader_getMethodCount(hEntry);
1590 : }
1591 :
1592 0 : void TYPEREG_CALLTYPE typereg_reader_getMethodName(void * hEntry, rtl_uString** pMethodName, sal_uInt16 index)
1593 : {
1594 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1595 :
1596 0 : if (pEntry == NULL)
1597 : {
1598 0 : rtl_uString_new(pMethodName);
1599 0 : return;
1600 : }
1601 :
1602 0 : const sal_Char* pTmp = pEntry->m_pMethods->getMethodName(index);
1603 : rtl_string2UString(
1604 : pMethodName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1605 0 : RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1606 : }
1607 :
1608 0 : sal_uInt16 TYPEREG_CALLTYPE typereg_reader_getMethodParameterCount(
1609 : void * hEntry, sal_uInt16 index)
1610 : {
1611 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1612 :
1613 0 : if (pEntry == NULL) return 0;
1614 :
1615 0 : return pEntry->m_pMethods->getMethodParamCount(index);
1616 : }
1617 :
1618 0 : static sal_uInt32 TYPEREG_CALLTYPE getMethodParamCount(TypeReaderImpl hEntry, sal_uInt16 index)
1619 : {
1620 0 : return typereg_reader_getMethodParameterCount(hEntry, index);
1621 : }
1622 :
1623 0 : void TYPEREG_CALLTYPE typereg_reader_getMethodParameterTypeName(void * hEntry, rtl_uString** pMethodParamType, sal_uInt16 index, sal_uInt16 paramIndex)
1624 : {
1625 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1626 :
1627 0 : if (pEntry == NULL)
1628 : {
1629 0 : rtl_uString_new(pMethodParamType);
1630 0 : return;
1631 : }
1632 :
1633 0 : const sal_Char* pTmp = pEntry->m_pMethods->getMethodParamType(index, paramIndex);
1634 : rtl_string2UString(
1635 : pMethodParamType, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1636 0 : RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1637 : }
1638 :
1639 0 : void TYPEREG_CALLTYPE typereg_reader_getMethodParameterName(void * hEntry, rtl_uString** pMethodParamName, sal_uInt16 index, sal_uInt16 paramIndex)
1640 : {
1641 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1642 :
1643 0 : if (pEntry == NULL)
1644 : {
1645 0 : rtl_uString_new(pMethodParamName);
1646 0 : return;
1647 : }
1648 :
1649 0 : const sal_Char* pTmp = pEntry->m_pMethods->getMethodParamName(index, paramIndex);
1650 : rtl_string2UString(
1651 : pMethodParamName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1652 0 : RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1653 : }
1654 :
1655 0 : RTParamMode TYPEREG_CALLTYPE typereg_reader_getMethodParameterFlags(void * hEntry, sal_uInt16 index, sal_uInt16 paramIndex)
1656 : {
1657 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1658 :
1659 0 : if (pEntry == NULL) return RT_PARAM_INVALID;
1660 :
1661 0 : return pEntry->m_pMethods->getMethodParamMode(index, paramIndex);
1662 : }
1663 :
1664 0 : sal_uInt16 TYPEREG_CALLTYPE typereg_reader_getMethodExceptionCount(
1665 : void * hEntry, sal_uInt16 index)
1666 : {
1667 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1668 :
1669 0 : if (pEntry == NULL) return 0;
1670 :
1671 0 : return pEntry->m_pMethods->getMethodExcCount(index);
1672 : }
1673 :
1674 0 : static sal_uInt32 TYPEREG_CALLTYPE getMethodExcCount(TypeReaderImpl hEntry, sal_uInt16 index)
1675 : {
1676 0 : return typereg_reader_getMethodExceptionCount(hEntry, index);
1677 : }
1678 :
1679 0 : void TYPEREG_CALLTYPE typereg_reader_getMethodExceptionTypeName(void * hEntry, rtl_uString** pMethodExcpType, sal_uInt16 index, sal_uInt16 excIndex)
1680 : {
1681 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1682 :
1683 0 : if (pEntry == NULL)
1684 : {
1685 0 : rtl_uString_new(pMethodExcpType);
1686 0 : return;
1687 : }
1688 :
1689 0 : const sal_Char* pTmp = pEntry->m_pMethods->getMethodExcType(index, excIndex);
1690 : rtl_string2UString(
1691 : pMethodExcpType, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1692 0 : RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1693 : }
1694 :
1695 0 : void TYPEREG_CALLTYPE typereg_reader_getMethodReturnTypeName(void * hEntry, rtl_uString** pMethodReturnType, sal_uInt16 index)
1696 : {
1697 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1698 :
1699 0 : if (pEntry == NULL)
1700 : {
1701 0 : rtl_uString_new(pMethodReturnType);
1702 0 : return;
1703 : }
1704 :
1705 0 : const sal_Char* pTmp = pEntry->m_pMethods->getMethodReturnType(index);
1706 : rtl_string2UString(
1707 : pMethodReturnType, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1708 0 : RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1709 : }
1710 :
1711 0 : RTMethodMode TYPEREG_CALLTYPE typereg_reader_getMethodFlags(void * hEntry, sal_uInt16 index)
1712 : {
1713 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1714 :
1715 0 : if (pEntry == NULL) return RTMethodMode::INVALID;
1716 :
1717 0 : return pEntry->m_pMethods->getMethodMode(index);
1718 : }
1719 :
1720 0 : void TYPEREG_CALLTYPE typereg_reader_getMethodDocumentation(void * hEntry, rtl_uString** pMethodDoku, sal_uInt16 index)
1721 : {
1722 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1723 :
1724 0 : if (pEntry == NULL)
1725 : {
1726 0 : rtl_uString_new(pMethodDoku);
1727 0 : return;
1728 : }
1729 :
1730 0 : const sal_Char* pTmp = pEntry->m_pMethods->getMethodDoku(index);
1731 : rtl_string2UString(
1732 : pMethodDoku, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1733 0 : RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1734 : }
1735 :
1736 0 : sal_uInt16 TYPEREG_CALLTYPE typereg_reader_getReferenceCount(void * hEntry)
1737 : {
1738 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1739 :
1740 0 : if (pEntry == NULL) return 0;
1741 :
1742 0 : return pEntry->m_pReferences->m_numOfEntries;
1743 : }
1744 :
1745 0 : static sal_uInt32 TYPEREG_CALLTYPE getReferenceCount(TypeReaderImpl hEntry)
1746 : {
1747 0 : return typereg_reader_getReferenceCount(hEntry);
1748 : }
1749 :
1750 0 : void TYPEREG_CALLTYPE typereg_reader_getReferenceTypeName(void * hEntry, rtl_uString** pReferenceName, sal_uInt16 index)
1751 : {
1752 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1753 :
1754 0 : if (pEntry == NULL)
1755 : {
1756 0 : rtl_uString_new(pReferenceName);
1757 0 : return;
1758 : }
1759 :
1760 0 : const sal_Char* pTmp = pEntry->m_pReferences->getReferenceName(index);
1761 : rtl_string2UString(
1762 : pReferenceName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1763 0 : RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1764 : }
1765 :
1766 0 : RTReferenceType TYPEREG_CALLTYPE typereg_reader_getReferenceSort(void * hEntry, sal_uInt16 index)
1767 : {
1768 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1769 :
1770 0 : if (pEntry == NULL) return RTReferenceType::INVALID;
1771 :
1772 0 : return pEntry->m_pReferences->getReferenceType(index);
1773 : }
1774 :
1775 0 : void TYPEREG_CALLTYPE typereg_reader_getReferenceDocumentation(void * hEntry, rtl_uString** pReferenceDoku, sal_uInt16 index)
1776 : {
1777 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1778 :
1779 0 : if (pEntry == NULL)
1780 : {
1781 0 : rtl_uString_new(pReferenceDoku);
1782 0 : return;
1783 : }
1784 :
1785 0 : const sal_Char* pTmp = pEntry->m_pReferences->getReferenceDoku(index);
1786 : rtl_string2UString(
1787 : pReferenceDoku, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1788 0 : RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1789 : }
1790 :
1791 0 : RTFieldAccess TYPEREG_CALLTYPE typereg_reader_getReferenceFlags(void * hEntry, sal_uInt16 index)
1792 : {
1793 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1794 :
1795 0 : if (pEntry == NULL) return RTFieldAccess::INVALID;
1796 :
1797 0 : return pEntry->m_pReferences->getReferenceAccess(index);
1798 : }
1799 :
1800 0 : sal_uInt16 TYPEREG_CALLTYPE typereg_reader_getSuperTypeCount(void * hEntry)
1801 : {
1802 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1803 :
1804 0 : if (pEntry == NULL) return 0;
1805 :
1806 0 : return pEntry->m_nSuperTypes;
1807 : }
1808 :
1809 0 : void TYPEREG_CALLTYPE typereg_reader_getSuperTypeName(
1810 : void * hEntry, rtl_uString ** pSuperTypeName, sal_uInt16 index)
1811 : {
1812 0 : TypeRegistryEntry* pEntry = static_cast<TypeRegistryEntry*>(hEntry);
1813 0 : if (pEntry != nullptr) {
1814 : try {
1815 : OSL_ASSERT(index < pEntry->m_nSuperTypes);
1816 0 : const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(pEntry->m_offset_SUPERTYPES + (index * sizeof(sal_uInt16))));
1817 : rtl_string2UString(
1818 : pSuperTypeName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
1819 0 : RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
1820 0 : return;
1821 0 : } catch (BlopObject::BoundsError &) {
1822 : SAL_WARN("registry", "bad data");
1823 : }
1824 : }
1825 0 : rtl_uString_new(pSuperTypeName);
1826 : }
1827 :
1828 0 : RegistryTypeReader_Api* TYPEREG_CALLTYPE initRegistryTypeReader_Api()
1829 : {
1830 : static RegistryTypeReader_Api aApi= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1831 0 : if (!aApi.acquire)
1832 : {
1833 0 : aApi.createEntry = &createEntry;
1834 0 : aApi.acquire = &typereg_reader_acquire;
1835 0 : aApi.release = &typereg_reader_release;
1836 0 : aApi.getMinorVersion = &getMinorVersion;
1837 0 : aApi.getMajorVersion = &getMajorVersion;
1838 0 : aApi.getTypeClass = &typereg_reader_getTypeClass;
1839 0 : aApi.getTypeName = &typereg_reader_getTypeName;
1840 0 : aApi.getSuperTypeName = &getSuperTypeName;
1841 0 : aApi.getUik = &getUik;
1842 0 : aApi.getDoku = &typereg_reader_getDocumentation;
1843 0 : aApi.getFileName = &typereg_reader_getFileName;
1844 0 : aApi.getFieldCount = &getFieldCount;
1845 0 : aApi.getFieldName = &typereg_reader_getFieldName;
1846 0 : aApi.getFieldType = &typereg_reader_getFieldTypeName;
1847 0 : aApi.getFieldAccess = &typereg_reader_getFieldFlags;
1848 0 : aApi.getFieldConstValue = &getFieldConstValue;
1849 0 : aApi.getFieldDoku = &typereg_reader_getFieldDocumentation;
1850 0 : aApi.getFieldFileName = &typereg_reader_getFieldFileName;
1851 0 : aApi.getMethodCount = &getMethodCount;
1852 0 : aApi.getMethodName = &typereg_reader_getMethodName;
1853 0 : aApi.getMethodParamCount = &getMethodParamCount;
1854 0 : aApi.getMethodParamType = &typereg_reader_getMethodParameterTypeName;
1855 0 : aApi.getMethodParamName = &typereg_reader_getMethodParameterName;
1856 0 : aApi.getMethodParamMode = &typereg_reader_getMethodParameterFlags;
1857 0 : aApi.getMethodExcCount = &getMethodExcCount;
1858 0 : aApi.getMethodExcType = &typereg_reader_getMethodExceptionTypeName;
1859 0 : aApi.getMethodReturnType = &typereg_reader_getMethodReturnTypeName;
1860 0 : aApi.getMethodMode = &typereg_reader_getMethodFlags;
1861 0 : aApi.getMethodDoku = &typereg_reader_getMethodDocumentation;
1862 0 : aApi.getReferenceCount = &getReferenceCount;
1863 0 : aApi.getReferenceName = &typereg_reader_getReferenceTypeName;
1864 0 : aApi.getReferenceType = &typereg_reader_getReferenceSort;
1865 0 : aApi.getReferenceDoku = &typereg_reader_getReferenceDocumentation;
1866 0 : aApi.getReferenceAccess = &typereg_reader_getReferenceFlags;
1867 :
1868 0 : return (&aApi);
1869 : }
1870 : else
1871 : {
1872 0 : return (&aApi);
1873 : }
1874 : }
1875 :
1876 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|