File: | home/maarten/src/libreoffice/core/registry/source/reflwrit.cxx |
Warning: | line 601, column 9 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | ||||
21 | #include <new> | |||
22 | #include <memory> | |||
23 | #include <algorithm> | |||
24 | #include <sal/types.h> | |||
25 | #include <osl/endian.h> | |||
26 | #include <rtl/string.hxx> | |||
27 | #include <rtl/ustring.hxx> | |||
28 | ||||
29 | #include "reflwrit.hxx" | |||
30 | #include <registry/refltype.hxx> | |||
31 | #include <registry/version.h> | |||
32 | #include <registry/writer.h> | |||
33 | ||||
34 | #include "reflcnst.hxx" | |||
35 | ||||
36 | ||||
37 | namespace { | |||
38 | ||||
39 | OString toByteString(rtl_uString const * str) { | |||
40 | return OString( | |||
41 | str->buffer, str->length, RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)), | |||
42 | OUSTRING_TO_OSTRING_CVTFLAGS(((sal_uInt32)0x0006) | ((sal_uInt32)0x0060) | ((sal_uInt32)0x0100 ) | ((sal_uInt32)0x0400))); | |||
43 | } | |||
44 | ||||
45 | } | |||
46 | ||||
47 | const sal_Unicode NULL_WSTRING[1] = { 0 }; | |||
48 | ||||
49 | #define BLOP_OFFSET_MAGIC0 0 | |||
50 | #define BLOP_OFFSET_SIZE(0 + sizeof(sal_uInt32)) (BLOP_OFFSET_MAGIC0 + sizeof(sal_uInt32)) | |||
51 | #define BLOP_OFFSET_MINOR((0 + sizeof(sal_uInt32)) + sizeof(sal_uInt32)) (BLOP_OFFSET_SIZE(0 + sizeof(sal_uInt32)) + sizeof(sal_uInt32)) | |||
52 | #define BLOP_OFFSET_MAJOR(((0 + sizeof(sal_uInt32)) + sizeof(sal_uInt32)) + sizeof(sal_uInt16 )) (BLOP_OFFSET_MINOR((0 + sizeof(sal_uInt32)) + sizeof(sal_uInt32)) + sizeof(sal_uInt16)) | |||
53 | #define BLOP_OFFSET_N_ENTRIES((((0 + sizeof(sal_uInt32)) + sizeof(sal_uInt32)) + sizeof(sal_uInt16 )) + sizeof(sal_uInt16)) (BLOP_OFFSET_MAJOR(((0 + sizeof(sal_uInt32)) + sizeof(sal_uInt32)) + sizeof(sal_uInt16 )) + sizeof(sal_uInt16)) | |||
54 | #define BLOP_HEADER_N_ENTRIES6 6 | |||
55 | ||||
56 | #define BLOP_FIELD_N_ENTRIES6 6 | |||
57 | ||||
58 | #define BLOP_METHOD_N_ENTRIES5 5 | |||
59 | ||||
60 | #define BLOP_PARAM_N_ENTRIES3 3 | |||
61 | ||||
62 | #define BLOP_REFERENCE_N_ENTRIES4 4 | |||
63 | ||||
64 | sal_uInt32 UINT16StringLen(const sal_uInt8* wstring) | |||
65 | { | |||
66 | if (!wstring) return 0; | |||
67 | ||||
68 | const sal_uInt8* b = wstring; | |||
69 | ||||
70 | while (b[0] || b[1]) b += sizeof(sal_uInt16); | |||
71 | ||||
72 | return ((b - wstring) / sizeof(sal_uInt16)); | |||
73 | } | |||
74 | ||||
75 | sal_uInt32 writeString(sal_uInt8* buffer, const sal_Unicode* v) | |||
76 | { | |||
77 | sal_uInt32 len = rtl_ustr_getLength(v) + 1; | |||
78 | sal_uInt32 i; | |||
79 | sal_uInt8* buff = buffer; | |||
80 | ||||
81 | for (i = 0; i < len; i++) | |||
82 | { | |||
83 | buff += writeUINT16(buff, static_cast<sal_uInt16>(v[i])); | |||
84 | } | |||
85 | ||||
86 | return (buff - buffer); | |||
87 | } | |||
88 | ||||
89 | sal_uInt32 readString(const sal_uInt8* buffer, sal_Unicode* v, sal_uInt32 maxSize) | |||
90 | { | |||
91 | sal_uInt32 len = UINT16StringLen(buffer) + 1; | |||
92 | sal_uInt32 i; | |||
93 | sal_uInt8* buff = const_cast<sal_uInt8*>(buffer); | |||
94 | ||||
95 | if(len > maxSize / 2) | |||
96 | { | |||
97 | len = maxSize / 2; | |||
98 | } | |||
99 | ||||
100 | for (i = 0; i < (len - 1); i++) | |||
101 | { | |||
102 | sal_uInt16 aChar; | |||
103 | ||||
104 | buff += readUINT16(buff, aChar); | |||
105 | ||||
106 | v[i] = static_cast<sal_Unicode>(aChar); | |||
107 | } | |||
108 | ||||
109 | v[len - 1] = L'\0'; | |||
110 | ||||
111 | return (buff - buffer); | |||
112 | } | |||
113 | ||||
114 | sal_uInt32 writeFloat(sal_uInt8* buffer, float v) | |||
115 | { | |||
116 | union | |||
117 | { | |||
118 | float v; | |||
119 | sal_uInt32 b; | |||
120 | } x; | |||
121 | ||||
122 | x.v = v; | |||
123 | ||||
124 | #ifdef REGTYPE_IEEE_NATIVE1 | |||
125 | writeUINT32(buffer, x.b); | |||
126 | #else | |||
127 | # error no IEEE | |||
128 | #endif | |||
129 | ||||
130 | return sizeof(sal_uInt32); | |||
131 | } | |||
132 | ||||
133 | sal_uInt32 writeDouble(sal_uInt8* buffer, double v) | |||
134 | { | |||
135 | union | |||
136 | { | |||
137 | double v; | |||
138 | struct | |||
139 | { | |||
140 | sal_uInt32 b1; | |||
141 | sal_uInt32 b2; | |||
142 | } b; | |||
143 | } x; | |||
144 | ||||
145 | x.v = v; | |||
146 | ||||
147 | #ifdef REGTYPE_IEEE_NATIVE1 | |||
148 | # ifdef OSL_BIGENDIAN | |||
149 | writeUINT32(buffer, x.b.b1); | |||
150 | writeUINT32(buffer + sizeof(sal_uInt32), x.b.b2); | |||
151 | # else | |||
152 | writeUINT32(buffer, x.b.b2); | |||
153 | writeUINT32(buffer + sizeof(sal_uInt32), x.b.b1); | |||
154 | # endif | |||
155 | #else | |||
156 | # error no IEEE | |||
157 | #endif | |||
158 | ||||
159 | return (sizeof(sal_uInt32) + sizeof(sal_uInt32)); | |||
160 | } | |||
161 | ||||
162 | /************************************************************************** | |||
163 | ||||
164 | buffer write functions | |||
165 | ||||
166 | **************************************************************************/ | |||
167 | ||||
168 | namespace { | |||
169 | ||||
170 | /************************************************************************** | |||
171 | ||||
172 | struct CPInfo | |||
173 | ||||
174 | **************************************************************************/ | |||
175 | ||||
176 | struct CPInfo | |||
177 | { | |||
178 | union | |||
179 | { | |||
180 | const char* aUtf8; | |||
181 | RTUik* aUik; | |||
182 | RTConstValueUnion aConst; | |||
183 | } m_value; | |||
184 | struct CPInfo* m_next; | |||
185 | CPInfoTag m_tag; | |||
186 | sal_uInt16 m_index; | |||
187 | ||||
188 | CPInfo(CPInfoTag tag, struct CPInfo* prev); | |||
189 | ||||
190 | sal_uInt32 getBlopSize() const; | |||
191 | ||||
192 | sal_uInt32 toBlop(sal_uInt8* buffer); | |||
193 | }; | |||
194 | ||||
195 | CPInfo::CPInfo(CPInfoTag tag, struct CPInfo* prev) | |||
196 | : m_next(nullptr) | |||
197 | , m_tag(tag) | |||
198 | , m_index(0) | |||
199 | { | |||
200 | if (prev) | |||
201 | { | |||
202 | m_index = prev->m_index + 1; | |||
203 | prev->m_next = this; | |||
204 | } | |||
205 | } | |||
206 | ||||
207 | sal_uInt32 CPInfo::getBlopSize() const | |||
208 | { | |||
209 | sal_uInt32 size = sizeof(sal_uInt32) /* size */ + sizeof(sal_uInt16) /* tag */; | |||
210 | ||||
211 | switch (m_tag) | |||
212 | { | |||
213 | case CP_TAG_CONST_BOOL: | |||
214 | size += sizeof(sal_uInt8); | |||
215 | break; | |||
216 | case CP_TAG_CONST_BYTE: | |||
217 | size += sizeof(sal_uInt8); | |||
218 | break; | |||
219 | case CP_TAG_CONST_INT16: | |||
220 | size += sizeof(sal_Int16); | |||
221 | break; | |||
222 | case CP_TAG_CONST_UINT16: | |||
223 | size += sizeof(sal_uInt16); | |||
224 | break; | |||
225 | case CP_TAG_CONST_INT32: | |||
226 | size += sizeof(sal_Int32); | |||
227 | break; | |||
228 | case CP_TAG_CONST_UINT32: | |||
229 | size += sizeof(sal_uInt32); | |||
230 | break; | |||
231 | case CP_TAG_CONST_INT64: | |||
232 | size += sizeof(sal_Int64); | |||
233 | break; | |||
234 | case CP_TAG_CONST_UINT64: | |||
235 | size += sizeof(sal_uInt64); | |||
236 | break; | |||
237 | case CP_TAG_CONST_FLOAT: | |||
238 | size += sizeof(sal_uInt32); | |||
239 | break; | |||
240 | case CP_TAG_CONST_DOUBLE: | |||
241 | size += sizeof(sal_uInt32) + sizeof(sal_uInt32); | |||
242 | break; | |||
243 | case CP_TAG_CONST_STRING: | |||
244 | size += (rtl_ustr_getLength(m_value.aConst.aString) + 1) * sizeof(sal_uInt16); | |||
245 | break; | |||
246 | case CP_TAG_UTF8_NAME: | |||
247 | size += strlen(m_value.aUtf8) + 1; | |||
248 | break; | |||
249 | case CP_TAG_UIK: | |||
250 | size += sizeof(sal_uInt32) + sizeof(sal_uInt16) + sizeof(sal_uInt16) + sizeof(sal_uInt32) + sizeof(sal_uInt32); | |||
251 | break; | |||
252 | default: | |||
253 | break; | |||
254 | } | |||
255 | ||||
256 | return size; | |||
257 | } | |||
258 | ||||
259 | ||||
260 | sal_uInt32 CPInfo::toBlop(sal_uInt8* buffer) | |||
261 | { | |||
262 | sal_uInt8* buff = buffer; | |||
263 | ||||
264 | buff += writeUINT32(buff, getBlopSize()); | |||
265 | buff += writeUINT16(buff, static_cast<sal_uInt16>(m_tag)); | |||
266 | ||||
267 | switch (m_tag) | |||
268 | { | |||
269 | case CP_TAG_CONST_BOOL: | |||
270 | buff += writeBYTE(buff, static_cast<sal_uInt8>(m_value.aConst.aBool)); | |||
271 | break; | |||
272 | case CP_TAG_CONST_BYTE: | |||
273 | buff += writeBYTE( | |||
274 | buff, static_cast< sal_uInt8 >(m_value.aConst.aByte)); | |||
275 | break; | |||
276 | case CP_TAG_CONST_INT16: | |||
277 | buff += writeINT16(buff, m_value.aConst.aShort); | |||
278 | break; | |||
279 | case CP_TAG_CONST_UINT16: | |||
280 | buff += writeINT16(buff, m_value.aConst.aUShort); | |||
281 | break; | |||
282 | case CP_TAG_CONST_INT32: | |||
283 | buff += writeINT32(buff, m_value.aConst.aLong); | |||
284 | break; | |||
285 | case CP_TAG_CONST_UINT32: | |||
286 | buff += writeUINT32(buff, m_value.aConst.aULong); | |||
287 | break; | |||
288 | case CP_TAG_CONST_INT64: | |||
289 | buff += writeUINT64(buff, m_value.aConst.aHyper); | |||
290 | break; | |||
291 | case CP_TAG_CONST_UINT64: | |||
292 | buff += writeUINT64(buff, m_value.aConst.aUHyper); | |||
293 | break; | |||
294 | case CP_TAG_CONST_FLOAT: | |||
295 | buff += writeFloat(buff, m_value.aConst.aFloat); | |||
296 | break; | |||
297 | case CP_TAG_CONST_DOUBLE: | |||
298 | buff += writeDouble(buff, m_value.aConst.aDouble); | |||
299 | break; | |||
300 | case CP_TAG_CONST_STRING: | |||
301 | buff += writeString(buff, m_value.aConst.aString); | |||
302 | break; | |||
303 | case CP_TAG_UTF8_NAME: | |||
304 | buff += writeUtf8(buff, m_value.aUtf8); | |||
305 | break; | |||
306 | case CP_TAG_UIK: | |||
307 | buff += writeUINT32(buff, m_value.aUik->m_Data1); | |||
308 | buff += writeUINT16(buff, m_value.aUik->m_Data2); | |||
309 | buff += writeUINT16(buff, m_value.aUik->m_Data3); | |||
310 | buff += writeUINT32(buff, m_value.aUik->m_Data4); | |||
311 | buff += writeUINT32(buff, m_value.aUik->m_Data5); | |||
312 | break; | |||
313 | default: | |||
314 | break; | |||
315 | } | |||
316 | ||||
317 | return (buff - buffer); | |||
318 | } | |||
319 | ||||
320 | ||||
321 | /************************************************************************** | |||
322 | ||||
323 | class FieldEntry | |||
324 | ||||
325 | **************************************************************************/ | |||
326 | ||||
327 | class FieldEntry | |||
328 | { | |||
329 | ||||
330 | public: | |||
331 | ||||
332 | OString m_name; | |||
333 | OString m_typeName; | |||
334 | OString m_doku; | |||
335 | OString m_fileName; | |||
336 | RTFieldAccess m_access; | |||
337 | RTValueType m_constValueType; | |||
338 | RTConstValueUnion m_constValue; | |||
339 | ||||
340 | FieldEntry(); | |||
341 | ~FieldEntry(); | |||
342 | ||||
343 | void setData(const OString& name, | |||
344 | const OString& typeName, | |||
345 | const OString& doku, | |||
346 | const OString& fileName, | |||
347 | RTFieldAccess access, | |||
348 | RTValueType constValueType, | |||
349 | RTConstValueUnion constValue); | |||
350 | // throws std::bad_alloc | |||
351 | }; | |||
352 | ||||
353 | FieldEntry::FieldEntry() | |||
354 | : m_access(RTFieldAccess::INVALID) | |||
355 | , m_constValueType(RT_TYPE_NONE) | |||
356 | { | |||
357 | } | |||
358 | ||||
359 | FieldEntry::~FieldEntry() | |||
360 | { | |||
361 | if ( | |||
362 | (m_constValueType == RT_TYPE_STRING) && | |||
363 | m_constValue.aString && | |||
364 | (m_constValue.aString != NULL_WSTRING) | |||
365 | ) | |||
366 | { | |||
367 | delete[] m_constValue.aString; | |||
368 | } | |||
369 | } | |||
370 | ||||
371 | void FieldEntry::setData(const OString& name, | |||
372 | const OString& typeName, | |||
373 | const OString& doku, | |||
374 | const OString& fileName, | |||
375 | RTFieldAccess access, | |||
376 | RTValueType constValueType, | |||
377 | RTConstValueUnion constValue) | |||
378 | { | |||
379 | std::unique_ptr<sal_Unicode[]> newValue; | |||
380 | if (constValueType == RT_TYPE_STRING && constValue.aString != nullptr) { | |||
381 | sal_Int32 n = rtl_ustr_getLength(constValue.aString) + 1; | |||
382 | newValue.reset(new sal_Unicode[n]); | |||
383 | memcpy(newValue.get(), constValue.aString, n * sizeof (sal_Unicode)); | |||
384 | } | |||
385 | ||||
386 | m_name = name; | |||
387 | m_typeName = typeName; | |||
388 | m_doku = doku; | |||
389 | m_fileName = fileName; | |||
390 | ||||
391 | if ( | |||
392 | (m_constValueType == RT_TYPE_STRING) && | |||
393 | m_constValue.aString && | |||
394 | (m_constValue.aString != NULL_WSTRING) | |||
395 | ) | |||
396 | { | |||
397 | delete[] m_constValue.aString; | |||
398 | } | |||
399 | ||||
400 | m_access = access; | |||
401 | m_constValueType = constValueType; | |||
402 | ||||
403 | if (m_constValueType == RT_TYPE_STRING) | |||
404 | { | |||
405 | if (constValue.aString == nullptr) | |||
406 | m_constValue.aString = NULL_WSTRING; | |||
407 | else | |||
408 | { | |||
409 | m_constValue.aString = newValue.release(); | |||
410 | } | |||
411 | } | |||
412 | else | |||
413 | { | |||
414 | m_constValue = constValue; | |||
415 | } | |||
416 | } | |||
417 | ||||
418 | /************************************************************************** | |||
419 | ||||
420 | class ParamEntry | |||
421 | ||||
422 | **************************************************************************/ | |||
423 | ||||
424 | class ParamEntry | |||
425 | { | |||
426 | public: | |||
427 | ||||
428 | OString m_typeName; | |||
429 | OString m_name; | |||
430 | RTParamMode m_mode; | |||
431 | ||||
432 | ParamEntry(); | |||
433 | ||||
434 | void setData(const OString& typeName, | |||
435 | const OString& name, | |||
436 | RTParamMode mode); | |||
437 | }; | |||
438 | ||||
439 | ParamEntry::ParamEntry() | |||
440 | : m_mode(RT_PARAM_INVALID) | |||
441 | { | |||
442 | } | |||
443 | ||||
444 | void ParamEntry::setData(const OString& typeName, | |||
445 | const OString& name, | |||
446 | RTParamMode mode) | |||
447 | { | |||
448 | m_name = name; | |||
449 | m_typeName = typeName; | |||
450 | m_mode = mode; | |||
451 | } | |||
452 | ||||
453 | /************************************************************************** | |||
454 | ||||
455 | class ReferenceEntry | |||
456 | ||||
457 | **************************************************************************/ | |||
458 | ||||
459 | class ReferenceEntry | |||
460 | { | |||
461 | public: | |||
462 | ||||
463 | OString m_name; | |||
464 | OString m_doku; | |||
465 | RTReferenceType m_type; | |||
466 | RTFieldAccess m_access; | |||
467 | ||||
468 | ReferenceEntry(); | |||
469 | ||||
470 | void setData(const OString& name, | |||
471 | RTReferenceType refType, | |||
472 | const OString& doku, | |||
473 | RTFieldAccess access); | |||
474 | }; | |||
475 | ||||
476 | ReferenceEntry::ReferenceEntry() | |||
477 | : m_type(RTReferenceType::INVALID) | |||
478 | , m_access(RTFieldAccess::INVALID) | |||
479 | { | |||
480 | } | |||
481 | ||||
482 | void ReferenceEntry::setData(const OString& name, | |||
483 | RTReferenceType refType, | |||
484 | const OString& doku, | |||
485 | RTFieldAccess access) | |||
486 | { | |||
487 | m_name = name; | |||
488 | m_doku = doku; | |||
489 | m_type = refType; | |||
490 | m_access = access; | |||
491 | } | |||
492 | ||||
493 | /************************************************************************** | |||
494 | ||||
495 | class MethodEntry | |||
496 | ||||
497 | **************************************************************************/ | |||
498 | ||||
499 | class MethodEntry | |||
500 | { | |||
501 | public: | |||
502 | ||||
503 | OString m_name; | |||
504 | OString m_returnTypeName; | |||
505 | RTMethodMode m_mode; | |||
506 | sal_uInt16 m_paramCount; | |||
507 | std::unique_ptr<ParamEntry[]> m_params; | |||
508 | sal_uInt16 m_excCount; | |||
509 | std::unique_ptr<OString[]> m_excNames; | |||
510 | OString m_doku; | |||
511 | ||||
512 | MethodEntry(); | |||
513 | ||||
514 | void setData(const OString& name, | |||
515 | const OString& returnTypeName, | |||
516 | RTMethodMode mode, | |||
517 | sal_uInt16 paramCount, | |||
518 | sal_uInt16 excCount, | |||
519 | const OString& doku); | |||
520 | ||||
521 | void setExcName(sal_uInt16 excIndex, const OString& name) const; | |||
522 | ||||
523 | protected: | |||
524 | ||||
525 | void reallocParams(sal_uInt16 size); | |||
526 | void reallocExcs(sal_uInt16 size); | |||
527 | }; | |||
528 | ||||
529 | MethodEntry::MethodEntry() | |||
530 | : m_mode(RTMethodMode::INVALID) | |||
531 | , m_paramCount(0) | |||
532 | , m_excCount(0) | |||
533 | { | |||
534 | } | |||
535 | ||||
536 | void MethodEntry::setData(const OString& name, | |||
537 | const OString& returnTypeName, | |||
538 | RTMethodMode mode, | |||
539 | sal_uInt16 paramCount, | |||
540 | sal_uInt16 excCount, | |||
541 | const OString& doku) | |||
542 | { | |||
543 | m_name = name; | |||
544 | m_returnTypeName = returnTypeName; | |||
545 | m_doku = doku; | |||
546 | ||||
547 | m_mode = mode; | |||
548 | ||||
549 | reallocParams(paramCount); | |||
550 | reallocExcs(excCount); | |||
551 | } | |||
552 | ||||
553 | void MethodEntry::setExcName(sal_uInt16 excIndex, const OString& name) const | |||
554 | { | |||
555 | if (excIndex < m_excCount) | |||
556 | { | |||
557 | m_excNames[excIndex] = name; | |||
558 | } | |||
559 | } | |||
560 | ||||
561 | void MethodEntry::reallocParams(sal_uInt16 size) | |||
562 | { | |||
563 | ParamEntry* newParams; | |||
564 | ||||
565 | if (size) | |||
566 | newParams = new ParamEntry[size]; | |||
567 | else | |||
568 | newParams = nullptr; | |||
569 | ||||
570 | if (m_paramCount) | |||
571 | { | |||
572 | sal_uInt16 i; | |||
573 | sal_uInt16 mn = std::min(size, m_paramCount); | |||
574 | ||||
575 | for (i = 0; i < mn; i++) | |||
576 | { | |||
577 | newParams[i].setData(m_params[i].m_typeName, m_params[i].m_name, m_params[i].m_mode); | |||
578 | } | |||
579 | ||||
580 | m_params.reset(); | |||
581 | } | |||
582 | ||||
583 | m_paramCount = size; | |||
584 | m_params.reset( newParams ); | |||
585 | } | |||
586 | ||||
587 | void MethodEntry::reallocExcs(sal_uInt16 size) | |||
588 | { | |||
589 | OString* newExcNames; | |||
590 | ||||
591 | if (size) | |||
592 | newExcNames = new OString[size]; | |||
593 | else | |||
594 | newExcNames = nullptr; | |||
595 | ||||
596 | sal_uInt16 i; | |||
597 | sal_uInt16 mn = std::min(size, m_excCount); | |||
598 | ||||
599 | for (i = 0; i < mn; i++) | |||
600 | { | |||
601 | newExcNames[i] = m_excNames[i]; | |||
| ||||
602 | } | |||
603 | ||||
604 | m_excCount = size; | |||
605 | m_excNames.reset( newExcNames ); | |||
606 | } | |||
607 | ||||
608 | ||||
609 | /************************************************************************** | |||
610 | ||||
611 | class TypeRegistryEntry | |||
612 | ||||
613 | **************************************************************************/ | |||
614 | ||||
615 | class TypeWriter | |||
616 | { | |||
617 | ||||
618 | public: | |||
619 | ||||
620 | sal_uInt32 m_refCount; | |||
621 | typereg_Version m_version; | |||
622 | RTTypeClass m_typeClass; | |||
623 | OString m_typeName; | |||
624 | sal_uInt16 m_nSuperTypes; | |||
625 | std::unique_ptr<OString[]> | |||
626 | m_superTypeNames; | |||
627 | OString m_doku; | |||
628 | OString m_fileName; | |||
629 | sal_uInt16 m_fieldCount; | |||
630 | FieldEntry* m_fields; | |||
631 | sal_uInt16 m_methodCount; | |||
632 | MethodEntry* m_methods; | |||
633 | sal_uInt16 m_referenceCount; | |||
634 | ReferenceEntry* m_references; | |||
635 | ||||
636 | std::unique_ptr<sal_uInt8[]> m_blop; | |||
637 | sal_uInt32 m_blopSize; | |||
638 | ||||
639 | TypeWriter(typereg_Version version, | |||
640 | OString const & documentation, | |||
641 | OString const & fileName, | |||
642 | RTTypeClass RTTypeClass, | |||
643 | bool published, | |||
644 | const OString& typeName, | |||
645 | sal_uInt16 superTypeCount, | |||
646 | sal_uInt16 FieldCount, | |||
647 | sal_uInt16 methodCount, | |||
648 | sal_uInt16 referenceCount); | |||
649 | ||||
650 | ~TypeWriter(); | |||
651 | ||||
652 | void setSuperType(sal_uInt16 index, OString const & name) const; | |||
653 | ||||
654 | void createBlop(); // throws std::bad_alloc | |||
655 | }; | |||
656 | ||||
657 | TypeWriter::TypeWriter(typereg_Version version, | |||
658 | OString const & documentation, | |||
659 | OString const & fileName, | |||
660 | RTTypeClass RTTypeClass, | |||
661 | bool published, | |||
662 | const OString& typeName, | |||
663 | sal_uInt16 superTypeCount, | |||
664 | sal_uInt16 fieldCount, | |||
665 | sal_uInt16 methodCount, | |||
666 | sal_uInt16 referenceCount) | |||
667 | : m_refCount(1) | |||
668 | , m_version(version) | |||
669 | , m_typeClass( | |||
670 | static_cast< enum RTTypeClass >( | |||
671 | RTTypeClass | (published ? RT_TYPE_PUBLISHED : 0))) | |||
672 | , m_typeName(typeName) | |||
673 | , m_nSuperTypes(superTypeCount) | |||
674 | , m_doku(documentation) | |||
675 | , m_fileName(fileName) | |||
676 | , m_fieldCount(fieldCount) | |||
677 | , m_fields(nullptr) | |||
678 | , m_methodCount(methodCount) | |||
679 | , m_methods(nullptr) | |||
680 | , m_referenceCount(referenceCount) | |||
681 | , m_references(nullptr) | |||
682 | , m_blopSize(0) | |||
683 | { | |||
684 | if (m_nSuperTypes > 0) | |||
685 | { | |||
686 | m_superTypeNames.reset( new OString[m_nSuperTypes] ); | |||
687 | } | |||
688 | ||||
689 | if (m_fieldCount) | |||
690 | m_fields = new FieldEntry[fieldCount]; | |||
691 | ||||
692 | if (m_methodCount) | |||
693 | m_methods = new MethodEntry[methodCount]; | |||
694 | ||||
695 | if (m_referenceCount) | |||
696 | m_references = new ReferenceEntry[referenceCount]; | |||
697 | } | |||
698 | ||||
699 | TypeWriter::~TypeWriter() | |||
700 | { | |||
701 | if (m_fieldCount) | |||
702 | delete[] m_fields; | |||
703 | ||||
704 | if (m_methodCount) | |||
705 | delete[] m_methods; | |||
706 | ||||
707 | if (m_referenceCount) | |||
708 | delete[] m_references; | |||
709 | } | |||
710 | ||||
711 | void TypeWriter::setSuperType(sal_uInt16 index, OString const & name) const | |||
712 | { | |||
713 | m_superTypeNames[index] = name; | |||
714 | } | |||
715 | ||||
716 | void TypeWriter::createBlop() | |||
717 | { | |||
718 | //TODO: Fix memory leaks that occur when std::bad_alloc is thrown | |||
719 | ||||
720 | std::unique_ptr<sal_uInt8[]> pBlopFields; | |||
721 | std::unique_ptr<sal_uInt8[]> pBlopMethods; | |||
722 | std::unique_ptr<sal_uInt8[]> pBlopReferences; | |||
723 | sal_uInt8* pBuffer = nullptr; | |||
724 | sal_uInt32 blopFieldsSize = 0; | |||
725 | sal_uInt32 blopMethodsSize = 0; | |||
726 | sal_uInt32 blopReferenceSize = 0; | |||
727 | ||||
728 | CPInfo root(CP_TAG_INVALID, nullptr); | |||
729 | sal_uInt16 cpIndexThisName = 0; | |||
730 | std::unique_ptr<sal_uInt16[]> cpIndexSuperNames; | |||
731 | sal_uInt16 cpIndexDoku = 0; | |||
732 | sal_uInt16 cpIndexFileName = 0; | |||
733 | CPInfo* pInfo = nullptr; | |||
734 | ||||
735 | sal_uInt16 entrySize = sizeof(sal_uInt16); | |||
736 | sal_uInt32 blopHeaderEntrySize = BLOP_OFFSET_N_ENTRIES((((0 + sizeof(sal_uInt32)) + sizeof(sal_uInt32)) + sizeof(sal_uInt16 )) + sizeof(sal_uInt16)) + entrySize + (BLOP_HEADER_N_ENTRIES6 * entrySize); | |||
737 | sal_uInt32 blopFieldEntrySize = BLOP_FIELD_N_ENTRIES6 * entrySize; | |||
738 | sal_uInt32 blopMethodEntrySize = BLOP_METHOD_N_ENTRIES5 * entrySize; | |||
739 | sal_uInt32 blopParamEntrySize = BLOP_PARAM_N_ENTRIES3 * entrySize; | |||
740 | sal_uInt32 blopReferenceEntrySize = BLOP_REFERENCE_N_ENTRIES4 * entrySize; | |||
741 | ||||
742 | sal_uInt32 blopSize = blopHeaderEntrySize; | |||
743 | ||||
744 | // create CP entry for this name | |||
745 | pInfo = new CPInfo(CP_TAG_UTF8_NAME, &root); | |||
746 | pInfo->m_value.aUtf8 = m_typeName.getStr(); | |||
747 | cpIndexThisName = pInfo->m_index; | |||
748 | ||||
749 | // nSuperTypes | |||
750 | blopSize += entrySize; | |||
751 | ||||
752 | // create CP entry for super names | |||
753 | if (m_nSuperTypes) | |||
754 | { | |||
755 | blopSize += m_nSuperTypes * entrySize; | |||
756 | ||||
757 | cpIndexSuperNames.reset(new sal_uInt16[m_nSuperTypes]); | |||
758 | ||||
759 | for (sal_uInt32 i=0; i < m_nSuperTypes; i++) | |||
760 | { | |||
761 | pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); | |||
762 | pInfo->m_value.aUtf8 = m_superTypeNames[i].getStr(); | |||
763 | cpIndexSuperNames[i] = pInfo->m_index; | |||
764 | } | |||
765 | } | |||
766 | ||||
767 | // create CP entry for doku | |||
768 | if (!m_doku.isEmpty()) | |||
769 | { | |||
770 | pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); | |||
771 | pInfo->m_value.aUtf8 = m_doku.getStr(); | |||
772 | cpIndexDoku = pInfo->m_index; | |||
773 | } | |||
774 | ||||
775 | // create CP entry for idl source filename | |||
776 | if (!m_fileName.isEmpty()) | |||
777 | { | |||
778 | pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); | |||
779 | pInfo->m_value.aUtf8 = m_fileName.getStr(); | |||
780 | cpIndexFileName = pInfo->m_index; | |||
781 | } | |||
782 | ||||
783 | // fields blop | |||
784 | blopSize += sizeof(sal_uInt16); // fieldCount + nFieldEntries | |||
785 | ||||
786 | if (m_fieldCount) | |||
787 | { | |||
788 | sal_uInt16 cpIndexName = 0; | |||
789 | sal_uInt16 cpIndexTypeName = 0; | |||
790 | sal_uInt16 cpIndexValue = 0; | |||
791 | sal_uInt16 cpIndexDoku2 = 0; | |||
792 | sal_uInt16 cpIndexFileName2 = 0; | |||
793 | ||||
794 | // nFieldEntries + n fields | |||
795 | blopFieldsSize = sizeof(sal_uInt16) + (m_fieldCount * blopFieldEntrySize); | |||
796 | ||||
797 | blopSize += blopFieldsSize; | |||
798 | ||||
799 | pBlopFields.reset(new sal_uInt8[blopFieldsSize]); | |||
800 | pBuffer = pBlopFields.get(); | |||
801 | ||||
802 | pBuffer += writeUINT16(pBuffer, BLOP_FIELD_N_ENTRIES6); | |||
803 | ||||
804 | for (sal_uInt16 i = 0; i < m_fieldCount; i++) | |||
805 | { | |||
806 | cpIndexName = 0; | |||
807 | cpIndexTypeName = 0; | |||
808 | cpIndexValue = 0; | |||
809 | cpIndexDoku2 = 0; | |||
810 | cpIndexFileName2 = 0; | |||
811 | ||||
812 | pBuffer += writeUINT16(pBuffer, static_cast<sal_uInt16>(m_fields[i].m_access)); | |||
813 | ||||
814 | if (!m_fields[i].m_name.isEmpty()) | |||
815 | { | |||
816 | pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); | |||
817 | pInfo->m_value.aUtf8 = m_fields[i].m_name.getStr(); | |||
818 | cpIndexName = pInfo->m_index; | |||
819 | } | |||
820 | pBuffer += writeUINT16(pBuffer, cpIndexName); | |||
821 | ||||
822 | if (!m_fields[i].m_typeName.isEmpty()) | |||
823 | { | |||
824 | pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); | |||
825 | pInfo->m_value.aUtf8 = m_fields[i].m_typeName.getStr(); | |||
826 | cpIndexTypeName = pInfo->m_index; | |||
827 | } | |||
828 | pBuffer += writeUINT16(pBuffer, cpIndexTypeName); | |||
829 | ||||
830 | if (m_fields[i].m_constValueType != RT_TYPE_NONE) | |||
831 | { | |||
832 | pInfo = new CPInfo(static_cast<CPInfoTag>(m_fields[i].m_constValueType), pInfo); | |||
833 | pInfo->m_value.aConst = m_fields[i].m_constValue; | |||
834 | cpIndexValue = pInfo->m_index; | |||
835 | } | |||
836 | pBuffer += writeUINT16(pBuffer, cpIndexValue); | |||
837 | ||||
838 | if (!m_fields[i].m_doku.isEmpty()) | |||
839 | { | |||
840 | pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); | |||
841 | pInfo->m_value.aUtf8 = m_fields[i].m_doku.getStr(); | |||
842 | cpIndexDoku2 = pInfo->m_index; | |||
843 | } | |||
844 | pBuffer += writeUINT16(pBuffer, cpIndexDoku2); | |||
845 | ||||
846 | if (!m_fields[i].m_fileName.isEmpty()) | |||
847 | { | |||
848 | pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); | |||
849 | pInfo->m_value.aUtf8 = m_fields[i].m_fileName.getStr(); | |||
850 | cpIndexFileName2 = pInfo->m_index; | |||
851 | } | |||
852 | pBuffer += writeUINT16(pBuffer, cpIndexFileName2); | |||
853 | } | |||
854 | } | |||
855 | ||||
856 | // methods blop | |||
857 | blopSize += sizeof(sal_uInt16); // methodCount | |||
858 | ||||
859 | if (m_methodCount) | |||
860 | { | |||
861 | std::unique_ptr<sal_uInt16[]> pMethodEntrySize( new sal_uInt16[m_methodCount] ); | |||
862 | sal_uInt16 cpIndexName = 0; | |||
863 | sal_uInt16 cpIndexReturn = 0; | |||
864 | sal_uInt16 cpIndexDoku2 = 0; | |||
865 | ||||
866 | // nMethodEntries + nParamEntries | |||
867 | blopMethodsSize = (2 * sizeof(sal_uInt16)); | |||
868 | ||||
869 | for (sal_uInt16 i = 0; i < m_methodCount; i++) | |||
870 | { | |||
871 | pMethodEntrySize[i] = static_cast<sal_uInt16>( blopMethodEntrySize + // header | |||
872 | sizeof(sal_uInt16) + // parameterCount | |||
873 | (m_methods[i].m_paramCount * blopParamEntrySize) + // exceptions | |||
874 | sizeof(sal_uInt16) + // exceptionCount | |||
875 | (m_methods[i].m_excCount * sizeof(sal_uInt16)) ); // exceptions | |||
876 | ||||
877 | blopMethodsSize += pMethodEntrySize[i]; | |||
878 | } | |||
879 | ||||
880 | pBlopMethods.reset(new sal_uInt8[blopMethodsSize]); | |||
881 | ||||
882 | blopSize += blopMethodsSize; | |||
883 | ||||
884 | pBuffer = pBlopMethods.get(); | |||
885 | ||||
886 | pBuffer += writeUINT16(pBuffer, BLOP_METHOD_N_ENTRIES5); | |||
887 | pBuffer += writeUINT16(pBuffer, BLOP_PARAM_N_ENTRIES3 ); | |||
888 | ||||
889 | for (sal_uInt16 i = 0; i < m_methodCount; i++) | |||
890 | { | |||
891 | cpIndexReturn = 0; | |||
892 | cpIndexDoku2 = 0; | |||
893 | ||||
894 | pBuffer += writeUINT16(pBuffer, pMethodEntrySize[i]); | |||
895 | pBuffer += writeUINT16( | |||
896 | pBuffer, | |||
897 | sal::static_int_cast< sal_uInt16 >(m_methods[i].m_mode)); | |||
898 | ||||
899 | if (!m_methods[i].m_name.isEmpty()) | |||
900 | { | |||
901 | pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); | |||
902 | pInfo->m_value.aUtf8 = m_methods[i].m_name.getStr(); | |||
903 | cpIndexName = pInfo->m_index; | |||
904 | } | |||
905 | pBuffer += writeUINT16(pBuffer, cpIndexName); | |||
906 | cpIndexName = 0; | |||
907 | ||||
908 | if (!m_methods[i].m_returnTypeName.isEmpty()) | |||
909 | { | |||
910 | pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); | |||
911 | pInfo->m_value.aUtf8 = m_methods[i].m_returnTypeName.getStr(); | |||
912 | cpIndexReturn = pInfo->m_index; | |||
913 | } | |||
914 | pBuffer += writeUINT16(pBuffer, cpIndexReturn); | |||
915 | ||||
916 | if (!m_methods[i].m_doku.isEmpty()) | |||
917 | { | |||
918 | pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); | |||
919 | pInfo->m_value.aUtf8 = m_methods[i].m_doku.getStr(); | |||
920 | cpIndexDoku2 = pInfo->m_index; | |||
921 | } | |||
922 | pBuffer += writeUINT16(pBuffer, cpIndexDoku2); | |||
923 | ||||
924 | sal_uInt16 j; | |||
925 | ||||
926 | pBuffer += writeUINT16(pBuffer, m_methods[i].m_paramCount); | |||
927 | ||||
928 | for (j = 0; j < m_methods[i].m_paramCount; j++) | |||
929 | { | |||
930 | if (!m_methods[i].m_params[j].m_typeName.isEmpty()) | |||
931 | { | |||
932 | pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); | |||
933 | pInfo->m_value.aUtf8 = m_methods[i].m_params[j].m_typeName.getStr(); | |||
934 | cpIndexName = pInfo->m_index; | |||
935 | } | |||
936 | pBuffer += writeUINT16(pBuffer, cpIndexName); | |||
937 | cpIndexName = 0; | |||
938 | ||||
939 | pBuffer += writeUINT16( | |||
940 | pBuffer, | |||
941 | sal::static_int_cast< sal_uInt16 >( | |||
942 | m_methods[i].m_params[j].m_mode)); | |||
943 | ||||
944 | if (!m_methods[i].m_params[j].m_name.isEmpty()) | |||
945 | { | |||
946 | pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); | |||
947 | pInfo->m_value.aUtf8 = m_methods[i].m_params[j].m_name.getStr(); | |||
948 | cpIndexName = pInfo->m_index; | |||
949 | } | |||
950 | pBuffer += writeUINT16(pBuffer, cpIndexName); | |||
951 | cpIndexName = 0; | |||
952 | } | |||
953 | ||||
954 | pBuffer += writeUINT16(pBuffer, m_methods[i].m_excCount); | |||
955 | ||||
956 | for (j = 0; j < m_methods[i].m_excCount; j++) | |||
957 | { | |||
958 | if (!m_methods[i].m_excNames[j].isEmpty()) | |||
959 | { | |||
960 | pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); | |||
961 | pInfo->m_value.aUtf8 = m_methods[i].m_excNames[j].getStr(); | |||
962 | cpIndexName = pInfo->m_index; | |||
963 | } | |||
964 | pBuffer += writeUINT16(pBuffer, cpIndexName); | |||
965 | cpIndexName = 0; | |||
966 | } | |||
967 | } | |||
968 | } | |||
969 | ||||
970 | // reference blop | |||
971 | blopSize += entrySize; // referenceCount | |||
972 | ||||
973 | if (m_referenceCount) | |||
974 | { | |||
975 | sal_uInt16 cpIndexName = 0; | |||
976 | sal_uInt16 cpIndexDoku2 = 0; | |||
977 | ||||
978 | // nReferenceEntries + n references | |||
979 | blopReferenceSize = entrySize + (m_referenceCount * blopReferenceEntrySize); | |||
980 | ||||
981 | blopSize += blopReferenceSize; | |||
982 | ||||
983 | pBlopReferences.reset(new sal_uInt8[blopReferenceSize]); | |||
984 | pBuffer = pBlopReferences.get(); | |||
985 | ||||
986 | pBuffer += writeUINT16(pBuffer, BLOP_REFERENCE_N_ENTRIES4); | |||
987 | ||||
988 | for (sal_uInt16 i = 0; i < m_referenceCount; i++) | |||
989 | { | |||
990 | pBuffer += writeUINT16( | |||
991 | pBuffer, | |||
992 | sal::static_int_cast< sal_uInt16 >(m_references[i].m_type)); | |||
993 | ||||
994 | cpIndexName = 0; | |||
995 | cpIndexDoku2 = 0; | |||
996 | ||||
997 | if (!m_references[i].m_name.isEmpty()) | |||
998 | { | |||
999 | pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); | |||
1000 | pInfo->m_value.aUtf8 = m_references[i].m_name.getStr(); | |||
1001 | cpIndexName = pInfo->m_index; | |||
1002 | } | |||
1003 | pBuffer += writeUINT16(pBuffer, cpIndexName); | |||
1004 | ||||
1005 | if (!m_references[i].m_doku.isEmpty()) | |||
1006 | { | |||
1007 | pInfo = new CPInfo(CP_TAG_UTF8_NAME, pInfo); | |||
1008 | pInfo->m_value.aUtf8 = m_references[i].m_doku.getStr(); | |||
1009 | cpIndexDoku2 = pInfo->m_index; | |||
1010 | } | |||
1011 | pBuffer += writeUINT16(pBuffer, cpIndexDoku2); | |||
1012 | ||||
1013 | pBuffer += writeUINT16(pBuffer, static_cast<sal_uInt16>(m_references[i].m_access)); | |||
1014 | } | |||
1015 | } | |||
1016 | ||||
1017 | ||||
1018 | // get CP infos blop-length | |||
1019 | pInfo = root.m_next; | |||
1020 | sal_uInt32 cpBlopSize = 0; | |||
1021 | sal_uInt16 cpCount = 0; | |||
1022 | ||||
1023 | while (pInfo) | |||
1024 | { | |||
1025 | cpBlopSize += pInfo->getBlopSize(); | |||
1026 | cpCount++; | |||
1027 | pInfo = pInfo->m_next; | |||
1028 | } | |||
1029 | ||||
1030 | blopSize += cpBlopSize; | |||
1031 | blopSize += sizeof(sal_uInt16); // constantPoolCount | |||
1032 | ||||
1033 | // write all in flat buffer | |||
1034 | ||||
1035 | sal_uInt8 * blop = new sal_uInt8[blopSize]; | |||
1036 | ||||
1037 | pBuffer = blop; | |||
1038 | ||||
1039 | // Assumes two's complement arithmetic with modulo-semantics: | |||
1040 | pBuffer += writeUINT32(pBuffer, magic + m_version); | |||
1041 | pBuffer += writeUINT32(pBuffer, blopSize); | |||
1042 | pBuffer += writeUINT16(pBuffer, minorVersion); | |||
1043 | pBuffer += writeUINT16(pBuffer, majorVersion); | |||
1044 | pBuffer += writeUINT16(pBuffer, BLOP_HEADER_N_ENTRIES6); | |||
1045 | ||||
1046 | pBuffer += writeUINT16(pBuffer, sal_uInt16(RT_UNO_IDL)); | |||
1047 | pBuffer += writeUINT16(pBuffer, static_cast<sal_uInt16>(m_typeClass)); | |||
1048 | pBuffer += writeUINT16(pBuffer, cpIndexThisName); | |||
1049 | pBuffer += writeUINT16(pBuffer, 0); // cpIndexUik | |||
1050 | pBuffer += writeUINT16(pBuffer, cpIndexDoku); | |||
1051 | pBuffer += writeUINT16(pBuffer, cpIndexFileName); | |||
1052 | ||||
1053 | // write supertypes | |||
1054 | pBuffer += writeUINT16(pBuffer, m_nSuperTypes); | |||
1055 | if (m_nSuperTypes) | |||
1056 | { | |||
1057 | for (sal_uInt32 i=0; i < m_nSuperTypes; i++) | |||
1058 | { | |||
1059 | pBuffer += writeUINT16(pBuffer, cpIndexSuperNames[i]); | |||
1060 | } | |||
1061 | cpIndexSuperNames.reset(); | |||
1062 | } | |||
1063 | ||||
1064 | pBuffer += writeUINT16(pBuffer, cpCount); | |||
1065 | ||||
1066 | // write and delete CP infos | |||
1067 | pInfo = root.m_next; | |||
1068 | ||||
1069 | while (pInfo) | |||
1070 | { | |||
1071 | CPInfo* pNextInfo = pInfo->m_next; | |||
1072 | ||||
1073 | pBuffer += pInfo->toBlop(pBuffer); | |||
1074 | delete pInfo; | |||
1075 | ||||
1076 | pInfo = pNextInfo; | |||
1077 | } | |||
1078 | ||||
1079 | auto writeList = [&pBuffer]( | |||
1080 | sal_uInt16 count, sal_uInt8 * data, sal_uInt32 size) | |||
1081 | { | |||
1082 | pBuffer += writeUINT16(pBuffer, count); | |||
1083 | if (size != 0) { | |||
1084 | memcpy(pBuffer, data, size); | |||
1085 | pBuffer += size; | |||
1086 | } | |||
1087 | }; | |||
1088 | ||||
1089 | // write fields | |||
1090 | writeList(m_fieldCount, pBlopFields.get(), blopFieldsSize); | |||
1091 | ||||
1092 | // write methods | |||
1093 | writeList(m_methodCount, pBlopMethods.get(), blopMethodsSize); | |||
1094 | ||||
1095 | // write references | |||
1096 | writeList(m_referenceCount, pBlopReferences.get(), blopReferenceSize); | |||
1097 | ||||
1098 | m_blop.reset( blop ); | |||
1099 | m_blopSize = blopSize; | |||
1100 | } | |||
1101 | ||||
1102 | } // unnamed namespace | |||
1103 | ||||
1104 | /************************************************************************** | |||
1105 | ||||
1106 | C-API | |||
1107 | ||||
1108 | **************************************************************************/ | |||
1109 | ||||
1110 | extern "C" { | |||
1111 | ||||
1112 | static void TYPEREG_CALLTYPE release(TypeWriterImpl hEntry) | |||
1113 | { | |||
1114 | TypeWriter* pEntry = static_cast<TypeWriter*>(hEntry); | |||
1115 | ||||
1116 | if (pEntry != nullptr) | |||
1117 | { | |||
1118 | if (--pEntry->m_refCount == 0) | |||
1119 | delete pEntry; | |||
1120 | } | |||
1121 | } | |||
1122 | ||||
1123 | sal_Bool TYPEREG_CALLTYPE typereg_writer_setFieldData( | |||
1124 | void * handle, sal_uInt16 index, rtl_uString const * documentation, | |||
1125 | rtl_uString const * fileName, RTFieldAccess flags, rtl_uString const * name, | |||
1126 | rtl_uString const * typeName, RTValueType valueType, | |||
1127 | RTConstValueUnion valueValue) | |||
1128 | SAL_THROW_EXTERN_C()throw () | |||
1129 | { | |||
1130 | try { | |||
1131 | static_cast< TypeWriter * >(handle)->m_fields[index].setData( | |||
1132 | toByteString(name), toByteString(typeName), | |||
1133 | toByteString(documentation), toByteString(fileName), flags, | |||
1134 | valueType, valueValue); | |||
1135 | } catch (std::bad_alloc &) { | |||
1136 | return false; | |||
1137 | } | |||
1138 | return true; | |||
1139 | } | |||
1140 | ||||
1141 | static void TYPEREG_CALLTYPE setFieldData(TypeWriterImpl hEntry, | |||
1142 | sal_uInt16 index, | |||
1143 | rtl_uString const * name, | |||
1144 | rtl_uString const * typeName, | |||
1145 | rtl_uString const * doku, | |||
1146 | rtl_uString const * fileName, | |||
1147 | RTFieldAccess access, | |||
1148 | RTValueType valueType, | |||
1149 | RTConstValueUnion constValue) | |||
1150 | { | |||
1151 | typereg_writer_setFieldData( | |||
1152 | hEntry, index, doku, fileName, access, name, typeName, valueType, | |||
1153 | constValue); | |||
1154 | } | |||
1155 | ||||
1156 | sal_Bool TYPEREG_CALLTYPE typereg_writer_setMethodData( | |||
1157 | void * handle, sal_uInt16 index, rtl_uString const * documentation, | |||
1158 | RTMethodMode flags, rtl_uString const * name, | |||
1159 | rtl_uString const * returnTypeName, sal_uInt16 parameterCount, | |||
1160 | sal_uInt16 exceptionCount) | |||
1161 | SAL_THROW_EXTERN_C()throw () | |||
1162 | { | |||
1163 | try { | |||
1164 | static_cast< TypeWriter * >(handle)->m_methods[index].setData( | |||
| ||||
1165 | toByteString(name), toByteString(returnTypeName), flags, | |||
1166 | parameterCount, exceptionCount, toByteString(documentation)); | |||
1167 | } catch (std::bad_alloc &) { | |||
1168 | return false; | |||
1169 | } | |||
1170 | return true; | |||
1171 | } | |||
1172 | ||||
1173 | sal_Bool TYPEREG_CALLTYPE typereg_writer_setMethodParameterData( | |||
1174 | void const * handle, sal_uInt16 methodIndex, sal_uInt16 parameterIndex, | |||
1175 | RTParamMode flags, rtl_uString const * name, rtl_uString const * typeName) | |||
1176 | SAL_THROW_EXTERN_C()throw () | |||
1177 | { | |||
1178 | try { | |||
1179 | static_cast< TypeWriter const * >(handle)-> | |||
1180 | m_methods[methodIndex].m_params[parameterIndex].setData( | |||
1181 | toByteString(typeName), toByteString(name), flags); | |||
1182 | } catch (std::bad_alloc &) { | |||
1183 | return false; | |||
1184 | } | |||
1185 | return true; | |||
1186 | } | |||
1187 | ||||
1188 | sal_Bool TYPEREG_CALLTYPE typereg_writer_setMethodExceptionTypeName( | |||
1189 | void const * handle, sal_uInt16 methodIndex, sal_uInt16 exceptionIndex, | |||
1190 | rtl_uString const * typeName) | |||
1191 | SAL_THROW_EXTERN_C()throw () | |||
1192 | { | |||
1193 | try { | |||
1194 | static_cast< TypeWriter const * >(handle)->m_methods[methodIndex].setExcName( | |||
1195 | exceptionIndex, toByteString(typeName)); | |||
1196 | } catch (std::bad_alloc &) { | |||
1197 | return false; | |||
1198 | } | |||
1199 | return true; | |||
1200 | } | |||
1201 | ||||
1202 | void const * TYPEREG_CALLTYPE typereg_writer_getBlob(void * handle, sal_uInt32 * size) | |||
1203 | SAL_THROW_EXTERN_C()throw () | |||
1204 | { | |||
1205 | TypeWriter * writer = static_cast< TypeWriter * >(handle); | |||
1206 | if (!writer->m_blop) { | |||
1207 | try { | |||
1208 | writer->createBlop(); | |||
1209 | } catch (std::bad_alloc &) { | |||
1210 | return nullptr; | |||
1211 | } | |||
1212 | } | |||
1213 | *size = writer->m_blopSize; | |||
1214 | return writer->m_blop.get(); | |||
1215 | } | |||
1216 | ||||
1217 | static const sal_uInt8* TYPEREG_CALLTYPE getBlop(TypeWriterImpl hEntry) | |||
1218 | { | |||
1219 | sal_uInt32 size; | |||
1220 | return static_cast< sal_uInt8 const * >( | |||
1221 | typereg_writer_getBlob(hEntry, &size)); | |||
1222 | } | |||
1223 | ||||
1224 | static sal_uInt32 TYPEREG_CALLTYPE getBlopSize(TypeWriterImpl hEntry) | |||
1225 | { | |||
1226 | sal_uInt32 size; | |||
1227 | typereg_writer_getBlob(hEntry, &size); | |||
1228 | return size; | |||
1229 | } | |||
1230 | ||||
1231 | sal_Bool TYPEREG_CALLTYPE typereg_writer_setReferenceData( | |||
1232 | void * handle, sal_uInt16 index, rtl_uString const * documentation, | |||
1233 | RTReferenceType sort, RTFieldAccess flags, rtl_uString const * typeName) | |||
1234 | SAL_THROW_EXTERN_C()throw () | |||
1235 | { | |||
1236 | try { | |||
1237 | static_cast< TypeWriter * >(handle)->m_references[index].setData( | |||
1238 | toByteString(typeName), sort, toByteString(documentation), flags); | |||
1239 | } catch (std::bad_alloc &) { | |||
1240 | return false; | |||
1241 | } | |||
1242 | return true; | |||
1243 | } | |||
1244 | ||||
1245 | void * TYPEREG_CALLTYPE typereg_writer_create( | |||
1246 | typereg_Version version, rtl_uString const * documentation, | |||
1247 | rtl_uString const * fileName, RTTypeClass typeClass, sal_Bool published, | |||
1248 | rtl_uString const * typeName, sal_uInt16 superTypeCount, | |||
1249 | sal_uInt16 fieldCount, sal_uInt16 methodCount, sal_uInt16 referenceCount) | |||
1250 | SAL_THROW_EXTERN_C()throw () | |||
1251 | { | |||
1252 | try { | |||
1253 | return new TypeWriter( | |||
1254 | version, toByteString(documentation), toByteString(fileName), | |||
1255 | typeClass, published, toByteString(typeName), superTypeCount, | |||
1256 | fieldCount, methodCount, referenceCount); | |||
1257 | } catch (std::bad_alloc &) { | |||
1258 | return nullptr; | |||
1259 | } | |||
1260 | } | |||
1261 | ||||
1262 | void TYPEREG_CALLTYPE typereg_writer_destroy(void * handle) SAL_THROW_EXTERN_C()throw () { | |||
1263 | delete static_cast< TypeWriter * >(handle); | |||
1264 | } | |||
1265 | ||||
1266 | sal_Bool TYPEREG_CALLTYPE typereg_writer_setSuperTypeName( | |||
1267 | void const * handle, sal_uInt16 index, rtl_uString const * typeName) | |||
1268 | SAL_THROW_EXTERN_C()throw () | |||
1269 | { | |||
1270 | try { | |||
1271 | static_cast< TypeWriter const * >(handle)->setSuperType( | |||
1272 | index, toByteString(typeName)); | |||
1273 | } catch (std::bad_alloc &) { | |||
1274 | return false; | |||
1275 | } | |||
1276 | return true; | |||
1277 | } | |||
1278 | ||||
1279 | static TypeWriterImpl TYPEREG_CALLTYPE createEntry( | |||
1280 | RTTypeClass typeClass, rtl_uString const * typeName, rtl_uString const * superTypeName, | |||
1281 | sal_uInt16 fieldCount) | |||
1282 | { | |||
1283 | OUString empty; | |||
1284 | sal_uInt16 superTypeCount = rtl_uString_getLength(superTypeName) == 0 | |||
1285 | ? 0 : 1; | |||
1286 | TypeWriterImpl t = typereg_writer_create( | |||
1287 | TYPEREG_VERSION_0, empty.pData, empty.pData, typeClass, false, typeName, | |||
1288 | superTypeCount, fieldCount, 0/*methodCount*/, 0/*referenceCount*/); | |||
1289 | if (superTypeCount > 0) { | |||
1290 | typereg_writer_setSuperTypeName(t, 0, superTypeName); | |||
1291 | } | |||
1292 | return t; | |||
1293 | } | |||
1294 | ||||
1295 | } | |||
1296 | ||||
1297 | RegistryTypeWriter::RegistryTypeWriter(RTTypeClass RTTypeClass, | |||
1298 | const OUString& typeName, | |||
1299 | const OUString& superTypeName, | |||
1300 | sal_uInt16 fieldCount) | |||
1301 | : m_hImpl(nullptr) | |||
1302 | { | |||
1303 | m_hImpl = createEntry(RTTypeClass, | |||
1304 | typeName.pData, | |||
1305 | superTypeName.pData, | |||
1306 | fieldCount); | |||
1307 | } | |||
1308 | ||||
1309 | RegistryTypeWriter::~RegistryTypeWriter() | |||
1310 | { | |||
1311 | release(m_hImpl); | |||
1312 | } | |||
1313 | ||||
1314 | void RegistryTypeWriter::setFieldData( sal_uInt16 index, | |||
1315 | const OUString& name, | |||
1316 | const OUString& typeName, | |||
1317 | const OUString& doku, | |||
1318 | const OUString& fileName, | |||
1319 | RTFieldAccess access, | |||
1320 | const RTConstValue& constValue) | |||
1321 | { | |||
1322 | ::setFieldData(m_hImpl, index, name.pData, typeName.pData, doku.pData, fileName.pData, access, constValue.m_type, constValue.m_value); | |||
1323 | } | |||
1324 | ||||
1325 | const sal_uInt8* RegistryTypeWriter::getBlop() | |||
1326 | { | |||
1327 | return ::getBlop(m_hImpl); | |||
1328 | } | |||
1329 | ||||
1330 | sal_uInt32 RegistryTypeWriter::getBlopSize() | |||
1331 | { | |||
1332 | return ::getBlopSize(m_hImpl); | |||
1333 | } | |||
1334 | ||||
1335 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |