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 5782253 : void SAL_CALL rtl_uStringbuffer_newFromStr_WithLength( rtl_uString ** newStr,
28 : const sal_Unicode * value,
29 : sal_Int32 count)
30 : {
31 5782253 : if (!value)
32 : {
33 0 : rtl_uString_new_WithLength( newStr, 16 );
34 0 : return;
35 : }
36 :
37 5782253 : rtl_uString_new_WithLength( newStr, count + 16 );
38 5782253 : (*newStr)->length = count;
39 5782253 : memcpy( (*newStr)->buffer, value, count * sizeof(sal_Unicode));
40 : RTL_LOG_STRING_NEW( *newStr );
41 5782253 : return;
42 : }
43 :
44 17200590 : rtl_uString * SAL_CALL rtl_uStringBuffer_refReturn( rtl_uString * pThis )
45 : {
46 : RTL_LOG_STRING_NEW( pThis );
47 17200590 : rtl_uString_acquire( pThis );
48 17200590 : return pThis;
49 : }
50 :
51 11076762 : rtl_uString * SAL_CALL rtl_uStringBuffer_makeStringAndClear( rtl_uString ** ppThis,
52 : sal_Int32 *nCapacity )
53 : {
54 : // avoid an un-necessary atomic ref/unref pair
55 11076762 : rtl_uString *pStr = *ppThis;
56 11076762 : *ppThis = NULL;
57 :
58 11076762 : rtl_uString_new (ppThis);
59 11076762 : *nCapacity = 0;
60 :
61 : RTL_LOG_STRING_NEW( pStr );
62 :
63 11076762 : return pStr;
64 : }
65 :
66 1050252 : sal_Int32 SAL_CALL rtl_uStringbuffer_newFromStringBuffer( rtl_uString ** newStr,
67 : sal_Int32 capacity,
68 : rtl_uString * oldStr )
69 : {
70 1050252 : sal_Int32 newCapacity = capacity;
71 :
72 1050252 : if (newCapacity < oldStr->length)
73 0 : newCapacity = oldStr->length;
74 :
75 1050252 : rtl_uString_new_WithLength( newStr, newCapacity );
76 :
77 1050252 : if (oldStr->length > 0) {
78 936628 : (*newStr)->length = oldStr->length;
79 936628 : memcpy( (*newStr)->buffer, oldStr->buffer, oldStr->length * sizeof(sal_Unicode));
80 : }
81 : RTL_LOG_STRING_NEW( *newStr );
82 1050252 : return newCapacity;
83 : }
84 :
85 2189027 : void SAL_CALL rtl_uStringbuffer_ensureCapacity
86 : (rtl_uString ** This, sal_Int32* capacity, sal_Int32 minimumCapacity)
87 : {
88 2189027 : if (minimumCapacity > *capacity)
89 : {
90 2188322 : rtl_uString * pTmp = *This;
91 2188322 : rtl_uString * pNew = NULL;
92 2188322 : *capacity = ((*This)->length + 1) * 2;
93 2188322 : if (minimumCapacity > *capacity)
94 : /* still lower, set to the minimum capacity */
95 1141760 : *capacity = minimumCapacity;
96 :
97 2188322 : rtl_uString_new_WithLength(&pNew, *capacity);
98 2188322 : pNew->length = (*This)->length;
99 2188322 : *This = pNew;
100 :
101 2188322 : memcpy( (*This)->buffer, pTmp->buffer, pTmp->length * sizeof(sal_Unicode) );
102 :
103 : RTL_LOG_STRING_NEW( pTmp ); // with accurate contents
104 2188322 : rtl_uString_release( pTmp );
105 : }
106 2189027 : }
107 :
108 133628207 : void SAL_CALL rtl_uStringbuffer_insert( rtl_uString ** This,
109 : sal_Int32 * capacity,
110 : sal_Int32 offset,
111 : const sal_Unicode * str,
112 : sal_Int32 len)
113 : {
114 : sal_Int32 nOldLen;
115 : sal_Unicode * pBuf;
116 : sal_Int32 n;
117 133628207 : if( len != 0 )
118 : {
119 133220994 : if (*capacity < (*This)->length + len)
120 1982969 : rtl_uStringbuffer_ensureCapacity( This, capacity, (*This)->length + len );
121 :
122 : /*
123 : if( len == 1 )
124 : This->buffer
125 : */
126 133220992 : nOldLen = (*This)->length;
127 133220992 : pBuf = (*This)->buffer;
128 :
129 : /* copy the tail */
130 133220992 : n = (nOldLen - offset);
131 133220992 : if( n == 1 )
132 : /* optimized for 1 character */
133 889 : pBuf[offset + len] = pBuf[offset];
134 133220103 : else if( n > 1 )
135 30533 : memmove( pBuf + offset + len, pBuf + offset, n * sizeof(sal_Unicode) );
136 :
137 : /* insert the new characters */
138 133220992 : if( len == 1 )
139 : /* optimized for 1 character */
140 128076074 : pBuf[offset] = *str;
141 5144918 : else if( len > 1 )
142 5144929 : memcpy( pBuf + offset, str, len * sizeof(sal_Unicode) );
143 133220992 : (*This)->length = nOldLen + len;
144 133220992 : pBuf[ nOldLen + len ] = 0;
145 : }
146 133628205 : }
147 :
148 993301 : void rtl_uStringbuffer_insertUtf32(
149 : rtl_uString ** pThis, sal_Int32 * capacity, sal_Int32 offset, sal_uInt32 c)
150 : SAL_THROW_EXTERN_C()
151 : {
152 : sal_Unicode buf[2];
153 : sal_Int32 len;
154 : OSL_ASSERT(c <= 0x10FFFF && !(c >= 0xD800 && c <= 0xDFFF));
155 993301 : if (c <= 0xFFFF) {
156 993299 : buf[0] = (sal_Unicode) c;
157 993299 : len = 1;
158 : } else {
159 2 : c -= 0x10000;
160 2 : buf[0] = (sal_Unicode) ((c >> 10) | 0xD800);
161 2 : buf[1] = (sal_Unicode) ((c & 0x3FF) | 0xDC00);
162 2 : len = 2;
163 : }
164 993301 : rtl_uStringbuffer_insert(pThis, capacity, offset, buf, len);
165 993301 : }
166 :
167 1543616 : void SAL_CALL rtl_uStringbuffer_insert_ascii( /*inout*/rtl_uString ** This,
168 : /*inout*/sal_Int32 * capacity,
169 : sal_Int32 offset,
170 : const sal_Char * str,
171 : sal_Int32 len)
172 : {
173 : sal_Int32 nOldLen;
174 : sal_Unicode * pBuf;
175 : sal_Int32 n;
176 1543616 : if( len != 0 )
177 : {
178 1543592 : if (*capacity < (*This)->length + len)
179 42429 : rtl_uStringbuffer_ensureCapacity( This, capacity, (*This)->length + len );
180 :
181 1543592 : nOldLen = (*This)->length;
182 1543592 : pBuf = (*This)->buffer;
183 :
184 : /* copy the tail */
185 1543592 : n = (nOldLen - offset);
186 1543592 : if( n == 1 )
187 : /* optimized for 1 character */
188 15 : pBuf[offset + len] = pBuf[offset];
189 1543577 : else if( n > 1 )
190 25891 : memmove( pBuf + offset + len, pBuf + offset, n * sizeof(sal_Unicode) );
191 :
192 : /* insert the new characters */
193 9174384 : for( n = 0; n < len; n++ )
194 : {
195 : /* Check ASCII range */
196 : OSL_ENSURE( (*str & 0x80) == 0, "Found ASCII char > 127");
197 :
198 7630792 : pBuf[offset + n] = (sal_Unicode)*(str++);
199 : }
200 :
201 1543592 : (*This)->length = nOldLen + len;
202 1543592 : pBuf[ nOldLen + len ] = 0;
203 : }
204 1543616 : }
205 :
206 : /*************************************************************************
207 : * rtl_uStringbuffer_remove
208 : */
209 1456596 : void SAL_CALL rtl_uStringbuffer_remove( rtl_uString ** This,
210 : sal_Int32 start,
211 : sal_Int32 len )
212 : {
213 : sal_Int32 nTailLen;
214 : sal_Unicode * pBuf;
215 :
216 1456596 : if (len > (*This)->length - start)
217 0 : len = (*This)->length - start;
218 :
219 : //remove nothing
220 1456596 : if (!len)
221 1456602 : return;
222 :
223 1456590 : pBuf = (*This)->buffer;
224 1456590 : nTailLen = (*This)->length - ( start + len );
225 :
226 1456590 : if (nTailLen)
227 : {
228 : /* move the tail */
229 1315359 : memmove(pBuf + start, pBuf + start + len, nTailLen * sizeof(sal_Unicode));
230 : }
231 :
232 1456590 : (*This)->length-=len;
233 1456590 : pBuf[ (*This)->length ] = 0;
234 : }
235 :
236 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|