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