U_CAPI int32_t U_EXPORT2 uidna_toUnicode(const UChar* src, int32_t srcLength, UChar* dest, int32_t destCapacity, int32_t options, UParseError* parseError, UErrorCode* status){ if(status == NULL || U_FAILURE(*status)){ return 0; } if( (src==NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0)){ *status = U_ILLEGAL_ARGUMENT_ERROR; return 0; } UStringPrepProfile* nameprep = usprep_open(NULL, DATA_FILE_NAME, status); if(U_FAILURE(*status)){ return -1; } int32_t retLen = _internal_toUnicode(src, srcLength, dest, destCapacity, options, nameprep, parseError, status); usprep_close(nameprep); return retLen; }
U_CAPI UStringPrepProfile* U_EXPORT2 usprep_openByType(UStringPrepProfileType type, UErrorCode* status) { if(status == NULL || U_FAILURE(*status)){ return NULL; } int32_t index = (int32_t)type; if (index < 0 || index >= UPRV_LENGTHOF(PROFILE_NAMES)) { *status = U_ILLEGAL_ARGUMENT_ERROR; return NULL; } return usprep_open(NULL, PROFILE_NAMES[index], status); }
U_CAPI int32_t U_EXPORT2 uidna_IDNToUnicode( const UChar* src, int32_t srcLength, UChar* dest, int32_t destCapacity, int32_t options, UParseError* parseError, UErrorCode* status){ if(status == NULL || U_FAILURE(*status)){ return 0; } if((src==NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0)){ *status = U_ILLEGAL_ARGUMENT_ERROR; return 0; } int32_t reqLength = 0; UStringPrepProfile* nameprep = usprep_open(NULL, DATA_FILE_NAME, status); if(U_FAILURE(*status)){ return 0; } //initialize pointers UChar *delimiter = (UChar*)src; UChar *labelStart = (UChar*)src; UChar *currentDest = (UChar*) dest; int32_t remainingLen = srcLength; int32_t remainingDestCapacity = destCapacity; int32_t labelLen = 0, labelReqLength = 0; UBool done = FALSE; for(;;){ labelLen = getNextSeparator(labelStart,remainingLen, &delimiter,&done); // The RFC states that // <quote> // ToUnicode never fails. If any step fails, then the original input // is returned immediately in that step. // </quote> // _internal_toUnicode will copy the label. /*if(labelLen==0 && done==FALSE){ *status = U_IDNA_ZERO_LENGTH_LABEL_ERROR; break; }*/ labelReqLength = _internal_toUnicode(labelStart, labelLen, currentDest, remainingDestCapacity, options, nameprep, parseError, status); if(*status == U_BUFFER_OVERFLOW_ERROR){ *status = U_ZERO_ERROR; // reset error remainingDestCapacity = 0; } if(U_FAILURE(*status)){ break; } reqLength +=labelReqLength; // adjust the destination pointer if(labelReqLength < remainingDestCapacity){ currentDest = currentDest + labelReqLength; remainingDestCapacity -= labelReqLength; }else{ // should never occur remainingDestCapacity = 0; } if(done == TRUE){ break; } // add the label separator // Unlike the ToASCII operation we don't normalize the label separators if(remainingDestCapacity > 0){ *currentDest++ = *(labelStart + labelLen); remainingDestCapacity--; } reqLength++; labelStart = delimiter; if(remainingLen >0 ){ remainingLen = (int32_t)(srcLength - (delimiter - src)); } } if(reqLength > MAX_DOMAIN_NAME_LENGTH){ *status = U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR; } usprep_close(nameprep); return u_terminateUChars(dest, destCapacity, reqLength, status); }
U_CAPI int32_t U_EXPORT2 uidna_IDNToASCII( const UChar *src, int32_t srcLength, UChar* dest, int32_t destCapacity, int32_t options, UParseError *parseError, UErrorCode *status){ if(status == NULL || U_FAILURE(*status)){ return 0; } if((src==NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0)){ *status = U_ILLEGAL_ARGUMENT_ERROR; return 0; } int32_t reqLength = 0; UStringPrepProfile* nameprep = usprep_open(NULL, DATA_FILE_NAME, status); if(U_FAILURE(*status)){ return 0; } //initialize pointers UChar *delimiter = (UChar*)src; UChar *labelStart = (UChar*)src; UChar *currentDest = (UChar*) dest; int32_t remainingLen = srcLength; int32_t remainingDestCapacity = destCapacity; int32_t labelLen = 0, labelReqLength = 0; UBool done = FALSE; for(;;){ labelLen = getNextSeparator(labelStart,remainingLen, &delimiter,&done); labelReqLength = 0; if(!(labelLen==0 && done)){// make sure this is not a root label separator. labelReqLength = _internal_toASCII( labelStart, labelLen, currentDest, remainingDestCapacity, options, nameprep, parseError, status); if(*status == U_BUFFER_OVERFLOW_ERROR){ *status = U_ZERO_ERROR; // reset error remainingDestCapacity = 0; } } if(U_FAILURE(*status)){ break; } reqLength +=labelReqLength; // adjust the destination pointer if(labelReqLength < remainingDestCapacity){ currentDest = currentDest + labelReqLength; remainingDestCapacity -= labelReqLength; }else{ // should never occur remainingDestCapacity = 0; } if(done == TRUE){ break; } // add the label separator if(remainingDestCapacity > 0){ *currentDest++ = FULL_STOP; remainingDestCapacity--; } reqLength++; labelStart = delimiter; if(remainingLen >0 ){ remainingLen = (int32_t)(srcLength - (delimiter - src)); } } if(reqLength > MAX_DOMAIN_NAME_LENGTH){ *status = U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR; } usprep_close(nameprep); return u_terminateUChars(dest, destCapacity, reqLength, status); }
extern int testData(TestIDNA& test) { char *basename=NULL; UErrorCode errorCode=U_ZERO_ERROR; char *saveBasename =NULL; profile = usprep_open(NULL, DATA_NAME, &errorCode); if(U_FAILURE(errorCode)){ test.errln("Failed to load IDNA data file. " + UnicodeString(u_errorName(errorCode))); return errorCode; } char* filename = (char*) malloc(strlen(IntlTest::pathToDataDirectory())*1024); //TODO get the srcDir dynamically const char *srcDir=IntlTest::pathToDataDirectory(); idnTrie = &profile->sprepTrie; indexes = profile->indexes; mappingData = profile->mappingData; //initialize pTestIDNA = &test; /* prepare the filename beginning with the source dir */ if(uprv_strchr(srcDir,U_FILE_SEP_CHAR) == NULL){ filename[0] = 0x2E; filename[1] = U_FILE_SEP_CHAR; uprv_strcpy(filename+2,srcDir); }else{ uprv_strcpy(filename, srcDir); } basename=filename+uprv_strlen(filename); if(basename>filename && *(basename-1)!=U_FILE_SEP_CHAR) { *basename++=U_FILE_SEP_CHAR; } /* process unassigned */ basename=filename+uprv_strlen(filename); if(basename>filename && *(basename-1)!=U_FILE_SEP_CHAR) { *basename++=U_FILE_SEP_CHAR; } /* first copy misc directory */ saveBasename = basename; uprv_strcpy(basename,MISC_DIR); basename = basename + uprv_strlen(MISC_DIR); *basename++=U_FILE_SEP_CHAR; /* process unassigned */ uprv_strcpy(basename,fileNames[0]); parseMappings(filename,TRUE, test,&errorCode); if(U_FAILURE(errorCode)) { test.errln( "Could not open file %s for reading \n", filename); return errorCode; } testAllCodepoints(test); usprep_close(profile); pTestIDNA = NULL; free(filename); return errorCode; }