Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : : #include <string.h>
21 : :
22 : : #include <rtl/alloc.h>
23 : : #include <osl/diagnose.h>
24 : : #include <osl/interlck.h>
25 : : #include <typelib/typedescription.h>
26 : : #include <uno/data.h>
27 : : #include <uno/dispatcher.h>
28 : : #include <uno/sequence2.h>
29 : :
30 : : #include "constr.hxx"
31 : : #include "copy.hxx"
32 : : #include "destr.hxx"
33 : :
34 : :
35 : : using namespace cppu;
36 : :
37 : : namespace cppu
38 : : {
39 : :
40 : : //------------------------------------------------------------------------------
41 : 13296499 : static inline uno_Sequence * reallocSeq(
42 : : uno_Sequence * pReallocate, sal_Size nElementSize, sal_Int32 nElements )
43 : : {
44 : : OSL_ASSERT( nElements >= 0 );
45 : 13296499 : uno_Sequence * pNew = 0;
46 : 13296499 : sal_uInt32 nSize = calcSeqMemSize( nElementSize, nElements );
47 [ + ]: 13296504 : if (nSize > 0)
48 : : {
49 [ + + ]: 13296509 : if (pReallocate == 0)
50 : : {
51 : 11987287 : pNew = (uno_Sequence *) rtl_allocateMemory( nSize );
52 : : }
53 : : else
54 : : {
55 : 1309222 : pNew = (uno_Sequence *) rtl_reallocateMemory( pReallocate, nSize );
56 : : }
57 [ + + ]: 13296518 : if (pNew != 0)
58 : : {
59 : : // header init
60 : 13296514 : pNew->nRefCount = 1;
61 : 13296514 : pNew->nElements = nElements;
62 : : }
63 : : }
64 : 13296513 : return pNew;
65 : : }
66 : :
67 : : //------------------------------------------------------------------------------
68 : 10378733 : static inline bool idefaultConstructElements(
69 : : uno_Sequence ** ppSeq,
70 : : typelib_TypeDescriptionReference * pElementType,
71 : : sal_Int32 nStartIndex, sal_Int32 nStopIndex,
72 : : sal_Int32 nAlloc = -1 ) // >= 0 means (re)alloc memory for nAlloc elements
73 : : {
74 : 10378733 : uno_Sequence * pSeq = *ppSeq;
75 [ - + + + : 10378733 : switch (pElementType->eTypeClass)
+ + + + +
+ + + + -
- + + - ]
76 : : {
77 : : case typelib_TypeClass_CHAR:
78 [ # # ]: 0 : if (nAlloc >= 0)
79 : 0 : pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc );
80 [ - ]: 0 : if (pSeq != 0)
81 : : {
82 : : memset(
83 : 0 : pSeq->elements + (sizeof(sal_Unicode) * nStartIndex),
84 : : 0,
85 : 0 : sizeof(sal_Unicode) * (nStopIndex - nStartIndex) );
86 : : }
87 : 0 : break;
88 : : case typelib_TypeClass_BOOLEAN:
89 [ + + ]: 37771 : if (nAlloc >= 0)
90 : 37691 : pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
91 [ + - ]: 37771 : if (pSeq != 0)
92 : : {
93 : : memset(
94 : 37771 : pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
95 : : 0,
96 : 37771 : sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
97 : : }
98 : 37771 : break;
99 : : case typelib_TypeClass_BYTE:
100 [ + + ]: 1808309 : if (nAlloc >= 0)
101 : 763534 : pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
102 [ + - ]: 1808317 : if (pSeq != 0)
103 : : {
104 : : memset(
105 : 1808317 : pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
106 : : 0,
107 : 1808317 : sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
108 : : }
109 : 1808317 : break;
110 : : case typelib_TypeClass_SHORT:
111 : : case typelib_TypeClass_UNSIGNED_SHORT:
112 [ + + ]: 7298 : if (nAlloc >= 0)
113 : 2414 : pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
114 [ + - ]: 7298 : if (pSeq != 0)
115 : : {
116 : : memset(
117 : 7298 : pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
118 : : 0,
119 : 7298 : sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
120 : : }
121 : 7298 : break;
122 : : case typelib_TypeClass_LONG:
123 : : case typelib_TypeClass_UNSIGNED_LONG:
124 [ + + ]: 70346 : if (nAlloc >= 0)
125 : 44709 : pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
126 [ + - ]: 70346 : if (pSeq != 0)
127 : : {
128 : : memset(
129 : 70346 : pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
130 : : 0,
131 : 70346 : sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
132 : : }
133 : 70346 : break;
134 : : case typelib_TypeClass_HYPER:
135 : : case typelib_TypeClass_UNSIGNED_HYPER:
136 [ + + ]: 3874 : if (nAlloc >= 0)
137 : 3372 : pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc );
138 [ + - ]: 3874 : if (pSeq != 0)
139 : : {
140 : : memset(
141 : 3874 : pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
142 : : 0,
143 : 3874 : sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
144 : : }
145 : 3874 : break;
146 : : case typelib_TypeClass_FLOAT:
147 : : {
148 [ + - ]: 5 : if (nAlloc >= 0)
149 : 5 : pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
150 [ + - ]: 5 : if (pSeq != 0)
151 : : {
152 : 5 : float * pElements = (float *) pSeq->elements;
153 [ + + ]: 10 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
154 : : {
155 : 5 : pElements[nPos] = 0.0;
156 : : }
157 : : }
158 : 5 : break;
159 : : }
160 : : case typelib_TypeClass_DOUBLE:
161 : : {
162 [ + + ]: 441231 : if (nAlloc >= 0)
163 : 383333 : pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
164 [ + - ]: 441231 : if (pSeq != 0)
165 : : {
166 : 441231 : double * pElements = (double *) pSeq->elements;
167 [ + + ]: 1517038 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
168 : : {
169 : 1075807 : pElements[nPos] = 0.0;
170 : : }
171 : : }
172 : 441231 : break;
173 : : }
174 : : case typelib_TypeClass_STRING:
175 : : {
176 [ + + ]: 1609264 : if (nAlloc >= 0)
177 : 1092503 : pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
178 [ + - ]: 1609264 : if (pSeq != 0)
179 : : {
180 : 1609264 : rtl_uString ** pElements = (rtl_uString **) pSeq->elements;
181 [ + + ]: 8214945 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
182 : : {
183 : 6605681 : pElements[nPos] = 0;
184 : 6605681 : rtl_uString_new( &pElements[nPos] );
185 : : }
186 : : }
187 : 1609264 : break;
188 : : }
189 : : case typelib_TypeClass_TYPE:
190 : : {
191 [ + + ]: 17574 : if (nAlloc >= 0)
192 : : {
193 : : pSeq = reallocSeq(
194 : 16683 : pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
195 : : }
196 [ + - ]: 17574 : if (pSeq != 0)
197 : : {
198 : : typelib_TypeDescriptionReference ** pElements =
199 : 17574 : (typelib_TypeDescriptionReference **) pSeq->elements;
200 [ + + ]: 274364 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
201 : : {
202 : 256790 : pElements[nPos] = _getVoidType();
203 : : }
204 : : }
205 : 17574 : break;
206 : : }
207 : : case typelib_TypeClass_ANY:
208 : : {
209 [ + + ]: 846136 : if (nAlloc >= 0)
210 : 754515 : pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
211 [ + - ]: 846136 : if (pSeq != 0)
212 : : {
213 : 846136 : uno_Any * pElements = (uno_Any *) pSeq->elements;
214 [ + + ]: 3015518 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
215 : : {
216 : 2169382 : CONSTRUCT_EMPTY_ANY( &pElements[nPos] );
217 : : }
218 : : }
219 : 846136 : break;
220 : : }
221 : : case typelib_TypeClass_ENUM:
222 : : {
223 [ + + ]: 6727 : if (nAlloc >= 0)
224 : 6149 : pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
225 [ + - ]: 6727 : if (pSeq != 0)
226 : : {
227 : 6727 : typelib_TypeDescription * pElementTypeDescr = 0;
228 [ + - ][ - + ]: 6727 : TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
[ + - ][ + + ]
[ + - ]
229 : : sal_Int32 eEnum =
230 : : ((typelib_EnumTypeDescription *)
231 : 6727 : pElementTypeDescr)->nDefaultEnumValue;
232 [ + - ][ - + ]: 6727 : TYPELIB_DANGER_RELEASE( pElementTypeDescr );
233 : :
234 : 6727 : sal_Int32 * pElements = (sal_Int32 *) pSeq->elements;
235 [ + + ]: 374025 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
236 : : {
237 : 367298 : pElements[nPos] = eEnum;
238 : : }
239 : : }
240 : 6727 : break;
241 : : }
242 : : case typelib_TypeClass_STRUCT:
243 : : case typelib_TypeClass_EXCEPTION:
244 : : {
245 : 2377813 : typelib_TypeDescription * pElementTypeDescr = 0;
246 [ + - ][ - + ]: 2377813 : TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
[ + - ][ + + ]
[ + - ]
247 : 2377809 : sal_Int32 nElementSize = pElementTypeDescr->nSize;
248 : :
249 [ + + ]: 2377809 : if (nAlloc >= 0)
250 : 997547 : pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
251 [ + - ]: 2377813 : if (pSeq != 0)
252 : : {
253 : 2377813 : char * pElements = pSeq->elements;
254 [ + + ]: 9409494 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
255 : : {
256 : : _defaultConstructStruct(
257 : 7031681 : pElements + (nElementSize * nPos),
258 [ + - ]: 7031681 : (typelib_CompoundTypeDescription *)pElementTypeDescr );
259 : : }
260 : : }
261 : :
262 [ + - ][ - + ]: 2377813 : TYPELIB_DANGER_RELEASE( pElementTypeDescr );
263 : : break;
264 : : }
265 : : case typelib_TypeClass_ARRAY:
266 : : {
267 : 0 : typelib_TypeDescription * pElementTypeDescr = 0;
268 [ # # ][ # # ]: 0 : TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
[ # # ][ # # ]
[ # # ]
269 : 0 : sal_Int32 nElementSize = pElementTypeDescr->nSize;
270 : :
271 [ # # ]: 0 : if (nAlloc >= 0)
272 : 0 : pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
273 [ # # ]: 0 : if (pSeq != 0)
274 : : {
275 : 0 : char * pElements = pSeq->elements;
276 [ # # ]: 0 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
277 : : {
278 : : _defaultConstructArray(
279 : 0 : pElements + (nElementSize * nPos),
280 [ # # ]: 0 : (typelib_ArrayTypeDescription *)pElementTypeDescr );
281 : : }
282 : : }
283 : :
284 [ # # ][ # # ]: 0 : TYPELIB_DANGER_RELEASE( pElementTypeDescr );
285 : : break;
286 : : }
287 : : case typelib_TypeClass_UNION:
288 : : {
289 : 0 : typelib_TypeDescription * pElementTypeDescr = 0;
290 [ # # ][ # # ]: 0 : TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
[ # # ][ # # ]
[ # # ]
291 : 0 : sal_Int32 nElementSize = pElementTypeDescr->nSize;
292 : :
293 [ # # ]: 0 : if (nAlloc >= 0)
294 : 0 : pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
295 [ # # ]: 0 : if (pSeq != 0)
296 : : {
297 : : sal_Int32 nValueOffset =
298 : : ((typelib_UnionTypeDescription *)
299 : 0 : pElementTypeDescr)->nValueOffset;
300 : : sal_Int64 nDefaultDiscr =
301 : : ((typelib_UnionTypeDescription *)
302 : 0 : pElementTypeDescr)->nDefaultDiscriminant;
303 : :
304 : 0 : typelib_TypeDescription * pDefaultTypeDescr = 0;
305 [ # # ][ # # ]: 0 : TYPELIB_DANGER_GET(
[ # # ][ # # ]
[ # # ]
306 : : &pDefaultTypeDescr,
307 : : ((typelib_UnionTypeDescription *)
308 : : pElementTypeDescr)->pDefaultTypeRef );
309 : :
310 : 0 : char * pElements = pSeq->elements;
311 [ # # ]: 0 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
312 : : {
313 : 0 : char * pMem = pElements + (nElementSize * nPos);
314 : : ::uno_constructData(
315 : 0 : (char *)pMem + nValueOffset, pDefaultTypeDescr );
316 : 0 : *(sal_Int64 *)pMem = nDefaultDiscr;
317 : : }
318 [ # # ][ # # ]: 0 : TYPELIB_DANGER_RELEASE( pDefaultTypeDescr );
319 : : }
320 : :
321 [ # # ][ # # ]: 0 : TYPELIB_DANGER_RELEASE( pElementTypeDescr );
322 : : break;
323 : : }
324 : : case typelib_TypeClass_SEQUENCE:
325 : : {
326 [ + + ]: 91387 : if (nAlloc >= 0)
327 : 20895 : pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc );
328 [ + - ]: 91387 : if (pSeq != 0)
329 : : {
330 : : uno_Sequence ** pElements =
331 : 91387 : (uno_Sequence **) pSeq->elements;
332 [ + + ]: 288431 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
333 : : {
334 : 197044 : pElements[nPos] = createEmptySequence();
335 : : }
336 : : }
337 : 91387 : break;
338 : : }
339 : : case typelib_TypeClass_INTERFACE: // either C++ or C-UNO interface
340 [ + + ]: 3060998 : if (nAlloc >= 0)
341 : 2798657 : pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
342 [ + - ]: 3061000 : if (pSeq != 0)
343 : : {
344 : : memset(
345 : 3061000 : pSeq->elements + (sizeof(void *) * nStartIndex),
346 : : 0,
347 : 3061000 : sizeof(void *) * (nStopIndex - nStartIndex) );
348 : : }
349 : 3061000 : break;
350 : : default:
351 : : OSL_FAIL( "### unexpected element type!" );
352 : 0 : pSeq = 0;
353 : 0 : break;
354 : : }
355 : :
356 [ - + ]: 10378736 : if (pSeq == 0)
357 : : {
358 : : OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
359 : 0 : return false;
360 : : }
361 : : else
362 : : {
363 : 10378736 : *ppSeq = pSeq;
364 : 10378736 : return true;
365 : : }
366 : : }
367 : :
368 : : //------------------------------------------------------------------------------
369 : 6152703 : static inline bool icopyConstructFromElements(
370 : : uno_Sequence ** ppSeq, void * pSourceElements,
371 : : typelib_TypeDescriptionReference * pElementType,
372 : : sal_Int32 nStartIndex, sal_Int32 nStopIndex,
373 : : uno_AcquireFunc acquire,
374 : : sal_Int32 nAlloc = -1 ) // >= 0 means (re)alloc memory for nAlloc elements
375 : : {
376 : 6152703 : uno_Sequence * pSeq = *ppSeq;
377 [ - + + + : 6152703 : switch (pElementType->eTypeClass)
+ + + + +
+ + + + -
+ + - ]
378 : : {
379 : : case typelib_TypeClass_CHAR:
380 [ # # ]: 0 : if (nAlloc >= 0)
381 : 0 : pSeq = reallocSeq( pSeq, sizeof(sal_Unicode), nAlloc );
382 [ # # ]: 0 : if (pSeq != 0)
383 : : {
384 : : memcpy(
385 : 0 : pSeq->elements + (sizeof(sal_Unicode) * nStartIndex),
386 : : (char *)pSourceElements + (sizeof(sal_Unicode) * nStartIndex),
387 : 0 : sizeof(sal_Unicode) * (nStopIndex - nStartIndex) );
388 : : }
389 : 0 : break;
390 : : case typelib_TypeClass_BOOLEAN:
391 [ + - ]: 115 : if (nAlloc >= 0)
392 : 115 : pSeq = reallocSeq( pSeq, sizeof(sal_Bool), nAlloc );
393 [ + - ]: 115 : if (pSeq != 0)
394 : : {
395 : : memcpy(
396 : 115 : pSeq->elements + (sizeof(sal_Bool) * nStartIndex),
397 : : (char *)pSourceElements + (sizeof(sal_Bool) * nStartIndex),
398 : 115 : sizeof(sal_Bool) * (nStopIndex - nStartIndex) );
399 : : }
400 : 115 : break;
401 : : case typelib_TypeClass_BYTE:
402 [ + - ]: 1775141 : if (nAlloc >= 0)
403 : 1775141 : pSeq = reallocSeq( pSeq, sizeof(sal_Int8), nAlloc );
404 [ + - ]: 1775141 : if (pSeq != 0)
405 : : {
406 : : memcpy(
407 : 1775141 : pSeq->elements + (sizeof(sal_Int8) * nStartIndex),
408 : : (char *)pSourceElements + (sizeof(sal_Int8) * nStartIndex),
409 : 1775141 : sizeof(sal_Int8) * (nStopIndex - nStartIndex) );
410 : : }
411 : 1775141 : break;
412 : : case typelib_TypeClass_SHORT:
413 : : case typelib_TypeClass_UNSIGNED_SHORT:
414 [ + - ]: 4939 : if (nAlloc >= 0)
415 : 4939 : pSeq = reallocSeq( pSeq, sizeof(sal_Int16), nAlloc );
416 [ + - ]: 4939 : if (pSeq != 0)
417 : : {
418 : : memcpy(
419 : 4939 : pSeq->elements + (sizeof(sal_Int16) * nStartIndex),
420 : : (char *)pSourceElements + (sizeof(sal_Int16) * nStartIndex),
421 : 4939 : sizeof(sal_Int16) * (nStopIndex - nStartIndex) );
422 : : }
423 : 4939 : break;
424 : : case typelib_TypeClass_LONG:
425 : : case typelib_TypeClass_UNSIGNED_LONG:
426 [ + - ]: 25917 : if (nAlloc >= 0)
427 : 25917 : pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
428 [ + - ]: 25917 : if (pSeq != 0)
429 : : {
430 : : memcpy(
431 : 25917 : pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
432 : : (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex),
433 : 25917 : sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
434 : : }
435 : 25917 : break;
436 : : case typelib_TypeClass_HYPER:
437 : : case typelib_TypeClass_UNSIGNED_HYPER:
438 [ + - ]: 601 : if (nAlloc >= 0)
439 : 601 : pSeq = reallocSeq( pSeq, sizeof(sal_Int64), nAlloc );
440 [ + - ]: 601 : if (pSeq != 0)
441 : : {
442 : : memcpy(
443 : 601 : pSeq->elements + (sizeof(sal_Int64) * nStartIndex),
444 : : (char *)pSourceElements + (sizeof(sal_Int64) * nStartIndex),
445 : 601 : sizeof(sal_Int64) * (nStopIndex - nStartIndex) );
446 : : }
447 : 601 : break;
448 : : case typelib_TypeClass_FLOAT:
449 [ + - ]: 25 : if (nAlloc >= 0)
450 : 25 : pSeq = reallocSeq( pSeq, sizeof(float), nAlloc );
451 [ + - ]: 25 : if (pSeq != 0)
452 : : {
453 : : memcpy(
454 : 25 : pSeq->elements + (sizeof(float) * nStartIndex),
455 : : (char *)pSourceElements + (sizeof(float) * nStartIndex),
456 : 25 : sizeof(float) * (nStopIndex - nStartIndex) );
457 : : }
458 : 25 : break;
459 : : case typelib_TypeClass_DOUBLE:
460 [ + - ]: 69320 : if (nAlloc >= 0)
461 : 69320 : pSeq = reallocSeq( pSeq, sizeof(double), nAlloc );
462 [ + - ]: 69320 : if (pSeq != 0)
463 : : {
464 : : memcpy(
465 : 69320 : pSeq->elements + (sizeof(double) * nStartIndex),
466 : : (char *)pSourceElements + (sizeof(double) * nStartIndex),
467 : 69320 : sizeof(double) * (nStopIndex - nStartIndex) );
468 : : }
469 : 69320 : break;
470 : : case typelib_TypeClass_ENUM:
471 [ + - ]: 1022 : if (nAlloc >= 0)
472 : 1022 : pSeq = reallocSeq( pSeq, sizeof(sal_Int32), nAlloc );
473 [ + - ]: 1022 : if (pSeq != 0)
474 : : {
475 : : memcpy(
476 : 1022 : pSeq->elements + (sizeof(sal_Int32) * nStartIndex),
477 : : (char *)pSourceElements + (sizeof(sal_Int32) * nStartIndex),
478 : 1022 : sizeof(sal_Int32) * (nStopIndex - nStartIndex) );
479 : : }
480 : 1022 : break;
481 : : case typelib_TypeClass_STRING:
482 : : {
483 [ + - ]: 1209319 : if (nAlloc >= 0)
484 : 1209319 : pSeq = reallocSeq( pSeq, sizeof(rtl_uString *), nAlloc );
485 [ + - ]: 1209319 : if (pSeq != 0)
486 : : {
487 : 1209319 : rtl_uString ** pDestElements = (rtl_uString **) pSeq->elements;
488 [ + + ]: 2368968 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
489 : : {
490 : : ::rtl_uString_acquire(
491 : 1159649 : ((rtl_uString **)pSourceElements)[nPos] );
492 : 1159649 : pDestElements[nPos] = ((rtl_uString **)pSourceElements)[nPos];
493 : : }
494 : : }
495 : 1209319 : break;
496 : : }
497 : : case typelib_TypeClass_TYPE:
498 : : {
499 [ + - ]: 982 : if (nAlloc >= 0)
500 : : {
501 : : pSeq = reallocSeq(
502 : 982 : pSeq, sizeof(typelib_TypeDescriptionReference *), nAlloc );
503 : : }
504 [ + - ]: 982 : if (pSeq != 0)
505 : : {
506 : : typelib_TypeDescriptionReference ** pDestElements =
507 : 982 : (typelib_TypeDescriptionReference **) pSeq->elements;
508 [ + + ]: 1135 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
509 : : {
510 : 153 : TYPE_ACQUIRE(
511 : : ((typelib_TypeDescriptionReference **)
512 : : pSourceElements)[nPos] );
513 : 153 : pDestElements[nPos] =
514 : : ((typelib_TypeDescriptionReference **)
515 : 153 : pSourceElements)[nPos];
516 : : }
517 : : }
518 : 982 : break;
519 : : }
520 : : case typelib_TypeClass_ANY:
521 : : {
522 [ + - ]: 177174 : if (nAlloc >= 0)
523 : 177174 : pSeq = reallocSeq( pSeq, sizeof(uno_Any), nAlloc );
524 [ + - ]: 177174 : if (pSeq != 0)
525 : : {
526 : 177174 : uno_Any * pDestElements = (uno_Any *) pSeq->elements;
527 [ + + ]: 684756 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
528 : : {
529 : 507582 : uno_Any * pSource = (uno_Any *)pSourceElements + nPos;
530 : : _copyConstructAny(
531 : : &pDestElements[nPos],
532 : : pSource->pData,
533 : : pSource->pType, 0,
534 : 507582 : acquire, 0 );
535 : : }
536 : : }
537 : 177174 : break;
538 : : }
539 : : case typelib_TypeClass_STRUCT:
540 : : case typelib_TypeClass_EXCEPTION:
541 : : {
542 : 2088111 : typelib_TypeDescription * pElementTypeDescr = 0;
543 [ + - ][ - + ]: 2088111 : TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
[ + - ][ + + ]
[ + - ]
544 : 2088111 : sal_Int32 nElementSize = pElementTypeDescr->nSize;
545 : :
546 [ + - ]: 2088111 : if (nAlloc >= 0)
547 : 2088111 : pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
548 [ + - ]: 2088111 : if (pSeq != 0)
549 : : {
550 : 2088111 : char * pDestElements = pSeq->elements;
551 : :
552 : : typelib_CompoundTypeDescription * pTypeDescr =
553 : 2088111 : (typelib_CompoundTypeDescription *)pElementTypeDescr;
554 [ + + ]: 12168663 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
555 : : {
556 : : char * pDest =
557 : 10080552 : pDestElements + (nElementSize * nPos);
558 : : char * pSource =
559 : 10080552 : (char *)pSourceElements + (nElementSize * nPos);
560 : :
561 [ + + ]: 10080552 : if (pTypeDescr->pBaseTypeDescription)
562 : : {
563 : : // copy base value
564 : : _copyConstructStruct(
565 : : pDest, pSource,
566 [ + - ]: 44321 : pTypeDescr->pBaseTypeDescription, acquire, 0 );
567 : : }
568 : :
569 : : // then copy members
570 : : typelib_TypeDescriptionReference ** ppTypeRefs =
571 : 10080553 : pTypeDescr->ppTypeRefs;
572 : 10080553 : sal_Int32 * pMemberOffsets = pTypeDescr->pMemberOffsets;
573 : 10080553 : sal_Int32 nDescr = pTypeDescr->nMembers;
574 : :
575 [ + + ]: 50042046 : while (nDescr--)
576 : : {
577 : : ::uno_type_copyData(
578 : 79922988 : pDest + pMemberOffsets[nDescr],
579 : 79922988 : pSource + pMemberOffsets[nDescr],
580 : 39961494 : ppTypeRefs[nDescr], acquire );
581 : : }
582 : : }
583 : : }
584 : :
585 [ + - ][ - + ]: 2088111 : TYPELIB_DANGER_RELEASE( pElementTypeDescr );
586 : : break;
587 : : }
588 : : case typelib_TypeClass_UNION:
589 : : {
590 : 0 : typelib_TypeDescription * pElementTypeDescr = 0;
591 [ # # ][ # # ]: 0 : TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
[ # # ][ # # ]
[ # # ]
592 : 0 : sal_Int32 nElementSize = pElementTypeDescr->nSize;
593 : :
594 [ # # ]: 0 : if (nAlloc >= 0)
595 : 0 : pSeq = reallocSeq( pSeq, nElementSize, nAlloc );
596 [ # # ]: 0 : if (pSeq != 0)
597 : : {
598 : 0 : char * pDestElements = pSeq->elements;
599 : :
600 : : sal_Int32 nValueOffset =
601 : : ((typelib_UnionTypeDescription *)
602 : 0 : pElementTypeDescr)->nValueOffset;
603 [ # # ]: 0 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
604 : : {
605 : : char * pDest =
606 : 0 : pDestElements + (nElementSize * nPos);
607 : : char * pSource =
608 : 0 : (char *)pSourceElements + (nElementSize * nPos);
609 : :
610 : : typelib_TypeDescriptionReference * pSetType = _unionGetSetType(
611 : 0 : pSource, pElementTypeDescr );
612 : : ::uno_type_copyData(
613 : 0 : pDest + nValueOffset,
614 : 0 : pSource + nValueOffset,
615 : 0 : pSetType, acquire );
616 : 0 : *(sal_Int64 *)pDest = *(sal_Int64 *)pSource;
617 : 0 : typelib_typedescriptionreference_release( pSetType );
618 : : }
619 : : }
620 : :
621 [ # # ][ # # ]: 0 : TYPELIB_DANGER_RELEASE( pElementTypeDescr );
622 : : break;
623 : : }
624 : : case typelib_TypeClass_SEQUENCE: // sequence of sequence
625 : : {
626 [ + - ]: 83811 : if (nAlloc >= 0)
627 : 83811 : pSeq = reallocSeq( pSeq, sizeof(uno_Sequence *), nAlloc );
628 [ + - ]: 83811 : if (pSeq != 0)
629 : : {
630 : 83811 : typelib_TypeDescription * pElementTypeDescr = 0;
631 [ + - ][ - + ]: 83811 : TYPELIB_DANGER_GET( &pElementTypeDescr, pElementType );
[ + - ][ - + ]
[ # # ]
632 : : typelib_TypeDescriptionReference * pSeqElementType =
633 : 83811 : ((typelib_IndirectTypeDescription *) pElementTypeDescr)->pType;
634 : 83811 : uno_Sequence ** pDestElements = (uno_Sequence **) pSeq->elements;
635 [ + + ]: 106932 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
636 : : {
637 : : uno_Sequence * pNew = icopyConstructSequence(
638 : 23121 : ((uno_Sequence **) pSourceElements)[nPos],
639 [ + - ]: 23121 : pSeqElementType, acquire, 0 );
640 : : OSL_ASSERT( pNew != 0 );
641 : : // ought never be a memory allocation problem,
642 : : // because of reference counted sequence handles
643 : 23121 : pDestElements[ nPos ] = pNew;
644 : : }
645 [ + - ][ - + ]: 83811 : TYPELIB_DANGER_RELEASE( pElementTypeDescr );
646 : : }
647 : 83811 : break;
648 : : }
649 : : case typelib_TypeClass_INTERFACE:
650 : : {
651 [ + - ]: 716226 : if (nAlloc >= 0)
652 : 716226 : pSeq = reallocSeq( pSeq, sizeof(void *), nAlloc );
653 [ + - ]: 716226 : if (pSeq != 0)
654 : : {
655 : 716226 : void ** pDestElements = (void **) pSeq->elements;
656 [ + + ]: 1273506 : for ( sal_Int32 nPos = nStartIndex; nPos < nStopIndex; ++nPos )
657 : : {
658 : 1114560 : _acquire( pDestElements[nPos] =
659 : 557280 : ((void **)pSourceElements)[nPos], acquire );
660 : : }
661 : : }
662 : 716226 : break;
663 : : }
664 : : default:
665 : : OSL_FAIL( "### unexpected element type!" );
666 : 0 : pSeq = 0;
667 : 0 : break;
668 : : }
669 : :
670 [ - + ]: 6152703 : if (pSeq == 0)
671 : : {
672 : : OSL_ASSERT( nAlloc >= 0 ); // must have been an allocation failure
673 : 0 : return false;
674 : : }
675 : : else
676 : : {
677 : 6152703 : *ppSeq = pSeq;
678 : 6152703 : return true;
679 : : }
680 : : }
681 : :
682 : : //------------------------------------------------------------------------------
683 : 4820800 : static inline bool ireallocSequence(
684 : : uno_Sequence ** ppSequence,
685 : : typelib_TypeDescriptionReference * pElementType,
686 : : sal_Int32 nSize,
687 : : uno_AcquireFunc acquire, uno_ReleaseFunc release )
688 : : {
689 : 4820800 : bool ret = true;
690 : 4820800 : uno_Sequence * pSeq = *ppSequence;
691 : 4820800 : sal_Int32 nElements = pSeq->nElements;
692 : :
693 [ + + ][ + + ]: 4820800 : if (pSeq->nRefCount > 1 ||
[ + + ][ - + ]
694 : : // not mem-copyable elements?
695 : : typelib_TypeClass_ANY == pElementType->eTypeClass ||
696 : : typelib_TypeClass_STRUCT == pElementType->eTypeClass ||
697 : : typelib_TypeClass_EXCEPTION == pElementType->eTypeClass)
698 : : {
699 : : // split sequence and construct new one from scratch
700 : 3511578 : uno_Sequence * pNew = 0;
701 : :
702 : 3511578 : sal_Int32 nRest = nSize - nElements;
703 [ + + ]: 3511578 : sal_Int32 nCopy = (nRest > 0 ? nElements : nSize);
704 : :
705 [ + - ]: 3511578 : if (nCopy >= 0)
706 : : {
707 : : ret = icopyConstructFromElements(
708 : : &pNew, pSeq->elements, pElementType,
709 : : 0, nCopy, acquire,
710 [ + - ]: 3511578 : nSize ); // alloc to nSize
711 : : }
712 [ + - ][ + + ]: 3511578 : if (ret && nRest > 0)
713 : : {
714 : : ret = idefaultConstructElements(
715 : : &pNew, pElementType,
716 : : nCopy, nSize,
717 [ - + ][ + - ]: 3456732 : nCopy >= 0 ? -1 /* no mem allocation */ : nSize );
718 : : }
719 : :
720 [ + - ]: 3511577 : if (ret)
721 : : {
722 : : // destruct sequence
723 [ + - ][ + + ]: 3511577 : if (osl_decrementInterlockedCount( &pSeq->nRefCount ) == 0)
724 : : {
725 [ + + ]: 1125766 : if (nElements > 0)
726 : : {
727 : : idestructElements(
728 : : pSeq->elements, pElementType,
729 [ + - ]: 1125073 : 0, nElements, release );
730 : : }
731 : 1125766 : rtl_freeMemory( pSeq );
732 : : }
733 : 3511578 : *ppSequence = pNew;
734 : 3511578 : }
735 : : }
736 : : else
737 : : {
738 : : OSL_ASSERT( pSeq->nRefCount == 1 );
739 [ + + ]: 1309222 : if (nSize > nElements) // default construct the rest
740 : : {
741 : : ret = idefaultConstructElements(
742 : : ppSequence, pElementType,
743 : : nElements, nSize,
744 : 1087422 : nSize ); // realloc to nSize
745 : : }
746 : : else // or destruct the rest and realloc mem
747 : : {
748 : : sal_Int32 nElementSize = idestructElements(
749 : : pSeq->elements, pElementType,
750 : 221800 : nSize, nElements, release );
751 : : // warning: it is assumed that the following will never fail,
752 : : // else this leads to a sequence null handle
753 : 221800 : *ppSequence = reallocSeq( pSeq, nElementSize, nSize );
754 : : OSL_ASSERT( *ppSequence != 0 );
755 : 221800 : ret = (*ppSequence != 0);
756 : : }
757 : : }
758 : :
759 : 4820800 : return ret;
760 : : }
761 : :
762 : : }
763 : :
764 : : extern "C"
765 : : {
766 : :
767 : : //##############################################################################
768 : 20051428 : sal_Bool SAL_CALL uno_type_sequence_construct(
769 : : uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType,
770 : : void * pElements, sal_Int32 len,
771 : : uno_AcquireFunc acquire )
772 : : SAL_THROW_EXTERN_C()
773 : : {
774 : : bool ret;
775 [ + + ]: 20051428 : if (len)
776 : : {
777 : 6900449 : typelib_TypeDescription * pTypeDescr = 0;
778 [ + ][ - + ]: 6900449 : TYPELIB_DANGER_GET( &pTypeDescr, pType );
[ + - ][ - + ]
[ # # ]
779 : :
780 : : typelib_TypeDescriptionReference * pElementType =
781 : 6900450 : ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
782 : :
783 : 6900450 : *ppSequence = 0;
784 [ + + ]: 6900450 : if (pElements == 0)
785 : : {
786 : : ret = idefaultConstructElements(
787 : : ppSequence, pElementType,
788 : : 0, len,
789 [ + - ]: 5828122 : len ); // alloc to len
790 : : }
791 : : else
792 : : {
793 : : ret = icopyConstructFromElements(
794 : : ppSequence, pElements, pElementType,
795 : : 0, len, acquire,
796 [ + - ]: 1072328 : len ); // alloc to len
797 : : }
798 : :
799 [ + ][ + + ]: 6900453 : TYPELIB_DANGER_RELEASE( pTypeDescr );
800 : : }
801 : : else
802 : : {
803 : 13150979 : *ppSequence = createEmptySequence();
804 : 13150994 : ret = true;
805 : : }
806 : :
807 : : OSL_ASSERT( (*ppSequence != 0) == ret );
808 : 20051437 : return ret;
809 : : }
810 : :
811 : : //##############################################################################
812 : 21173 : sal_Bool SAL_CALL uno_sequence_construct(
813 : : uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr,
814 : : void * pElements, sal_Int32 len,
815 : : uno_AcquireFunc acquire )
816 : : SAL_THROW_EXTERN_C()
817 : : {
818 : : bool ret;
819 [ + + ]: 21173 : if (len > 0)
820 : : {
821 : : typelib_TypeDescriptionReference * pElementType =
822 : 6463 : ((typelib_IndirectTypeDescription *)pTypeDescr)->pType;
823 : :
824 : 6463 : *ppSequence = 0;
825 [ + - ]: 6463 : if (pElements == 0)
826 : : {
827 : : ret = idefaultConstructElements(
828 : : ppSequence, pElementType,
829 : : 0, len,
830 : 6463 : len ); // alloc to len
831 : : }
832 : : else
833 : : {
834 : : ret = icopyConstructFromElements(
835 : : ppSequence, pElements, pElementType,
836 : : 0, len, acquire,
837 : 0 : len ); // alloc to len
838 : : }
839 : : }
840 : : else
841 : : {
842 : 14710 : *ppSequence = createEmptySequence();
843 : 14710 : ret = true;
844 : : }
845 : :
846 : : OSL_ASSERT( (*ppSequence != 0) == ret );
847 : 21173 : return ret;
848 : : }
849 : :
850 : : //##############################################################################
851 : 5518116 : sal_Bool SAL_CALL uno_type_sequence_realloc(
852 : : uno_Sequence ** ppSequence, typelib_TypeDescriptionReference * pType,
853 : : sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release )
854 : : SAL_THROW_EXTERN_C()
855 : : {
856 : : OSL_ENSURE( ppSequence, "### null ptr!" );
857 : : OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
858 : :
859 : 5518116 : bool ret = true;
860 [ + + ]: 5518116 : if (nSize != (*ppSequence)->nElements)
861 : : {
862 : 4820738 : typelib_TypeDescription * pTypeDescr = 0;
863 [ + - ][ + ]: 4820738 : TYPELIB_DANGER_GET( &pTypeDescr, pType );
[ + + ][ - + ]
[ # # ]
864 : : ret = ireallocSequence(
865 : : ppSequence, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
866 [ + - ]: 4820738 : nSize, acquire, release );
867 [ + - ][ - + ]: 4820740 : TYPELIB_DANGER_RELEASE( pTypeDescr );
868 : : }
869 : 5518118 : return ret;
870 : : }
871 : :
872 : : //##############################################################################
873 : 70 : sal_Bool SAL_CALL uno_sequence_realloc(
874 : : uno_Sequence ** ppSequence, typelib_TypeDescription * pTypeDescr,
875 : : sal_Int32 nSize, uno_AcquireFunc acquire, uno_ReleaseFunc release )
876 : : SAL_THROW_EXTERN_C()
877 : : {
878 : : OSL_ENSURE( ppSequence, "### null ptr!" );
879 : : OSL_ENSURE( nSize >= 0, "### new size must be at least 0!" );
880 : :
881 : 70 : bool ret = true;
882 [ + + ]: 70 : if (nSize != (*ppSequence)->nElements)
883 : : {
884 : : ret = ireallocSequence(
885 : : ppSequence, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
886 : 60 : nSize, acquire, release );
887 : : }
888 : 70 : return ret;
889 : : }
890 : :
891 : : //##############################################################################
892 : 57222525 : sal_Bool SAL_CALL uno_type_sequence_reference2One(
893 : : uno_Sequence ** ppSequence,
894 : : typelib_TypeDescriptionReference * pType,
895 : : uno_AcquireFunc acquire, uno_ReleaseFunc release )
896 : : SAL_THROW_EXTERN_C()
897 : : {
898 : : OSL_ENSURE( ppSequence, "### null ptr!" );
899 : 57222525 : bool ret = true;
900 : 57222525 : uno_Sequence * pSequence = *ppSequence;
901 [ + + ]: 57222525 : if (pSequence->nRefCount > 1)
902 : : {
903 : 1799133 : uno_Sequence * pNew = 0;
904 [ + + ]: 1799133 : if (pSequence->nElements > 0)
905 : : {
906 : 1568797 : typelib_TypeDescription * pTypeDescr = 0;
907 [ + - ][ - + ]: 1568797 : TYPELIB_DANGER_GET( &pTypeDescr, pType );
[ + - ][ - + ]
[ # # ]
908 : :
909 : : ret = icopyConstructFromElements(
910 : : &pNew, pSequence->elements,
911 : : ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
912 : : 0, pSequence->nElements, acquire,
913 [ + - ]: 1568797 : pSequence->nElements ); // alloc nElements
914 [ + - ]: 1568797 : if (ret)
915 : : {
916 [ + - ]: 1568797 : idestructSequence( *ppSequence, pType, pTypeDescr, release );
917 : 1568797 : *ppSequence = pNew;
918 : : }
919 : :
920 [ + - ][ - + ]: 1568797 : TYPELIB_DANGER_RELEASE( pTypeDescr );
921 : : }
922 : : else
923 : : {
924 : 230336 : pNew = allocSeq( 0, 0 );
925 : 230336 : ret = (pNew != 0);
926 [ + - ]: 230336 : if (ret)
927 : : {
928 : : // easy destruction of empty sequence:
929 [ + - ][ - + ]: 230336 : if (osl_decrementInterlockedCount( &pSequence->nRefCount ) == 0)
930 : 0 : rtl_freeMemory( pSequence );
931 : 1799133 : *ppSequence = pNew;
932 : : }
933 : : }
934 : : }
935 : 57222525 : return ret;
936 : : }
937 : :
938 : : //##############################################################################
939 : 60 : sal_Bool SAL_CALL uno_sequence_reference2One(
940 : : uno_Sequence ** ppSequence,
941 : : typelib_TypeDescription * pTypeDescr,
942 : : uno_AcquireFunc acquire, uno_ReleaseFunc release )
943 : : SAL_THROW_EXTERN_C()
944 : : {
945 : : OSL_ENSURE( ppSequence, "### null ptr!" );
946 : 60 : bool ret = true;
947 : 60 : uno_Sequence * pSequence = *ppSequence;
948 [ - + ]: 60 : if (pSequence->nRefCount > 1)
949 : : {
950 : 0 : uno_Sequence * pNew = 0;
951 [ # # ]: 0 : if (pSequence->nElements > 0)
952 : : {
953 : : ret = icopyConstructFromElements(
954 : : &pNew, pSequence->elements,
955 : : ((typelib_IndirectTypeDescription *)pTypeDescr)->pType,
956 : : 0, pSequence->nElements, acquire,
957 [ # # ]: 0 : pSequence->nElements ); // alloc nElements
958 [ # # ]: 0 : if (ret)
959 : : {
960 : : idestructSequence(
961 [ # # ]: 0 : pSequence, pTypeDescr->pWeakRef, pTypeDescr, release );
962 : 0 : *ppSequence = pNew;
963 : : }
964 : : }
965 : : else
966 : : {
967 : 0 : pNew = allocSeq( 0, 0 );
968 : 0 : ret = (pNew != 0);
969 [ # # ]: 0 : if (ret)
970 : : {
971 : : // easy destruction of empty sequence:
972 [ # # ][ # # ]: 0 : if (osl_decrementInterlockedCount( &pSequence->nRefCount ) == 0)
973 : 0 : rtl_freeMemory( pSequence );
974 : 0 : *ppSequence = pNew;
975 : : }
976 : : }
977 : :
978 : : }
979 : 60 : return ret;
980 : : }
981 : :
982 : : //##############################################################################
983 : 0 : void SAL_CALL uno_sequence_assign(
984 : : uno_Sequence ** ppDest,
985 : : uno_Sequence * pSource,
986 : : typelib_TypeDescription * pTypeDescr,
987 : : uno_ReleaseFunc release )
988 : : SAL_THROW_EXTERN_C()
989 : : {
990 [ # # ]: 0 : if (*ppDest != pSource)
991 : : {
992 : 0 : ::osl_incrementInterlockedCount( &pSource->nRefCount );
993 : 0 : idestructSequence( *ppDest, pTypeDescr->pWeakRef, pTypeDescr, release );
994 : 0 : *ppDest = pSource;
995 : : }
996 : 0 : }
997 : :
998 : : //##############################################################################
999 : 3109339 : void SAL_CALL uno_type_sequence_assign(
1000 : : uno_Sequence ** ppDest,
1001 : : uno_Sequence * pSource,
1002 : : typelib_TypeDescriptionReference * pType,
1003 : : uno_ReleaseFunc release )
1004 : : SAL_THROW_EXTERN_C()
1005 : : {
1006 [ + + ]: 3109339 : if (*ppDest != pSource)
1007 : : {
1008 : 2879426 : ::osl_incrementInterlockedCount( &pSource->nRefCount );
1009 : 2879426 : idestructSequence( *ppDest, pType, 0, release );
1010 : 2879426 : *ppDest = pSource;
1011 : : }
1012 : 3109339 : }
1013 : :
1014 : : }
1015 : :
1016 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|