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 <osl/interlck.h>
23 :
24 : #include <rtl/ustrbuf.hxx>
25 : #include <strimp.hxx>
26 :
27 : #if USE_SDT_PROBES
28 : #define RTL_LOG_STRING_BITS 16
29 : #endif
30 :
31 10047474 : void SAL_CALL rtl_uStringbuffer_newFromStr_WithLength( rtl_uString ** newStr,
32 : const sal_Unicode * value,
33 : sal_Int32 count)
34 : {
35 10047474 : if (!value)
36 : {
37 0 : rtl_uString_new_WithLength( newStr, 16 );
38 0 : return;
39 : }
40 :
41 10047474 : rtl_uString_new_WithLength( newStr, count + 16 );
42 10047474 : (*newStr)->length = count;
43 10047474 : memcpy( (*newStr)->buffer, value, count * sizeof(sal_Unicode));
44 : RTL_LOG_STRING_NEW( *newStr );
45 10047474 : return;
46 : }
47 :
48 0 : rtl_uString * SAL_CALL rtl_uStringBuffer_refReturn( rtl_uString * pThis )
49 : {
50 : RTL_LOG_STRING_NEW( pThis );
51 0 : rtl_uString_acquire( pThis );
52 0 : return pThis;
53 : }
54 :
55 21092526 : rtl_uString * SAL_CALL rtl_uStringBuffer_makeStringAndClear( rtl_uString ** ppThis,
56 : sal_Int32 *nCapacity )
57 : {
58 : // avoid an un-necessary atomic ref/unref pair
59 21092526 : rtl_uString *pStr = *ppThis;
60 21092526 : *ppThis = NULL;
61 :
62 21092526 : rtl_uString_new (ppThis);
63 21092526 : *nCapacity = 0;
64 :
65 : RTL_LOG_STRING_NEW( pStr );
66 :
67 21092526 : return pStr;
68 : }
69 :
70 7398263 : sal_Int32 SAL_CALL rtl_uStringbuffer_newFromStringBuffer( rtl_uString ** newStr,
71 : sal_Int32 capacity,
72 : rtl_uString * oldStr )
73 : {
74 7398263 : sal_Int32 newCapacity = capacity;
75 :
76 7398263 : if (newCapacity < oldStr->length)
77 0 : newCapacity = oldStr->length;
78 :
79 7398263 : rtl_uString_new_WithLength( newStr, newCapacity );
80 :
81 7398263 : if (oldStr->length > 0) {
82 6503747 : (*newStr)->length = oldStr->length;
83 6503747 : memcpy( (*newStr)->buffer, oldStr->buffer, oldStr->length * sizeof(sal_Unicode));
84 : }
85 : RTL_LOG_STRING_NEW( *newStr );
86 7398263 : return newCapacity;
87 : }
88 :
89 9532108 : void SAL_CALL rtl_uStringbuffer_ensureCapacity
90 : (rtl_uString ** This, sal_Int32* capacity, sal_Int32 minimumCapacity)
91 : {
92 9532108 : if (minimumCapacity > *capacity)
93 : {
94 9289202 : rtl_uString * pTmp = *This;
95 9289202 : rtl_uString * pNew = NULL;
96 9289202 : *capacity = ((*This)->length + 1) * 2;
97 9289202 : if (minimumCapacity > *capacity)
98 : /* still lower, set to the minimum capacity */
99 4250922 : *capacity = minimumCapacity;
100 :
101 9289202 : rtl_uString_new_WithLength(&pNew, *capacity);
102 9289201 : pNew->length = (*This)->length;
103 9289201 : *This = pNew;
104 :
105 9289201 : memcpy( (*This)->buffer, pTmp->buffer, pTmp->length * sizeof(sal_Unicode) );
106 :
107 : RTL_LOG_STRING_NEW( pTmp ); // with accurate contents
108 9289201 : rtl_uString_release( pTmp );
109 : }
110 9532108 : }
111 :
112 272372158 : void SAL_CALL rtl_uStringbuffer_insert( rtl_uString ** This,
113 : sal_Int32 * capacity,
114 : sal_Int32 offset,
115 : const sal_Unicode * str,
116 : sal_Int32 len)
117 : {
118 : sal_Int32 nOldLen;
119 : sal_Unicode * pBuf;
120 : sal_Int32 n;
121 272372158 : if( len != 0 )
122 : {
123 271232623 : if (*capacity < (*This)->length + len)
124 8716386 : rtl_uStringbuffer_ensureCapacity( This, capacity, (*This)->length + len );
125 :
126 : /*
127 : if( len == 1 )
128 : This->buffer
129 : */
130 271232655 : nOldLen = (*This)->length;
131 271232655 : pBuf = (*This)->buffer;
132 :
133 : /* copy the tail */
134 271232655 : n = (nOldLen - offset);
135 271232655 : if( n == 1 )
136 : /* optimized for 1 character */
137 3105 : pBuf[offset + len] = pBuf[offset];
138 271229550 : else if( n > 1 )
139 138237 : memmove( pBuf + offset + len, pBuf + offset, n * sizeof(sal_Unicode) );
140 :
141 : /* insert the new characters */
142 271232655 : if( len == 1 )
143 : /* optimized for 1 character */
144 258399725 : pBuf[offset] = *str;
145 12832930 : else if( len > 1 )
146 12832933 : memcpy( pBuf + offset, str, len * sizeof(sal_Unicode) );
147 271232655 : (*This)->length = nOldLen + len;
148 271232655 : pBuf[ nOldLen + len ] = 0;
149 : }
150 272372190 : }
151 :
152 7605574 : void rtl_uStringbuffer_insertUtf32(
153 : rtl_uString ** pThis, sal_Int32 * capacity, sal_Int32 offset, sal_uInt32 c)
154 : SAL_THROW_EXTERN_C()
155 : {
156 : sal_Unicode buf[2];
157 : sal_Int32 len;
158 : OSL_ASSERT(c <= 0x10FFFF && !(c >= 0xD800 && c <= 0xDFFF));
159 7605574 : if (c <= 0xFFFF) {
160 7605570 : buf[0] = (sal_Unicode) c;
161 7605570 : len = 1;
162 : } else {
163 4 : c -= 0x10000;
164 4 : buf[0] = (sal_Unicode) ((c >> 10) | 0xD800);
165 4 : buf[1] = (sal_Unicode) ((c & 0x3FF) | 0xDC00);
166 4 : len = 2;
167 : }
168 7605574 : rtl_uStringbuffer_insert(pThis, capacity, offset, buf, len);
169 7605574 : }
170 :
171 5074975 : void SAL_CALL rtl_uStringbuffer_insert_ascii( /*inout*/rtl_uString ** This,
172 : /*inout*/sal_Int32 * capacity,
173 : sal_Int32 offset,
174 : const sal_Char * str,
175 : sal_Int32 len)
176 : {
177 : sal_Int32 nOldLen;
178 : sal_Unicode * pBuf;
179 : sal_Int32 n;
180 5074975 : if( len != 0 )
181 : {
182 5074695 : if (*capacity < (*This)->length + len)
183 321855 : rtl_uStringbuffer_ensureCapacity( This, capacity, (*This)->length + len );
184 :
185 5074695 : nOldLen = (*This)->length;
186 5074695 : pBuf = (*This)->buffer;
187 :
188 : /* copy the tail */
189 5074695 : n = (nOldLen - offset);
190 5074695 : if( n == 1 )
191 : /* optimized for 1 character */
192 30 : pBuf[offset + len] = pBuf[offset];
193 5074665 : else if( n > 1 )
194 117967 : memmove( pBuf + offset + len, pBuf + offset, n * sizeof(sal_Unicode) );
195 :
196 : /* insert the new characters */
197 36754998 : for( n = 0; n < len; n++ )
198 : {
199 : /* Check ASCII range */
200 : OSL_ENSURE( (*str & 0x80) == 0, "Found ASCII char > 127");
201 :
202 31680303 : pBuf[offset + n] = (sal_Unicode)*(str++);
203 : }
204 :
205 5074695 : (*This)->length = nOldLen + len;
206 5074695 : pBuf[ nOldLen + len ] = 0;
207 : }
208 5074975 : }
209 :
210 : /*************************************************************************
211 : * rtl_uStringbuffer_remove
212 : */
213 3396519 : void SAL_CALL rtl_uStringbuffer_remove( rtl_uString ** This,
214 : sal_Int32 start,
215 : sal_Int32 len )
216 : {
217 : sal_Int32 nTailLen;
218 : sal_Unicode * pBuf;
219 :
220 3396519 : if (len > (*This)->length - start)
221 0 : len = (*This)->length - start;
222 :
223 : //remove nothing
224 3396519 : if (!len)
225 3396531 : return;
226 :
227 3396507 : pBuf = (*This)->buffer;
228 3396507 : nTailLen = (*This)->length - ( start + len );
229 :
230 3396507 : if (nTailLen)
231 : {
232 : /* move the tail */
233 2745860 : memmove(pBuf + start, pBuf + start + len, nTailLen * sizeof(sal_Unicode));
234 : }
235 :
236 3396507 : (*This)->length-=len;
237 3396507 : pBuf[ (*This)->length ] = 0;
238 : }
239 :
240 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|