114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project/* 214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project******************************************************************************* 314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project* 4103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius* Copyright (C) 2001-2012, International Business Machines 514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project* Corporation and others. All Rights Reserved. 614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project* 714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project******************************************************************************* 8103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius* file name: ustr_wcs.cpp 914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project* encoding: US-ASCII 1014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project* tab size: 8 (not used) 1114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project* indentation:4 1214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project* 1314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project* created on: 2004sep07 1414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project* created by: Markus W. Scherer 1514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project* 1614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project* u_strToWCS() and u_strFromWCS() functions 1714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project* moved here from ustrtrns.c for better modularization. 1814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project*/ 1914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 2014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project#include "unicode/utypes.h" 2114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project#include "unicode/ustring.h" 2214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project#include "cstring.h" 2314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project#include "cwchar.h" 2414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project#include "cmemory.h" 2514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project#include "ustr_imp.h" 2614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project#include "ustr_cnv.h" 2714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 2814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project#if defined(U_WCHAR_IS_UTF16) || defined(U_WCHAR_IS_UTF32) || !UCONFIG_NO_CONVERSION 2914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 3014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project#define _STACK_BUFFER_CAPACITY 1000 3114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project#define _BUFFER_CAPACITY_MULTIPLIER 2 3214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 3314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project#if !defined(U_WCHAR_IS_UTF16) && !defined(U_WCHAR_IS_UTF32) 34103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// TODO: We should use CharString for char buffers and UnicodeString for UChar buffers. 35103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// Then we could change this to work only with wchar_t buffers. 36103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic inline UBool 3714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Projectu_growAnyBufferFromStatic(void *context, 3814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project void **pBuffer, int32_t *pCapacity, int32_t reqCapacity, 3914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project int32_t length, int32_t size) { 40103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Use char* not void* to avoid the compiler's strict-aliasing assumptions 41103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // and related warnings. 42103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius char *newBuffer=(char *)uprv_malloc(reqCapacity*size); 4314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(newBuffer!=NULL) { 4414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(length>0) { 4514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project uprv_memcpy(newBuffer, *pBuffer, length*size); 4614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 4714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project *pCapacity=reqCapacity; 4814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } else { 4914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project *pCapacity=0; 5014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 5114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 5214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* release the old pBuffer if it was not statically allocated */ 53103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if(*pBuffer!=(char *)context) { 5414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project uprv_free(*pBuffer); 5514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 5614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 5714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project *pBuffer=newBuffer; 5814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project return (UBool)(newBuffer!=NULL); 5914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project} 6014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 6114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project/* helper function */ 6214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Projectstatic wchar_t* 6314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project_strToWCS(wchar_t *dest, 6414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project int32_t destCapacity, 6514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project int32_t *pDestLength, 6614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project const UChar *src, 6714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project int32_t srcLength, 6814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project UErrorCode *pErrorCode){ 6914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 7014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project char stackBuffer [_STACK_BUFFER_CAPACITY]; 7114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project char* tempBuf = stackBuffer; 7214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project int32_t tempBufCapacity = _STACK_BUFFER_CAPACITY; 7314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project char* tempBufLimit = stackBuffer + tempBufCapacity; 7414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project UConverter* conv = NULL; 7514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project char* saveBuf = tempBuf; 7614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project wchar_t* intTarget=NULL; 7714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project int32_t intTargetCapacity=0; 7814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project int count=0,retVal=0; 7914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 8014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project const UChar *pSrcLimit =NULL; 8114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project const UChar *pSrc = src; 8214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 8314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project conv = u_getDefaultConverter(pErrorCode); 8414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 8514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(U_FAILURE(*pErrorCode)){ 8614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project return NULL; 8714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 8814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 8914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(srcLength == -1){ 9014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project srcLength = u_strlen(pSrc); 9114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 9214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 9314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project pSrcLimit = pSrc + srcLength; 9414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 9514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project for(;;) { 9614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* reset the error state */ 9714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project *pErrorCode = U_ZERO_ERROR; 9814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 9914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* convert to chars using default converter */ 10014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project ucnv_fromUnicode(conv,&tempBuf,tempBufLimit,&pSrc,pSrcLimit,NULL,(UBool)(pSrc==pSrcLimit),pErrorCode); 10114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project count =(tempBuf - saveBuf); 10214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 10314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* This should rarely occur */ 10414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR){ 10514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project tempBuf = saveBuf; 10614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 10714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* we dont have enough room on the stack grow the buffer */ 108103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t newCapacity = 2 * srcLength; 109103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if(newCapacity <= tempBufCapacity) { 110103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius newCapacity = _BUFFER_CAPACITY_MULTIPLIER * tempBufCapacity; 111103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 112103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if(!u_growAnyBufferFromStatic(stackBuffer,(void**) &tempBuf, &tempBufCapacity, 113103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius newCapacity, count, 1)) { 11414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project goto cleanup; 11514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 11614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 11714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project saveBuf = tempBuf; 11814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project tempBufLimit = tempBuf + tempBufCapacity; 11914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project tempBuf = tempBuf + count; 12014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 12114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } else { 12214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project break; 12314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 12414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 12514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 12614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(U_FAILURE(*pErrorCode)){ 12714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project goto cleanup; 12814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 12914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 13014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* done with conversion null terminate the char buffer */ 13114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(count>=tempBufCapacity){ 13214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project tempBuf = saveBuf; 13314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* we dont have enough room on the stack grow the buffer */ 13414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(!u_growAnyBufferFromStatic(stackBuffer,(void**) &tempBuf, &tempBufCapacity, 135103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius count+1, count, 1)) { 13614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project goto cleanup; 13714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 13814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project saveBuf = tempBuf; 13914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 14014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 14114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project saveBuf[count]=0; 14214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 14314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 14414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* allocate more space than required 14514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project * here we assume that every char requires 14614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project * no more than 2 wchar_ts 14714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project */ 14814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project intTargetCapacity = (count * _BUFFER_CAPACITY_MULTIPLIER + 1) /*for null termination */; 14914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project intTarget = (wchar_t*)uprv_malloc( intTargetCapacity * sizeof(wchar_t) ); 15014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 15114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(intTarget){ 15214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 15314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project int32_t nulLen = 0; 15414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project int32_t remaining = intTargetCapacity; 15514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project wchar_t* pIntTarget=intTarget; 15614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project tempBuf = saveBuf; 15714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 15814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* now convert the mbs to wcs */ 15914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project for(;;){ 16014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 16114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* we can call the system API since we are sure that 16214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project * there is atleast 1 null in the input 16314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project */ 16414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project retVal = uprv_mbstowcs(pIntTarget,(tempBuf+nulLen),remaining); 16514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 16614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(retVal==-1){ 16714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project *pErrorCode = U_INVALID_CHAR_FOUND; 16814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project break; 16914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project }else if(retVal== remaining){/* should never occur */ 17014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project int numWritten = (pIntTarget-intTarget); 17114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project u_growAnyBufferFromStatic(NULL,(void**) &intTarget, 17214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project &intTargetCapacity, 17314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project intTargetCapacity * _BUFFER_CAPACITY_MULTIPLIER, 17414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project numWritten, 17514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project sizeof(wchar_t)); 17614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project pIntTarget = intTarget; 17714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project remaining=intTargetCapacity; 17814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 17914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(nulLen!=count){ /*there are embedded nulls*/ 18014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project pIntTarget+=numWritten; 18114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project remaining-=numWritten; 18214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 18314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 18414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project }else{ 18514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project int32_t nulVal; 18614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /*scan for nulls */ 18714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* we donot check for limit since tempBuf is null terminated */ 18814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project while(tempBuf[nulLen++] != 0){ 18914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 19014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project nulVal = (nulLen < srcLength) ? 1 : 0; 19114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project pIntTarget = pIntTarget + retVal+nulVal; 19214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project remaining -=(retVal+nulVal); 19314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 19414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* check if we have reached the source limit*/ 19514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(nulLen>=(count)){ 19614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project break; 19714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 19814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 19914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 20014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project count = (int32_t)(pIntTarget-intTarget); 20114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 20214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(0 < count && count <= destCapacity){ 20314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project uprv_memcpy(dest,intTarget,count*sizeof(wchar_t)); 20414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 20514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 20614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(pDestLength){ 20714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project *pDestLength = count; 20814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 20914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 21014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* free the allocated memory */ 21114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project uprv_free(intTarget); 21214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 21314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project }else{ 21414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project *pErrorCode = U_MEMORY_ALLOCATION_ERROR; 21514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 21614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Projectcleanup: 21714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* are we still using stack buffer */ 21814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(stackBuffer != saveBuf){ 21914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project uprv_free(saveBuf); 22014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 22114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project u_terminateWChars(dest,destCapacity,count,pErrorCode); 22214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 22314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project u_releaseDefaultConverter(conv); 22414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 22514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project return dest; 22614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project} 22714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project#endif 22814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 22914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source ProjectU_CAPI wchar_t* U_EXPORT2 23014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Projectu_strToWCS(wchar_t *dest, 23114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project int32_t destCapacity, 23214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project int32_t *pDestLength, 23314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project const UChar *src, 23414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project int32_t srcLength, 23514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project UErrorCode *pErrorCode){ 23614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 23714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* args check */ 23814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(pErrorCode==NULL || U_FAILURE(*pErrorCode)){ 23914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project return NULL; 24014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 24114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 24250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if( (src==NULL && srcLength!=0) || srcLength < -1 || 24350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (destCapacity<0) || (dest == NULL && destCapacity > 0) 24450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ) { 24514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; 24614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project return NULL; 24714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 24814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 24914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project#ifdef U_WCHAR_IS_UTF16 25014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* wchar_t is UTF-16 just do a memcpy */ 25114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(srcLength == -1){ 25214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project srcLength = u_strlen(src); 25314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 25414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(0 < srcLength && srcLength <= destCapacity){ 25514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project uprv_memcpy(dest,src,srcLength*U_SIZEOF_UCHAR); 25614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 25714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(pDestLength){ 25814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project *pDestLength = srcLength; 25914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 26014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 26114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project u_terminateUChars(dest,destCapacity,srcLength,pErrorCode); 26214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 26314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project return dest; 26414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 26514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project#elif defined U_WCHAR_IS_UTF32 26614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 26714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project return (wchar_t*)u_strToUTF32((UChar32*)dest, destCapacity, pDestLength, 26814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project src, srcLength, pErrorCode); 26914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 27014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project#else 27114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 27214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project return _strToWCS(dest,destCapacity,pDestLength,src,srcLength, pErrorCode); 27314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 27414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project#endif 27514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 27614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project} 27714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 27814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project#if !defined(U_WCHAR_IS_UTF16) && !defined(U_WCHAR_IS_UTF32) 27914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project/* helper function */ 28014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Projectstatic UChar* 28114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project_strFromWCS( UChar *dest, 28214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project int32_t destCapacity, 28314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project int32_t *pDestLength, 28414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project const wchar_t *src, 28514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project int32_t srcLength, 28614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project UErrorCode *pErrorCode) 28714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project{ 28814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project int32_t retVal =0, count =0 ; 28914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project UConverter* conv = NULL; 29014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project UChar* pTarget = NULL; 29114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project UChar* pTargetLimit = NULL; 29214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project UChar* target = NULL; 29314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 29414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project UChar uStack [_STACK_BUFFER_CAPACITY]; 29514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 29614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project wchar_t wStack[_STACK_BUFFER_CAPACITY]; 29714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project wchar_t* pWStack = wStack; 29814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 29914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 30014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project char cStack[_STACK_BUFFER_CAPACITY]; 30114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project int32_t cStackCap = _STACK_BUFFER_CAPACITY; 30214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project char* pCSrc=cStack; 30314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project char* pCSave=pCSrc; 30414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project char* pCSrcLimit=NULL; 30514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 30614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project const wchar_t* pSrc = src; 30714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project const wchar_t* pSrcLimit = NULL; 30814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 30914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(srcLength ==-1){ 31014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* if the wchar_t source is null terminated we can safely 31114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project * assume that there are no embedded nulls, this is a fast 31214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project * path for null terminated strings. 31314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project */ 31414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project for(;;){ 31514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* convert wchars to chars */ 31614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project retVal = uprv_wcstombs(pCSrc,src, cStackCap); 31714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 31814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(retVal == -1){ 31914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project *pErrorCode = U_ILLEGAL_CHAR_FOUND; 32014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project goto cleanup; 32114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project }else if(retVal >= (cStackCap-1)){ 32214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* Should rarely occur */ 32314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project u_growAnyBufferFromStatic(cStack,(void**)&pCSrc,&cStackCap, 32414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project cStackCap * _BUFFER_CAPACITY_MULTIPLIER, 0, sizeof(char)); 32514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project pCSave = pCSrc; 32614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project }else{ 32714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* converted every thing */ 32814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project pCSrc = pCSrc+retVal; 32914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project break; 33014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 33114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 33214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 33314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project }else{ 33414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* here the source is not null terminated 33514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project * so it may have nulls embeded and we need to 33614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project * do some extra processing 33714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project */ 33814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project int32_t remaining =cStackCap; 33914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 34014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project pSrcLimit = src + srcLength; 34114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 34214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project for(;;){ 34314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project register int32_t nulLen = 0; 34414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 34514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* find nulls in the string */ 34614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project while(nulLen<srcLength && pSrc[nulLen++]!=0){ 34714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 34814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 34914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if((pSrc+nulLen) < pSrcLimit){ 35014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* check if we have enough room in pCSrc */ 35114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(remaining < (nulLen * MB_CUR_MAX)){ 35214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* should rarely occur */ 35314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project int32_t len = (pCSrc-pCSave); 35414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project pCSrc = pCSave; 35514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* we do not have enough room so grow the buffer*/ 35614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project u_growAnyBufferFromStatic(cStack,(void**)&pCSrc,&cStackCap, 35714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project _BUFFER_CAPACITY_MULTIPLIER*cStackCap+(nulLen*MB_CUR_MAX),len,sizeof(char)); 35814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 35914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project pCSave = pCSrc; 36014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project pCSrc = pCSave+len; 36114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project remaining = cStackCap-(pCSrc - pCSave); 36214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 36314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 36414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* we have found a null so convert the 36514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project * chunk from begining of non-null char to null 36614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project */ 36714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project retVal = uprv_wcstombs(pCSrc,pSrc,remaining); 36814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 36914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(retVal==-1){ 37014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* an error occurred bail out */ 37114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project *pErrorCode = U_ILLEGAL_CHAR_FOUND; 37214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project goto cleanup; 37314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 37414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 37514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project pCSrc += retVal+1 /* already null terminated */; 37614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 37714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project pSrc += nulLen; /* skip past the null */ 37814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project srcLength-=nulLen; /* decrement the srcLength */ 37914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project remaining -= (pCSrc-pCSave); 38014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 38114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 38214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project }else{ 38314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* the source is not null terminated and we are 38414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project * end of source so we copy the source to a temp buffer 38514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project * null terminate it and convert wchar_ts to chars 38614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project */ 38714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(nulLen >= _STACK_BUFFER_CAPACITY){ 38814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* Should rarely occcur */ 38914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* allocate new buffer buffer */ 39014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project pWStack =(wchar_t*) uprv_malloc(sizeof(wchar_t) * (nulLen + 1)); 39114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(pWStack==NULL){ 39214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project *pErrorCode = U_MEMORY_ALLOCATION_ERROR; 39314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project goto cleanup; 39414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 39514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 39614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(nulLen>0){ 39714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* copy the contents to tempStack */ 39814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project uprv_memcpy(pWStack,pSrc,nulLen*sizeof(wchar_t)); 39914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 40014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 40114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* null terminate the tempBuffer */ 40214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project pWStack[nulLen] =0 ; 40314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 40414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(remaining < (nulLen * MB_CUR_MAX)){ 40514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* Should rarely occur */ 40614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project int32_t len = (pCSrc-pCSave); 40714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project pCSrc = pCSave; 40814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* we do not have enough room so grow the buffer*/ 40914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project u_growAnyBufferFromStatic(cStack,(void**)&pCSrc,&cStackCap, 41014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project cStackCap+(nulLen*MB_CUR_MAX),len,sizeof(char)); 41114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 41214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project pCSave = pCSrc; 41314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project pCSrc = pCSave+len; 41414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project remaining = cStackCap-(pCSrc - pCSave); 41514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 41614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* convert to chars */ 41714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project retVal = uprv_wcstombs(pCSrc,pWStack,remaining); 41814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 41914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project pCSrc += retVal; 42014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project pSrc += nulLen; 42114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project srcLength-=nulLen; /* decrement the srcLength */ 42214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project break; 42314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 42414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 42514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 42614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 42714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* OK..now we have converted from wchar_ts to chars now 42814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project * convert chars to UChars 42914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project */ 43014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project pCSrcLimit = pCSrc; 43114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project pCSrc = pCSave; 43214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project pTarget = target= dest; 43314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project pTargetLimit = dest + destCapacity; 43414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 43514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project conv= u_getDefaultConverter(pErrorCode); 43614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 43714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(U_FAILURE(*pErrorCode)|| conv==NULL){ 43814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project goto cleanup; 43914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 44014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 44114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project for(;;) { 44214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 44314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project *pErrorCode = U_ZERO_ERROR; 44414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 44514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* convert to stack buffer*/ 44614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project ucnv_toUnicode(conv,&pTarget,pTargetLimit,(const char**)&pCSrc,pCSrcLimit,NULL,(UBool)(pCSrc==pCSrcLimit),pErrorCode); 44714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 44814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* increment count to number written to stack */ 44914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project count+= pTarget - target; 45014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 45114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR){ 45214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project target = uStack; 45314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project pTarget = uStack; 45414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project pTargetLimit = uStack + _STACK_BUFFER_CAPACITY; 45514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } else { 45614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project break; 45714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 45814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 45914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 46014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 46114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(pDestLength){ 46214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project *pDestLength =count; 46314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 46414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 46514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project u_terminateUChars(dest,destCapacity,count,pErrorCode); 46614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 46714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Projectcleanup: 46814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 46914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(cStack != pCSave){ 47014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project uprv_free(pCSave); 47114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 47214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 47314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(wStack != pWStack){ 47414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project uprv_free(pWStack); 47514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 47614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 47714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project u_releaseDefaultConverter(conv); 47814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 47914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project return dest; 48014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project} 48114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project#endif 48214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 48314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source ProjectU_CAPI UChar* U_EXPORT2 48414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Projectu_strFromWCS(UChar *dest, 48514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project int32_t destCapacity, 48614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project int32_t *pDestLength, 48714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project const wchar_t *src, 48814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project int32_t srcLength, 48914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project UErrorCode *pErrorCode) 49014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project{ 49114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 49214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* args check */ 49314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(pErrorCode==NULL || U_FAILURE(*pErrorCode)){ 49414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project return NULL; 49514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 49650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 49750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if( (src==NULL && srcLength!=0) || srcLength < -1 || 49850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (destCapacity<0) || (dest == NULL && destCapacity > 0) 49950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ) { 50014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; 50114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project return NULL; 50214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 50314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 50414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project#ifdef U_WCHAR_IS_UTF16 50514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project /* wchar_t is UTF-16 just do a memcpy */ 50614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(srcLength == -1){ 50714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project srcLength = u_strlen(src); 50814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 50914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(0 < srcLength && srcLength <= destCapacity){ 51014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project uprv_memcpy(dest,src,srcLength*U_SIZEOF_UCHAR); 51114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 51214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project if(pDestLength){ 51314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project *pDestLength = srcLength; 51414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project } 51514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 51614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project u_terminateUChars(dest,destCapacity,srcLength,pErrorCode); 51714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 51814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project return dest; 51914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 52014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project#elif defined U_WCHAR_IS_UTF32 52114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 52214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project return u_strFromUTF32(dest, destCapacity, pDestLength, 52314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project (UChar32*)src, srcLength, pErrorCode); 52414a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 52514a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project#else 52614a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 52714a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project return _strFromWCS(dest,destCapacity,pDestLength,src,srcLength,pErrorCode); 52814a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 52914a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project#endif 53014a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 53114a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project} 53214a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project 53314a752ecbd4e9bccfc5fa0a6a5e9ace7747a4cbcThe Android Open Source Project#endif /* #if !defined(U_WCHAR_IS_UTF16) && !defined(U_WCHAR_IS_UTF32) && !UCONFIG_NO_CONVERSION */ 534