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 <cassert>
21 : #include <vector>
22 : // compiled via include from itemset.cxx only!
23 : #include <boost/scoped_array.hpp>
24 :
25 : #ifdef DBG_UTIL
26 :
27 : #define DBG_CHECK_RANGES(sal_uInt16, pArr) \
28 : for ( const sal_uInt16 *pRange = pArr; *pRange; pRange += 2 ) \
29 : { \
30 : DBG_ASSERT( pRange[0] <= pRange[1], "ranges must be sorted" ); \
31 : DBG_ASSERT( !pRange[2] || ( pRange[2] - pRange[1] ) > 1, \
32 : "ranges must be sorted and discrete" ); \
33 : }
34 :
35 : #else
36 :
37 : #define DBG_CHECK_RANGES(sal_uInt16,pArr)
38 :
39 : #endif
40 :
41 0 : inline void Swap_Impl(const sal_uInt16 *& rp1, const sal_uInt16 *& rp2)
42 : {
43 0 : const sal_uInt16 * pTemp = rp1;
44 0 : rp1 = rp2;
45 0 : rp2 = pTemp;
46 0 : }
47 :
48 :
49 0 : sal_uInt16 InitializeRanges_Impl( sal_uInt16 *&rpRanges, va_list pArgs,
50 : sal_uInt16 nWh1, sal_uInt16 nWh2, sal_uInt16 nNull )
51 :
52 : /** <H3>Description</H3>
53 :
54 : Creates an sal_uInt16-ranges-array in 'rpRanges' using 'nWh1' and 'nWh2' as
55 : first range, 'nNull' as terminator or start of 2nd range and 'pArgs' as
56 : remaider.
57 :
58 : It returns the number of sal_uInt16s which are contained in the described
59 : set of sal_uInt16s.
60 : */
61 :
62 : {
63 0 : sal_uInt16 nSize = 0, nIns = 0;
64 0 : std::vector<sal_uInt16> aNumArr;
65 0 : aNumArr.push_back( nWh1 );
66 0 : aNumArr.push_back( nWh2 );
67 : DBG_ASSERT( nWh1 <= nWh2, "Ungueltiger Bereich" );
68 0 : nSize += nWh2 - nWh1 + 1;
69 0 : aNumArr.push_back( nNull );
70 0 : bool bEndOfRange = false;
71 0 : while ( 0 !=
72 : ( nIns =
73 : sal::static_int_cast< sal_uInt16 >(
74 0 : va_arg( pArgs, int ) ) ) )
75 : {
76 0 : bEndOfRange = !bEndOfRange;
77 0 : if ( bEndOfRange )
78 : {
79 0 : const sal_uInt16 nPrev(*aNumArr.rbegin());
80 : DBG_ASSERT( nPrev <= nIns, "Ungueltiger Bereich" );
81 0 : nSize += nIns - nPrev + 1;
82 : }
83 0 : aNumArr.push_back( nIns );
84 : }
85 :
86 : assert( bEndOfRange ); // odd number of Which-IDs
87 :
88 : // so, jetzt sind alle Bereiche vorhanden und
89 0 : rpRanges = new sal_uInt16[ aNumArr.size() + 1 ];
90 0 : std::copy( aNumArr.begin(), aNumArr.end(), rpRanges);
91 0 : *(rpRanges + aNumArr.size()) = 0;
92 :
93 0 : return nSize;
94 : }
95 :
96 :
97 0 : sal_uInt16 Count_Impl( const sal_uInt16 *pRanges )
98 :
99 : /** <H3>Description</H3>
100 :
101 : Determines the number of sal_uInt16s in an 0-terminated array of pairs of
102 : sal_uInt16s. The terminating 0 is not included in the count.
103 : */
104 :
105 : {
106 0 : sal_uInt16 nCount = 0;
107 0 : while ( *pRanges )
108 : {
109 0 : nCount += 2;
110 0 : pRanges += 2;
111 : }
112 0 : return nCount;
113 : }
114 :
115 :
116 0 : sal_uInt16 Capacity_Impl( const sal_uInt16 *pRanges )
117 :
118 : /** <H3>Description</H3>
119 :
120 : Determines the total number of sal_uInt16s described in an 0-terminated
121 : array of pairs of sal_uInt16s, each representing an range of sal_uInt16s.
122 : */
123 :
124 : {
125 0 : sal_uInt16 nCount = 0;
126 :
127 0 : if ( pRanges )
128 : {
129 0 : while ( *pRanges )
130 : {
131 0 : nCount += pRanges[1] - pRanges[0] + 1;
132 0 : pRanges += 2;
133 : }
134 : }
135 0 : return nCount;
136 : }
137 :
138 :
139 0 : SfxUShortRanges::SfxUShortRanges( const SfxUShortRanges &rOrig )
140 :
141 : /** <H3>Description</H3>
142 :
143 : Copy-Ctor.
144 : */
145 :
146 : {
147 0 : if ( rOrig._pRanges )
148 : {
149 0 : sal_uInt16 nCount = Count_Impl( rOrig._pRanges ) + 1;
150 0 : _pRanges = new sal_uInt16[nCount];
151 0 : memcpy( _pRanges, rOrig._pRanges, sizeof(sal_uInt16) * nCount );
152 : }
153 : else
154 0 : _pRanges = 0;
155 0 : }
156 :
157 :
158 0 : SfxUShortRanges::SfxUShortRanges( sal_uInt16 nWhich1, sal_uInt16 nWhich2 )
159 :
160 : /** <H3>Description</H3>
161 :
162 : Constructs an SfxUShortRanges-instance from one range of sal_uInt16s.
163 :
164 : precondition:
165 : nWhich1 <= nWhich2
166 : */
167 :
168 0 : : _pRanges( new sal_uInt16[3] )
169 : {
170 0 : _pRanges[0] = nWhich1;
171 0 : _pRanges[1] = nWhich2;
172 0 : _pRanges[2] = 0;
173 0 : }
174 :
175 :
176 0 : SfxUShortRanges::SfxUShortRanges( const sal_uInt16* pArr )
177 :
178 : /** <H3>Description</H3>
179 :
180 : Constcurts an SfxUShortRanges-instance from an sorted ranges of sal_uInt16s,
181 : terminates with on 0.
182 :
183 : precondition: for each n >= 0 && n < (sizeof(pArr)-1)
184 : pArr[2n] <= pArr[2n+1] && ( pArr[2n+2]-pArr[2n+1] ) > 1
185 : */
186 :
187 : {
188 : DBG_CHECK_RANGES(sal_uInt16, pArr);
189 0 : sal_uInt16 nCount = Count_Impl(pArr) + 1;
190 0 : _pRanges = new sal_uInt16[ nCount ];
191 0 : memcpy( _pRanges, pArr, sizeof(sal_uInt16) * nCount );
192 0 : }
193 :
194 :
195 0 : bool SfxUShortRanges::operator==( const SfxUShortRanges &rOther ) const
196 : {
197 : // Object pointers equal?
198 0 : if ( this == &rOther )
199 0 : return true;
200 :
201 : // Ranges pointers equal?
202 0 : if ( _pRanges == rOther._pRanges )
203 0 : return true;
204 :
205 : // Counts equal?
206 0 : sal_uInt16 nCount = Count();
207 0 : if ( nCount != rOther.Count() )
208 0 : return false;
209 :
210 : // Check arrays.
211 0 : sal_uInt16 n = 0;
212 0 : while( _pRanges[ n ] != 0 )
213 : {
214 : // Elements at current position equal?
215 0 : if ( _pRanges[ n ] != rOther._pRanges[ n ] )
216 0 : return false;
217 :
218 0 : ++n;
219 : }
220 :
221 0 : return true;
222 : }
223 :
224 :
225 0 : SfxUShortRanges& SfxUShortRanges::operator =
226 : (
227 : const SfxUShortRanges &rRanges
228 : )
229 :
230 : /** <H3>Description</H3>
231 :
232 : Assigns ranges from 'rRanges' to '*this'.
233 : */
234 :
235 : {
236 : // special case: assign itself
237 0 : if ( &rRanges == this )
238 0 : return *this;
239 :
240 0 : delete[] _pRanges;
241 :
242 : // special case: 'rRanges' is empty
243 0 : if ( rRanges.IsEmpty() )
244 0 : _pRanges = 0;
245 : else
246 : {
247 : // copy ranges
248 0 : sal_uInt16 nCount = Count_Impl( rRanges._pRanges ) + 1;
249 0 : _pRanges = new sal_uInt16[ nCount ];
250 0 : memcpy( _pRanges, rRanges._pRanges, sizeof(sal_uInt16) * nCount );
251 : }
252 0 : return *this;
253 : }
254 :
255 :
256 0 : SfxUShortRanges& SfxUShortRanges::operator +=
257 : (
258 : const SfxUShortRanges &rRanges
259 : )
260 :
261 : /** <H3>Description</H3>
262 :
263 : Merges *this with 'rRanges'.
264 :
265 : for each sal_uInt16 n:
266 : this->Contains( n ) || rRanges.Contains( n ) => this'->Contains( n )
267 : !this->Contains( n ) && !rRanges.Contains( n ) => !this'->Contains( n )
268 : */
269 :
270 : {
271 : // special cases: one is empty
272 0 : if ( rRanges.IsEmpty() )
273 0 : return *this;
274 0 : if ( IsEmpty() )
275 0 : return *this = rRanges;
276 :
277 : // First, run thru _pRanges and rRanges._pRanges and determine the size of
278 : // the new, merged ranges:
279 0 : sal_uInt16 nCount = 0;
280 0 : const sal_uInt16 * pRA = _pRanges;
281 0 : const sal_uInt16 * pRB = rRanges._pRanges;
282 :
283 : for (;;)
284 : {
285 : // The first pair of pRA has a lower lower bound than the first pair
286 : // of pRB:
287 0 : if (pRA[0] > pRB[0])
288 0 : Swap_Impl(pRA, pRB);
289 :
290 : // We are done with the merging if at least pRA is exhausted:
291 0 : if (!pRA[0])
292 0 : break;
293 :
294 : for (;;)
295 : {
296 : // Skip those pairs in pRB that completely lie in the first pair
297 : // of pRA:
298 0 : while (pRB[1] <= pRA[1])
299 : {
300 0 : pRB += 2;
301 :
302 : // Watch out for exhaustion of pRB:
303 0 : if (!pRB[0])
304 : {
305 0 : Swap_Impl(pRA, pRB);
306 0 : goto count_rest;
307 : }
308 : }
309 :
310 : // If the next pair of pRA does not at least touch the current new
311 : // pair, we are done with the current new pair:
312 0 : if (pRB[0] > pRA[1] + 1)
313 0 : break;
314 :
315 : // The next pair of pRB extends the current new pair; first,
316 : // extend the current new pair (we are done if pRB is then
317 : // exhausted); second, switch the roles of pRA and pRB in order to
318 : // merge in those following pairs of the original pRA that will
319 : // lie in the (now larger) current new pair or will even extend it
320 : // further:
321 0 : pRA += 2;
322 0 : if (!pRA[0])
323 0 : goto count_rest;
324 0 : Swap_Impl(pRA, pRB);
325 : }
326 :
327 : // Done with the current new pair:
328 0 : pRA += 2;
329 0 : nCount += 2;
330 : }
331 :
332 : // Only pRB has more pairs available, pRA is already exhausted:
333 : count_rest:
334 0 : for (; pRB[0]; pRB += 2)
335 0 : nCount += 2;
336 :
337 : // Now, create new ranges of the correct size and, on a second run thru
338 : // _pRanges and rRanges._pRanges, copy the merged pairs into the new
339 : // ranges:
340 0 : sal_uInt16 * pNew = new sal_uInt16[nCount + 1];
341 0 : pRA = _pRanges;
342 0 : pRB = rRanges._pRanges;
343 0 : sal_uInt16 * pRN = pNew;
344 :
345 : for (;;)
346 : {
347 : // The first pair of pRA has a lower lower bound than the first pair
348 : // of pRB:
349 0 : if (pRA[0] > pRB[0])
350 0 : Swap_Impl(pRA, pRB);
351 :
352 : // We are done with the merging if at least pRA is exhausted:
353 0 : if (!pRA[0])
354 0 : break;
355 :
356 : // Lower bound of current new pair is already known:
357 0 : *pRN++ = pRA[0];
358 :
359 : for (;;)
360 : {
361 : // Skip those pairs in pRB that completely lie in the first pair
362 : // of pRA:
363 0 : while (pRB[1] <= pRA[1])
364 : {
365 0 : pRB += 2;
366 :
367 : // Watch out for exhaustion of pRB:
368 0 : if (!pRB[0])
369 : {
370 0 : Swap_Impl(pRA, pRB);
371 0 : ++pRB;
372 0 : goto copy_rest;
373 : }
374 : }
375 :
376 : // If the next pair of pRA does not at least touch the current new
377 : // pair, we are done with the current new pair:
378 0 : if (pRB[0] > pRA[1] + 1)
379 0 : break;
380 :
381 : // The next pair of pRB extends the current new pair; first,
382 : // extend the current new pair (we are done if pRB is then
383 : // exhausted); second, switch the roles of pRA and pRB in order to
384 : // merge in those following pairs of the original pRA that will
385 : // lie in the (now larger) current new pair or will even extend it
386 : // further:
387 0 : pRA += 2;
388 0 : if (!pRA[0])
389 : {
390 0 : ++pRB;
391 0 : goto copy_rest;
392 : }
393 0 : Swap_Impl(pRA, pRB);
394 : }
395 :
396 : // Done with the current new pair, now upper bound is also known:
397 0 : *pRN++ = pRA[1];
398 0 : pRA += 2;
399 : }
400 :
401 : // Only pRB has more pairs available (which are copied to the new ranges
402 : // unchanged), pRA is already exhausted:
403 : copy_rest:
404 0 : for (; *pRB;)
405 0 : *pRN++ = *pRB++;
406 0 : *pRN = 0;
407 :
408 0 : delete[] _pRanges;
409 0 : _pRanges = pNew;
410 :
411 0 : return *this;
412 : }
413 :
414 :
415 0 : SfxUShortRanges& SfxUShortRanges::operator -=
416 : (
417 : const SfxUShortRanges &rRanges
418 : )
419 :
420 : /** <H3>Description</H3>
421 :
422 : Removes 'rRanges' from '*this'.
423 :
424 : for each sal_uInt16 n:
425 : this->Contains( n ) && rRanges.Contains( n ) => !this'->Contains( n )
426 : this->Contains( n ) && !rRanges.Contains( n ) => this'->Contains( n )
427 : !this->Contains( n ) => !this'->Contains( n )
428 : */
429 :
430 : {
431 : // special cases: one is empty
432 0 : if ( rRanges.IsEmpty() || IsEmpty() )
433 0 : return *this;
434 :
435 : // differentiate 'rRanges' in a temporary copy of '*this'
436 : // (size is computed for maximal possibly split-count plus terminating 0)
437 0 : sal_uInt16 nThisSize = Count_Impl(_pRanges);
438 0 : sal_uInt16 nTargetSize = 1 + ( nThisSize + Count_Impl(rRanges._pRanges) );
439 0 : boost::scoped_array<sal_uInt16> pTarget(new sal_uInt16[ nTargetSize ]);
440 0 : memset( pTarget.get(), 0, sizeof(sal_uInt16)*nTargetSize );
441 0 : memcpy( pTarget.get(), _pRanges, sizeof(sal_uInt16)*nThisSize );
442 :
443 0 : sal_uInt16 nPos1 = 0, nPos2 = 0, nTargetPos = 0;
444 0 : while( _pRanges[ nPos1 ] )
445 : {
446 0 : sal_uInt16 l1 = _pRanges[ nPos1 ]; // lower bound of interval 1
447 0 : sal_uInt16 u1 = _pRanges[ nPos1+1 ]; // upper bound of interval 1
448 0 : sal_uInt16 l2 = rRanges._pRanges[ nPos2 ]; // lower bound of interval 2
449 0 : sal_uInt16 u2 = rRanges._pRanges[ nPos2+1 ]; // upper bound of interval 2
450 :
451 : // boundary cases
452 : // * subtrahend is empty -> copy the minuend
453 0 : if( !l2 )
454 : {
455 0 : pTarget[ nTargetPos ] = l1;
456 0 : pTarget[ nTargetPos+1 ] = u1;
457 0 : nTargetPos += 2;
458 0 : nPos1 += 2;
459 0 : continue;
460 : }
461 : // * next subtrahend interval is completely higher -> copy the minuend
462 0 : if( u1 < l2 )
463 : {
464 0 : pTarget[ nTargetPos ] = l1;
465 0 : pTarget[ nTargetPos+1 ] = u1;
466 0 : nTargetPos += 2;
467 0 : nPos1 += 2;
468 0 : continue;
469 : }
470 :
471 : // * next subtrahend interval is completely lower -> try next
472 0 : if( u2 < l1 )
473 : {
474 0 : nPos2 += 2;
475 0 : continue;
476 : }
477 :
478 : // intersecting cases
479 : // * subtrahend cuts out from the beginning of the minuend
480 0 : if( l2 <= l1 && u2 <= u1 )
481 : {
482 : // reduce minuend interval, try again (minuend might be affected by other subtrahend intervals)
483 0 : _pRanges[ nPos1 ] = u2 + 1;
484 0 : nPos2 += 2; // this cannot hurt any longer
485 0 : continue;
486 : }
487 :
488 : // * subtrahend cuts out from the end of the minuend
489 0 : if( l1 <= l2 && u1 <= u2 )
490 : {
491 : // copy remaining part of minuend (cannot be affected by other intervals)
492 0 : if( l1 < l2 ) // anything left at all?
493 : {
494 0 : pTarget[ nTargetPos ] = l1;
495 0 : pTarget[ nTargetPos+1 ] = l2 - 1;
496 0 : nTargetPos += 2;
497 : // do not increment nPos2, might affect next minuend interval, too
498 : }
499 0 : nPos1 += 2; // nothing left at all
500 0 : continue;
501 : }
502 :
503 : // * subtrahend completely deletes minuend (larger or same at both ends)
504 0 : if( l1 >= l2 && u1 <= u2 )
505 : {
506 0 : nPos1 += 2; // minuend deleted
507 : // do not increment nPos2, might affect next minuend interval, too
508 0 : continue;
509 : }
510 :
511 : // * subtrahend divides minuend into two pieces
512 0 : if( l1 <= l2 && u1 >= u2 ) // >= and <= since they may be something left only at one side
513 : {
514 : // left side
515 0 : if( l1 < l2 ) // anything left at all
516 : {
517 0 : pTarget[ nTargetPos ] = l1;
518 0 : pTarget[ nTargetPos+1 ] = l2 - 1;
519 0 : nTargetPos += 2;
520 : }
521 :
522 : // right side
523 0 : if( u1 > u2 ) // anything left at all
524 : {
525 : // reduce minuend interval, try again (minuend might be affected by other subtrahend itnervals )
526 0 : _pRanges[ nPos1 ] = u2 + 1;
527 : }
528 :
529 : // subtrahend is completely used
530 0 : nPos2 += 2;
531 0 : continue;
532 : }
533 :
534 : // we should never be here
535 : OSL_FAIL( "SfxUShortRanges::operator-=: internal error" );
536 : } // while
537 :
538 0 : pTarget[ nTargetPos ] = 0;
539 :
540 : // assign the differentiated ranges
541 0 : delete[] _pRanges;
542 :
543 0 : sal_uInt16 nUShorts = Count_Impl(pTarget.get()) + 1;
544 0 : if ( 1 != nUShorts )
545 : {
546 0 : _pRanges = new sal_uInt16[ nUShorts ];
547 0 : memcpy( _pRanges, pTarget.get(), nUShorts * sizeof(sal_uInt16) );
548 : }
549 : else
550 0 : _pRanges = 0;
551 :
552 0 : return *this;
553 : }
554 :
555 :
556 0 : SfxUShortRanges& SfxUShortRanges::operator /=
557 : (
558 : const SfxUShortRanges &rRanges
559 : )
560 :
561 : /** <H3>Description</H3>
562 :
563 : Determines intersection of '*this' with 'rRanges'.
564 :
565 : for each sal_uInt16 n:
566 : this->Contains( n ) && rRanges.Contains( n ) => this'->Contains( n )
567 : !this->Contains( n ) => !this'->Contains( n )
568 : !rRanges.Contains( n ) => !this'->Contains( n )
569 : */
570 :
571 : {
572 : // boundary cases
573 : // * first set is empty -> nothing to be done
574 : // * second set is empty -> delete first set
575 0 : if( rRanges.IsEmpty() )
576 : {
577 0 : delete[] _pRanges;
578 :
579 0 : _pRanges = new sal_uInt16[1];
580 0 : _pRanges[0] = 0;
581 :
582 0 : return *this;
583 : }
584 :
585 : // intersect 'rRanges' in a temporary copy of '*this'
586 : // (size is computed for maximal possibly split-count plus terminating 0)
587 0 : sal_uInt16 nThisSize = Count_Impl(_pRanges);
588 0 : sal_uInt16 nTargetSize = 1 + ( nThisSize + Count_Impl(rRanges._pRanges) );
589 0 : boost::scoped_array<sal_uInt16> pTarget(new sal_uInt16[ nTargetSize ]);
590 0 : memset( pTarget.get(), 0, sizeof(sal_uInt16)*nTargetSize );
591 0 : memcpy( pTarget.get(), _pRanges, sizeof(sal_uInt16)*nThisSize );
592 :
593 0 : sal_uInt16 nPos1 = 0, nPos2 = 0, nTargetPos = 0;
594 0 : while( _pRanges[ nPos1 ] != 0 && rRanges._pRanges[ nPos2 ] != 0 )
595 : {
596 0 : sal_uInt16 l1 = _pRanges[ nPos1 ]; // lower bound of interval 1
597 0 : sal_uInt16 u1 = _pRanges[ nPos1+1 ]; // upper bound of interval 1
598 0 : sal_uInt16 l2 = rRanges._pRanges[ nPos2 ]; // lower bound of interval 2
599 0 : sal_uInt16 u2 = rRanges._pRanges[ nPos2+1 ]; // upper bound of interval 2
600 :
601 0 : if( u1 < l2 )
602 : {
603 : // current interval in s1 is completely before ci in s2
604 0 : nPos1 += 2;
605 0 : continue;
606 : }
607 0 : if( u2 < l1 )
608 : {
609 : // ci in s2 is completely before ci in s1
610 0 : nPos2 += 2;
611 0 : continue;
612 : }
613 :
614 : // assert: there exists an intersection between ci1 and ci2
615 :
616 0 : if( l1 <= l2 )
617 : {
618 : // c1 "is more to the left" than c2
619 :
620 0 : if( u1 <= u2 )
621 : {
622 0 : pTarget[ nTargetPos ] = l2;
623 0 : pTarget[ nTargetPos+1 ] = u1;
624 0 : nTargetPos += 2;
625 0 : nPos1 += 2;
626 0 : continue;
627 : }
628 : else
629 : {
630 0 : pTarget[ nTargetPos ] = l2;
631 0 : pTarget[ nTargetPos+1 ] = u2;
632 0 : nTargetPos += 2;
633 0 : nPos2 += 2;
634 : }
635 : }
636 : else
637 : {
638 : // c2 "is more to the left" than c1"
639 :
640 0 : if( u1 > u2 )
641 : {
642 0 : pTarget[ nTargetPos ] = l1;
643 0 : pTarget[ nTargetPos+1 ] = u2;
644 0 : nTargetPos += 2;
645 0 : nPos2 += 2;
646 : }
647 : else
648 : {
649 0 : pTarget[ nTargetPos ] = l1;
650 0 : pTarget[ nTargetPos+1 ] = u1;
651 0 : nTargetPos += 2;
652 0 : nPos1 += 2;
653 : }
654 : }
655 : }; // while
656 0 : pTarget[ nTargetPos ] = 0;
657 :
658 : // assign the intersected ranges
659 0 : delete[] _pRanges;
660 :
661 0 : sal_uInt16 nUShorts = Count_Impl(pTarget.get()) + 1;
662 0 : if ( 1 != nUShorts )
663 : {
664 0 : _pRanges = new sal_uInt16[ nUShorts ];
665 0 : memcpy( _pRanges, pTarget.get(), nUShorts * sizeof(sal_uInt16) );
666 : }
667 : else
668 0 : _pRanges = 0;
669 :
670 0 : return *this;
671 : }
672 :
673 :
674 0 : sal_uInt16 SfxUShortRanges::Count() const
675 :
676 : /** <H3>Description</H3>
677 :
678 : Determines the number of USHORTs in the set described by the ranges
679 : of USHORTs in '*this'.
680 : */
681 :
682 : {
683 0 : return Capacity_Impl( _pRanges );
684 : }
685 :
686 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|