UChar32* Utf16ToUtf32( UChar const* pwz, int const cch, int& cchResult ) { UChar32* pqzDest = nullptr; int cchDest = 0; cchResult = 0; UErrorCode errorCode = U_ZERO_ERROR; u_strToUTF32( nullptr, 0, &cchDest, pwz, cch, &errorCode ); if ( U_BUFFER_OVERFLOW_ERROR != errorCode && U_STRING_NOT_TERMINATED_WARNING != errorCode ) { debug( L"Utf16ToUtf32: u_strToUTF32 failed, errorCode=%d\n", errorCode ); return nullptr; } int cchDestCapacity = cchDest + 1; pqzDest = new UChar32[cchDestCapacity]; cchDest = 0; errorCode = U_ZERO_ERROR; u_strToUTF32( pqzDest, cchDestCapacity, &cchDest, pwz, cch, &errorCode ); if ( U_ZERO_ERROR != errorCode && U_STRING_NOT_TERMINATED_WARNING != errorCode ) { debug( L"Utf16ToUtf32: u_strToUTF32 failed, errorCode=%d\n", errorCode ); delete[] pqzDest; return nullptr; } cchResult = cchDest; return pqzDest; }
static PyObject* icu_swap_case(PyObject *self, PyObject *input) { PyObject *result = NULL; UErrorCode status = U_ZERO_ERROR; UChar *input_buf = NULL, *output_buf = NULL; UChar32 *buf = NULL; int32_t sz = 0, sz32 = 0, i = 0; input_buf = python_to_icu(input, &sz); if (input_buf == NULL) goto end; output_buf = (UChar*) calloc(3 * sz, sizeof(UChar)); buf = (UChar32*) calloc(2 * sz, sizeof(UChar32)); if (output_buf == NULL || buf == NULL) { PyErr_NoMemory(); goto end; } u_strToUTF32(buf, 2 * sz, &sz32, input_buf, sz, &status); for (i = 0; i < sz32; i++) { if (u_islower(buf[i])) buf[i] = u_toupper(buf[i]); else if (u_isupper(buf[i])) buf[i] = u_tolower(buf[i]); } u_strFromUTF32(output_buf, 3*sz, &sz, buf, sz32, &status); if (U_FAILURE(status)) { PyErr_SetString(PyExc_ValueError, u_errorName(status)); goto end; } result = icu_to_python(output_buf, sz); end: if (input_buf != NULL) free(input_buf); if (output_buf != NULL) free(output_buf); if (buf != NULL) free(buf); return result; } // }}}
U_CAPI wchar_t* U_EXPORT2 u_strToWCS(wchar_t *dest, int32_t destCapacity, int32_t *pDestLength, const UChar *src, int32_t srcLength, UErrorCode *pErrorCode){ /* args check */ if(pErrorCode==NULL || U_FAILURE(*pErrorCode)){ return NULL; } if( (src==NULL && srcLength!=0) || srcLength < -1 || (destCapacity<0) || (dest == NULL && destCapacity > 0) ) { *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; return NULL; } #ifdef U_WCHAR_IS_UTF16 /* wchar_t is UTF-16 just do a memcpy */ if(srcLength == -1){ srcLength = u_strlen(src); } if(0 < srcLength && srcLength <= destCapacity){ uprv_memcpy(dest,src,srcLength*U_SIZEOF_UCHAR); } if(pDestLength){ *pDestLength = srcLength; } u_terminateUChars(dest,destCapacity,srcLength,pErrorCode); return dest; #elif defined U_WCHAR_IS_UTF32 return (wchar_t*)u_strToUTF32((UChar32*)dest, destCapacity, pDestLength, src, srcLength, pErrorCode); #else return _strToWCS(dest,destCapacity,pDestLength,src,srcLength, pErrorCode); #endif }
// wrapper around the reference Punycode implementation static int32_t convertToPuny(const UChar* src, int32_t srcLength, UChar* dest, int32_t destCapacity, UErrorCode& status){ uint32_t b1Stack[MAX_LABEL_BUFFER_SIZE]; int32_t b1Len = 0, b1Capacity = MAX_LABEL_BUFFER_SIZE; uint32_t* b1 = b1Stack; char b2Stack[MAX_LABEL_BUFFER_SIZE]; char* b2 = b2Stack; int32_t b2Len =MAX_LABEL_BUFFER_SIZE ; punycode_status error; unsigned char* caseFlags = NULL; u_strToUTF32((UChar32*)b1,b1Capacity,&b1Len,src,srcLength,&status); if(status == U_BUFFER_OVERFLOW_ERROR){ // redo processing of string /* we do not have enough room so grow the buffer*/ b1 = (uint32_t*) uprv_malloc(b1Len * sizeof(uint32_t)); if(b1==NULL){ status = U_MEMORY_ALLOCATION_ERROR; goto CLEANUP; } status = U_ZERO_ERROR; // reset error u_strToUTF32((UChar32*)b1,b1Len,&b1Len,src,srcLength,&status); } if(U_FAILURE(status)){ goto CLEANUP; } //caseFlags = (unsigned char*) uprv_malloc(b1Len *sizeof(unsigned char)); error = punycode_encode(b1Len,b1,caseFlags, (uint32_t*)&b2Len, b2); status = getError(error); if(status == U_BUFFER_OVERFLOW_ERROR){ /* we do not have enough room so grow the buffer*/ b2 = (char*) uprv_malloc( b2Len * sizeof(char)); if(b2==NULL){ status = U_MEMORY_ALLOCATION_ERROR; goto CLEANUP; } status = U_ZERO_ERROR; // reset error punycode_status error = punycode_encode(b1Len,b1,caseFlags, (uint32_t*)&b2Len, b2); status = getError(error); } if(U_FAILURE(status)){ goto CLEANUP; } if(b2Len < destCapacity){ convertASCIIToUChars(b2,dest,b2Len); }else{ status =U_BUFFER_OVERFLOW_ERROR; } CLEANUP: if(b1Stack != b1){ uprv_free(b1); } if(b2Stack != b2){ uprv_free(b2); } uprv_free(caseFlags); return b2Len; }