1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #include <osl/interlck.h> 25 26 #ifndef _RTL_STRING_HXX_ 27 #include <rtl/ustrbuf.hxx> 28 #endif 29 #include <rtl/memory.h> 30 31 /* 32 #include <rtl/alloc.h> 33 */ 34 35 36 37 /************************************************************************* 38 * rtl_uStringbuffer_newFromStr_WithLength 39 */ 40 void SAL_CALL rtl_uStringbuffer_newFromStr_WithLength( rtl_uString ** newStr, 41 const sal_Unicode * value, 42 sal_Int32 count) 43 { 44 if (!value) 45 { 46 rtl_uString_new_WithLength( newStr, 16 ); 47 return; 48 } 49 50 rtl_uString_new_WithLength( newStr, count + 16 ); 51 (*newStr)->length = count; 52 rtl_copyMemory( (*newStr)->buffer, value, count * sizeof(sal_Unicode)); 53 return; 54 } 55 56 /************************************************************************* 57 * rtl_uStringbuffer_newFromStringBuffer 58 */ 59 sal_Int32 SAL_CALL rtl_uStringbuffer_newFromStringBuffer( rtl_uString ** newStr, 60 sal_Int32 capacity, 61 rtl_uString * oldStr ) 62 { 63 sal_Int32 newCapacity = capacity; 64 65 if (newCapacity < oldStr->length) 66 newCapacity = oldStr->length; 67 68 rtl_uString_new_WithLength( newStr, newCapacity ); 69 70 if (oldStr->length > 0) { 71 (*newStr)->length = oldStr->length; 72 rtl_copyMemory( (*newStr)->buffer, oldStr->buffer, oldStr->length * sizeof(sal_Unicode)); 73 } 74 return newCapacity; 75 } 76 77 /************************************************************************* 78 * rtl_uStringbuffer_ensureCapacity 79 */ 80 void SAL_CALL rtl_uStringbuffer_ensureCapacity 81 (rtl_uString ** This, sal_Int32* capacity, sal_Int32 minimumCapacity) 82 { 83 if (minimumCapacity > *capacity) 84 { 85 rtl_uString * pTmp = *This; 86 rtl_uString * pNew = NULL; 87 *capacity = ((*This)->length + 1) * 2; 88 if (minimumCapacity > *capacity) 89 /* still lower, set to the minimum capacity */ 90 *capacity = minimumCapacity; 91 92 rtl_uString_new_WithLength(&pNew, *capacity); 93 pNew->length = (*This)->length; 94 *This = pNew; 95 96 rtl_copyMemory( (*This)->buffer, pTmp->buffer, pTmp->length * sizeof(sal_Unicode) ); 97 rtl_uString_release( pTmp ); 98 } 99 } 100 101 /************************************************************************* 102 * rtl_uStringbuffer_insert 103 */ 104 void SAL_CALL rtl_uStringbuffer_insert( rtl_uString ** This, 105 sal_Int32 * capacity, 106 sal_Int32 offset, 107 const sal_Unicode * str, 108 sal_Int32 len) 109 { 110 sal_Int32 nOldLen; 111 sal_Unicode * pBuf; 112 sal_Int32 n; 113 if( len != 0 ) 114 { 115 if (*capacity < (*This)->length + len) 116 rtl_uStringbuffer_ensureCapacity( This, capacity, (*This)->length + len ); 117 118 /* 119 if( len == 1 ) 120 This->buffer 121 */ 122 nOldLen = (*This)->length; 123 pBuf = (*This)->buffer; 124 125 /* copy the tail */ 126 n = (nOldLen - offset); 127 if( n == 1 ) 128 /* optimized for 1 character */ 129 pBuf[offset + len] = pBuf[offset]; 130 else if( n > 1 ) 131 rtl_moveMemory( pBuf + offset + len, pBuf + offset, n * sizeof(sal_Unicode) ); 132 133 /* insert the new characters */ 134 if( len == 1 ) 135 /* optimized for 1 character */ 136 pBuf[offset] = *str; 137 else if( len > 1 ) 138 rtl_copyMemory( pBuf + offset, str, len * sizeof(sal_Unicode) ); 139 (*This)->length = nOldLen + len; 140 pBuf[ nOldLen + len ] = 0; 141 } 142 } 143 144 void rtl_uStringbuffer_insertUtf32( 145 rtl_uString ** pThis, sal_Int32 * capacity, sal_Int32 offset, sal_uInt32 c) 146 { 147 sal_Unicode buf[2]; 148 sal_Int32 len; 149 OSL_ASSERT(c <= 0x10FFFF && !(c >= 0xD800 && c <= 0xDFFF)); 150 if (c <= 0xFFFF) { 151 buf[0] = (sal_Unicode) c; 152 len = 1; 153 } else { 154 c -= 0x10000; 155 buf[0] = (sal_Unicode) ((c >> 10) | 0xD800); 156 buf[1] = (sal_Unicode) ((c & 0x3FF) | 0xDC00); 157 len = 2; 158 } 159 rtl_uStringbuffer_insert(pThis, capacity, offset, buf, len); 160 } 161 162 /************************************************************************* 163 * rtl_uStringbuffer_insert_ascii 164 */ 165 void SAL_CALL rtl_uStringbuffer_insert_ascii( /*inout*/rtl_uString ** This, 166 /*inout*/sal_Int32 * capacity, 167 sal_Int32 offset, 168 const sal_Char * str, 169 sal_Int32 len) 170 { 171 sal_Int32 nOldLen; 172 sal_Unicode * pBuf; 173 sal_Int32 n; 174 if( len != 0 ) 175 { 176 if (*capacity < (*This)->length + len) 177 rtl_uStringbuffer_ensureCapacity( This, capacity, (*This)->length + len ); 178 179 nOldLen = (*This)->length; 180 pBuf = (*This)->buffer; 181 182 /* copy the tail */ 183 n = (nOldLen - offset); 184 if( n == 1 ) 185 /* optimized for 1 character */ 186 pBuf[offset + len] = pBuf[offset]; 187 else if( n > 1 ) 188 rtl_moveMemory( pBuf + offset + len, pBuf + offset, n * sizeof(sal_Unicode) ); 189 190 /* insert the new characters */ 191 for( n = 0; n < len; n++ ) 192 { 193 /* Check ASCII range */ 194 OSL_ENSURE( (*str & 0x80) == 0, "Found ASCII char > 127"); 195 196 pBuf[offset + n] = (sal_Unicode)*(str++); 197 } 198 199 (*This)->length = nOldLen + len; 200 pBuf[ nOldLen + len ] = 0; 201 } 202 } 203 204 205