/* Improve code coverage of UPropsVectors */ static void TestUPropsVector() { UErrorCode errorCode = U_ILLEGAL_ARGUMENT_ERROR; UPropsVectors *pv = upvec_open(100, &errorCode); if (pv != NULL) { log_err("Should have returned NULL if UErrorCode is an error."); return; } errorCode = U_ZERO_ERROR; pv = upvec_open(-1, &errorCode); if (pv != NULL || U_SUCCESS(errorCode)) { log_err("Should have returned NULL if column is less than 0.\n"); return; } errorCode = U_ZERO_ERROR; pv = upvec_open(100, &errorCode); if (pv == NULL || U_FAILURE(errorCode)) { log_err("Unable to open UPropsVectors.\n"); return; } if (upvec_getValue(pv, 0, 1) != 0) { log_err("upvec_getValue should return 0.\n"); } if (upvec_getRow(pv, 0, NULL, NULL) == NULL) { log_err("upvec_getRow should not return NULL.\n"); } if (upvec_getArray(pv, NULL, NULL) != NULL) { log_err("upvec_getArray should return NULL.\n"); } upvec_close(pv); }
/* open a selector. If converterListSize is 0, build for all converters. If excludedCodePoints is NULL, don't exclude any codepoints */ U_CAPI UConverterSelector* U_EXPORT2 ucnvsel_open(const char* const* converterList, int32_t converterListSize, const USet* excludedCodePoints, const UConverterUnicodeSet whichSet, UErrorCode* status) { // check if already failed if (U_FAILURE(*status)) { return NULL; } // ensure args make sense! if (converterListSize < 0 || (converterList == NULL && converterListSize != 0)) { *status = U_ILLEGAL_ARGUMENT_ERROR; return NULL; } // allocate a new converter LocalUConverterSelectorPointer newSelector( (UConverterSelector*)uprv_malloc(sizeof(UConverterSelector))); if (newSelector.isNull()) { *status = U_MEMORY_ALLOCATION_ERROR; return NULL; } uprv_memset(newSelector.getAlias(), 0, sizeof(UConverterSelector)); if (converterListSize == 0) { converterList = NULL; converterListSize = ucnv_countAvailable(); } newSelector->encodings = (char**)uprv_malloc(converterListSize * sizeof(char*)); if (!newSelector->encodings) { *status = U_MEMORY_ALLOCATION_ERROR; return NULL; } newSelector->encodings[0] = NULL; // now we can call ucnvsel_close() // make a backup copy of the list of converters int32_t totalSize = 0; int32_t i; for (i = 0; i < converterListSize; i++) { totalSize += (int32_t)uprv_strlen(converterList != NULL ? converterList[i] : ucnv_getAvailableName(i)) + 1; } // 4-align the totalSize to 4-align the size of the serialized form int32_t encodingStrPadding = totalSize & 3; if (encodingStrPadding != 0) { encodingStrPadding = 4 - encodingStrPadding; } newSelector->encodingStrLength = totalSize += encodingStrPadding; char* allStrings = (char*) uprv_malloc(totalSize); if (!allStrings) { *status = U_MEMORY_ALLOCATION_ERROR; return NULL; } for (i = 0; i < converterListSize; i++) { newSelector->encodings[i] = allStrings; uprv_strcpy(newSelector->encodings[i], converterList != NULL ? converterList[i] : ucnv_getAvailableName(i)); allStrings += uprv_strlen(newSelector->encodings[i]) + 1; } while (encodingStrPadding > 0) { *allStrings++ = 0; --encodingStrPadding; } newSelector->ownEncodingStrings = TRUE; newSelector->encodingsCount = converterListSize; UPropsVectors *upvec = upvec_open((converterListSize+31)/32, status); generateSelectorData(newSelector.getAlias(), upvec, excludedCodePoints, whichSet, status); upvec_close(upvec); if (U_FAILURE(*status)) { return NULL; } return newSelector.orphan(); }
extern void generateData(const char *dataDir, UBool csource) { static int32_t indexes[UBIDI_IX_TOP]={ UBIDI_IX_TOP }; static uint8_t trieBlock[40000]; static uint8_t jgArray[0x300]; /* at most for U+0600..U+08FF */ const uint32_t *row; UChar32 start, end, prev, jgStart; int32_t i; UNewDataMemory *pData; UNewTrie *pTrie; UErrorCode errorCode=U_ZERO_ERROR; int32_t trieSize; long dataLength; makeMirror(); pTrie=utrie_open(NULL, NULL, 20000, 0, 0, TRUE); if(pTrie==NULL) { fprintf(stderr, "genbidi error: unable to create a UNewTrie\n"); exit(U_MEMORY_ALLOCATION_ERROR); } prev=jgStart=0; for(i=0; (row=upvec_getRow(pv, i, &start, &end))!=NULL && start<UPVEC_FIRST_SPECIAL_CP; ++i) { /* store most values from vector column 0 in the trie */ if(!utrie_setRange32(pTrie, start, end+1, *row, TRUE)) { fprintf(stderr, "genbidi error: unable to set trie value (overflow)\n"); exit(U_BUFFER_OVERFLOW_ERROR); } /* store Joining_Group values from vector column 1 in a simple byte array */ if(row[1]!=0) { if(start<0x600 || 0x8ff<end) { fprintf(stderr, "genbidi error: Joining_Group for out-of-range code points U+%04lx..U+%04lx\n", (long)start, (long)end); exit(U_ILLEGAL_ARGUMENT_ERROR); } if(prev==0) { /* first code point with any value */ prev=jgStart=start; } else { /* add No_Joining_Group for code points between prev and start */ while(prev<start) { jgArray[prev++ -jgStart]=0; } } /* set Joining_Group value for start..end */ while(prev<=end) { jgArray[prev++ -jgStart]=(uint8_t)row[1]; } } } /* finish jgArray, pad to multiple of 4 */ while((prev-jgStart)&3) { jgArray[prev++ -jgStart]=0; } indexes[UBIDI_IX_JG_START]=jgStart; indexes[UBIDI_IX_JG_LIMIT]=prev; trieSize=utrie_serialize(pTrie, trieBlock, sizeof(trieBlock), NULL, TRUE, &errorCode); if(U_FAILURE(errorCode)) { fprintf(stderr, "genbidi error: utrie_serialize failed: %s (length %ld)\n", u_errorName(errorCode), (long)trieSize); exit(errorCode); } indexes[UBIDI_IX_TRIE_SIZE]=trieSize; indexes[UBIDI_IX_MIRROR_LENGTH]=mirrorTop; indexes[UBIDI_IX_LENGTH]= (int32_t)sizeof(indexes)+ trieSize+ 4*mirrorTop+ (prev-jgStart); if(beVerbose) { printf("trie size in bytes: %5d\n", (int)trieSize); printf("size in bytes of mirroring table: %5d\n", (int)(4*mirrorTop)); printf("length of Joining_Group array: %5d (U+%04x..U+%04x)\n", (int)(prev-jgStart), (int)jgStart, (int)(prev-1)); printf("data size: %5d\n", (int)indexes[UBIDI_IX_LENGTH]); } indexes[UBIDI_MAX_VALUES_INDEX]= ((int32_t)U_CHAR_DIRECTION_COUNT-1)| (((int32_t)U_JT_COUNT-1)<<UBIDI_JT_SHIFT)| (((int32_t)U_JG_COUNT-1)<<UBIDI_MAX_JG_SHIFT); if(csource) { /* write .c file for hardcoded data */ UTrie trie={ NULL }; UTrie2 *trie2; FILE *f; utrie_unserialize(&trie, trieBlock, trieSize, &errorCode); if(U_FAILURE(errorCode)) { fprintf( stderr, "genbidi error: failed to utrie_unserialize(ubidi.icu trie) - %s\n", u_errorName(errorCode)); exit(errorCode); } /* use UTrie2 */ dataInfo.formatVersion[0]=2; dataInfo.formatVersion[2]=0; dataInfo.formatVersion[3]=0; trie2=utrie2_fromUTrie(&trie, 0, &errorCode); if(U_FAILURE(errorCode)) { fprintf( stderr, "genbidi error: utrie2_fromUTrie() failed - %s\n", u_errorName(errorCode)); exit(errorCode); } { /* delete lead surrogate code unit values */ UChar lead; trie2=utrie2_cloneAsThawed(trie2, &errorCode); for(lead=0xd800; lead<0xdc00; ++lead) { utrie2_set32ForLeadSurrogateCodeUnit(trie2, lead, trie2->initialValue, &errorCode); } utrie2_freeze(trie2, UTRIE2_16_VALUE_BITS, &errorCode); if(U_FAILURE(errorCode)) { fprintf( stderr, "genbidi error: deleting lead surrogate code unit values failed - %s\n", u_errorName(errorCode)); exit(errorCode); } } f=usrc_create(dataDir, "ubidi_props_data.c"); if(f!=NULL) { usrc_writeArray(f, "static const UVersionInfo ubidi_props_dataVersion={", dataInfo.dataVersion, 8, 4, "};\n\n"); usrc_writeArray(f, "static const int32_t ubidi_props_indexes[UBIDI_IX_TOP]={", indexes, 32, UBIDI_IX_TOP, "};\n\n"); usrc_writeUTrie2Arrays(f, "static const uint16_t ubidi_props_trieIndex[%ld]={\n", NULL, trie2, "\n};\n\n"); usrc_writeArray(f, "static const uint32_t ubidi_props_mirrors[%ld]={\n", mirrors, 32, mirrorTop, "\n};\n\n"); usrc_writeArray(f, "static const uint8_t ubidi_props_jgArray[%ld]={\n", jgArray, 8, prev-jgStart, "\n};\n\n"); fputs( "static const UBiDiProps ubidi_props_singleton={\n" " NULL,\n" " ubidi_props_indexes,\n" " ubidi_props_mirrors,\n" " ubidi_props_jgArray,\n", f); usrc_writeUTrie2Struct(f, " {\n", trie2, "ubidi_props_trieIndex", NULL, " },\n"); usrc_writeArray(f, " { ", dataInfo.formatVersion, 8, 4, " }\n"); fputs("};\n", f); fclose(f); } utrie2_close(trie2); } else { /* write the data */ pData=udata_create(dataDir, UBIDI_DATA_TYPE, UBIDI_DATA_NAME, &dataInfo, haveCopyright ? U_COPYRIGHT_STRING : NULL, &errorCode); if(U_FAILURE(errorCode)) { fprintf(stderr, "genbidi: unable to create data memory, %s\n", u_errorName(errorCode)); exit(errorCode); } udata_writeBlock(pData, indexes, sizeof(indexes)); udata_writeBlock(pData, trieBlock, trieSize); udata_writeBlock(pData, mirrors, 4*mirrorTop); udata_writeBlock(pData, jgArray, prev-jgStart); /* finish up */ dataLength=udata_finish(pData, &errorCode); if(U_FAILURE(errorCode)) { fprintf(stderr, "genbidi: error %d writing the output file\n", errorCode); exit(errorCode); } if(dataLength!=indexes[UBIDI_IX_LENGTH]) { fprintf(stderr, "genbidi: data length %ld != calculated size %d\n", dataLength, (int)indexes[UBIDI_IX_LENGTH]); exit(U_INTERNAL_PROGRAM_ERROR); } } utrie_close(pTrie); upvec_close(pv); }
U_CFUNC void exitAdditionalProperties() { utrie_close(newTrie); upvec_close(pv); }