/******************************************************************** * COPYRIGHT: * Copyright (c) 1997-1999, International Business Machines Corporation and * others. All Rights Reserved. ********************************************************************/ /******************************************************************************** * * File CU_CAPITST.C * * Modification History: * Name Description * Madhu Katragadda Ported for C API ********************************************************************************* */ #include #include #include #include #include "ccapitst.h" #include "unicode/uloc.h" #include "unicode/ucnv.h" #include "unicode/ucnv_err.h" #include "cintltst.h" #include "unicode/utypes.h" #include "unicode/ustring.h" #include "cstring.h" #include "cmemory.h" #define NUM_CODEPAGE 1 #define MAX_FILE_LEN 1024*20 #define UCS_FILE_NAME_SIZE 100 /* default codepage name for ucnv_getDefaultName() testing */ #ifdef WIN32 /* this assumes a Western European Windows */ # define DEFAULT_CODEPAGE "IBM-1252" #elif defined(OS390) # define DEFAULT_CODEPAGE "ibm-1047-s390" #elif defined(OS400) # define DEFAULT_CODEPAGE "ibm-37" #else # define DEFAULT_CODEPAGE "LATIN_1" #endif /*writes and entire UChar* (string) along with a BOM to a file*/ void WriteToFile(const UChar *a, FILE *myfile); /*Case insensitive compare*/ int32_t strCaseIcmp(const char* a1,const char * a2); /*returns an action other than the one provided*/ UConverterFromUCallback otherUnicodeAction(UConverterFromUCallback MIA); UConverterToUCallback otherCharAction(UConverterToUCallback MIA); void addTestConvert(TestNode** root) { addTest(root, &TestConvert, "tsconv/ccapitst/TestConvert"); } void TestConvert() { char myptr[4]; char save[4]; char subchar [4] = {(char)0xBE, (char)0xEF}; int32_t testLong1 = 0; int16_t rest = 0; FILE* f = NULL; FILE* f2 = NULL; int32_t uniLen = 0; int32_t len = 0; int32_t x = 0; FILE* ucs_file_in = NULL; UChar BOM = 0x0000; UChar myUChar = 0x0000; char myChar = 0x00; char mytarget[MAX_FILE_LEN]; char* mytarget_1=mytarget; char* mytarget_use = mytarget; UChar* consumedUni = NULL; char* consumedChar = NULL; char* consumed = NULL; char output_cp_buffer [MAX_FILE_LEN]; UChar ucs_file_buffer [MAX_FILE_LEN]; UChar* ucs_file_buffer_use = ucs_file_buffer; UChar my_ucs_file_buffer [MAX_FILE_LEN]; UChar* my_ucs_file_buffer_1=my_ucs_file_buffer; int32_t i = 0; int8_t ii = 0; uint16_t ij = 0; int32_t j = 0; int32_t k = 0; uint16_t codepage_index = 0; uint16_t count; int32_t cp = 0; UErrorCode err = U_ZERO_ERROR; const char* available_conv; char ucs_file_name[UCS_FILE_NAME_SIZE]; UConverterFromUCallback MIA1; UConverterToUCallback MIA2; UChar myUnitarget[MAX_FILE_LEN]; UChar *myUnitarget_1 = myUnitarget; UConverter* someConverters[5]; UConverter* myConverter = 0; UChar* displayname = 0; const char* locale; UChar* uchar1 = 0; UChar* uchar2 = 0; UChar* uchar3 = 0; int32_t targetcapacity2; int32_t targetcapacity; int32_t targetsize; int32_t disnamelen; const UChar* tmp_ucs_buf; const UChar* tmp_consumedUni=NULL; const char* tmp_mytarget_use; const char* tmp_consumed; /****************************************************************** Checking Unicode -> ksc ******************************************************************/ const char* CodePagesToTest[NUM_CODEPAGE] = { "IBM-949" }; const uint16_t CodePageNumberToTest[NUM_CODEPAGE] = { 949 }; const int32_t CodePagesAsciiControls[NUM_CODEPAGE] = { 0xFFFFFFFF }; const int32_t CodePagesOtherControls[NUM_CODEPAGE] = { 0x00000005 }; const int8_t CodePagesMinChars[NUM_CODEPAGE] = { 1 }; const int8_t CodePagesMaxChars[NUM_CODEPAGE] = { 2 }; const int16_t CodePagesSubstitutionChars[NUM_CODEPAGE] = { (int16_t)0xAFFE }; const char* CodePagesTestFiles[NUM_CODEPAGE] = { "uni-text.txt" }; const UConverterPlatform CodePagesPlatform[NUM_CODEPAGE] = { UCNV_IBM }; const UConverterToUCallback CodePagesMissingCharAction[NUM_CODEPAGE] = { UCNV_TO_U_CALLBACK_SUBSTITUTE }; const UConverterFromUCallback CodePagesMissingUnicodeAction[NUM_CODEPAGE] = { UCNV_FROM_U_CALLBACK_SUBSTITUTE }; const char* CodePagesLocale[NUM_CODEPAGE] = { "ko_KR" }; UChar CodePagesFlakySequence[NUM_CODEPAGE][20] = { {(UChar)0xAC10,(UChar)0xAC11, (UChar)0xAC12, (UChar)0xAC13 , (UChar)0xAC14, (UChar)0xAC15, (UChar)0xAC16, (UChar)0xAC17, (UChar)0xd7a4 /*Offensive Codepoint*/, (UChar)0xAC14, (UChar)0xAC15} }; char CodePagesFlakyCharSequence[NUM_CODEPAGE][20] = { { (char)0xB0, (char)0xA8, (char)0xB0, (char)0xA9, (char)0xB0, (char)0xAA, (char)0xB0, (char)0xAB, (char)0xb0, (char)0xff,/*Offensive Codepoint*/ (char)0xB0, (char)0xAC, (char)0xB0, (char)0xAD } }; /* flush the converter cache to get a consistent state before the flushing is tested */ ucnv_flushCache(); /*Calling all the UnicodeConverterCPP API and checking functionality*/ /*Tests ucnv_getAvailableName(), getAvialableCount()*/ log_verbose("Testing ucnv_countAvailable()..."); testLong1=ucnv_countAvailable(); log_verbose("Number of available Codepages: %d\n", testLong1); log_verbose("\n---Testing ucnv_getAvailableName.."); /*need to check this out */ available_conv = ucnv_getAvailableName(testLong1); /* Test ucnv_countAliases() etc. */ count = ucnv_countAliases("utf-8", &err); if(U_FAILURE(err)) { log_err("FAILURE! ucnv_countAliases(\"utf-8\") -> %s\n", myErrorName(err)); } else if(count <= 0) { log_err("FAILURE! ucnv_countAliases(\"utf-8\") -> %d aliases\n", count); } else { /* try to get the aliases individually */ const char *alias; alias = ucnv_getAlias("utf-8", 0, &err); if(U_FAILURE(err)) { log_err("FAILURE! ucnv_getAlias(\"utf-8\", 0) -> %s\n", myErrorName(err)); } else if(uprv_strcmp("UTF8", alias) != 0) { log_err("FAILURE! ucnv_getAlias(\"utf-8\", 0) -> %s instead of UTF8\n", alias); } else { uint16_t i; for(i = 0; i < count; ++i) { alias = ucnv_getAlias("utf-8", i, &err); if(U_FAILURE(err)) { log_err("FAILURE! ucnv_getAlias(\"utf-8\", %d) -> %s\n", i, myErrorName(err)); } else if(uprv_strlen(alias) > 20) { /* sanity check */ log_err("FAILURE! ucnv_getAlias(\"utf-8\", %d) -> alias %s insanely long, corrupt?!\n", i, alias); } else { log_verbose("alias %d for utf-8: %s\n", i, alias); } } if(U_SUCCESS(err)) { /* try to fill an array with all aliases */ const char **aliases; aliases=(const char **)uprv_malloc(count * sizeof(const char *)); if(aliases != 0) { ucnv_getAliases("utf-8", aliases, &err); if(U_FAILURE(err)) { log_err("FAILURE! ucnv_getAliases(\"utf-8\") -> %s\n", myErrorName(err)); } else { for(i = 0; i < count; ++i) { /* compare the pointers with the ones returned individually */ alias = ucnv_getAlias("utf-8", i, &err); if(U_FAILURE(err)) { log_err("FAILURE! ucnv_getAlias(\"utf-8\", %d) -> %s\n", i, myErrorName(err)); } else if(aliases[i] != alias) { log_err("FAILURE! ucnv_getAliases(\"utf-8\")[%d] != ucnv_getAlias(\"utf-8\", %d)\n", i, i); } } } uprv_free((char **)aliases); } } } } /*Testing ucnv_open()*/ someConverters[0] = ucnv_open("ibm-949", &err); if (U_FAILURE(err)) { log_err("FAILURE! %s\n", myErrorName(err)); } someConverters[1] = ucnv_open("ibm-949", &err); if (U_FAILURE(err)) { log_err("FAILURE! %s\n", myErrorName(err)); } someConverters[2] = ucnv_open("ibm-949", &err); if (U_FAILURE(err)) { log_err("FAILURE! %s\n", myErrorName(err)); } someConverters[3] = ucnv_open("ibm-834", &err); if (U_FAILURE(err)) { log_err("FAILURE! %s\n", myErrorName(err)); } someConverters[4] = ucnv_open("ibm-943", &err); if (U_FAILURE(err)) { log_err("FAILURE! %s\n", myErrorName(err));} /* Testing ucnv_flushCache() */ log_verbose("\n---Testing ucnv_flushCache...\n"); if (ucnv_flushCache()==0) log_verbose("Flush cache ok\n"); else log_err("Flush Cache failed\n"); /*testing ucnv_close() and ucnv_flushCache() */ ucnv_close(someConverters[0]); ucnv_close(someConverters[1]); ucnv_close(someConverters[2]); ucnv_close(someConverters[3]); if (j=ucnv_flushCache()==2) log_verbose("Flush cache ok\n"); /*because first, second and third are same */ else log_err("Flush Cache failed or there is an error in ucnv_close()\n"); ucnv_close(someConverters[4]); if (ucnv_flushCache()==1) log_verbose("Flush cache ok\n"); else log_err("Flush Cache failed\n"); /* Testing ucnv_openCCSID(), ucnv_open(), ucnv_getName() */ log_verbose("\n---Testing ucnv_open default...\n"); someConverters[0] = ucnv_open(NULL,&err); someConverters[1] = ucnv_open(NULL,&err); someConverters[2] = ucnv_open("utf8", &err); someConverters[3] = ucnv_openCCSID(949,UCNV_IBM,&err); ucnv_close(ucnv_openCCSID(1051, UCNV_IBM, &err)); /* test for j350; ucnv_close(NULL) is safe */ if (U_FAILURE(err)){ log_err("FAILURE! %s\n", myErrorName(err));} /* Testing ucnv_getName()*/ /*default code page */ if ((uprv_stricmp(ucnv_getName(someConverters[0], &err), DEFAULT_CODEPAGE)==0)&& (uprv_stricmp(ucnv_getName(someConverters[1], &err), DEFAULT_CODEPAGE)==0)) log_verbose("getName ok\n"); else log_err("getName failed\n"); /*Testing ucnv_getDefaultName() and ucnv_setDefaultNAme()*/ if(uprv_stricmp(ucnv_getDefaultName(), DEFAULT_CODEPAGE)==0) log_verbose("getDefaultName o.k.\n"); else log_err("getDefaultName failed \n"); /*change the default name by setting it */ ucnv_setDefaultName("changed"); if(strcmp(ucnv_getDefaultName(), "changed")==0) log_verbose("setDefaultName o.k"); else log_err("setDefaultName failed"); /*set it back to the original name */ ucnv_setDefaultName(DEFAULT_CODEPAGE); ucnv_close(someConverters[0]); ucnv_close(someConverters[1]); ucnv_close(someConverters[2]); ucnv_close(someConverters[3]); for (codepage_index=0; codepage_index < NUM_CODEPAGE; ++codepage_index) { i = 0; strcpy(ucs_file_name, ctest_getTestDirectory()); strcat(ucs_file_name, CodePagesTestFiles[codepage_index]); ucs_file_in = fopen(ucs_file_name,"rb"); if (!ucs_file_in) { log_err("Couldn't open the Unicode file [%s]... Exiting...\n", ucs_file_name); exit(0); } /*Creates a converter and testing ucnv_openCCSID(u_int code_page, platform, errstatus*/ /* myConverter =ucnv_openCCSID(CodePageNumberToTest[codepage_index],UCNV_IBM, &err); */ /* ucnv_flushCache(); */ myConverter =ucnv_open( "ibm-949", &err); if (!myConverter || U_FAILURE(err)) { log_err("Error creating the convertor \n"); exit(0); } /*testing for ucnv_getName() */ log_verbose("Testing ucnv_getName()...\n"); ucnv_getName(myConverter, &err); if(U_FAILURE(err)) log_err("Error in getName\n"); else { log_verbose("getName o.k. %s\n", ucnv_getName(myConverter, &err)); } if (strCaseIcmp(ucnv_getName(myConverter, &err), CodePagesToTest[codepage_index])) log_err("getName failed\n"); else log_verbose("getName ok\n"); /*Tests ucnv_getMaxCharSize() and ucnv_getMinCharSize()*/ log_verbose("Testing ucnv_getMaxCharSize()...\n"); if (ucnv_getMaxCharSize(myConverter)==CodePagesMaxChars[codepage_index]) log_verbose("Max byte per character OK\n"); else log_err("Max byte per character failed\n"); log_verbose("\n---Testing ucnv_getMinCharSize()...\n"); if (ucnv_getMinCharSize(myConverter)==CodePagesMinChars[codepage_index]) log_verbose("Min byte per character OK\n"); else log_err("Min byte per character failed\n"); /*Testing for ucnv_getSubstChars() and ucnv_setSubstChars()*/ log_verbose("\n---Testing ucnv_getSubstChars...\n"); ii=4; ucnv_getSubstChars(myConverter, myptr, &ii, &err); for(x=0;x> 8) | (myUChar << 8)); /*adjust if BIG_ENDIAN*/ } myUChar = ucs_file_buffer[i-1]; ucs_file_buffer[i-1] = (BOM==0xFEFF)?myUChar:((myUChar >> 8) | (myUChar << 8)); /*adjust if BIG_ENDIAN Corner Case*/ /*testing ucnv_fromUChars() and ucnv_toUChars() */ /*uchar1---fromUChar--->output_cp_buffer --toUChar--->uchar2*/ uchar1=(UChar*)malloc(sizeof(UChar) * (u_strlen(ucs_file_buffer)+1)); u_uastrcpy(uchar1,""); u_strncpy(uchar1,ucs_file_buffer,i); uchar3=(UChar*)malloc(sizeof(UChar)*(u_strlen(ucs_file_buffer)+1)); u_uastrcpy(uchar3,""); u_strncpy(uchar3,ucs_file_buffer,i); /*Calls the Conversion Routine */ testLong1 = MAX_FILE_LEN; log_verbose("\n---Testing ucnv_fromUChars()\n"); targetcapacity = ucnv_fromUChars(myConverter, output_cp_buffer, testLong1, uchar1, -1, &err); if (U_FAILURE(err)) { log_err("\nFAILURE...%s\n", myErrorName(err)); } else log_verbose(" ucnv_fromUChars() o.k.\n"); /*the codepage intermediate buffer should be null terminated */ output_cp_buffer[targetcapacity]='\0'; /*test the conversion routine */ log_verbose("\n---Testing ucnv_toUChars()\n"); /*call it first time for trapping the targetcapacity and size needed to allocate memory for the buffer uchar2 */ targetcapacity2=0; targetsize = ucnv_toUChars(myConverter, NULL, targetcapacity2, output_cp_buffer, strlen(output_cp_buffer), &err); /*if there is an buffer overflow then trap the values and pass them and make the actual call*/ if(err==U_BUFFER_OVERFLOW_ERROR) { err=U_ZERO_ERROR; uchar2=(UChar*)malloc((targetsize) * sizeof(UChar)); targetsize = ucnv_toUChars(myConverter, uchar2, targetsize, output_cp_buffer, strlen(output_cp_buffer), &err); if(U_FAILURE(err)) log_err("ucnv_toUChars() FAILED %s\n", myErrorName(err)); else log_verbose(" ucnv_toUChars() o.k.\n"); if(u_strcmp(uchar1,uchar2)!=0) log_err("equality test failed with convertion routine\n"); } else { log_err("ERR: calling toUChars: Didn't get U_BUFFER_OVERFLOW .. expected it.\n"); } /*testing for ucnv_fromUnicode() and ucnv_toUnicode() */ /*Clean up re-usable vars*/ j=0; log_verbose("Testing ucnv_fromUnicode().....\n"); tmp_ucs_buf=ucs_file_buffer_use; ucnv_fromUnicode(myConverter, &mytarget_1, mytarget + MAX_FILE_LEN, &tmp_ucs_buf, ucs_file_buffer_use+i, NULL, TRUE, &err); consumedUni = (UChar*)tmp_consumedUni; if (U_FAILURE(err)) { log_err("FAILURE! %s\n", myErrorName(err)); } else log_verbose("ucnv_fromUnicode() o.k.\n"); /*Uni1 ----ToUnicode----> Cp2 ----FromUnicode---->Uni3 */ log_verbose("Testing ucnv_toUnicode().....\n"); tmp_mytarget_use=mytarget_use; tmp_consumed = consumed; ucnv_toUnicode(myConverter, &my_ucs_file_buffer_1, my_ucs_file_buffer + MAX_FILE_LEN, &tmp_mytarget_use, mytarget_use+strlen((char*)mytarget_use), NULL, FALSE, &err); consumed = (char*)tmp_consumed; if (U_FAILURE(err)) { log_err("FAILURE! %s\n", myErrorName(err)); } else log_verbose("ucnv_toUnicode() o.k.\n"); log_verbose("\n---Testing RoundTrip ...\n"); u_strncpy(uchar3, my_ucs_file_buffer,i); if(u_strcmp(uchar1,uchar3)==0) log_verbose("Equality test o.k.\n"); else log_err("Equality test failed\n"); /*sanity compare */ if(uchar2 == NULL) { log_err("uchar2 was NULL (ccapitst.c line %d), couldn't do sanity check\n", __LINE__); } else { if(u_strcmp(uchar2, uchar3)==0) log_verbose("Equality test o.k.\n"); else log_err("Equality test failed\n"); } fclose(ucs_file_in); ucnv_close(myConverter); free(displayname); if (uchar1 != 0) free(uchar1); if (uchar2 != 0) free(uchar2); if (uchar3 != 0) free(uchar3); } } void WriteToFile(const UChar *a, FILE *myfile) { uint32_t size = u_strlen(a); uint16_t i = 0; UChar b = 0xFEFF; /*Writes the BOM*/ fwrite(&b, sizeof(UChar), 1, myfile); for (i=0; i< size; i++) { b = a[i]; fwrite(&b, sizeof(UChar), 1, myfile); } return; } int32_t strCaseIcmp(const char* a1, const char * a2) { int32_t i=0, ret=0; while(a1[i]&&a2[i]) { ret += tolower(a1[i])-tolower(a2[i]); i++; } return ret; } UConverterFromUCallback otherUnicodeAction(UConverterFromUCallback MIA) { return (MIA==(UConverterFromUCallback)UCNV_FROM_U_CALLBACK_STOP)?(UConverterFromUCallback)UCNV_FROM_U_CALLBACK_SUBSTITUTE:(UConverterFromUCallback)UCNV_FROM_U_CALLBACK_STOP; } UConverterToUCallback otherCharAction(UConverterToUCallback MIA) { return (MIA==(UConverterToUCallback)UCNV_TO_U_CALLBACK_STOP)?(UConverterToUCallback)UCNV_TO_U_CALLBACK_SUBSTITUTE:(UConverterToUCallback)UCNV_TO_U_CALLBACK_STOP; }