1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)******************************************************************************* 3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Copyright (C) 2001-2010, International Business Machines 5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Corporation and others. All Rights Reserved. 6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)******************************************************************************* 8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* file name: ustr_wcs.c 9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* encoding: US-ASCII 10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* tab size: 8 (not used) 11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* indentation:4 12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* created on: 2004sep07 14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* created by: Markus W. Scherer 15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* u_strToWCS() and u_strFromWCS() functions 17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* moved here from ustrtrns.c for better modularization. 18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/ 19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utypes.h" 21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ustring.h" 22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cstring.h" 23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cwchar.h" 24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cmemory.h" 25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ustr_imp.h" 26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ustr_cnv.h" 27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if defined(U_WCHAR_IS_UTF16) || defined(U_WCHAR_IS_UTF32) || !UCONFIG_NO_CONVERSION 29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define _STACK_BUFFER_CAPACITY 1000 31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define _BUFFER_CAPACITY_MULTIPLIER 2 32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !defined(U_WCHAR_IS_UTF16) && !defined(U_WCHAR_IS_UTF32) 34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static U_INLINE UBool 35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_growAnyBufferFromStatic(void *context, 36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) void **pBuffer, int32_t *pCapacity, int32_t reqCapacity, 37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t length, int32_t size) { 38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) void *newBuffer=uprv_malloc(reqCapacity*size); 40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(newBuffer!=NULL) { 41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(length>0) { 42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_memcpy(newBuffer, *pBuffer, length*size); 43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pCapacity=reqCapacity; 45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pCapacity=0; 47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* release the old pBuffer if it was not statically allocated */ 50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*pBuffer!=(void *)context) { 51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(*pBuffer); 52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pBuffer=newBuffer; 55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return (UBool)(newBuffer!=NULL); 56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* helper function */ 59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static wchar_t* 60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)_strToWCS(wchar_t *dest, 61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t destCapacity, 62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t *pDestLength, 63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *src, 64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t srcLength, 65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode){ 66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char stackBuffer [_STACK_BUFFER_CAPACITY]; 68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char* tempBuf = stackBuffer; 69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t tempBufCapacity = _STACK_BUFFER_CAPACITY; 70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char* tempBufLimit = stackBuffer + tempBufCapacity; 71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UConverter* conv = NULL; 72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char* saveBuf = tempBuf; 73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) wchar_t* intTarget=NULL; 74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t intTargetCapacity=0; 75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int count=0,retVal=0; 76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *pSrcLimit =NULL; 78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *pSrc = src; 79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) conv = u_getDefaultConverter(pErrorCode); 81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*pErrorCode)){ 83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(srcLength == -1){ 87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcLength = u_strlen(pSrc); 88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pSrcLimit = pSrc + srcLength; 91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(;;) { 93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* reset the error state */ 94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode = U_ZERO_ERROR; 95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* convert to chars using default converter */ 97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_fromUnicode(conv,&tempBuf,tempBufLimit,&pSrc,pSrcLimit,NULL,(UBool)(pSrc==pSrcLimit),pErrorCode); 98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) count =(tempBuf - saveBuf); 99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* This should rarely occur */ 101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR){ 102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) tempBuf = saveBuf; 103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* we dont have enough room on the stack grow the buffer */ 105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(!u_growAnyBufferFromStatic(stackBuffer,(void**) &tempBuf, &tempBufCapacity, 106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (_BUFFER_CAPACITY_MULTIPLIER * (srcLength)), count,sizeof(char))){ 107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto cleanup; 108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) saveBuf = tempBuf; 111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) tempBufLimit = tempBuf + tempBufCapacity; 112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) tempBuf = tempBuf + count; 113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*pErrorCode)){ 120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto cleanup; 121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* done with conversion null terminate the char buffer */ 124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(count>=tempBufCapacity){ 125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) tempBuf = saveBuf; 126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* we dont have enough room on the stack grow the buffer */ 127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(!u_growAnyBufferFromStatic(stackBuffer,(void**) &tempBuf, &tempBufCapacity, 128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) tempBufCapacity-count+1, count,sizeof(char))){ 129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto cleanup; 130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) saveBuf = tempBuf; 132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) saveBuf[count]=0; 135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* allocate more space than required 138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * here we assume that every char requires 139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * no more than 2 wchar_ts 140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) intTargetCapacity = (count * _BUFFER_CAPACITY_MULTIPLIER + 1) /*for null termination */; 142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) intTarget = (wchar_t*)uprv_malloc( intTargetCapacity * sizeof(wchar_t) ); 143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(intTarget){ 145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t nulLen = 0; 147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t remaining = intTargetCapacity; 148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) wchar_t* pIntTarget=intTarget; 149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) tempBuf = saveBuf; 150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* now convert the mbs to wcs */ 152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(;;){ 153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* we can call the system API since we are sure that 155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * there is atleast 1 null in the input 156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) retVal = uprv_mbstowcs(pIntTarget,(tempBuf+nulLen),remaining); 158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(retVal==-1){ 160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode = U_INVALID_CHAR_FOUND; 161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else if(retVal== remaining){/* should never occur */ 163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int numWritten = (pIntTarget-intTarget); 164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_growAnyBufferFromStatic(NULL,(void**) &intTarget, 165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) &intTargetCapacity, 166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) intTargetCapacity * _BUFFER_CAPACITY_MULTIPLIER, 167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) numWritten, 168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sizeof(wchar_t)); 169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pIntTarget = intTarget; 170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) remaining=intTargetCapacity; 171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(nulLen!=count){ /*there are embedded nulls*/ 173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pIntTarget+=numWritten; 174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) remaining-=numWritten; 175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else{ 178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t nulVal; 179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /*scan for nulls */ 180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* we donot check for limit since tempBuf is null terminated */ 181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while(tempBuf[nulLen++] != 0){ 182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) nulVal = (nulLen < srcLength) ? 1 : 0; 184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pIntTarget = pIntTarget + retVal+nulVal; 185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) remaining -=(retVal+nulVal); 186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* check if we have reached the source limit*/ 188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(nulLen>=(count)){ 189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) count = (int32_t)(pIntTarget-intTarget); 194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(0 < count && count <= destCapacity){ 196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_memcpy(dest,intTarget,count*sizeof(wchar_t)); 197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(pDestLength){ 200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pDestLength = count; 201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* free the allocated memory */ 204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(intTarget); 205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else{ 207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode = U_MEMORY_ALLOCATION_ERROR; 208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)cleanup: 210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* are we still using stack buffer */ 211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(stackBuffer != saveBuf){ 212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(saveBuf); 213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_terminateWChars(dest,destCapacity,count,pErrorCode); 215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_releaseDefaultConverter(conv); 217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return dest; 219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI wchar_t* U_EXPORT2 223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_strToWCS(wchar_t *dest, 224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t destCapacity, 225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t *pDestLength, 226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *src, 227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t srcLength, 228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode){ 229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* args check */ 231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(pErrorCode==NULL || U_FAILURE(*pErrorCode)){ 232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if( (src==NULL && srcLength!=0) || srcLength < -1 || 236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (destCapacity<0) || (dest == NULL && destCapacity > 0) 237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ) { 238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; 239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifdef U_WCHAR_IS_UTF16 243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* wchar_t is UTF-16 just do a memcpy */ 244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(srcLength == -1){ 245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcLength = u_strlen(src); 246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(0 < srcLength && srcLength <= destCapacity){ 248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_memcpy(dest,src,srcLength*U_SIZEOF_UCHAR); 249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(pDestLength){ 251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pDestLength = srcLength; 252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_terminateUChars(dest,destCapacity,srcLength,pErrorCode); 255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return dest; 257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#elif defined U_WCHAR_IS_UTF32 259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return (wchar_t*)u_strToUTF32((UChar32*)dest, destCapacity, pDestLength, 261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) src, srcLength, pErrorCode); 262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#else 264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return _strToWCS(dest,destCapacity,pDestLength,src,srcLength, pErrorCode); 266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !defined(U_WCHAR_IS_UTF16) && !defined(U_WCHAR_IS_UTF32) 272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* helper function */ 273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UChar* 274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)_strFromWCS( UChar *dest, 275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t destCapacity, 276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t *pDestLength, 277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const wchar_t *src, 278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t srcLength, 279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) 280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t retVal =0, count =0 ; 282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UConverter* conv = NULL; 283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar* pTarget = NULL; 284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar* pTargetLimit = NULL; 285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar* target = NULL; 286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar uStack [_STACK_BUFFER_CAPACITY]; 288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) wchar_t wStack[_STACK_BUFFER_CAPACITY]; 290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) wchar_t* pWStack = wStack; 291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char cStack[_STACK_BUFFER_CAPACITY]; 294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t cStackCap = _STACK_BUFFER_CAPACITY; 295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char* pCSrc=cStack; 296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char* pCSave=pCSrc; 297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char* pCSrcLimit=NULL; 298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const wchar_t* pSrc = src; 300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const wchar_t* pSrcLimit = NULL; 301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(srcLength ==-1){ 303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* if the wchar_t source is null terminated we can safely 304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * assume that there are no embedded nulls, this is a fast 305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * path for null terminated strings. 306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(;;){ 308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* convert wchars to chars */ 309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) retVal = uprv_wcstombs(pCSrc,src, cStackCap); 310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(retVal == -1){ 312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode = U_ILLEGAL_CHAR_FOUND; 313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto cleanup; 314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else if(retVal >= (cStackCap-1)){ 315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Should rarely occur */ 316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_growAnyBufferFromStatic(cStack,(void**)&pCSrc,&cStackCap, 317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cStackCap * _BUFFER_CAPACITY_MULTIPLIER, 0, sizeof(char)); 318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pCSave = pCSrc; 319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else{ 320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* converted every thing */ 321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pCSrc = pCSrc+retVal; 322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else{ 327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* here the source is not null terminated 328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * so it may have nulls embeded and we need to 329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * do some extra processing 330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t remaining =cStackCap; 332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pSrcLimit = src + srcLength; 334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(;;){ 336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) register int32_t nulLen = 0; 337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* find nulls in the string */ 339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while(nulLen<srcLength && pSrc[nulLen++]!=0){ 340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if((pSrc+nulLen) < pSrcLimit){ 343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* check if we have enough room in pCSrc */ 344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(remaining < (nulLen * MB_CUR_MAX)){ 345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* should rarely occur */ 346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t len = (pCSrc-pCSave); 347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pCSrc = pCSave; 348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* we do not have enough room so grow the buffer*/ 349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_growAnyBufferFromStatic(cStack,(void**)&pCSrc,&cStackCap, 350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) _BUFFER_CAPACITY_MULTIPLIER*cStackCap+(nulLen*MB_CUR_MAX),len,sizeof(char)); 351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pCSave = pCSrc; 353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pCSrc = pCSave+len; 354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) remaining = cStackCap-(pCSrc - pCSave); 355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* we have found a null so convert the 358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * chunk from begining of non-null char to null 359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) retVal = uprv_wcstombs(pCSrc,pSrc,remaining); 361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(retVal==-1){ 363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* an error occurred bail out */ 364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode = U_ILLEGAL_CHAR_FOUND; 365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto cleanup; 366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pCSrc += retVal+1 /* already null terminated */; 369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pSrc += nulLen; /* skip past the null */ 371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcLength-=nulLen; /* decrement the srcLength */ 372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) remaining -= (pCSrc-pCSave); 373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else{ 376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* the source is not null terminated and we are 377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * end of source so we copy the source to a temp buffer 378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * null terminate it and convert wchar_ts to chars 379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(nulLen >= _STACK_BUFFER_CAPACITY){ 381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Should rarely occcur */ 382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* allocate new buffer buffer */ 383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pWStack =(wchar_t*) uprv_malloc(sizeof(wchar_t) * (nulLen + 1)); 384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(pWStack==NULL){ 385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode = U_MEMORY_ALLOCATION_ERROR; 386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto cleanup; 387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(nulLen>0){ 390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* copy the contents to tempStack */ 391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_memcpy(pWStack,pSrc,nulLen*sizeof(wchar_t)); 392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* null terminate the tempBuffer */ 395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pWStack[nulLen] =0 ; 396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(remaining < (nulLen * MB_CUR_MAX)){ 398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Should rarely occur */ 399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t len = (pCSrc-pCSave); 400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pCSrc = pCSave; 401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* we do not have enough room so grow the buffer*/ 402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_growAnyBufferFromStatic(cStack,(void**)&pCSrc,&cStackCap, 403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cStackCap+(nulLen*MB_CUR_MAX),len,sizeof(char)); 404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pCSave = pCSrc; 406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pCSrc = pCSave+len; 407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) remaining = cStackCap-(pCSrc - pCSave); 408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* convert to chars */ 410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) retVal = uprv_wcstombs(pCSrc,pWStack,remaining); 411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pCSrc += retVal; 413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pSrc += nulLen; 414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcLength-=nulLen; /* decrement the srcLength */ 415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* OK..now we have converted from wchar_ts to chars now 421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * convert chars to UChars 422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pCSrcLimit = pCSrc; 424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pCSrc = pCSave; 425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pTarget = target= dest; 426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pTargetLimit = dest + destCapacity; 427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) conv= u_getDefaultConverter(pErrorCode); 429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*pErrorCode)|| conv==NULL){ 431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto cleanup; 432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(;;) { 435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode = U_ZERO_ERROR; 437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* convert to stack buffer*/ 439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucnv_toUnicode(conv,&pTarget,pTargetLimit,(const char**)&pCSrc,pCSrcLimit,NULL,(UBool)(pCSrc==pCSrcLimit),pErrorCode); 440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* increment count to number written to stack */ 442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) count+= pTarget - target; 443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR){ 445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) target = uStack; 446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pTarget = uStack; 447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pTargetLimit = uStack + _STACK_BUFFER_CAPACITY; 448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(pDestLength){ 455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pDestLength =count; 456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_terminateUChars(dest,destCapacity,count,pErrorCode); 459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)cleanup: 461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(cStack != pCSave){ 463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(pCSave); 464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(wStack != pWStack){ 467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(pWStack); 468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_releaseDefaultConverter(conv); 471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return dest; 473f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 474f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 475f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 476f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI UChar* U_EXPORT2 477f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_strFromWCS(UChar *dest, 478f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t destCapacity, 479f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t *pDestLength, 480f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const wchar_t *src, 481f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t srcLength, 482f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) 483f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 484f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 485f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* args check */ 486f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(pErrorCode==NULL || U_FAILURE(*pErrorCode)){ 487f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 488f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 489f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 490f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if( (src==NULL && srcLength!=0) || srcLength < -1 || 491f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (destCapacity<0) || (dest == NULL && destCapacity > 0) 492f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ) { 493f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; 494f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 495f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 496f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 497f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifdef U_WCHAR_IS_UTF16 498f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* wchar_t is UTF-16 just do a memcpy */ 499f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(srcLength == -1){ 500f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcLength = u_strlen(src); 501f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 502f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(0 < srcLength && srcLength <= destCapacity){ 503f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_memcpy(dest,src,srcLength*U_SIZEOF_UCHAR); 504f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 505f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(pDestLength){ 506f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pDestLength = srcLength; 507f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 508f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 509f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_terminateUChars(dest,destCapacity,srcLength,pErrorCode); 510f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 511f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return dest; 512f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 513f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#elif defined U_WCHAR_IS_UTF32 514f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 515f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return u_strFromUTF32(dest, destCapacity, pDestLength, 516f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (UChar32*)src, srcLength, pErrorCode); 517f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 518f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#else 519f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 520f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return _strFromWCS(dest,destCapacity,pDestLength,src,srcLength,pErrorCode); 521f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 522f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 523f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 524f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 525f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 526f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif /* #if !defined(U_WCHAR_IS_UTF16) && !defined(U_WCHAR_IS_UTF32) && !UCONFIG_NO_CONVERSION */ 527