Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / sal / rtl / strbuf.cxx
blob2b7d8e96a8d13a37314b67cb378855fc6c67412f
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 <rtl/strbuf.hxx>
24 #include "strimp.hxx"
26 /*************************************************************************
27 * rtl_stringbuffer_newFromStr_WithLength
29 void SAL_CALL rtl_stringbuffer_newFromStr_WithLength( rtl_String ** newStr,
30 const sal_Char * value,
31 sal_Int32 count )
33 assert(newStr);
34 assert(count >= 0);
35 if (!value)
37 rtl_string_new_WithLength( newStr, 16 );
38 return;
41 // use raw alloc to avoid overwriting the buffer twice
42 if ( *newStr)
43 rtl_string_release( *newStr );
44 *newStr = rtl_string_ImplAlloc( count + 16 );
45 (*newStr)->length = count;
46 memcpy( (*newStr)->buffer, value, count );
47 memset( (*newStr)->buffer + count, 0, 16 );
50 /*************************************************************************
51 * rtl_stringbuffer_newFromStringBuffer
53 sal_Int32 SAL_CALL rtl_stringbuffer_newFromStringBuffer( rtl_String ** newStr,
54 sal_Int32 capacity,
55 rtl_String * oldStr )
57 assert(newStr);
58 assert(oldStr);
59 assert(capacity >= 0);
60 sal_Int32 newCapacity = capacity;
62 if (newCapacity < oldStr->length)
63 newCapacity = oldStr->length;
65 rtl_string_new_WithLength( newStr, newCapacity );
66 if (oldStr->length > 0) {
67 (*newStr)->length = oldStr->length;
68 memcpy( (*newStr)->buffer, oldStr->buffer, oldStr->length );
70 return newCapacity;
73 /*************************************************************************
74 * rtl_stringbuffer_ensureCapacity
76 void SAL_CALL rtl_stringbuffer_ensureCapacity
77 (rtl_String ** This, sal_Int32* capacity, sal_Int32 minimumCapacity)
79 assert(This);
80 // assert(capacity && *capacity >= 0);
81 // assert(minimumCapacity >= 0);
82 if (minimumCapacity > *capacity)
84 rtl_String * pTmp = *This;
85 rtl_String * pNew = nullptr;
86 auto nLength = (*This)->length;
87 *capacity = (nLength + 1) * 2;
88 if (minimumCapacity > *capacity)
89 /* still lower, set to the minimum capacity */
90 *capacity = minimumCapacity;
92 // use raw alloc to avoid overwriting the buffer twice
93 pNew = rtl_string_ImplAlloc( *capacity );
94 pNew->length = nLength;
95 *This = pNew;
97 memcpy( (*This)->buffer, pTmp->buffer, nLength );
98 memset( (*This)->buffer + nLength, 0, *capacity - nLength );
99 rtl_string_release( pTmp );
103 /*************************************************************************
104 * rtl_stringbuffer_insert
106 void SAL_CALL rtl_stringbuffer_insert( rtl_String ** This,
107 sal_Int32 * capacity,
108 sal_Int32 offset,
109 const sal_Char * str,
110 sal_Int32 len )
112 assert(This);
113 assert(capacity && *capacity >= 0);
114 assert(offset >= 0 && offset <= (**This).length);
115 assert(len >= 0);
116 sal_Int32 nOldLen;
117 sal_Char * pBuf;
118 sal_Int32 n;
119 if( len != 0 )
121 if (*capacity < (*This)->length + len)
122 rtl_stringbuffer_ensureCapacity( This, capacity, (*This)->length + len );
124 nOldLen = (*This)->length;
125 pBuf = (*This)->buffer;
127 /* copy the tail */
128 n = (nOldLen - offset);
129 if( n == 1 )
130 /* optimized for 1 character */
131 pBuf[offset + len] = pBuf[offset];
132 else if( n > 1 )
133 memmove( pBuf + offset + len, pBuf + offset, n * sizeof(sal_Char) );
135 /* insert the new characters */
136 if( str != nullptr )
138 if( len == 1 )
139 /* optimized for 1 character */
140 pBuf[offset] = *str;
141 else
142 memcpy( pBuf + offset, str, len * sizeof(sal_Char) );
144 (*This)->length = nOldLen + len;
145 pBuf[ nOldLen + len ] = 0;
149 /*************************************************************************
150 * rtl_stringbuffer_remove
152 void SAL_CALL rtl_stringbuffer_remove( rtl_String ** This,
153 sal_Int32 start,
154 sal_Int32 len )
156 assert(This);
157 assert(start >= 0 && start <= (**This).length);
158 assert(len >= 0);
159 sal_Int32 nTailLen;
160 sal_Char * pBuf;
162 if (len > (*This)->length - start)
163 len = (*This)->length - start;
165 //remove nothing
166 if (!len)
167 return;
169 pBuf = (*This)->buffer;
170 nTailLen = (*This)->length - ( start + len );
172 if (nTailLen)
174 /* move the tail */
175 memmove(pBuf + start, pBuf + start + len, nTailLen * sizeof(sal_Char));
178 (*This)->length-=len;
179 pBuf[ (*This)->length ] = 0;
182 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */