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/diagnose.h> 29 #include <osl/interlck.h> 30 31 #include <rtl/byteseq.h> 32 #include <rtl/alloc.h> 33 #include <rtl/memory.h> 34 35 /* static data to be referenced by all empty strings 36 * the refCount is predefined to 1 and must never become 0 ! 37 */ 38 static sal_Sequence aEmpty_rtl_ByteSeq = 39 { 40 1, /* sal_Int32 refCount; */ 41 0, /* sal_Int32 length; */ 42 { 0 } /* sal_Unicode buffer[1]; */ 43 }; 44 45 //================================================================================================== 46 void SAL_CALL rtl_byte_sequence_reference2One( 47 sal_Sequence ** ppSequence ) 48 { 49 sal_Sequence * pSequence, * pNew; 50 sal_Int32 nElements; 51 52 OSL_ENSURE( ppSequence, "### null ptr!" ); 53 pSequence = *ppSequence; 54 55 if (pSequence->nRefCount > 1) 56 { 57 nElements = pSequence->nElements; 58 if (nElements) 59 { 60 pNew = (sal_Sequence *)rtl_allocateMemory( SAL_SEQUENCE_HEADER_SIZE + nElements ); 61 62 if ( pNew != 0 ) 63 rtl_copyMemory( pNew->elements, pSequence->elements, nElements ); 64 65 if (! osl_decrementInterlockedCount( &pSequence->nRefCount )) 66 rtl_freeMemory( pSequence ); 67 } 68 else 69 { 70 pNew = (sal_Sequence *)rtl_allocateMemory( SAL_SEQUENCE_HEADER_SIZE ); 71 } 72 73 if ( pNew != 0 ) 74 { 75 pNew->nRefCount = 1; 76 pNew->nElements = nElements; 77 } 78 79 *ppSequence = pNew; 80 } 81 } 82 83 //================================================================================================== 84 void SAL_CALL rtl_byte_sequence_realloc( 85 sal_Sequence ** ppSequence, sal_Int32 nSize ) 86 { 87 sal_Sequence * pSequence, * pNew; 88 sal_Int32 nElements; 89 90 OSL_ENSURE( ppSequence, "### null ptr!" ); 91 pSequence = *ppSequence; 92 nElements = pSequence->nElements; 93 94 if (nElements == nSize) 95 return; 96 97 if (pSequence->nRefCount > 1) // split 98 { 99 pNew = (sal_Sequence *)rtl_allocateMemory( SAL_SEQUENCE_HEADER_SIZE + nSize ); 100 101 if ( pNew != 0 ) 102 { 103 if (nSize > nElements) 104 { 105 rtl_copyMemory( pNew->elements, pSequence->elements, nElements ); 106 rtl_zeroMemory( pNew->elements + nElements, nSize - nElements ); 107 } 108 else 109 { 110 rtl_copyMemory( pNew->elements, pSequence->elements, nSize ); 111 } 112 } 113 114 if (! osl_decrementInterlockedCount( &pSequence->nRefCount )) 115 rtl_freeMemory( pSequence ); 116 pSequence = pNew; 117 } 118 else 119 { 120 pSequence = (sal_Sequence *)rtl_reallocateMemory( 121 pSequence, SAL_SEQUENCE_HEADER_SIZE + nSize ); 122 } 123 124 if ( pSequence != 0 ) 125 { 126 pSequence->nRefCount = 1; 127 pSequence->nElements = nSize; 128 } 129 130 *ppSequence = pSequence; 131 } 132 133 //================================================================================================== 134 void SAL_CALL rtl_byte_sequence_acquire( sal_Sequence *pSequence ) 135 { 136 OSL_ASSERT( pSequence ); 137 osl_incrementInterlockedCount( &(pSequence->nRefCount) ); 138 } 139 140 //================================================================================================== 141 void SAL_CALL rtl_byte_sequence_release( sal_Sequence *pSequence ) 142 { 143 if ( pSequence != 0 ) 144 { 145 if (! osl_decrementInterlockedCount( &(pSequence->nRefCount )) ) 146 { 147 rtl_freeMemory( pSequence ); 148 } 149 } 150 } 151 152 //================================================================================================== 153 void SAL_CALL rtl_byte_sequence_construct( sal_Sequence **ppSequence , sal_Int32 nLength ) 154 { 155 OSL_ASSERT( ppSequence ); 156 if( *ppSequence ) 157 { 158 rtl_byte_sequence_release( *ppSequence ); 159 *ppSequence = 0; 160 } 161 162 if( nLength ) 163 { 164 *ppSequence = (sal_Sequence *) rtl_allocateZeroMemory( SAL_SEQUENCE_HEADER_SIZE + nLength ); 165 166 if ( *ppSequence != 0 ) 167 { 168 (*ppSequence)->nRefCount = 1; 169 (*ppSequence)->nElements = nLength; 170 } 171 } 172 else 173 { 174 *ppSequence = &aEmpty_rtl_ByteSeq; 175 rtl_byte_sequence_acquire( *ppSequence ); 176 } 177 } 178 179 //================================================================================================== 180 void SAL_CALL rtl_byte_sequence_constructNoDefault( sal_Sequence **ppSequence , sal_Int32 nLength ) 181 { 182 OSL_ASSERT( ppSequence ); 183 if( *ppSequence ) 184 { 185 rtl_byte_sequence_release( *ppSequence ); 186 *ppSequence = 0; 187 } 188 189 *ppSequence = (sal_Sequence *) rtl_allocateMemory( SAL_SEQUENCE_HEADER_SIZE + nLength ); 190 191 if ( *ppSequence != 0 ) 192 { 193 (*ppSequence)->nRefCount = 1; 194 (*ppSequence)->nElements = nLength; 195 } 196 } 197 198 //================================================================================================== 199 void SAL_CALL rtl_byte_sequence_constructFromArray( 200 sal_Sequence **ppSequence, const sal_Int8 *pData , sal_Int32 nLength ) 201 { 202 rtl_byte_sequence_constructNoDefault( ppSequence , nLength ); 203 if ( *ppSequence != 0 ) 204 rtl_copyMemory( (*ppSequence)->elements, pData, nLength ); 205 } 206 207 //================================================================================================== 208 void SAL_CALL rtl_byte_sequence_assign( sal_Sequence **ppSequence , sal_Sequence *pSequence ) 209 { 210 if ( *ppSequence != pSequence) 211 { 212 if( *ppSequence ) 213 { 214 rtl_byte_sequence_release( *ppSequence ); 215 } 216 *ppSequence = pSequence; 217 rtl_byte_sequence_acquire( *ppSequence ); 218 } 219 // else 220 // nothing to do 221 222 } 223 224 //================================================================================================== 225 sal_Bool SAL_CALL rtl_byte_sequence_equals( sal_Sequence *pSequence1 , sal_Sequence *pSequence2 ) 226 { 227 OSL_ASSERT( pSequence1 ); 228 OSL_ASSERT( pSequence2 ); 229 if (pSequence1 == pSequence2) 230 { 231 return sal_True; 232 } 233 if (pSequence1->nElements != pSequence2->nElements) 234 { 235 return sal_False; 236 } 237 return (sal_Bool) 238 (rtl_compareMemory( 239 pSequence1->elements, pSequence2->elements, pSequence1->nElements ) 240 == 0); 241 } 242 243 244 //================================================================================================== 245 const sal_Int8 *SAL_CALL rtl_byte_sequence_getConstArray( sal_Sequence *pSequence ) 246 { 247 return ((const sal_Int8*)(pSequence->elements)); 248 } 249 250 //================================================================================================== 251 sal_Int32 SAL_CALL rtl_byte_sequence_getLength( sal_Sequence *pSequence ) 252 { 253 return pSequence->nElements; 254 } 255