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>
24 #include <rtl/character.hxx>
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 // use raw alloc to avoid overwriting the buffer twice
46 rtl_uString_release( *newStr
);
47 *newStr
= rtl_uString_ImplAlloc( count
+ 16 );
48 (*newStr
)->length
= count
;
49 memcpy( (*newStr
)->buffer
, value
, count
* sizeof(sal_Unicode
) );
50 memset( (*newStr
)->buffer
+ count
, 0, 16 * sizeof(sal_Unicode
) );
51 RTL_LOG_STRING_NEW( *newStr
);
54 rtl_uString
* SAL_CALL
rtl_uStringBuffer_refReturn( rtl_uString
* pThis
)
56 RTL_LOG_STRING_NEW( pThis
);
57 rtl_uString_acquire( pThis
);
61 rtl_uString
* SAL_CALL
rtl_uStringBuffer_makeStringAndClear( rtl_uString
** ppThis
,
62 sal_Int32
*nCapacity
)
66 // avoid an un-necessary atomic ref/unref pair
67 rtl_uString
*pStr
= *ppThis
;
70 rtl_uString_new (ppThis
);
73 RTL_LOG_STRING_NEW( pStr
);
78 sal_Int32 SAL_CALL
rtl_uStringbuffer_newFromStringBuffer( rtl_uString
** newStr
,
80 rtl_uString
* oldStr
)
83 assert(capacity
>= 0);
85 sal_Int32 newCapacity
= capacity
;
87 if (newCapacity
< oldStr
->length
)
88 newCapacity
= oldStr
->length
;
90 rtl_uString_new_WithLength( newStr
, newCapacity
);
92 if (oldStr
->length
> 0) {
93 (*newStr
)->length
= oldStr
->length
;
94 memcpy( (*newStr
)->buffer
, oldStr
->buffer
, oldStr
->length
* sizeof(sal_Unicode
));
96 RTL_LOG_STRING_NEW( *newStr
);
100 void SAL_CALL rtl_uStringbuffer_ensureCapacity
101 (rtl_uString
** This
, sal_Int32
* capacity
, sal_Int32 minimumCapacity
)
104 assert(capacity
&& *capacity
>= 0);
105 assert(minimumCapacity
>= 0);
106 if (minimumCapacity
> *capacity
)
108 rtl_uString
* pTmp
= *This
;
109 rtl_uString
* pNew
= nullptr;
110 auto nLength
= (*This
)->length
;
111 *capacity
= (nLength
+ 1) * 2;
112 if (minimumCapacity
> *capacity
)
113 /* still lower, set to the minimum capacity */
114 *capacity
= minimumCapacity
;
116 // use raw alloc to avoid overwriting the buffer twice
117 pNew
= rtl_uString_ImplAlloc( *capacity
);
118 pNew
->length
= nLength
;
121 memcpy( (*This
)->buffer
, pTmp
->buffer
, nLength
* sizeof(sal_Unicode
) );
122 memset( (*This
)->buffer
+ nLength
, 0, (*capacity
- nLength
) * sizeof(sal_Unicode
) );
124 RTL_LOG_STRING_NEW( pTmp
); // with accurate contents
125 rtl_uString_release( pTmp
);
129 void SAL_CALL
rtl_uStringbuffer_insert( rtl_uString
** This
,
130 sal_Int32
* capacity
,
132 const sal_Unicode
* str
,
136 assert(capacity
&& *capacity
>= 0);
137 assert(offset
>= 0 && offset
<= (**This
).length
);
144 if (*capacity
< (*This
)->length
+ len
)
145 rtl_uStringbuffer_ensureCapacity( This
, capacity
, (*This
)->length
+ len
);
147 nOldLen
= (*This
)->length
;
148 pBuf
= (*This
)->buffer
;
151 n
= (nOldLen
- offset
);
153 /* optimized for 1 character */
154 pBuf
[offset
+ len
] = pBuf
[offset
];
156 memmove( pBuf
+ offset
+ len
, pBuf
+ offset
, n
* sizeof(sal_Unicode
) );
158 /* insert the new characters */
162 /* optimized for 1 character */
165 memcpy( pBuf
+ offset
, str
, len
* sizeof(sal_Unicode
) );
167 (*This
)->length
= nOldLen
+ len
;
168 pBuf
[ nOldLen
+ len
] = 0;
172 void rtl_uStringbuffer_insertUtf32(
173 rtl_uString
** pThis
, sal_Int32
* capacity
, sal_Int32 offset
, sal_uInt32 c
)
178 OSL_ASSERT(rtl::isUnicodeScalarValue(c
));
180 buf
[0] = static_cast<sal_Unicode
>(c
);
184 buf
[0] = static_cast<sal_Unicode
>((c
>> 10) | 0xD800);
185 buf
[1] = static_cast<sal_Unicode
>((c
& 0x3FF) | 0xDC00);
188 rtl_uStringbuffer_insert(pThis
, capacity
, offset
, buf
, len
);
191 void SAL_CALL
rtl_uStringbuffer_insert_ascii( /*inout*/rtl_uString
** This
,
192 /*inout*/sal_Int32
* capacity
,
194 const sal_Char
* str
,
198 assert(capacity
&& *capacity
>= 0);
199 assert(offset
>= 0 && offset
<= (**This
).length
);
200 assert(len
== 0 || str
!= nullptr);
207 if (*capacity
< (*This
)->length
+ len
)
208 rtl_uStringbuffer_ensureCapacity( This
, capacity
, (*This
)->length
+ len
);
210 nOldLen
= (*This
)->length
;
211 pBuf
= (*This
)->buffer
;
214 n
= (nOldLen
- offset
);
216 /* optimized for 1 character */
217 pBuf
[offset
+ len
] = pBuf
[offset
];
219 memmove( pBuf
+ offset
+ len
, pBuf
+ offset
, n
* sizeof(sal_Unicode
) );
221 /* insert the new characters */
222 for( n
= 0; n
< len
; n
++ )
224 /* Check ASCII range */
225 OSL_ENSURE( (*str
& 0x80) == 0, "Found ASCII char > 127");
227 pBuf
[offset
+ n
] = static_cast<sal_Unicode
>(*(str
++));
230 (*This
)->length
= nOldLen
+ len
;
231 pBuf
[ nOldLen
+ len
] = 0;
235 /*************************************************************************
236 * rtl_uStringbuffer_remove
238 void SAL_CALL
rtl_uStringbuffer_remove( rtl_uString
** This
,
243 assert(start
>= 0 && start
<= (**This
).length
);
248 if (len
> (*This
)->length
- start
)
249 len
= (*This
)->length
- start
;
255 pBuf
= (*This
)->buffer
;
256 nTailLen
= (*This
)->length
- ( start
+ len
);
261 memmove(pBuf
+ start
, pBuf
+ start
+ len
, nTailLen
* sizeof(sal_Unicode
));
264 (*This
)->length
-=len
;
265 pBuf
[ (*This
)->length
] = 0;
268 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */