U_CAPI char* U_EXPORT2 u_austrncpy(char *s1, const UChar *ucs2, int32_t n) { char *target = s1; UErrorCode err = U_ZERO_ERROR; UConverter *cnv = u_getDefaultConverter(&err); if(U_SUCCESS(err) && cnv != NULL) { ucnv_reset(cnv); ucnv_fromUnicode(cnv, &target, s1+n, &ucs2, ucs2+u_ustrnlen(ucs2, n), NULL, TRUE, &err); ucnv_reset(cnv); /* be good citizens */ u_releaseDefaultConverter(cnv); if(U_FAILURE(err) && (err != U_BUFFER_OVERFLOW_ERROR) ) { *s1 = 0; /* failure */ } if(target < (s1+n)) { /* U_BUFFER_OVERFLOW_ERROR isn't an err, just means no termination will happen. */ *target = 0; /* terminate */ } } else { *s1 = 0; } return s1; }
UChar* ufmt_defaultCPToUnicode(const char *s, int32_t sSize, UChar *target, int32_t tSize) { UChar *alias; UErrorCode status = U_ZERO_ERROR; UConverter *defConverter = u_getDefaultConverter(&status); if(U_FAILURE(status) || defConverter == 0) return 0; if(sSize <= 0) { sSize = uprv_strlen(s) + 1; } /* perform the conversion in one swoop */ if(target != 0) { alias = target; ucnv_toUnicode(defConverter, &alias, alias + tSize, &s, s + sSize - 1, NULL, TRUE, &status); /* add the null terminator */ *alias = 0x0000; } u_releaseDefaultConverter(defConverter); return target; }
U_IO_API STD_OSTREAM & U_EXPORT2 operator<<(STD_OSTREAM& stream, const UnicodeString& str) { if(str.length() > 0) { char buffer[200]; UConverter *converter; UErrorCode errorCode = U_ZERO_ERROR; // use the default converter to convert chunks of text converter = u_getDefaultConverter(&errorCode); if(U_SUCCESS(errorCode)) { const UChar *us = str.getBuffer(); const UChar *uLimit = us + str.length(); char *s, *sLimit = buffer + (sizeof(buffer) - 1); do { errorCode = U_ZERO_ERROR; s = buffer; ucnv_fromUnicode(converter, &s, sLimit, &us, uLimit, 0, FALSE, &errorCode); *s = 0; // write this chunk if(s > buffer) { stream << buffer; } } while(errorCode == U_BUFFER_OVERFLOW_ERROR); u_releaseDefaultConverter(converter); } } /* stream.flush();*/ return stream; }
U_CAPI UResourceBundle * U_EXPORT2 ures_openU(const UChar *myPath, const char *localeID, UErrorCode *status) { char pathBuffer[1024]; int32_t length; char *path = pathBuffer; if(status==NULL || U_FAILURE(*status)) { return NULL; } if(myPath==NULL) { path = NULL; } else { length=u_strlen(myPath); if(length>=sizeof(pathBuffer)) { *status=U_ILLEGAL_ARGUMENT_ERROR; return NULL; } else if(uprv_isInvariantUString(myPath, length)) { /* * the invariant converter is sufficient for package and tree names * and is more efficient */ u_UCharsToChars(myPath, path, length+1); /* length+1 to include the NUL */ } else { #if !UCONFIG_NO_CONVERSION /* use the default converter to support variant-character paths */ UConverter *cnv=u_getDefaultConverter(status); length=ucnv_fromUChars(cnv, path, (int32_t)sizeof(pathBuffer), myPath, length, status); u_releaseDefaultConverter(cnv); if(U_FAILURE(*status)) { return NULL; } if(length>=sizeof(pathBuffer)) { /* not NUL-terminated - path too long */ *status=U_ILLEGAL_ARGUMENT_ERROR; return NULL; } #else /* the default converter is not available */ *status=U_UNSUPPORTED_ERROR; return NULL; #endif } } return ures_open(path, localeID, status); }
U_CAPI char* U_EXPORT2 u_austrcpy(char *s1, const UChar *ucs2 ) { UErrorCode err = U_ZERO_ERROR; UConverter *cnv = u_getDefaultConverter(&err); if(U_SUCCESS(err) && cnv != NULL) { int32_t len = ucnv_fromUChars(cnv, s1, MAX_STRLEN, ucs2, -1, &err); u_releaseDefaultConverter(cnv); s1[len] = 0; } else { *s1 = 0; } return s1; }
U_CAPI UChar* U_EXPORT2 u_uastrcpy(UChar *ucs1, const char *s2 ) { UErrorCode err = U_ZERO_ERROR; UConverter *cnv = u_getDefaultConverter(&err); if(U_SUCCESS(err) && cnv != NULL) { ucnv_toUChars(cnv, ucs1, MAX_STRLEN, s2, (int32_t)uprv_strlen(s2), &err); u_releaseDefaultConverter(cnv); if(U_FAILURE(err)) { *ucs1 = 0; } } else { *ucs1 = 0; } return ucs1; }
/* helper function */ static wchar_t* _strToWCS(wchar_t *dest, int32_t destCapacity, int32_t *pDestLength, const UChar *src, int32_t srcLength, UErrorCode *pErrorCode){ char stackBuffer [_STACK_BUFFER_CAPACITY]; char* tempBuf = stackBuffer; int32_t tempBufCapacity = _STACK_BUFFER_CAPACITY; char* tempBufLimit = stackBuffer + tempBufCapacity; UConverter* conv = NULL; char* saveBuf = tempBuf; wchar_t* intTarget=NULL; int32_t intTargetCapacity=0; int count=0,retVal=0; const UChar *pSrcLimit =NULL; const UChar *pSrc = src; conv = u_getDefaultConverter(pErrorCode); if(U_FAILURE(*pErrorCode)){ return NULL; } if(srcLength == -1){ srcLength = u_strlen(pSrc); } pSrcLimit = pSrc + srcLength; for(;;) { /* reset the error state */ *pErrorCode = U_ZERO_ERROR; /* convert to chars using default converter */ ucnv_fromUnicode(conv,&tempBuf,tempBufLimit,&pSrc,pSrcLimit,NULL,(UBool)(pSrc==pSrcLimit),pErrorCode); count =(tempBuf - saveBuf); /* This should rarely occur */ if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR){ tempBuf = saveBuf; /* we dont have enough room on the stack grow the buffer */ if(!u_growAnyBufferFromStatic(stackBuffer,(void**) &tempBuf, &tempBufCapacity, (_BUFFER_CAPACITY_MULTIPLIER * (srcLength)), count,sizeof(char))){ goto cleanup; } saveBuf = tempBuf; tempBufLimit = tempBuf + tempBufCapacity; tempBuf = tempBuf + count; } else { break; } } if(U_FAILURE(*pErrorCode)){ goto cleanup; } /* done with conversion null terminate the char buffer */ if(count>=tempBufCapacity){ tempBuf = saveBuf; /* we dont have enough room on the stack grow the buffer */ if(!u_growAnyBufferFromStatic(stackBuffer,(void**) &tempBuf, &tempBufCapacity, tempBufCapacity-count+1, count,sizeof(char))){ goto cleanup; } saveBuf = tempBuf; } saveBuf[count]=0; /* allocate more space than required * here we assume that every char requires * no more than 2 wchar_ts */ intTargetCapacity = (count * _BUFFER_CAPACITY_MULTIPLIER + 1) /*for null termination */; intTarget = (wchar_t*)uprv_malloc( intTargetCapacity * sizeof(wchar_t) ); if(intTarget){ int32_t nulLen = 0; int32_t remaining = intTargetCapacity; wchar_t* pIntTarget=intTarget; tempBuf = saveBuf; /* now convert the mbs to wcs */ for(;;){ /* we can call the system API since we are sure that * there is atleast 1 null in the input */ retVal = uprv_mbstowcs(pIntTarget,(tempBuf+nulLen),remaining); if(retVal==-1){ *pErrorCode = U_INVALID_CHAR_FOUND; break; }else if(retVal== remaining){/* should never occur */ int numWritten = (pIntTarget-intTarget); u_growAnyBufferFromStatic(NULL,(void**) &intTarget, &intTargetCapacity, intTargetCapacity * _BUFFER_CAPACITY_MULTIPLIER, numWritten, sizeof(wchar_t)); pIntTarget = intTarget; remaining=intTargetCapacity; if(nulLen!=count){ /*there are embedded nulls*/ pIntTarget+=numWritten; remaining-=numWritten; } }else{ int32_t nulVal; /*scan for nulls */ /* we donot check for limit since tempBuf is null terminated */ while(tempBuf[nulLen++] != 0){ } nulVal = (nulLen < srcLength) ? 1 : 0; pIntTarget = pIntTarget + retVal+nulVal; remaining -=(retVal+nulVal); /* check if we have reached the source limit*/ if(nulLen>=(count)){ break; } } } count = (int32_t)(pIntTarget-intTarget); if(0 < count && count <= destCapacity){ uprv_memcpy(dest,intTarget,count*sizeof(wchar_t)); } if(pDestLength){ *pDestLength = count; } /* free the allocated memory */ uprv_free(intTarget); }else{ *pErrorCode = U_MEMORY_ALLOCATION_ERROR; } cleanup: /* are we still using stack buffer */ if(stackBuffer != saveBuf){ uprv_free(saveBuf); } u_terminateWChars(dest,destCapacity,count,pErrorCode); u_releaseDefaultConverter(conv); return dest; }
/* helper function */ static UChar* _strFromWCS( UChar *dest, int32_t destCapacity, int32_t *pDestLength, const wchar_t *src, int32_t srcLength, UErrorCode *pErrorCode) { int32_t retVal =0, count =0 ; UConverter* conv = NULL; UChar* pTarget = NULL; UChar* pTargetLimit = NULL; UChar* target = NULL; UChar uStack [_STACK_BUFFER_CAPACITY]; wchar_t wStack[_STACK_BUFFER_CAPACITY]; wchar_t* pWStack = wStack; char cStack[_STACK_BUFFER_CAPACITY]; int32_t cStackCap = _STACK_BUFFER_CAPACITY; char* pCSrc=cStack; char* pCSave=pCSrc; char* pCSrcLimit=NULL; const wchar_t* pSrc = src; const wchar_t* pSrcLimit = NULL; if(srcLength ==-1){ /* if the wchar_t source is null terminated we can safely * assume that there are no embedded nulls, this is a fast * path for null terminated strings. */ for(;;){ /* convert wchars to chars */ retVal = uprv_wcstombs(pCSrc,src, cStackCap); if(retVal == -1){ *pErrorCode = U_ILLEGAL_CHAR_FOUND; goto cleanup; }else if(retVal >= (cStackCap-1)){ /* Should rarely occur */ u_growAnyBufferFromStatic(cStack,(void**)&pCSrc,&cStackCap, cStackCap * _BUFFER_CAPACITY_MULTIPLIER, 0, sizeof(char)); pCSave = pCSrc; }else{ /* converted every thing */ pCSrc = pCSrc+retVal; break; } } }else{ /* here the source is not null terminated * so it may have nulls embeded and we need to * do some extra processing */ int32_t remaining =cStackCap; pSrcLimit = src + srcLength; for(;;){ register int32_t nulLen = 0; /* find nulls in the string */ while(nulLen<srcLength && pSrc[nulLen++]!=0){ } if((pSrc+nulLen) < pSrcLimit){ /* check if we have enough room in pCSrc */ if(remaining < (nulLen * MB_CUR_MAX)){ /* should rarely occur */ int32_t len = (pCSrc-pCSave); pCSrc = pCSave; /* we do not have enough room so grow the buffer*/ u_growAnyBufferFromStatic(cStack,(void**)&pCSrc,&cStackCap, _BUFFER_CAPACITY_MULTIPLIER*cStackCap+(nulLen*MB_CUR_MAX),len,sizeof(char)); pCSave = pCSrc; pCSrc = pCSave+len; remaining = cStackCap-(pCSrc - pCSave); } /* we have found a null so convert the * chunk from begining of non-null char to null */ retVal = uprv_wcstombs(pCSrc,pSrc,remaining); if(retVal==-1){ /* an error occurred bail out */ *pErrorCode = U_ILLEGAL_CHAR_FOUND; goto cleanup; } pCSrc += retVal+1 /* already null terminated */; pSrc += nulLen; /* skip past the null */ srcLength-=nulLen; /* decrement the srcLength */ remaining -= (pCSrc-pCSave); }else{ /* the source is not null terminated and we are * end of source so we copy the source to a temp buffer * null terminate it and convert wchar_ts to chars */ if(nulLen >= _STACK_BUFFER_CAPACITY){ /* Should rarely occcur */ /* allocate new buffer buffer */ pWStack =(wchar_t*) uprv_malloc(sizeof(wchar_t) * (nulLen + 1)); if(pWStack==NULL){ *pErrorCode = U_MEMORY_ALLOCATION_ERROR; goto cleanup; } } if(nulLen>0){ /* copy the contents to tempStack */ uprv_memcpy(pWStack,pSrc,nulLen*sizeof(wchar_t)); } /* null terminate the tempBuffer */ pWStack[nulLen] =0 ; if(remaining < (nulLen * MB_CUR_MAX)){ /* Should rarely occur */ int32_t len = (pCSrc-pCSave); pCSrc = pCSave; /* we do not have enough room so grow the buffer*/ u_growAnyBufferFromStatic(cStack,(void**)&pCSrc,&cStackCap, cStackCap+(nulLen*MB_CUR_MAX),len,sizeof(char)); pCSave = pCSrc; pCSrc = pCSave+len; remaining = cStackCap-(pCSrc - pCSave); } /* convert to chars */ retVal = uprv_wcstombs(pCSrc,pWStack,remaining); pCSrc += retVal; pSrc += nulLen; srcLength-=nulLen; /* decrement the srcLength */ break; } } } /* OK..now we have converted from wchar_ts to chars now * convert chars to UChars */ pCSrcLimit = pCSrc; pCSrc = pCSave; pTarget = target= dest; pTargetLimit = dest + destCapacity; conv= u_getDefaultConverter(pErrorCode); if(U_FAILURE(*pErrorCode)|| conv==NULL){ goto cleanup; } for(;;) { *pErrorCode = U_ZERO_ERROR; /* convert to stack buffer*/ ucnv_toUnicode(conv,&pTarget,pTargetLimit,(const char**)&pCSrc,pCSrcLimit,NULL,(UBool)(pCSrc==pCSrcLimit),pErrorCode); /* increment count to number written to stack */ count+= pTarget - target; if(*pErrorCode==U_BUFFER_OVERFLOW_ERROR){ target = uStack; pTarget = uStack; pTargetLimit = uStack + _STACK_BUFFER_CAPACITY; } else { break; } } if(pDestLength){ *pDestLength =count; } u_terminateUChars(dest,destCapacity,count,pErrorCode); cleanup: if(cStack != pCSave){ uprv_free(pCSave); } if(wStack != pWStack){ uprv_free(pWStack); } u_releaseDefaultConverter(conv); return dest; }
static int32_t u_scanf_string_handler(UFILE *input, u_scanf_spec_info *info, ufmt_args *args, const UChar *fmt, int32_t *fmtConsumed, int32_t *argConverted) { const UChar *source; UConverter *conv; char *arg = (char*)(args[0].ptrValue); char *alias = arg; char *limit; UErrorCode status = U_ZERO_ERROR; int32_t count; int32_t skipped = 0; UChar c; UBool isNotEOF = FALSE; /* skip all ws in the input */ if (info->fIsString) { skipped = u_scanf_skip_leading_ws(input, info->fPadChar); } /* get the string one character at a time, truncating to the width */ count = 0; /* open the default converter */ conv = u_getDefaultConverter(&status); if(U_FAILURE(status)) return -1; while( (info->fWidth == -1 || count < info->fWidth) && (isNotEOF = ufile_getch(input, &c)) && (!info->fIsString || (c != info->fPadChar && !u_isWhitespace(c)))) { if (!info->fSkipArg) { /* put the character from the input onto the target */ source = &c; /* Since we do this one character at a time, do it this way. */ if (info->fWidth > 0) { limit = alias + info->fWidth - count; } else { limit = alias + ucnv_getMaxCharSize(conv); } /* convert the character to the default codepage */ ucnv_fromUnicode(conv, &alias, limit, &source, source + 1, NULL, TRUE, &status); if(U_FAILURE(status)) { /* clean up */ u_releaseDefaultConverter(conv); return -1; } } /* increment the count */ ++count; } /* put the final character we read back on the input */ if (!info->fSkipArg) { if ((info->fWidth == -1 || count < info->fWidth) && isNotEOF) u_fungetc(c, input); /* add the terminator */ if (info->fIsString) { *alias = 0x00; } } /* clean up */ u_releaseDefaultConverter(conv); /* we converted 1 arg */ *argConverted = !info->fSkipArg; return count + skipped; }