1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include <osl/interlck.h> 29 30 #ifndef _RTL_STRING_HXX_ 31 #include <rtl/ustrbuf.hxx> 32 #endif 33 #include <rtl/memory.h> 34 35 /* 36 #include <rtl/alloc.h> 37 */ 38 39 40 41 /************************************************************************* 42 * rtl_uStringbuffer_newFromStr_WithLength 43 */ 44 void SAL_CALL rtl_uStringbuffer_newFromStr_WithLength( rtl_uString ** newStr, 45 const sal_Unicode * value, 46 sal_Int32 count) 47 { 48 if (!value) 49 { 50 rtl_uString_new_WithLength( newStr, 16 ); 51 return; 52 } 53 54 rtl_uString_new_WithLength( newStr, count + 16 ); 55 (*newStr)->length = count; 56 rtl_copyMemory( (*newStr)->buffer, value, count * sizeof(sal_Unicode)); 57 return; 58 } 59 60 /************************************************************************* 61 * rtl_uStringbuffer_newFromStringBuffer 62 */ 63 sal_Int32 SAL_CALL rtl_uStringbuffer_newFromStringBuffer( rtl_uString ** newStr, 64 sal_Int32 capacity, 65 rtl_uString * oldStr ) 66 { 67 sal_Int32 newCapacity = capacity; 68 69 if (newCapacity < oldStr->length) 70 newCapacity = oldStr->length; 71 72 rtl_uString_new_WithLength( newStr, newCapacity ); 73 74 if (oldStr->length > 0) { 75 (*newStr)->length = oldStr->length; 76 rtl_copyMemory( (*newStr)->buffer, oldStr->buffer, oldStr->length * sizeof(sal_Unicode)); 77 } 78 return newCapacity; 79 } 80 81 /************************************************************************* 82 * rtl_uStringbuffer_ensureCapacity 83 */ 84 void SAL_CALL rtl_uStringbuffer_ensureCapacity 85 (rtl_uString ** This, sal_Int32* capacity, sal_Int32 minimumCapacity) 86 { 87 if (minimumCapacity > *capacity) 88 { 89 rtl_uString * pTmp = *This; 90 rtl_uString * pNew = NULL; 91 *capacity = ((*This)->length + 1) * 2; 92 if (minimumCapacity > *capacity) 93 /* still lower, set to the minimum capacity */ 94 *capacity = minimumCapacity; 95 96 rtl_uString_new_WithLength(&pNew, *capacity); 97 pNew->length = (*This)->length; 98 *This = pNew; 99 100 rtl_copyMemory( (*This)->buffer, pTmp->buffer, pTmp->length * sizeof(sal_Unicode) ); 101 rtl_uString_release( pTmp ); 102 } 103 } 104 105 /************************************************************************* 106 * rtl_uStringbuffer_insert 107 */ 108 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 if( len != 0 ) 118 { 119 if (*capacity < (*This)->length + len) 120 rtl_uStringbuffer_ensureCapacity( This, capacity, (*This)->length + len ); 121 122 /* 123 if( len == 1 ) 124 This->buffer 125 */ 126 nOldLen = (*This)->length; 127 pBuf = (*This)->buffer; 128 129 /* copy the tail */ 130 n = (nOldLen - offset); 131 if( n == 1 ) 132 /* optimized for 1 character */ 133 pBuf[offset + len] = pBuf[offset]; 134 else if( n > 1 ) 135 rtl_moveMemory( pBuf + offset + len, pBuf + offset, n * sizeof(sal_Unicode) ); 136 137 /* insert the new characters */ 138 if( len == 1 ) 139 /* optimized for 1 character */ 140 pBuf[offset] = *str; 141 else if( len > 1 ) 142 rtl_copyMemory( pBuf + offset, str, len * sizeof(sal_Unicode) ); 143 (*This)->length = nOldLen + len; 144 pBuf[ nOldLen + len ] = 0; 145 } 146 } 147 148 void rtl_uStringbuffer_insertUtf32( 149 rtl_uString ** pThis, sal_Int32 * capacity, sal_Int32 offset, sal_uInt32 c) 150 { 151 sal_Unicode buf[2]; 152 sal_Int32 len; 153 OSL_ASSERT(c <= 0x10FFFF && !(c >= 0xD800 && c <= 0xDFFF)); 154 if (c <= 0xFFFF) { 155 buf[0] = (sal_Unicode) c; 156 len = 1; 157 } else { 158 c -= 0x10000; 159 buf[0] = (sal_Unicode) ((c >> 10) | 0xD800); 160 buf[1] = (sal_Unicode) ((c & 0x3FF) | 0xDC00); 161 len = 2; 162 } 163 rtl_uStringbuffer_insert(pThis, capacity, offset, buf, len); 164 } 165 166 /************************************************************************* 167 * rtl_uStringbuffer_insert_ascii 168 */ 169 void SAL_CALL rtl_uStringbuffer_insert_ascii( /*inout*/rtl_uString ** This, 170 /*inout*/sal_Int32 * capacity, 171 sal_Int32 offset, 172 const sal_Char * str, 173 sal_Int32 len) 174 { 175 sal_Int32 nOldLen; 176 sal_Unicode * pBuf; 177 sal_Int32 n; 178 if( len != 0 ) 179 { 180 if (*capacity < (*This)->length + len) 181 rtl_uStringbuffer_ensureCapacity( This, capacity, (*This)->length + len ); 182 183 nOldLen = (*This)->length; 184 pBuf = (*This)->buffer; 185 186 /* copy the tail */ 187 n = (nOldLen - offset); 188 if( n == 1 ) 189 /* optimized for 1 character */ 190 pBuf[offset + len] = pBuf[offset]; 191 else if( n > 1 ) 192 rtl_moveMemory( pBuf + offset + len, pBuf + offset, n * sizeof(sal_Unicode) ); 193 194 /* insert the new characters */ 195 for( n = 0; n < len; n++ ) 196 { 197 /* Check ASCII range */ 198 OSL_ENSURE( (*str & 0x80) == 0, "Found ASCII char > 127"); 199 200 pBuf[offset + n] = (sal_Unicode)*(str++); 201 } 202 203 (*This)->length = nOldLen + len; 204 pBuf[ nOldLen + len ] = 0; 205 } 206 } 207 208 209