1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
22 #include <osl/interlck.h>
23 #include <osl/diagnose.h>
25 #include <rtl/ustrbuf.hxx>
29 #define RTL_LOG_STRING_BITS 16
32 void SAL_CALL
rtl_uStringbuffer_newFromStr_WithLength( rtl_uString
** newStr
,
33 const sal_Unicode
* value
,
40 rtl_uString_new_WithLength( newStr
, 16 );
44 rtl_uString_new_WithLength( newStr
, count
+ 16 );
45 (*newStr
)->length
= count
;
46 memcpy( (*newStr
)->buffer
, value
, count
* sizeof(sal_Unicode
));
47 RTL_LOG_STRING_NEW( *newStr
);
51 rtl_uString
* SAL_CALL
rtl_uStringBuffer_refReturn( rtl_uString
* pThis
)
53 RTL_LOG_STRING_NEW( pThis
);
54 rtl_uString_acquire( pThis
);
58 rtl_uString
* SAL_CALL
rtl_uStringBuffer_makeStringAndClear( rtl_uString
** ppThis
,
59 sal_Int32
*nCapacity
)
63 // avoid an un-necessary atomic ref/unref pair
64 rtl_uString
*pStr
= *ppThis
;
67 rtl_uString_new (ppThis
);
70 RTL_LOG_STRING_NEW( pStr
);
75 sal_Int32 SAL_CALL
rtl_uStringbuffer_newFromStringBuffer( rtl_uString
** newStr
,
77 rtl_uString
* oldStr
)
80 assert(capacity
>= 0);
82 sal_Int32 newCapacity
= capacity
;
84 if (newCapacity
< oldStr
->length
)
85 newCapacity
= oldStr
->length
;
87 rtl_uString_new_WithLength( newStr
, newCapacity
);
89 if (oldStr
->length
> 0) {
90 (*newStr
)->length
= oldStr
->length
;
91 memcpy( (*newStr
)->buffer
, oldStr
->buffer
, oldStr
->length
* sizeof(sal_Unicode
));
93 RTL_LOG_STRING_NEW( *newStr
);
97 void SAL_CALL rtl_uStringbuffer_ensureCapacity
98 (rtl_uString
** This
, sal_Int32
* capacity
, sal_Int32 minimumCapacity
)
101 assert(capacity
&& *capacity
>= 0);
102 assert(minimumCapacity
>= 0);
103 if (minimumCapacity
> *capacity
)
105 rtl_uString
* pTmp
= *This
;
106 rtl_uString
* pNew
= NULL
;
107 *capacity
= ((*This
)->length
+ 1) * 2;
108 if (minimumCapacity
> *capacity
)
109 /* still lower, set to the minimum capacity */
110 *capacity
= minimumCapacity
;
112 rtl_uString_new_WithLength(&pNew
, *capacity
);
113 pNew
->length
= (*This
)->length
;
116 memcpy( (*This
)->buffer
, pTmp
->buffer
, pTmp
->length
* sizeof(sal_Unicode
) );
118 RTL_LOG_STRING_NEW( pTmp
); // with accurate contents
119 rtl_uString_release( pTmp
);
123 void SAL_CALL
rtl_uStringbuffer_insert( rtl_uString
** This
,
124 sal_Int32
* capacity
,
126 const sal_Unicode
* str
,
130 assert(capacity
&& *capacity
>= 0);
131 assert(offset
>= 0 && offset
<= (**This
).length
);
138 if (*capacity
< (*This
)->length
+ len
)
139 rtl_uStringbuffer_ensureCapacity( This
, capacity
, (*This
)->length
+ len
);
141 nOldLen
= (*This
)->length
;
142 pBuf
= (*This
)->buffer
;
145 n
= (nOldLen
- offset
);
147 /* optimized for 1 character */
148 pBuf
[offset
+ len
] = pBuf
[offset
];
150 memmove( pBuf
+ offset
+ len
, pBuf
+ offset
, n
* sizeof(sal_Unicode
) );
152 /* insert the new characters */
156 /* optimized for 1 character */
159 memcpy( pBuf
+ offset
, str
, len
* sizeof(sal_Unicode
) );
161 (*This
)->length
= nOldLen
+ len
;
162 pBuf
[ nOldLen
+ len
] = 0;
166 void rtl_uStringbuffer_insertUtf32(
167 rtl_uString
** pThis
, sal_Int32
* capacity
, sal_Int32 offset
, sal_uInt32 c
)
172 OSL_ASSERT(c
<= 0x10FFFF && !(c
>= 0xD800 && c
<= 0xDFFF));
174 buf
[0] = (sal_Unicode
) c
;
178 buf
[0] = (sal_Unicode
) ((c
>> 10) | 0xD800);
179 buf
[1] = (sal_Unicode
) ((c
& 0x3FF) | 0xDC00);
182 rtl_uStringbuffer_insert(pThis
, capacity
, offset
, buf
, len
);
185 void SAL_CALL
rtl_uStringbuffer_insert_ascii( /*inout*/rtl_uString
** This
,
186 /*inout*/sal_Int32
* capacity
,
188 const sal_Char
* str
,
192 assert(capacity
&& *capacity
>= 0);
193 assert(offset
>= 0 && offset
<= (**This
).length
);
194 assert(len
== 0 || str
!= nullptr);
201 if (*capacity
< (*This
)->length
+ len
)
202 rtl_uStringbuffer_ensureCapacity( This
, capacity
, (*This
)->length
+ len
);
204 nOldLen
= (*This
)->length
;
205 pBuf
= (*This
)->buffer
;
208 n
= (nOldLen
- offset
);
210 /* optimized for 1 character */
211 pBuf
[offset
+ len
] = pBuf
[offset
];
213 memmove( pBuf
+ offset
+ len
, pBuf
+ offset
, n
* sizeof(sal_Unicode
) );
215 /* insert the new characters */
216 for( n
= 0; n
< len
; n
++ )
218 /* Check ASCII range */
219 OSL_ENSURE( (*str
& 0x80) == 0, "Found ASCII char > 127");
221 pBuf
[offset
+ n
] = (sal_Unicode
)*(str
++);
224 (*This
)->length
= nOldLen
+ len
;
225 pBuf
[ nOldLen
+ len
] = 0;
229 /*************************************************************************
230 * rtl_uStringbuffer_remove
232 void SAL_CALL
rtl_uStringbuffer_remove( rtl_uString
** This
,
237 assert(start
>= 0 && start
<= (**This
).length
);
242 if (len
> (*This
)->length
- start
)
243 len
= (*This
)->length
- start
;
249 pBuf
= (*This
)->buffer
;
250 nTailLen
= (*This
)->length
- ( start
+ len
);
255 memmove(pBuf
+ start
, pBuf
+ start
+ len
, nTailLen
* sizeof(sal_Unicode
));
258 (*This
)->length
-=len
;
259 pBuf
[ (*This
)->length
] = 0;
262 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */