lok: Don't attempt to select the exact text after a failed search.
[LibreOffice.git] / sal / rtl / ustrbuf.cxx
blob7f5d698c76ecdb3bf7b95ac5581d3cc939a4789d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include <string.h>
22 #include <osl/interlck.h>
23 #include <osl/diagnose.h>
25 #include <rtl/ustrbuf.hxx>
26 #include <strimp.hxx>
28 #if USE_SDT_PROBES
29 #define RTL_LOG_STRING_BITS 16
30 #endif
32 void SAL_CALL rtl_uStringbuffer_newFromStr_WithLength( rtl_uString ** newStr,
33 const sal_Unicode * value,
34 sal_Int32 count)
36 assert(newStr);
37 assert(count >= 0);
38 if (!value)
40 rtl_uString_new_WithLength( newStr, 16 );
41 return;
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 );
48 return;
51 rtl_uString * SAL_CALL rtl_uStringBuffer_refReturn( rtl_uString * pThis )
53 RTL_LOG_STRING_NEW( pThis );
54 rtl_uString_acquire( pThis );
55 return pThis;
58 rtl_uString * SAL_CALL rtl_uStringBuffer_makeStringAndClear( rtl_uString ** ppThis,
59 sal_Int32 *nCapacity )
61 assert(ppThis);
62 assert(nCapacity);
63 // avoid an un-necessary atomic ref/unref pair
64 rtl_uString *pStr = *ppThis;
65 *ppThis = NULL;
67 rtl_uString_new (ppThis);
68 *nCapacity = 0;
70 RTL_LOG_STRING_NEW( pStr );
72 return pStr;
75 sal_Int32 SAL_CALL rtl_uStringbuffer_newFromStringBuffer( rtl_uString ** newStr,
76 sal_Int32 capacity,
77 rtl_uString * oldStr )
79 assert(newStr);
80 assert(capacity >= 0);
81 assert(oldStr);
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 );
94 return newCapacity;
97 void SAL_CALL rtl_uStringbuffer_ensureCapacity
98 (rtl_uString ** This, sal_Int32* capacity, sal_Int32 minimumCapacity)
100 assert(This);
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;
114 *This = pNew;
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,
125 sal_Int32 offset,
126 const sal_Unicode * str,
127 sal_Int32 len)
129 assert(This);
130 assert(capacity && *capacity >= 0);
131 assert(offset >= 0 && offset <= (**This).length);
132 assert(len >= 0);
133 sal_Int32 nOldLen;
134 sal_Unicode * pBuf;
135 sal_Int32 n;
136 if( len != 0 )
138 if (*capacity < (*This)->length + len)
139 rtl_uStringbuffer_ensureCapacity( This, capacity, (*This)->length + len );
141 nOldLen = (*This)->length;
142 pBuf = (*This)->buffer;
144 /* copy the tail */
145 n = (nOldLen - offset);
146 if( n == 1 )
147 /* optimized for 1 character */
148 pBuf[offset + len] = pBuf[offset];
149 else if( n > 1 )
150 memmove( pBuf + offset + len, pBuf + offset, n * sizeof(sal_Unicode) );
152 /* insert the new characters */
153 if( str != nullptr )
155 if( len == 1 )
156 /* optimized for 1 character */
157 pBuf[offset] = *str;
158 else
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)
168 SAL_THROW_EXTERN_C()
170 sal_Unicode buf[2];
171 sal_Int32 len;
172 OSL_ASSERT(c <= 0x10FFFF && !(c >= 0xD800 && c <= 0xDFFF));
173 if (c <= 0xFFFF) {
174 buf[0] = (sal_Unicode) c;
175 len = 1;
176 } else {
177 c -= 0x10000;
178 buf[0] = (sal_Unicode) ((c >> 10) | 0xD800);
179 buf[1] = (sal_Unicode) ((c & 0x3FF) | 0xDC00);
180 len = 2;
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,
187 sal_Int32 offset,
188 const sal_Char * str,
189 sal_Int32 len)
191 assert(This);
192 assert(capacity && *capacity >= 0);
193 assert(offset >= 0 && offset <= (**This).length);
194 assert(len == 0 || str != nullptr);
195 assert(len >= 0);
196 sal_Int32 nOldLen;
197 sal_Unicode * pBuf;
198 sal_Int32 n;
199 if( len != 0 )
201 if (*capacity < (*This)->length + len)
202 rtl_uStringbuffer_ensureCapacity( This, capacity, (*This)->length + len );
204 nOldLen = (*This)->length;
205 pBuf = (*This)->buffer;
207 /* copy the tail */
208 n = (nOldLen - offset);
209 if( n == 1 )
210 /* optimized for 1 character */
211 pBuf[offset + len] = pBuf[offset];
212 else if( n > 1 )
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,
233 sal_Int32 start,
234 sal_Int32 len )
236 assert(This);
237 assert(start >= 0 && start <= (**This).length);
238 assert(len >= 0);
239 sal_Int32 nTailLen;
240 sal_Unicode * pBuf;
242 if (len > (*This)->length - start)
243 len = (*This)->length - start;
245 //remove nothing
246 if (!len)
247 return;
249 pBuf = (*This)->buffer;
250 nTailLen = (*This)->length - ( start + len );
252 if (nTailLen)
254 /* move the tail */
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: */